# What is Clipper?

Clipper is the blue-chip DEX with no impermanent loss.

### The Blue-Chip DEX

Clipper is a DEX designed for blue-chip tokens (e.g., ETH, WBTC, USD stablecoins, etc.) and no impermanent loss. Blue-chip tokens comprise 70% of all on-chain trading volume.

Clipper's [novel architecture](/introduction/how-clipper-makes-money-for-lps#fmm-architecture) makes money for LPs using the same arbitrage strategy used by professional market makers, but implemented in a permissionless and non-custodial manner. In contrast to most DEXs, Clipper's LP yields are not generated from fees.

Clipper computes prices off-chain using a sophisticated formula that incorporates low-latency price feeds from centralized exchanges along with a snapshot of on-chain state. It then uses on-chain proofs to validate prices and preserve permissionlessness. This allows Clipper to make money from arbitrage, instead of paying a tax to arbitrageurs, while keeping gas fees low for traders. On Clipper, liquidity providers take home [superior yields](/introduction/how-lps-earn-from-arbitrage) with **no impermanent loss** and traders can expect no whales or bots front-running their trades. Clipper was initially developed by [Shipyard Software](https://www.shipyardsoftware.org) and licensed to [AdmiralDAO](https://www.admiraldao.xyz/).

Previously, Clipper focused solely on smaller trades. Recent architectural improvements now allow it to provide best prices for all trades, with sufficient TVL.

**Clipper is currently available on the following chains:**

* Ethereum
* Polygon
* Optimism
* Arbitrum
* Mantle Network
* Base

> **⛵️ Fun Fact:** Clipper is named for the mid-19th-century merchant vessels that revolutionized global trade. Clipper ships were designed for speed, partially by trading off cargo capacity, and made their owners millions of dollars.&#x20;


# How Clipper Makes Money for LPs

Clipper makes money for LPs through arbitrage. This requires significantly more sophisticated formulas than can be supported on-chain, given gas prices and block time constraints. Thus, Clipper does not rely on the Constant Product Market Maker (CPMM) used by most DEXs. Instead, Clipper has a unique architecture called the [Formula Market Maker](https://www.shipyardsoftware.org/post/what-is-a-fmm?ref=blog.clipper.exchange) (FMM), which enables off-chain computation without compromising custody.

### FMM Architecture

Clipper’s FMM is a hybrid mechanism that has both on-chain and off-chain components. It can utilize any formula that is part of the invariant function family developed in Shipyard's original [whitepaper on market making](https://github.com/shipyard-software/market-making-whitepaper). Unlike CPMMs whose pricing formulas only consider token ratios in pools, the FMM pricing function utilizes both token ratios and external real-time market prices from centralized and decentralized oracles. Clipper’s FMM performs pricing computations off-chain then verifies and validates them on-chain to prevent malicious quotes and determine if there have been any significant price changes between the time pricing data was pulled off-chain and applied to an on-chain swap. This design is highly efficient--keeping the hard work of solving formulas off-chain and verifying them on-chain avoids high gas costs while keeping the entire system trustless and transparent.

While the above describes how the FMM operates on the Polygon, Optimism, and Arbitrum versions of Clipper, on **Ethereum** it performs the comparative price computations and validations off-chain against the on-chain data. This further reduced Clipper’s gas usage on Ethereum, resulting in even lower gas costs for both traders and LPs—*both relative to the previous iteration and other leading DEXs.*

### No Impermanent Loss

There’s a major misconception that impermanent loss (IL) is an unavoidable feature of DEX liquidity pools. The misconception came about because most DEXs utilize a CPMM. CPMMs *are* inherently prone to IL due to how they balance liquidity pool assets. Tokens on CPMM-based DEXs are priced by a constant function (x\*y=k) and IL is caused by arbitrageurs exploiting discrepancies between the prices set by the CPMM and external market prices. While arbitrage activity keeps CPMM prices in line with the rest of the market, the profit arbitrageurs extract is siphoned from LP holdings.

> 💡 Despite its name, *impermanent loss* is a real risk that can have lasting and detrimental effects on LP returns. LPs realize this loss if upon withdrawing their stake from the pool, the value of the assets they retrieve is lower (at current market prices) than if they had simply held them.

Impermanent loss can be avoided by using a more sophisticated market maker with better pricing information. Clipper’s FMM uses both the token ratios in pools and decentralized price oracles to balance assets, instead of a constant function. The price oracles make it so that when external market prices change, Clipper’s prices update without the need for arbitrage trades. **The absence of impermanent loss contributes to** [**superior LP yields**](/introduction/how-lps-earn-from-arbitrage)**!**

{% hint style="info" %}
Note: This doesn’t mean that Clipper LPs are always profitable; all yield-generating opportunities come with a degree of risk. Clipper tracks the rebalancing portfolio you may have learned about in Modern Portfolio Theory. This portfolio provides optimal risk-adjusted beta exposure while generating free alpha from volatility along the way. It’s the approach that won a Nobel Prize in 1990.
{% endhint %}


# How LPs Earn from Arbitrage

Rather than from trading fees, Clipper generates LP returns by pursuing a statistical arbitrage strategy similar to many traditional finance asset managers. However, it does so permissionlessly according to a formula that anyone can observe, predict, and verify for themselves. This ensures composability and enables non-custodial liquidity.

The specific strategy is a Daily Rebalancing Portfolio (DRP). This is a common strategy for commodities trading.

> **Example of how rebalancing works:** Imagine a $2,000 dual-asset portfolio with target allocations of 50% ETH and 50% USDC. On day one, ETH doubles in price, raising the ETH allocation in the portfolio from $1,000 to $2,000. The portfolio allocation is now 66% ETH ($2,000) and 33% USDC ($1,000) and must be rebalanced back to 50/50. This is accomplished by selling $500 worth of ETH for USDC, returning the portfolio to 50% ETH ($1,500) and 50% USDC ($1,500).

Daily rebalancing works whenever assets have high daily volatility and mean reversion relative to monthly/yearly volatility. This is because daily rebalancing has the effect of systematically buying low and selling high each day. It generates profits each day, which are the source of yield for Clipper LPs. This is a well-researched phenomenon that earned Harry Markowitz the[ Nobel Prize](https://www.nobelprize.org/prizes/economic-sciences/1990/press-release/?ref=blog.clipper.exchange) in Economics in 1990.

> **Example of how rebalancing profits:** Imagine the aforementioned 50/50 ETH-USDC portfolio. On day two, ETH drops to its original value of $1,000. The portfolio again must be rebalanced by selling $375 USDC for ETH, resulting in $1,125 in ETH and $1,125 USDC, totalling $2,250. This is a 1.125x return. If the same assets had simply been held for the two days, the return would only be 1x (no return).&#x20;

👉 [**Spreadsheet**](https://docs.google.com/spreadsheets/d/1cZbJ18QvBuIcTofajTeAzVAdT5CmoUGzIN2nr12-8os/edit#gid=0) **showing how this works.**

👉 **Research on** [**Portfolio Rebalancing**](https://seekingalpha.com/article/4046116-investors-alpha-systematic-portfolio-rebalancing?ref=blog.clipper.exchange) **and** [**A Mathematical and Empirical Analysis of Rebalancing Alpha**](https://www.researchgate.net/publication/228179008_Optimal_Rebalancing_A_Scalable_Solution?ref=blog.clipper.exchange)

It turns out that blue-chip crypto assets, specifically ETH and WBTC, trade like commodities, just like gold and oil. This means a daily rebalancing statistical arbitrage strategy will work for them.

> **Evidence:** A Hurst Exponent test we ran (below) on the price movements of ETH from late 2015 through May 2023 shows that from mid-2018 onward ETH has typically been either memoryless or mean reverting, whereas prior to that it was noticeably momentum driven. This verifies that ETH prices seem to be more mean reverting as the asset has matured, making it a prime candidate for rebalancing. This is typically the case with blue-chip crypto assets, such as the Core Assets included in Clipper's Core pools.

{% hint style="info" %}
In a memoryless price series, variance over 90-day windows should be 3x the variance at the 30-day window. A momentum price series will be above 3, and a mean-reverting series will be below 3.&#x20;
{% endhint %}

<figure><img src="/files/arCCqdVh2ZNqU0Gpf0W2" alt="" width="375"><figcaption></figcaption></figure>

This strategy is especially attractive because Clipper rebalances without having to pay transaction costs that otherwise create “performance drag.” Instead, Clipper executes its trades with the noisy order flow from traders. Volume in Clipper's pools turns over extremely fast—sometimes multiple times per week. This means that traders will quickly rebalance Clipper’s pools for it. In other words, traders pay the transaction costs instead of Clipper, eliminating performance drag.

\
👉 **Research on** [**Rebalancing Portfolios With and Without Transaction Costs**](https://www.cs.cmu.edu/~avrim/Papers/portfolio.pdf?ref=blog.clipper.exchange)

### The Diversified Portfolio Also Reduces Risk&#x20;

A well-diversified, rebalancing portfolio has other benefits as well. Modern Portfolio Theory states that such a portfolio results in better long-term returns at a lower level of risk than investing solely in any one asset. Many financial advisors recommend a classic personal portfolio of [60% stocks and 40% bonds](https://www.nytimes.com/2015/04/12/business/mutfund/the-value-of-a-classic-in-a-turbocharged-world.html). Theoretically, this is an optimal way to gain exposure to an asset class. This long-term additional return further enhances Clipper’s yields.

👉 **Research on** [**Universal Portfolios**](https://isl.stanford.edu/~cover/papers/paper93.pdf?ref=blog.clipper.exchange)**, which increase long-term return while decreasing risk**


# Clipper's Benchmark: No Impermanent Loss

Clipper's pools act like a daily rebalancing portfolio composed of roughly [1/3 ETH, 1/3 WBTC, and 1/3 stablecoins](https://snapshot.org/#/theadmiraldao.eth/proposal/0xef7eee23d3b3357cee5d5f0c7b08bc8934b1993b35b0b655226c6572c584271a) (with zero transaction costs for rebalancing). **This rebalancing strategy results in no impermanent loss for LPs.**&#x20;

### How Clipper Stacks Up Against the Benchmark

Clipper's benchmark is no impermanent loss. It achieves this through tracking a theoretical costless DRP.&#x20;

If we look at a sample of Clipper's performance from September 11, 2022 through October 10, 2022, we see that it closely tracks the DRP while staying slightly ahead of it--finishing the interval almost 40 basis points ahead.&#x20;

<figure><img src="/files/iSgcXGgpr2fdfYrGRmIo" alt="" width="375"><figcaption></figcaption></figure>

Clipper was within 1 bps of the DRP for more than three-quarters of the days in the period. For those days where Clipper and the DRP diverged by more than 1 bps, Clipper was in the leading position more than two-thirds of the time (23% vs. 10% of days).&#x20;

<figure><img src="/files/Mq008YXyvAtcaDogx3hR" alt="" width="563"><figcaption></figcaption></figure>

The reason for return divergence is that Clipper’s [FMM](/introduction/how-clipper-makes-money-for-lps#fmm-architecture) will make trades continuously with traders over the course of a day, while the theoretical DRP is simulated to costlessly rebalance *once* per day. Despite the divergences, the daily correlation of percent returns to the returns of the DRP was extremely high at ρ = 0.9996.

Clipper's close tracking of the DRP is what enables it to hit its no impermanent loss benchmark.&#x20;

👉 Visit Clipper's [benchmark page](https://clipper.exchange/data/benchmark) for real-time performance.&#x20;


# Clipper vs. CPMMs vs. HODLing

Clipper's rebalancing strategy generally performs better than CPMMs (used by most DEXs) or HODLing, but it of course depends on market behavior. Below are examples of several market regimes and how the different strategies would perform in each.&#x20;

<figure><img src="/files/N5gpYL1eQ72KzgGcqrza" alt="" width="563"><figcaption></figcaption></figure>

{% hint style="info" %}
Note that this is stylized--what’s important is the relative short-term volatility and mean reversion to the long-term shifts.
{% endhint %}

## Clipper vs. The CPMM

Both Clipper and the CPMM provide beta exposure (return attributed to overall market returns) to the assets in their respective pools. However, the similarities end there. Instead of rebalancing as conceived of in Modern Portfolio Theory, the CPMM trades according to its inherent x\*y = k function. While Clipper provides alpha, the CPMM generates *negative* alpha, better known as impermanent loss. At best, if prices haven’t moved by the end of the period the CPMM generates no loss. If prices have moved in either direction, there is substantial loss. The CPMM generates no profit from short-term volatility and loses money from long-term volatility. Meanwhile, yield comes not from the rebalancing process but rather from arbitrary fees charged to traders on top of trade prices.

In other words, impermanent loss is not an attribute of all DEXs, it is an attribute solely of CPMM-based AMMs. Conceptually, the CPMM “sells low and buys high” as prices change, which is the opposite of Clipper's strategy (and common sense). The below figure shows how CPMMs only account for an asset’s beginning and ending prices. In contrast, Clipper's strategy accounts for price movements in the interim and profits from volatility.

<figure><img src="/files/86oHSx94238yDIqRP8Vb" alt="" width="375"><figcaption></figcaption></figure>

As you can see, the attributes of the CPMM are not very favorable to LPs. Why then is it used by all first-generation DEXs? Because it is extremely simple to implement. It is also simple to calculate on-chain, which makes gas costs low. This tradeoff between gas and complexity is what Clipper's FMM architecture overcomes.

👉 **See** [**Appendix**](/introduction/clippers-benchmark-no-impermanent-loss/appendix-math#rebalanced-portfolio-benchmark) **for math on the CPMM vs Clipper**

### Comparing Yields&#x20;

Because the DeFi community is so used to CPMM DEXs, APY comparisons assume all pools are structured as CPMMs with trading fees and impermanent loss. Because Clipper does not have explicit trading fees or impermanent loss, it’s difficult to directly compare Clipper’s bottom-line LP figures with the top-line revenue numbers CPMM-based DEXs use. To ensure full transparency and keep LPs informed, Clipper reports comparable metrics and historical earnings on Clipper's [data dashboard](https://clipper.exchange/data?ref=blog.clipper.exchange).

## Clipper vs. HODLing

Clipper has an objectively better risk-return profile than HODLing and should outperform it in current market regimes. However, there are price series' that could result in better returns from HODLing. To provide concrete data, below are several months of Clipper's performance vs. HODLing an equivalent initial portfolio.&#x20;

<table><thead><tr><th width="134.00000000000003">Month</th><th>Clipper's Performance (bps)</th><th>HODL Performance (bps)</th></tr></thead><tbody><tr><td>April 2023</td><td>+213</td><td>+185</td></tr><tr><td>May 2023</td><td>-5</td><td>-14</td></tr><tr><td>June 2023</td><td>+472</td><td>+458</td></tr><tr><td>July 2023</td><td>-169</td><td>-177</td></tr></tbody></table>


# Appendix: Math

## Setup

Each day we have five relevant values:

* Yesterday’s asset prices in dollars, p’
* Today’s asset prices in dollars, p
* Yesterday’s (human) quantity vector, q’ on a *per LP token* basis
* Today’s (human) quantity vector, q on a *per LP token* basis
* Our target wealths vector, v, which we take to be wealth fractions:

$$
\sum\_i v\_i = 1 \ \ \ v\_i \geq 0
$$

Observe that v should *tend to* be proportional to the actual wealth (q\_i\*p\_i) on each asset i.

### Calculating Daily Returns & Benchmarks

All of these benchmarks are designed so that 0 represents no change. Since the values are expected to be small, they may not need to have log taken for additive basis points.

**Daily $ Returns**

$$
\frac{\sum\_i p\_iq\_i - \sum\_i p'\_iq'\_i}{\sum\_i p'\_iq'\_i}
$$

This measures how much the portfolio increased in $ terms since yesterday.

### Daily Crypto Basis Returns

$$
\frac{\sum\_i p\_iq\_i - \sum\_i p\_iq'\_i}{\sum\_i p\_iq'\_i}
$$

This value will be negative if we would prefer yesterday’s portfolio to today’s portfolio at today’s prices.

### Rebalanced Portfolio Benchmark

$$
\sum\_i \left(\frac{p\_i}{p'\_i}\right) v\_i - 1
$$

This is our target benchmark for Clipper: our daily dollar gain should track it closely and ideally outperform.

Observe that a rebalanced portfolio can *outperform* a static (”held”) portfolio consisting of any (!) initial combination of the assets themselves. For instance, imagine the two-asset case consisting of a risky asset and a stablecoin. On day one, the risky asset doubles in price. On day two the risky asset returns to its original value. It can be verified that a 50-50 rebalanced portfolio will return 1.125x, vs. 1x for simply holding any combination of assets for the two days.

### CPMM Loss Benchmark

In the CPMM, we have that:

$$
\begin{align\*}
\prod q\_i^{v\_i} & = C \\
\sum\_i v\_i \log q\_i & = \log C
\end{align\*}
$$

Day-to-day, the portfolio of the CPMM changes to have wealth proportional to the new set of prices. By working out this constant log-sum, we get the following expression for how much “impermanent” loss a CPMM mechanism takes on:

$$
\frac{\prod\_i \left( \frac{p\_i}{p'\_i} \right)^{v\_i} - \sum\_i \left( \frac{p\_i}{p'\_i} \right)v\_i}{\sum\_i \left( \frac{p\_i}{p'\_i} \right)v\_i}
$$

This value is at most 0 when the prices are the same. Clipper’s crypto performance (loss or gain) should substantially outperform this benchmark.


# Why Clipper Has Better Trading Prices

**Because Clipper generates more efficient returns for LPs, it can afford to offer better prices to traders.**&#x20;

With \~$10M in liquidity (TVL), Clipper has best prices trades up to $10k. As TVL grows, Clipper will have best prices on larger trades--e.g., $50M TVL would correspond to best prices on trades up to $50k.&#x20;

Below are the results of a [sampling study](https://blog.clipper.exchange/clipper-vs-0x-price-study/) against 0x API for a $10K USDC<>ETH trade over several days in August 2023. [The results](https://docs.google.com/presentation/d/1QLYkVzOBrMvy8axKhID_ag0IVEaARIfN/edit#slide=id.p6) show Clipper beat 0x 92.5% of the time on both legs of the trade and 99.6% of the time on at least one leg.&#x20;

<figure><img src="/files/IjdoS7fw5d8eETe6Illy" alt="" width="563"><figcaption></figcaption></figure>


# DAO Protocol Fees

Clipper adds a small spread (\~10bps) to each trade. 100% of this spread goes to AdmiralDAO as protocol fees. DAO protocol fees are published by [Token Terminal](https://tokenterminal.com/terminal/projects/clipper/financial-statement) and are also publicly auditable [on-chain](https://etherscan.io/address/0xD8Cc0304de58fCE5147796606Db14500d94b5EF2?ref=blog.clipper.exchange).

### How the Spread Works&#x20;

The spread is measured by summing the positive difference between Clipper input and output on swaps, according to on-chain price oracles. This is fully verifiable on-chain, so LPs don’t need to take anyone’s word for it.

This spread generates excess returns *on top of* Clipper's rebalancing strategy and no impermanent loss benchmark ("benchmark outperformance").  This structure means **LPs only pay fees if they profit.** This is a big difference from other AMMs, which charge fees on all trades, even those that lose money for LPs.&#x20;

You can track benchmark outperformance [here](https://clipper.exchange/data/benchmark).


# DAO Governance

Clipper is governed by AdmiralDAO.

[AdmiralDAO](https://www.admiraldao.xyz/) is a decentralized autonomous organization [governed by the community](/governance-token/community-governance) and supported by Admiralty LLC, a non-profit member-managed LLC [domiciled in the Marshall Islands](https://www.shipyardsoftware.org/post/shipyard-dao-marshall-islands?ref=blog.clipper.exchange). The DAO controls a multisig wallet with several signers.

For more on AdmiralDAO, please visit the [AdmiralDAO docs](https://docs.admiraldao.xyz/introduction/admiralty).&#x20;


# Liquidity Pools

Clipper's [pools](https://clipper.exchange/app/liquidity/pool?ref=blog.clipper.exchange) are multi-asset liquidity pools composed of Clipper Core Assets (*usually ETH, WBTC, USDC, USDT, DAI, and the native token of the given chain*). These assets are commodities that comprise 70% of all trade volume in DeFi.

<div align="center"><figure><img src="/files/qDUYnUUDE7nKrxaQVrrB" alt="" width="563"><figcaption><p>Example of Clipper Core Assets on the Polygon netowrk</p></figcaption></figure></div>

Unlike most DEX liquidity pools, Clipper LPs earn yield on a *pro rata* portion of the entire pool, not just the asset(s) they deposit. Upon deposit, LPs receive LP tokens which represent their fractional ownership of the underlying pool. LP tokens have no value other than this representation.

{% hint style="info" %}
LP tokens are called **CLIPPERLP** on the Ethereum network and **CLPRDRPL** on all other chains--despite the difference in name, they serve the same purpose.&#x20;
{% endhint %}

There is one liquidity pool on each chain. The benefit of using one unified pool is to consolidate liquidity, rather than fragmenting it across multiple pools to achieve the same pairings. This increases capital efficiency, allowing for higher yields with lower fees.


# Depositing & Withdrawing

## Depositing

The only requirement for providing liquidity on Clipper is that your wallet is not on the OFAC list. To deposit, simply connect your wallet and follow the on-screen prompts.

### Clipper LP Tokens

Upon deposit, you will receive LP tokens (called either CLIPPERLP or CLPDRPL, depending on the chain). These tokens represent your fractional ownership of the underlying pool and have **no value** other than this representation. Their purpose is to enable Clipper to normalize each LP’s deposits and withdrawal amounts by calculating their pool ownership value per token. Hold on to your LP tokens, **you will need them for withdrawal**.

The rewards you collect as an LP will be added to the overall value of your deposit and can be withdrawn at the same time as your principal.

## Withdrawing LP Deposits & Rewards

{% hint style="info" %}
Clipper is a non-custodial mechanism. Even if the Clipper web page goes down, unlocking and burning LP tokens to withdraw assets are operations that are always available by directly interacting with the smart contracts on the blockchain.
{% endhint %}

To withdraw, you must redeem (burn) your LP tokens. You will have the option to withdraw either a single asset or a pro rata share of all tokens in the multi-asset pool.

If you choose the second option, the relative composition of tokens is determined by each asset’s external market prices, which Clipper uses to calculate the value per token for the pool. This is done by taking the value of the assets at those external market prices and dividing that value by the total number of tokens in the pool.

{% hint style="info" %}
**Note:** Previously, Clipper had additional liquidity pools called Coves. Coves are now deprecated, but LPs are still able to withdraw their liquidity from Coves indefinitely.&#x20;
{% endhint %}


# Farming Pools

Clipper’s [farming pools](https://clipper.exchange/app/rewards) are multi-asset liquidity pools made up of Core Assets. They function like the [main pools](/how-to-use-clipper/liquidity-pools) but have the added benefit of enabling LPs to earn reward tokens for staking their liquidity.&#x20;

### How to Deposit into a Farming Pool:

1. From [here](https://clipper.exchange/app/liquidity/pool?farm=0xD0454428ecd868A9AC615125FCbDB5Da9027436e), enter the token and amount you wish to deposit and connect your wallet.           *Note: The pool supports both individual asset and multi-asset deposits. If you are depositing $100k USD or more, a multi-asset deposit is recommended for better reward profits.*
2. Allow Clipper to use your tokens.
3. You will be shown your potential reward token earnings. Rewards will depend not only on the size of your deposit and the current size of the pool, but **also on how long you let your rewards grow**.&#x20;
4. Confirm your deposit.
5. Once the transaction completes in your wallet, your liquidity will be added to the farming pool and will start accruing reward tokens. You will receive ClipperLP tokens upon depositing. ClipperLP tokens simply represent your fractional ownership of the underlying pool, they have no intrinsic value. ClipperLP is used in the harvesting process, so hold onto them. &#x20;

{% hint style="info" %}
🌾 **Note:** Farming rewards continue to grow for the entire duration that your liquidity remains in the pool. You can withdraw at any time, however, there is an initial "waiting period" if you want to harvest your full rewards. Below is an example of how this works: \
\
The duration of the "waiting period" is specified upon deposit *(often 30 days but may vary)*. If the current reward rate is 5 tokens per day (hypothetical), on day 30 you will have accrued 150 reward tokens, at which point you can harvest all 150 tokens (100% of your return). However, if you decide to withdraw on day 20, for example, you will only receive a portion of the 100 tokens you've accrued (<100% of reward--exact amount depends on various factors) because you have not met the waiting period requirement yet. Once you hit the "waiting period" requirement, you will receive 100% of your accrued rewards (*on that deposit*) from that day onward--and r**ewards continue to accrue even after the "waiting period" is reached.**    \
\
**This is intended to reward LPs who leave their liquidity in for longer durations and incentivize longer-term liquidity provision rather than quick reward schemes.**&#x20;
{% endhint %}

### How to Harvest Rewards&#x20;

1. Visit the [**Rewards page**](https://clipper.exchange/app/rewards) to view your harvest data and harvest your rewards. Harvest data shows how much of your rewards are currently available to claim and how much time is left until you reach your maximum claim amount.
2. Click “Harvest” to begin harvesting.&#x20;
3. Enter the amount of reward tokens you want to harvest. This can be equal to or less than the amount you have available to harvest.
4. Allow Clipper to use your ClipperLP tokens to harvest Sreward tokens.&#x20;
5. Confirm your harvest.
6. Once the transaction completes in your wallet, your reward tokens are harvested to your wallet.

👉 Check out the [SAIL Farming page](/governance-token/sail-primer/sail-farming) for info specific to farming & harvesting governance tokens.&#x20;


# Trading

**To start trading**, connect your wallet to Clipper and follow the on-screen prompts.

### Trading Fees

**There are no fees for traders on Clipper!** Instead, Clipper takes a small portion of LP gains from each profitable trade. This means that for traders, the price quotes you see on Clipper have no explicit fees or hidden costs. Read about how Clipper’s fees for LPs work [here](/introduction/how-lps-earn-from-arbitrage#dao-fees).


# Community Adventures

Clipper periodically hosts Adventures, which are immersive experiences that are a cross between a digital scavenger hunt and a turn-based game

Each Adventure has a pirate-themed storyline that typically builds upon that of the previous Adventure. Participants are broken up into teams, with each team consisting of a ship, a captain, and a crew of pirates. The ships race through activities in the web3 world to uncover the treasure awaiting them.

Adventures offer the Clipper community a fun, gamified way to engage with the platform, win prizes, and interact with other community members.

For an example of a past Adventure, check out [this blog post](https://blog.clipper.exchange/adventure-3-building-clippertopia/) and its [recap](https://blog.clipper.exchange/adventure-3-recap/).

**👉 New Adventures are announced in** [**Discord**](https://discord.com/invite/clipperdex) **with full sign-up and participation instructions provided there as well**.


# FAQs

🦜 Frequently asked questions

### General

**Who is the team behind Clipper?**

Clipper was built by Shipyard Software, a leading design shop that develops custom-built DEXs. Shipyard’s team can be viewed [here](https://www.shipyardsoftware.org/about#team).

**How do I report a bug?**

Please report bugs [**here**](https://forms.gle/5xLEQzNqkiuwFJeT6).

**Can I use a hardware wallet on Clipper?**

Yes, any hardware wallet that is compatible with your crypto assets’ token standards can be used with Clipper.

### Liquidity

**Who can be a Clipper LP?**

The only requirement is that your wallet is not on the OFAC list.

**Is there a limit on how much liquidity I can deposit?**

No.

**Is there any lockup period for LP deposits?**

No.

**How does a token's current balance in a Core pool affect the value of a deposit?**

LPs will be granted a larger number of pool tokens (and therefore, a higher percentage of pool ownership) for depositing assets that are currently undersupplied in the pool.

By looking at the star rating next to each asset in Core pools, you can see how its supply in the pool will impact your deposit. (i.e., an asset with a 3-star rating is undersupplied, therefore a deposit of this asset may be more likely to increase in value. An asset with a 1-star or 0-star rating is oversupplied in the pool, therefore a deposit of this asset may be less likely to increase in value.)

**On the Clipper data page, what is "Profit Yield"?**

This net trading gain figure is the sum of the positive difference between Clipper input and output on swaps, according to on-chain price oracles. This figure is the best entirely on-chain auditable proxy for Clipper LP's excess gains over and above the DRP benchmark. This is what the DAO takes its fees from.

**On the Clipper data page, what is "Comparable APY"? How does it relate to impermanent loss?**

Top-line yield that includes the impermanent loss (IL) avoided by Clipper’s FMM design. These APYs are directly comparable with the APYs reported by most other DEXs like Uniswap and Sushi, which advertise inflated figures that don't account for hidden costs.

The annualized yields (APYs) shared by these DEXs are calculated from "fees" that include a great deal of IL. Clipper's innovative FMM design not only allows LPs to avoid the impermanent loss that other DEXs face but also to calculate the counterfactual of the amount of IL that LPs *would have* suffered. We call that counterfactual amount "avoided IL".

Avoided IL is calculated by comparing Clipper LPs' gain/loss on a crypto-basis (i.e., measured in crypto, not USD) to the crypto-basis loss of the CPMM mechanism used by Uniswap, etc. This crypto-basis loss can be calculated from (and will change based on) the difference in dollar values of the assets at the start and end of a time period. Comparable APY is then calculated by taking Clipper's profit yield and adding it to the avoided IL.

We believe Comparable APY represents the best and most accurate expression of Clipper's "yield" when LPs are considering which DEX to deposit into.

### Transactions

**Should I be concerned about front running, MEV, or sandwich attacks when trading on Clipper?**

These kinds of attacks can happen with decentralized exchanges like Uniswap or SUSHI that do not offer traders guaranteed rates in swaps. Bots watch pending transactions and can construct ways to give traders a worse rate, pocketing the surplus.

A unique aspect of Clipper is that all signed quotes are firm, so you do not need to worry about bots stealing from your intended transactions.

**Why is my transaction pending for so long?**

The most likely explanation is that the gas price associated with your transaction was too low for miners to consider including it in a new block. Depending on your wallet, you may be able to cancel your pending transaction or re-submit it with a higher gas price. Etherscan maintains a [**detailed "Gas Tracker" page**](https://etherscan.io/gastracker) with frequently updated estimates of execution price and timeliness.

**Will my gas costs be refunded?**

As is typical for interactions on blockchains, any gas that was not consumed by a transaction on Clipper will be refunded to its sender.

**How can we verify someone is affiliated with the protocol?**

We will post codes here: SEAL 911 verification


# Community Governance

SAIL is the governance token of AdmiralDAO.

### How Community Governance Works

Community governance of [AdmiralDAO](https://www.admiraldao.xyz/) (and by extension Clipper) is driven by SAIL token holders--the DAO's governance token. Every SAIL holder is a member of AdmiralDAO 🤝.&#x20;

DAO members are empowered to submit and vote on governance proposals in order to make changes to products overseen by the DAO (like Clipper), SAIL-related initiatives, allocation of community Treasury funds, or the governance framework itself. Proposal topics might cover (but are not limited to) items such as:&#x20;

* Protocol upgrades (new features, security enhancements, performance optimizations)
* Clipper LP fee structure modification
* Deploying Clipper on new chains&#x20;
* Additions or adjustments to SAIL farming incentives&#x20;
* Changes to SAIL supply cap&#x20;
* Changes to governance process timelines or structure

> AdmiralDAO members follow the governance process to propose, vote on, and implement changes. For more on the governance process visit [the AdmiralDAO docs](https://docs.admiraldao.xyz/community-governance/governance-process).&#x20;

### How to Get SAIL&#x20;

**SAIL is earned through yield farming on Clipper.** Farming is the best way to obtain SAIL and doesn't require any purchase of tokens.&#x20;

SAIL farming simply entails staking liquidity in the SAIL farming pool on Clipper, letting your rewards grow, and then harvesting your SAIL tokens. Staked liquidity can be in the form of ETH, BTC, USDC, or other stablecoins and blue-chip tokens. Being a SAIL holder enables you to actively participate in community governance. The more SAIL you hold, the greater your on-chain voting power.&#x20;

👉 Check out the [SAIL Farming](/governance-token/sail-primer/sail-farming) section for details and instructions or start farming right away [here](https://clipper.exchange/app/liquidity/pool?farm=0xD0454428ecd868A9AC615125FCbDB5Da9027436e). &#x20;

**SAIL and U.S. Securities Regulation**

* AdmiralDAO studied the U.S. regulatory landscape at issuance. The analysis and conclusions are explained in [this blog post](https://www.admiraldao.xyz/blog/sail-securities-law).


# SAIL Primer

Note: All information in this Primer is publicly available information.

## About SAIL & Clipper <a href="#about-sail-and-clipper" id="about-sail-and-clipper"></a>

SAIL is the token of [clipper.exchange.](/disclaimers-and-technical/integrating-with-clipper-rfq/guides/interacting-with-the-clipper-exchange-contracts) Clipper is a DEX designed for the pairs that matter most, namely ETH<>USD, WBTC<>USD, and the the native token of a given chain. These pairs comprise 80% of all on-chain trading volume (70% of Uniswap’s volume is just its ETH<>USD pool). Winning the market for just these pairs would mean winning the majority of all DeFi volume.

Clipper uses a hybrid onchain/offchain architecture with a ‘compute offchain, prove onchain’ design philosophy. It computes prices off-chain using a publicly-disclosed formula that ingests low-latency price feeds from centralized exchanges along with a snapshot of on-chain state. Clipper’s onchain pool then uses on-chain proofs to validate prices and preserve permissionlessness. This allows Clipper to make money from arbitrage, instead of losing money to arbitrageurs, while keeping gas fees low. On Clipper, liquidity providers take home superior yields with no impermanent loss and traders can expect better prices with no whales or bots front-running their trades. Because Clipper can sustain better prices, it can capture value (the “Intel Inside” strategy).

Clipper was initially developed by Shipyard Software and licensed to AdmiralDAO, a nonprofit member-managed DAO LLC in the Marshall Islands (see <https://www.admiraldao.xyz/>). It’s latest version (5th) was deployed in Q1 2023. See <https://docs.clipper.exchange/> for full information.

Clipper earns protocol revenue by charging a \~10bps protocol fee on each trade.

#### SAIL Utility & History <a href="#sail-utility-and-history" id="sail-utility-and-history"></a>

SAIL can be staked for , which has voting power in Clipper’s DAO (AdmiralDAO). veSAIL also receives yield in the form of SAIL acquired from open market SAIL buybacks using Clipper’s revenue. SAIL was issued August 22, 2023 by airdrop. There was no ICO, presale or private sale.


# Clipper Fundamentals

## Clipper Traction & Further Info <a href="#clipper-traction-and-further-info" id="clipper-traction-and-further-info"></a>

**Revenue:** $500k annualized revenue (up 2.5x from Q3). See​ <https://tokenterminal.com/terminal/projects/clipper>

**Usage:** $2.5 billion volume (8.3 billion comparable volume) from 216,000 traders across 2 million transactions with 99,000 LPs. See <https://dune.com/shipyard_software/clipper-official>

* Note that people typically multiply Clipper’s volume by 3.3x to compare it to other DEXs. This is because Clipper’s prices are firm, precluding arbitrage/MEV bots. In contrast, 70% of Uniswap (and other CPMM) volume is arbitrage/MEV bots programmatically reacting to ‘real trades’. Mathematically, 1 / (1-70%) = 3.3x.

**Community:** 100k+ discord, 120k+ twitter.**Chains:** Ethereum Mainnet, Optimism, Polygon, Arbitrum, Mantle, Base, Moonbeam.

**Price Competitiveness:** Clipper beats 0x API 92.5% of the time on a $10,000 USDC<>ETH trade. <https://docs.clipper.exchange/introduction/why-clipper-has-better-trading-prices>

**Yields:** Typically base APYs of 50%+ on ETH/WBTC/USD. See <https://clipper.exchange/app/liquidity>

**Proof of No Impermanent Loss:** Zero LVR ([Loss Versus Rebalancing](https://a16zcrypto.com/posts/article/lvr-quantifying-the-cost-of-providing-liquidity-to-automated-market-makers/)  is a16z’s metric) since the last deployment in Q1 2023. Learn more about Clipper's No Impermanent Loss (NIL) Index <https://clipper.exchange/data>


# DEX Market Structure

## Market Structure, Trends & TAM (”Intents” and “Solvers”) <a href="#market-structure-trends-and-tam-intents-and-solvers" id="market-structure-trends-and-tam-intents-and-solvers"></a>

The DEX market is rapidly moving toward an aggregator-based ‘intents’ model, in which user-facing frontends (e.g. 1inch Fusion, Metamask, UniswapX, Cowswap, etc) allow third party ‘solvers’ to compete to fill trades by composing in multiple sources of liquidity. These solvers always algorithmically route in the DEX offering the best price. Since Clipper has best prices, it tends to win these trades. 95% of Clipper’s volume comes from 1inch and UniswapX. Clipper is the only onchain permissioned filler for UniswapX.

The “big win” for Clipper would be processing the majority of all DeFi spot volume (\~$1 Trillion annually). This solely requires winning the market for ETH<>USD (and on other chains the native token of that chain). The more the DEX market moves toward a ‘solver’ model, the more possible this becomes, because solvers will algorithmically route to Clipper. ***One could can think of Clipper as a leveraged bet on the trend of Aggregators, Intents & Solvers.*** Note this is not financial advice and we give no assurances or predictions about SAIL price.

### Clipper Roadmap <a href="#clipper-roadmap" id="clipper-roadmap"></a>

Clipper’s roadmap (proposed by and subject to approval by DAO governance) prioritizes:Increasing volume by deploying new Solvers and on new Chains.Increasing TVL by improving the LP UX, analytics, and integrating with third party vaults.Full roadmap here: ​​<https://www.notion.so/native/shipyardsoftware/AdmiralDAO-Roadmap-ccf04d9205e34a32b4dfbb52904b4cd4?deepLinkOpenNewTab=true>


# SAIL Supply & Circulation

SAIL is the governance token of AdmiralDAO, the DAO behind Clipper DEX.

### **Contract Address**

> **Ethereum:** 0xd8F1460044925d2D5c723C7054cd9247027415B7
>
> **Optimism:** 0x7a1263eC3Bf0a19e25C553B8A2C312e903262C5E&#x20;
>
> **Arbitrum:** 0xb52BD62eE0Cf462Fa9CCbDA4bf27Fe84D9ab6Cf7&#x20;
>
> **Polygon:** 0xd1a718f77ab5d22e3955050658d7f65ae857a85e

### Supply & Distribution

* Total circulating supply: 1,000,000,000
* [AdmiralDAO Tokenomics](https://docs.admiraldao.xyz/community-governance/sail-tokenomics)&#x20;

**Genesis Event:** No ICO, pre-sales, or private sales. A community airdrop was distributed at launch to reward early Clipper users for retroactive behaviors.  [SAIL Claim Dune Dashboard](https://dune.com/rusty378/sail-claim)

**Disclosure:** Shipyard Software's equity investors have an effective cost basis of $0.065 per token, were the tokens paid to Shipyard to be distributed as a dividend.

**Token Type:** ERC-20

<figure><img src="/files/aV7KLJxlgWbVcwZT7EnY" alt="" width="563"><figcaption></figcaption></figure>

<figure><img src="/files/eCov12aLXMMfZQep4rjh" alt="" width="563"><figcaption><p>Clipper Community receives plurality of SAIL in year 1 through airdrop.</p></figcaption></figure>

<figure><img src="/files/Dt3UJ34GQYXWtAVTpjJw" alt="" width="563"><figcaption></figcaption></figure>

<figure><img src="/files/tQjAq9hPr07Ry8rm0CLJ" alt="" width="563"><figcaption></figcaption></figure>

### Year 1 Circulating Supply\*

<table><thead><tr><th width="196">Month</th><th width="176" data-type="number">Shipyard Software</th><th width="260" data-type="number">Protocols + Service Providers</th><th width="140" data-type="number">DAO Treasury</th><th width="145" data-type="number">Community</th><th width="100" data-type="number">Total</th></tr></thead><tbody><tr><td>September 1, 2023</td><td>0</td><td>55491023.59</td><td>20000000</td><td>52500000</td><td>127991023.59</td></tr><tr><td>October 1, 2023</td><td>0</td><td>57904633.27</td><td>25000000</td><td>61887408.08</td><td>144792041.35</td></tr><tr><td>November 1, 2023</td><td>0</td><td>60318242.95</td><td>30000000</td><td>71274816.17</td><td>161593059.12</td></tr><tr><td>December 1, 2023</td><td>0</td><td>62731852.63</td><td>35000000</td><td>80662224.25</td><td>178394076.88</td></tr><tr><td>January 1, 2024</td><td>0</td><td>65145462.31</td><td>40000000</td><td>90049632.33</td><td>195195094.65</td></tr><tr><td>February 1, 2024</td><td>0</td><td>67559071.99</td><td>45000000</td><td>99437040.42</td><td>211996112.41</td></tr><tr><td>March 1, 2024</td><td>0</td><td>69972681.68</td><td>50000000</td><td>108824448.5</td><td>228797130.18</td></tr><tr><td>April 1, 2024</td><td>9756097.56</td><td>72386291.36</td><td>55000000</td><td>124228707.08</td><td>261371096</td></tr><tr><td>May 1, 2024</td><td>19512195.12</td><td>74799901.04</td><td>60000000</td><td>139632965.67</td><td>293945061.83</td></tr><tr><td>June 1, 2024</td><td>29268292.68</td><td>77213510.73</td><td>65000000</td><td>155037224.25</td><td>326519027.65</td></tr><tr><td>July 1, 2024</td><td>39024390.24</td><td>79627120.41</td><td>70000000</td><td>170441482.83</td><td>359092993.49</td></tr><tr><td>August 1, 2024</td><td>48780487.8</td><td>82040730.09</td><td>75000000</td><td>185845741.42</td><td>391666959.31</td></tr></tbody></table>

**\***&#x53;tart-of-period distributions. September 2023 is first full month of circulation. SAIL airdrop was executed on August 22, 2023.&#x20;


# SAIL Farming

SAIL is earned through yield farming on Clipper. The process is simple: stake liquidity in the SAIL farming pool, let your rewards grow, and harvest your SAIL when ready!

Staking in the [SAIL farming pool](https://clipper.exchange/app/liquidity/pool?farm=0xD0454428ecd868A9AC615125FCbDB5Da9027436e) has the added benefit of earning you superior rewards as a liquidity provider (compared to other DEX pools) by way of Clipper's [novel pool design](/introduction/how-clipper-makes-money-for-lps) which has no impermanent loss!

> Clipper’s [farming pools](https://clipper.exchange/app/rewards) are multi-asset liquidity pools made up of Clipper Core Assets (BTC, ETH, USDC, and other "blue-chip" tokens and stablecoins). Clipper has multiple farming pools that provide different reward tokens, but these instructions focus specifically on the SAIL farming pool.&#x20;

### 💧 How to Deposit into the Farming Pool

1. From [here](https://clipper.exchange/app/liquidity/pool?farm=0xD0454428ecd868A9AC615125FCbDB5Da9027436e), enter the token and amount you wish to deposit and connect your wallet.&#x20;

   *Note: The pool supports both individual asset and multi-asset deposits. If you are depositing $100k USD or more, a multi-asset deposit is recommended for better reward profits.*
2. Allow Clipper to use your tokens.
3. You will be shown your potential SAIL earnings. Rewards will depend not only on the size of your deposit and the current size of the pool, but **also on how long you let your rewards grow**.&#x20;
4. Confirm your deposit.
5. Once the transaction completes in your wallet, your liquidity will be added to the farming pool and will start accruing SAIL. You will receive ClipperLP tokens upon depositing. ClipperLP tokens simply represent your fractional ownership of the underlying pool, they have no intrinsic value. ClipperLP is used in the harvesting process, so hold onto them.  &#x20;

{% hint style="info" %}
🌾 **Important Note:** Farming rewards continue to grow for the entire duration that your liquidity remains in the pool. You can withdraw at any time, however, there is an initial "waiting period" if you want to harvest your full rewards. Below is an example of how this works: \
\
The duration of the "waiting period" is specified upon deposit *(often 30 days but may vary)*. If the current reward rate is 5 SAIL per day (hypothetical), on day 30 you will have accrued 150 SAIL, at which point you can harvest all 150 SAIL (100% of your return). However, if you decide to withdraw on day 20, for example, you will only receive a portion of the 100 SAIL you've accrued (<100% of reward--exact amount depends on various factors) because you have not met the waiting period requirement yet. Once you hit the "waiting period" requirement, you will receive 100% of your accrued rewards (*on that deposit*) from that day onward--and r**ewards continue to accrue even after the "waiting period" is reached.**    \
\
**This is intended to reward LPs who leave their liquidity in for longer durations and incentivize longer-term liquidity provision rather than quick reward schemes.**&#x20;
{% endhint %}

### 🚜 How to Harvest SAIL

1. Visit the [**Rewards page**](https://clipper.exchange/app/rewards) to view your harvest data and harvest your rewards. Harvest data shows how much of your rewards are currently available to claim and how much time is left until you reach your maximum claim amount.
2. Click “Harvest” to begin harvesting.&#x20;
3. Enter the amount of SAIL tokens you want to harvest. This can be equal to or less than the amount you have available to harvest.
4. Allow Clipper to use your ClipperLP tokens to harvest SAIL.
5. Confirm your harvest.
6. Once the transaction completes in your wallet, your SAIL is harvested to your wallet.


# veSAIL

SAIL is for Governance

veSAIL is the vote escrowed token (veToken) of AdmiralDAO. It enables SAIL holders to stake their tokens in an escrow account to earn additional SAIL, further increasing their voting rights and giving governance participants a vested interest in managing the DAO.

### How veSAIL Works

SAIL holders stake their SAIL in the [escrow account](https://clipper.exchange/app/liquidity/stake/sail) and receive veSAIL in return. veSAIL can be used in governance, just like SAIL.&#x20;

To convert veSAIL back to SAIL and redeem rewards, depositors burn their veSAIL. The exchange rate between veSAIL and SAIL changes over time, depending on how much additional SAIL (for rewards) resides in the redemption contract.&#x20;

Note that the [DAO voted](https://snapshot.org/#/theadmiraldao.eth/proposal/0xa17214a8d24a40145a7086c5e23e783b3017a07327aa0544562264f8a8a41005) to distribute Real Yield instead of (or in addition to) of SAIL. That is expected to be implemented in veSAIL v2.

### Is There a Lockup Period?&#x20;

Currently, there is no required lock-up period for veSAIL, similar to the 0-day lock-up for xSushi. However, a lock-up parameter may be implemented by DAO governance in the future.

{% hint style="info" %}
Note that although there is no required lockup period, the longer a deposit is left in the escrow contract the more rewards it accrues.&#x20;
{% endhint %}

### Where Do the SAIL Rewards Come From?

A portion of Clipper’s protocol fees will be used to purchase SAIL off the open market. This SAIL is then deposited into the redemption contract and distributed as rewards to veSAIL holders. In the future, SAIL rewards may be vested over a long timeframe to ensure long-term incentive alignment of governance participants.&#x20;

**For information on protocol fees see:**

* [How Clipper Generates Protocol Fees ](https://docs.clipper.exchange/introduction/how-dao-protocol-fees-work)
* View protocol fees on [Token Terminal](https://tokenterminal.com/terminal/projects/clipper/financial-statement)
* The magnitude of the opportunity: [Projecting Protocol Fees](https://blog.clipper.exchange/dao-protocol-fees/)&#x20;
* DEX traction: [Clipper DEX performance](https://dune.com/shipyard_software/clipper-official)

### How to Get veSAIL**‍**

1. Visit Clipper's [Get veSAIL page](https://clipper.exchange/app/liquidity/stake/sail) and connect your wallet.&#x20;
2. Enter the amount of SAIL you want to stake. You will be shown the current SAIL<->veSAIL conversion rate here.&#x20;
3. Once your transaction completes, your returns will begin growing at the current Staking APY rate listed on the veSAIL dashboard! Your SAIL balance is always visible on the [SAIL page](https://clipper.exchange/sail).

<figure><img src="/files/NRyRSxy6DqFx24eBYI4V" alt="" width="375"><figcaption></figcaption></figure>


# Token Listings

A repository of third-party token listings.

### [CoinGecko](https://www.coingecko.com/)

<figure><img src="/files/pM9xsIIitLiNcckFfmne" alt="" width="359"><figcaption></figcaption></figure>

{% embed url="<https://www.coingecko.com/en/coins/sail-2>" %}

### [Uniswap](https://info.uniswap.org/#/)

<figure><img src="/files/KGLZerQM6Zen1ZHesOXG" alt="" width="397"><figcaption></figcaption></figure>

{% embed url="<https://app.uniswap.org/#/tokens/ethereum/0xd8f1460044925d2d5c723c7054cd9247027415b7>" %}

### [Bybit](https://www.bybit.com/en-US)

<figure><img src="/files/0RFgQnmsAXIWAAPgvaVF" alt="" width="293"><figcaption></figcaption></figure>

{% embed url="<https://www.bybit.com/en-US/trade/spot/SAIL/USDT>" %}

### [Gate.io](https://www.gate.io/)

<figure><img src="/files/o35ynoHf2MIe3zyHbHxG" alt="" width="352"><figcaption></figcaption></figure>

{% embed url="<https://www.gate.io/trade/SAIL_USDT>" %}

<figure><img src="/files/7vsEW62ngUd4qSvQQ6P4" alt=""><figcaption></figcaption></figure>

{% embed url="<https://www.bitgo.com/>" %}


# Audits

Clipper has been audited by [Quantstamp](https://quantstamp.com/) and [Solidified](https://www.solidified.io/), in addition to a 3-week bug bounty hosted by [ImmuneFi](https://immunefi.com/). New deploys are internally and externally audited, and reports are commissioned depending on complexity.

## Quantstamp Audit

{% file src="/files/-MeQQbEsv7rRnS9IUpNp" %}

## Solidified Audit

{% file src="/files/W02aFCYQ3pR8MUV5JHOo" %}

{% file src="/files/qXAbwbzkbKaV8HKqeQu8" %}

{% file src="/files/-MeRSMu1QaF-AvqWDc01" %}


# Smart Contracts

#### SAIL & Clipper Contracts

* **Ethereum**
  * **SAIL Contract:** [0xd8F1460044925d2D5c723C7054cd9247027415B7](https://etherscan.io/token/0xd8F1460044925d2D5c723C7054cd9247027415B7)
  * **Pool Contract:** [0x655edce464cc797526600a462a8154650eee4b77](https://etherscan.io/address/0x655edce464cc797526600a462a8154650eee4b77)
  * **Farming Contract:** [0xD0454428ecd868A9AC615125FCbDB5Da9027436e](https://etherscan.io/address/0xD0454428ecd868A9AC615125FCbDB5Da9027436e)
  * **Farming Helper:** [0x6e3FB8a019E78785E80cea1d413Bc3Ab650c2449](https://etherscan.io/address/0x6e3fb8a019e78785e80cea1d413bc3ab650c2449)
  * **veSAIL Contract:** [0x26fE2f89a1FEf1bC90b8a89D8AD18a1891166ff5](https://etherscan.io/address/0x26fE2f89a1FEf1bC90b8a89D8AD18a1891166ff5)
* **Optimism**
  * **SAIL Contract:** [0x7a1263eC3Bf0a19e25C553B8A2C312e903262C5E](https://optimistic.etherscan.io/token/0x7a1263eC3Bf0a19e25C553B8A2C312e903262C5E)
  * **Pool Contract:** [0x5130f6ce257b8f9bf7fac0a0b519bd588120ed40](https://optimistic.etherscan.io/address/0x5130f6ce257b8f9bf7fac0a0b519bd588120ed40)
  * **Farming Contract:** [0xAc2B3f9a13E7273639bcDCa55742391CDACC74cB](https://optimistic.etherscan.io/address/0xAc2B3f9a13E7273639bcDCa55742391CDACC74cB)
* **Arbitrum**&#x20;
  * **SAIL Contract:** [0xb52BD62eE0Cf462Fa9CCbDA4bf27Fe84D9ab6Cf7](https://arbiscan.io/token/0xb52BD62eE0Cf462Fa9CCbDA4bf27Fe84D9ab6Cf7)
  * **Pool Contract:** [0x769728b5298445ba2828c0f3f5384227fbf590c5](https://arbiscan.io/address/0x769728b5298445ba2828c0f3f5384227fbf590c5)
* **Polygon PoS**
  * **SAIL Contract:** [0xd1a718f77ab5d22e3955050658d7f65ae857a85e](https://polygonscan.com/token/0xd1a718f77ab5d22e3955050658d7f65ae857a85e)
  * **Pool Contract:** [0x6bfce69d1df30fd2b2c8e478edec9daa643ae3b8](https://polygonscan.com/address/0x6bfce69d1df30fd2b2c8e478edec9daa643ae3b8)
  * **vefxSAIL Contract:**\
    [0x8E44D33d980E9e6f23370600173B22ca1815a7Ad](https://polygonscan.com/address/0x8E44D33d980E9e6f23370600173B22ca1815a7Ad)
* **Mantle Network**&#x20;
  * **Pool Contract:** [0x769728b5298445BA2828c0f3F5384227fbF590C5](https://explorer.mantle.xyz/address/0x769728b5298445BA2828c0f3F5384227fbF590C5)
* **Base**&#x20;
  * **Pool Contract:** [0xb32D856cAd3D2EF07C94867A800035E37241247C](https://basescan.org/address/0xb32d856cad3d2ef07c94867a800035e37241247c#events)&#x20;
* **Polygon** **zkEVM**
  * **Pool Contract:** [0xAe00af61bE6861eE956C8e56BF22144d024acb57](https://zkevm.polygonscan.com/address/0xAe00af61bE6861eE956C8e56BF22144d024acb57)

**Clipper LP Token Contracts**

* **Ethereum:** [0x655eDCE464CC797526600a462A8154650EEe4B77](https://etherscan.io/token/0x655edce464cc797526600a462a8154650eee4b77)
* **Optimism:** [0x5130f6cE257B8F9bF7fac0A0b519Bd588120ed40](https://optimistic.etherscan.io/token/0x5130f6ce257b8f9bf7fac0a0b519bd588120ed40)
* **Arbitrum:** [0x769728b5298445BA2828c0f3F5384227fbF590C5](https://arbiscan.io/token/0x769728b5298445ba2828c0f3f5384227fbf590c5)
* **Polygon PoS:** [0x6Bfce69d1Df30FD2B2C8e478EDEC9dAa643Ae3B8](https://polygonscan.com/token/0x6bfce69d1df30fd2b2c8e478edec9daa643ae3b8)
* **Mantle Network:** [0x769728b5298445BA2828c0f3F5384227fbF590C5](https://explorer.mantle.xyz/token/0x769728b5298445BA2828c0f3F5384227fbF590C5/token-transfers)
* **Base:** [0xb32D856cAd3D2EF07C94867A800035E37241247C](https://basescan.org/token/0xb32d856cad3d2ef07c94867a800035e37241247c)
* **Polygon zkEVM:** [0xAe00af61bE6861eE956C8e56BF22144d024acb57](https://zkevm.polygonscan.com/address/0xAe00af61bE6861eE956C8e56BF22144d024acb57)

#### Ethereum Auxiliary Addresses&#x20;

* Transfer Helper (for deposits, permits, and transfers of legacy CLPRDRPL): 0x6e3FB8a019E78785E80cea1d413Bc3Ab650c2449
* Protocol Deposit: 0x84f4625C3E92b368E403cB002A9bF9bc7a9ae1b9

#### Legacy Addresses

* Clipper FMM v2: 0xE7b0CE0526fbE3969035a145C9e9691d4d9D216c
* Clipper FMM v1: 0xcc12532e95c2a6a4c53af153b9b739a3cc9218a7
* Exchange Contract: 0x2e9c6Dcdca22A5952A88C4b18EDB5B54C5155BC9
* Pool Contract: 0xe82906b6B1B04f631D126c974Af57a3A7B6a99d9
* Router Contract: 0xf0f455E8b8F4f96Ae5109493C5d3eA5e2c09de47
* Polygon PoS: 0xD01e3549160c62Acabc4D0EB89F67aAFA3de8EEd
* Optimism: \*\*\*\*0xDBD4ffC32b34f630DD8aC18D37162eC8462db7dB
* Moonbeam: 0xe90d415Af331237Ae18a882EC21870f1965BE933
* Polygon zkEVM Pool Contrac&#x74;**:** 0xe38C90a0233F18749Fb74e595c4De871e5498C13


# Subgraph

Clipper has a GraphQL API Endpoint hosted by [The Graph](https://thegraph.com/docs/about/introduction#what-the-graph-is) called a subgraph. The subgraph is for indexing and organizing data from Clipper's smart contracts and can be used to query Clipper data.

Subgraph information is serviced by a decentralized group of server operators called Indexers.

### Get Started

Learn more about how subgraphs work by checking out [The Graph's official documentation](https://thegraph.com/docs/en/). If you are unfamiliar with GraphQL, we recommend first taking a quick look at their documentation [here](https://graphql.org/learn/).

### Ethereum

* [Explorer Page](https://thegraph.com/explorer/subgraphs/AcoumtPXDDyoqHSuc9y51mgGS7DSze4XyF83RG7Db3R5?view=Overview)
* Graphql Endpoint: <https://api.thegraph.com/subgraphs/name/edoapp/clipper>
* [Code Repo](https://github.com/shipyard-software/clipper-rfq-subgraph)

### Optimism

* [Explorer Page](https://thegraph.com/hosted-service/subgraph/edoapp/clipper-optimism)
* Graphql Endpoint: <https://api.thegraph.com/subgraphs/name/edoapp/clipper-optimism>
* [Code Repo](https://github.com/shipyard-software/clipper-rfq-subgraph)

### Polygon

* [Explorer Page](https://thegraph.com/hosted-service/subgraph/edoapp/clipper-polygon)
* Graphql Endpoint: <https://api.thegraph.com/subgraphs/name/edoapp/clipper-polygon>
* [Code Repo](https://github.com/shipyard-software/clipper-rfq-subgraph)

### Arbitrum

* [Explorer Page](https://api.thegraph.com/subgraphs/name/edoapp/clipper-arbitrum)
* Graphql Endpoint: <https://api.thegraph.com/subgraphs/name/edoapp/clipper-arbitrum>
* [Code Repo](https://github.com/shipyard-software/clipper-rfq-subgraph)

### Helpful Resources

* [Video Tutorial on creating an API Key](https://www.youtube.com/watch?v=UrfIpm-Vlgs)
* [Managing your API Key & setting your indexer preferences](https://thegraph.com/docs/en/studio/managing-api-keys/)
* [Querying from an application](https://thegraph.com/docs/en/developer/querying-from-your-app/)
* [How to use the explorer and playground to query on-chain data](https://medium.com/@chidubem_/how-to-query-on-chain-data-with-the-graph-f8507488215)
* [Deploy your own Subgraph](https://thegraph.com/docs/en/developing/creating-a-subgraph/)


# Entities

* [`Pool`](#pool)
* [`DailyPoolStatus`](#dailypoolstatus)
* [`HourlyPoolStatus`](#hourlypoolstatus)
* [`Token`](#token)
* [`Swap`](#swap)
* [`Pair`](#pair)
* [`TransactionSource`](#transactionsource)
* [`User`](#user)
* [`Deposit`](#deposit)
* [`CoveDeposit`](#covedeposit)
* [`Withdrawal`](#withdrawal)
* [`CoveWithdrawal`](#covewithdrawal)
* [`AllCoveStatus`](#allcovestatus)
* [`AllCoveHistoricStatus`](#allcovehistoricstatus)
* [`Cove`](#cove)
* [`HistoricCoveStatus`](#historiccovestatus)
* [`UserCoveStake`](#usercovestake)

## Pool

Description: get specific details of the pool

| Field            | Type                                                                            | Description                                                                         |
| ---------------- | ------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
| id               | ID!                                                                             | pool address                                                                        |
| volumeUSD        | BigDecimal!                                                                     | all time USD swapped                                                                |
| avgTrade         | BigDecimal!                                                                     | Average trade amount of all time in USD                                             |
| txCount          | BigInt!                                                                         | all time number of transactions                                                     |
| feeUSD           | BigDecimal!                                                                     | all time fee collected in USD                                                       |
| avgTradeFee      | BigDecimal                                                                      | Average trade fee of all time in USD                                                |
| avgFeeInBps      | BigDecimal!                                                                     | average fee in basis points                                                         |
| depositCount     | BigInt!                                                                         | all time deposits count                                                             |
| avgDeposit       | BigDecimal!                                                                     | Average deposit amount of all time in USD                                           |
| depositedUSD     | BigDecimal!                                                                     | all time deposited amount in USD                                                    |
| withdrawalCount  | BigInt!                                                                         | all time withdrawals count                                                          |
| avgWithdraw      | BigDecimal!                                                                     | Average withdrawal amount of all time in USD                                        |
| withdrewUSD      | BigDecimal!                                                                     | all time withdrew amount in USD                                                     |
| uniqueUsers      | BigInt!                                                                         | number of all time unique users                                                     |
| poolTokensSupply | BigInt!                                                                         | number of pool tokens supplied by the smart contract (used for time-travel queries) |
| dailyHistory     | [DailyPoolStatus](#dailypoolstatus) !                                           | time snapshots of pool data                                                         |
| hourlyHistory    | [HourlyPoolStatus](#hourlypoolstatus)[`!`](broken://pages/AL8hGKNw8b89VFkpbRLu) | time snapshots of pool data                                                         |

## DailyPoolStatus

Description: get specific details of the daily pool status

| Field            | Type        | Description                                                      |
| ---------------- | ----------- | ---------------------------------------------------------------- |
| id               | ID!         | {pool address}-{fromTimestamp}-{toTimestamp}                     |
| from             | BigInt!     | assets pool changed from                                         |
| to               | BigInt!     | assets pool changed to                                           |
| pool             | Pool!       | pointer to the pool                                              |
| poolTokensSupply | BigInt!     | snapshot of number of pool tokens supplied by the smart contract |
| txCount          | BigInt!     | number of transactions during period                             |
| volumeUSD        | BigDecimal! | volume in USD                                                    |
| avgTrade         | BigDecimal! | Average trade amount in USD                                      |
| feeUSD           | BigDecimal! | fee collected in USD                                             |
| avgTradeFee      | BigDecimal  | Average trade fee in USD                                         |
| avgFeeInBps      | BigDecimal! | average fee in basis points                                      |
| depositCount     | BigInt!     | number of deposits during daily period                           |
| depositedUSD     | BigDecimal! | deposited amount during daily period                             |
| avgDeposit       | BigDecimal! | Average deposited amount of USD during daily period              |
| withdrawalCount  | BigInt!     | number of withdrawals during daily period                        |
| withdrewUSD      | BigDecimal! | withdrew amount during daily period                              |
| avgWithdraw      | BigDecimal! | Average withdrawal amount of USD during daily period             |
| poolValue        | BigDecimal! | # pool liquidity value at the beginning of the day               |

## HourlyPoolStatus

Description: get specific details of the hourly pool status

| Field           | Type        | Description                                           |
| --------------- | ----------- | ----------------------------------------------------- |
| id              | ID!         | {pool address}-{fromTimestamp}-{toTimestamp}          |
| from            | BigInt!     | assets pool changed from                              |
| to              | BigInt!     | assets pool changed to                                |
| pool            | Pool!       | pointer to the pool                                   |
| txCount         | BigInt!     | number of transactions during daily period            |
| volumeUSD       | BigDecimal! | volume in USD                                         |
| avgTrade        | BigDecimal! | Average trade amount of USD during hourly period      |
| feeUSD          | BigDecimal! | fee collected in USD                                  |
| avgTradeFee     | BigDecimal  | Average trade fee in USD                              |
| avgFeeInBps     | BigDecimal! | average fee in basis points                           |
| depositCount    | BigInt!     | number of deposits during hourly period               |
| depositedUSD    | BigDecimal! | deposited amount during hourly period                 |
| avgDeposit      | BigDecimal! | Average deposited amount of USD during hourly period  |
| withdrawalCount | BigInt!     | number of withdrawals during hourly period            |
| withdrewUSD     | BigDecimal! | withdrew amount during hourly period                  |
| avgWithdraw     | BigDecimal! | Average withdrawal amount of USD during hourly period |

## Token

Description: get specific details of the token

| Field        | Type        | Description                                            |
| ------------ | ----------- | ------------------------------------------------------ |
| id           | ID!         | token address                                          |
| symbol       | String!     | token symbol                                           |
| name         | String!     | token name                                             |
| decimals     | BigInt!     | token decimals                                         |
| txCount      | BigInt!     | transactions across all pools that include this token  |
| volume       | BigDecimal! | volume in token units                                  |
| volumeUSD    | BigDecimal! | volume in derived USD                                  |
| tvl          | BigDecimal! | total value locked in pool (supports additional pools) |
| tvlUSD       | BigDecimal! | total value locked from derived usd                    |
| deposited    | BigDecimal! | total amount deposited in pool                         |
| depositedUSD | BigDecimal! | total amount in USD deposited in pool                  |
| type         | TokenType   | type of token (longtail or shorttail)                  |
| cove         | Cove        | if type is longtail, cove should be set                |

## Swap

Description: get specific details of the swap

| Field               | Type               | Description                                |
| ------------------- | ------------------ | ------------------------------------------ |
| id                  | ID!                | transaction hash + "-" + event log index   |
| pool                | Pool               | pointer to the pool                        |
| transaction         | Bytes!             | pointer to transaction                     |
| timestamp           | BigInt!            | timestamp of transaction                   |
| inToken             | Token!             | allow indexing by tokens                   |
| outToken            | Token!             | allow indexing by tokens                   |
| sender              | User!              | sender of the swap                         |
| recipient           | Bytes!             | recipient of the swap                      |
| origin              | Bytes!             | the EOA that initiated the txn# txn origin |
| amountIn            | BigDecimal!        | delta of inAsset swapped                   |
| amountOut           | BigDecimal!        | delta of outAsset swapped                  |
| amountInUSD         | BigDecimal!        | derived info                               |
| amountOutUSD        | BigDecimal!        | derived info                               |
| feeUSD              | BigDecimal!        | fee of swap in USD                         |
| pricePerInputToken  | BigDecimal!        | price of token swapped                     |
| pricePerOutputToken | BigDecimal!        | price of toeken received                   |
| transactionSource   | TransactionSource! | origin of the transaction                  |
| logIndex            | BigInt             | order within the txn                       |
| pair                | Pair               | pair traded (not required for cove swaps)  |
| swapType            | SwapType           | cove asset or core asset                   |
| cove                | Cove               | if type is longtail, cove should be set    |

## Pair

Description: get specific details of the Pair

| Field     | Type                                                    | Description                            |
| --------- | ------------------------------------------------------- | -------------------------------------- |
| id        | ID!                                                     | asset 1 + asset 2 address              |
| asset0    | Token!                                                  | asset 0 of the pair                    |
| asset1    | Token!                                                  | asset 1 of the pair                    |
| txCount   | BigInt!                                                 | all time transaction on this pair      |
| volumeUSD | BigDecimal!                                             | volume of all time transactions in USD |
| swaps     | [Swap](#swap)[`!`](broken://pages/AL8hGKNw8b89VFkpbRLu) | swaps data                             |

## TransactionSource

Description: get specific details of the transaction source

| Field   | Type                                                    | Description                               |
| ------- | ------------------------------------------------------- | ----------------------------------------- |
| id      | ID!                                                     | origin name                               |
| txCount | BigInt!                                                 | number of all time transactions by source |
| swaps   | [Swap](#swap)[`!`](broken://pages/AL8hGKNw8b89VFkpbRLu) | derived swaps                             |

## User

Description: get specific details of the user

| Field            | Type                                                    | Description                             |
| ---------------- | ------------------------------------------------------- | --------------------------------------- |
| id               | ID!                                                     | wallet address                          |
| txCount          | BigInt!                                                 | number of all time transactions by user |
| firstTxTimestamp | BigInt!                                                 | timestamp of first transaction          |
| lastTxTimestamp  | BigInt!                                                 | timestamp of last transaction           |
| volumeUSD        | BigDecimal!                                             | total volume trade by user              |
| swaps            | [Swap](#swap)[`!`](broken://pages/AL8hGKNw8b89VFkpbRLu) | list of trades made by the user         |

## Deposit

Description: get specific details of the deposit

| Field      | Type        | Description                                                          |
| ---------- | ----------- | -------------------------------------------------------------------- |
| id         | ID!         | transaction hash                                                     |
| timestamp  | BigInt!     | timestamp of transaction                                             |
| pool       | Pool!       | pool deposited to                                                    |
| poolTokens | BigDecimal! | pool tokens received by the deposit                                  |
| amountUsd  | BigDecimal! | The equivalent usd value of received pool tokens at the moment of tx |
| depositor  | Bytes!      | sender of the transaction                                            |

## CoveDeposit

Description: get specific details of the cove deposit

| Field     | Type        | Description                                                   |
| --------- | ----------- | ------------------------------------------------------------- |
| id        | ID!         | transaction hash                                              |
| timestamp | BigInt!     | time stamp of deposit                                         |
| cove      | Cove!       | coves are made up of separate user-generating liquidity pools |
| amountUsd | BigDecimal! | captured usd value at the moment of transaction               |
| depositor | Bytes!      | address of depositor                                          |

## Withdrawal

Description: get specific details of the withdrawal

| Field      | Type        | Description                                     |
| ---------- | ----------- | ----------------------------------------------- |
| id         | ID!         | transaction hash                                |
| timestamp  | BigInt!     | timestamp of withdrawal                         |
| pool       | Pool!       | pool to where the whitdrawal was done           |
| poolTokens | BigDecimal! | Pool tokens burned to withdraw                  |
| amountUsd  | BigDecimal! | captured usd value at the moment of transaction |
| withdrawer | Bytes!      | withdrawer of the transaction                   |

## CoveWithdrawal

Description: get specific details of the cove withdrawal

| Field      | Type        | Description                                                   |
| ---------- | ----------- | ------------------------------------------------------------- |
| id         | ID!         | transaction hash                                              |
| timestamp  | BigInt!     | timestamp of withdrawal                                       |
| cove       | Cove!       | coves are made up of separate user-generating liquidity pools |
| amountUsd  | BigDecimal! | captured usd value at the moment of transaction               |
| withdrawer | Bytes!      | withdrawer of the transaction                                 |

## AllCoveStatus

Description: get specific details of all cove status

| Field           | Type        | Description                            |
| --------------- | ----------- | -------------------------------------- |
| id              | ID!         | Id of smart contract                   |
| volumeUSD       | BigDecimal! | volume of all time transactions in USD |
| txCount         | Int!        | total transactons of coves             |
| depositCount    | Int!        | total deposits of coves                |
| withdrawalCount | Int!        | total withdrawal of coves              |

## AllCoveHistoricStatus

Description: get specific details of all cove historic status

| Field           | Type                | Description                |
| --------------- | ------------------- | -------------------------- |
| id              | ID!                 | Id of smart contract       |
| from            | BigInt!             | assets pool changed from   |
| to              | BigInt!             | assets pool changed to     |
| volumeUSD       | BigDecimal!         | historic volume            |
| txCount         | Int!                | historic transaction count |
| depositCount    | Int!                | historic deposit count     |
| withdrawalCount | Int!                | historic withdrawal count  |
| statusType      | StatusHistoricType! | historic status            |

## Cove

Description: get specific details of cove

| Field               | Type        | Description                                                 |
| ------------------- | ----------- | ----------------------------------------------------------- |
| id                  | ID!         | cove token address                                          |
| longtailAsset       | Token!      | pointer to CoveAsset                                        |
| coveAssetName       | String!     | duplicate of longtailAsset for easy filtering               |
| coveAssetSymbol     | String!     | the asset symbol of cove                                    |
| volumeUSD           | BigDecimal! | all time USD swapped                                        |
| swapCount           | BigInt!     | all time number of swaps using this cove                    |
| poolTokenAmount     | BigDecimal! | tvl of pool token and long tail currently held by the cove. |
| longtailTokenAmount | BigDecimal! | tvl of longtail tokens                                      |
| tvlUSD              | BigDecimal! | poolTokenAmount times the price of pool token times two     |
| createdAt           | BigInt!     | timestamp to when the cove was opened                       |
| transaction         | Bytes!      | transaction that initialized the cove.                      |
| depositCount        | BigInt!     | all time deposits count                                     |
| withdrawalCount     | BigInt!     | all time withdrawals count                                  |

## HistoricCoveStatus

Description: get specific details of historic cove status

| Field           | Type                | Description                                                   |
| --------------- | ------------------- | ------------------------------------------------------------- |
| id              | ID!                 | {coveId}-{fromTimestamp}-{toTimestamp}                        |
| cove            | Cove!               | coves are made up of separate user-generating liquidity pools |
| from            | BigInt!             | assets pool changed from                                      |
| to              | BigInt!             | assets pool changed to                                        |
| volumeUSD       | BigDecimal!         | historic valume in USD                                        |
| price           | BigDecimal!         | historic price                                                |
| txCount         | Int!                | historic transaction count                                    |
| depositCount    | Int!                | historic deposit count                                        |
| withdrawalCount | Int!                | historic withdrawal count                                     |
| statusType      | StatusHistoricType! | historic status                                               |

## UserCoveStake

Description: get specific details of user cove stake

| Field         | Type     | Description               |
| ------------- | -------- | ------------------------- |
| id            | ID!      | {coveId}-{wallet}         |
| cove          | Cove!    | cove user transacted with |
| user          | Bytes!   | address of user           |
| depositTokens | BigInt!  | user deposited tokens     |
| active        | Boolean! | active status of user     |


# Queries

Below are some sample queries you can use to gather information from the Clipper contracts.

You can build your own queries using a [GraphQL Explorer](https://graphiql-online.com/graphiql) and enter your endpoint to limit the data to exactly what you need.

## Get Swaps

```graphql
{
  swaps {
    id
    inToken {
      name
      symbol
    }
    outToken {
      name
      symbol
    }
    transaction {
      id
    }
    amountIn
    amountOut
    origin
    sender {
      id
    }
    timestamp
    transactionSource {
      id
    }
  }
}
```

## Get Deposits to Clipper pool

```graphql
{
  deposits(orderBy: timestamp, orderDirection: desc) {
    amount
    usdValue
    token {
      symbol
    }
    amount
  }
}
```

## Get txs by pair

```graphql
{
  pairs {
    txCount
    asset0 {
      symbol
    }
    asset1 {
      symbol
    }
  }
}
```

## Swap Count

```graphql
{
  pools {
    id
    txCount
  }
}
```


# Integrating with Clipper RFQ


# Introduction

## How does it work?

Clipper has a hybrid onchain/offchain infrastructure. We expose an API to you with price feeds and a k-parameter, and give you the formula that we use to quote prices based on those + onchain data. That way you can route based on predictions of what Clipper will quote. Once you’re ready to use Clipper in a route you request a quote from our servers. Output scales with input so you can compose in multihop trades.

{% hint style="success" %}
**Clipper prioritizes protecting LP yield and restricts toxic bot flow.** Clipper values real users. To  prevent toxic flow Clipper verifies wallets. Specifically it makes a verification on the wallets used for  swaps and checks whether they are EOA (not contracts), have a min amount of ETH, and have done previous txs.
{% endhint %}

## RFQ Swap API <a href="#supported-networks" id="supported-networks"></a>

<figure><img src="/files/cBTsEgtrLWBdfGSmFil0" alt=""><figcaption></figcaption></figure>

1. Client retrieves pool information
2. Client inputs pool information (price feeds, k factor, etc) in the formula to predict quotes.
3. Client retrieves a firm quote from API
4. Client creates a swap transaction in the clipper pool contract using values from previous step.

For more details about integration check [How to use clipper RFQ API?](/disclaimers-and-technical/integrating-with-clipper-rfq/guides/how-to-use-clipper-rfq-api)

## Supported Networks <a href="#supported-networks" id="supported-networks"></a>

<table><thead><tr><th width="226">Network</th><th>Chain ID</th></tr></thead><tbody><tr><td>Ethereum Mainnet</td><td>1</td></tr><tr><td>Polygon Mainnet</td><td>137</td></tr><tr><td>Optimism Mainnet</td><td>10</td></tr><tr><td>Mantle Mainnet</td><td>5000</td></tr><tr><td>Arbitrum One</td><td>42161</td></tr></tbody></table>

{% hint style="info" %}
If you want to review our contracts for each supported network, please refer to this [link](/disclaimers-and-technical/smart-contracts)
{% endhint %}

## Get Started

[How to use Clipper API?](/disclaimers-and-technical/integrating-with-clipper-rfq/guides/how-to-use-clipper-rfq-api)

[Code Examples](/disclaimers-and-technical/integrating-with-clipper-rfq/guides/integration-examples)

[Estimate Clipper Prices](/disclaimers-and-technical/integrating-with-clipper-rfq/guides/estimate-clipper-prices)

[Interacting with Clipper Exchange](/disclaimers-and-technical/integrating-with-clipper-rfq/guides/interacting-with-the-clipper-exchange-contracts)

[API Reference](/disclaimers-and-technical/integrating-with-clipper-rfq/api-reference/api-v1/overview)

[Troubleshooting](/disclaimers-and-technical/integrating-with-clipper-rfq/troubleshooting-and-faqs)

To see who else has integrated with Clipper, checkout the data page: <https://clipper.exchange/data>


# Guides

You will find some practical examples of how to integrate with the API and the pool contracts.


# How to use clipper RFQ API?

Clipper's Formula Market Maker (FMM) is implemented similar to a typical Request For Quotes (RFQ) system. In an [RFQ architecture](/disclaimers-and-technical/integrating-with-clipper-rfq/introduction#supported-networks), you first ask our offchain server to quote a transaction price, specifying the buy and sell tokens and either a target input or output amount. You then have a short amount of time to accept that quote, and receive back a signed certificate from our offchain server. Then, you must pass that transaction and signed certificate to our onchain smart contracts to execute the swap.

Clipper supports a “send, then swap" modality and is designed to be as simple as possible to chain within a larger set of transactions, or to automate trading with bots.

{% hint style="warning" %}
It's essential to obtain the credentials in order to proceed with the guide for API usage. Please reach out to us to acquire the necessary credentials for API access, please refer to the [Authorization](/disclaimers-and-technical/integrating-with-clipper-rfq/api-reference/api-v2/overview) section to know details.
{% endhint %}

{% hint style="info" %}
You can see the supported networks [here](/disclaimers-and-technical/integrating-with-clipper-rfq/introduction#supported-networks)
{% endhint %}

1. Get exchange address and asset information.

```javascript
const fetch = require('node-fetch');

const chainId = 137;  // You can use a different network. Look for our supported networks
const fieldset = 'offchain-data';
const authorizationHeader = 'YXBpLXVzZXI6dXNlci1wYXNz';  // This is a placeholder 

const requestOptions = {
  method: 'GET',
  headers: {
    'x-api-key': authorizationHeader,
    'Content-Type': 'application/json'
  }
};

const response = await fetch(`https://blade-api.sushi.com/rfq/v2/pool/${chainId}?fieldset=${fieldset}`, requestOptions);
const data = await response.json();
console.log(data);
```

The API response will look like the following (some fields omitted):

```javascript
{
  "pool_type": "offchain",
  "pools": [
    {
      "pool": {
        "chain_id": 1,
        "address": "0x655eDCE464CC797526600a462A8154650EEe4B77",
        "num_assets": 4,
        "k": 0.06,
        "time_in_seconds": 60,
        "default_time_in_seconds": 60,
        "swaps_enabled": true
      },
      "assets": [
        {
          "name": "ETH",
          "address": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
          "price_in_usd": 2076.799,
          "listing_weight": 79
        },
        {
          "name": "USDC",
          "address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
          "price_in_usd": 1,
          "listing_weight": 188
        },
        {
          "name": "USDT",
          "address": "0xdAC17F958D2ee523a2206206994597C13D831ec7",
          "price_in_usd": 1,
          "listing_weight": 305
        },
        {
          "name": "DAI",
          "address": "0x6B175474E89094C44Da98b954EedeAC495271d0F",
          "price_in_usd": 1,
          "listing_weight": 250
        }
      ],
      "pairs": [
        {
          "assets": [
            "ETH",
            "USDC"
          ],
          "fee_in_basis_points": 9
        },
        {
          "assets": [
            "ETH",
            "USDT"
          ],
          "fee_in_basis_points": 9
        },
        {
          "assets": [
            "ETH",
            "DAI"
          ],
          "fee_in_basis_points": 8
        },
        {
          "assets": [
            "USDC",
            "USDT"
          ],
          "fee_in_basis_points": 5
        },
        {
          "assets": [
            "USDC",
            "DAI"
          ],
          "fee_in_basis_points": 5
        },
        {
          "assets": [
            "USDT",
            "DAI"
          ],
          "fee_in_basis_points": 5
        }
      ]
    }
  ]
}
```

> 💡 You can include the query param <mark style="color:red;">`time_in_seconds`</mark> to the GET call if you intend to get quotes for values other than the default\_time\_in\_seconds for a chain. As you lower the time you will see lower fees (and therefore better prices).&#x20;
>
> 💡 You can include the <mark style="color:red;">`pool_address`</mark> query parameter; if it’s not provided, multiple pools can be returned per chain.
>
> 💡 To obtain more details about the endpoint, its parameters, and the response, please refer to the API Reference in the [pool](/disclaimers-and-technical/integrating-with-clipper-rfq/api-reference/api-v2/pool-v2) section.

{% hint style="warning" %}
You should estimate clipper prices using the offchain state information for better performance. Review the section [Estimate Clipper Prices](/disclaimers-and-technical/integrating-with-clipper-rfq/guides/estimate-clipper-prices) to know more about it.
{% endhint %}

2. Request a quote

```javascript
const fetch = require('node-fetch');

const params = {
  pool_address: '0x655eDCE464CC797526600a462A8154650EEe4B77', // Should be set to the appropriate pool address 
  output_asset_symbol: 'USDC',
  input_asset_symbol: 'DAI',
  input_amount: '2000000000000000000', // XOR: output_amount: '2000000000000000000'
  time_in_seconds: 30. // A good suggestion for Polygon is 30 seconds. As this value increases, the quote will get worse for the user.
};
const queryString = new URLSearchParams(params).toString();
const authorizationHeader = 'YXBpLXVzZXI6dXNlci1wYXNz';  // This is a placeholder 

const requestOptions = {
  method: 'GET',
  headers: {
    'x-api-key': authorizationHeader,
    'Content-Type': 'application/json'
  },
};

const response = await fetch('https://blade-api.sushi.com/rfq/v2/quote/{CHAIN_ID}?${queryString}');
const data = await response.json();
console.log(data);

```

{% hint style="warning" %} <mark style="color:orange;">`input_asset_symbol`</mark> and <mark style="color:orange;">`output_asset_symbol`</mark> should correspond to the asset name returned from the <mark style="color:orange;">`/rfq/v2/pool`</mark>  call in the step 1.&#x20;
{% endhint %}

The API response will look like the following (some fields omitted):

```json
{
    "id": "320d255f-5864-4245-927c-fa4951121ee8",
    "must_accept_by": "2023-09-01 18:10:36.629117+00:00",
    "good_until": 1693591896,
    "chain_id": 137,
    "input_amount": "2000000000000000000",
    "output_amount": "2000000",
    "input_value_in_usd": 2.0,
    "output_value_in_usd": 2.0,
    "rate": 1.0,
    "input_asset_address": "0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063",
    "output_asset_address": "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174"
}
```

{% hint style="warning" %}
For assets like <mark style="color:orange;">`ETH`</mark> and <mark style="color:orange;">`MATIC`</mark> Clipper exchange uses the wrapped version of these assets, a distinction made clear and unambiguous by the inclusion of the contract addresses in the response.
{% endhint %}

> 💡 To obtain more details about the endpoint, its parameters, and the response, please refer to the API Reference in the [quote](/disclaimers-and-technical/integrating-with-clipper-rfq/api-reference/api-v2/quote-v2) section.

3. Sign the quote

{% hint style="warning" %}
Only members of the Clipper Community and DEX aggregator partners can get their quotes signed. If you're building a DEX aggregator, please reach out to the team on [Discord](https://discord.gg/FYwjZBmQ) for access (MNDA required).
{% endhint %}

{% hint style="warning" %}
Our quotes are firm. If a signed order make it onchain by the <mark style="color:orange;">`good_until`</mark> time it will generally be honored as explicitly written. Note that, on some chains, if other orders frontrun the signed quote it may be rejected - this is a security precaution to prevent sybil attacks.
{% endhint %}

```javascript
const fetch = require('node-fetch');

const params = {
  quote_id: "590d7956-c7cc-45da-83ed-23f6901f74e9",  // id we get get in first step
  destination_address: "0x5901920A7b8cb1Bba39220FAC138Ffb3800dD212",  // it will receive the output token
  sender_address: "0x5901920A7b8cb1Bba39220FAC138Ffb3800dD212". // Optional: it is for DEX aggregator partners that are using their own smart contract
};

const authorizationHeader = 'YXBpLXVzZXI6dXNlci1wYXNz';  // This is a placeholder

const requestOptions = {
  method: 'POST',
  headers: {
    'x-api-key': authorizationHeader,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(params)
};

const response = await fetch('https://blade-api.sushi.com/rfq/sign', requestOptions);
const data = await response.json();
console.log(data);

```

The API response will look like the following:

```json
{
    "chain_id": 137,
    "input_asset_address": "0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063",
    "output_asset_address": "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174",
    "input_amount": "2000000000000000000",
    "output_amount": "2000000",
    "good_until": "627710173538668076417607179014705162363943960351250641945575434764",
    "destination_address": "0xab83Af831dfb4028EBFd3fFA74A828a4d5DCaAC5",
    "signature": {
        "v": 28,
        "r": "0x8a866d67003c32bf9b4bd40f6abf1fe939a288ad2199f967c108d4e73ecb6916",
        "s": "0x4c9b1219a35139c5f7ce58452fb3d3c8fdff27c7dd3af055fbbdfd30ef0a0a20"
    },
    "clipper_exchange_address": "0x6Bfce69d1Df30FD2B2C8e478EDEC9dAa643Ae3B8"
}
```

{% hint style="info" %}
If you want to get the bytes representation of the swap to be sent directly to the pool contract you can review our [calldata swap feature](/disclaimers-and-technical/integrating-with-clipper-rfq/api-reference/api-v1/sign#with-calldata)
{% endhint %}

> 💡 To obtain more details about the endpoint, its parameters, and the response, please refer to the API Reference in the [sign](/disclaimers-and-technical/integrating-with-clipper-rfq/api-reference/api-v1/sign) section

4. Send the transaction

**Using ether.js**

{% file src="/files/aQLi0qsgSmlfob5AeYIa" %}

```javascript
import ethers from "ethers";
import exchangeAbi from "./exchangeAbi.json";

async function executeSwap(signResponse) {
  const provider = new ethers.providers.JsonRpcProvider(process.env.RPC_URL);
  const exchangeContract = new ethers.Contract(
    signResponse.clipper_exchange_address,
    exchangeAbi,
    provider
  );
  // Any 32 bytes identifier
  const auxData = "0x00000000000000000000000000000000000000000000000000";

  const result = await exchangeContract.swap(
    signResponse.input_asset_address,
    signResponse.output_asset_address,
    signResponse.input_amount,
    signResponse.outputAmount,
    signRespose.good_until,
    signResponse.destination_address,
    [signResponse.signature.v, signResponse.signature.r, signResponse.signature.s],
    auxData
  )
```

> 💡 You can review the guide [Interacting with the Clipper Exchange](/disclaimers-and-technical/integrating-with-clipper-rfq) to know more ways of interact with Clipper. You can also review code examples in the section [Integration Examples](/disclaimers-and-technical/integrating-with-clipper-rfq/guides/integration-examples)

{% hint style="info" %}
You can find a complete swap flow example [here](/disclaimers-and-technical/integrating-with-clipper-rfq/guides/integration-examples/complete-swap-flow)
{% endhint %}


# Estimate Clipper Prices

In order to assist in integrating Clipper with DEX Aggregators & Resolvers, offchain state information that is used to calculate Clipper prices is made available in a read-only endpoint that can be queried frequently. This state information can then be used to accurately estimate Clipper price quotes when combined with onchain state information (pulled and maintained by the aggregators themselves).

{% hint style="success" %}
You can view code to see how to implement it, in our section [Complete Swap Flow](/disclaimers-and-technical/integrating-with-clipper-rfq/guides/integration-examples/complete-swap-flow)
{% endhint %}

## 1. Get pool data

Make a GET call to <mark style="color:orange;">`https://blade-api.sushi.com/rfq/v2/pool/{CHAIN_ID}?fieldset=offchain-data`</mark>

This endpoint returns a JSON blob that holds Clipper's offchain state information. Note that this response is modified from the standard response to the endpoint by removing *any* calls to the onchain contracts for response speed.

The API response will look like the following:&#x20;

```json
{
  "pool_type": "offchain",
  "pools": [
    {
      "pool": {
        "chain_id": 1,
        "address": "0x655eDCE464CC797526600a462A8154650EEe4B77",
        "num_assets": 4,
        "k": 0.06,
        "time_in_seconds": 60,
        "default_time_in_seconds": 60,
        "swaps_enabled": true
      },
      "assets": [
        {
          "name": "ETH",
          "address": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
          "price_in_usd": 2076.799,
          "listing_weight": 79
        },
        {
          "name": "USDC",
          "address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
          "price_in_usd": 1,
          "listing_weight": 188
        },
        {
          "name": "USDT",
          "address": "0xdAC17F958D2ee523a2206206994597C13D831ec7",
          "price_in_usd": 1,
          "listing_weight": 305
        },
        {
          "name": "DAI",
          "address": "0x6B175474E89094C44Da98b954EedeAC495271d0F",
          "price_in_usd": 1,
          "listing_weight": 250
        }
      ],
      "pairs": [
        {
          "assets": [
            "ETH",
            "USDC"
          ],
          "fee_in_basis_points": 9
        },
        {
          "assets": [
            "ETH",
            "USDT"
          ],
          "fee_in_basis_points": 9
        },
        {
          "assets": [
            "ETH",
            "DAI"
          ],
          "fee_in_basis_points": 8
        },
        {
          "assets": [
            "USDC",
            "USDT"
          ],
          "fee_in_basis_points": 5
        },
        {
          "assets": [
            "USDC",
            "DAI"
          ],
          "fee_in_basis_points": 5
        },
        {
          "assets": [
            "USDT",
            "DAI"
          ],
          "fee_in_basis_points": 5
        }
      ]
    }
  ]
}
```

> 💡 To obtain more details about the endpoint, its parameters, and the response, please refer to the API Reference in the [pool](/disclaimers-and-technical/integrating-with-clipper-rfq/api-reference/api-v2/pool-v2) section.

## 2. Estimate Clipper Prices using On- and Off- chain Data

1. Convert (using <mark style="color:orange;">`decimals`</mark>) the onchain balances of the Clipper Pool - the quantity vector <mark style="color:orange;">`q`</mark> - into human-readable terms (i.e., a balance of 100 ETH instead of 1e20 ETH.
2. Calculate the fee-adjustment multiplier for the swapping pair <mark style="color:orange;">`M = (10000-fee_in_basis_points)/10000`</mark> (10,000 = number of basis points in 100%).
3. Solve for a swap from asset X to asset Y through root-finding or a closed form solution. Let <mark style="color:orange;">`pX`</mark>, <mark style="color:orange;">`qX`</mark>, <mark style="color:orange;">`wX`</mark>, and <mark style="color:orange;">`inX`</mark> represent the current price, quantity, listing weight, and swap input of asset X, and similarly <mark style="color:orange;">`pY`</mark>, <mark style="color:orange;">`qY`</mark>, <mark style="color:orange;">`wY`</mark>, and <mark style="color:orange;">`outY`</mark> represent the current price, quantity, listing weight, and swap output of asset Y. Exactly one of <mark style="color:orange;">`inX`</mark> or <mark style="color:orange;">`outY`</mark> should be unknown. That unknown quantity is then found by solving an indifference pricing equation relating current utility from the assets X and Y to the utility from those assets after the swap:

$$
\frac{(pX \cdot {qX})^{1-k}}{{wX}^k} + \frac{(pY \cdot {qY})^{1-k}}{{wY}^k} \ = \ \frac{(pX \cdot ({qX + M\cdot{inX}}))^{1-k}}{{wX}^k} + \frac{(pY \cdot ({qY}-{outY}))^{1-k}}{{wY}^k}
$$

Checks should be done to ensure an intermediate solution to this equation before attempting to solve:

* If <mark style="color:orange;">`outY`</mark> is specified:
  * <mark style="color:orange;">`outY`</mark> should be no larger than <mark style="color:orange;">`qY`</mark>.
  * The LHS of the formula (current utility) should be larger than the RHS (utility after swap) evaluated at <mark style="color:orange;">`inX=0`</mark>
  * The LHS of the formula should be smaller than the RHS when evaluated at very large <mark style="color:orange;">`inX`</mark>
* If <mark style="color:orange;">`inX`</mark> is specified:
  * The LHS of the formula (current utility) should not be smaller than the RHS (utility after swap) evaluated at `outY=qY`
  * The LHS of the formula should be smaller than the RHS when evaluated at <mark style="color:orange;">`outY=0`</mark>

### Closed Formed Solution

{% hint style="info" %}
In practice, this is the preferred way to solve the equation because it tends to be faster and more consistent. It is more numerically unstable in the worst case since it requires 1/(1-k) exponentiation, but in practice Clipper’s k tends to be small, making 1/(1-k) ≈ 1
{% endhint %}

* If <mark style="color:orange;">`inX`</mark> is specified, then:

$$
{outY} = {qY}-\frac{\left\[\left(\frac{(pX \cdot {qX})^{1-k}}{{wX}^k} + \frac{(pY \cdot {qY})^{1-k}}{{wY}^k} - \frac{(pX \cdot ({qX + M\cdot{inX}}))^{1-k}}{{wX}^k} \right)\cdot wY^k\right]^{\frac{1}{1-k}}}{pY}
$$

* If <mark style="color:orange;">`outY`</mark> is specified, then:

$$
{inX} = \frac{1}{M}\cdot\left\[\frac{\left\[\left(\frac{(pX \cdot {qX})^{1-k}}{{wX}^k} + \frac{(pY \cdot {qY})^{1-k}}{{wY}^k} - \frac{(pY \cdot ({qY}-{outY}))^{1-k}}{{wY}^k}\right)\cdot {wX}^k\right]^{\frac{1}{1-k}}}{pX}-{qX}\right]
$$

### Root Finding

A good initial guess (for a Newton method solver) for <mark style="color:orange;">`inX`</mark> or <mark style="color:orange;">`outY`</mark> is the FMV of the other value.

* If <mark style="color:orange;">`inX`</mark> is specified, then try:

$$
outY \approx M \cdot inX \cdot pX/pY
$$

* If <mark style="color:orange;">`outY`</mark> is specified, try:&#x20;

$$
inX \approx (outY \cdot pY) / (M\*pX)
$$

In practice, the actual Clipper price quote will also depend on the amount of time the quote is alive for, as well as the most recent price update. These should result in only small changes from the estimated quotes produced by this process.

### Final Check: Output Value No Larger than Input Value

Finally, we enforce that **the FMV (according to&#x20;*****our*** <mark style="color:orange;">**`price_in_usd`**</mark>**&#x20;values) of the contributed input is at least the FMV of the output.** This constraint will typically only bind when the Clipper pool is very far off target allocations, since in general fees plus slippage will be sufficient to ensure the condition.

If <mark style="color:orange;">`inX`</mark> was specified and <mark style="color:orange;">`outY`</mark> has been calculated to solve the formula, then as a final check:

$$
outY \equiv \min\left\[outY, (inX \cdot pX) / {pY} \right]
$$

If <mark style="color:orange;">`outY`</mark> is specified and <mark style="color:orange;">`inX`</mark> has been calculated to solve the formula, then as a final check:

$$
inX \equiv \max\left\[inX, (outY \cdot pY) / {pX} \right]
$$

{% hint style="warning" %}
Note that these tests are done *without regard to fees*.
{% endhint %}


# Interacting with the Clipper Exchange contracts

There are several different external functions for interacting with the Clipper exchange onchain, depending on your use case. In all of these functions, Signature is a struct defined by:

```solidity
struct Signature {
  uint8 v;
  bytes32 r;
  bytes32 s;
}
```

### **Avoiding Transaction Errors with the Clipper API**

Clipper is designed to be used sequentially, so that it trades only one active and outstanding signed quote at a time. Once you execute a swap with Clipper all of your existing quotes from before that swap are "dirty" and may no longer be honored onchain.

If you try to sign multiple quotes, or use the same signed quote multiple times, the transactions are highly likely to revert on the blockchain, costing you gas. To avoid this, always call for fresh quotes after you transact with Clipper.

### **Swapping Tokens for Tokens**

<mark style="color:orange;">`function swap(address inputToken, address outputToken, uint256 inputAmount, uint256 outputAmount, uint256 goodUntil, address destinationAddress, Signature calldata theSignature, bytes calldata auxiliaryData) external;`</mark>

<mark style="color:orange;">`function transmitAndSwap(address inputToken, address outputToken, uint256 inputAmount, uint256 outputAmount, uint256 goodUntil, address destinationAddress, Signature calldata theSignature, bytes calldata auxiliaryData) external;`</mark>

Observe that the signed quote has all of these values to use, except for <mark style="color:orange;">`auxiliaryData`</mark> which can be set to any string and is used for identification purposes in the event logs.

The difference between <mark style="color:orange;">`swap`</mark> and `transmitAndSwap` is that <mark style="color:orange;">`transmitAndSwap`</mark> starts by transferring <mark style="color:orange;">`inputAmount`</mark> of the <mark style="color:orange;">`inputToken`</mark> from <mark style="color:orange;">`msg.sender`</mark> to the exchange, while <mark style="color:orange;">`swap`</mark> assumes that the appropriate amount of the input token has already been transmitted. Which function you should use depends on if and how you are connecting the Clipper swap to other operations.

{% hint style="info" %}
See the complete example [here](/disclaimers-and-technical/integrating-with-clipper-rfq/guides/integration-examples#complete-swap-flow)
{% endhint %}

### Handling Native Currency

On each chain a native currency has special privileges and abilities and is often not **ERC20** compatible. For instance, **MATIC** is the native currency on Polygon. Unlike the Clipper implementation on Ethereum mainnet, Clipper's RFQ architecture only uses **ERC20** tokens, meaning that these native currencies must be wrapped before exchange with Clipper, and that Clipper can only return the wrapped version of these assets from the exchange.

However, for convenience, we provide two sets of functions for handling native currency in a direct fashion. For these swaps, you must get a signature for a transaction to or from the wrapped version of the native currency, as this is what will actually be exchanged.

For swaps of tokens to native currency (example: **DAI** to **MATIC** on **Polygon**), use:

<mark style="color:orange;">`function sellTokenForEth(address inputToken, uint256 inputAmount, uint256 outputAmount, uint256 goodUntil, address destinationAddress, Signature calldata theSignature, bytes calldata auxiliaryData) external;`</mark>

<mark style="color:orange;">`function transmitAndSellTokenForEth(address inputToken, uint256 inputAmount, uint256 outputAmount, uint256 goodUntil, address destinationAddress, Signature calldata theSignature, bytes calldata auxiliaryData) external;`</mark>

As with token-to-token swaps, the difference between these functions is that the first assumes that at least <mark style="color:orange;">`inputAmount`</mark> of <mark style="color:orange;">`inputToken`</mark> has already been sent, while the second pulls that input token directly from <mark style="color:orange;">`msg.sender`</mark>. Observe further that:

The `outputToken` argument is not present (since it will be native currency)

These functions refer to the native currency as Eth regardless of chain

For swaps of native currency to tokens (example: **MATIC** to **USDC** on **Polygon**), use:

<mark style="color:orange;">`function sellEthForToken(address outputToken, uint256 inputAmount, uint256 outputAmount, uint256 goodUntil, address destinationAddress, Signature calldata theSignature, bytes calldata auxiliaryData) external payable;`</mark>

This function can operate either by attaching the native currency to the call as msg.value or by transferring that native currency to the exchange contract prior to the function call.

{% hint style="info" %}
See the an example [here](/disclaimers-and-technical/integrating-with-clipper-rfq/guides/integration-examples/swap-native-token-shorttail) and [here](/disclaimers-and-technical/integrating-with-clipper-rfq/guides/integration-examples/swap-shorttail-native-token)&#x20;
{% endhint %}

### **Reduced calldata API**

On L2s like Optimism, Clipper's exchange contracts include two special functions that operate with reduced calldata in order to lower transaction costs. These functions are:

<mark style="color:orange;">`function packedTransmitAndSwap(uint256 packedInput, uint256 packedOutput, uint256 packedGoodUntil, bytes32 auxData, bytes32 r, bytes32 vs) external payable;`</mark>

<mark style="color:orange;">`function packedSwap(uint256 packedInput, uint256 packedOutput, uint256 packedGoodUntil, bytes32 auxData, bytes32 r, bytes32 vs) external payable;`</mark>

Similar to the other Clipper functions, use <mark style="color:orange;">`packedTransmitAndSwap`</mark> to transmit the token from <mark style="color:orange;">`msg.sender`</mark> and use <mark style="color:orange;">`packedSwap`</mark> if tokens have already been transmitted.

### Handling Native Currency in the L2 API

Indicate native currency (e.g., ETH on Optimism) should be the input or output by setting the contract address to address(0).

#### *Packed Format Values*

The *packed* format is a way of compressing an integer amount and a contract address into a single <mark style="color:orange;">`uint256`</mark> value. The packed format puts the address as the (first, lowest order) 160 bits (= 40 hex values = 20 bytes) and the amount as the (second, highest order) 96 bits (= 24 hex values = 12 bytes). To created a *packed* value, leftshift the integer amount by 160 bits and add it to the binary representation of the contract address. The four packed arguments into this function, and the values they encode, are:

<mark style="color:orange;">`packedInput`</mark>: input amount and contract address

<mark style="color:orange;">`auxData`</mark> - this is a <mark style="color:orange;">`bytes32`</mark> value that is a packed representation of an identifying string, and the <mark style="color:orange;">`destination_address`</mark> (lowest order bytes). The identifying string is emitted as part of <mark style="color:orange;">`Swapped`</mark> event and allows us to attribute trade sourced correctly.

<mark style="color:orange;">`packedOutput`</mark>: output amount and contract address

<mark style="color:orange;">`packedGoodUntil`</mark>: Simply use the <mark style="color:orange;">`good_until`</mark> value received from the server - it is already a packed representation of state.

#### *Short Signatures*

These functions use [the EIP 2098 "short signature" representation](https://eips.ethereum.org/EIPS/eip-2098) for the signature returned from the Clipper Exchange server. Source code to convert from the *v, r, s* signature value to the *r, vs* short signature is available on the EIP.

### Intermediate Contract Whitelisting

Clipper limits the number of signed quotes per day for each <mark style="color:orange;">`destination_address`</mark>. If you make use of an intermediate or routing contract, please let us know the address you intend to use for that and we can whitelist the address to remove its daily signing limits.


# Integration Examples

## Complete swap flow

If you want to see a complete flow to make a swap you can review this [code](/disclaimers-and-technical/integrating-with-clipper-rfq/guides/integration-examples/complete-swap-flow). In this example you can see the different steps.

1. Get pool data
2. Estimate Clipper Prices
3. Create a quote
4. Sign a quote
5. Execute a transaction

## Swaps

There are three kinds of assets:

1. **Shorttail**: Assets on Clipper Pool
2. **Longtail**: Assets not on Clipper Pool but can be traded through coves.
3. **ClipperLP:** Underlying token representing fraction of clipper pool.

Given those three assets, there may be the following Swap combinations:

#### Core pool Swaps

[Native token → Shorttail](/disclaimers-and-technical/integrating-with-clipper-rfq/guides/integration-examples/swap-native-token-shorttail)

[Shorttail → Native token](/disclaimers-and-technical/integrating-with-clipper-rfq/guides/integration-examples/swap-shorttail-native-token)

[Shorttail → Shorttail](/disclaimers-and-technical/integrating-with-clipper-rfq/guides/integration-examples/swap-shorttail-shorttail)


# Swap Native token → Shorttail

E.g: 0.01 ETH → USDC on Ethereum mainnet (Chain 1), specifying selling amount.

{% file src="/files/aQLi0qsgSmlfob5AeYIa" %}
ABI used in the example
{% endfile %}

```javascript
const fetch = require('node-fetch');
import ethers from "ethers";
import exchangeAbi from "./exchangeAbi.json";

// Get a quote
async function getQuote() {
  const quotePayload = {
    "pool_address": "0x655eDCE464CC797526600a462A8154650EEe4B77"
    "output_asset_symbol": "USDC",
    "input_asset_symbol": "ETH",
    "time_in_seconds": 60,
    "input_amount": "10000000000000000"
  };
  const queryString = new URLSearchParams(quotePayload).toString();
  const requestOptions = {
    method: 'GET',
    headers: {
      'x-api-key': 'YXBpLXVzZXI6dXNlci1wYXNz',  // This is a placeholder 
      'Content-Type': 'application/json'
    }
  };

  const response = await fetch(`https://blade-api.sushi.com/rfq/v2/quote/1?${queryString}`, requestOptions);
  const quote = await response.json();
  
  return quote;
}

// Sign the quote
async function signQuote(quoteId) {
  const signPayload = {
    "quote_id": quoteId,
    "destination_address": "0x0000000000000000000000000000000000000000"
  };

  const requestOptions = {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(signPayload)
  };

  const response = await fetch('https://blade-api.sushi.com/rfq/sign', requestOptions);
  const signResponse = await response.json();
  
  return signResponse;
}

// Execute transaction
async function executeSwap(signResponse) {
  const provider = new ethers.providers.JsonRpcProvider(process.env.RPC_URL);
  const exchangeContract = new ethers.Contract(
    signResponse.clipper_exchange_address,
    exchangeAbi,
    provider
  );
  
  const auxData = "0x00000000000000000000000000000000000000000000000000";

  const result = await exchangeContract.sellEthForToken(
    signResponse.output_asset_address,
    signResponse.input_amount,
    signResponse.output_amount,
    signResponse.good_until,
    signResponse.destination_address,
    [
      signResponse.signature.v,
      signResponse.signature.r,
      signResponse.signature.s,
    ],
    auxData,
    {
      value: signResponse.input_amount,
    }
  );
}

async function main() {
  // 1. Get a quote 
  const quote = await getQuote();
  console.log("Quote:", quote);
  
  // 2. Sign a quote
  const signResponse = await signQuote(quote.id);
  console.log("Sign Response:", signResponse);
  
  // 3. Execute transaction
  await executeSwap(signResponse);
  console.log("Swap executed successfully.");
}
```


# Swap Shorttail → Native token

E.g: OP → 0.01 ETH on Optimism (Chain 10)

{% file src="/files/II7qG5dv1PQnCMROInAV" %}
ABI used in the example
{% endfile %}

{% hint style="info" %}
Since this is a L2 (optimism) example, we use <mark style="color:orange;">`packed`</mark> form values, as explained [here](/disclaimers-and-technical/integrating-with-clipper-rfq/guides/interacting-with-the-clipper-exchange-contracts#packed-format-values). In this case, we need to call the <mark style="color:orange;">`packedTransmitAndSwap`</mark> method from clipper’s smart contract which has the following interface:

<mark style="color:orange;">`function packedTransmitAndSwap(uint256 packedInput, uint256 packedOutput, uint256 packedGoodUntil, bytes32 auxData, bytes32 r, bytes32 vs)`</mark>
{% endhint %}

```javascript
const fetch = require('node-fetch');
import ethers from "ethers";
import packedExchangeAbi from "./packedExchangeAbi.json";
import { hexZeroPad } from 'ethers/lib/utils';

// Get a quote
async function getQuote() {
  const quotePayload = {
    "pool_address": "0x663fA8731045765067e2B5b6acB19BE2ce974C7f",
    "output_asset_symbol": "ETH",
    "input_asset_symbol": "OP",
    "time_in_seconds": 60,
    "output_amount": "10000000000000000"
  };
  const queryString = new URLSearchParams(quotePayload).toString();
  const requestOptions = {
    method: 'GET',
    headers: {
      'x-api-key': 'YXBpLXVzZXI6dXNlci1wYXNz',  // This is a placeholderer,
      'Content-Type': 'application/json'
    }
  };

  const response = await fetch(`https://blade-api.sushi.com/rfq/v2/quote/10?${queryString}`);
  const quote = await response.json();
  
  return quote;
}

// Sign the quote
async function signQuote(quoteId) {
  const signPayload = {
    "quote_id": quoteId,
    "destination_address": "0xab83Af831dfb4028EBFd3fFA74A828a4d5DCaAC5"
  };

  const requestOptions = {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(signPayload)
  };

  const response = await fetch('https://blade-api.sushi.com/rfq/sign', requestOptions);
  const signResponse = await response.json();
  
  return signResponse;
}

// Execute transaction
async function executeSwap(signResponse) {
  const provider = new ethers.providers.JsonRpcProvider(process.env.RPC_URL);
  const clipperPackedContract = new ethers.Contract(
    signResponse.clipper_exchange_address,
    packedExchangeAbi,
    provider
  );

  const auxData = "0x00000000000000000000000000000000000000000000000000";
  const packedInput = packAddressAndAmount(signResponse.input_amount, signResponse.input_asset_address);
  const packedOutput = packAddressAndAmount(signResponse.output_amount, signResponse.output_asset_address);
  const packedGoodUntil = signResponse.good_until;
  const packedData = packAddressAndAmount(auxData, signResponse.destination_address);
  const r = byte32(signResponse.signature.r);
  const vs = byte32(shortenSignature(signResponse.signature.s, signResponse.signature.v));

  const result = await clipperPackedContract.packedTransmitAndSwap(
    packedInput, packedOutput, packedGoodUntil, auxData, r, vs
  );
}

// In order to calculate the packed values, we can use the following methods
function packAddressAndAmount(amount, address) {
  const addressBn = BigInt(address);
  const amountBn = BigInt(amount);

  return (amountBn << 160n) + addressBn;
}

// Converts the value to 32 bytes and fills the rest with leading zeroes.
function byte32(value) {
  return hexZeroPad(value.toString(16), 32);
}

function shortenSignature(s, v) {
  const parity = BigInt(v - 27);
  const shiftedParity = parity << 255n;

  return s + shiftedParity.toString(16);
}

// Main function
async function main() {
  // 1. Get a quotey
  const quote = await getQuote();
  console.log("Quote:", quote);
  
  // 2. Sign a quote
  const signResponse = await signQuote(quote.id);
  console.log("Sign Response:", signResponse);
  
  // 3. Execute transaction
  await executeSwap(signResponse);
  console.log("Swap executed successfully.");
}

```


# Swap Shorttail → Shorttail

E.g: 2 DAI -> USDC on Polygon (Chain 137)

{% file src="/files/aQLi0qsgSmlfob5AeYIa" %}
ABI used in the example
{% endfile %}

```javascript
const fetch = require('node-fetch');
import ethers from "ethers";
import exchangeAbi from "./exchangeAbi.json";

async function getQuote() {
  const quotePayload = {
    "pool_address": "0x6Bfce69d1Df30FD2B2C8e478EDEC9dAa643Ae3B8",
    "output_asset_symbol": "USDC",
    "input_asset_symbol": "DAI",
    "time_in_seconds": 60,
    "input_amount": "2000000000000000000"
  };
  const queryString = new URLSearchParams(quotePayload).toString();

  const requestOptions = {
    method: 'GET',
    headers: {
      'x-api-key': 'YXBpLXVzZXI6dXNlci1wYXNz',  // This is a placeholder 
      'Content-Type': 'application/json'
    }
  };

  const response = await fetch(`https://blade-api.sushi.com/rfq/v2/quote/137?${queryString}`);
  const quote = await response.json();
  
  return quote;
}

async function signQuote(quote) {
  const signPayload = {
    "quote_id": quote.id,
    "destination_address": "0xab83Af831dfb4028EBFd3fFA74A828a4d5DCaAC5"
  };

  const requestOptions = {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(signPayload)
  };

  const response = await fetch('https://blade-api.sushi.com/rfq/sign', requestOptions);
  const signResponse = await response.json();
  
  return signResponse;
}

async function executeSwap(signResponse) {
  const provider = new ethers.providers.JsonRpcProvider(process.env.RPC_URL);
  const exchangeContract = new ethers.Contract(
    signResponse.clipper_exchange_address,
    exchangeAbi,
    provider
  );

  const auxData = "0x00000000000000000000000000000000000000000000000000";

  const result = await exchangeContract.transmitAndSwap(
    signResponse.input_asset_address,
    signResponse.output_asset_address,
    signResponse.input_amount,
    signResponse.output_amount,
    signResponse.good_until,
    signResponse.destination_address,
    [signResponse.signature.v, signResponse.signature.r, signResponse.signature.s],
    auxData
  );
}

async function main() {
  // 1. Get quote
  const quote = await getQuote();
  console.log("Quote:", quote);
  
  // 2. Sign the quote
  const signResponse = await signQuote(quote);
  console.log("Sign Response:", signResponse);
  
  // 3. Execute transaction
  await executeSwap(signResponse);
  console.log("Swap executed successfully.");
}

```


# Complete Swap Flow

We’ve created some demonstration integration code in NodeJS to show how you can replicate Clipper quotes locally and send the transaction using Clipper RFQ API. The code has demonstration solvers for both the closed form and root finding modalities.

Add <mark style="color:orange;">`package.json`</mark> file with this code:

```json
{
  "name": "clipper",
  "version": "1.0.0",
  "main": "main.js",
  "license": "MIT",
  "dependencies": {
    "bignumber.js": "^9.0.2",
    "node-fetch": "^3.2.0",
    "root-finding": "^1.0.2",
    "web3": "^1.7.0"
  },
  "type": "module"
}

```

Add <mark style="color:orange;">`main.js`</mark> file with this code

```javascript
import fetch from 'node-fetch'
import BN from 'bignumber.js'
import nr from 'root-finding'
import Web3 from 'web3'
import fs from 'fs'
import ethers from "ethers";
import exchangeAbi from "./exchangeAbi.json";

const nodeUrl = process.env.NODE_URL

const rawdata = fs.readFileSync('ERC20.abi.json');
const ERC20ABI = JSON.parse(rawdata);
const authorizationHeader = 'YXBpLXVzZXI6dXNlci1wYXNz';  // This is a placeholder 

const web3 = new Web3(nodeUrl)


async function main() {
    // 1. GET POOL INFO AND ESTIMATE CLIPPER PRICES
    const poolAddress = '0x6Bfce69d1Df30FD2B2C8e478EDEC9dAa643Ae3B8'
    const data = await fetch(`https://blade-api.sushi.com/rfq/v2/pool/137?fieldset=offchain-data&pool_address=${pool_address}`, {
        method: 'GET',
        headers: {'x-api-key': authorizationHeader}
    }).then((x) => x.json());
    const prices = data.pools[0]
    const asset_one = 'MATIC'
    const asset_two = 'USDC'
    const decimalsX = 18
    const decimalsY = 6
    const humanInX = 10000


    let fee_in_basis_points = 0
    for (const pair of prices.pairs) {
        if(((pair.assets[0] === asset_one) && (pair.assets[1] === asset_two)) ||
           ((pair.assets[1] === asset_one) && (pair.assets[0] === asset_two))){
            fee_in_basis_points = pair.fee_in_basis_points
            break
        }
    }

    const assetOneObj = prices.assets.find((x) => x.name === asset_one)
    const assetTwoObj = prices.assets.find((x) => x.name === asset_two)

    const assetOneContract = new web3.eth.Contract(ERC20ABI, assetOneObj.address)
    const assetTwoContract = new web3.eth.Contract(ERC20ABI, assetTwoObj.address)

    const assetOneBalance = await assetOneContract.methods.balanceOf(poolAddress).call()
    const assetTwoBalance = await assetTwoContract.methods.balanceOf(poolAddress).call()

    const M = (10000-fee_in_basis_points)/10000

    const scaledDecimalsX = new BN(10).exponentiatedBy(decimalsX)
    const scaledDecimalsY = new BN(10).exponentiatedBy(decimalsY)
    
    const adjustedInX = humanInX*M
    const inX = new BN(humanInX).multipliedBy(scaledDecimalsX)

    // Pull in additional onchain state. This is from a snapshot of USDC and USDT, respectively.
    const qX = new BN(assetOneBalance).dividedBy(scaledDecimalsX).toNumber()
    const qY = new BN(assetTwoBalance).dividedBy(scaledDecimalsY).toNumber()
    // Pull additional offchain state
    const k = prices.pool.k
    // format variables according to formula
    const pX = assetOneObj.price_in_usd
    const wX = assetOneObj.listing_weight

    const pY = assetTwoObj.price_in_usd
    const wY = assetTwoObj.listing_weight

    const initialGuess = (adjustedInX*pX)/pY

    const initialUtility = Math.pow(pX*qX, 1-k)/Math.pow(wX, k) + Math.pow(pY*qY, 1-k)/Math.pow(wY, k) 
    const newXUtility =  Math.pow(pX*(qX+adjustedInX), 1-k)/Math.pow(wX, k)

    let outY;

    // CLOSED FORM SOLUTION
    const outYClosedForm = qY-Math.pow((initialUtility - newXUtility)*Math.pow(wY,k), (1/(1-k)))/pY

    // ROOT FINDING SOLUTION
    function newYUtility(outY) {
        return Math.pow(pY*(qY-outY), 1-k)/Math.pow(wY, k) 
    }

    function zeroMe(outY) {
        return initialUtility - newXUtility - newYUtility(outY)
    }
    // nr.newtonRaphson(guess, increment, iteration, eps, f);
    // These increment, iteration, and eps values may need to be changed
    const outYRootFinding = nr.newtonRaphson(initialGuess, 1e-6, 50, 1e-8, zeroMe)
    console.log('Closed Form: ', outYClosedForm);
    console.log('Root Finding: ', outYRootFinding);
    outY = outYClosedForm;
    // Adjust for FMV restriction, input >= output (without respect to fees!)
    outY = Math.min(outY, (humanInX*pX)/pY).toFixed(decimalsY)

    // 2. CREATE A QUOTE
    const quotePayload = {
        "input_asset_symbol": asset_one,
        "output_asset_symbol": asset_two,
        "pool_address": "0x6Bfce69d1Df30FD2B2C8e478EDEC9dAa643Ae3B8",
        "input_amount": inX.toFixed(),
        "time_in_seconds": prices.pool.default_time_in_seconds
    }
    const queryString = new URLSearchParams(quotePayload).toString();
    const quote = await fetch(`https://blade-api.sushi.com/rfq/v2/quote/137?${queryString}`, {
        method: 'GET',
        headers: {
            'Content-Type': 'application/json',
            'x-api-key': authorizationHeader
        }
    })
        .then((x) => x.json())

    console.log({
        fromFormula: outY,
        fromQuote: new BN(quote.output_amount).dividedBy(scaledDecimalsY).toFixed(decimalsY)
    })
    
    // 3. SIGN THE QUOTE
    const sign = await fetch('https://blade-api.sushi.com/rfq/sign', {
        method: 'POST',
        body: JSON.stringify({
            quote_id: quote.id,  // Use the quote_id from the previous /quote call
            destination_address: "0x5901920A7b8cb1Bba39220FAC138Ffb3800dD212",
            sender_address: "0x5901920A7b8cb1Bba39220FAC138Ffb3800dD212", // Optional: it is for DEX aggregator partners that are using their own smart contract
        }),
        headers: {
            'Content-Type': 'application/json',
            'x-api-key': authorizationHeader
        }
    }).then((x) => x.json());
    
    // 4. SEND THE TRANSACTION
    const provider = new ethers.providers.JsonRpcProvider(process.env.RPC_URL);
    const exchangeContract = new ethers.Contract(
        sign.clipper_exchange_address,
        exchangeAbi,
        provider
    );
    
    // Any 32 bytes identifier
    const auxData = "0x00000000000000000000000000000000000000000000000000";

    const result = await exchangeContract.swap(
        sign.input_asset_address,
        sign.output_asset_address,
        sign.input_amount,
        sign.output_amount,
        sign.good_until,
        sign.destination_address,
        [sign.signature.v, sign.signature.r, sign.signature.s],
        auxData
    );
    console.log("Swap Result:", result);
}
main()

```

Add <mark style="color:orange;">`ERC20.abi.json`</mark>

{% file src="/files/JKitp2vpnhjSQ44EjmrN" %}

Add <mark style="color:orange;">`exchangeAbi.json`</mark>

{% file src="/files/aQLi0qsgSmlfob5AeYIa" %}

Install packages

```bash
npm install
```

Run the code

```bash
NODE_URL="https://polygon-rpc.com/" node main.js
```

### Extra notes of the code

The code compares the output from a root-finding implementation in our code (”fromFormula”) to the output from the Clipper servers (”fromQuote”) on Polygon. Note that sometimes these values may diverge slightly because of Polygon block updates.

You can change the tokens and amounts by changing these values in <mark style="color:orange;">`main.js`</mark>

```javascript
const asset_one = 'USDT'
const asset_two = 'USDC'
const decimalsX = 6
const decimalsY = 6
const humanInX = 100
```

The <mark style="color:orange;">asset\_</mark> values are token names, <mark style="color:orange;">`decimals`</mark> values should be the <mark style="color:orange;">`decimals`</mark> for the first and second tokens, respectively, and <mark style="color:orange;">`humanInX`</mark> should be the sold amount of <mark style="color:orange;">`asset_one`</mark> in human terms (i.e., 1000 USDC ≈ $1,000 rather than “1000000000” USDC).


# Blade Pool LP withdraw process

### unlockDeposit() → returns (uint256 poolTokens)

Unlocks LP tokens after the vesting period ends.

**Process Overview:**

* Verify if the caller has a vested deposit.
* Ensure the lock period has ended.
* Transfer the LP tokens to the caller.
* Remove the vesting record.

{% hint style="info" %}
Does not withdraw assets. Only gives access to LP tokens. LP tokens must have been created using a vesting deposit.
{% endhint %}

{% hint style="danger" %}
**Revert Conditions:**&#x20;

No active vesting deposit exists.

Vesting period has not passed.
{% endhint %}

### burnToWithdraw(uint256 amount)

Burns the caller’s LP tokens and withdraws their proportional share of all pool assets.

**Process Overview:**&#x20;

* Calculates the fraction of the pool being burned.
* Burns LP tokens from the caller.
* Transfers a proportional amount of each asset in the pool.
* Emits a Withdrawn event.

{% hint style="info" %}
No vesting needed. Useful for instant withdrawals. Only works if the caller already holds LP tokens.
{% endhint %}

{% hint style="danger" %}
**Revert conditions:**&#x20;

Caller doesn’t have enough LP tokens.&#x20;

Asset transfer fails.
{% endhint %}


# API Reference


# API v2


# Overview

## Endpoints

Learn more about the different endpoints of Swap V2 API:

* [GET /rfq/pool/v2/{CHAIN\_ID}](/disclaimers-and-technical/integrating-with-clipper-rfq/api-reference/api-v2/pool-v2) - Get information about a blockchain network supported by clipper.
* [GET /rfq/quote/v2/{CHAIN\_ID} ](/disclaimers-and-technical/integrating-with-clipper-rfq/api-reference/api-v2/quote-v2)- Generate potential asset swap quotes. Obtain pricing and essential details for informed decision-making **:**

**New Domain**

`https://blade-api.sushi.com`<br>

### Authorization

In order to prevent abuse on the API we implement rate limits on the requests, to overcome these limits as an aggregator get in contact with the support team to get API credentials (user and password) [here](mailto:aggregators@shipyardsoftware.org).

{% hint style="warning" %}
For API v2 the api key auth is required.
{% endhint %}

The API uses the API KEY authentication method. You have to include the credentials in the header <mark style="color:orange;">`x-api-key`</mark>.

Example: If your api key is <mark style="color:orange;">TzuiYrpRgN2</mark>

```bash
curl --location 'https://blade-api.sushi.com/rfq/v2/pool/1?fieldset=offchain-data&pool_address=0x655eDCE464CC797526600a462A8154650EEe4B77' \
--header 'x-api-key: TzuiYrpRgN2' \
--data ''
```

### Errors

#### Common Error Codes

<table><thead><tr><th width="118">Code</th><th>Reason</th></tr></thead><tbody><tr><td>400</td><td>Bad Request - Invalid data in the request</td></tr><tr><td>401</td><td>Unauthorized</td></tr><tr><td>403</td><td>Forbidden Error</td></tr><tr><td>500</td><td>Internal Server Error</td></tr><tr><td>503</td><td>External Service Error</td></tr></tbody></table>

#### Error Format

```json
{
    "errorMessage": "Description of the error",
    "errorType": "Type of the error",
    "errorCode": 422,  // it is returned only when we have a clipper code for the error
    "data": []  // is is returned only when the input data is invalid
}
```

{% hint style="warning" %} <mark style="color:orange;">`error_code`</mark> and <mark style="color:orange;">`data`</mark> are not always present
{% endhint %}

*Examples*&#x20;

1. If we make a request to [quote](/disclaimers-and-technical/integrating-with-clipper-rfq/api-reference/api-v2/quote-v2) endpoint and the body does not have the field <mark style="color:orange;">`chain_id`</mark> (required param), the API response will look like similar to this:

```json
{
    "errorMessage": "Invalid input data",
    "errorType": "BadData",
    "errorCode": 422,
    "data": [
        {
            "type": "missing",
            "loc": [
                "chain_id"
            ],
            "msg": "Field required",
            "input": {
                "input_amount": "18000",
                "input_asset_symbol": "ETH",
                "output_asset_symbol": "WBTC",
                "time_in_seconds": 60
            },
            "url": "https://errors.pydantic.dev/2.1/v/missing"
        }
    ]
}
```

2. If we make a request to [quote](/disclaimers-and-technical/integrating-with-clipper-rfq/api-reference/api-v2/quote-v2) endpoint and we send an <mark style="color:orange;">`input_asset_symbol`</mark> that clipper does not support, the API response will look like similar to this

```json
{
    "errorMessage": "input_asset_symbol: INVALIDASSET is not supported",
    "errorType": "BadData"
}
```

3. If we make a request to [quote](/disclaimers-and-technical/integrating-with-clipper-rfq/api-reference/api-v1/quote) endpoint and we send invalid credentials

```json
{
    "errorMessage": "Auth: Access is forbidden",
    "errorType": "Forbidden"
}
```

#### Clipper Error Codes

These codes appear in the field <mark style="color:orange;">`errorCode`</mark>

<table><thead><tr><th width="112">Code</th><th>Reason</th></tr></thead><tbody><tr><td>422</td><td>Invalid input data</td></tr><tr><td>409</td><td>Quote problems</td></tr></tbody></table>


# Pool v2

This endpoint provides comprehensive information about all the pools on the selected chain, including details about its assets, the contract address of its liquidity pool, and other relevant data. This information is crucial for making off-chain calculations and predicting quotes.

### URL

```url
https://blade-api.sushi.com/rfq/v2/pool/{CHAIN_ID}
```

## Request

| Path Param | Description                                  | Example       |
| ---------- | -------------------------------------------- | ------------- |
| chain      | <p>Integer - Required<br>ID of the chain</p> | chain\_id=137 |

<table><thead><tr><th width="178.33333333333331">Query Param</th><th>Description</th><th>Example</th></tr></thead><tbody><tr><td>pool_address</td><td>str - Optional<br>The address of the pool. If not provided, all pools on the selected chain will be returned.</td><td>pool_address=0x655eDCE464CC797526600a462A8154650EEe4B77</td></tr><tr><td>time_in_seconds</td><td><p>Integer - Optional</p><p>The time duration for which a quote will be available. This value is used to calculate the fees; as you decrease the time, you will see lower fees.</p><p>By default, the system sets a predefined value. </p><p><strong>Note:</strong> For on-chain data, this field is not considered.</p></td><td>time_in_seconds=30</td></tr><tr><td>fieldset</td><td><p>String - Optional<br>Determines whether the API should make calls to the blockchain to return on-chain data.</p><p><strong>Accepted Value</strong>: <mark style="color:orange;"><code>offchain-data</code></mark> If the parameter is not provided, it will default to handling on-chain data.</p></td><td>fieldset=offchain-data</td></tr></tbody></table>

## Response

#### On-chain object

<table><thead><tr><th width="133">Field</th><th>Description</th></tr></thead><tbody><tr><td>pools</td><td>List of <a href="#pool-data-on-chain-object">Pool data on-chain object</a></td></tr><tr><td>pool_type</td><td>String - <mark style="color:orange;"><code>offchain</code></mark></td></tr></tbody></table>

#### Pool Data on-chain object

<table><thead><tr><th width="133">Field</th><th>Description</th></tr></thead><tbody><tr><td>pool</td><td><a href="#pool-on-chain-object">Pool on-chain object</a></td></tr><tr><td>assets</td><td>List of <a href="#asset-o-chain-object">Asset on-chain objects</a></td></tr></tbody></table>

#### Pool on-chain object

<table><thead><tr><th width="248">Field</th><th>Description</th></tr></thead><tbody><tr><td>chain_id</td><td>Integer - ID of the chain</td></tr><tr><td>address</td><td>String(ETH address) - Clipper contract address of the pool, is the address used when executing a transaction</td></tr><tr><td>num_assets</td><td>Integer - The total of assets available in the chain</td></tr><tr><td>value_in_usd</td><td>Float - Value of the pool in USD (***REVIEW TEMO)</td></tr><tr><td>swaps_enabled</td><td>Bool - Represents if the swaps are available for the chain</td></tr></tbody></table>

#### Asset on-chain object

<table><thead><tr><th width="158">Field</th><th>Description</th></tr></thead><tbody><tr><td>name</td><td>String - The name of the asset, this value should be used when making a quote</td></tr><tr><td>address</td><td>String(ETH address) - The contract address of the asset</td></tr><tr><td>price_in_usd</td><td>Float - Current price in dollars for the asset</td></tr><tr><td>value_in_usd</td><td>Float - Value of the pool in USD</td></tr><tr><td>target_value_in_usd</td><td>Float - USD target value for this asset in the pool</td></tr></tbody></table>

#### Off-chain object

<table><thead><tr><th width="133">Field</th><th>Description</th></tr></thead><tbody><tr><td>pools</td><td>List of <a href="#pool-data-off-chainobject">Pool data off-chain object</a></td></tr><tr><td>pool_type</td><td>String - <mark style="color:orange;"><code>offchain</code></mark></td></tr></tbody></table>

#### Pool Data off-chain object

<table><thead><tr><th width="133">Field</th><th>Description</th></tr></thead><tbody><tr><td>pool</td><td><a href="#pool-off-chain-object">Pool off-chain object</a></td></tr><tr><td>assets</td><td>List of <a href="#asset-off-chainobject">Asset off-chain objects</a></td></tr><tr><td>pairs</td><td>List of <a href="#pair-object">Pair objects</a></td></tr></tbody></table>

#### Pool off-chain object

<table><thead><tr><th width="248">Field</th><th>Description</th></tr></thead><tbody><tr><td>chain_id</td><td>Integer - ID of the chain</td></tr><tr><td>address</td><td>String(ETH address) - Clipper contract address of the pool, is the address used when executing a transaction</td></tr><tr><td>num_assets</td><td>Integer - The total of assets available in the chain</td></tr><tr><td>k</td><td>Float - K factor</td></tr><tr><td>time_in_seconds</td><td>Integer - Number of seconds were used to calculate the fees of a swap, this number indicates the number of seconds that quotes are live</td></tr><tr><td>default_time_in_seconds</td><td>Integer - Default number of seconds that quotes are live, is value used to calculate fees when don't send the query param <mark style="color:orange;"><code>time_in_seconds</code></mark></td></tr><tr><td>swaps_enabled</td><td>Bool - Represents if the swaps are available for the chain</td></tr></tbody></table>

#### Asset off-chain object

<table><thead><tr><th width="158">Field</th><th>Description</th></tr></thead><tbody><tr><td>name</td><td>String - The name of the asset, this value should be used when making a quote</td></tr><tr><td>address</td><td>String(ETH address) - The contract address of the asset</td></tr><tr><td>price_in_usd</td><td>Float - Current price in dollars for the asset</td></tr><tr><td>listing_weight</td><td>Integer - asset weight within the pool</td></tr></tbody></table>

#### Pair object

<table><thead><tr><th width="201">Field</th><th>Description</th></tr></thead><tbody><tr><td>assets</td><td>List[str] - Pair of assets available to make a swap - e.g: ["ETH", "MATIC"]</td></tr><tr><td>fee_in_basis_points</td><td>Float - Fee for make a swap between the pair</td></tr></tbody></table>

## Examples

1.Get the offchain data for Polygon chain (chain\_id=137)

***Request***

<pre class="language-bash" data-overflow="wrap" data-full-width="false"><code class="lang-bash"><strong>curl -X GET "https://blade-api.sushi.com/rfq/v2/pool/1?fieldset=offchain-data" -H "x-api-key: mQzA8Uy6nZ8Vy"
</strong></code></pre>

***Response***

```json
{
  "pool_type": "offchain",
  "pools": [
    {
      "pool": {
        "chain_id": 1,
        "address": "0x655eDCE464CC797526600a462A8154650EEe4B77",
        "num_assets": 4,
        "k": 0.06,
        "time_in_seconds": 60,
        "default_time_in_seconds": 60,
        "swaps_enabled": true
      },
      "assets": [
        {
          "name": "ETH",
          "address": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
          "price_in_usd": 2076.799,
          "listing_weight": 79
        },
        {
          "name": "USDC",
          "address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
          "price_in_usd": 1,
          "listing_weight": 188
        },
        {
          "name": "USDT",
          "address": "0xdAC17F958D2ee523a2206206994597C13D831ec7",
          "price_in_usd": 1,
          "listing_weight": 305
        },
        {
          "name": "DAI",
          "address": "0x6B175474E89094C44Da98b954EedeAC495271d0F",
          "price_in_usd": 1,
          "listing_weight": 250
        }
      ],
      "pairs": [
        {
          "assets": [
            "ETH",
            "USDC"
          ],
          "fee_in_basis_points": 9
        },
        {
          "assets": [
            "ETH",
            "USDT"
          ],
          "fee_in_basis_points": 9
        },
        {
          "assets": [
            "ETH",
            "DAI"
          ],
          "fee_in_basis_points": 8
        },
        {
          "assets": [
            "USDC",
            "USDT"
          ],
          "fee_in_basis_points": 5
        },
        {
          "assets": [
            "USDC",
            "DAI"
          ],
          "fee_in_basis_points": 5
        },
        {
          "assets": [
            "USDT",
            "DAI"
          ],
          "fee_in_basis_points": 5
        }
      ]
    }
  ]
}
```

2. Get the on-chain data for mainnet chain (chain\_id=1)

***Request***

{% code overflow="wrap" %}

```bash
curl -X GET "https://blade-api.sushi.com/rfq/v2/pool/1?pool_address=0x655eDCE464CC797526600a462A8154650EEe4B77" -H "x-api-key: mQzA8Uy6nZ8Vy"
```

{% endcode %}

***Response***

```json
{
  "pool_type": "onchain",
  "pools": [
    {
      "pool": {
        "chain_id": 1,
        "address": "0x655eDCE464CC797526600a462A8154650EEe4B77",
        "num_assets": 4,
        "pool_tokens": 1.3792871898369242e+24,
        "value_in_usd": 1978682.496424432,
        "swaps_enabled": true
      },
      "assets": [
        {
          "name": "USDC",
          "address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
          "balance": "417751254142",
          "price_in_usd": 1,
          "value_in_usd": 417751.254142,
          "target_value_in_usd": 416727.89356391726
        },
        {
          "name": "USDT",
          "address": "0xdAC17F958D2ee523a2206206994597C13D831ec7",
          "balance": "259059412007",
          "price_in_usd": 1,
          "value_in_usd": 259059.412007,
          "target_value_in_usd": 256868.3409508736
        },
        {
          "name": "DAI",
          "address": "0x6B175474E89094C44Da98b954EedeAC495271d0F",
          "balance": "309714519494182375269440",
          "price_in_usd": 1,
          "value_in_usd": 309714.5194941824,
          "target_value_in_usd": 313379.3759600658
        },
        {
          "name": "ETH",
          "address": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
          "balance": "476877882758190421102",
          "price_in_usd": 2080.527,
          "value_in_usd": 992157.3107812497,
          "target_value_in_usd": 991706.8859495752
        }
      ]
    }
  ]
}
```


# Quote v2

This endpoint facilitates the creation of a potential quote for executing a swap between two assets. It allows users to obtain pricing information and other essential details necessary to initiate asset swaps within the system. Use this endpoint to explore the potential cost and feasibility of asset exchanges before finalizing transactions.

### URL

```url
https://blade-api.sushi.com/rfq/v2/quote/{CHAIN_ID}
```

## Request

| Path Param | Description                                  | Example       |
| ---------- | -------------------------------------------- | ------------- |
| chain      | <p>Integer - Required<br>ID of the chain</p> | chain\_id=137 |

<table><thead><tr><th width="210.33333333333331">Query Param</th><th width="328">Description</th><th>Example</th></tr></thead><tbody><tr><td>pool_address</td><td>str - Optional<br>Address of the pool. If not present, the best pool will be calculated</td><td>pool_address=0x655eDCE464CC797526600a462A8154650EEe4B77</td></tr><tr><td>time_in_seconds</td><td>Integer - Optional<br>Amount of time between accepting a quote and receiving the quote on the blockchain. As this value increases, the quote will get worse for the user.</td><td>time_in_seconds=30</td></tr><tr><td>output_amount</td><td>Integer/String - Optional<br>Desired quantity of assets to receive as part of the swap<br>This field is mutually exclusive with <mark style="color:orange;"><code>input_amount</code></mark></td><td>output_amount=18000</td></tr><tr><td>input_amount</td><td>Integer/String - Optional<br>Desired quantity of assets you are willing to exchange<br>This field is mutually exclusive with <mark style="color:orange;"><code>output_amount</code></mark></td><td><br>input_amount=18000</td></tr><tr><td>input_asset_symbol</td><td>String - Required<br>Identifier of the asset you want to provide for the swap<br>Should correspond to the asset name returned from the <a href="/pages/YosZgKsXrSyhOO0Ib84i">pool</a> call</td><td>input_asset_symbol=ETH</td></tr><tr><td>output_asset_symbol</td><td>String - Required<br>Identifier of the asset you want to receive in the swap<br>Should correspond to the asset name returned from the <a href="/pages/YosZgKsXrSyhOO0Ib84i">pool</a> call</td><td>output_asset_symbol=DAI</td></tr></tbody></table>

## Response

Quote object

<table><thead><tr><th width="244">Field</th><th>Description</th></tr></thead><tbody><tr><td>id</td><td>String(UUID) - Id of the quote, use this value when signing a quote</td></tr><tr><td>must_accept_by</td><td>String - Human-readable UTC timestamp by which you must accept the quote and should be expected to be a short duration. If this time has passed already, request a new quote - the server will not sign a quote after <mark style="color:orange;"><code>must_accept_by</code></mark> has passed</td></tr><tr><td>good_until</td><td>Integer - number of seconds that quotes live</td></tr><tr><td>chain_id</td><td>Integer - Represents the ID of the chain</td></tr><tr><td>input_asset_address</td><td>String - Contract address of the asset you want to provide for the swap</td></tr><tr><td>input_amount</td><td>String - Amount of assets to be exchanged</td></tr><tr><td>output_asset_address</td><td>String - Contract address of the asset you want to receive in the swap</td></tr><tr><td>output_amount</td><td>String - Amount of assets you will receive in the exchange</td></tr><tr><td>input_value_in_usd</td><td>Float - Amount in dollars to be exchanged</td></tr><tr><td>output_value_in_usd</td><td>Float - Amount in dollars you will receive in the exchange</td></tr><tr><td>created_at</td><td>Integer - Unix Timestamp indicating the date and time when the quote was created</td></tr><tr><td>rate</td><td>Float - swap rate</td></tr></tbody></table>

## Examples

If you want to create a quote to make a swap from ETH to USDC in Ethereum Mainnet (chain\_id=1)

***Request***

```bash
curl -X GET "https://blade-api.sushi.com/rfq/v2/quote/1?pool_address=0x655eDCE464CC797526600a462A8154650EEe4B77&time_in_seconds=60&output_asset_symbol=USDC&input_asset_symbol=ETH&input_amount=10000000000000000000" \
-H "x-api-key: mQzA8Uy6nZ8Vyh" \
-H "Content-Type: application/json"
```

***Response***

```json
{
    "id": "05a51aa6-41b5-4c61-a452-f1b95d0d43e4",
    "must_accept_by": "2023-10-13 22:24:20.932560+00:00",
    "good_until": 1697235920,
    "chain_id": 1,
    "input_amount": "10000000000000000000",
    "output_amount": "5661947917",
    "input_value_in_usd": 15595.15,
    "output_value_in_usd": 5668.12,
    "created_at": 1697235848,
    "rate": 566.1947917,
    "input_asset_address": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
    "output_asset_address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
}
```


# Deposit v2

This endpoint allows users to deposit assets into a liquidity pool by submitting the required details, such as the pool contract address and the amount of assets to be deposited. This process is crucial for users who want to increase the liquidity of the pool and potentially earn rewards or fees. Use this endpoint to securely and efficiently add assets to the pool, contributing to the stability and performance of the ecosystem.

## Request

<table><thead><tr><th>Body Param</th><th>Description</th><th>Example</th></tr></thead><tbody><tr><td>sender</td><td>String - Required<br>The address of the user initiating the deposit transaction.</td><td>"0x960376b3F62f41E7e66809a05D1C5afdFD60A0E9"</td></tr><tr><td>pool_address</td><td>String - Required<br>The address of the pool</td><td>"0x989E8F547FbCa65f4FB0af41e50e4058e6c68166"</td></tr><tr><td>days_to_lock</td><td>Integer<br>Number of days to lock the deposit in the liquidity pool.<br><strong>Note:</strong> <strong>Required</strong> for all pools except Katana, which uses <code>lock_time</code> instead.</td><td>5</td></tr><tr><td>lock_time</td><td>Integer<br>Number of minutes to lock the deposit in the liquidity pool.<br><strong>Note:</strong> Only suported by the Katana pool. For other pools, use <code>days_to_lock</code>.</td><td>5</td></tr><tr><td>deposit</td><td>Object<br>An object containing the asset address and the amount to deposit as a string. The amount should be in its machine-readable form.<br><br>This parameter is required only if <code>single asset</code> is false.</td><td><p></p><pre class="language-json"><code class="lang-json">{
    "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599": "400000000",
    "0x6B175474E89094C44Da98b954EedeAC495271d0F": "2000000000000000000",
    "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2": "1000000000000000000",
    "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48": "2000000"
}
</code></pre></td></tr><tr><td>chain_id</td><td><p>Integer - Required</p><p>The unique identifier of the blockchain network where the deposit will be made.</p></td><td>1</td></tr><tr><td>output_pool_tokens</td><td>Integer - Optional<br>The total number of pool tokens the user wants to receive. It is only valid for single-asset deposits.</td><td>10000</td></tr><tr><td>single_asset</td><td>Bool - Optional<br>A boolean that indicates whether only one asset is being deposited. <br>Default = False</td><td>true</td></tr><tr><td>single_token</td><td><p>String</p><p>Required only when <code>single_asset</code> is true. This represents the address of the single asset being deposited.</p></td><td>0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599</td></tr></tbody></table>

## Response

Deposit object

| Field                      | Description                                                                                                                                                                                                                                                                                                                          |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| sender                     | String - The address of the user who initiated the deposit transaction.                                                                                                                                                                                                                                                              |
| n\_days                    | <p>Integer - The number of days the assets will be locked in the pool, matching the <code>days\_to\_lock</code> from the request.<br><strong>Note:</strong> Supported for all pools except Katana. For katana, returns <code>lock\_time</code>.</p>                                                                                  |
| lock\_time                 | <p>Integer - The number of minutes the assets will be locked in the pool, matching the <code>lock\_time</code> from the request.<br><strong>Note:</strong> Only supported by the Katana pool. For other pools, returns <code>n\_days</code>.</p>                                                                                     |
| good\_until                | The timestamp indicating how long the deposit details, including the signature, are valid.                                                                                                                                                                                                                                           |
| pool\_tokens               | String - The total number of pool tokens that will be given to the user as a result of the deposit.                                                                                                                                                                                                                                  |
| signature                  | Object - A [EIP 2098 "short signature" representation](https://eips.ethereum.org/EIPS/eip-2098) for the signature from the Clipper Exchange server                                                                                                                                                                                   |
| clipper\_exchange\_address | The address of the Clipper exchange contract where the deposit is being made.                                                                                                                                                                                                                                                        |
| deposit\_amounts           | <p>List - A list of the amounts to be deposited for each asset. If an asset was not provided in the request, the amount returned will be 0. For example, if 3 assets were provided in a 4-asset pool, the response will include an amount of 0 for the missing asset.<br><br>For  single asset deposit this field is not present</p> |
| amount                     | String - (Single-asset deposits only) The total amount of the single asset that is being deposited into the pool.                                                                                                                                                                                                                    |
| token                      | String - (Single-asset deposits only) The address of the token that is being deposited into the pool.                                                                                                                                                                                                                                |
| extra\_data                | <p>Encode LP token price and prices list into ABI-compatible bytes.<br><strong>Note:</strong> Only supported by the Katana pool. </p>                                                                                                                                                                                                |

## Examples

#### Deposit Multiple Assets

If you want to deposit multiples assets.

***Request***

```bash
curl -X POST "https://blade-api.sushi.com/rfq/v2/deposit" \
-H "Content-Type: application/json" \
-d '{
  "deposit": {
    "0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1": "2000000000000000000"
  },
  "sender": "0x54298A80a06068587E13b9dC1AC090259A98D5cD",
  "days_to_lock": 10,
  "chain_id": 10,
  "single_asset": false,
  "pool_address": "0x5130f6cE257B8F9bF7fac0A0b519Bd588120ed40"
}'
```

***Response***

```json
{
    "sender": "0x54298A80a06068587E13b9dC1AC090259A98D5cD",
    "n_days": 10,
    "pool_tokens": "29438108002416884",
    "good_until": 1729657240,
    "signature": {
        "v": 28,
        "r": "0x7c37b52021ea25ed38cbaf4def111eb9b5e6f0c1dc6c34ded53b9824c40febbf",
        "s": "0x66ce09126a23cadf277877e556f2d6c5bc3ad1e7080368a13bb0349208d30396"
    },
    "clipper_exchange_address": "0x5130f6cE257B8F9bF7fac0A0b519Bd588120ed40",
    "deposit_amounts": [
        "0",
        "0",
        "0",
        "0",
        "2000000000000000000",
        "0",
        "0"
    ]
}
```

**Katana Example:**

***Request***

```bash
curl -X POST "https://blade-api.sushi.com/rfq/v2/deposit" \
-H "Content-Type: application/json" \
-d '{
  "deposit": {
    "0x0913DA6Da4b42f538B445599b46Bb4622342Cf52": "2000000000000000000"
  },
  "sender": "0x54298A80a06068587E13b9dC1AC090259A98D5cD",
  "lock_time":720,
  "chain_id": 747474,
  "single_asset": false,
  "pool_address": "0x989E8F547FbCa65f4FB0af41e50e4058e6c68166"
}'
```

***Response***

```json
{
    "sender": "0x54298A80a06068587E13b9dC1AC090259A98D5cD",
    "pool_tokens": "1911697202535426211354545867456512",
    "good_until": 1754952442,
    "signature": {
        "v": 27,
        "r": "0xa4be6ab4120b2d55e383f9489e317c05911097cf38b92f8dffe393fed23c07ec",
        "s": "0x66d48deb50124d9e4d20c5f6ce570fd930f6bb8a1cd67bae68daef5fbf89112c"
    },
    "clipper_exchange_address": "0x989E8F547FbCa65f4FB0af41e50e4058e6c68166",
    "extra_data": "0x000000000000000000000000000000000000000098b593221fc2d138f0a669c5000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000e475704f93603000000000000000000000000000000000000000000000000019257a485f5ec7000000",
    "deposit_amounts": [
        "0",
        "2000000000000000000"
    ],
    "lock_time": 720
}
```

#### Deposit With Specific output pool token

If you want to deposit and specify how many pool tokens receive.

***Request***

```bash
curl -X POST "https://blade-api.sushi.com/rfq/v2/deposit" \
-H "Content-Type: application/json" \
-d '{
  "sender": "0x54298A80a06068587E13b9dC1AC090259A98D5cD",
  "days_to_lock": 10,
  "chain_id": 10,
  "single_asset": true,
  "output_pool_tokens": 29438108002416884,
  "single_token": "0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1"
  "pool_address": "0x5130f6cE257B8F9bF7fac0A0b519Bd588120ed40"
}'
```

***Response***

```json
{
    "sender": "0x54298A80a06068587E13b9dC1AC090259A98D5cD",
    "n_days": 10,
    "pool_tokens": "29438108002416884",
    "good_until": 1729657750,
    "signature": {
        "v": 28,
        "r": "0x8abcd885e7c151158e21288124b6cac461088ecd9ac07938752667277de2f581",
        "s": "0x4716077b4ee2eaf0668d0c219c507581efa61c287e1bdfe32597fb5d19609641"
    },
    "clipper_exchange_address": "0x5130f6cE257B8F9bF7fac0A0b519Bd588120ed40",
    "amount": "1998512049104122112",
    "token": "0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1"
}
```


# API v1


# Overview

## Endpoints

Learn more about the different endpoints of the Swap API:

* [GET /rfq/pool](/disclaimers-and-technical/integrating-with-clipper-rfq/api-reference/api-v1/pool) - Get information about a blockchain network supported by Clipper.
* [POST /rfq/quote](/disclaimers-and-technical/integrating-with-clipper-rfq/api-reference/api-v1/quote) - Generate potential asset swap quotes. Obtain pricing and essential details for informed decision-making.
* [POST /rfq/sign](/disclaimers-and-technical/integrating-with-clipper-rfq/api-reference/api-v1/sign) - Facilitates blockchain transaction preparation and security by returning the required signature and data. Use it for efficient and secure asset swaps.

## Authorization

To prevent abuse of the API, we implement rate limits on requests. If you need to bypass these limits as an aggregator, please contact our support team to get API credentials (username and password) [here](mailto:aggregators@shipyardsoftware.org).

These credentials are used to authorize requests made to the following endpoints: <mark style="color:orange;">`/rfq/pool`</mark> , <mark style="color:orange;">`/rfq/quote`</mark> and <mark style="color:orange;">`/rfq/sign`</mark>

#### Basic Authentication

{% hint style="danger" %}
DEPRECATED: If you are using Basic Authentication, please contact us to receive an API key.
{% endhint %}

The API uses the Basic authentication method, where you must include the credentials (<mark style="color:orange;">`username:password`</mark>) in the headers in <mark style="color:orange;">`Base64`</mark> format.

**Example:**

If your username is "<mark style="color:orange;">`clipper`</mark>" and your password is "<mark style="color:orange;">`clipperdocs`</mark>", the Base64 encoded string for <mark style="color:orange;">`clipper:clipperdocs`</mark> is <mark style="color:orange;">`Y2xpcHBlcjpjbGlwcGVyZG9jcw==`</mark>.

```bash
curl --location 'https://api.clipper.exchange/rfq/quote' \
--header 'Authorization: Basic Y2xpcHBlcjpjbGlwcGVyZG9jcw==' \
--header 'Content-Type: application/json' \
--data '{
  "input_amount": "780000000000000",
  "input_asset_symbol": "ETH",
  "output_asset_symbol": "DAI",
  "time_in_seconds": 60,
  "chain_id": 1
}
'
```

#### Api Key Authentication

The API uses the API KEY authentication method. You have to include the credentials in the header <mark style="color:orange;">`x-api-key`</mark>.

Example: If your api key is <mark style="color:orange;">TzuiYrpRgN2</mark>

```bash
curl --location 'https://api.clipper.exchange/rfq/quote' \
--header 'x-api-key: TzuiYrpRgN2' \
--header 'Content-Type: application/json' \
--data '{
  "input_amount": "780000000000000",
  "input_asset_symbol": "ETH",
  "output_asset_symbol": "DAI",
  "time_in_seconds": 60,
  "chain_id": 1
}
'
```

{% hint style="danger" %}
The API v1 currently supports both API Key and Basic Authentication. However, Basic Authentication will be deprecated in the future. \
\
**Note**: The Pool endpoint currently only supports Basic Authentication. To use API Key authentication, use the [Pool V2](/disclaimers-and-technical/integrating-with-clipper-rfq/api-reference/api-v2/pool-v2) endpoint.
{% endhint %}

### Errors

#### Common Error Codes

<table><thead><tr><th width="118">Code</th><th>Reason</th></tr></thead><tbody><tr><td>400</td><td>Bad Request - Invalid data in the request</td></tr><tr><td>401</td><td>Unauthorized</td></tr><tr><td>403</td><td>Forbidden Error</td></tr><tr><td>500</td><td>Internal Server Error</td></tr><tr><td>503</td><td>External Service Error</td></tr></tbody></table>

#### Error Format

```json
{
    "errorMessage": "Description of the error",
    "errorType": "Type of the error",
    "errorCode": 422,  // it is returned only when we have a clipper code for the error
    "data": []  // is is returned only when the input data is invalid
}
```

{% hint style="warning" %} <mark style="color:orange;">`error_code`</mark> and <mark style="color:orange;">`data`</mark> are not always present
{% endhint %}

*Examples*&#x20;

1. If we make a request to [quote](/disclaimers-and-technical/integrating-with-clipper-rfq/api-reference/api-v1/quote) endpoint and the body does not have the field <mark style="color:orange;">`chain_id`</mark> (required param), the API response will look like similar to this:

```json
{
    "errorMessage": "Invalid input data",
    "errorType": "BadData",
    "errorCode": 422,
    "data": [
        {
            "type": "missing",
            "loc": [
                "chain_id"
            ],
            "msg": "Field required",
            "input": {
                "input_amount": "18000",
                "input_asset_symbol": "ETH",
                "output_asset_symbol": "WBTC",
                "time_in_seconds": 60
            },
            "url": "https://errors.pydantic.dev/2.1/v/missing"
        }
    ]
}
```

2. If we make a request to [quote](/disclaimers-and-technical/integrating-with-clipper-rfq/api-reference/api-v1/quote) endpoint and we send an <mark style="color:orange;">`input_asset_symbol`</mark> that clipper does not support, the API response will look like similar to this

```json
{
    "errorMessage": "input_asset_symbol: INVALIDASSET is not supported",
    "errorType": "BadData"
}
```

3. If we make a request to [quote](/disclaimers-and-technical/integrating-with-clipper-rfq/api-reference/api-v1/quote) endpoint and we send invalid credentials

```json
{
    "errorMessage": "Auth: Access is forbidden",
    "errorType": "Forbidden"
}
```

#### Clipper Error Codes

These codes appear in the field <mark style="color:orange;">`errorCode`</mark>

<table><thead><tr><th width="112">Code</th><th>Reason</th></tr></thead><tbody><tr><td>422</td><td>Invalid input data</td></tr><tr><td>409</td><td>Quote problems</td></tr></tbody></table>


# Pool

{% hint style="warning" %}
If you already have an API key for authentication, we recommend using [Pool v2](/disclaimers-and-technical/integrating-with-clipper-rfq/api-reference/api-v2/pool-v2) instead as it does not support API key authentication.
{% endhint %}

This endpoint provides comprehensive information about a clipper pool, including details on its assets, the contract address of its liquidity pool, and other pertinent data. This information is crucial for making off-chain calculations and predicting quotes.

## Request

<table><thead><tr><th width="178.33333333333331">Query Param</th><th>Description</th><th>Example</th></tr></thead><tbody><tr><td>chain_id</td><td>Integer - Required<br>ID of the chain.</td><td>chain_id=137 - Polygon<br>chain_id=1 - Ethereum mainnet</td></tr><tr><td>time_in_seconds</td><td><p>Integer - Optional</p><p>The time duration for which a quote will be available. This value is used to calculate the fees; as you decrease the time, you will see lower fees.</p><p>By default, the system sets a predefined value. </p><p><strong>Note:</strong> For on-chain data, this field is not considered.</p></td><td>time_in_seconds=30</td></tr><tr><td>fieldset</td><td><p>String - Optional<br>Determines whether the API should make calls to the blockchain to return on-chain data.</p><p><strong>Accepted Value</strong>: <mark style="color:orange;"><code>offchain-data</code></mark> If the parameter is not provided, it will default to handling on-chain data.</p></td><td>fieldset=offchain-data</td></tr></tbody></table>

## Response

#### Offchain object

<table><thead><tr><th width="133">Field</th><th>Description</th></tr></thead><tbody><tr><td>pool</td><td><a href="#pool-object">Pool object</a></td></tr><tr><td>assets</td><td>List of <a href="#asset-object">Asset objects</a></td></tr><tr><td>pairs</td><td>List of <a href="#pair-object">Pair objects</a></td></tr><tr><td>pool_type</td><td>String - <mark style="color:orange;"><code>offchain</code></mark></td></tr></tbody></table>

#### Pool object

<table><thead><tr><th width="248">Field</th><th>Description</th></tr></thead><tbody><tr><td>chain_id</td><td>Integer - ID of the chain</td></tr><tr><td>address</td><td>String(ETH address) - Clipper contract address of the pool, is the address used when executing a transaction</td></tr><tr><td>num_assets</td><td>Integer - The total of assets available in the chain</td></tr><tr><td>k</td><td>Float - K factor</td></tr><tr><td>time_in_seconds</td><td>Integer - Number of seconds were used to calculate the fees of a swap, this number indicates the number of seconds that quotes are live</td></tr><tr><td>default_time_in_seconds</td><td>Integer - Default number of seconds that quotes are live, is value used to calculate fees when don't send the query param <mark style="color:orange;"><code>time_in_seconds</code></mark></td></tr><tr><td>swaps_enabled</td><td>Bool - Represents if the swaps are available for the chain</td></tr></tbody></table>

#### Asset object

<table><thead><tr><th width="158">Field</th><th>Description</th></tr></thead><tbody><tr><td>name</td><td>String - The name of the asset, this value should be used when making a quote</td></tr><tr><td>address</td><td>String(ETH address) - The contract address of the asset</td></tr><tr><td>price_in_usd</td><td>Float - Current price in dollars for the asset</td></tr><tr><td>listing_weight</td><td>Integer - asset weight within the pool</td></tr></tbody></table>

#### Pair object

<table><thead><tr><th width="201">Field</th><th>Description</th></tr></thead><tbody><tr><td>assets</td><td>List[str] - Pair of assets available to make a swap - e.g: ["ETH", "MATIC"]</td></tr><tr><td>fee_in_basis_points</td><td>Float - Fee for make a swap between the pair</td></tr></tbody></table>

## Examples

Get the offchain data for Polygon chain (chain\_id=137)

***Request***

{% code overflow="wrap" %}

```bash
curl -X GET "https://api.clipper.exchange/rfq/pool?chain_id=137&fieldset=offchain-data" -H "Authorization: Basic dGVzdDp0ZXN0MTIzNA=="
```

{% endcode %}

***Response***

```json
{
    "pool": {
        "chain_id": 137,
        "address": "0x6Bfce69d1Df30FD2B2C8e478EDEC9dAa643Ae3B8",
        "num_assets": 6,
        "k": 0.115,
        "time_in_seconds": 60,
        "default_time_in_seconds": 60,
        "swaps_enabled": true
    },
    "assets": [
        {
            "name": "ETH",
            "address": "0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619",
            "price_in_usd": 1656.9150000000002,
            "listing_weight": 125
        },
        {
            "name": "MATIC",
            "address": "0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270",
            "price_in_usd": 0.56802,
            "listing_weight": 100
        },
        {
            "name": "WBTC",
            "address": "0x1BFD67037B42Cf73acF2047067bd4F2C47D9BfD6",
            "price_in_usd": 27405.915,
            "listing_weight": 178
        },
        {
            "name": "USDC",
            "address": "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174",
            "price_in_usd": 1.0,
            "listing_weight": 178
        },
        {
            "name": "DAI",
            "address": "0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063",
            "price_in_usd": 1.0,
            "listing_weight": 250
        },
        {
            "name": "USDT",
            "address": "0xc2132D05D31c914a87C6611C10748AEb04B58e8F",
            "price_in_usd": 1.0,
            "listing_weight": 305
        }
    ],
    "pairs": [
        {
            "assets": [
                "ETH",
                "MATIC"
            ],
            "fee_in_basis_points": 12.0
        },
        {
            "assets": [
                "ETH",
                "WBTC"
            ],
            "fee_in_basis_points": 6.0
        },
        {
            "assets": [
                "ETH",
                "USDC"
            ],
            "fee_in_basis_points": 8.0
        },
        {
            "assets": [
                "ETH",
                "DAI"
            ],
            "fee_in_basis_points": 8.0
        },
        {
            "assets": [
                "ETH",
                "USDT"
            ],
            "fee_in_basis_points": 8.0
        },
        {
            "assets": [
                "MATIC",
                "WBTC"
            ],
            "fee_in_basis_points": 12.0
        },
        {
            "assets": [
                "MATIC",
                "USDC"
            ],
            "fee_in_basis_points": 12.0
        },
        {
            "assets": [
                "MATIC",
                "DAI"
            ],
            "fee_in_basis_points": 12.0
        },
        {
            "assets": [
                "MATIC",
                "USDT"
            ],
            "fee_in_basis_points": 12.0
        },
        {
            "assets": [
                "WBTC",
                "USDC"
            ],
            "fee_in_basis_points": 8.0
        },
        {
            "assets": [
                "WBTC",
                "DAI"
            ],
            "fee_in_basis_points": 8.0
        },
        {
            "assets": [
                "WBTC",
                "USDT"
            ],
            "fee_in_basis_points": 8.0
        },
        {
            "assets": [
                "USDC",
                "DAI"
            ],
            "fee_in_basis_points": 5.0
        },
        {
            "assets": [
                "USDC",
                "USDT"
            ],
            "fee_in_basis_points": 5.0
        },
        {
            "assets": [
                "DAI",
                "USDT"
            ],
            "fee_in_basis_points": 5.0
        }
    ],
    "pool_type": "offchain"
}
```


# Quote

This endpoint facilitates the creation of a potential quote for executing a swap between two assets. It allows users to obtain pricing information and other essential details necessary to initiate asset swaps within the system. Use this endpoint to explore the potential cost and feasibility of asset exchanges before finalizing transactions.

## Request

<table><thead><tr><th width="210.33333333333331">Body Param</th><th width="328">Description</th><th>Example</th></tr></thead><tbody><tr><td>chain_id</td><td>Integer - Required<br>ID of the chain</td><td>"chain_id": 137</td></tr><tr><td>time_in_seconds</td><td>Integer - Optional<br>Amount of time between accepting a quote and receiving the quote on the blockchain. As this value increases, the quote will get worse for the user.</td><td>"time_in_seconds": 30</td></tr><tr><td>output_amount</td><td>Integer/String - Optional<br>Desired quantity of assets to receive as part of the swap<br>This field is mutually exclusive with <mark style="color:orange;"><code>input_amount</code></mark></td><td>"output_amount": "18000"<br>output_amount: 18000</td></tr><tr><td>input_amount</td><td>Integer/String - Optional<br>Desired quantity of assets you are willing to exchange<br>This field is mutually exclusive with <mark style="color:orange;"><code>output_amount</code></mark></td><td>"input_amount": "18000"<br>input_amount: 18000</td></tr><tr><td>input_asset_symbol</td><td>String - Required<br>Identifier of the asset you want to provide for the swap<br>Should correspond to the asset name returned from the <a href="/pages/snRZumQ9OXOeU5XeLlNY">pool</a> call</td><td>"input_asset_symbol": "ETH"</td></tr><tr><td>output_asset_symbol</td><td>String - Required<br>Identifier of the asset you want to receive in the swap<br>Should correspond to the asset name returned from the <a href="/pages/snRZumQ9OXOeU5XeLlNY">pool</a> call</td><td>"output_asset_symbol": "DAI"</td></tr></tbody></table>

## Response

Quote object

<table><thead><tr><th width="244">Field</th><th>Description</th></tr></thead><tbody><tr><td>id</td><td>String(UUID) - Id of the quote, use this value when signing a quote</td></tr><tr><td>must_accept_by</td><td>String - Human-readable UTC timestamp by which you must accept the quote and should be expected to be a short duration. If this time has passed already, request a new quote - the server will not sign a quote after <mark style="color:orange;"><code>must_accept_by</code></mark> has passed</td></tr><tr><td>good_until</td><td>Integer - number of seconds that quotes live</td></tr><tr><td>chain_id</td><td>Integer - Represents the ID of the chain</td></tr><tr><td>input_asset_address</td><td>String - Contract address of the asset you want to provide for the swap</td></tr><tr><td>input_amount</td><td>String - Amount of assets to be exchanged</td></tr><tr><td>output_asset_address</td><td>String - Contract address of the asset you want to receive in the swap</td></tr><tr><td>output_amount</td><td>String - Amount of assets you will receive in the exchange</td></tr><tr><td>input_value_in_usd</td><td>Float - Amount in dollars to be exchanged</td></tr><tr><td>output_value_in_usd</td><td>Float - Amount in dollars you will receive in the exchange</td></tr><tr><td>created_at</td><td>Integer - Unix Timestamp indicating the date and time when the quote was created</td></tr><tr><td>rate</td><td>Float - swap rate</td></tr></tbody></table>

## Examples

If you want to create a quote to make a swap from ETH to USDC in Ethereum Mainnet (chain\_id=1)

***Request***

```bash
curl -X POST "https://api.clipper.exchange/rfq/quote" \
-H "x-api-key: TzuY788jU6lOoj" \
-H "Content-Type: application/json" \
-d '{
  "input_amount": "10000000000000000000",
  "input_asset_symbol": "ETH",
  "output_asset_symbol": "USDC",
  "time_in_seconds": 60,
  "chain_id": 1
}'
```

***Response***

```json
{
    "id": "05a51aa6-41b5-4c61-a452-f1b95d0d43e4",
    "must_accept_by": "2023-10-13 22:24:20.932560+00:00",
    "good_until": 1697235920,
    "chain_id": 1,
    "input_amount": "10000000000000000000",
    "output_amount": "5661947917",
    "input_value_in_usd": 15595.15,
    "output_value_in_usd": 5668.12,
    "created_at": 1697235848,
    "rate": 566.1947917,
    "input_asset_address": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
    "output_asset_address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
}
```


# Sign

The endpoint plays a pivotal role in the preparation and execution of secure asset swaps on the blockchain. By providing a Quote ID and a destination address, users can initiate the signing process, resulting in the generation of the essential signature and transaction data. This signature and data package, in turn, is integral for ensuring the validity and security of asset transfers within the blockchain network.&#x20;

## Request

<table><thead><tr><th width="202.33333333333331">Body Param</th><th width="314">Description</th><th>Example</th></tr></thead><tbody><tr><td>quote_id</td><td>String(UUID) - Required<br>The id of the quote returned in <a href="/pages/UHqFseVynZQj78nvOhhj">quote</a> endpoint</td><td>"4c707e45-7019-4b81-b875-c5eb6fe061d6"</td></tr><tr><td>destination_address</td><td>String - Required<br>It will receive the output token</td><td>"0x960376b3F62f41E7e66809a05D1C5afdFD60A0E9"</td></tr><tr><td>sender_address</td><td>String - Optional<br>it is for DEX aggregator partners that are using their own smart contract to mediate the interaction between users and Clipper. Aggregators should use the address of the account that they will pull tokens from (i.e., the EOA user address) as opposed to the address of their deployed contract. This is an optional value on signing requests - by default, destination_address will be used.</td><td>"0x960376b3F62f41E7e66809a05D1C5afdFD60A0E9"</td></tr><tr><td>aux_data</td><td>String(bit32) - Optional<br>It is for use the calldata swap feature, it can be set to any string and is used for identification purposes in the event logs. By default is <mark style="color:orange;"><code>0x436c697070657200000000000000000000000000000000000000000000000000</code></mark> that is the representation of <mark style="color:orange;"><code>Clipper</code></mark></td><td> "0x31494e4348000000000000000000000000000000000000000000000000000000"</td></tr><tr><td>calldata</td><td>Bool - Optional<br>Send this as true if we want to get the bytes representation of the swap in the response. Client can use this to be sent directly to the pool contract for execution.<br>Default is <mark style="color:orange;"><code>false</code></mark></td><td>true</td></tr><tr><td>native_input</td><td>Bool - Optional<br>If the input token is native (e.g. raw ETH), this value must be true. This will use the <code>sellEthForToken</code> contract function and will take the msg.value for the input. e.g <mark style="color:orange;"><code>ETH -> USDC</code></mark><br>Default is <mark style="color:orange;"><code>false</code></mark><br>This field is mutually exclusive with <mark style="color:orange;"><code>native_output</code></mark></td><td>true</td></tr><tr><td>native_output</td><td>Bool - Optional<br>If the output token is native (i.e. raw ETH), this value must be true. This will use the <code>sellTokenForEth</code> contract function. e.g <mark style="color:orange;"><code>USDC -> ETH</code></mark><br>Default is <mark style="color:orange;"><code>false</code></mark><br>This field is mutually exclusive with <mark style="color:orange;"><code>native_input</code></mark></td><td>true</td></tr></tbody></table>

{% hint style="info" %}
In case that you want to deal with raw ETH or MATIC for input or output on the swap you should use <mark style="color:orange;">`native_input`</mark> and <mark style="color:orange;">`native_output`</mark> params. More details about Native Tokens can be found [here](/disclaimers-and-technical/integrating-with-clipper-rfq/guides/interacting-with-the-clipper-exchange-contracts#handling-native-currency).
{% endhint %}

## Response

Sign object

<table><thead><tr><th width="255">Field</th><th>Description</th></tr></thead><tbody><tr><td>chain_id</td><td>Integer - Represents the ID of the chain</td></tr><tr><td>input_asset_address</td><td>String - Contract address of the asset you want to provide for the swap</td></tr><tr><td>output_asset_address</td><td>String - Contract address of the asset you want to receive in the swap</td></tr><tr><td>input_amount</td><td>String - Amount of assets to be exchanged</td></tr><tr><td>output_amount</td><td>String - Amount of assets you will receive in the exchange</td></tr><tr><td>good_until</td><td>String - Number of seconds that quotes live. It can also contained a packed representation of the state</td></tr><tr><td>destination_address</td><td>String - Address will receive the output token</td></tr><tr><td>signature</td><td>Object - A <a href="https://eips.ethereum.org/EIPS/eip-2098">EIP 2098 "short signature" representation</a> for the signature from the Clipper Exchange server</td></tr><tr><td>clipper_exchange_address</td><td>String - Clipper contract address of the pool, is the address used when executing a transaction</td></tr><tr><td>calldata</td><td>String - Bytes representation of the swap function and parameters to be sent directly to the <mark style="color:orange;">clipper_exchange_address</mark> for execution</td></tr></tbody></table>

## Examples

#### Without calldata

If you want to sign a quote and manually use the values in the response to create the transaction.

***Request***

```bash
curl -X POST "https://api.clipper.exchange/rfq/sign" \
-H "x-api-key: TzuY788jU6lOoj" \
-H "Content-Type: application/json" \
-d '{
  "destination_address": "0x960376b3F62f41E7e66809a05D1C5afdFD60A0E9",
  "quote_id": "<QUOTE_ID>"
}'
```

***Response***

```json
{
    "chain_id": 1,
    "input_asset_address": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
    "output_asset_address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
    "input_amount": "10000000000000000000",
    "output_amount": "5661947917",
    "good_until": "364238673390486983853316167090878487969884185392043445686993915855904",
    "destination_address": "0x960376b3F62f41E7e66809a05D1C5afdFD60A0E9",
    "signature": {
        "v": 28,
        "r": "0xfb8599e4ef2c89b03e1ebc3067f0ba38ecea64517bafa932e5c642318ec923d9",
        "s": "0x1d3c7e38951b23bc459ac91ad668dede2a681bc4c98b915116983f4ae1dcdaa7"
    },
    "clipper_exchange_address": "0xE7b0CE0526fbE3969035a145C9e9691d4d9D216c"
}
```

#### With Calldata

1. If you want to sign a quote and get the bytes representation of the swap to be sent directly to the pool contract for execution.

***Request***

```bash
curl -X POST "https://api.clipper.exchange/rfq/sign" \
-H "x-api-key: TzuY788jU6lOoj" \
-H "Content-Type: application/json" \
-d '{
  "destination_address": "0x960376b3F62f41E7e66809a05D1C5afdFD60A0E9",
  "quote_id": "<QUOTE_ID>",
  "calldata": true,
  "aux_data": "0x31494e4348000000000000000000000000000000000000000000000000000000",
}'
```

***Response***

```json
{
    "chain_id": 1,
    "input_asset_address": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
    "output_asset_address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
    "input_amount": "10000000000000000000",
    "output_amount": "5661947917",
    "good_until": "364266596581665814407146313234570973398742125152679878859837657433201",
    "destination_address": "0x960376b3F62f41E7e66809a05D1C5afdFD60A0E9",
    "signature": {
        "v": 28,
        "r": "0x762ad0475b3a7c42735686d7911f117a2ff6fca1bc3c5c75f4ee43df8da2a61b",
        "s": "0x1eceffea0a50d12566e9fa6b4d9ed826106143d321389654c3c327c648f6f3f6"
    },
    "clipper_exchange_address": "0xE7b0CE0526fbE3969035a145C9e9691d4d9D216c",
    "calldata": "0x2b651a6c000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000008ac7230489e8000000000000000000000000000000000000000000000000000000000001517a780d0000000d82eb0b930000000005f7906e00b1a2bc2ec50000006400bc6529c471000000000000000000000000960376b3f62f41e7e66809a05d1c5afdfd60a0e9000000000000000000000000000000000000000000000000000000000000001c762ad0475b3a7c42735686d7911f117a2ff6fca1bc3c5c75f4ee43df8da2a61b1eceffea0a50d12566e9fa6b4d9ed826106143d321389654c3c327c648f6f3f60000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000002031494e4348000000000000000000000000000000000000000000000000000000"
}
```

2. If you want to sign a quote (using native input token) and get the bytes representation of the swap to be sent directly to the pool contract.

***Request***

```bash
curl -X POST "https://api.clipper.exchange/rfq/sign" \
-H "x-api-key: TzuY788jU6lOoj" \
-H "Content-Type: application/json" \
-d '{
  "destination_address": "0x960376b3F62f41E7e66809a05D1C5afdFD60A0E9",
  "quote_id": "<QUOTE_ID>",
  "calldata": true,
  "aux_data": "0x31494e4348000000000000000000000000000000000000000000000000000000",
  "native_input": true
}'
```

***Response***

```json
{
    "chain_id": 1,
    "input_asset_address": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
    "output_asset_address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
    "input_amount": "10000000000000000000",
    "output_amount": "5661947917",
    "good_until": "364126526759930684504042968316937832960196094624343681678885719229598",
    "destination_address": "0x960376b3F62f41E7e66809a05D1C5afdFD60A0E9",
    "signature": {
        "v": 28,
        "r": "0x1a8fc0856ff121e3ba5a244ee0837cef3d6c6ea96c593decc1b9d074c74c0139",
        "s": "0x60bd1d8700fca625b58cbc4fe84c61b29bf46c9855146eda18da557ab0e079d5"
    },
    "clipper_exchange_address": "0xE7b0CE0526fbE3969035a145C9e9691d4d9D216c",
    "calldata": "0x27a9b424000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000008ac7230489e8000000000000000000000000000000000000000000000000000000000001517a780d0000000d81968de90000000005f7911f00b1a2bc2ec50000006400bc6529c49e000000000000000000000000960376b3f62f41e7e66809a05d1c5afdfd60a0e9000000000000000000000000000000000000000000000000000000000000001c1a8fc0856ff121e3ba5a244ee0837cef3d6c6ea96c593decc1b9d074c74c013960bd1d8700fca625b58cbc4fe84c61b29bf46c9855146eda18da557ab0e079d50000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000002031494e4348000000000000000000000000000000000000000000000000000000"
}
```


# Troubleshooting & FAQs

### **403 Error with message “Unknown sender\_address” in sign API**

* The **sender\_address** is detected as unsafe (possibly bot).
* If the client is using a contract as router for the quote we need to whitelist the contract address in order to bypass the bot check.


# Terms of Service

Adopted: June 15, 2020

Welcome to the Clipper app ([www.clipper.exchange](http://www.clipper.exchange)), a website-hosted user interface (the “Interface”) made available by Shipyard Software Inc. (“we”, “our”, or “us”). The Interface provides access to a decentralized protocol on the Ethereum blockchain that allows users to trade cryptocurrencies on a peer-to-peer basis (the “Protocol”). Additionally, you can access the Protocol through third-party web or mobile interfaces. You are responsible for doing your own diligence on those interfaces to understand the fees and risks they present. These Terms of Use and any terms and conditions incorporated herein by reference (collectively, the “Terms”) govern your access and use of the Interface. You must read the Terms carefully. By accessing, browsing or otherwise using the Interface, or by acknowledging agreement to the Terms on the Interface, you agree that you have read, understood and accepted all of the Terms and our Privacy Policy (the “Privacy Policy”), which is incorporated by reference into the Terms. THE TERMS CONTAIN IMPORTANT INFORMATION, INCLUDING A BINDING ARBITRATION PROVISION AND A CLASS ACTION WAIVER, BOTH OF WHICH IMPACT YOUR RIGHTS AS TO HOW DISPUTES ARE RESOLVED. We may change, amend, or revise the Terms from time to time and at any time, in our sole discretion. When we make changes, we will make the updated Terms available on the Interface and update the “Last Updated” date at the beginning of the Terms accordingly. Please check the Terms periodically for changes. Any changes to the Terms will apply on the date that they are made, and your continued access or use of the Interface after the Terms have been updated will constitute your binding acceptance of the updates. If you do not agree to the revised Terms, then you should not continue to access or use the Interface.&#x20;

## 1. Eligibility&#x20;

In order to use the Interface, you must satisfy the following eligibility requirements:&#x20;

1\. you are of legal age in the jurisdiction in which you reside and you have legal capacity to enter into the Terms and be bound by them;&#x20;

2\. if you accept the Terms on behalf of a legal entity, you must have the legal authority to accept the Terms on that entity’s behalf, in which case “you” (except as used in this paragraph) will mean that entity;&#x20;

3\. you are not a resident, national or agent of Antigua and Barbuda, Algeria, Bangladesh, Bolivia, Belarus, Burundi, Myanmar (Burma), Cote D'Ivoire (Ivory Coast), Crimea and Sevastopol, Cuba, Democratic Republic of Congo, Ecuador, Iran, Iraq, Libya, Mali, Morocco, Liberia, Nepal, North Korea, Somalia, Sudan, Syria, Venezuela, Zimbabwe or any other country to which the United States, the United Kingdom or the European Union embargoes goods or imposes similar sanctions (collectively, “Restricted Territories”); (ii) you are not a member of any sanctions list or equivalent maintained by the United States government, the United Kingdom government, by the European Union or the United Nations (collectively, “Sanctions Lists Persons”); or (iii) you do not intend to transact with any Restricted Territories or Sanctions List Persons;&#x20;

4\. you are not a Restricted Person;&#x20;

5\. you are not a resident of, reside in, a citizen of, incorporated in, or have a registered office the Republic of China; and&#x20;

6\. your use of the Interface is not prohibited by and does not otherwise violate, assist you in the violation of any applicable laws or regulations, or contribute to or facilitate any illegal activity.&#x20;

## 2. Access to the Interface&#x20;

We reserve the right to disable access to the Interface at any time in the event of any breach of the Terms, including without limitation, if we reasonably believe that you, at any time, fail to satisfy the eligibility requirements set forth in the Terms. Further, we reserve the right to limit or restrict access to the Interface by any person or entity, or within any geographic area or legal jurisdiction, at any time and in our sole discretion. We will not be liable to you for any losses or damages you may suffer as a result of or in connection with the Interface being inaccessible to you at any time or for any reason.

## 3. Proprietary Rights&#x20;

1\. We own all intellectual property and other rights in the Interface and its contents, including, but not limited to, software, text, images, trademarks, service marks, copyrights, patents, and designs. Unless expressly authorized by us, you may not copy, modify, adapt, rent, license, sell, publish, distribute, or otherwise permit any third party to access or use the Interface or any of its contents. Accessing or using the Interface does not constitute a grant to you of any proprietary intellectual property or other rights in the Interface or its contents.&#x20;

2\. You will retain ownership of all intellectual property and other rights in any information and materials you submit through the Interface. However, by uploading such information or materials, you grant us a worldwide, royalty-free, irrevocable license to use, copy, distribute, publish and send this data in any manner in accordance with applicable laws and regulations.&#x20;

3\. You may choose to submit comments, bug reports, ideas or other feedback about the Interface, including, without limitation, about how to improve the Interface (collectively, “Feedback”). By submitting any Feedback, you agree that we are free to use such Feedback at our discretion and without additional compensation to you, and to disclose such Feedback to third parties (whether on a non-confidential basis, or otherwise). If necessary under applicable law, then you hereby grant us a perpetual, irrevocable, non-exclusive, transferable, worldwide license under all rights necessary for us to incorporate and use your Feedback for any purpose.&#x20;

4\. If you satisfy all of the eligibility requirements in the Terms and that your access to and use of the Interface complies with the Terms, you hereby are granted a single, personal, limited license to access and use the Interface. This license is non- exclusive, non-transferable, and freely revocable by us at any time without notice or cause. Use of the Interface for any purpose not expressly permitted by the Terms is strictly prohibited.&#x20;

## 4. Prohibited Activity&#x20;

You agree not to engage in, or attempt to engage in, any of the following categories of prohibited activity in relation to your access or use of the Interface:&#x20;

1\. Activity that breaches the Terms;&#x20;

2\. Activity that infringes on or violates any copyright, trademark, service mark, patent, right of publicity, right of privacy, or other proprietary or intellectual property rights under the law.&#x20;

3\. Activity that seeks to interfere with or compromise the integrity, security, or proper functioning of any computer, server, network, personal device, or other information technology system, including, but not limited to, the deployment of viruses and denial of service attacks.&#x20;

4\. Activity that seeks to defraud us or any other person or entity, including, but not limited to, providing any false, inaccurate, or misleading information in order to unlawfully obtain the property of another.&#x20;

5\. Activity that violates any applicable law, rule, or regulation concerning the integrity of trading markets, including, but not limited to, the manipulative tactics commonly known as spoofing and wash trading.&#x20;

6\. Activity that violates any applicable law, rule, or regulation of the United States or another relevant jurisdiction, including, but not limited to, the restrictions and regulatory requirements imposed by U.S. law.&#x20;

7\. Activity that disguises or interferes in any way with the IP address of the computer you are using to access or use the Interface or that otherwise prevents us from correctly identifying the IP address of the computer you are using to access the Interface.&#x20;

8\. Activity that transmits, exchanges, or is otherwise supported by the direct or indirect proceeds of criminal or fraudulent activity.&#x20;

## 5. No Professional Advice or Fiduciary Duties&#x20;

1\. All information provided in connection with your access and use of the Interface is for informational purposes only and should not be construed as professional advice. You should not take, or refrain from taking, any action based on any information contained in the Interface or any other information that we make available at any time, including, without limitation, blog posts, articles, links to third-party content, news feeds, tutorials, tweets and videos. Before you make any financial, legal, or other decisions involving the Interface, you should seek independent professional advice from an individual who is licensed and qualified in the area for which such advice would be appropriate.&#x20;

2\. The Terms are not intended to, and do not, create or impose any fiduciary duties on us. To the fullest extent permitted by law, you acknowledge and agree that we owe no fiduciary duties or liabilities to you or any other party, and that to the extent any such duties or liabilities may exist at law or in equity, those duties and liabilities are hereby irrevocably disclaimed, waived, and eliminated. You further agree that the only duties and obligations that we owe you are those set out expressly in the Terms.&#x20;

## 6. No Warranties&#x20;

The Interface is provided on an “AS IS” and “AS AVAILABLE” basis. To the fullest extent permitted by law, we disclaim any representations and warranties of any kind, whether express, implied, or statutory, including, but not limited to, the warranties of merchantability and fitness for a particular purpose. You acknowledge and agree that your access and use of the Interface is at your own risk. We do not represent or warrant that access to the Interface will be continuous, uninterrupted, timely, or secure; that the information contained in the Interface will be accurate, reliable, complete, or current; or that the Interface will be free from errors, defects, viruses, or other harmful elements. No advice, information, or statement that we make should be treated as creating any warranty concerning the Interface. We do not endorse, guarantee, or assume responsibility for any advertisements, offers, or statements made by third parties concerning the Interface.&#x20;

## 7. Compliance Obligations&#x20;

The Interface may not be available or appropriate for use in all jurisdictions. By accessing or using the Interface, you agree that you are solely and entirely responsible for compliance with all laws and regulations that may apply to you. You further agree that we have no obligation to inform you of any potential liabilities or violations of law or regulation that may arise in connection with your access and use of the Interface and that we are not liable in any respect for any failure by you to comply with any applicable laws or regulations.&#x20;

## 8. Assumption of Risk

By accessing and using the Interface, you represent that you understand (a) the inherent risks associated with products made available through the Protocol, and (b) the inherent risks associated with using cryptographic and blockchain-based systems. You further represent that you have a working knowledge of the usage and intricacies of blockchain-based digital assets, including, without limitation, ERC-20 token standard available on the Ethereum blockchain. You further understand that the markets for these blockchain-based digital assets are highly volatile due to factors that include, but are not limited to, adoption, speculation, technology, security, and regulation. You acknowledge that the cost and speed of transacting with blockchain-based systems, such as Ethereum, are variable and may increase or decrease, respectively, drastically at any time. You hereby acknowledge and agree that we are not responsible for any of these variables or risks associated with the Protocol and cannot be held liable for any resulting losses that you experience while accessing or using the Interface. Accordingly, you understand and agree to assume full responsibility for all of the risks of accessing and using the Interface to interact with the Protocol.&#x20;

## 9. Third-Party Resources and Promotions&#x20;

The Interface may contain references or links to third-party resources, including, but not limited to, information, materials, products, or services, that we do not own or control. In addition, third parties may offer promotions related to your access and use of the Interface. We do not endorse or assume any responsibility for any such resources or promotions. If you access any such resources or participate in any such promotions, you do so at your own risk, and you understand that the Terms do not apply to your dealings or relationships with any third parties. You expressly relieve us of any and all liability arising from your use of any such resources or participation in any such promotions.&#x20;

## 10. Release of Claims&#x20;

You expressly agree that you assume all risks in connection with your access and use of the Interface. You further expressly waive and release us from any and all liability, claims, causes of action, or damages arising from or in any way relating to your access and use of the Interface.&#x20;

## 11. Indemnity

You agree to hold harmless, release, defend, and indemnify us and our officers, directors, employees, contractors, agents, affiliates, and subsidiaries from and against all claims, damages, obligations, losses, liabilities, costs, and expenses arising from: (a) your access and use of the Interface; (b) your violation of the Terms, the rights of any third party, or any other applicable law, rule, or regulation; and (c) any other party’s access and use of the Interface with your assistance or using any device or account that you own or control.&#x20;

## 12. Limitation of Liability&#x20;

Under no circumstances shall we or any of our officers, directors, employees, contractors, agents, affiliates, or subsidiaries be liable to you for any indirect, punitive, incidental, special, consequential, or exemplary damages, including (but not limited to) damages for loss of profits, goodwill, use, data, or other intangible property, arising out of or relating to any access or use of the Interface, nor will we be responsible for any damage, loss, or injury resulting from hacking, tampering, or other unauthorized access or use of the Interface or the information contained within it. We assume no liability or responsibility for any: (a) errors, mistakes, or inaccuracies of content; (b) personal injury or property damage, of any nature whatsoever, resulting from any access or use of the Interface; (c) unauthorized access or use of any secure server or database in our control, or the use of any information or data stored therein; (d) interruption or cessation of function related to the Interface; (e) bugs, viruses, trojan horses, or the like that may be transmitted to or through the Interface; (f) errors or omissions in, or loss or damage incurred as a result of the use of, any content made available through the Interface; and (g) the defamatory, offensive, or illegal conduct of any third party. Under no circumstances shall we or any of our officers, directors, employees, contractors, agents, affiliates, or subsidiaries be liable to you for any claims, proceedings, liabilities, obligations, damages, losses, or costs in an amount exceeding the amount you paid to us in exchange for access to and use of the Interface, or $100.00, whichever is lesser. This limitation of liability applies regardless of whether the alleged liability is based on contract, tort, negligence, strict liability, or any other basis, and even if we have been advised of the possibility of such liability. Some jurisdictions do not allow the exclusion of certain warranties or the limitation or exclusion of certain liabilities and damages. Accordingly, some of the disclaimers and limitations set forth in the Terms may not apply to you. This limitation of liability shall apply to the fullest extent permitted by law.&#x20;

## 13. Dispute Resolution&#x20;

We will use our best efforts to resolve any potential disputes through informal, good faith negotiations. If a potential dispute arises, you must contact us by sending an email to <support@shipyardsoftware.org> so that we can attempt to resolve it without resorting to formal dispute resolution. If we are not able to reach an informal resolution within sixty days of your email, then you and we both agree to resolve the potential dispute according to the process set forth below. Any claim or controversy arising out of or relating to the Interface, the Terms, or any other acts or omissions for which you may contend that we are liable, including (but not limited to) any claim or controversy as to arbitrability (“Dispute”), shall be decided solely and exclusively by binding arbitration in the State of Delaware., administered by JAMS. Such arbitration shall be conducted in accordance with the then prevailing JAMS Streamlined Arbitration Rules & Procedures, with the following exceptions to such rules if in conflict: (a) one arbitrator shall be chosen by JAMS; (b) each party to the arbitration will pay an equal share of the expenses and fees of the arbitrator, together with other expenses of the arbitration incurred or approved by the arbitrator; and (c) arbitration may proceed in the absence of any party if written notice (pursuant to JAMS’ rules and regulations) of the proceedings has been given to such party. The parties agree to abide by all decisions and awards rendered in such proceedings. Such decisions and awards rendered by the arbitrator shall be final and conclusive. All such controversies, claims or disputes shall be decided in this manner in lieu of any action at law or equity. IF FOR ANY REASON THIS ARBITRATION CLAUSE BECOMES NOT APPLICABLE, THEN EACH PARTY (A) TO THE FULLEST EXTENT PERMITTED BY APPLICABLE LAW, HEREBY IRREVOCABLY WAIVES ALL RIGHT TO TRIAL BY JURY AS TO ANY ISSUE RELATING HERETO IN ANY ACTION, PROCEEDING OR COUNTERCLAIM ARISING OUT OF OR RELATING TO THIS SAFE OR ANY OTHER MATTERS INVOLVING THE PARTIES AND (B) SUBMITS TO THE EXCLUSIVE JURISDICTION AND VENUE OF THE FEDERAL OR DISTRICT COURTS LOCATED IN THE STATE OF DELAWARE., AND EACH PARTY AGREES NOT TO INSTITUTE ANY SUCH ACTION OR PROCEEDING IN ANY OTHER COURT IN ANY OTHER JURISDICTION. Each party irrevocably and unconditionally waives any objection that it may now or hereafter have to the laying of venue of any action or proceeding arising out of or relating to this Safe in the courts referred to in this Section 13.&#x20;

## 14. Class Action and Jury Trial Waiver&#x20;

You must bring any and all Disputes against us in your individual capacity and not as a plaintiff in or member of any purported class action, collective action, private attorney general action, or other representative proceeding. This provision applies to class arbitration. You and we both agree to waive the right to demand a trial by jury.&#x20;

## 15. Governing Law&#x20;

You agree that the laws of the state of Delaware, without regard to principles of conflict of laws, govern the Terms and any Dispute between you and us.&#x20;

## 16. Force Majeure&#x20;

We shall not be liable for delays, failure in performance or interruption of service which result directly or indirectly from any cause or condition beyond our reasonable control, including but not limited to, significant market volatility, any delay or failure due to any act of God, act of civil or military authorities, act of terrorists, civil disturbance, war, strike or other labor dispute, fire, interruption in telecommunications or Internet services or network provider services, failure of equipment and/or software, other catastrophe or any other occurrence which is beyond our reasonable control and shall not affect the validity and enforceability of any remaining provisions.&#x20;

## 17. Entire Agreement&#x20;

The Terms, including the Privacy Policy, constitute the entire agreement between you and us with respect to the subject matter hereof, including the Interface. The Terms, including the Privacy Policy, supersede any and all prior or contemporaneous written and oral agreements, communications and other understandings relating to the subject matter of the Terms.&#x20;

## 18. Privacy Policy&#x20;

The Privacy Policy describes the ways we collect, use, store and disclose your personal information. You agree to the collection, use, storage, and disclosure of your data in accordance with the Privacy Policy.


# Privacy Policy

Last updated July 23, 2021

This Privacy Policy (“Policy”) describes how Shipyard Software Inc. (“Shipyard,” “we,” “us” or “our”) may collect, use and disclose information, and your choices regarding this information. Please read this Policy carefully before using the Clipper automated market maker protocol (“Clipper”) and contact us with questions at [support@shipyardsoftware.org](mailto:privacy@shipyardsoftware.org).<br>

**APPLICABILITY OF THIS POLICY**

This Policy applies to our services, which include the services we provide on <https://clipper.finance> or any other websites, pages, features, mobile applications, or content we own or operate (collectively, the “Sites”) or when you use any Clipper API or third party applications relying on such an API, and related services (collectively, the “Services”). If you do not agree with the terms of this Policy, do not access or use the Services, Sites, or any other aspect of our business.

**WHAT WE COLLECT**

When you interact with our Services, we may collect:&#x20;

* Financial Information, such as your Ethereum wallet address and information, transaction history, and associated fees paid.
* Transaction Information, such as information about the transactions you make on our Services, such as the type of transaction, transaction amount, and timestamp.&#x20;
* Correspondence, such as your feedback, questionnaire and other survey responses, and information you provide to our support teams, including via our help chat.
* Online Identifiers, such as geo location/tracking details, browser fingerprint, operating system, browser name and version, and/or personal IP addresses.
* Usage Data, such as user preferences and other data collected via cookies and similar technologies.
* Information from cookies and other tracking technologies. We, and third parties we authorize, may Sites and mobile apps, and collect information about the use of the Services, as well as about our interactions with you. This information may include internet protocol (IP) addresses, browser type, internet service provider (ISP), referring/exit pages, operating system, date/time stamp, and clickstream data, and information about your interactions with the communications we send to you. We may combine this automatically collected log information with other information we collect about you. You may choose to set your web browser to refuse cookies, or to alert you when cookies are being sent. If you do so, please note that some parts of our Services may not function properly.

**HOW WE USE INFORMATION**

We use your information in accordance with your instructions, including any applicable terms in the Terms of Use, and as required by applicable law. We may also use the information we collect for:

**Providing Services and Features**

We may use the information we collect to provide, personalize, maintain, and improve our products and Services, including as we described in the Terms of Use. This includes using information to:&#x20;

* operate, maintain, customize, measure, and improve our Services, and manage our business;&#x20;
* process transactions;&#x20;
* send information, including confirmations, notices, updates, security alerts, and support and administrative messages; and&#x20;
* to create de-identified or aggregated data.

**Safety and Security**

We may use your information to help maintain the safety, security, and integrity of you and our Services, including to:

* protect, investigate, and deter against fraudulent, unauthorized, or illegal activity;
* monitor and verify identity or service access, combat spam, malware or security risks;
* perform internal operations necessary to provide our Services, including to troubleshoot software bugs and operational problems;
* enforce our agreements with third parties, and address violations of our Terms of Use or agreements for other Services; and
* comply with applicable security laws and regulations.

**User Support**

We may use information we collect to provide support, including to:

* direct questions to the appropriate support person;
* investigate and address user concerns; and
* monitor and improve our customer support responses and processes.

**Research and Development**

We may use the information we collect for testing, research, analysis, and product development to improve your experience. This helps us to improve and enhance the safety and security of our Services, improve our ability to prevent the use of our Services for illegal or improper purposes and develop new features and products relating to our Services.

**Legal and Regulatory Compliance**

We may verify your identity by comparing the personal information you provide against third-party databases and public records. We may use the information we collect to investigate or address claims or disputes relating to use of our Services, or as otherwise allowed by applicable law, or as requested by regulators, government entities, and official inquiries.

**Direct Marketing**

We may use the information we collect to market our Services to you. This may include sending you communications about our Services, features, promotions, surveys, news, updates, and events, and managing your participation in these promotions and events. If you do not want us to send you marketing communications, please opt out by selecting “unsubscribe” to any marketing email sent by us or by contacting us at <support@shipyardsoftware.org>.

**HOW WE SHARE & DISCLOSE INFORMATION**

We may share your information in the following circumstances:

* With Your Consent. For example, you may let us share personal information with others for their own marketing uses. Those uses will be subject to their privacy policies.&#x20;
* To Comply with Our Legal Obligations. We may share your information: (A) to cooperate with government investigations; (B) when we are compelled to do so by a subpoena, court order, or similar legal procedure; (C) when we believe in good faith that the disclosure of personal information is necessary to prevent harm to another person; (D) to report suspected illegal activity; or (E) to investigate violations of our User Agreement or any other applicable policies.
* With Service Providers. We may share your information with service providers who help facilitate business and compliance operations such as marketing and technology services. Our contracts require these service providers to only use your information in connection with the services they perform for us.
* During a Change to Our Business. If we engage in a merger, acquisition, bankruptcy, dissolution, reorganization, sale of some or all of our assets or stock, financing, public offering of securities, acquisition of all or a portion of our business, a similar transaction or proceeding, or steps in contemplation of such activities, some or all of your information may be shared or transferred, subject to standard confidentiality arrangements.
* Aggregated or De-identified Data. We may share aggregated and/or anonymized data with others for their own uses.

**DATA RETENTION**

To view or update your information, contact us at <support@shipyardsoftware.org>. We store your information throughout the life of your use of the Clipper and retain your information for a minimum of five years to comply with our legal obligations or to resolve disputes. If you cease using Clipper, we will neither use your information for any further purposes, nor sell or share your information with third parties, except as necessary to prevent fraud and assist law enforcement, as required by law, or in accordance with this Policy.

**SECURITY**

We maintain administrative, technical, and physical safeguards designed to protect the personal information we maintain against unauthorized access or disclosure. No system can be completely secure. Therefore, although we take steps to secure your information, we cannot guarantee that your information, searches, or other communication will always remain secure. You are responsible for all activity on Clipper relating to any of your Ethereum network addresses and/or cryptocurrency wallets.

**AGE LIMITATIONS**

To the extent prohibited by applicable law, we do not allow use of our Services and Sites by anyone younger than the legal age in the jurisdiction in which the user resides. If you learn that anyone younger than the legal age has unlawfully provided us with personal data, please contact us at <support@shipyardsoftware.org> and we will take steps to delete such information, close any such accounts, and, to the extent possible, prevent the user from continuing to use our Services.

**CHANGES TO THIS POLICY**

If we make any changes, we will change the Last Updated date above. We encourage you to review this Policy to stay informed. If we make material changes, we will provide additional notice, such as via the email specified in your account or through the Services or Sites.

**ONLINE TRACKING OPT-OUT GUIDE**

Like many companies online, we use services provided by Google and other companies that use tracking technology. These services rely on tracking technologies—such as cookies and web beacons—to collect directly from your device information about your browsing activities, your interactions with websites, and the device you are using to connect to the Internet. There are a number of ways to opt out of having your online activity and device data collected through these services, which we have summarized below:

* Blocking cookies in your browser. Most browsers let you remove or reject cookies, including cookies used for interest-based advertising. To do this, follow the instructions in your browser settings. Many browsers accept cookies by default until you change your settings. For more information about cookies, including how to see what cookies have been set on your device and how to manage and delete them, visit [www.allaboutcookies.org](http://www.allaboutcookies.org).
* Blocking advertising ID use in your mobile settings. Your mobile device settings may provide functionality to limit use of the advertising ID associated with your mobile device for interest-based advertising purposes. Using privacy plug-ins or browsers. You can block our websites from setting cookies used for interest-based ads by using a browser with privacy features.
* Platform opt-outs. The following advertising partner offers opt-out features that let you opt-out of use of your information for interest-based advertising — Google: <https://adssettings.google.com>. Advertising industry opt-out tools. You can also use the opt-out options set forth below to limit use of your information for interest-based advertising by participating companies. Note that because these opt-out mechanisms are specific to the device or browser on which they are exercised, you will need to opt out on every browser and device that you use. Digital Advertising Alliance: <http://optout.aboutads.info> Network Advertising Initiative: <http://optout.networkadvertising.org/>

**NOTICE TO CALIFORNIA RESIDENTS**

We are required by the California Consumer Privacy Act of 2018 (“CCPA”) to provide this CCPA Notice to California residents to explain how we collect, use and share their personal information, and the rights and choices we offer California residents regarding our handling of their personal information.

**CCPA Scope and Exclusions**

This CCPA Notice, including the description of our Privacy Practices and your Privacy Rights, apply only to California residents whose interactions with us are limited to:

* visiting our consumer websites; and
* signing up for email alerts; and

This CCPA Notice does not apply to the personal information we collect, use or disclose about:

* individuals who provide information to us to initiate or complete the process of interacting with our platform, which are subject to the notice set forth in the Additional Disclosure section of this Policy; or
* representatives of businesses that seek to obtain our products or services, or to provide products or services to us.

**Privacy Practices**

We do not “sell” the personal information we collect (as such term is defined in the CCPA) for monetary value (and will not sell it without providing a right to opt out). Like many companies, we may use third-party cookies for our advertising purposes. If you would like to learn how you may opt out of our use of cookies and other tracking technologies, please review the instructions provided in the Online Tracking Opt-out Guide section of this Policy.

**Privacy Rights**

The CCPA grants individuals the following rights:

* Information. You can request information about how we have collected, used and shared your personal information during the past 12 months. For details about the personal information we have collected over the last 12 months, including the categories of sources, please see the What We Collect section of this Policy. We collect this information for the business and commercial purposes described in the How We Use Information section of this Policy. We share this information with the categories of third parties described in the How We Share and Disclose Information section of this Policy.
* Access. You can request a copy of the personal information that we maintain about you.
* Deletion. You can ask us to delete the personal information that we collected or maintain about you.

Please note that the CCPA limits these rights by, for example, prohibiting us from providing certain sensitive information in response to an access request and limiting the circumstances in which we must comply with a deletion request. We will also respond to requests for information and access only to the extent we are able to associate with a reasonable effort the information we maintain with the identifying details you provide in your request. If we deny your request, we will communicate our decision to you. You are entitled to exercise the rights described above free from discrimination.

**How to Submit a Request**

To request access to or deletion of personal information to <support@shipyardsoftware.org>.

**Identity Verification**

The CCPA requires us to verify the identity of the individual submitting a request to access or delete personal information before providing a substantive response to the request. We will ask you to verify your identity when you submit a request.&#x20;

**Authorized Agents**

California residents can empower an “authorized agent” to submit requests on their behalf. We will require the authorized agent to have a written authorization confirming that authority.&#x20;

**ADDITIONAL DISCLOSURE FOR OUR CONSUMERS AND CUSTOMERS**

This Additional Disclosure governs our collection, use and sharing of personal information that users provide to us to initiate or complete the process of interacting with Clipper. To the extent there are conflicting provisions between this Additional Disclosure and other sections of the Privacy Policy, the Additional Disclosure will govern.

The types of personal information we collect and share can include:

* Contact details
* Transaction history
* Cryptocurrency balances and wallets When you are no longer our customer, we continue to share your information as described in this notice.

**Reasons We Can Share Your Personal Information**

We need to share users’ personal information to operate certain aspects of Clipper and our business. Below, whether we share your personal information, the reasons we share your personal information and whether you can limit this sharing

* We share users’ personal information for our everyday business purposes, such as to process and match your orders and respond to court orders and legal investigations. You cannot limit our sharing of this information.
* We share users’ personal information for our marketing purposes, such as to offer our products and services to you. You cannot limit our sharing of this information.
* We do not share users’ personal information for joint marketing with financial companies.&#x20;
* We do not share users’ personal information for our affiliates’ everyday business purposes.
* We do not share users’ personal information for our affiliates to market to you.
* We do not share users’ personal information for nonaffiliates to market to you.

**How Does Shipyard Protect My Personal Information?**

To protect your personal information from unauthorized access and use, we use security measures that comply with federal law. These measures include computer safeguards and secured ﬁles and buildings.&#x20;

**How Does Shipyard Collect My Personal Information?**

We collect your personal information, for example, when you deposit Digital Assets in Clipper, make transactions using the Clipper, or withdraw Digital Assets from Clipper. We may also collect your personal information from other companies.

**Why Can’t I Limit All Sharing?**

Applicable laws give you the right to limit only (1) sharing for affiliates’ everyday business purposes, (2) affiliates from using your information to market to you, and (3) share for nonaffiliates to market to you. We do not share any information to any of those parties for those reasons; thus, you may not limit sharing of information.

State laws and individual companies may give you additional rights to limit sharing. See below for more on your rights under state law.

As used in this Additional Disclosure section, “affiliates” refer to companies related by common ownership or control; “nonaffiliates” refer to companies no related by common ownership or control; and “joint marketing” refers to a formal agreement between nonaffiliated financial companies that together market financial products or services to you.

**CONTACT US**

Please contact us if you have any questions about this Policy or if you are seeking to exercise any of your statutory rights. We will respond within a reasonable timeframe. You may contact us at <support@shipyardsoftware.org>.


