# 关于Saddle

Saddle是一个自动做市商（AMM），旨在实现固定价值加密资产之间的高效交易。Saddle上线的同时也推出了代币化比特币矿池，使其用户能在renBTC、WBTC、sBTC、和renBTC之间进行交易并提供流动性。

Saddle是从[Thesis](https://thesis.co/)分拆出来之子公司，而母公司Thesis则是[tBTC](https://tbtc.network/)、[Keep](https://keep.network/)和[Fold](https://foldapp.com/)等项目背后的加密风险投资公司。

## 了解固定价值加密资产

### 什么是固定价值加密资产？

固定价值加密资产是指透过某种方式，将其价值与一基础资产挂钩。以稳定币或代币化比特币为例，这些货币的价值永远都分别是1美元。

目前固定价值加密资产能透过不同的机制来将其价值固定，某些资产，例如sBTC或sUSD，是运用综合的的方式来维持他们的挂钩（此例是透过抵押SNX）。还有一些资产则是透过实际基础资产的支持和可赎性，来维持其挂钩，而这个机制亦或不需要许可（例如tBTC），亦或需经过集中保管人（例如WBTC、USDC）。

这些不同的方式和相关的风险是为什么同一类型的固定价值加密资产会有轻微的价格波动。

### 固定价值加密资产有什么问题？

此类的资产交易可能成本高昂且效率低下，最后因为高滑点和交易手续费而导致资本损失。

### Saddle如何解决该问题？

为解决固定价值加密资产间交易的问题，Saddle对此提供一款经过专门设计改良的AMM，让用户能以最小滑点在这些资产之间进行交易。

## Saddle的解决方案

### 比特币为一等公民

比特币是市值最大的加密货币，且以太坊（Ethereum）上代币化比特币的数量仍持续呈爆炸式的增长—2020年的供应量已增加了高达[135](https://btconethereum.com/)倍。但尽管如此，代币化比特币在功能与支持方面通常不会被优先考虑。我们深信比特币应被视为DeFi中的一等公民。

### Virtual Synth功能支持

Virtual Synths是[SIP-89](https://sips.synthetix.io/sips/sip-89)所引入的一个Synthetix新特性。在“[关于Virtual Synths以及何处寻找他们](https://blog.synthetix.io/virtual-synths/)”一文中，SNX创始人Kain Warwick完整的概述了其潜在的发展。简而言之，Virtual Synths能够使Saddle平台上的任何资产实现大型、低滑点的交易。我们正积极的进行此项整合，并会在不久的将来分享更多相关细节。Virtual Synths是开启固定价值加密资产之间深层链上流动性的关键，而我们的目标是成为Synthetix生态系统的首要出入通道。

### 奖励机制留住LP

DeFi协议仍在不停探讨如何适当的激励及留住流动性提供者（LPs）。其中一种常见的机制是取款时的固定百分比费用（例如Yearn Vaults）。但是这种机制无法奖励长期的流动性提供者。为解决此问题，Saddle重新配置了取款费用，使该费用在一个月内减少至0。在另行通知前，此费用将于上线后暂时取消。我们现正努力研商更多其他的方式来激励LP，敬请保持关注！

### 安全性

保障用户资金的安全性是我们的首要之务。Saddle[运用Solidity](https://github.com/saddle-finance/saddle-contract)来实现[StableSwap](https://www.curve.fi/stableswap-paper.pdf)算法。使用任何涉及资金的代码皆需要格外的谨慎和详尽的审查，这也是为什么我们透过[Certik](https://certik.foundation/)、[Quantstamp](https://quantstamp.com/)、和[Open Zeppelin](https://openzeppelin.com/)，连续进行了三次智能合约审计。[点击这里阅读审计报告](https://github.com/saddle-finance/saddle-audits)。除此之外，我们还执行了名为“治理证明”（Proof of Governance）的[受保护启动](https://medium.com/electric-capital/derisking-defi-guarded-launches-2600ce730e0a)，下面将有更多细节。

## 关注Saddle最新消息

请到[Discord](https://discord.gg/hX8RZFBW9R)、[Twitter](https://twitter.com/saddlefinance)、[Telegram](https://t.me/saddle_finance)、[Github](https://github.com/saddle-finance)、和[Medium](https://medium.com/saddle)上关注我们。


# 常见问题解答

回答您关于AMM、代币化比特币、和Saddle app等的相关问题。

还有更多问题吗？[加入我们的Discord](https://discord.gg/hX8RZFBW9R)

## 问题和解答

### 什么是Saddle？

Saddle是一款针对固定价值加密资产的自动做市商（AMM）。Saddle能使任何持有固定价值加密资产的用户以最小滑点在其他固定资产之间进行交易，从而确保用户不会在进行交易时损失资产价值。

### 什么是代币化比特币？

代币化比特币是从比特币区块链被“存款”到以太坊区块链的BTC。此时，BTC会被保存于一存款合同中，该合同接着在以太坊上“铸造”和BTC具有相同价值的代币，但是此代币却具有ERC-20代币的所有功能。代币化比特币包括了tBTC、renBTCc、WBTC、和sBTC等。

### 什么是固定价值加密资产？

固定价值加密资产是指透过某种方式，将其价值与一基础资产挂钩。以稳定币或代币化比特币为例，这些货币的价值永远都分别是1美元。

目前固定价值加密资产能透过不同的机制来将其价值固定，某些资产，例如sBTC或sUSD，是运用综合的的方式来维持他们的挂钩（此例是透过抵押SNX）。还有一些资产则是透过实际基础资产的支持和可赎性，来维持其挂钩，而这个机制亦或不需要许可（例如tBTC），亦或需经过集中保管人（例如WBTC、USDC）。

这些不同的方式和相关的风险是为什么同一类型的固定价值加密资产会有轻微的价格波动。

### 为什么Saddle的启动要使用代币化比特币？

比特币是市值最大的加密货币，且以太坊上代币化比特币的数量仍持续呈爆炸式的增长—2020年的供应量已增加了高达135倍。但尽管如此，代币化比特币在功能与支持方面通常不会被优先考虑。我们深信比特币应被视为DeFi中的一等公民。

### Saddle也会支持其他资产池吗？何时开始？

会的！我们日后将会开始支持其他固定价值加密资产的交易，例如稳定币和以太坊代币。这些资产池预计会在2021年第一或第二季度上线。

### Saddle有发行代币吗？

Saddle目前没有发行代币。

### Saddle的受保护启动—“治理证明”是什么？有谁能参与？

Saddle上线时启用了治理证明（PoG），借此实施一定的限制来保护我们的用户，防止女巫攻击。起初，TVL资金池的上限为150 BTC，且每一个地址的存款限额为1 BTC，尔后这些限制将会于每1至2周提高一次。

若LP欲符合PoG资格，该地址必须透过下列任一方式来证明其积极的网路参与：

* 链上投票或委托 (MKR, COMP, YFI, YAM, CRV, UNI, UMA, Moloch DAO)
* [Snapshot](https://snapshot.page/)链下投票（所有协议）
* 抵押SNX和铸造sUSD (>$20)

[这里提供了完整的合格地址清单](https://github.com/saddle-finance/saddle-allowlist-addresses)。PoG只是暂时的，并会在将来被逐步淘汰。

我们采用此种受保护的启动是为了建立一个更可控的环境，以确保平稳的启动、减少变数、并在一个可控的环境下对用户的资金负责。我们的首要目标是要确保应用程序运行无碍、保障用户资金的安全、以及使我们的支持者、开发人员、和用户皆对于我们能成功并公正启动的能力保有信心。

*受保护的启动并不适用于AMM。用户能立即在启动时在不同代币化比特币类型之间进行交易。*

### 为什么当我使用Saddle时会收到“很抱歉，这个地址没有存款的资格…”的信息？

Saddle的启动使用了名为治理证明（PoG）的受保护启动。若您看到错误信息，代表您所使用的钱包尚未在上列的治理过程中使用过。您可以尝试连接另一个钱包，或者等待受保护的启动结束。

### 谁可以使用Saddle？

在启动时，**每个人都**可以使用Saddle的AMM在代币化比特币配对之间进行交易。

然而在启动时，欲在Saddle上成为流动性提供者的用户必须参与过特定的治理过程， 您可参考“Saddle的受保护启动，‘治理证明’，是什么？…”问题来了解更多细节。

### 如何使用Saddle？

进入[Saddle App](https://saddle.exchange)便能立即开始使用！

### Saddle的流动性提供者可获得什么奖励？

Keep Network团队已承诺每周提供250,000 KEEP作为流动性提供者的奖赏。这意味着若达到TVL上限，LP能获得高达\~30%的年度百分比收益率（APY）！[点击这里](https://keep.network/)了解更多关于Keep Network、KEEP、和抵押KEEP以增加APY的机会。

### 什么是tBTC？

tBTC是第一个真正去中心化、具安全性的代币化比特币，其安全性受到Keep Network的保护。而Keep Network则是一种保护隐私权的区块链解决方案。Keep Network将铸造tBTC的密钥储存在去中心化的“keeps”里，因而消除了中心化的弱点。

### 碍于受保护的启动，我无法为Saddle提供流动性。什么时候我才能开始使用Saddle呢？

受保护的启动会随着时间被逐步淘汰，届时任何人都能为Saddle的资金池提供流动性。

同时，任何人都能透过Saddle 的AMM在不同代币化比特币类型之间进行交易。

### 使用Saddle需要多少费用？

在启动时，从Saddle资金池取款不需任何费用。接着我们会采用费用递减机制，将费用在您首次提供流动性后的一个月内递减至0bps。

### 是谁创建了Saddle？

Saddle是由一群DeFi专家所创建，他们皆具有在Uber、Amazon、和Square等Web2公司多年的开发经验。您可能已经在YFI社区中与我们的创始人[Sunil](https://www.linkedin.com/in/sunilsrivatsa/)（亦称为[devops199fan](https://twitter.com/devops199fan)，是位多重签名的持有者）有过互动，或者已使用过我们团队成员所创建的工具，例如[John](https://www.linkedin.com/in/jongseunglim/)（亦称为[Weeb\_Mcgee](https://twitter.com/Weeb_Mcgee)）的[yieldfarming.info](https://yieldfarming.info/)。

### Saddle安全吗？

Saddle已经过Certik、Quantstamp、和Open Zeppelin等公司的审计。[点击这里](https://github.com/saddle-finance/saddle-audits)阅读审计报告。

### 如何关注Saddle?

[Discord](https://discord.gg/hX8RZFBW9R)! [Twitter](https://twitter.com/saddlefinance)! [Telegram](https://t.me/saddle_finance)! [Github](https://github.com/saddle-finance)! [Medium](https://medium.com/saddle)!


# About Saddle

Saddle is an automated market maker (AMM) designed to enable efficient trading between pegged value crypto assets.

{% hint style="danger" %}
The Saddle DAO voted to wind down the protocol by pausing all pools and dissolving the community multisig in [SIP-54](https://vote.saddle.community/#/proposal/0x271aef6b1d04cf08878b33d304add4827da146dc7b1ca12d802a3922e29ad34b).  Users are advised to withdraw their funds [here](https://saddle.exchange/#/pools).
{% endhint %}

## **About Saddle**

Saddle is a decentralized automated market maker ([AMM](https://docs.saddle.finance/automated-market-makers)) on the Ethereum blockchain, optimized for trading [pegged value crypto assets](https://docs.saddle.finance/saddle-faq#what-are-pegged-value-crypto-assets-pegged-assets) with [minimal slippage](https://docs.saddle.finance/saddle-faq#what-is-a-slippage). Saddle enables cheap, efficient, swift, and low-slippage swaps for traders and high-yield pools for LPs. We believe in [collaboration](https://docs.saddle.finance/build-with-saddle), in building Saddle as a DeFi lego block, in helping DeFi teams bring AMMs to any blockchain.

## **Why Saddle?**

**Saddle stands for DeFi**: We commit ourselves to [open-source software](https://github.com/saddle-finance) and collaboration to fulfil the promise of DeFi, of financial Lego blocks.

**Saddle is safe & legit**: Saddle protocol is audited and secured by leading blockchain security firms like Certik, Quantstamp, and OpenZeppelin. Read the audits [here](https://github.com/saddle-finance/saddle-audits).

**Saddle is collaborative and fun to work with**: We root our ethos in the desire to [support](https://docs.saddle.finance/build-with-saddle) the DeFi ecosystem and partner with like-minded protocols.

## **How do I learn more about Saddle?**

To get an introduction to the features and ecosystem of Saddle, follow these links.

| Section                                                                        | Description                                                                                                                                                                                   |
| ------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [Automated Market Makers](https://docs.saddle.finance/automated-market-makers) | AMMs democratized cryptocurrency trading by doing away with order books and institutional market makers. Learn about the fundamentals and various swap algorithms.                            |
| [Saddle Pools](https://docs.saddle.finance/saddle-pools)                       | Saddle Pools are the liquidity pools in Saddle Finance. Learn about various liquidity pools, how to deposit and withdraw, fees, rewards, and risks.                                           |
| [Saddle Incentives](https://docs.saddle.finance/saddle-incentives)             | Saddle rewards the liquidity providers for their contribution to the liquidity pools. Learn about terminologies, rewards available, and staking LP token to earn incentives.                  |
| [Saddle Protocol Stats](https://docs.saddle.finance/saddle-protocol-stats)     | Learn about the key stats and the analytics tools available to interpret Saddle protocol.                                                                                                     |
| [Yield Farming Tools](https://docs.saddle.finance/yield-farming-tools)         | Yield farming is an incentive mechanism to put your assets to work and generate high returns. Learn about the tools which offer convenient information about Saddle pools and your liquidity. |
| [Build With Saddle](https://docs.saddle.finance/build-with-saddle)             | We welcome an opportunity to work with you. Learn about our values, support for growing the DeFi ecosystem, and ways to collaborate with us.                                                  |
| [Smart Contract Security](https://docs.saddle.finance/smart-contract-audit)    | We hire well reputed external agencies to audit our smart contract codes. Learn about the certifications for Saddle’s smart contracts.                                                        |
| [Asset Specific Risks](https://docs.saddle.finance/asset-specific-risks)       | Before we accept a cryptocurrency for the Saddle pools, we evaluate the underlying risks for the assets and operations of the asset.                                                          |
| [Saddle FAQ](https://docs.saddle.finance/saddle-faq)                           | Frequently asked questions on Saddle Finance, Liquidity Pools, Pegged Assets, Rewards and Incentives.                                                                                         |
| [Glossary](https://docs.saddle.finance/glossary)                               | This Glossary consists of terms and definitions used across Saddle.                                                                                                                           |
| [Contract Addresses](https://docs.saddle.finance/contracts)                    | The Saddle’s Contract Addresses are listed here.                                                                                                                                              |
| [Solidity Docs](https://docs.saddle.finance/solidity-docs)                     | Developer documents for Saddle protocol and how to interact with it.                                                                                                                          |
| [Code Repository](https://github.com/saddle-finance)                           | Saddle's source-code repository on GitHub                                                                                                                                                     |

Cannot find what you are looking for? You can use the search and navigation options available.

![Navigation & Search Panels](/files/-MlEk15Ebn8URJ4RQNxl)

## **Who built Saddle?**

Saddle is built by DeFi natives with prior years of developer experience at Web2 companies like Uber, Amazon, and Square. As regular DeFi users ourselves, we’ve seen first-hand how important an active and vibrant community is for a project’s success. We know Web2, but we know Web3 better.

You might have interacted with our founder [Sunil](https://www.linkedin.com/in/sunilsrivatsa/) (aka [devops199fan](https://twitter.com/devops199fan)) in the YFI community (he’s a multisig signer), or used tools created by members of our team, like [yieldfarming.info](https://yieldfarming.info) by [John](https://www.linkedin.com/in/jongseunglim/) (aka [Weeb\_Mcgee](https://twitter.com/Weeb_Mcgee)).

## **How do I trade on Saddle?**

Visit [https://saddle.exchange/](https://saddle.exchange) to start trading.

## **How do I work with Saddle?**

Check out [Build with Saddle](https://docs.saddle.finance/build-with-saddle) on ways to collaborate.

## **How can I follow Saddle?**

You can keep up with us on any of these channels.

| Channel     | Link                                                           |
| ----------- | -------------------------------------------------------------- |
| Saddle Blog | [https://blog.saddle.finance/](https://blog.saddle.finance)    |
| Discord     | [https://discord.gg/hX8RZFBW9R](https://discord.gg/qEtPn5pBvk) |
| Twitter     | <https://twitter.com/saddlefinance>                            |
| GitHub      | <https://github.com/saddle-finance>                            |
| Telegram    | <https://t.me/saddle_finance>                                  |

## **Logos & Media Kit**

You can download Saddle's logo, guidelines, and brand assets from [here](https://drive.google.com/drive/folders/13rTY6x24crioqOgyGCE6zJo0197AMVtD?usp=share_link).


# Automated Market Makers

AMMs democratized cryptocurrency trading by doing away with order books and institutional market makers.

## **MARKETS**

Markets facilitate trade in a society by connecting the sellers to the buyers. Trading of goods, services, or information (assets collectively) happens in a purpose-built marketplace. For instance, a local community might have a farmers’ market to trade locally produced vegetables and fruits. Whilst a stock market like New York Stock Exchange (NYSE) allows global participants to trade in stocks. A traditional market comprises buyers, sellers, brokers-dealers, and market makers.

Let’s look at the fundamentals first.

***Buyer**:* A person or an organization buying, planning to buy, or agrees to buy assets.

***Seller**:* A person or an organization selling, planning to sell, or agrees to sell assets.

***Broker-Dealer**:* A person or an organization buying and/or selling on behalf of its customers or for their own. The person/organization acts as a *broker (or agent)* when executing orders on behalf of the client and acts as a *dealer (or principal)* when trades for their own account.

***Bid:*** Buyers make a bid, specifying the price they will pay and the quantity required.

***Ask:*** Sellers offer an ask price, specifying the price they will sell and the quantity available.

***Bid-Ask Spread***: The difference between the Ask and the Bid. For example, if the sellers’ ask is $55 and the buyers’ bid is $53, the bid-ask spread is $2. The bid-ask spread determines the market liquidity. For heavily traded assets, the bid-ask spread will be tighter (narrow). However, for assets with little demand or sparsely traded, the bid-ask spread may be high or even unknown.

***Liquidity:*** Refers to how easily and quickly assets are bought or sold *without* affecting the asset's price. If there is a high volume of trade, the bid-ask spread should be narrow for the asset traded. Therefore, liquid. Contrarily, when there is a wide (or unknown) bid-ask spread, then the asset is illiquid.

***Market Maker**:* Market makers (MM) help keep the market functioning by actively buying and selling assets. MMs can be an individual or an organization providing liquidity to the market by transacting on both sides of the market (buy and sell). For example, the MM might offer a Bid for $20/stock and Ask for $20.05/stock. Market makers earn a profit through the bid-ask spread and carry a risk of price variations during Buy-Hold-Sell cycle. The common type of market maker are the brokerage houses.

***Slippage***: Slippage results from a change in bid-ask spread. There is a time delay between the trade request and execution in the market. During this time, if the bid-ask spread changes, then slippage occurs.

***Order Book**:* Most modern financial markets are order-driven (buy-sell) markets. At the heart of the trade is an order book; an electronic register of the list of buy and sell orders. A typical order book has three parts – buy orders, sell orders, and order history. The order book helps improve market transparency, help traders make informed decisions, and identifies participants and price of a trade.

***Exchange***: Exchange is a market where trading is conducted. For example, New York Stock Exchange (NYSE), London Stock Exchange (LSE), or the Cryptocurrency exchanges like Saddle, Binance, Coinbase, or Uniswap.

## **CRYPTOCURRENCY EXCHANGES**

A cryptocurrency exchange is a marketplace for trading cryptocurrencies. Broadly, two types of cryptocurrency exchanges exist:

***Centralized Exchanges (CEX)***: A cryptocurrency exchange owned and governed by a 3rd party. E.g., Binance, Coinbase, and Bitfinex.

***Decentralized Exchanges (DEX)***: A cryptocurrency exchange, unlike CEX, is not owned or governed by a 3rd party. A DEX acts as a peer-to-peer (P2P) platform, facilitating trade with no central party. E.g., [Saddle](https://saddle.exchange/#/), Uniswap, Sushiswap, and Mdex.

The DEX ecosystem is nascent and maturing. Despite few shortcomings, compared to CEX, decentralized exchanges grew in popularity. The allure of removing middlemen, lower fees, and decentralization pushed the adoption of DEX.

### **Order Book Challenges**

The early version of the cryptocurrency exchanges used the order book model, like traditional exchanges. The order book model works well where the trade volumes and liquidity are high, resulting in lower [slippages](https://docs.saddle.finance/saddle-faq#what-is-max-slippage). Leading cryptocurrencies, like Bitcoin and Ethereum, have high volumes of trade. While other cryptocurrencies and tokens, which don’t have high volumes, faced challenges with the order book model.

In the illustration below, the seller's Ask is $20.50 and the buyer's Bids are not closer to the Ask. This results in a liquidity challenge. Market makers, therefore, step in to keep the market functioning by actively buying and selling assets - i.e., transacting on both sides to keep the market functioning. The market makers carry the risk of a price variation during Buy-Hold-Sell cycle.

![](/files/-Mkpc523XmbnX5grYZJx)

The main issue is related to high slippages and volatility due to low volumes of trade. The absence of market makers round the clock further constrained the liquidity. Automated Market Makers (AMM), therefore, emerged as a solution to the order book challenge.

## **AUTOMATED MARKET MAKER (AMM)**

Market makers are essential in an exchange to provide liquidity, control spreads, and maintain slippages. Since cryptocurrency exchanges work 24x7, the need for automated market makers rose. AMMs democratized cryptocurrency trading by doing away with order books and institutional market makers. Instead, AMMs execute trade automatically using [algorithms ](https://docs.saddle.finance/saddle-faq#how-does-saddle-work)and [liquidity pools](https://docs.saddle.finance/saddle-faq#what-is-a-saddle-pool). Let’s understand a few basic concepts first.

***Permissionless:*** Unlike traditional exchanges, permission-less networks require no permission to join and interact with the blockchain network. Permission-less AMMs allow anyone with an internet connection to become a part of the market to trade.

***Liquidity Pools***: Instead of an order book, AMMs use liquidity pools to facilitate trade. Liquidity pool, a smart contract, is a fund of tokens (or coins). In AMMs, traders interact with the smart contracts, to enable liquidity and price discovery. Because of the permissionless nature, AMMs allow anyone to provide liquidity to the liquidity pool. The liquidity pool smart contract holds two or more tokens and allows anyone to deposit and withdraw funds from them, but only according to specific mathematical rules.

***Liquidity Providers***: Liquidity providers contribute assets (cryptocurrency tokens and coins) to liquidity pools. In exchange for providing the tokens, the LPs normally earn a fee. Now, when a trade executes on an AMM, the trade executes against the liquidity pool. This eliminates the need for an order book and for the buyer and seller to be present at that moment in time.

***Algorithm***: AMMs use an [algorithm ](https://docs.saddle.finance/automated-market-makers#amm-swap-algorithms)(mathematical formula) for pricing the assets, thus replacing the order book mechanism. There are variations of the pricing formula deployed currently, which we will cover later.

***Yield Farming***: [Yield farming](https://docs.saddle.finance/saddle-faq#what-is-yield-farming) is an incentive mechanism to put an individual’s cryptocurrency assets to work and generate high returns. Liquidity providers, in yield farming protocols, stake or lock up their assets to earn rewards and higher interests.

![](/files/-Mkpc524vvTBjrre0zB8)

***Impermanent Loss***: Though the AMM model offers better stability and returns, there is a risk of impermanent loss – a temporary loss experienced by liquidity providers because of volatility in the liquidity pool assets. In simple terms, if the liquidity provider had held onto the asset, without providing it as a liquidity to the pool, the individuals would have had more money/value. But impermanent loss is a temporary situation as the AMMs regulate the price closer to market, eventually.

## **AMM SWAP ALGORITHMS**

Having understood what AMMs are, let’s now deconstruct them. You can think of an AMM as a friendly and obedient market maker bot, always willing to quote a price, no matter the time of the day or day of the week.

To quote you a price, the bot uses a mathematical formula (used interchangeably with pricing algorithm or swap algorithm) and works relentlessly in the background. The algorithm implemented varies from the simplex to the complex. We’ll look at the commonly used swap algorithms, including the [StableSwap algorithm](https://docs.saddle.finance/automated-market-makers#stableswap-algorithm) used by Saddle.

{% hint style="info" %}
Find Saddle's StableSwap implementation code [here](https://github.com/saddle-finance/saddle-contract/blob/master/contracts/Swap.sol)
{% endhint %}

### **Constant Product Formula**

Constant product formula is probably the simplest and the earliest algorithm to come into the market. Uniswap popularized the mathematical formula:

**x \* y = k**

where **x** is the amount of Token#1 in the liquidity pool, **y** is the amount of Token#2 in the liquidity pool, and **k** is a fixed constant.

Let’s look at a few critical aspects from the example below. An ETH-USDT liquidity pool is set-up with 100 ETH and 300,000 USDT, provided by the liquidity providers. As the pool is set-up, the initial conditions are:

|                     |                    |                   |                      |
| ------------------- | ------------------ | ----------------- | -------------------- |
| **USDT: ETH PRICE** | **USDT Liquidity** | **ETH Liquidity** | **Constant Product** |
| 3000 : 1            | 300,000            | 100               | 30,000,000           |
| **Initial price**   | **x**              | **y**             | **k**                |

When a trader wants to swap the tokens in the pool, the formula will try to achieve the constant product equilibrium. For example, if a trader wants to swap USDT for 1 ETH, then to maintain a constant product of 30,000,000 the price quoted for USDT will be 3,030.30 (a premium of 1% over the initial setup price) and the liquid pool composition after the swap will be:

|                     |                    |                   |                      |
| ------------------- | ------------------ | ----------------- | -------------------- |
| **USDT: ETH PRICE** | **USDT Liquidity** | **ETH Liquidity** | **Constant Product** |
| 3030.30 : 1         | 303,030.30         | 99                | 30,000,000           |
| **1% premium**      | **x**              | **y**             | **k**                |

Likewise, if a trader wants to swap USDT for 5 ETH, the price quoted by the algorithm will be 3,157.89 (a premium of 5.3% over the initial setup price) and the liquid pool composition after the swap will be:

|                     |                    |                   |                      |
| ------------------- | ------------------ | ----------------- | -------------------- |
| **USDT: ETH PRICE** | **USDT Liquidity** | **ETH Liquidity** | **Constant Product** |
| 3157.89 : 1         | 315,789.47         | 95                | 30,000,000           |
| **5.26% premium**   | **x**              | **y**             | **k**                |

Uniswap first implemented the constant product formula and Balancer refined it with a generalized formula. But there is a challenge.

The constant product formula determines the price when someone trades against the liquidity pool. As we see from the chart below, we calculate the price as a ratio of the tokens in the pool. The pricing curve has a hyperbola when plotted against two tokens. When someone withdraws, say Token#1, the proportionate Token#2 to be deposited, to maintain the constant product, varies.

![](/files/-Mkpc525vfk-4CWaYfjL)

Given the volatile nature of cryptocurrency, the market price of the tokens also fluctuates. The constant product formula *does not update* the price of the tokens in the pool with the market movement. In certain cases, the price update is a simple [off-chain observation](https://docs.uniswap.org/protocol/V2/concepts/advanced-topics/pricing). This resulted in the risk of higher slippages.

Thanks to [arbitrageurs](https://docs.balancer.fi/core-concepts/protocol/pools#weighted-pools), once they find a cheaper price, they’ll move the funds around liquid pools for profit making. Eventually, the price in the liquidity pools starts stabilizing closer to the market price. This does not, however, eliminate the slippage challenge in full.

### **Constant Sum Formula**

To address the slippage issue, AMMs explored the constant sum formula as an option. Constant sum formula solves for the equation:

**x + y = k**

where **x** is the amount of Token#1 in the liquidity pool, **y** is the amount of Token#2 in the liquidity pool, and **k** is a fixed constant.

While the constant sum formula solves the slippage problem, it provides only *fixed liquidity*. For markets to function well, they need a constant supply of liquidity and hence this model didn’t suit the purpose well.

![](/files/-Mkpc526lat8cLBh11Mo)

### **Stableswap Algorithm**

The innovation into AMMs mathematical formula continued to find a solution to the slippage (constant product formula) and fixed liquidity (constant sum formula) problems. Hybrid mathematical models, combining the best of many models, rose to prominence. One such model is the Stableswap algorithm.

First introduced by [Curve](https://curve.fi/whitepaper), the Stableswap is a hybrid algorithm. The Stableswap hybrid combines both Constant Product and Constant Sum models, and the following chart shows the Stableswap algorithm in relation to constant product and constant sum invariants.

![](/files/-MkpaFB4dLtNlGQrAgU-)

* **Constant Sum:** When the liquidity pool portfolio is balanced, the algorithm functions as a Constant Sum formula; **x + y = k**. You can observe the StableSwap ***blue line*** staying close to the Constant Sum ***red line***, and the price is stable.
* **Constant Product:** As the liquidity pool portfolio becomes imbalanced, the StableSwap algorithm functions as a Constant Product formula; **x \* y = k**. You can observe the StableSwap ***blue line*** now resembling the Constant Product ***purple line***, and the price becoming expensive.

{% hint style="info" %}
Find Saddle's StableSwap implementation in Solidity [here](https://github.com/saddle-finance/saddle-contract/blob/master/contracts/Swap.sol)
{% endhint %}

## **PEGGED-VALUE ASSETS**

Saddle liquidity pools implement the StableSwap mathematical formula to reduce slippage and keep the market liquid. Saddle facilitates trades of stablecoins, where the price is [pegged ](https://docs.saddle.finance/saddle-faq#pegged-value-assets)to an underlying asset, bringing in further stability. For example:

***USDT***: A stablecoin pegged 1:1 to the USD fiat currency as the underlying asset.

***DAI***: A stablecoin soft pegged to the USD algorithmically.

***FRAX***: A fractional-algorithmic stablecoin that is partially backed by collateral and partially stabilized algorithmically.

***wBTC***: An ERC20 token backed 1:1 by the actual Bitcoin.

***alETH***: An ERC20 token, but backed 4:1 by ETH.

### **Dynamic Pegs**

The Constant Product formula *does not update* the price of the tokens in the pool with the market movement. The Stableswap formula motivates swaps around price ratio 1.0, well suited for stablecoins. Dynamic pegs are the next evolution of AMMs.

Dynamic pegs will bring the benefits of Stableswaps to cryptocurrency assets which aren’t pegged to another asset. By using an automatic price change mechanism, the algorithm will move the price based on real-time profit margin calculations, to adjust for slippages. Thus, benefiting both the traders and the AMMs.


# Saddle Pools

Saddle Pools are the liquidity pools in Saddle Finance.

## **LIQUIDITY POOLS**

Traditional exchanges use order books to facilitate trade. The centrally managed order books represent the buy and sell orders placed by individuals, derive the price of an asset, and match buyers to sellers. The emergence of the decentralized finance (DeFi) ecosystem turned the concept of order book on its head with [Automated Market Makers](https://docs.saddle.finance/automated-market-makers) (AMM).

AMMs in DeFi use algorithms to price assets and facilitate trade. Staying true to the philosophy of DeFi, AMMs are permissionless, automatic, and available 24/7. Therefore, there are no buyers and sellers (in the traditional sense) in AMMs. Instead, AMMs use [liquidity pools](https://docs.saddle.finance/saddle-faq#what-is-a-saddle-pool) for the trade.

Liquidity pool, a smart contract, is a fund of tokens. The liquidity providers deposit the tokens into the pool. Anyone with an internet connection and holding tokens can become a [liquidity provider](https://docs.saddle.finance/saddle-faq#who-is-a-liquidity-provider) (LP). In exchange for providing the tokens, the LPs normally earn a fee. Now, when a trade executes on an AMM, the trade executes against the liquidity pool. This eliminates the need for an order book and for the buyer and seller to be present at that moment in time.

### **Fees**

Trading on a Saddle pool carries two fees – a trading fee and a gas fee.

***Trading fee**:* The trading fee applies to every trade and the prevailing fee is displayed in the pool information. Typically, the fee is 0.04%. However, the fee may vary depending on the pool.

***Admin fee**:* The admin fee is included as a % of the trading fee. Currently it is zero.

***Gas fee**:* The fee payable to Ethereum network to confirm the transactions. The [gas fee](https://www.gasnow.org) varies depending on the speed of confirmation time required and represented in gwei (1 gwei = 10`-9` ETH).

{% hint style="info" %}
Find Saddle's fee calculation code [here](https://github.com/saddle-finance/saddle-contract/blob/38328fba920abd10bfe3ac9fde98e7c9cc50af9a/contracts/Swap.sol#L81)
{% endhint %}

![](/files/P21IGH1KPIoaO6hzq9ZK)

### **Rewards**

Saddle [rewards ](https://docs.saddle.finance/saddle-incentives)the liquidity providers for their contribution to the liquidity pool. Depending on the liquidity pool, the rewards structure varies. There are many ways to earn rewards – interest from trading fees, interest from lending, and pool specific incentives. We have covered the details of rewards under the liquidity pool sections below.

{% hint style="info" %}
Find Saddle's reward calculation code [here](https://github.com/saddle-finance/saddle-contract/blob/master/contracts/helper/MiniChefV2.sol)
{% endhint %}

### **Risks**

As with any investment, traditional or DeFi, providing liquidity to the pools carries a risk. Typically, the risks include risk of smart contracts, risks associated with the tokens/Stablecoins in the liquidity pools, and/or the risks associated with the AMMs. We outline the risks in the [Saddle pool risk](https://docs.saddle.finance/saddle-pools#saddle-pool-risks) section.

## **USING SADDLE POOLS**

Working with Saddle pools is easy. You can lend, borrow, and earn interest & rewards by using Saddle pools. By depositing assets into Saddle pools, you become a liquidity provider eligible to earn trading fees. At any time of your choice, you can withdraw your assets.

### **Deposit**

Depositing assets into a pool on Saddle allows users to take part in the protocol as liquidity providers and earn reward incentives. Go to <https://saddle.exchange/#/pools>

* **Step 1:** Choose the pool on the top navigation bar
* **Step 2:** Click on *Deposit*

![](/files/XYZmK3JSv7d5giTFyMJQ)

* **Step 3:** Enter the amount(s) you would like to deposit on one or more of the assets listed in the Saddle pool. (*Tip: deposit underweight assets to get an LP token bonus*).
* **Step 4:** Click *Advanced Options* to select options like slippage and gas.

![](/files/-MkBipyE_WiSXprR4UPF)

* **Step 5:** Click *Deposit* and review the details and confirm the transaction. *(Tip: If you are depositing into a* [*Metapool*](https://docs.saddle.finance/saddle-faq#what-is-a-base-pool-and-metapool)*, you have the **option** of depositing individual assets or depositing LP tokens from the* [*base pool*](https://docs.saddle.finance/saddle-faq#what-is-a-base-pool-and-metapool)*)*

![](/files/-MkBR5yxxIoAyyOJcSfi)

* **Step 6:** After the transaction confirms, stake your LP tokens to earn rewards (details under pool section).
* **Step 7:** Keep track of your rewards!

{% embed url="<https://www.youtube.com/watch?v=RCsBinGAZEg>" %}

{% hint style="info" %}
Find Saddle's smart contract code [here](https://github.com/saddle-finance/saddle-contract/blob/38328fba920abd10bfe3ac9fde98e7c9cc50af9a/contracts/Swap.sol#L387)
{% endhint %}

### **Withdraw**

If at any point you want to withdraw your assets, head out to <https://saddle.exchange/#/pools>

**1. Unstaking LP Tokens**

If you have staked your LP tokens for rewards (applicable for select Saddle Pools only), you must unstake the tokens first before withdrawing your asset.

* **Step 1:** Go to the rewards dashboard as applicable in your case ([KEEP Rewards](https://dashboard.keep.network/liquidity), [ALCX Rewards](https://app.alchemix.fi/farms), [FRAX Rewards](https://app.frax.finance/staking))
* **Step 2:** Unstake your LP Tokens

**2. Withdraw Assets**

After unstaking your LP Tokens (where applicable), return to [Saddle Pools](https://saddle.exchange/#/pools) and follow the steps outlined below to withdraw your assets.

* **Step 1:** Choose the pool on the top navigation bar
* **Step 2:** Click on *Withdraw*

![](/files/F7I64Ya2qWPoPAY0Fu0M)

* **Step 3:** Enter the amount you’d like to withdraw from one or more of the assets listed in the Saddle pool. (*Tip: withdraw overweight assets to get a bonus*).
* **Step 4:** Click *Advanced Options* to select options like slippage and gas.

![](/files/-Mjcgd1C7YKeIm3fejtc)

* **Step 5:** Click *Withdraw* and review the details and confirm the transaction.

{% hint style="info" %}
Find Saddle's smart contract code [here](https://github.com/saddle-finance/saddle-contract/blob/38328fba920abd10bfe3ac9fde98e7c9cc50af9a/contracts/Swap.sol#L314)
{% endhint %}

## **CHOOSING A SADDLE POOL**

[Stablecoins ](https://docs.saddle.finance/saddle-faq#what-are-stablecoins)are becoming popular because of the stability they bring to the volatile crypto world. Stablecoins also come in various flavors – backed by assets (e.g., fiat currency, gold), cryptocurrencies, and algorithmically stabilized.

Saddle supports a [wide range](https://docs.saddle.finance/saddle-faq#what-tokens-are-currently-supported-by-saddle) of Stablecoins, giving users the flexibility to choose and move between Stablecoins of their choice. Therefore, the list of Stablecoins supported by Saddle keeps growing. In this section, we will explain how you can choose various Stablecoin pools, the rewards and risks specific to the pools.

Broadly, there are three types of pools to select from – BTC, ETH, and USD.

![](/files/qa3izpzYxQvb8TrQl5lJ)

### **Base Pool & Metapool**

Saddle pools are of two types – base and metapools.

* ***Base pools*** contain two or more tokens and implement the StableSwap algorithm.
* ***Metapools*** contain one token to trade with another underlying Base pool. For example, in the sUSD Pool, we pool the single token sUSD alongside Stablecoin Pool V2 (DAI, USDC, USDT). Adding the single asset to the metapool, however, does not dilute the liquidity of the underlying base pool.

|              |                    |           |                          |                                                                                                                            |                                                                                                  |
| ------------ | ------------------ | --------- | ------------------------ | -------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
| **CATEGORY** | **POOL**           | **TYPE**  | **TOKENS**               | **STATUS**                                                                                                                 | **REWARDS**                                                                                      |
| BTC          | BTC Pool           | Base Pool | wBTC, renBTC, sBTC, tBTC | Outdated - [Migrate](https://docs.saddle.finance/saddle-incentives#migrating-incentives-to-tbtc-metapool) to tBTC Metapool | <ul><li>N/A</li></ul>                                                                            |
| BTC          | BTC Pool V2        | Base Pool | wBTC, renBTC, sBTC       | Live                                                                                                                       | <ul><li>Trading fees</li></ul>                                                                   |
| BTC          | tBTC Pool          | Metapool  | tBTCv2, saddleBTC-V2     | Live                                                                                                                       | <ul><li>Trading fees</li><li>KEEP Incentives</li></ul>                                           |
| ETH          | alETH Pool         | Base Pool | WETH, alETH, sETH        | Live                                                                                                                       | <ul><li>Trading fees</li><li>ALCX incentives</li><li>Flash loan fees</li></ul>                   |
| ETH          | vETH2 Pool         | Base Pool | WETH, VETH2              | Paused                                                                                                                     | N/A                                                                                              |
| USD          | Stablecoin Pool    | Base Pool | DAI, USDC, USDT          | Outdated – [Migrate](https://medium.com/saddle/launching-v2-of-the-saddle-3pool-bc82f0bcd700) to V2                        | N/A                                                                                              |
| USD          | Stablecoin Pool V2 | Base Pool | DAI, USDC, USDT          | Live                                                                                                                       | <ul><li>Trading fees</li><li>Flash loan fees</li></ul>                                           |
| USD          | D4 Pool            | Base Pool | alUSD, FEI, FRAX, LUSD   | Live                                                                                                                       | <ul><li>Trading fees</li><li>Flash loan fees</li><li>TRIBE, FXS, LQTY, ALCX incentives</li></ul> |
| USD          | sUSD Pool          | Metapool  | sUSD, saddleUSD-V2       | Live                                                                                                                       | <ul><li>Trading fees</li><li>Flash loan fees</li></ul>                                           |
| USD          | wCUSD Pool         | Metapool  | wCUSD, saddleUSD-V2      | Live                                                                                                                       | <ul><li>Trading fees</li></ul>                                                                   |

{% hint style="info" %}
Find Saddle's deployed code base [here](https://github.com/saddle-finance/saddle-contract/tree/master/deployments)
{% endhint %}

### **BTC Pool**

The BTC pool currently supports four wrapped variants of Bitcoin, enabling Bitcoin users to take part in the Ethereum DeFi ecosystem.

* *wBTC*: Wrapped BTC is an ERC20 token backed 1:1 by the actual Bitcoin.
* *renBTC*: Like wBTC, renBTC is an ERC20 token backed 1:1 by Bitcoin. Ren also decentralizes the custody of the BTC.
* *tBTC*: Like Ren, tBTC is backed 1:1 by Bitcoin and truly decentralized.
* *sBTC*: sBTC differs from the rest, as Bitcoins does not back it. The value of sBTC is kept stable through an over-collateralization mechanism leveraging Synthetix SNX tokens.

![](/files/-MkBR5z1sL7OIET67ipl)

**Rewards**

**Note: BTC Pool is outdated. Follow the** [**migration**](https://docs.saddle.finance/saddle-incentives#migrating-incentives-to-tbtc-metapool) **guide to move your assets and KEEP incentives to the new tBTC Metapool.**

Saddle rewards you in two ways for the BTC pool – trading fees and as KEEP incentives every time you provide liquidity to the BTC pool.

The Keep Network team has committed weekly reward incentives for liquidity providers. After the transaction confirms, stake your LP tokens on the [KEEP Liquidity Rewards Dashboard](https://dashboard.keep.network/liquidity) in the Saddle Pool to earn KEEP rewards. Check [KEEP](https://dashboard.keep.network/liquidity) to know the current APY for the deposits.

![](/files/O2cTub9pn9kL7gAyhgB0)

### **BTC Pool V2**

The BTC pool V2 currently supports three wrapped variants of Bitcoin, enabling Bitcoin users to take part in the Ethereum DeFi ecosystem.

* *wBTC*: Wrapped BTC is an ERC20 token backed 1:1 by the actual Bitcoin.
* *renBTC*: Like wBTC, renBTC is an ERC20 token backed 1:1 by Bitcoin. Ren also decentralizes the custody of the BTC.
* *sBTC*: sBTC differs from the rest, as Bitcoins does not back it. The value of sBTC is kept stable through an over-collateralization mechanism leveraging Synthetix SNX tokens.

![](/files/jYlYStSg1zQwyQdLVvWP)

**Rewards**

Saddle rewards you with trading fees for the BTC Pool V2.

### **tBTC Pool**

The Saddle tBTC Pool is a metapool. In this pool, we pooled the single token tBTCv2 alongside BTC Pool V2 (wBTC, renBTC, sBTC). Adding the single asset to the metapool, however, does not dilute the liquidity of the underlying base pool.

* *tBTCv2*: tBTC is backed 1:1 by Bitcoin and truly decentralized.
* *saddleBTC-V2*: A base pool (BTC Pool V2) on Saddle comprising the pegged assets wBTC, renBTC, and sBTC.

![](/files/Gt53Oa2lmnPQmgHndIe8)

**Rewards**

Saddle rewards you in two ways for the tBTC pool – trading fees and as KEEP incentives every time you provide liquidity to the tBTC pool.

After the transaction confirms, stake your LP tokens on the [KEEP Liquidity Rewards Dashboard](https://dashboard.keep.network/liquidity) in the Saddle Pool to earn KEEP rewards. Check [KEEP ](https://dashboard.keep.network/liquidity)to know the current APY for the deposits.

![](https://lh5.googleusercontent.com/YLb-mQ8N0Sw-CVM8LlqRAA32zU_YIviHuvjQ8Kq-govkGMtixSItgPfRCi42Wm-KmvPEwe3PiDyeuwBsha_KZ94Hn6etEku7K5ja5PYN91IyMa9CxQobaNQKHwcSkR9qnP5wNsQ)

### **alETH Pool**

The ETH pool on Saddle is of alETH – a synthetic ETH backed asset by Alchemix. alETH is a multi-pool currently supporting three variants of Ethereum, enabling seamless and cheap switch between pegged-value ETH assets (backed or wrapped).

* *WETH*: Wrapped ETH is an ERC20 token backed 1:1 by ETH, allowing trade directly with ALT coins.
* *alETH*: Like WETH, alETH is an ERC20 token, but backed 4:1 by ETH.
* *sETH*: sETH is a short position built through the dYdX protocol and can be traded like any ERC20 token. sETH is tied to USD-backed stablecoin DAI.

![](/files/xl8sHiFnnwCMOklsWAKm)

**Rewards**

Saddle rewards you trading fees, flash loan fees, and ALCX tokens every time you provide liquidity to the alETH pool. After the transaction confirms, stake your LP tokens on the [Alchemix Staking Dashboard](https://app.alchemix.fi/farms) to earn rewards. Check [ALCX](https://app.alchemix.fi/farms) to know the current APY for the deposits.

![](/files/QN15W7Gp7dx5iD5zBajp)

### **Stablecoin Pool V2**

The Stablecoin pool contains three stablecoins, unlocking deep on-chain liquidity between pegged value crypto assets.

* *USDC*: USDC is an ERC20 token pegged 1:1 to the US dollars (USD)
* *USDT*: USDT, like USDC, is pegged 1:1 to the USD
* *DAI*: DAI is soft pegged to the USD algorithmically.

**Note:** Stablecoin Pool (v1) is outdated and V2 is live now. V2 provides a smoother and cheaper way to provide liquidity and swap the stablecoins. V2 also comes with optimized code (lower gas costs), metapool, [flash loan](https://docs.saddle.finance/howtoflashloan) support, and no more withdrawal fee.

Follow [this guide](https://medium.com/saddle/launching-v2-of-the-saddle-3pool-bc82f0bcd700) to migrate your liquidity to V2.

![](/files/-MkBR5z7uu0UzLeB9dR6)

**Rewards**

Saddle rewards you in two ways for the stablecoin pool - trading fees and flash loan fees. The Stablecoin Pool V2 live supports flash loans, which will generate additional returns for liquidity providers.

### **D4 Pool**

The Saddle D4 (decentralized) pool consists entirely of permissionless, decentralized stablecoins. Stablecoins like USDC, USDT, and Dai are not permissionless – centralized organizations manage them with varying degrees of transparency.

In contrast, the Saddle D4 pool, currently composed of four permissionless stablecoins, ensures users can take part with no restrictions or blacklisting.

* *alUSD*: A yield-backed synthetic stablecoin minted via Alchemix Finance, a DAO-governed synthetic asset platform.
* *FEI*: A scalable and decentralized stablecoin that leverages protocol-controlled value (PCV) for peg maintenance while maintaining highly liquid secondary markets.
* *FRAX*: A fractional-algorithmic stablecoin that is partially backed by collateral and partially stabilized algorithmically.
* *LUSD*: The USD-pegged stablecoin of the Liquity decentralized borrowing protocol.

![](/files/qJeek0HhybqKLVfSm2SM)

**Rewards**

Saddle rewards you in three ways for the D4 decentralized pool – trading fees, flash loan fees, and as four rewards (TRIBE, FXS, LQTY, and ALCX tokens) every time you provide liquidity to the D4 pool. After the transaction confirms, stake your LP tokens on the [Frax Finance](https://app.frax.finance/staking#Saddle_alUSD_FEI_FRAX_LUSD) dashboard to earn rewards. Check [Frax](https://app.frax.finance/staking#Saddle_alUSD_FEI_FRAX_LUSD) to know the current APR for the deposits.

![](/files/-MkBSv2qVQh1SkuBO2or)

### **sUSD Pool**

The Saddle sUSD Pool is a metapool. In this pool, we pooled the single token sUSD alongside Stablecoin Pool V2 (DAI, USDC, USDT). Adding the single asset to the metapool, however, does not dilute the liquidity of the underlying base pool.

* *sUSD*: A synthetic stablecoin on the Synthetix platform, whose value tracks the US Dollar.
* *saddleUSD-V2*: A base pool (Stablecoin Pool V2) on Saddle comprising the stablecoins USDT, USDC, and DAI.

![](/files/ZhdcKpYOU8Dlv3CzJ2vT)

**Rewards**

Saddle rewards you with trading fees and flash loan fees for the sUSD pool.

### **wCUSD Pool**

The Saddle wCUSD Pool is a metapool. In this pool, we pooled the single token CUSD (Celo Dollars) alongside Stablecoin Pool V2 (DAI, USDC, USDT). Adding the single asset to the metapool, however, does not dilute the liquidity of the underlying base pool.

* *wCUSD*: Wrapped Celo Dollar (wCUSD) is an ERC20 token, representing a 1:1 share of Celo Dollar (CUSD).
* *saddleUSD-V2*: A base pool (Stablecoin Pool V2) on Saddle comprising the stablecoins USDT, USDC, and DAI.

![](/files/tqu09dMiqEidJf68KSgw)

**Rewards**

Saddle rewards you with trading fees for the wCUSD pool.

## **SADDLE POOL RISKS**

Providing liquidity to Saddle is highly risky. The risk of this pool includes, but not limited to:

### **Technical Risks**

***Smart contract risk:*** Before using the protocol, we highly recommend [reading the code](https://github.com/saddle-finance/saddle-contract) and understanding the risks involved with being a Liquidity Provider (LP) and/or using the AMM to trade pegged value crypto assets.

***Audit risk:*** OpenZeppelin, Quantstamp, and Certik [audited](https://github.com/saddle-finance/saddle-audits) the Saddle smart contracts. However, security audits don’t eliminate all risks. Do not supply assets you cannot afford to lose to Saddle as a liquidity provider.

***Systemic risk:*** A 3/7 Gnosis Safe multisig controls Saddle's admin keys. The signers are Mariano Conti, Kain Warwick, DegenSpartan, Klim K, Damir Bandalo, scoopytrooples, and Aurelius. This multisig has capabilities to pause new deposits and trades in case of technical emergencies. Users will always be able to withdraw their funds regardless of new deposits being paused. The multisig can also change the swap/withdrawal fees and the per pool/account deposit limits.

***Hacking/Protocol failure:*** Even though blockchain technology is, theoretically, hack-proof, there have been instances of hacking either the protocol or surrounding ecosystem such as wallets, exchanges, and marketplaces.

***Scalability:*** The underlying blockchain network (Ethereum) suffers from network slowdown because of the high volume of transactions. While solutions are being tested out and deployed to improve the network throughput, the risk of slowdown of the Ethereum network, affecting transactions, remains.

***Experimental technology:*** No technology is perfect and prone to human errors and technical glitches, especially new and upcoming technologies such as blockchain and DeFi.

### **Market Risks**

***Pegged value asset risk:*** If one asset in the pool significantly depegs, it will effectively mean that it will leave pool liquidity providers holding only that asset.

***Market Cap:*** The crypto market fluctuates wildly. Though stablecoins are meant to address the volatility, there is always a risk of losing some principle or the assets backing the stablecoins might decline.

***Liquidity:*** Liquidity risk may happen because of a seller not finding a buyer or there is a mandatory lock-in period.

***Pricing errors:*** We constantly introduce new products and prices to offer innovative solutions to our customers. An error or a misinformed strategy may affect the returns.

***Economic incentive failure:*** As a relatively new product and technology, there is still a risk of widespread acceptance, and therefore demand. While extra incentives are offered and calibrated regularly, the risk of incentive mechanisms not encouraging the desired behavior exists.

***Impermanent loss risk:*** Impermanent loss occurs when the value of the funds staked to the AMM fluctuates drastically.

***Margin slippage risks:*** Slippage occurs when the execution price of a trade is different from its requested price. Though Saddle maintains minimal slippage, using the Stableswap algorithm, there is always a risk of slippage.

### **Counterparty Risks**

***Asset-backed stablecoins:*** The collaterals in reserve backing the stablecoins is a black box in some cases, especially, where the stablecoins are issued by centralized protocols.

***Algorithmic stablecoins:*** Certain algorithmic stablecoins have no collateral and are partially/fully collateralized by their native token. An insolvency risk of the native token collapsing exists with these digital assets.

***Blacklisting***: Centrally managed stablecoins are also subject to risks such as blacklisting accounts, and regulatory risks like mandatory KYC, or even erasing funds.

***Oracle risk:*** Many systems rely on Oracles (3rd party systems) for information such as market price. A risk of technical glitches or malicious attack exists with the Oracle feeds.

### **Other Risks**

***Regulatory:*** Cryptocurrencies and DeFis are unregulated in many countries. While governments and regulators are stepping in, the risk of regulatory framework changing and affecting the investments persists.

***Taxation:*** As a new and rapidly developing asset class, cryptocurrencies are subject to high Stablecoins are at the heart of Saddle DeFi ecosystem. Whilst all stablecoin investments are risky, some carry higher risks. Therefore, the risk of Saddle pools vary from pool to pool. In this section, uncertainty. Substantial risk exists regarding the tax treatment of investment in digital assets.

***Black Swan:*** A black swan event is a rare event - such as an attack on the collateral, unexpected price decrease, or a highly coordinated attack by malicious parties.

***User abandonment:*** DeFi and AMMs are complex technologies and concepts. A risk of users abandoning the protocol in favor of seemingly simpler systems exists.

### **Risks Per Pool**

Stablecoins are at the heart of the Saddle DeFi ecosystem. Whilst all stablecoin investments are risky, some carry higher risks. Therefore, the risk of Saddle pools varies from [pool to pool](https://docs.saddle.finance/asset-specific-risks). In this section, we’ve highlighted the *key risk indices* for various pools.

### **Assets Reference**

This section provides a reference to the documentation for the various assets used in Saddle Pools.

|                      |                                  |                                                                                  |                                                                                     |                                                    |                                                                                                                                                 |                                                                                                |
| -------------------- | -------------------------------- | -------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| **Asset**            | **Website**                      | **Whitepaper**                                                                   | **Document**                                                                        | **Source Code**                                    | **Audits**                                                                                                                                      | **Contract**                                                                                   |
| **alETH, alUSD**     | [WB](https://www.alchemix.fi)    | [WP](https://alchemix.fi/c76d1d663f6c8247b86a8fca83d5bd1b.pdf)                   | [DOC](https://alchemix-finance.gitbook.io/alchemix-finance/)                        | [SC](https://github.com/alchemix-finance)          | [AUD](https://alchemix.fi/a208baf6ca7e0d6b0116461f05e27cd9.pdf)                                                                                 | [CON](https://github.com/alchemix-finance/contract-addresses/blob/dev/alchemix-addresses.json) |
| **DAI**              | [WB](https://makerdao.com)       | [WP](https://makerdao.com/en/whitepaper/)                                        | [DOC](https://docs.makerdao.com)                                                    | [SC](https://github.com/makerdao)                  | [AUD](https://github.com/makerdao/audits)                                                                                                       | [CON](https://etherscan.io/address/0x6b175474e89094c44da98b954eedeac495271d0f)                 |
| **FEI**              | [WB](https://fei.money)          | [WP](https://docs.fei.money/whitepaper)                                          | [DOC](https://docs.fei.money)                                                       | [SC](https://github.com/fei-protocol)              | [AUD](https://docs.fei.money/audit)                                                                                                             | [CON](https://docs.fei.money/protocol/contract-addresses)                                      |
| **FRAX**             | [WB](https://frax.finance)       | [WP](https://docs.frax.finance/overview)                                         | [DOC](https://docs.frax.finance)                                                    | [SC](https://github.com/FraxFinance/frax-solidity) | [AUD](https://certik.foundation/vendors/fraxfinance)                                                                                            | [CON](https://docs.frax.finance/smart-contracts/frax)                                          |
| **LUSD**             | [WB](https://www.liquity.org)    | [WP](https://docsend.com/view/bwiczmy)                                           | [DOC](https://docs.liquity.org)                                                     | [SC](https://github.com/liquity/dev)               | [AUD](https://docs.liquity.org/documentation/resources#security-audits)                                                                         | [CON](https://docs.liquity.org/documentation/resources#contract-addresses)                     |
| **renBTC**           | [WB](https://renproject.io)      | [WP](https://renproject.io/litepaper.pdf)                                        | [DOC](https://docs.renproject.io/developers)                                        | [SC](https://github.com/renproject)                | [AUD](https://github.com/renproject/ren/wiki/Audits)                                                                                            | [CON](https://renproject.github.io/ren-client-docs/contracts/)                                 |
| **sBTC, sETH, sUSD** | [WB](https://synthetix.io)       | [WP](https://docs.synthetix.io/litepaper)                                        | [DOC](https://docs.synthetix.io)                                                    | [SC](https://github.com/Synthetixio)               | [AUD](https://docs.synthetix.io/contracts/audits/)                                                                                              | [CON](https://docs.synthetix.io/addresses/)                                                    |
| **tBTC**             | [WB](https://tbtc.network)       | [WP](https://docs.keep.network/tbtc/index.pdf)                                   | [DOC](https://tbtc.network/developers/)                                             | [SC](https://github.com/keep-network/tbtc)         | [AUD](https://github.com/keep-network/tbtc/tree/a85cc4c6453ab88684c365f41335281c98a828d9#security)                                              | -                                                                                              |
| **USDC**             | [WB](https://www.centre.io/usdc) | [WP](https://f.hubspotusercontent30.net/hubfs/9304636/PDF/centre-whitepaper.pdf) | [DOC](https://www.centre.io/developer-resources)                                    | [SC](https://github.com/centrehq)                  | -                                                                                                                                               | [CON](https://etherscan.io/token/0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48)                   |
| **USDT**             | [WB](https://tether.to)          | [WP](https://tether.to/wp-content/uploads/2016/06/TetherWhitePaper.pdf)          | [DOC](https://tether.to/knowledge-base/)                                            | [SC](https://github.com/shipshapecode/tether)      | [AUD](https://wallet.tether.to/transparency?__cf_chl_jschl_tk__=pmd_b52840356b4c3f57d84b3b0cdf1606bfa5688dab-1628925480-0-gqNtZGzNAeKjcnBszQh6) | [CON](https://etherscan.io/address/0xdac17f958d2ee523a2206206994597c13d831ec7)                 |
| **wBTC**             | [WB](https://wbtc.network)       | [WP](https://wbtc.network/assets/wrapped-tokens-whitepaper.pdf)                  | [DOC](https://github.com/WrappedBTC/bitcoin-token-smart-contracts/tree/master/docs) | [SC](https://github.com/WrappedBTC)                | [AUD](https://wbtc.network/dashboard/order-book)                                                                                                | [CON](https://etherscan.io/address/0x2260fac5e5542a773aa44fbcfedf7c193bc2c599)                 |
| **WETH**             | [WB](https://weth.io)            | -                                                                                | [DOC](https://openbase.com/js/advanced-weth/documentation)                          | [SC](https://github.com/WETH10)                    | -                                                                                                                                               | [CON](https://etherscan.io/address/0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2)                 |

**Disclaimer:** These are links to external websites. Saddle Finance does not provide or maintain the external websites. We do not guarantee the accuracy, relevance, timeliness, and/or completeness of any information on the external websites.


# Community Pools

Community Pools are the user-generated, permissionless pools on Saddle Finance.

## Community Pools: Definitions, Benefits, and Risks

### What are Community Pools?

Community Pools are (also known as Factory Pools, Permissionless Pools, and User-generated pools) are liquidity pools that users can create themselves. Users are allowed to choose the tokens within the pool and their respective weights. All the Community Pools created are then accessible on Saddle.

### What are the benefits of Community Pools?

Community Pools have several benefits compared to [Saddle Pools](https://docs.saddle.finance/saddle-pools):

* Community Pools are **permissionless**. Permissionless refers to an action that can be taken or a system that can be accessed without the approval of an intermediary. This means that anyone can create a Community Pool at any time.
* Community Pools are **decentralized**. There is no gatekeeper. Anyone can list any token, without having to wait.
* Community Pools can provide a **revenue stream**. Community Pools share fees with the Pool Creator, providing a potential new revenue stream to a protocol, trader, or hodler who creates the Community Pool. Read more [here](#what-percentage-of-pool-fees-go-to-the-pool-creator).

### What are the risks of Community Pools?

All the risks of Saddle Pools apply to Community Pools. Read more about the risks of Saddle Pools [here](https://docs.saddle.finance/saddle-pools#saddle-pool-risks).

In addition, Community Pools present additional risks including:

* **Due diligence risk** : Saddle does not conduct due diligence or verify the safety of each Community Pool. Saddle does not reimburse for losses incurred in a Community Pool. It is important to conduct your own research on each Community Pool. Read all the documentation to understand the risks of Community Pools and their risks.
* **Token risk** : Liquidity Pools that are permissionless, like Community Pools, are key to decentralization, but they also present additional risks. Some users list fake tokens, hoping to trick others into buying the wrong asset. Saddle has no control over the tokens added in the Community Pool. That means it is very important to make sure that one is purchasing the correct asset before executing a trade. One must verify the token addresses one trades in a Community Pool.

### How does one stay safe in Community Pools?

* Understand all the tokens present in any Community Pool. This applies even if you are depositing USDC.
* Make sure the parameters are realistic. Get [support](#what-technical-support-is-available-to-pool-creators-who-create-community-pools-on-saddle) if needed.
* Ensure that a liquidator is running in the pool.
* Check that the oracle is displaying the correct price.

## How to Create a Community Pool

### How do I create a Community Pool?

Community Pools can be created within a simple interface and by configuring a set of parameters for your asset.

1. First, navigate to the Saddle dApp, select the “Pools” menu, and select “Create Pool.”

   <figure><img src="/files/cGP70cxJzNH7fAyPZavX" alt=""><figcaption><p>Click the Button "Create Pool" to create a Community Pool.</p></figcaption></figure>
2. Next, Add the Pool Name and Pool Symbol.

   * The Pool Name will show up on the Pools page and also in the Withdraw / Deposit views. It is good practice for the pool name to be descriptive of what type of pool it is.
   * The Pool Symbol is the name that will display on the list of pools on the Saddle frontend. It is good practice for the Pool Symbol to indicate what tokens are in the pool.

   <figure><img src="/files/NiijeiemkzpLfNxvrSkU" alt=""><figcaption></figcaption></figure>
3. Next, scroll down to choose the Pool Type and set the parameters for the Community Pool.

   * The three options for Pool Type are USD Metapool, BTC Metapool, and Base Pool.
   * The three Parameters that Pool Creators can set are the Pool Fees, the Amplification Coefficient, and the Token contracts.

   <figure><img src="/files/lAK2iMQdUooZBlbKHqPb" alt=""><figcaption><p>Parameters that a Pool Creator can set when creating a Community Pool.</p></figcaption></figure>
4. When all the parameters are filled in, the `Create Community Pool` button will be activated. Click `Create Community Pool`. To see your pool, navigate to <https://saddle.exchange/#/pools>. The Pool Symbol chosen for your Community Pool will show up on <https://saddle.exchange/#/pools> with the `Community` tag .
5. After deploying a pool, you must seed initial liquidity. You can do this by navigating to the Community Pool on <https://saddle.exchange/#/pools> and clicking the `Deposit` button next to your Community Pool. This will bring you to the Add Liquidity page. Connect your wallet and add tokens to your Community Pool.

   <figure><img src="/files/5lsEgvL9W3EFcDeiffd0" alt=""><figcaption><p>Button to deposit into a Community Pool.</p></figcaption></figure>

   <figure><img src="/files/BD9gZFdjY7E0r6HDUiTZ" alt=""><figcaption><p>Page for adding liquidity to a Community Pool.</p></figcaption></figure>

### Does Saddle charge any fee for deploying a Community Pool on Saddle?

Saddle does not charge or take a fee for creating a Community Pool. There is no fee charged by Saddle associated with creating and deploying a Community Pool on Saddle.

There is a gas fee associated with deploying a pool that must be paid by the Pool Creator. The gas fee will depend on the network at the time of creating the Community Pool.

### Are there any Listing criteria that a Community Pool must meet in order to be listed on Saddle’s frontend?

There are no listing criteria. If the addresses used are valid, the Community Pool will show up on [Saddle](https://saddle.exchange/#/pools), where Community Pools are ordered automatically by amount of TVL, with higher TVL Community Pools on top.

### What kinds of pools can be created using Saddle’s Community Pools?

Three kinds of pools can be created using Saddle’s Community Pools.

* Base pools
* BTC metapools
* USD metapools

Read more about these different types of pools [here](https://docs.saddle.finance/saddle-pools#base-pool-and-metapool).

### What chains are Community Pools available on?

Community Pools are available to deploy on Ethereum Mainnet, Arbitrum, and Optimism.

It’s Saddle’s goal to support Community Pools on every chain where the Saddle dApp is available.

### What parameters of Community Pools can users define?

There are 3 parameters that Creators of a Community Pool can define:

* **The Pool Fee** : The Pool Fees are the [trading fees](https://docs.saddle.finance/glossary#saddle-fees) that are charged to traders making swaps in the pool. Pool Creators can set the Pool Fee as a value between 0.01% (minimum) – 1% (maximum).
* **The Amplification Coefficient** : A value which can either compress or expand the range of low slippage swaps.
* **Token contracts** : Which tokens make up the pool.

### How do I LP into a Community Pool?

Go to <https://saddle.exchange/#/pools> and navigate to the Community Pool you want to provide liquidity to. Click `Deposit`.

### How do I withdraw from a Community Pool?

Go to <https://saddle.exchange/#/pools> and navigate to the Community Pool you want to provide liquidity to. Click `Withdraw`.

## Community Pools: FAQs

### Can the Saddle DAO make any admin changes to the parameters of a Community Pool?

* The parameters chosen by the Pool Creator cannot be changed. Other users can create separate pools with different parameters.
* Saddle can’t change any of the parameters. Saddle can’t pause Community Pools.
* Saddle can delist pools from Saddle’s registry, removing the Pools from frontend. The Community Pool would still be visible on other frontends.

### What tokens are supported by Community Pools? Are there any types of tokens that are not supported?

Any token that’s not rebasing is supported by Community Pools. Conversely, tokens that are rebasing are not supported by Community Pools.

### What percentage of Pool Fees go to the Pool Creator?

Admin fees will be split 50-50 between the Pool Creator and Saddle.

Admin fees is charged as percentage of the charged swap fee. This can be changed anytime by the Pool Creator.

Note that at 100% admin fee, LPs will receive NO swap fees.

Example: If a Pool Creator sets Pool Fee value to 0.04% valid range: \[0.01% \~ 1%] then:

* 5/ 0.02% goes to LPs (users who deposited in the pool)
* 2.5/ 0.01% goes to Pool Creator
* 2.5/ 0.01% goes to to the Saddle multisig, with a 3/2 split between veSDL and Treasury

### How are Pool Fees disbursed to the Pool Creator?

When claimed, fees in each community pool will be split 50-50 between the creator of the pool and the Saddle Treasury.

Saddle will automatically trigger fee collection once the pool's admin fee has reached over certain threshold. If pool creators wish to, they can trigger it manually via calling `withdrawAdminFees()` function on etherscan page of the pool.

This link to the etherscan to the pool can be found in each pool's deposit or withdraw view.

### **What are the listing requirements for a Community Pool to be displayed on Saddle?**

There are no listing requirements. All Community Pools that are created will show up on [Saddle](https://saddle.exchange/#/pools).

### Is it possible to remove a Community Pool once deployed?

It is not possible for Saddle or anyone to destroy or remove a Community Pool once deployed. Saddle can remove a Community Pool from the registry (Saddle frontend). Users would still be able to use the Community Pool from their own frontend.

### What technical support is available to Pool Creators who create Community Pools on Saddle?

Saddle is to be used at your own risk. Admins have no special keys and cannot recover funds if sent improperly. However, a wide variety of resources are still available to help you use Saddle Community Pools. If you have questions, please make sure to reach out in the following channels.

* \#support forum on Saddle’s Discord: <https://discord.gg/qEtPn5pBvk>.
* Chatbot on [Saddle](https://saddle.exchange/#/).
* Saddle’s Telegram chat: <https://t.me/saddle_finance>.

Saddle’s partnership team is available to provide bespoke technical support and marketing to Saddle’s partner protocols. Reach out to Partnerships Lead Christian Gonzalez-Capizzi on Telegram (@cxgonzalez) and on Discord (CXGonzalez#2321)


# Layer 2 Guide

Layer 2 is a different network running atop the Ethereum Mainnet (Layer 1).

### **ETHEREUM LAYER 2 SOLUTIONS** <a href="#toc87951811" id="toc87951811"></a>

Ethereum network is a popular destination for most decentralized apps (dApps). The popularity has led to enormous activity of Ethereum, which results in high gas fees and slow transaction speed. [Layer 2 networks](https://ethereum.org/en/developers/docs/scaling/layer-2-rollups/) are a solution for Ethereum scaling challenges.

Layer 2 is a different network running atop the Ethereum Mainnet (layer 1) and stays on the Mainnet as smart contract. Thus, layer 2 solutions help scale applications by handling transactions off the Ethereum Mainnet (layer 1) while taking advantage of the robust decentralized security model of Mainnet.

### **Rollups** <a href="#toc87951812" id="toc87951812"></a>

Rollups perform transaction execution outside the Ethereum Mainnet (layer 1) and post the transaction data on layer 1. The “rollup” is so-called because the layer 2 solutions roll up transactions and fit them into a single block in layer 1. As transaction data is on layer 1, rollups are secured by layer 1. There are two types of rollups:

**1) Optimistic rollups** assume transactions are valid by default (hence the name optimistic) and only runs computation, via a fraud proof, in the event of a challenge. Optimistic rollups are scalable because they don't do any computation by default. If someone notices a fraudulent transaction, the rollup will execute a fraud-proof and run the transaction's computation, using the available state data.

| **Advantages**                                                                    | **Disadvantages**                                                                                                        |
| --------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| <ul><li>Low gas fees</li><li>Scalable</li><li>Smart contract compatible</li></ul> | <ul><li>Long wait times for on-chain transaction because of potential fraud challenges (may take up to a week)</li></ul> |

Major implementations of optimistic rollups: [Optimism](https://optimism.io), [Arbitrum](https://arbitrum.io), [Boba](https://boba.network), [Fuel Network](https://fuel.sh).

**2) Zero-knowledge rollups** runs computation off-chain and submits a validity proof to the chain. Also known as ZK rollups or ZKRUs, these scaling solutions “roll up” many transactions off-chain and generate a cryptographic proof known as SNARK (validity proof) for the whole bundle. The validity proof is posted on layer 1, and the proof can be quickly verified, and invalid batches are rejected straightaway.

| **Advantages**                                                                                 | **Disadvantages**                                                                           |
| ---------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- |
| <ul><li>Low gas fees</li><li>Scalable</li><li>Shorter wait time for fund withdrawals</li></ul> | <ul><li>Some solutions don't have EVM support (ZKSync 2.0 is expected in Q4 2021)</li></ul> |

Major implementations of ZK-rollup: [Loopring](https://loopring.org/#/), [Aztek 2.0](https://aztec.network), [Starkware](https://starkware.co), [zkTube](https://zktube.io).

### **ARBITRUM & OPTIMISM LAYER 2** <a href="#toc87951813" id="toc87951813"></a>

[Arbitrum](https://arbitrum.io) and [Optimism](https://optimism.io) are both layer 2 solutions with a lot in common – both implement optimistic rollup, have smart contracts living in Ethereum Mainnet (layer 1), and use ETH as their currency.

**Note**: The challenge window for fraud and dispute is ***one week*** for both Optimism and Arbitrum. Your transactions in a bundle under suspicion can be held up for one week before they’re verified, and funds are released. However, the challenge process varies across Optimism and Arbitrum.

* **Arbitrum**: When a [challenge](https://developer.offchainlabs.com/docs/dispute_resolution#dispute-resolution) is submitted, Arbitrum uses an offchain dispute resolution process to isolate a single step within a transaction. The isolated step is then sent to EVM for final verification.
* **Optimism**: When a [challenge](https://community.optimism.io/docs/protocol/fraud-proofs.html) is submitted, the entire transaction in question is run through the Ethereum EVM.

{% hint style="info" %}
Find Saddle's deployed code base [here](https://github.com/saddle-finance/saddle-contract/tree/master/deployments)
{% endhint %}

### **Arbitrum: Moving Assets In And Out (Deposit/Withdraw)** <a href="#toc87951814" id="toc87951814"></a>

You can transfer assets from Layer 1 Ethereum to Layer 2 Arbitrum through the [Arbitrum Bridge](https://bridge.arbitrum.io). Follow this [guideline](https://arbitrum.io/bridge-tutorial/) to deposit and withdraw crypto assets in Arbitrum.

### **Optimism: Moving Assets In And Out (Deposit/Withdraw)** <a href="#toc87951815" id="toc87951815"></a>

Follow these guidelines to move crypto assets in Optimism.

* **Deposit or Withdraw Ether** via the [Official Optimism Bridge](https://app.optimism.io/bridge/deposit).
* **Deposit or Withdraw ERC-20 tokens** via [The Optimism Gateway](https://app.optimism.io/bridge/deposit) or [3rd Party Bridges](https://www.optimism.io/apps/bridges).

### BRIDGES <a href="#toc87951816" id="toc87951816"></a>

Like physical bridges which connect locations enabling movement of people and wealth, in the crypto ecosystem, a bridge is a connection between blockchain networks operating under different conditions. Bridges establish interoperability by enabling transfer of assets and information.

The communities built around individual blockchain networks need to collaborate and cooperate for the ecosystem to be truly decentralized and open. Bridges help the benefits to cross the boundaries and grow beyond the genesis ecosystem.

Therefore, bridges are not only about connecting Layer 1 Mainnet and Layer 2 solutions. For the ecosystem to mature and blossom, we require bridges across Layer 2 as well. Besides the bridges mentioned above, there are other bridges available to transfer assets across Layer 1/Layer 2. Let’s explore a few bridges now.

### **Hop Protocol** <a href="#toc87951817" id="toc87951817"></a>

[Hop](https://hop.exchange) is a scalable rollup-to-rollup general token bridge. Hop allows users to transfer tokens directly and easily between Layer 2s, sidechains, and Layer 1 Ethereum. With Hop, users can send tokens from one rollup to another almost immediately without having to wait for the rollup’s challenge period. [Built with Saddle](https://docs.saddle.finance/build-with-saddle#hop-protocol), Hop is a protocol built for quick, low cost, and trustless transfer of assets.

Check out the guide [here](https://medium.com/hop-protocol/hop-send-tokens-across-rollups-30f14c432f7c) to get started.

### **Synapse Protocol** <a href="#toc87951818" id="toc87951818"></a>

[Synapse](https://synapseprotocol.com) is another bridge that provides users the option for cost-efficient, user friendly, and low-slippage stablecoin trade. Synapse unifies the thriving L1/L2 ecosystem, allowing users to seamlessly bridge assets across the most popular chains. Synapse allows users to frictionlessly transfer stablecoins to/from Arbitrum, Avalanche, BSC, Ethereum, Fantom, Polygon (as well as ETH to/from Arbitrum) - with more chains and assets in the works.

Check out the guide [here](https://docs.synapseprotocol.com/how-to/bridge) to get started.

### **Celer Bridge** <a href="#toc87951819" id="toc87951819"></a>

[Celer](https://www.celer.network) network is a layer-2 scaling platform that brings fast, secure, and low-cost blockchain applications on Ethereum, Polkadot and other blockchains to mass adoption. Celer bridge ([cBridge](https://cbridge.celer.network)) can be used to instantly transfer token cross-chain and cross-layer between any two of these networks: Ethereum, Arbitrum, Polygon, and Binance Smart Chain. cBridge keeps the liquidity flow between these loosely coupled networks without long delays or a trust-based custodian.

Check out the guide [here](https://cbridge-docs.celer.network/#/) to get started.

### **Connext Network** <a href="#toc87951820" id="toc87951820"></a>

[Connext](https://connext.network) is a protocol for fast, fully noncustodial transfers and contract calls between EVM-compatible systems. As a cross-chain routing network, Connext enables seamless communication between the Ethereum mainnet, L2 systems, and shards. Connext routers act as the backbone of the network, providing liquidity for user swaps and earning fees in return.

Check out the guide [here](https://docs.connext.network) to get started.

### **WORKING WITH SADDLE L2 POOLS** <a href="#toc87951821" id="toc87951821"></a>

Swapping and LP'ing are the same as on L1 (check out the [deposit](https://docs.saddle.finance/saddle-pools#deposit) and [withdraw](https://docs.saddle.finance/saddle-pools#withdraw) guides), but ensure you have **successfully switched the network**.

### **Switching from L1 to L2 Network** <a href="#toc87951822" id="toc87951822"></a>

* **Step 1:** Head to <https://saddle.exchange/#/pools>.
* **Step 2:** Switch the network from **Ethereum to Arbitrum** to LP or trade using Saddle’s L2 Stablecoin pools.

![](/files/0ay0Q3Zx4JFa0h5T90hS)

* **Step 3:** ***Confirm the*** network switch

![](/files/jgg0wCf2LzVSTaMKWBoL)

* **Step 4 :** Once switched, working with L2 pools is the same as on L1 pools (check out the [deposit](https://docs.saddle.finance/saddle-pools#deposit) and [withdraw](https://docs.saddle.finance/saddle-pools#withdraw) guides).

### **Incentives** <a href="#toc87951823" id="toc87951823"></a>

Depositing assets into a pool on Saddle allows users to take part in the protocol as liquidity providers and earn reward incentives.

Read more about pool incentives in the [tokenomics section](/sdl-token).


# SDL Token

SDL is the Saddle DAO governance token.

Saddle has served as community and a developer first infrastructure entirely embracing open-source collaboration since our launch in Jan 2021. We are here today because of the many community members and liquidity providers who supported our journey over the past year.

As the Saddle protocol grows and develops, DAO governance is our next step in our community and LPs outreach.

**SDL is the Saddle DAO governance token.**

{% hint style="info" %}
Find SDL token code [here](https://github.com/saddle-finance/saddle-contract/blob/master/contracts/SDL.sol)
{% endhint %}

### **SDL ALLOCATION** <a href="#toc87947029" id="toc87947029"></a>

The max supply of 1 billion SDL has been minted at genesis and will become available over the course of 3 years. We split the initial SDL allocation between:

| **Allocation**           | **% of Tokens** | **# of Tokens** | **Vesting Period**                       |
| ------------------------ | --------------- | --------------- | ---------------------------------------- |
| Saddle community members | 51%             | 510,000,000 SDL | *See breakdown in the following section* |
| Investors                | 22.5%           | 225,000,000 SDL | 2 years                                  |
| Team members             | 25.9%           | 259,000,000 SDL | 3 years                                  |
| Advisors                 | 0.6%            | 6,000,000 SDL   | 3 years                                  |

![SDL Token Allocation](/files/5ahrSmwYBhNZ7Y5eOEfO)

{% hint style="info" %}
Find SDL token vesting code [here](https://github.com/saddle-finance/saddle-contract/blob/master/contracts/Vesting.sol) and [here](https://github.com/saddle-finance/saddle-contract/blob/master/contracts/RetroactiveVesting.sol)
{% endhint %}

### **SDL Community Token Allocation** <a href="#toc87947030" id="toc87947030"></a>

The Saddle community tokens (510,000,000 SDL) are further allocated as per the schedule below:

| **Allocation**                                                | **% of Tokens** | **# of Tokens**   | **Vesting Period** |   |
| ------------------------------------------------------------- | --------------- | ----------------- | ------------------ | - |
| 1) Past liquidity providers and users, as distributed below:  | 15%             | 150,000,000 SDL   | 2 years            |   |
| *1.1) Historical LPs*                                         | *10.5%*         | *105,000,000 SDL* | *2 years*          |   |
| *1.2) veCRV Holders*                                          | *3*%            | *30,000,000 SDL*  | *2 years*          |   |
| *1.3) Any address that swapped $100> using Saddle contracts*  | *0.5%*          | *5,000,000 SDL*   | *2 years*          |   |
| *1.4) Multisig signers*                                       | *0.5%*          | *5,000,000 SDL*   | *2 years*          |   |
| *1.5) Early depositors*                                       | *0.5%*          | *5,000,000 SDL*   | *2 years*          |   |
| 2) Liquidity mining                                           | 5%              | 50,000,000 SDL    | No vesting         |   |
| 3) Community incentives program (bounties4bandits) and grants | 1%              | 10,000,000 SDL    | No vesting         |   |
| 4) Governance treasury                                        | 30%             | 200,000,000 SDL   | 3 years            |   |

15% of SDL (150,000,000 SDL) can be claimed by past liquidity providers and users with 2-year vesting. This is broken down as follows:

* 10.5% pro rata to historical liquidity providers (105,000,000 SDL)
  * Cut-off date is 11/1/21
  * Tokens were distributed per block to historical liquidity providers by accounting for provided liquidity amounts in dollars as a percent of total TVL
  * Rewards were doubled during the one month [guarded launch period](https://docs.saddle.finance/saddle-faq#what-is-saddles-proof-of-governance)
* 3% split evenly across veCRV holders (30,000,000 SDL) as a token of thanks for the StableSwap maths (using the latest [EPS snapshot](https://github.com/ellipsis-finance/vecrv-airdrop/blob/master/distributions/distribution-2021-10-28.json))
* 0.5% split evenly across each address that has ever swapped using Saddle contracts (5,000,000 SDL)
  * Cutoff date is 10/1/21 (any addresses swapping with any Saddle contract before then is eligible)
  * Addresses swapping less than a total of $100 are excluded to prevent sybils
* 0.5% split evenly across multisig signers (5,000,000 SDL)
* 0.5% pro rata to early depositors - we’d like to appreciate and compensate these community members, a few of whom took risks and lost value.

The token is initially **non-transferable for a period of between 3 to 12 months**. After 3 months, governance may vote to enable transfers. After 12 months, they may be enabled by anyone. The token and vesting contracts have been audited by [Quantstamp](https://quantstamp.com), read the audit [here](https://github.com/saddle-finance/saddle-audits/blob/master/10-27-2021_Quantstamp_Token.pdf).

We are launching SDL as non-transferrable to allow community members to earn more and deter short-term profit-seekers and mercenaries.

All historical users and liquidity providers can claim their SDL now on [the Saddle dApp](http://saddle.exchange).

### **EARNING SDL TOKENS** <a href="#toc87947031" id="toc87947031"></a>

You can earn the Saddle tokens in 2 ways – by LPing in Saddle’s incentivized pools and by participating in the bounties4bandits (b4b) program.

### **Liquidity Mining** <a href="#toc87947032" id="toc87947032"></a>

5% of SDL (50,000,000 SDL) has been allocated to liquidity mining programs across [Ethereum](https://ethereum.org/en/), [Arbitrum](https://offchainlabs.com), and (later) [Optimism](https://www.optimism.io) which can be earned without any vesting. The initial liquidity mining program will run for 6 months and 2.23% (22,300,000 SDL) will be distributed as follows:

| **Pool**      | **Network**     | **% of Tokens** | **# of Tokens** |
| ------------- | --------------- | --------------- | --------------- |
| alETH         | Ethereum        | 0.50%           | 4,958,678       |
| BTC V2        | Ethereum        | 0.25%           | 2,479,339       |
| D4            | Ethereum        | 0.25%           | 2,479,339       |
| Stablecoin V2 | Ethereum        | 0.25%           | 2,479,339       |
| Stablecoin    | Arbitrum (L2)   | 0.50%           | 4,958,678       |
| *Stablecoin*  | *Optimism (L2)* | *0.50%*         | *4,958,678*     |

Liquidity mining will begin on 11/18/21 12:00 AM UTC. The remaining 3.75% of tokens have been earmarked for future pools, to be decided upon by the community. Specific information on SDL incentives for each pool is available on the [Pools page on the dApp](https://saddle.exchange/#/pools).

### **bounties4bandits (b4b) Community Incentives Program** <a href="#toc87947033" id="toc87947033"></a>

0.75% (7,500,000 SDL) is allocated with no vesting to a community multisig for grants for community contributions through [bounties4bandits (b4b)](https://saddle.finance/#/b4b), a program run by our community members in collaboration with [Encode Club](https://www.encode.club). Encode Club is receiving a 0.25% grant over three years for their continued support.

\
b4b is Saddle’s hackathon / grants program for Saddle community members to get involved and get rewarded, with several technical and non-technical tracks. Learn more about b4b [here](https://saddle.finance/#/b4b).

### **GOVERNANCE TREASURY** <a href="#toc87947034" id="toc87947034"></a>

The remaining 30% of tokens (300,000,000 SDL) will vest to the governance treasury over 3 years. The community will decide how to distribute these tokens going forward through community initiatives, liquidity mining, and other programs.

![Governance Treasury](/files/9c3zH6z55RefrUtsmEqB)

### **GOVERNANCE** <a href="#toc87947035" id="toc87947035"></a>

SDL token holders can vote on proposals. Initially, the proposals will be on [Snapshot](https://snapshot.org), which the current [community multisig](https://docs.saddle.finance/saddle-faq#who-controls-saddles-admin-keys) will then enact. [Discourse](https://www.saddle.community) will be the platform for discussion of the proposals.

We expect proposals in the next few months to migrate to fully on-chain governance using the [Compound Governor Bravo](https://compound.finance) and add additional token economics.

Sign up for an account on the [Saddle community Discourse](https://www.saddle.community) to participate in protocol governance.

***


# veSDL (vote escrowed) SDL

## Definitions

* **SDL token** - transferable, used for incentives via emission
* **Vote escrow SDL (veSDL)** - non-transferable, locked up by depositing SDL into the voting escrow contract, period from 1 week to 4 years
* **Gauge** - the smart contract controlling how much SDL incentives are emitted to each pool; veSDL holders can vote which pool to allocate SDL incentives to on a weekly basis
* **User checkpoint** - a user checkpoint in the veSDL mechanism is any time when you interact with veSDL: locking SDL (depositing into a gauge), unlocking SDL (withdrawing from a gauge) or claiming rewards.

## Summary

### Introduction

With the SDL token unlock comes the implementation of “vote escrow” tokenomics, step 1 in our tokenomics roadmap. But what does this change enable SDL holders to do?

Up until now, Saddle has incentivized LPs by offering SDL (and occasionally other partner) tokens as a reward for their deposited liquidity. But there’s a problem: token emission rates for these incentives are fixed. What if market conditions change? Enter veSDL.

### What is veSDL?

veSDL and gauges work together to give users a mechanism to vote for the pool to which they want SDL rewards allocated. Users can get veSDL by locking their SDL in the Vote Escrow contract from 1 week to 4 years. The longer the lock, the more veSDL and voting power they receive from locking each SDL

Instead of holders making a tradeoff between fixed, potentially higher SDL emissions and being LPs for tokens they like more, vote escrow tokenomics allows SDL holders to lock their SDL for a period of time for veSDL, or “vote escrowed” SDL. The longer they lock, the higher the veSDL:SDL exchange rate to incentivize long-term community participation. Once users have veSDL they can vote in weekly *gauge weight voting*.

<figure><img src="/files/o24JA8USabC6jCYILM3r" alt=""><figcaption><p>Difference between SDL and veSDL.</p></figcaption></figure>

### Gauge weight voting

The weekly gauge weight vote determines how Saddle’s weekly SDL emissions get distributed in the following week. As outlined in [SIP-24](https://snapshot.org/#/saddlefinance.eth/proposal/0xe2a3e49dd86ef9f3e778486371b727b5e1ac8a1bc36326f431d5de63c8b287ca), **30M tokens of the SDL supply will be emitted over the first 6 months post token unlock**. That means 30M SDL / 6 months = 1.25m SDL will be emitted in liquidity mining incentives per week. After 6 months, a new Saddle Improvement Proposal will go to governance to change the weekly emissions rate to a tapering schedule.

This means that SDL users will be able to lock up their SDL for veSDL, vote in weekly gauge votes to determine where SDL incentives get emitted the following week, and collectively choose how attractive each pool is for the broader DeFi community.

### Boosts and trading fees

When users lock up SDL, they also receive personal SDL emission boosts (i.e. “boosties”) for the pools they’re personally LPs for.

By default, all users (those without veSDL) get 1x the reward rate. Those with veSDL will receive a boost of 1-2.5x the base reward rate, based on the amount of veSDL the user has relative to their LP size.

Also note that users’ boosties are recalculated automatically every 2 weeks. Each individual's boost rate is recalculated any time they interact with a gauge or veSDL (i.e. user checkpoint)

Finally, recall that Saddle collects a 0.04% trading fee on most trades. 50% of the trading fee goes to liquidity providers in the form of whatever tokens they are providing. The other 50% gets divided in two ways: 60% goes to veSDL token holders in the form of a Sushiswap SDL/ETH LP token; the other 40% goes to Saddle's treasury in the form of USDC.

## Benefits

### **Boosties**

When users lock up SDL for veSDL, the pools they’re providing liquidity to will benefit from boosted SDL emissions for that particular user.

### **Weekly gauge weight voting**

Every week the weights of the Saddle gauge go to vote. This controls the distribution of SDL liquidity mining incentives across all of Saddle’s pools included in the gauge system. veSDL holders are able to participate in this weekly vote to route SDL incentives to whichever pool they choose. This could be a pool they’re already a part of, or a pool they’re being bribed to support, resulting in additional rewards for veSDL holders.

### **Voting on SIPs / governance proposals**

Once veSDL goes live, all Snapshot voting will be transitioned from SDL held to veSDL held. Which means veSDL holders will have the benefit of being able to participate in Saddle’s governance and helping to direct the growth of the protocol

### **Bribes**

veSDL holders have the potential to receive airdrops from protocols whose tokens are part of Saddle’s liquidity pools in exchange for voting to increase the gauge weight of those pools those protocol’s token is a part of. Users benefit from airdrops in exchange for their votes, protocols benefit from there being added incentives for users to provide liquidity with their token. Everyone wins. Take a look at [pitch.money](https://pitch.money/) for an example.

## How-to-Guide

### How to lock/unlock SDL <> veSDL

In order to maximize your SDL rewards for LPing (up to 2.5x!), you’ll need some veSDL. Head to the veSDL page on saddle.exchange to lock your SDL and receive veSDL.

#### To lock SDL into veSDL:

1. Input into SDL Lock section how much SDL you want to lock
2. Input into calendar how long you want to lock up your SDL for
   * Minimum is 1 week (1 SDL locked for 1 week = 0.0048 veSDL)
   * Maximum is 4 years (1 SDL locked for 4 years = 1 veSDL)
3. Click \[Create Lock] button, approve + execute transaction in your wallet
   * If you already have some SDL locked, the UI will show \[Adjust Lock] button instead.
   * In this case, you can add more SDL which will have the same unlock as your existing lock
   * You can also increase the unlock time without adding more SDL
   * Depending on how much additional SDL you want to lock into veSDL, the UI will show how much additional veSDL you will receive.
   * Note it is not possible to lock SDL for a shorter duration than your current veSDL lock duration

![](https://lh5.googleusercontent.com/Qc-DM7uFwIKqEW69u2oGy2Wvxk_9vnxyB2CmEmKQwW1hjrAxRn8AbvOwzGvxEC4ydkBhBzNRcQL3yhATMcFPZKTbW2NIQMLS5tGVpU8mjMQ09kUpLYXIZwT_w63kWSflm3cKy8HmycrN2VKEiA)

#### To unlock veSDL back into SDL:

1. Go to veSDL Unlock section and click \[Unlock] button, approve + execute transaction in your wallet
   * Note that unlocking veSDL before lockup expiry date will have a penalty. The amount is prorated linearly; so the closer you get to your unlock date, the smaller the penalty for unlocking early.

![](https://lh3.googleusercontent.com/HcPbhXTgF99TsbPF1sgMqEzHUHsm_ecK2KmfU7C_304ep3Da2oFt1Lz6pkSnByukH3elGwvR0Q2FUPbzcRVnSXgsgoOzRlFb8VtadUoIpjzK9xPph-mwjnXvM209FFTtL0dIbIsYaBCdGXjMag)

### How to calculate how much veSDL you need to max out reward boosts (boosties)

The amount of veSDL you need to hold in order to max out SDL rewards will vary depending on a number of factors.

The best way to max out your boosties is by using the veToken calculator.

1. Head to the veSDL page on saddle.exchange
2. Click “veToken calculator” text at the end of the SDL Lock section

To calculate max boost (2.5x),

1. Under Max boost calculator, select which pool to calculate for (see image below)
2. Input how much liquidity you’re planning to deposit
3. See results directly below

To calculate your current boost

1. Under My boost calculator, input your veSDL amount (if you have veSDL, it will be auto-populated with your veSDL holdings)
2. See results directly below

Note that the amount of veSDL needed to maintain maximum boost changes depending on pool size and amount of veSDL pool LPs hold. In order to maintain max boosties, we recommend locking 20-50% more SDL than what the Max boost calculator shows.

![](/files/dmLpv3NZoueaWrwXI1IO)

### How to vote in gauge for allocating SDL rewards

As a veSDL holder, you have the power to vote on which Saddle pools will emit SDL incentives (and how much incentives) on a weekly basis.

For the first 6 months following launch of veSDL, a total of 30M SDL in incentives will be emitted. Your vote will help determine which pools those incentives are emitted to, and thus which pool LPs will receive more SDL for their contributions to pool liquidity. (Note that in the first week, SDL incentives will be distributed proportionally to each pool based on TVL on Mainnet. Pools on alt L1s and L2s will continue to emit rewards via MiniChef and will be added to the gauge system at a later date)

Voting is done via Snapshot, so it will be free / gasless!

To vote, simply head to the veSDL page on saddle.exchange, and under the Gauge Vote section, click the \[Vote] button for the current week. (Or head to [Saddle’s Snapshot](https://snapshot.org/#/saddlefinance.eth) directly to vote).

**First vote (for Week 2) will start on Friday 06/24/2022.**

![](https://lh3.googleusercontent.com/biKzFSWey8uy9nRRqIejvRCQVIo2aTE0e3iIJt8Advrz-6XOs_-HjS78UY9Y-upVd1bGAWSgRH-jMCp-_YpIOjC6rTNxTAlQ85EqOfLPJzglApCFqD7f31dqDUgg85cPrXjmovq8FhiYrW634A)

### Understanding your voting power (i.e. how much veSDL you’re actually holding) based on lock time

The longer you lock your assets, the stronger your voting power.

The elements that influence your voting power are the amount of tokens locked and the period of time: simply put, your voting power = the quantity of SDL locked \* number of weeks locked. For example: Locking 1 SDLfor 4 years gives right to 1 veSDL; locking for 1 year equates to 0.25 veSDL; locking for 1 week equates to 0.0048 veSDL

As a result, those who commit to holding veSDL for a longer period of time have more voting power (and boosties).

Note that your voting power decays over time, so as your lock duration for SDL decreases, so does your voting power.

## veSDL FAQ

#### **When is the first vote? / When does SDL emissions start via the gauges?**

The gauge will start SDL reward emissions on 06/23/2022 at 8PM EST.

First vote (for Week 2) will start the following day on 06/24/2022.

During the first week (06/23/2022 - 06/30/2022), \~63.5% of SDL emissions will be allocated proportionally to each Saddle pool based on TVL, on Mainnet only. Pools on alt L1s and L2s will continue to emit rewards via MiniChef and will be added to the gauge system at a later date. The remaining 36.5% of SDL emissions are allocated to the SDL/ETH SushiSwap gauge.

#### What is vote locking, vote escrow, or veSDL?

When you provide liquidity to Saddle, you earn part of the fees of the pool you provided liquidity to and SDL tokens as a bonus. This works as an incentive for providing liquidity.

If you lock those SDL tokens you received – for a period that goes from 1 to 4 years – you receive a certain amount of veSDL – Vote Escrowed SDL.

You can use veSDL to:

* Boost your rewards in different SDL pools;
* Get voting rights on which pool receives SDL emissions;
* Vote on Snapshot on Saddle governance proposals.

Moreover:

* The longer the locking period, the greater the voting power of the hodler;
* veSDL cannot be transferred – the only way you have to get veSDL is by locking SDL

#### What is the vote locking boost (boosties)?

When you lock SDL, you also earn a boost on your provided liquidity – up to 2.5x. The goal of boosties is to incentivize users to participate in governance by rewarding them with a bigger share of the daily SDL inflation.

#### How are boosties calculated?

There are a few factors the impact your reward boost: The quantity of SDL tokens locked – the higher the amount, the higher the reward; The locking period; Pool liquidity and your proportional ownership of LP tokens; Many factors impact how much veSDL you need to have locked to max out your reward boost for pools you’re LPing in: To calculate how much boost you currently have, see guide [here](#how-to-calculate-how-much-vesdl-you-need-to-max-out-reward-boosts-boosties).

#### How often does my veSDL voting power change?

Your voting power decreases over time, but your boost will take notice of your decreasing voting power every 2 weeks and at user checkpoints. Everyone's boost rate is recalculated automatically every 2 weeks. Each individual's boost rate is also recalculated any time they interact with a gauge or veSDL (i.e. if there’s a user checkpoint).

#### How do boosties work if I LP in multiple Saddle pools?

Depending on how much veSDL you hold, boosties are automatically applied to every Saddle pool you’re LPing for. However, depending on a number of other [factors](#how-are-boosties-calculated), you may need to lock up more SDL in order to maximize your rewards for the most competitive pools you’re LPing in.

#### Can I vote for multiple pools?

Yes. For clarification:

* Voting with veSDL -> determines which pool receives SDL reward emissions
  * When use you use your veSDL to vote for a pool/gauge, you are determining which pool is receiving SDL reward allocations
* Holding veSDL -> your LP in Saddle pools get boosted rewards
  * Independently, based on how much veSDL you hold, your LP in Saddle pools will get boosted rewards automatically

Note that voting doesn't remove or deplete your veSDL. You can both vote and get boosties with your full veSDL.

#### How do I get veSDL?

Purchase SDL on SushiSwap if you don’t own any SDL, then visit the veSDL page at saddle.exchange/#/veSDL and lock your SDL to get veSDL. For more details, visit the guide on How to [lock/unlock SDL <> veSDL](#how-to-lock-unlock-sdl-less-than-greater-than-vesdl).

#### Can I buy, sell, or transfer veSDL?

No, veSDL is non-transferrable. See previous FAQ for how to get veSDL.

#### How do I unlock my veSDL?

Visit saddle.exchange/#/veSDL to unlock your veSDL:

* Option 1: waiting until your vote lock expires and unlocking penalty-free
* Option 2: unlock SDL whenever you want at the cost of paying a penalty.
  * The penalty is calculated by taking the minimum between .75 and (time left until unlock) / 4 years.
  * *For example if you have 2 year left on your lock, the penalty is min(.75, 1/2) = 0.5. So the penalty is 50%.*
  * Penalties are distributed to the remaining lockers pro-rata.

#### **How do I apply boosties?**

If you are creating a new lock (i.e. locking SDL into veSDL for the first time), your boosties will be applied automatically.

If you are adding to your lock (i.e. locking more SDL when you already hold veSDL), you’ll need a checkpoint action (i.e. any interaction with the gauge system counts; so claiming or depositing or withdrawing) in order to update your boost.

* When you lock more SDL, it will not apply the boost on existing gauges automatically.
* When you stake or withdraw LP tokens to/from a gauge it will apply the latest boost based on your veSDL and LP deposit size.
* When you claim rewards, your boost value is based on prior veSDL balance when you last interacted with the gauge, but with current total LP supply in the gauge. Then it’ll update your boost based on current veSDL for future calls.
* If you lock more SDL and don’t claim, you will maintain the initial boost. However, by the time you claim, the total reward rate may have been reduced (rate reduction is possible every 2 weeks). Claiming will use the latest reward rate with prior boost value. Thus you may receive less overall compared to claiming every 2 weeks.

[Click here](#how-to-guide) for a guide on how locking and boosting your SDL rewards works.

#### Will users that hold veSDL on other chains be able to participate in governance?

SDL can only be locked into veSDL on mainnet and is non-transferable once locked. Users holding SDL on other chains will need to bridge to mainnet to lock and participate in governance.


# Cross Chain Gauges

Cross chain gauges are a set of contracts that enable bridging of SDL from the mainnet to corresponding sidechains for liquidity incentivization purposes.

### What are Cross Chain Gauges?

* Cross chain gauges are a set of contracts that enable bridging of SDL from the mainnet to corresponding sidechains for liquidity incentivization purposes
  * This is based on the voting data and veSDL balance from the mainnet.
  * The use of cross chain gauges allows Saddle to combine all sidechain/L2 rewards into the same gauge voting mechanism currently used on the mainnet.
  * Cross chain gauges work in pairs of RootGauge/ChildGauge contracts.
    * A RootGauge contract on the mainnet has the same address as a ChildGauge contract on a sidechain.
    * Users stake sidechain LP tokens via the ChildGauge on a sidechain, and then vote for the corresponding RootGauge on the mainnet.

### What are the benefits of Cross Chain Gauges?

* For the protocol:
  * Easier tracking of rewards. Retire minichefs.
  * Rewards are automatically bridged whenever they are needed. Less management required.
* For our users:
  * No more Snapshot votes for minichef weights.
  * Users will be able to vote on Mainnet with their veSDL balance and their vote carries over. (Same benefit of on-chain gauge voting.)

### Cross Chain Gauges – Risks

* What are the risks of using Cross Chain Gauges?
  * The system is dependent on the associated bridges for each chain. If a bridge becomes unavailable, the admin can take action to prevent issues.
* What are some preventative measures in place in case of exploits?
  * There is a 7-day buffer period per every epoch during which the admin (saddle multisig) can take action to prevent any issues before distribution of SDL is started.
* Some contracts are not fully audited.
  * ArbitrumBridger.sol, OptimismBridger.sol
    * Logic using respective official bridges for bridging to each network.
  * ChildOracle.sol
    * Receives and stores veSDL user data on each side chain
  * RootOracle.sol
    * Pushes veSDL user data to each side chain
  * AnyCallTranslator.sol
    * Responsible for talking to AnyCallv6
  * RewardForwarder.sol
    * Permissionless external reward forwarder for gauges
* How can I stay safe when using Cross Chain Gauges?
  * When voting for a RootGauge/ChildGauge, be sure to double check the name and/or address to ensure you are voting for the correct gauge. This will help prevent any potential errors or misunderstandings.
  * If you notice any irregular distribution/bridging, please reach out to us on Discord.

### Cross Chain Gauges – How-To

* How do I stake my LP tokens in a gauge on a side chain?

  * Via Farms page or within each pool’s deposit/withdraw page.

  <figure><img src="https://lh6.googleusercontent.com/PDUZYowvkZPKqdT8im6lQxSAoz83Kd3cMg5AmzxZR6nA7qgoQ_9siu7V80FOW-R9UuA2_LDhi14_bAhoGsnDig-m_liHxznmjEa_787PD6jGgoiRVVHQOucuQ-JLc1D_n8r1gOKjDKRGFzNnsFBAeUKW3LSsKpld5XEkQoxdadxF1qgaOK9Fmhv0LQr0zg" alt=""><figcaption></figcaption></figure>
* How do I vote for a gauge on a side chain?

  * All votes must happen on Mainnet where veSDL exists.
  * Vote options will contain root gauges that have corresponding child gauges on side chains.
  * You can vote for the corresponding root gauge.

  <figure><img src="https://lh6.googleusercontent.com/DVfnC6Hy74qbAWw1K7VlBdVZ8JurvI8IK-qxbfdRZxjpSfJNrLZGj-wYSujP_FKEOwTVBjHsA0rDhsh_UtXEARoVodqO4A54cwcaYSndVjk_i5bgTFHjNZyFhHTYKQsg8GhITo0xx-aLz-1hE6Bzg8F0AFQBVzWoK9Jq4JA2n-vsst0vQxM8EiqxuorSKA" alt=""><figcaption></figcaption></figure>
* How do I claim SDL for a child gauge?

  * Via Farms page or modal on top right.

  <figure><img src="https://lh3.googleusercontent.com/xYv5mLroGW-4OGFtvRno-e73s-qet1caaOAjysBN8F27sdLZv9eX1WYa3JUgQ9mNqjQuLaWd09ZUF3sHRbUHzNpHPWc-uJO6N71Kf5eBLvndRp08esxYKVVPrlRgvFqazKLpvRGNcaq-kMjqS6nxHeyLzSg34QbB2g42fL8WIAvQKeZg46C8CmLZHqaDjg" alt=""><figcaption></figcaption></figure>

### Cross Chain Gauges – FAQs

* How frequently are the rewards bridged to sidechains?
  * At least every 7 days. The rewards for side chains will wait in mainnet until the current epoch is over. Then once the new epoch starts, the waiting SDL can be bridged.
  * An epoch is a 7-day period that begins on Wednesday at UTC 00:00. Minter typically distributes SDL based on the votes up to the previous epoch. In the case of cross chain gauges, there is a buffer of another epoch before rewards are bridged to the side chains for distribution.
* How long does bridging take after the end of the epoch?
  * Depends on each bridge service, but can expect an average of 10-20 minutes.
* Do users have to do anything special to trigger the emission?
  * On each sidechain, the first claim action per epoch will be used for triggering bridging.
  * Thus, if you claim too early in each epoch, your SDL may be delayed due to bridging
  * After the launch, the Saddle team will run an automated script every week to ensure the bridging is triggered w/o user action
* I claimed my pending SDL on a sidechain but nothing happened. What’s going on?
  * If you are the first account to claim SDL in that epoch, your call will be used to trigger the bridging SDL from mainnet. You can wait for the bridging to finish and make the claim transaction again to receive the pending SDL.


# Governance (SIPs)

SIP stands for Saddle Improvement Proposal.

### Important links:

* [Saddle Improvement Proposals GitHub](https://github.com/saddle-finance/SIPS)
* [Saddle Improvement Proposals](https://sips.saddle.community) (overview)
* [Discourse](https://www.saddle.community) (saddle.community)
* [Snapshot](https://snapshot.org/#/saddlefinance.eth)

## Proposal Process

**SIP** stands for [Saddle Improvement Proposal](https://github.com/saddle-finance/SIPS/blob/master/SIPS/sip-0.md#what-is-an-sip). An SIP is a design document providing information to the Saddle community about a proposed change to the system. The author builds consensus within the community and documents dissenting opinions.

### GOVERNANCE STEPS

The chart below shows a high-level view of the Saddle governance process:

![](/files/GaAajFq89w36Hv067nJ7)

#### Stage 1: Gauge Interest

If you have an idea for improving the Saddle protocol, the first stage is to test the waters. Go to Saddle on [Discord](https://discord.gg/qEtPn5pBvk) and look for the Governance > [#discussion](https://discord.com/channels/780508954916290610/909713556491108352) channel. Share your idea and listen to what the community has to say.

If the initial reactions are positive and encouraging, start formalizing your idea into a post for polling on Discourse.

#### Stage 2: Poll on Discourse

Go to [Discourse](https://www.saddle.community), look for the [Proposals](https://www.saddle.community/c/proposals/6) category, and post your proposal there (rec copying the formatting from a prev passing proposal, or using [this template](https://github.com/saddle-finance/SIPS/blob/master/sip-X.md)).

![](https://lh3.googleusercontent.com/ZjKjKwrLsW36QT2_bYZTbruEWpONi6vEU6kK-398u_2rD6kVsfsGb-GjIzbwc3KgWb0FP8sSKqZxGs_HbMaD19ofrZdmfVnck5pIU7hrvC7azEsyjx7l665iaMLl5kaQV7fm6h5F)

Here’s are a few handy tools to help draft your post:

* Tips on posting proposals on Discourse: [Link](https://www.saddle.community/t/about-the-proposals-category/15)
* Template for your post: [Link](https://github.com/saddle-finance/SIPS/blob/master/sip-X.md)
* Before you click the submit button, check if your post has:
  * **Sections:** Simple Summary, Abstract, Motivation, Specification
  * **Poll:** Include a 72h poll (using the most appropriate poll type, typically Y/N or multiple choice)

All set! Last step is to ping a Saddle Core Contributor in Discord to blast your shiny new proposal on all the socials to maximize engagement.

#### Stage 3: Vote on Snapshot

If the Discourse poll passes after 72 hours, the SIP editor will step in to formalize the SIP. The voting process comprises:

* Creating a vote on [Snapshot](https://snapshot.org/#/saddlefinance.eth) (by SIP editor)
* Creating a specific discussion channel on [Discord](https://discord.gg/qEtPn5pBvk) (by Saddle core contributor or gov mod)
* Announcing the vote on all socials (by Saddle core contributor)
* 72-hour voting period *for SDL holders*

**Stage 4: Fork SIP**

Once the Snapshot voting is finished and passes successfully, the SIP editor will fork the SIPs repo and create a pull request (PR):

* The PR will have a copy of your proposal
* With the metadata filled out, notably *discussions-to* which will link to the Discourse post
* The proposal will be named in the format: *sip-draft\_title\_abbrev.md*
* Read [SIP-0](https://github.com/saddle-finance/SIPS/blob/master/SIPS/sip-0.md) for additional information (e.g., workflow, attaching images/diagrams, SIP editor responsibilities).

#### Stage 5: Execution

Lastly, a Saddle core contributor or SIP editor will coordinate with the [community multisig](/saddle-faq#who-controls-saddles-admin-keys) to execute the proposed change.

### GOVERNANCE ROLES

The stakeholders for the governance process can be both internal and external. Various governance roles exist to ensure the stakeholders engage in delivering the type of value desired or expected. The key roles and responsibilities of Saddle governance are:

#### SIP Editor

Broadly, the [SIP editor](https://github.com/saddle-finance/SIPS/blob/master/SIPS/sip-0.md#sip-editors)’s powers and responsibilities are:

* Checks the incoming proposals for quality
* Validate technical correctness
* Check language and grammar, and other editorial aspects
* Work with the SIP authors for revision, where required
* Create vote on Snapshot
* Formalize and document passed SIPs on GitHub

The editors don’t pass on judgement on SIPs, rather act as an administrative check-and-balance role.

**Who:** The current editors are @alphastorm, @penandlim, @hammeiam, and @ug02fast.

#### Saddle Core Contributors

Core contributor powers and responsibilities:

* Provide feedback on proposals
* Advise on how best to create a passing proposal
* Create channels and shepherd discussions in Discord and Discourse
* Post announcements of voting start on social channels (Discord, TG, Twitter)

**Who:** Anyone with a `Saddle Team` role in Discord

#### Governance Mod

Gov mod powers and responsibilities:

* Moderating messages in communities and deleting inappropriate messages
* Invite, ban, or suspend people who violate the community rules
* Create channels and shepherd discussions in Discord and Discourse
* Create vote on Snapshot

**Who:** No one as of now. Community members interested in contributing as a gov mod should ping `zim#2649` on Discord.


# Saddle Incentives

Saddle rewards the liquidity providers for their contribution to the liquidity pools.

## **SADDLE REWARDS**

Saddle *does not* have a token currently and offers no Saddle specific incentives. However, we offer incentives from other protocols. The [liquidity providers](https://docs.saddle.finance/saddle-faq#who-is-a-liquidity-provider) are rewarded for their contribution to the liquidity pool. Depending on the liquidity pool, the rewards structure varies.

{% hint style="info" %}
Find Saddle's reward calculation code [here](https://github.com/saddle-finance/saddle-contract/blob/master/contracts/helper/MiniChefV2.sol)
{% endhint %}

### **Terminologies**

The terminologies used across Saddle are:

**Earned Fees**: Any earnings of ***Trading Fees*** and/or ***Flash Loan Fees*** from providing liquidity to the Saddle pools.

**Incentives**: The incentives from the ***Saddle protocol and/or partners protocols***. For e.g., KEEP, ALCX. *Note:* Currently there are no Saddle protocol specific incentives.

**Rewards**: Refers collectively to both ***earned fees and incentives***.

### **APY & APR**

Before we cover the pool specific rewards, let’s understand the difference between APY and APR.

**Annual Percentage Yield (APY):** APY refers to the amount of interest a liquidity provider earns over one year. APY is like an interest rate, but the biggest benefit of APY is the *compounding*.

**Annual Percentage Rate (APR):** APR does not factor compounding and represents the annual interest rate.

Let’s take a scenario of 1% interest each month. Therefore,

|                                                |                                                   |
| ---------------------------------------------- | ------------------------------------------------- |
| **APR at 1% interest per month**               | **APY at 1% interest per month**                  |
| APR = Periodic Rate x No. of Periods in a Year | APY = (1 + Periodic Rate) `Number of periods` – 1 |
| APR = 1% X 12 months                           | APY = (1+1%)`12`-1                                |
| 12.00%                                         | 12.68%                                            |

### **Saddle APY & Reward APR**

In Saddle both APY and APR are available as rewards to the liquidity providers. The prevailing rates are available in the [pool details](https://docs.saddle.finance/saddle-pools).

![](/files/-MkpchNJFUDzVsJ89MaD)

**APY pay-out**: In Saddle, APY is calculated based on the last 24 hour volume. In the event of no volume, then you will observe “-” in the Saddle dApp frontend. The trading fees compound automatically for every transaction and are paid when the liquidity providers withdraw their funds.

**APR pay-out**: Saddle partners provide the pool specific APR incentives. Refer to the pool specific section for details.

### **Staking LP Tokens**

The *typical* process to take part in the reward program is to stake the LP tokens. Refer to the pool specific sections to know more about the reward program provided by our partners.

![](/files/HZAtdfBTU9HDfo2JQzdK)

## **BTC Pool**

Saddle rewards you in two ways for the BTC pool – trading fees and as KEEP incentives when you provide liquidity to the BTC pool and stake the LP tokens respectively.

![](/files/4VzgsuxS0KBGR18GomDQ)

### **Trading Fees**

When you provide liquidity to the BTC pool, we will show you the APY you are eligible to receive. The trading fees compound automatically for every transaction and are paid when the liquidity providers withdraw their funds.

### **KEEP Incentives**

**Note: BTC Pool is outdated. Follow the** [**migration**](https://docs.saddle.finance/saddle-incentives#migrating-incentives-to-tbtc-metapool) **guide to move your assets and KEEP incentives to the new tBTC Metapool.**

Once you provide liquidity to the BTC pool, you will receive KEEP tokens representing your share of the liquidity pool. Follow these steps to stake the KEEP LP tokens to earn rewards. Check [KEEP](https://dashboard.keep.network/liquidity) dashboard to know the current interest rates for the deposits.

* **Step 1:** Go to [KEEP Liquidity Rewards Dashboard](https://dashboard.keep.network/liquidity)
* **Step 2:** Connect your wallet

![](/files/-MkpchNMwAXcTeCu1eCf)

* **Step 3:** Scroll down and select **TBTC V2 + SADDLE** pool
* **Step 4:** Enter the amount of KEEP tokens to stake and click DEPOSIT

![](/files/sVjKBqzytvrtpfmLHbgw)

* **Step 5:** Start earning incentives

### **Migrating incentives to tBTC Metapool**

The tBTC metapool is now [live](https://saddle.exchange/#/pools/tbtc/deposit). The assets from BTC Pool v1 are now split across BTC Pool V2 and tBTC Metapool.

![](/files/-MkpchNO_Avs_qCX-guf)

The KEEP incentives will have to be moved from BTC Pool (v1) to the tBTC metapool. The migration is ***not an automatic process*** and will have to be done manually, as outlined here.

**1. Unstaking KEEP Incentives**

* **Step 1:** Go to [KEEP Liquidity Rewards Dashboard](https://dashboard.keep.network/liquidity)
* **Step 2:** Connect your wallet
* **Step 3:** Scroll down and select **TBTC V2 + SADDLE** pool
* **Step 4:** Click WITHDRAW ALL to unstake your KEEP rewards

**2. Withdraw assets from BTC Pool (v1)**

* **Step 1:** Go to [BTC Pool Withdraw](https://saddle.exchange/#/pools/btc/withdraw)
* **Step 2:** Enter the amount you wish to withdraw
* **Step 3:** Choose slippage and gas
* **Step 4:** Click Withdraw

**3. Option 1 : Deposit assets into directly into tBTC Metapool**

* **Step 1:** Go to [tBTC Pool Deposit](https://saddle.exchange/#/pools/tbtc/deposit)
* **Step 2:** Enter the amount you wish to deposit
* **Step 3:** Choose slippage and gas
* **Step 4:** Click Deposit
* **Step 5:** After the transaction confirms, stake your LP tokens to earn rewards

**3. Option 2 : Deposit assets into BTC Pool V2 and then into tBTC Metapool**

* **Step 1:** Go to [BTC Pool V2 Deposit](https://saddle.exchange/#/pools/btcv2/deposit)
* **Step 2:** Enter the amount you wish to deposit
* **Step 3:** Choose slippage and gas
* **Step 4:** Click Deposit
* **Step 5:** Receive LP Tokens (saddleBTC-V2)
* **Step 6:** Go to [tBTC Pool Deposit](https://saddle.exchange/#/pools/tbtc/deposit)
* **Step 7:** Click on **Deposit Wrapped**

![](/files/-MkpchNPbKHqhlieo9wQ)

* **Step 8:** Enter the amount you wish to deposit
* **Step 9:** Choose slippage and gas
* **Step 10:** Click Deposit
* **Step 11:** After the transaction confirms, stake your LP tokens to earn rewards

**4. Staking LP tokens to earn incentives**

**Note 1**: tBTC has been upgraded to v2, learn more about it [here](https://blog.keep.network/keep-proposal-overview-shifting-incentives-towards-coverage-pools-and-tbtc-v2-6517a37625c2).

**Note 2:** You can follow this [guide](https://forum.keep.network/t/how-to-stake-saddle-tbtc-lps-with-etherscan/335) to stake tBTC using Etherscan.

## **alETH Pool**

Saddle rewards you trading fees, flash loan fees , and alETH LP tokens every time you provide liquidity to the alETH pool and stake the LP tokens respectively.

![](/files/uQGyEJlC806hTGhJcpzG)

### **Trading Fees**

When you provide liquidity to the alETH pool, we will show you the APY you are eligible to receive. The trading fees compound automatically for every transaction and are paid when the liquidity providers withdraw their funds.

### **Flash Loan Fees**

The alETH pool also supports flash loans, which will generate additional returns for liquidity providers. When you provide liquidity to the alETH pool, we will show you the APY you are eligible to receive. The flash loan fees are included in the trading fees.

### **ALCX Incentives**

Once you provide liquidity to the alETH pool, you will receive alETH Saddle LP tokens representing your share of the liquidity pool. Follow these steps to stake the ALCX LP tokens to earn incentives. Check [Alchemix Staking Dashboard](https://app.alchemix.fi/farms) to know the current interest rates for the deposits.

* **Step 1:** Go to [Alchemix Staking Dashboard](https://app.alchemix.fi/farms)
* **Step 2:** Click on **Connect** to connect to your wallet

![](/files/-MkpchNR7IwD2mQlsVHH)

* **Step 3:** Once the wallet is connected, click on **alETH Saddle LP Pool**

![](/files/O3z1HDCur8m4rk3nbbyi)

* **Step 4:** Enter the amount of LP token you wish to stake and click approve

![](/files/-MkpchNT86SxM4Fyucdx)

* **Step 5:** Start earning incentives

## **Stablecoin Pool V2**

Saddle rewards you in two ways for the stablecoin pool - trading fees and flash loan fees. The Stablecoin Pool V2 live supports flash loans, which will generate additional returns for liquidity providers.

![](/files/-MkpchNUx52h36uWR0c9)

**Note:** Stablecoin Pool (v1) is outdated and V2 is live now. V2 provides a smoother and cheaper way to provide liquidity and swap the stablecoins. V2 also comes with optimized code (lower gas costs), meta pool, [flash loan](https://docs.saddle.finance/howtoflashloan) support, and no more withdrawal fee. Follow [this guide](https://medium.com/saddle/launching-v2-of-the-saddle-3pool-bc82f0bcd700) to migrate your liquidity to V2.

### **Trading Fees**

When you provide liquidity to the Stablecoin V2 pool, we will show you the APY you are eligible to receive. The trading fees compound automatically for every transaction and are paid when the liquidity providers withdraw their funds.

### **Flash Loan Fees**

The Stablecoin V2 pool also supports flash loans, which will generate additional returns for liquidity providers. When you provide liquidity to the pool, we will show you the APY you are eligible to receive. The flash loan fees are included in the trading fees.

## **D4 Pool**

Saddle rewards you in three ways for the D4 decentralized pool – trading fees, flash loan fees , and four incentives (TRIBE, FXS, LQTY, and ALCX tokens) every time you provide liquidity to the D4 pool.

![](/files/drt4usYR0yOw5D2EKMHT)

### **Trading Fees**

When you provide liquidity to the D4 pool, we will show you the APY you are eligible to receive. The trading fees compound automatically for every transaction and are paid when the liquidity providers withdraw their funds.

### **Flash Loan Fees**

The D4 pool also supports flash loans, which will generate additional returns for liquidity providers. When you provide liquidity to the D4 pool, we will show you the APY you are eligible to receive. The flash loan fees are included in the trading fees.

### **ALCX/FXS/LQTY/TRIBE Incentives**

Once you provide liquidity to the D4 pool, you will receive LP tokens representing your share of the liquidity pool. Follow these steps to stake the LP tokens to earn incentives (ALCX, FXS, LQTY, and TRIBE), using the [FRAX Staking Dashboard](https://app.frax.finance/staking). The current interest rates for the deposits are available in the dashboard.

* **Step 1:** Go to [FRAX Staking Dashboard](about:blank)
* **Step 2:** Choose on **Staking** **🡪 Saddle alUSD/FEI/FRAX/USD**

![](/files/-MkpchNWI4Hl_nB_1bGU)

* **Step 3**: Scroll down and click on **Connect Wallet**

![](/files/-MkpchNXB5C-OHgk0xON)

* **Step 4**: Choose the **Amount** to stake, **Days** to stake, and click on **Stake**

![](/files/-MkpchNYjvyT54pFloNF)

* **Step 5:** Start earning incentives

## **sUSD Metapool**

Saddle rewards you with trading fees when you provide liquidity to the sUSD metapool. If you observe “-” in the Saddle dApp frontend, it means there has not been any trading volume over the last 24 hours to calculate the APY.

## **BTC Pool V2**

Saddle BTC pool V2 is [live](https://blog.saddle.finance/launching-v2-of-the-saddle-btc-pool/). Saddle rewards you with trading fees when you provide liquidity to the BTC Pool V2. For migrating incentives from BTC Pool v1, follow this [guide](https://docs.saddle.finance/saddle-incentives#migrating-incentives-to-tbtc-metapool).

## **tBTC Metapool**

Saddle tBTC Metapool is [live](https://saddle.exchange/#/pools/tbtc/deposit). For details on rewards and migrating rewards, refer to the [BTC Pool section](https://docs.saddle.finance/saddle-incentives#migrating-incentives-to-tbtc-metapool).

Saddle rewards you in two ways for the tBTC Metapool – trading fees and as KEEP incentives when you provide liquidity to the tBTC Metapool and stake the LP tokens respectively.

![](https://lh5.googleusercontent.com/W-HDdIeYNYYsblQtJJkozIhLcPcDSCgQ5Nu6Ojf9hi7ssPLIg-eMtQEOm1j4TyxTqBQAPVpjYGa0Pk7qWL2ePNGag6pP_z2aCdB9mUSxSpMHK1PdSKEfUhhTP3I4pIfVtFwUi60)

### **Trading Fees**

When you provide liquidity to the tBTC metapool, we will show you the APY you are eligible to receive. The trading fees compound automatically for every transaction and are paid when the liquidity providers withdraw their funds.

### **KEEP Incentives**

Once you provide liquidity to the BTC pool, you will receive KEEP tokens representing your share of the liquidity pool. Follow these steps to stake the KEEP LP tokens to earn rewards. Check [KEEP](https://dashboard.keep.network/liquidity) dashboard to know the current interest rates for the deposits.

**Step 1:** Go to [KEEP Liquidity Rewards Dashboard](https://dashboard.keep.network/liquidity)

**Step 2**: Connect your wallet

![](https://lh5.googleusercontent.com/5NMf0iiwGiO7CUv6WK4Eq8AOng9meiuA5166qw3Uoz-fya0dwxu2S_Q6nsFBekGwz6OqFTLeYQ9Kf7GIqfd7tDQ6eVb_jHxPRe5KTXMX00pAwpPaME8ALiC8WQnNLq3HhLNYFEQ)

**Step 3:** Scroll down and select \*\*TBTC V2 + SADDLE \*\*pool

**Step 4:** Enter the amount of KEEP tokens to stake and click DEPOSIT

![](https://lh6.googleusercontent.com/38cpxpgO33vDyL26QTsGfRcwM1F884LQuzuTULstnyHOozsptRvyy-SY35MIEq-GNbS3v2X-JVq8tTRH9P8Zz7k-Dh-l_v4l2WLHzlk3Ucelxw3N1k5TzxyUuHQoKIBKo3S_6yY)

**Step 5:** Start earning incentives

**Note: If you are migrating from BTC Pool, you must manually migrate your KEEP rewards. Check out the migration** [**guide**](https://docs.saddle.finance/saddle-incentives#migrating-incentives-to-tbtc-metapool)**.**

## **wCUSD Metapool**

Saddle rewards you with trading fees when you provide liquidity to the wCUSD metapool. If you observe “-” in the Saddle dApp frontend, it means there has not been any trading volume over the last 24 hours to calculate the APY.


# Saddle Protocol Stats

Key stats and tools to interpret Saddle protocol.

In this section, we will explain the key stats and the analytics tools available to interpret the protocol stats.

## **SADDLE PROTOCOL STATS**

### **Total Value Locked (TVL)**

Total value locked is the funds (assets) currently locked (staked) in Saddle protocol. TVL represents the total dollar valuation of all the assets deposited in Saddle’s smart contracts.

Live Chart: <https://www.tokenterminal.com/terminal/projects/saddle-finance>

![](/files/wvVewUn55iPui7p1Idvr)

### **Trading Volume (TV)**

Trading volume is the number of units traded in the market during a time. For instance, a 24-hour trading volume shows the value of assets bought and sold over the course of a day.

Live Chart: <https://www.tokenterminal.com/terminal/projects/saddle-finance>

![](/files/pHGWRn4YpOgFK0NJgEmH)

### **Total Revenue (Trading Fees)**

Total revenue is a measure of the trading fees paid by the traders over a specific period.

Live Chart: <https://www.tokenterminal.com/terminal/projects/saddle-finance>

![](/files/RWxJxhoxupgQRzHsobr3)

### **Supply-Side Revenue**

Supply-side revenue is the share of trading fees which go to the liquidity providers (LPs) for their contribution to the liquidity pools.

Live Chart: <https://www.tokenterminal.com/terminal/projects/saddle-finance>

![](/files/IgXF4s9ntMJBWx58ca3q)

### **Revenue Composition**

A chart on asset vs revenue comparison – which asset contributes most to the revenue generated on Saddle.

Live Chart: <https://www.tokenterminal.com/terminal/projects/saddle-finance>

![](/files/v9DwSmpPU0NcAthV5QC4)

### **Liquidity By Asset**

Liquidity refers to how easily and quickly assets are bought or sold *without* affecting the asset's price. Assets with a high volume of trade are typically considered liquid.

Live Chart: <https://dune.xyz/alphast0rm/Saddle>

![](/files/OFgFrPO6I8k046KjSst1)

### **LP Tokens Staked**

Saddle rewards LP tokens for contributing to the liquidity pools. Liquidity providers can further stake the LP tokens to earn additional rewards. This stat shows the LP tokens issued vs staked.

Live Chart: <https://dune.xyz/alphast0rm/Saddle>

![](/files/Bcpg1SJjGytUBlLtYNxs)

## **SADDLE POOL STATS**

Besides the protocol stats, many tools are available to understand the technical information around Saddle. In this section, we will explain the key stats and the tools available to interpret the technical stats.

### **Unique Deposit Address**

The unique deposit address denotes the liquidity providers of Saddle. A wide spread of unique addresses is a measure of the fair distribution and mass adoption of the Saddle ecosystem.

Live Chart: <https://dune.xyz/alphast0rm/Saddle>

![](/files/GHHxZFXhDAAHFm4Uot6Y)

### **Smart Contract Stats**

By using block explorer tools - like [Etherscan](https://etherscan.io), [BlockChair](https://blockchair.com), or [OKLink](https://www.oklink.com) – users can extract and analyze lots of technical stats around Saddle’s smart contracts. To extract the information, you’ll need the Ethereum address. You’ll find the smart contract address of all Saddle Pools [here](https://docs.saddle.finance/contracts).

In this example, we’ll analyze the stats of the D4 Saddle Pool with the smart contract address: *0xC69DDcd4DFeF25D8a793241834d4cc4b3668EAD6*.

**Etherscan.io Block Explorer**

* **Step 1:** Choose the pool and copy the smart contract address from [here](https://docs.saddle.finance/contracts)
* **Step 2:** Go to [https://etherscan.io/](https://etherscan.io)
* **Step 3:** Enter the smart contract address in the search box. Click *Search*.
* **Step 4**: You’ll now see the stats of the D4 Saddle Pool

![](/files/Vl1wgQjpD4R2w9XRiLV6)

**Blockchair.com Block Explorer**

* **Step 1:** Choose the pool and copy the smart contract address from [here](https://docs.saddle.finance/contracts)
* **Step 2:** Go to [https://blockchair.com/](https://blockchair.com)
* **Step 3:** Enter the smart contract address in the search box. Click *Search*.
* **Step 4**: You’ll now see the stats of the D4 Saddle Pool

![](/files/Mmxb5WMurQizpQpl2xrn)

### **Visualizing Smart Contracts**

By using visualization tools - like [Bitquery](https://explorer.bitquery.io) – users can extract the stats in visual and easily digestible format. To extract the information, you’ll need the Ethereum address. You’ll find the smart contract address of all Saddle Pools [here](https://docs.saddle.finance/contracts).

In this example, we’ll analyze the stats of the D4 Saddle Pool with the smart contract address: *0xC69DDcd4DFeF25D8a793241834d4cc4b3668EAD6*.

**Bitquery.io Block Explorer**

* **Step 1:** Choose the pool and copy the smart contract address from [here](https://docs.saddle.finance/contracts)
* **Step 2:** Go to [https://explorer.bitquery.io/](https://explorer.bitquery.io)
* **Step 3:** Enter the smart contract address in the search box. Click *Search*.
* **Step 4**: Click on Ethereum Mainnet in the results shown

![](/files/K892FbCRy5MDyHgTWSEP)

![](/files/LwDa60rpeihP2rtvgW6q)


# Yield Farming Tools

Key tools which offer convenient information about Saddle pools and your liquidity.

[Liquidity pools](https://docs.saddle.finance/saddle-faq#what-is-a-saddle-pool) are becoming integral to decentralized finance. With continuous innovation, it may become complicated to keep track of everything that’s essential. [Yield farm](https://docs.saddle.finance/saddle-faq#what-is-yield-farming)/ asset management and rewards management tools provide DeFi data in one convenient place. Many tools are available to track liquidity, prices, interest rates, yields, and rewards.

In this section, we’ll highlight key tools which offer convenient information about Saddle pools and your liquidity.

## **YIELD FARM & ASSET MANAGEMENT TOOLS**

### **VFAT.TOOLS**

Vfat.tools is a calculator for yield farming. With a minimalist dashboard, vfat.tools offer concise information regarding liquidity pools and their APYs.

You can access the Saddle farming calculator from the URL: <https://vfat.tools/saddle/>.

![](/files/-MkkkwMgLsKx5nI1JAl9)

### **ZAPPER.FI**

Zapper is a DeFi dashboard for monitoring your portfolio, including assets, debts, liquidity pools, staking, claimable rewards, and yield farming activities – but it requires you to share no personal data. You can enter and exit DeFi positions directly, through the Zapper dashboard, via actions called “Zap In” and “Zap Out.”

You can access Saddle farming dashboard from the URL: <https://zapper.fi/farm>

**Go to Zapper.fi/farm 🡪 search for Saddle tokens**

![](/files/-MkkkwMh_DBETW2HalTA)

**Choose Saddle tokens 🡪 Stake or Unstake**

![](/files/-MkkkwMiVdDBKTZpvuWB)

## **REWARDS MANAGEMENT TOOLS**

### **TBTCFARM.INFO**

Track the different yields you can get on tBTC token.

You can access the Saddle pool information from the URL: <https://www.tbtcfarm.info/pool/saddle>

![](/files/-MkkkwMjAbSH68kcCxF2)

### **KEEP REWARDS**

Stake, track, and unstake the KEEP LP (liquidity pool) tokens you can get on Saddle BTC pool.

You can access the Saddle pool information from the URL: <https://dashboard.keep.network/liquidity>

![](/files/50WGWclIGwHM2UitJixH)

### **ALCX REWARDS**

Stake, track, and unstake the ALCX LP (liquidity pool) tokens you can get on Saddle alETH pool.

You can access the Saddle pool information from the URL: <https://app.alchemix.fi/farms>

![](/files/-MkpchNSqugonvu_dE-U)

### **FRAX REWARDS**

Stake, track, and unstake the four LP tokens (ALCX, FXS, LQTY, and TRIBE) you can get on Saddle D4 pool.

You can access the Saddle pool information from the URL: <https://app.frax.finance/staking>

![](/files/hFUxwOwK2PgWcgbq6i28)


# Build With Saddle

We welcome an opportunity to work with you.

Saddle combines the best of three worlds – Bitcoin, Pegged Value Assets, and Ethereum DeFi. Saddle is an [automated market maker](https://docs.saddle.finance/automated-market-makers) (AMM) enabling trading between [pegged value crypto assets](https://docs.saddle.finance/saddle-faq#what-are-pegged-value-crypto-assets-pegged-assets). We solve the [slippage problem](https://docs.saddle.finance/saddle-faq#what-is-a-slippage) with a tailored AMM allowing users to trade with minimal slippage.

### **Our Values**

Saddle stands for DeFi, for financial Lego blocks.

* We commit ourselves to [open-source software](https://github.com/saddle-finance) and collaboration.
* We support all projects that want on top of our code
* We’ll work with you if you want to bring pegged asset swap to another chain.

### **Collaborate With Saddle**

We welcome an opportunity to work with you. Here are a few ways to collaborate:

* Work together on implementing our code, provide engineering support, and answer questions
* Feature you and your project in our upcoming AMA series
* Promote your project across our social channels
* Token swaps and joint projects

We have just a few asks in return – kindly give us credits on your social channels and include us in any token distributions :)

### **Logo & Media Kit**

You can download Saddle's logo, guidelines, and brand assets from [here](https://drive.google.com/drive/folders/13rTY6x24crioqOgyGCE6zJo0197AMVtD?usp=share_link).

### **Get in Touch**

Want to work on something together?

* Join our [Discord](https://discord.gg/qEtPn5pBvk) and write a post in #partnership-intake-forum, or
* Tweet or DM to us on [Twitter](https://twitter.com/saddlefinance)

## **FEATURED PROJECTS**

The following projects have used Saddle’s protocol code, with varying degrees of collaboration and support.

{% hint style="info" %}
Find the forked projects of Saddle [here](https://github.com/saddle-finance/saddle-contract/network/members)
{% endhint %}

### **SushiSwap V3**

***Project*****:** [SushiSwap](https://sushi.com) is an automated market-making (AMM) decentralized exchange (DEX). Besides DEX, SushiSwap involves a collection of governance, operations and reward contracts that help grow the ecosystem and utilization.

***Chain*****:** Ethereum blockchain.

***Partnership***: SushiSwap’s AMM uses Saddle’s StableSwap implementation for the pegged-assets pool.

***Key People***: SushiSwap was created in 2020 by a pseudonymous individual or group called [Chef Nomi](https://twitter.com/NomiChef), along with co-founders, Sushiswap and [0xMaki](https://twitter.com/0xMaki).

### **Nerve Finance / Synapse**

***Project*****:** [Nerve](https://nerve.fi) / [Synapse](https://synapseprotocol.com) is a StableSwap automated market maker and trustless cross-chain bridge.

***Chain*****:** Ethereum, Binance Smart Chain, Polygon, Avalanche, Arbitrum.

***Partnership***: Nerve/Synapse’s AMM uses Saddle’s StableSwap implementation for pegged-asset pools and Ethereum off-ramp.

***Key People***: Nerve/Synapse's team stays [anonymous](https://docs.nerve.fi/faq#analytics). But you can follow the core team members via their twitter links [(@AureliusBTC](https://twitter.com/AureliusBTC) and [@Socrates0x](https://twitter.com/Socrates0x)).

### **Snowball**

***Project*****:** [Snowball](https://snowball.network) is a yield optimizer on the Avalanche Network. Snowball combines multiple DeFi protocols to create an interconnected experience. Swap stablecoins, deposit liquidity, or auto-compound liquidity rewards.

***Chain*****:** Avalanche Network.

***Partnership***: Saddle financed Snowball’s AMM audits. Snowball also airdropped us their governance tokens.

***Key People***: The team is currently anon & was started by [@AbominableSasquatch](https://twitter.com/AbominableSas).

### **Iron Finance**

***Project*****:** [Iron Finance](https://iron.finance) is a multi-chain, decentralized, non-custodial ecosystem of DeFi products, protocols, and use cases. IronSwap is an automated market maker (AMM) specialized for fast and efficient stablecoin swapping, aiming to have the best rates with the lowest fees and smallest slippage.

***Chain*****:** Polygon Network.

***Partnership***: IronSwap’s AMM uses Saddle’s StableSwap implementation for the pegged-assets pool.

***Key People***: The Iron Finance team is currently anonymous.

### **Hop Protocol**

***Project*****:** [Hop](https://hop.exchange) is a scalable rollup-to-rollup general token bridge. It allows users to send tokens from one rollup or sidechain to another almost immediately without having to wait for the networks challenge period. It works by involving market makers (referred to as Bonder) who front the liquidity at the destination chain for a small fee. The Bonder extends this credit in the form of hTokens which are then swapped for their native token counterpart in an AMM. The result allows users to seamlessly transfer tokens from one network to the next.

***Chain*****:** Ethereum, Polygon, xDai, Optimism, Arbitrum.

***Partnership***: Hop uses Saddle’s StableSwap as the AMM bridge.

***Key People***: The team comprises [Chris Whinfrey](https://twitter.com/whinfreychris) and [Shane Fontaine](https://twitter.com/shanefontaine).

## **OUR INVESTORS**

Saddle is backed by notable tech investors with a track record of working with successful web3 companies.

### **Framework**

[Framework](https://framework.ventures) is a venture firm that builds alongside the founders. Framework partners with founders and teams to build token-based networks and develop the requisite cryptoeconomics, governance, and community to scale.

### **Polychain Capital**

[Polychain](https://polychain.capital) Capital is the world’s premier digital asset investment fund. Based in San Francisco, Polychain actively manages global blockchain assets to achieve exceptional returns for their investors. Polychain values long-term vision, fierce intelligence, quantitative reasoning, and low-ego open-minded people.

### **Electric Capital**

[Electric](https://www.electriccapital.com) Capital is an early-stage venture firm focused on cryptocurrencies, blockchain, fintech, and marketplaces. EC invests in companies and protocols built on top of Programmable Money.

### **Dragonfly Capital**

[Dragonfly](https://www.dcp.capital) Capital is a cross-border cryptoasset investment firm. Dragonfly Capital Partners are investing in and supporting the most promising opportunities in the cryptoasset class. Managed by experienced VCs from the U.S. and Asia, Dragonfly Capital Partners brings together the leading participants in the decentralized economy.

### **Coinbase Ventures**

[Coinbase Ventures](https://ventures.coinbase.com) invests in companies building the open financial system. Coinbase ventures provide financing to promising early-stage companies that have the teams and ideas that can move the space forward in a positive, meaningful way.

### **Nascent**

[Nascent](https://www.nascent.xyz) is a global, multi-strategy investment firm focused on crypto & open finance.

### **Alameda Research**

[Alameda](https://www.alameda-research.com) Research founded in October 2017 manages over $1 billion in digital assets and trade $1-10 billion per day across thousands of products: all major coins and altcoins, as well as their derivatives. Alameda has a full-scale global operation with the ability to trade in all major exchanges and markets.

### **BoostVC**

[Boost](https://www.boost.vc) VC is an accelerator firm headquartered in San Mateo, California. Boost VC, founded in 2012, invests in pre-seed startups through its accelerator program. It seeks to invest in the cryptocurrency, virtual reality, augmented reality, space, robotics, artificial intelligence, biotech, ocean, and time travel technology sectors.

### **Thesis**

[Thesis](https://thesis.co) builds and funds products and protocols in cryptocurrency and decentralized technology.


# Smart Contract Security

We hire well reputed external agencies to audit our smart contract codes.

Smart contracts are subject to flaws, coding errors, unintended behavior, and inefficiencies. Once deployed in the blockchain, smart contracts are immutable (cannot change). At Saddle, we take the security of the smart contract seriously.

We conduct our own internal security audit of the smart contract code we’ve written. As a further check, to make sure Saddle’s code is proper and working as intended, we hire well reputed external agencies to audit our smart contract codes.

As for now, we have passed security auditing on all Saddle smart contracts, from the following auditors, with no issues.

| **AUDITOR**                             | **PROTOCOL AUDIT**                                                                              | **VIRTUAL SWAP AUDIT**                                                                                      | **TOKEN AUDIT**                                                                                       |
| --------------------------------------- | ----------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- |
| [Certik](https://certik.io)             | [PASSED](https://github.com/saddle-finance/saddle-audits/blob/master/10-29-2020_Certik.pdf)     | N/A                                                                                                         | N/A                                                                                                   |
| [Quantstamp](https://quantstamp.com)    | [PASSED](https://github.com/saddle-finance/saddle-audits/blob/master/12-09-2020_Quantstamp.pdf) | [PASSED](https://github.com/saddle-finance/saddle-audits/blob/master/03-31-2021_Quantstamp_VirtualSwap.pdf) | [PASSED](https://github.com/saddle-finance/saddle-audits/blob/master/10-27-2021_Quantstamp_Token.pdf) |
| [OpenZepplin](https://openzeppelin.com) | [PASSED](https://blog.openzeppelin.com/saddle-contracts-audit/)                                 | N/A                                                                                                         | N/A                                                                                                   |

***Disclaimer**:* Security audits don’t eliminate all risks. Using Saddle as an exchange for a user should be significantly less risky, but please bear in mind there are still risks. Refer to the risks section for more details.

### **Certik Audit Report**

Founded in 2018 by professors at Yale University and Columbia University, CertiK is a pioneer in blockchain security, using best-in-class AI technology to secure and monitor blockchain protocols and smart contracts. CertiK’s mission is to secure the cyber world. Starting with blockchain, CertiK applies innovations from academia into enterprise, enabling mission-critical applications to be built with security and correctness.

![](/files/-MkBjqr-cxKGheGmibe1)

CERTIX AUDIT REPORT FOR SADDLE PROTOCOL - 29 OCT 2020

### **Quantstamp Audit Report**

Quantstamp is the leader in blockchain security, having performed over 200 audits and secured over $100 billion in value. Their top team of PhDs and security professionals have a combined total of over 1,000 Google Scholar citations. They have audited many blockchain systems, including Ethereum 2.0, Binance Smart Chain, Flow, Cardano, and Avalanche and have secured successful innovative applications such as Maker, Compound, and NBA Top Shot.

![](/files/-MkBjqr0Hw6JdiVyTNxe)

QUANTSTAMP AUDIT REPORT FOR SADDLE PROTOCOL - 10 DEC 2020

![](/files/-MkBjqr1cgR4HcfoJdzE)

QUANTSTAMP AUDIT REPORT FOR SADDLE VIRTUAL SWAP – 31 MAR 2021

### **OpenZeppelin Audit Report**

Founded in 2015, OpenZeppelin has set industry standards for building secure distributed systems. OpenZeppelin builds developer tools and performs security audits for distributed systems that power multimillion-dollar economies. OpenZeppelin verifies the distributed systems work as intended by performing an audit. Their engineers fully review the system's architecture and codebase and then write a thorough report that includes actionable feedback for every issue found.

![](/files/-MkBjqr29i5QtY08p9DP)

OPENZEPPLIN AUDIT REPORT FOR SADDLE PROTOCOL - 11 DEC 2020

## **SADDLE ADMIN KEYS SECURITY**

A [Gnosis Safe](https://gnosis-safe.io) multisig secures Saddle’s admin keys. Gnosis is a trusted platform to manage digital assets in Ethereum. Gnosis Safe is a smart contract wallet running on Ethereum, which requires a minimum number of people to approve a transaction before it can occur (M-of-N). This assures that no single person could compromise the funds.

A [3/8 Gnosis Safe multisig](https://etherscan.io/address/0x3F8E527aF4e0c6e763e8f368AC679c44C45626aE) secures Saddle's admin keys. The signers are Mariano Conti, Sam Kazemian, DegenSpartan, Klim K, Damir Bandalo, Aurelius, Scoopy Trooples, and Weston Nelson.

| **NAME**                                           | **ENS**           | **ADDRESS**                                |
| -------------------------------------------------- | ----------------- | ------------------------------------------ |
| [Mariano Conti](https://twitter.com/nanexcool)     | -                 | 0x6F2A8Ee9452ba7d336b3fba03caC27f7818AeAD6 |
| [ScupyTrooples](https://twitter.com/scupytrooples) | scupytrooples.eth | 0xf872703f1c8f93fa186869bac83bac5a0c87c3c8 |
| [DegenSpartan](https://twitter.com/DegenSpartan)   | degenspartan.eth  | 0x4E60bE84870FE6AE350B563A121042396Abe1eaF |
| [Klim K](https://twitter.com/milkyklim)            | yfi.milkyklim.eth | 0x0cec743b8ce4ef8802cac0e5df18a180ed8402a7 |
| [Damir Bandalo](https://twitter.com/damirbandalo)  | -                 | 0xa83838221278f22ee5bAe3E523f34D42b066D67D |
| [Aurelius](https://twitter.com/AureliusBTC)        | aurelius0x.eth    | 0x0AF91FA049A7e1894F480bFE5bBa20142C6c29a9 |
| [Sam Kazemian](https://twitter.com/samkazemian)    | -                 | 0x17e06ce6914E3969f7BD37D8b2a563890cA1c96e |
| [Weston Nelson](https://twitter.com/westonnelson)  | westonnelson.eth  | 0xD131F1BcDd547e067Af447dD3C36C99d6be9FdEB |

*Note: The multisig has the capability to pause new deposits and trades in case of technical emergency. Users will always be able to withdraw their funds regardless of new deposits being paused. The multisig can also change the swap/withdrawal fees and the per pool/account deposit limits.*

## **BUG BOUNTY PROGRAM**

We encourage the community to help us find bugs or vulnerabilities in the protocol, and offer a bounty to those who do so with good intention. With the passing of [SIP-29](https://snapshot.org/#/saddlefinance.eth/proposal/0x867fd038ed31a996901dead7ffbb32b2fcd38408e5924e7f489dbf7f62cbdcd0), the bounty is to be calculated as the lower value of 10% of the total possible exploit, or 5MM SDL. The bounty will be delivered immediately as liquid SDL.

*Note: This bounty does not cover any front-end/visual bugs, or any server-side code of any web application that interacts with Saddle. The Saddle Bug Bounty is applicable only to vulnerable smart contract code: defined as contracts deployed by Saddle, on any chain, that manage the value of Saddle’s treasury assets and/or user deposited assets. This bounty is a "no questions asked" policy for disclosures and/or immediate return of funds after any incident.*

### **Reporting Process**

Please report any bugs and issues for the Saddle protocol through the [Immunefi Saddle bug bounty program](https://immunefi.com/bounty/saddle/). Reports through any other channels will not be considered.

### **Immunefi Terms & Conditions**

These [Terms and Conditions](https://immunefi.com/bounty/saddle/) cover your participation in the Immunefi Bug Bounty Program. By submitting any vulnerabilities to Saddle Finance or otherwise participating in the Program in any manner, you accept these Terms.


# Asset Specific Risks

Before we accept a cryptocurrency for the Saddle pools, we evaluate the underlying risks for the assets and operations of the asset.

Investing in cryptocurrencies varies in risk. The cryptocurrency assets in the various Saddle protocols are an integral part of the Saddle ecosystem. Any risks to the assets may negatively impact the pool.

Before we accept a cryptocurrency for the liquidity pools, we evaluate the underlying risks for the assets and operations of the asset. If one or more risks are significant, we don’t accept the cryptocurrency for the Saddle pools. The three main risk evaluation parameters are:

***Smart-contract risks***: DeFi is a complicated network interconnected through hundreds of smart contracts created by various 3rd parties. Typically, smart contracts undergo code reviews, security audits, and bug bounty programs - yet that doesn’t absolve the contracts of any technical glitches and bugs entirely. When Saddle evaluates a cryptocurrency asset for our liquidity pools, we focus on the maturity, besides many other parameters, of the smart contract. The **age** of the smart contract and the community **adoption** (specifically the number of transactions) is a powerful indicator of the smart contract robustness.

***Counter-party risks***: Counterparty risk relates to a 3rd party defaulting on its contractual obligation. Though open blockchain networks and DeFi are designed with the goal of eliminating counterparty risks, some cryptocurrency assets carry the counterparty risk because of their design. Digital assets tied to real-world assets, dependent on external Oracles for information, and centralized are few examples of counterparty risk. At Saddle, we qualitatively evaluate counterparty risks from a **trust** and **governance** point of view.

***Market risks***: We primarily relate fluctuations and liquidity to the market risks of cryptocurrencies. Stablecoins and pegged-value assets, which make up the Saddle pools, address the volatility to an extent. However, if one asset in the pool significantly depegs, it will effectively mean that it will leave pool liquidity providers holding only that asset. Liquidity risk may happen because of a seller not finding a buyer or there is a mandatory lock-in period.

In this section, we will examine the risks for each asset in the Saddle pools composition. The information provided is as of the 3rd week of **Aug 2021**.

|                        |                               |                  |                |             |              |            |
| ---------------------- | ----------------------------- | ---------------- | -------------- | ----------- | ------------ | ---------- |
| **Asset**              | **Age**                       | **Transactions** | **Governance** | **Holders** | **MCAP ($)** | **Supply** |
| **BTC Pool**           |                               |                  |                |             |              |            |
| renBTC                 | > 1 year                      | 10k - 100k       | Decentralized  | 1k - 5k     | $100m - $1b  | < 500k     |
| sBTC                   | > 2 years                     | 10k - 100k       | Decentralized  | 1k - 5k     | $100m - $1b  | < 500k     |
| tBTC                   | > 1 year                      | < 10,000         | Decentralized  | < 1,000     | $10m - 50m   | < 500k     |
| wBTC                   | > 2 years                     | 100k - 500k      | Decentralized  | 10k - 100k  | > $5b        | < 500k     |
| **alETH Pool**         |                               |                  |                |             |              |            |
| alETH                  | < 1 year                      | 10k - 100k       | Decentralized  | < 1,000     | N/A          | N/A        |
| sETH                   | > 2 years                     | 10k - 100k       | Decentralized  | 1k - 5k     | $100m - $1b  | < 500k     |
| WETH                   | > 2 years                     | > 1m             | Decentralized  | 100k - 1m   | > $1b        | 1m - 10m   |
| **Stablecoin Pool V2** |                               |                  |                |             |              |            |
| DAI                    | > 1 year                      | > 10m            | Decentralized  | 100k - 1m   | > $5b        | > 5b       |
| USDC                   | > 2 years                     | > 10m            | Centralized    | > 1m        | > $5b        | > 5b       |
| USDT                   | > 2 years                     | > 10m            | Centralized    | > 1m        | > $5b        | > 5b       |
| **D4 Pool**            |                               |                  |                |             |              |            |
| alUSD                  | < 1 year                      | < 10,000         | Decentralized  | < 1,000     | $100m - $1b  | 100m - 1b  |
| FEI                    | < 1 year                      | 10k - 100k       | Decentralized  | 1k - 5k     | $100m - $1b  | 100m - 1b  |
| FRAX                   | < 1 year                      | 100k - 500k      | Decentralized  | 1k - 5k     | $100m - $1b  | N/A        |
| LUSD                   | < 1 year                      | 100k - 500k      | Decentralized  | 1k - 5k     | $100m - $1b  | N/A        |
| **sUSD Pool**          |                               |                  |                |             |              |            |
| sUSD                   | > 2 years                     | 500k - 1m        | Decentralized  | 10k - 100k  | $100m - $1b  | 100m - 1b  |
| saddleUSD-V2           | *Refer to Stablecoin Pool V2* |                  |                |             |              |            |
| **wCUSD Pool**         |                               |                  |                |             |              |            |
| wCUSD                  | < 1 year                      | < 10,000         | Decentralized  | < 1,000     | $1m - $10m   | 500k - 1m  |
| saddleUSD-V2           | *Refer to Stablecoin Pool V2* |                  |                |             |              |            |

## **alETH**

alETH is a synthetic ETH backed asset by Alchemix Finance. alETH is an ERC20 token, backed 4:1 by ETH.

***Smart-contract risks***: The alETH smart [contract](https://etherscan.io/token/0x0100546F2cD4C9D97f798fFC9755E47865FF7Ee6) was launched in June 2021, making it a relatively *young contract*. The number of transactions since launch stands at 2,852. The total [amount](https://explorer.bitquery.io/ethereum/token/0x0100546f2cd4c9d97f798ffc9755e47865ff7ee6) transacted is \~76,131 alETH, with a median of \~1.25 alETH.

***Counter-party risks***: Alchemix Finance is a future-yield-backed synthetic asset platform and community [DAO](https://alchemix-finance.gitbook.io/alchemix-finance/alchemix-dao). The vision is for a full on-chain governance, giving complete control to the community for several protocol parameters. There are 128 token [holders](https://etherscan.io/token/0x0100546F2cD4C9D97f798fFC9755E47865FF7Ee6#balances) at the time of writing.

***Market risks***: alETH is backed by ETH in the 4:1 ratio. At present, the [market](https://forum.alchemix.fi/public/d/173-aip-15-raise-the-aleth-debt-cap-and-end-alusd-only-rewards) capitalization for alETH is over US$ 41 million.

***Notable incidents***: The following incidents and/or bugs were observed relating to the protocol:

* [Incident Report – 06162021](https://forum.alchemix.fi/public/d/137-incident-report-06162021) relating to a bug.

## **alUSD**

alUSD is a yield-backed synthetic stablecoin minted via Alchemix Finance. Users deposit DAI stablecoin to mint alUSD which tokenizes upto 50% of the DAI deposited.

***Smart-contract risks***: The alUSD smart [contract](https://etherscan.io/address/0xbc6da0fe9ad5f3b0d58160288917aa56653660e9) was launched in February 2021, making it a *young contract*. The number of transactions since launch stands at 2,852. The total [amount](https://explorer.bitquery.io/ethereum/token/0xBC6DA0FE9aD5f3b0d58160288917AA56653660E9) transacted is \~ 9,599,359,702 alUSD, with a median of \~ 9,650 alUSD.

***Counter-party risks***: Alchemix Finance is a future-yield-backed synthetic asset platform and community [DAO](https://alchemix-finance.gitbook.io/alchemix-finance/alchemix-dao). The vision is for a full on-chain governance, giving complete control to the community for several protocol parameters. There are 1,280 token [holders](https://etherscan.io/token/tokenholderchart/0xBC6DA0FE9aD5f3b0d58160288917AA56653660E9) at the time of writing.

***Market risks***: alUSD is yield-backed by depositing the DAI stablecoin. At present, the [market](https://www.coingecko.com/en/coins/alchemix-usd) capitalization for alUSD is $251,612,072 and a circulation coin supply of 252,895,826.

***Notable incidents***: The following incidents and/or bugs were identified relating to the protocol:

* None at the time of writing.

## **DAI**

DAI is a stablecoin or ERC-20 token backed by different digital currencies deposited into its smart contract vaults. DAI attempts to maintain a 1:1 peg to USD.

***Smart-contract risks***: The DAI smart [contract](https://etherscan.io/token/0x6b175474e89094c44da98b954eedeac495271d0f) was launched in November 2019 (prior to Nov 2019, it was active as SAI starting December 2017), making it a *mature* *contract*. The number of transactions since launch stands at over 11 million. The total [amount](https://explorer.bitquery.io/ethereum/token/0x6b175474e89094c44da98b954eedeac495271d0f) transacted is over 580 million DAI, with a median of \~ 998 DAI.

***Counter-party risks***: MakerDAO develops and maintains the software that powers the DAI stablecoin system. MKR holders [govern](https://makerdao.com/en/governance/) the Maker Protocol, which includes adjusting policy for the Dai stablecoin, choosing new collateral types, and improving governance itself. There are 380,957 token [holders](https://etherscan.io/token/tokenholderchart/0x6b175474e89094c44da98b954eedeac495271d0f) at the time of writing.

***Market risks***: Users can generate DAI as debt by depositing equivalent collateral in a smart contract governed vault. At present, the [market](https://www.coingecko.com/en/coins/dai) capitalization for alUSD is over $5.7 billion and a circulation coin supply exceeding 5.7 billion.

***Notable incidents***: The following incidents and/or bugs were identified relating to the protocol:

* Maker’s price feed oracle [stuck](https://defipulse.com/blog/defi-status-report-black-thursday/) resulting in a MKR debt [auction](https://blog.makerdao.com/mkr-debt-auction-announcement-and-details/).

## **FEI**

FEI is a scalable and decentralized stablecoin that leverages protocol-controlled value (PCV) for peg maintenance while maintaining highly liquid secondary markets.

***Smart-contract risks***: The FEI smart [contract](https://etherscan.io/token/0x956f47f50a910163d8bf957cf5846d573e7f87ca) was launched in April 2021, making it a *relatively* *young contract*. The number of transactions since launch stands at 113,670. The total [amount](https://explorer.bitquery.io/ethereum/token/0xBC6DA0FE9aD5f3b0d58160288917AA56653660E9) transacted is over 401 million FEI, with a median of \~ 21,253 FEI.

***Counter-party risks***: FEI is a fully decentralized design and minimal dependence on any centralized assets or protocols on Ethereum. Fei Protocol has a DAO called the Fei [DAO](https://docs.fei.money/governance/fei-dao) from the start. There are 3,880 token [holders](https://etherscan.io/token/tokenholderchart/0x956f47f50a910163d8bf957cf5846d573e7f87ca) at the time of writing.

***Market risks***: Fei is a direct incentive stablecoin which is undercollateralized and fully decentralized, with the goal to maintain a liquid market in which ETH/FEI trades closely to the ETH/USD price. At present, the [market](https://www.coingecko.com/en/coins/fei-protocol) capitalization for FEI is $ 415,899,906 and a circulation coin supply of 417,462,622.

***Notable incidents***: The following incidents and/or bugs were identified relating to the protocol:

* FEI pool becoming [unusable](https://cointelegraph.com/news/fei-protocol-struggles-with-a-bug-as-holders-are-mostly-unable-to-sell-the-token) for a time.
* Bonding curve [bug](https://medium.com/fei-protocol/fei-bonding-curve-bug-post-mortem-98d2c6f271e9).

## **FRAX**

FRAX is a fractional-algorithmic stablecoin that is partially backed by collateral and partially stabilized algorithmically.

***Smart-contract risks***: The FRAX smart [contract](https://etherscan.io/token/0x853d955acef822db058eb8505911ed77f175b99e) was launched in December 2020, making it a *mature contract*. The number of transactions since launch stands well over 107,000. The total [amount](https://explorer.bitquery.io/ethereum/token/0x853d955acef822db058eb8505911ed77f175b99e) transacted is over 5.4 billion FRAX, with a median of \~ 15,988 FRAX.

***Counter-party risks***: The end goal of the Frax protocol is to provide a highly scalable, decentralized, algorithmic money in place of fixed-supply digital assets like BTC. The Frax [governance](https://docs.frax.finance/smart-contracts/governance) module is forked from Compound, with FXS acting as the voting token in the system. There are 1,615 token [holders](https://etherscan.io/token/tokenholderchart/0x853d955acef822db058eb8505911ed77f175b99e) at the time of writing.

***Market risks***: Frax is open-source, permissionless, and entirely on-chain. At present, the [market](https://www.coingecko.com/en/coins/frax) capitalization for FRAX is more than $300 million.

***Notable incidents***: The following incidents and/or bugs were identified relating to the protocol:

* None at the time of writing.

## **LUSD**

LUSD is a collateral-backed stablecoin with a hard price floor of $1 USD. Users of the Liquity protocol (the issuers of LUSD) lock ETH for LUSD stablecoin. There’s only a one-time borrowing fee applicable.

***Smart-contract risks***: The LUSD smart [contract](https://etherscan.io/token/0x5f98805A4E8be255a32880FDeC7F6728C6568bA0) was launched in April 2021, making it a *relatively* *young contract*. The number of transactions since launch stands at 104,550. The total [amount](https://explorer.bitquery.io/ethereum/token/0x5f98805A4E8be255a32880FDeC7F6728C6568bA0) transacted is over 17,311,656,894 LUSD, with a median of \~ 3,536 LUSD.

***Counter-party risks***: Liquity is a decentralized borrowing protocol that allows interest-free loans against Ether as a collateral. Liquity as a protocol is non-custodial, immutable, and [governance-free](https://docs.liquity.org/documentation/community-resources#podcasts). There are 2,778 token [holders](https://etherscan.io/token/tokenholderchart/0x5f98805A4E8be255a32880FDeC7F6728C6568bA0) at the time of writing.

***Market risks***: The loans are secured by a Stability Pool containing LUSD. At present, the [market](https://www.coingecko.com/en/coins/liquity-usd) capitalization for LUSD is $ 603,016,411.

***Notable incidents***: The following incidents and/or bugs were identified relating to the protocol:

* None at the time of writing.

## **renBTC**

renBTC is an ERC20 token backed 1:1 by Bitcoin. Ren also decentralizes the custody of the BTC. User’s deposit BTC to RenVM, which holds that BTC and mints renBTC with 1:1 ratio.

***Smart-contract risks***: The renBTC smart [contract](https://etherscan.io/address/0xeb4c2781e4eba804ce9a9803c67d0893436bb27d) was launched in May 2020, making it a fairly *mature contract*. The number of transactions since launch stands at 34,738. The total [amount](https://explorer.bitquery.io/ethereum/token/0xeb4c2781e4eba804ce9a9803c67d0893436bb27d) transacted is \~ 1,116,999 renBTC, with a median of \~ 0.23 renBTC.

***Counter-party risks***: Ren project is a trustless, decentralized virtual machine, which connects blockchains via the REN tokens. The Ren project aims to be the leading [decentralized](https://forum.renproject.io/t/ren-governance-process/392) universal interoperability protocol in the crypto ecosystem. There are 3,062 token [holders](https://etherscan.io/token/tokenholderchart/0xeb4c2781e4eba804ce9a9803c67d0893436bb27d) at the time of writing.

***Market risks***: At present, the [market](https://www.coingecko.com/en/coins/renbtc) capitalization for renBTC is more than $679 million and a circulation coin supply of 13,817.

***Notable incidents***: The following incidents and/or bugs were identified relating to the protocol:

* None at the time of writing.

## **sBTC**

sBTC differs from the rest, as Bitcoins does not back it. The value of sBTC is kept stable through an over-collateralization mechanism leveraging Synthetix SNX tokens.

***Smart-contract risks***: The sBTC smart [contract](https://etherscan.io/token/0xfE18be6b3Bd88A2D2A7f928d00292E7a9963CfC6) was launched in September 2019, making it a *mature contract*. The number of transactions since launch stands at 29,636. The total [amount](https://explorer.bitquery.io/ethereum/token/0xfE18be6b3Bd88A2D2A7f928d00292E7a9963CfC6) transacted is \~ 139,697 sBTCUSD, with a median of \~ 0.199 sBTC.

***Counter-party risks***: Synthetix is a decentralized platform on Ethereum for the creation of Synths: on-chain synthetic assets that track the value of real-world assets. The key decentralised autonomous organisations ([DAOs](https://docs.synthetix.io/governance/)) are the - Spartan Council, Protocol DAO, Synthetix DAO, Ambassadors DAO and the Grants DAO. There are 1,342 token [holders](https://etherscan.io/token/tokenholderchart/0xfE18be6b3Bd88A2D2A7f928d00292E7a9963CfC6) at the time of writing.

***Market risks***: Synthetix is composed of a smart contract infrastructure and a set of incentives which maintains Synth prices. At present, the [market](https://www.coingecko.com/en/coins/sbtc) capitalization for sBTC is over $176 million and a circulation coin supply of 3,576.

***Notable incidents***: The following incidents and/or bugs were identified relating to the protocol:

* None at the time of writing.

## **sETH**

Synthetix is a decentralised synthetic asset issuance protocol built on Ethereum. These synthetic assets are collateralized by the Synthetix Network Token (SNX) which when locked in the contract enables the issuance of synthetic assets (Synths).

***Smart-contract risks***: The sETH smart [contract](https://etherscan.io/token/0x5e74c9036fb86bd7ecdcb084a0673efc32ea31cb) was launched in September 2019, making it a *mature contract*. The number of transactions since launch stands at 96,733. The total [amount](https://explorer.bitquery.io/ethereum/token/0x5e74c9036fb86bd7ecdcb084a0673efc32ea31cb) transacted is \~ 8,978,550 sETH, with a median of \~ 4.4 sETH.

***Counter-party risks***: Synthetix is a decentralized platform on Ethereum for the creation of Synths: on-chain synthetic assets that track the value of real-world assets. The key decentralised autonomous organisations ([DAOs](https://docs.synthetix.io/governance/)) are the - Spartan Council, Protocol DAO, Synthetix DAO, Ambassadors DAO and the Grants DAO. There are 2,044 token [holders](https://etherscan.io/token/tokenholderchart/0x5e74c9036fb86bd7ecdcb084a0673efc32ea31cb) at the time of writing.

***Market risks***: Synthetix is composed of a smart contract infrastructure and a set of incentives which maintains Synth prices. At present, the [market](https://www.coingecko.com/en/coins/seth) capitalization for sETH is over $346 million and a circulation coin supply of 104,954.

***Notable incidents***: The following incidents and/or bugs were identified relating to the protocol:

* Synthetix Reverses [Oracle Error-Caused](https://cointelegraph.com/news/synthetix-reverses-oracle-error-caused-misplaced-seth-in-exchange-for-a-bug-bounty) Misplaced sETH.

## **sUSD**

sUSD is a synthetic USD token created by staking Synthetix Network Token (SNX) or ETH in Synthetix, a decentralized synthetic asset issuance protocol built on Ethereum.

***Smart-contract risks***: The sUSD smart [contract](https://etherscan.io/token/0x57ab1ec28d129707052df4df418d58a2d46d5f51) was launched in September 2018 and migrated to the current contract in May 2020, making it a *mature contract*. The number of transactions since launch stands at 781,978. The total [amount](https://explorer.bitquery.io/ethereum/token/0x57ab1ec28d129707052df4df418d58a2d46d5f51) transacted is \~ 33,424,667,667 sUSD, with a median of \~ 802.5 sUSD.

***Counter-party risks***: Synthetix is a decentralized platform on Ethereum for the creation of Synths: on-chain synthetic assets that track the value of real-world assets. The key decentralised autonomous organisations ([DAOs](https://docs.synthetix.io/governance/)) are the - Spartan Council, Protocol DAO, Synthetix DAO, Ambassadors DAO and the Grants DAO. There are 12,576 token [holders](https://etherscan.io/token/tokenholderchart/0x57ab1ec28d129707052df4df418d58a2d46d5f51) at the time of writing.

***Market risks***: Synthetix is composed of a smart contract infrastructure and a set of incentives which maintains Synth prices. At present, the [market](https://www.coingecko.com/en/coins/susd) capitalization for sUSD is over $288 million and a circulation coin supply of over 288 million.

***Notable incidents***: The following incidents and/or bugs were identified relating to the protocol:

* None at the time of writing.

## **tBTC**

tBTC is an open-source project of Keep, Summa and the Cross-Chain Group. tBTC, an ERC-20 token, is backed 1:1 by Bitcoin and truly decentralized.

***Smart-contract risks***: The tBTC smart [contract](https://etherscan.io/token/0x1bBE271d15Bb64dF0bc6CD28Df9Ff322F2eBD847) was launched in May 2020, making it a *mature contract*. The number of transactions since launch stands at 188. The total [amount](https://explorer.bitquery.io/ethereum/token/0x1bBE271d15Bb64dF0bc6CD28Df9Ff322F2eBD847) transacted is \~ 37 tbTC, with a median of \~ 0.0005 tBTC.

***Counter-party risks***: tBTC is a safe and permissionless bridge between BTC and ETH. The first version of tBTC has been built with no ability to upgrade contracts, following a Bitcoin-inspired philosophy of immutability and opt-in [governance](https://tbtc.network/developers/tbtc-security-model/). Any future versions of tBTC will be new systems, and require social coordination to “upgrade”, like how a hard fork might on Bitcoin. There are 32 token [holders](https://etherscan.io/token/tokenholderchart/0x1bBE271d15Bb64dF0bc6CD28Df9Ff322F2eBD847) at the time of writing.

***Market risks***: At present, the [market](https://www.coingecko.com/en/coins/alchemix-usd) capitalization for tBTC is $ 42,688,862 and a circulation coin supply of 873.

***Notable incidents***: The following incidents and/or bugs were identified relating to the protocol:

* 10-day [emergency](https://www.theblockcrypto.com/post/65941/tbtc-post-mortem-describes-how-a-missed-smart-contract-bug-forced-the-developers-to-press-the-emergency-pause-button) pause for new deposits after identifying a smart contract bug.

## **USDC**

USDC is an ERC20 token pegged 1:1 to the US dollars (USD). USDC is issued by regulated financial institutions, backed by fully reserved assets, redeemable on a 1:1 basis for US dollars, and governed by Centre, a membership-based consortium that sets technical, policy and financial standards for stablecoins.

***Smart-contract risks***: The USDC smart [contract](https://etherscan.io/token/0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48) was launched in September 2018, making it a *mature contract*. The number of transactions since launch stands at over 24 million. The total [amount](https://explorer.bitquery.io/ethereum/token/0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48) transacted is over 1,5 trillion USDC, with a median of \~ 1,050 USDC.

***Counter-party risks***: USDC is [governed](https://www.centre.io/hubfs/PDF/Centre_Blacklisting_Policy_20200512.pdf?hsLang=en) by The Centre Consortium which could block transactions and blacklist addresses. There are over 1 million token [holders](https://etherscan.io/token/tokenholderchart/0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48) at the time of writing.

***Market risks***: USDC has gained wide adoption since its inception because of its easy integration with all ERC-20 compatible wallets. At present, the [market](https://www.coingecko.com/en/coins/usd-coin) capitalization for USDC is \~ $27 billion and a circulation coin supply of \~ 27 billion.

***Notable incidents***: The following incidents and/or bugs were identified relating to the protocol:

* None at the time of writing.

## **USDT**

USDT, like USDC, is pegged 1:1 to the USD. It’s the oldest USD backed stablecoin.

***Smart-contract risks***: The USDT smart [contract](https://etherscan.io/address/0xdac17f958d2ee523a2206206994597c13d831ec7) was launched in November 2017, making it a *mature contract*. The number of transactions since launch stands at over 109 million. The total [amount](https://explorer.bitquery.io/ethereum/token/0xdac17f958d2ee523a2206206994597c13d831ec7) transacted is over 2.4 trillion USDT, with a median of \~ 726 USDT.

***Counter-party risks***: USDT is [pegged](https://wallet.tether.to/transparency) to USD and Euros on a scale of 1:1 by a Hong Kong based firm, Tether Holdings Limited. There are over 3.4 million token [holders](https://etherscan.io/token/tokenholderchart/0xdac17f958d2ee523a2206206994597c13d831ec7) at the time of writing.

***Market risks***: USDT is the most widely integrated digital-to- fiat currency today. At present, the [market](https://www.coingecko.com/en/coins/tether) capitalization for USDT is \~ $65 billion and a circulation coin supply of \~ 65 billion.

***Notable incidents***: The following incidents and/or bugs were identified relating to the protocol:

* None at the time of writing.

## **wBTC**

Wrapped BTC is an ERC20 token backed 1:1 by the actual Bitcoin. Users can swap their BTC for WBTC through merchants, like Kyber, Set Protocol, Ren, etc.

***Smart-contract risks***: The wBTC smart [contract](https://etherscan.io/address/0x2260fac5e5542a773aa44fbcfedf7c193bc2c599) was launched in November 2018, making it a *mature contract*. The number of transactions since launch stands at over 419,000. The total [amount](https://explorer.bitquery.io/ethereum/token/0x2260fac5e5542a773aa44fbcfedf7c193bc2c599) transacted is \~ 10,203,162 wBTC, with a median of \~ 0.26 wBTC.

***Counter-party risks***: Merchants perform key roles for the WBTC community as [administrators](https://wbtc.network/assets/wrapped-tokens-whitepaper.pdf) who start minting newly wrapped tokens and burning wrapped tokens which are performed by the Custodians. There are 35,930 token [holders](https://etherscan.io/token/tokenholderchart/0x2260fac5e5542a773aa44fbcfedf7c193bc2c599) at the time of writing.

***Market risks***: Minting in the wrapped framework is started by a merchant and performed by a custodian. At present, the [market](https://www.coingecko.com/en/coins/wrapped-bitcoin) capitalization for wBTC is over $9 billion and a circulation coin supply of over 194,000.

***Notable incidents***: The following incidents and/or bugs were identified relating to the protocol:

* Price [manipulation](https://www.trustnodes.com/2020/02/17/flashloan-haxor-sent-wbtcs-price-to-4000-on-kyber) through flashloans.

## **wCUSD**

Wrapped Celo Dollars is an ERC20 token, representing a 1:1 share of Celo Dollar (CUSD). wCUSD provides a simple and secure bridge to Ethereum’s DeFi ecosystem.

***Smart-contract risks***: The wCUSD smart [contract](https://etherscan.io/token/0xad3e3fc59dff318beceaab7d00eb4f68b1ecf195) was launched in December 2020, making it a relatively *young contract*. The number of transactions since launch stands at 52. The total [amount](https://explorer.bitquery.io/ethereum/token/0xad3e3fc59dff318beceaab7d00eb4f68b1ecf195) transacted is \~ 2,247,874 wCUSD, with a median of \~ 988 wCUSD.

***Counter-party risks***: Wrapping CUSD to wCUSD is permissionless and so is the reverse process to unwrap. There are 7 token [holders](https://etherscan.io/token/tokenholderchart/0xad3e3fc59dff318beceaab7d00eb4f68b1ecf195) at the time of writing.

***Market risks***: Minting in the wrapped framework is started by a merchant and performed by a custodian. At present, the fully diluted [market](https://coinmarketcap.com/currencies/wrapped-celo/) capitalization for wCUSD is over $3 million and a total coin [supply](https://www.coingecko.com/en/coins/wrapped-celo-dollar) of close to 700,000.

***Notable incidents***: The following incidents and/or bugs were identified relating to the protocol:

· None at the time of writing.

## **WETH**

ETH was the proto-token of the Ethereum Alt tokens, which means it was built before the ERC-20 standard existed. Wrapped ETH is an ERC20 token backed 1:1 by ETH, allowing trade directly with ALT coins.

***Smart-contract risks***: The wETH smart [contract](https://etherscan.io/address/0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2) was launched in December 2017, making it a *mature contract*. The number of transactions since launch stands at over 2.3 million. The total [amount](https://explorer.bitquery.io/ethereum/token/0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2) transacted is \~ 2,322,213,729 wETH, with a median of \~ 0.87 wETH.

***Counter-party risks***: Wrapping ETH to wETH is permissionless and so is the reverse process to unwrap. There are 225,770 token [holders](https://etherscan.io/token/tokenholderchart/0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2) at the time of writing.

***Market risks***: Users can verify that WBTC is fully-backed via on-chain proof of reserves. At present, the [market](https://coinmarketcap.com/currencies/weth/) capitalization for wETH is over 3.7 billion (fully diluted) and a total coin supply of over 1.1 million.

***Notable incidents***: The following incidents and/or bugs were identified relating to the protocol:

* None at the time of writing.


# Saddle FAQ

Frequently asked questions on Saddle Finance, Liquidity Pools, Pegged Assets, Rewards and Incentives.

## **GENERAL**

Frequently asked questions and answers regarding Saddle Finance. Still have questions? [Join our Discord](https://discord.gg/qEtPn5pBvk).

### **What is Saddle?**

Saddle is a decentralized automated market maker ([AMM](https://docs.saddle.finance/automated-market-makers)) on the Ethereum blockchain, optimized for trading [pegged value crypto assets](https://docs.saddle.finance/saddle-faq#what-are-pegged-value-crypto-assets-pegged-assets) with [minimal slippage](https://docs.saddle.finance/saddle-faq#what-is-a-slippage). Saddle enables cheap, efficient, swift, and low-slippage swaps for traders and high-yield pools for LPs. We believe in [collaboration](https://docs.saddle.finance/build-with-saddle), in building Saddle as a DeFi lego block, in helping DeFi teams bring AMMs to any blockchain.

### **Why Saddle?**

***Saddle stands for DeFi***: We commit ourselves to [open-source software](https://github.com/saddle-finance) and collaboration to fulfil the promise of DeFi, of financial Lego blocks.

***Saddle is safe & legit***: Saddle protocol is audited and secured by leading blockchain security firms like Certik, Quantstamp, and OpenZeppelin. Read the audits [here](https://github.com/saddle-finance/saddle-audits).

***Saddle is collaborative and fun to work with***: We root our ethos in the desire to [support ](https://docs.saddle.finance/build-with-saddle)the DeFi ecosystem and partner with like-minded protocols.

### **Who built Saddle?**

Saddle is built by DeFi natives with prior years of developer experience at Web2 companies like Uber, Amazon, and Square. As regular DeFi users ourselves, we’ve seen first-hand how important an active and vibrant community is for a project’s success. We know Web2, but we know Web3 better.

You might have interacted with our founder [Sunil](https://www.linkedin.com/in/sunilsrivatsa/) (aka [devops199fan](https://twitter.com/devops199fan)) in the YFI community (he’s a multisig signer), or used tools created by members of our team, like [yieldfarming.info](https://yieldfarming.info) by [John](https://www.linkedin.com/in/jongseunglim/) (aka [Weeb\_Mcgee](https://twitter.com/Weeb_Mcgee)).

### **Where can I find Saddle's logo or brand assets?**

You can download Saddle's logo, guidelines, and brand assets from [here](https://drive.google.com/drive/folders/13rTY6x24crioqOgyGCE6zJo0197AMVtD?usp=share_link).

### **How does Saddle work?**

Saddle is an automated market maker (AMM) enabling trading between pegged value crypto assets. Saddle liquidity pools implement the StableSwap mathematical formula to reduce slippage and keep the market liquid. First introduced by [Curve](https://curve.fi/whitepaper), Stableswap is a hybrid algorithm. The Stableswap hybrid combines both Constant Product and Constant Sum models.

For more on AMMs and Stableswap check out the [AMM section](https://docs.saddle.finance/automated-market-makers).

{% hint style="info" %}
Find Saddle's StableSwap implementation code [here](https://github.com/saddle-finance/saddle-contract/blob/master/contracts/Swap.sol)
{% endhint %}

### **Does Saddle have a token?**

Yes, Saddle's token is the SDL token, you can learn more about it in the [SDL Token section](/sdl-token).

{% hint style="info" %}
Find SDL token code [here](https://github.com/saddle-finance/saddle-contract/blob/master/contracts/SDL.sol)
{% endhint %}

### Where can I trade SDL?

SDL is non-transferrable for 3-12 months following launch (depending on governance). During the lockup period, SDL is not tradable.

{% hint style="info" %}
Find SDL token vesting code [here](https://github.com/saddle-finance/saddle-contract/blob/master/contracts/Vesting.sol) and [here](https://github.com/saddle-finance/saddle-contract/blob/master/contracts/RetroactiveVesting.sol)
{% endhint %}

### **What is the price of SDL?**

SDL is non-transferrable for 3-12 months following launch (depending on governance). During the lockup period, SDL is not tradable, so it does not have a price.

### **Who can use Saddle?**

Anyone and everyone. All you need to use Saddle is an internet connection and a ERC-20 compatible wallet like [Metamask](https://metamask.io).

### **How do I use Saddle?**

With Saddle, there are two general actions users can take: [swap assets](https://saddle.exchange/#/) or [provide liquidity](https://saddle.exchange/#/pools).

* ***Swapping*** between two assets on Saddle gives users efficient trading and low slippage.

{% embed url="<https://www.youtube.com/embed/8XE5ErpfhQo?feature=oembed>" %}

* ***Providing liquidity*** by depositing assets into a pool on Saddle allows users to take part in the protocol as liquidity providers and earn reward incentives.

{% embed url="<https://www.youtube.com/embed/RCsBinGAZEg?feature=oembed>" %}

Head to the [Saddle d](https://saddle.exchange)[App](https://saddle.exchange) and start using it now!

### **Are there alternate front ends for Saddle protocol?**

There are several frontends available:

| **FRONT END** | **LINK**                                                                |
| ------------- | ----------------------------------------------------------------------- |
| Main dApp     | [https://saddle.exchange/](https://saddle.exchange)                     |
| ENS           | [https://saddlefinance.eth.link/](https://saddlefinance.eth.link)       |
| Fleek Mirror  | [https://saddlefinance.on.fleek.co/](https://saddlefinance.on.fleek.co) |
| IPNS          | <https://ipfs.io/ipns/saddle.exchange>                                  |

You can also use any of the following aggregators:

| **AGGREGATOR** | **LINK**                                      |
| -------------- | --------------------------------------------- |
| 1inch          | [https://app.1inch.io/](https://app.1inch.io) |
| Matcha         | [https://matcha.xyz/](https://matcha.xyz)     |
| Paraswap       | [https://paraswap.io/](https://paraswap.io)   |

You can also run the frontend locally using the GitHub repo:

| **LOCAL**             | **LINK**                                            |
| --------------------- | --------------------------------------------------- |
| GitHub Front End Repo | <https://github.com/saddle-finance/saddle-frontend> |

### **What are the fees for using Saddle?**

Trading on a Saddle pool carries two fees – a trading fee and a gas fee.

***Trading fee**:* The trading fee applies to every trade and the prevailing fee is displayed in the pool information. Typically, the fee is 0.04%. However, the fee may vary depending on the pool.

***Admin fee**:* The admin fee is included as a % of the trading fee. Currently it is zero.

***Gas fee**:* The fee payable to Ethereum network to confirm the transactions. The gas fee varies depending on the speed of confirmation time required and represented in gwei (1 gwei = 10-9 ETH).

![Example of Saddle Fees](/files/l5GdJ8aa5pBbIbJ9Ztrc)

**Note:** There is no fee to withdraw your liquidity from Saddle pools. Initial versions of our contracts contained a withdrawal fee feature, but we have removed this from all future pools.

{% hint style="info" %}
Find Saddle's fee calculation code [here](https://github.com/saddle-finance/saddle-contract/blob/38328fba920abd10bfe3ac9fde98e7c9cc50af9a/contracts/Swap.sol#L81)
{% endhint %}

### **Is Saddle safe?**

Saddle has been [audited](https://docs.saddle.finance/smart-contract-audit) by Certik, Quantstamp, and OpenZeppelin. We have passed security auditing on all Saddle smart contracts, from the following auditors.

| **AUDITOR**                             | **PROTOCOL AUDIT**                                                                              | **VIRTUAL SWAP AUDIT**                                                                                      |
| --------------------------------------- | ----------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| [Certik](https://certik.io)             | [PASSED](https://github.com/saddle-finance/saddle-audits/blob/master/10-29-2020_Certik.pdf)     | N/A                                                                                                         |
| [Quantstamp](https://quantstamp.com)    | [PASSED](https://github.com/saddle-finance/saddle-audits/blob/master/12-09-2020_Quantstamp.pdf) | [PASSED](https://github.com/saddle-finance/saddle-audits/blob/master/03-31-2021_Quantstamp_VirtualSwap.pdf) |
| [OpenZepplin](https://openzeppelin.com) | [PASSED](https://blog.openzeppelin.com/saddle-contracts-audit/)                                 | N/A                                                                                                         |

***Disclaimer**:* Investing in cryptocurrencies is risky. Using Saddle as an exchange should be significantly less risky, but keep in mind there are still risks. Refer to the [risks section](https://docs.saddle.finance/asset-specific-risks) for more details.

### **Who controls Saddle's admin keys?**

A [Gnosis Safe](https://gnosis-safe.io) multisig secures Saddle’s admin keys. Gnosis is a trusted platform to manage digital assets in Ethereum. A [3/7 Gnosis Safe multisig](https://etherscan.io/address/0x3F8E527aF4e0c6e763e8f368AC679c44C45626aE) secures Saddle's admin keys. The signers are:

| **NAME**                                             | **ENS**           | **ADDRESS**                                |
| ---------------------------------------------------- | ----------------- | ------------------------------------------ |
| [Mariano Conti](https://twitter.com/nanexcool)       | -                 | 0x6F2A8Ee9452ba7d336b3fba03caC27f7818AeAD6 |
| [Weston Nelson](https://twitter.com/westonnelson)    | -                 | 0xD131F1BcDd547e067Af447dD3C36C99d6be9FdEB |
| [DegenSpartan](https://twitter.com/DegenSpartan)     | degenspartan.eth  | 0x4E60bE84870FE6AE350B563A121042396Abe1eaF |
| [Klim K](https://twitter.com/milkyklim)              | yfi.milkyklim.eth | 0x0cec743b8ce4ef8802cac0e5df18a180ed8402a7 |
| [Damir Bandalo](https://twitter.com/damirbandalo)    | -                 | 0xa83838221278f22ee5bAe3E523f34D42b066D67D |
| [Aurelius](https://twitter.com/AureliusBTC)          | aurelius0x.eth    | 0x0AF91FA049A7e1894F480bFE5bBa20142C6c29a9 |
| [Scoopy Trooples](https://twitter.com/scupytrooples) | -                 | 0xf872703F1C8f93fA186869Bac83BAC5A0c87C3c8 |
| [Sam Kazemain](https://twitter.com/samkazemian)      | -                 | 0x17e06ce6914E3969f7BD37D8b2a563890cA1c96e |

This 3/7 multisig has capabilities to pause new deposits and trades in case of technical emergencies. Users will always be able to withdraw their funds regardless of new deposits being paused. The multisig can also change the swap/withdrawal fees and the per pool/account deposit limits.

### **What smart contracts does the community multisig control?**

The community multisig currently owns all pool/metapool, team/investor vesting, and MiniChef rewards contracts.

For a full list of contract addresses, please reference the [Contract Addresses docs](https://docs.saddle.finance/contracts).

### **Does the Saddle protocol use any oracles?**

No, the Saddle protocol does not use any oracles as all computation is a function of the current pool balance/composition.

### **Is the Saddle protocol susceptible to front running?**

The Saddle protocol does not contain any front running mitigations as they are not possible to include in the protocol itself.

We encourage users to use the [Flashbots Protect RPC](https://docs.flashbots.net/flashbots-protect/rpc/quick-start/) to protect themselves from front running.

### **What institutional investments did Saddle get?**

Refer to the [Our Investors](https://docs.saddle.finance/build-with-saddle#our-investors) section in Build with Saddle. The section contains a list of the institutional investors supporting Saddle.

### **Did you copy Curve?**

Our original vision was to use Synthetix as a bridge across asset pools to facilitate large, low-slippage trades (alla virtual swap). In the ideal scenario, we would have just built on top of Curve’s [StableSwap](https://curve.fi/whitepaper), but they had a restrictive license, so we had to reimplement it.

From the beginning, we’ve been open about using the StableSwap algorithm. StableSwap is a [Hybrid Function Market Maker](https://papers.ssrn.com/sol3/papers.cfm?abstract_id=3722714) based on the Constant Product Market Maker (implemented by Uniswap) and Constant Sum Market Maker. While the StableSwap algorithm was indeed developed by a member of the Curve team, it is nonetheless published in the public domain.

The comparison of Curve and Saddle is rooted in the algorithm used. Saddle’s technical implementation (and perhaps equally important, our ethos) is different.

### **Why support Saddle over Curve?**

**Principally**, Saddle is built on the values of open-source and collaboration, while Curve operates on a restrictive license. We welcome anyone who wants to build on top of Saddle or bring stablecoin / pegged asset DEX/AMM to another chain. Check out [Build with Saddle](https://docs.saddle.finance/build-with-saddle) on ways to collaborate.

**Technically**, Saddle is implemented in Solidity, while Curve is implemented using Vyper. Here’s a [research paper](https://www.researchgate.net/publication/334626679_Data_Protection_with_Ethereum_Blockchain) comparing the two languages.

{% hint style="info" %}
Find the forked projects of Saddle [here](https://github.com/saddle-finance/saddle-contract/network/members)
{% endhint %}

### **How do I work with Saddle?**

Check out [Build with Saddle](https://docs.saddle.finance/build-with-saddle) on ways to collaborate.

### **What is Saddle’s "Proof of Governance"?**

Saddle launched with Proof of Governance (PoG) to protect our users with certain limits and discourage sybil attacks. Initially, there will be a pool TVL cap of 150 BTC and a per-address deposit limit of 1 BTC. These limits were raised every 1-2 weeks.

**Note:** The guarded launch has been successful and as of 22nd February 2021, we have disabled the guard ([Etherscan transaction](https://etherscan.io/tx/0xedc38ea0b5f1cc740c6659cdecdc5b379bcd77b1eae59709d41e9811b92a4d66)). Anyone can become a liquidity provider in Saddle's pools.

For LPs to qualify for PoG, an address must have demonstrated active network participation in one of the following ways:

* On-chain voting or delegation (MKR, COMP, YFI, YAM, CRV, UNI, UMA, Moloch DAO)
* Off-chain voting on Snapshot (all protocols)
* Staking SNX and minting sUSD (>$20)

The cutoff date for all activity was 1st October 2020, except for UNI, which was 1st January 2021.

A full list of eligible addresses is available [here](https://github.com/saddle-finance/saddle-allowlist-addresses). PoG was temporary and has been phased out.

We implemented this guarded launch to establish a more controlled environment that will allow us to ensure a stable launch and remain responsible with users’ funds. Our aim above all else is to ensure the application performs to its expectations, users’ funds remain safe, and our community of supporters, developers, and users remain confident in our ability to launch successfully and fairly.

### **How can I keep up-to-date about Saddle?**

| **FOLLOW FOR LATEST SADDLE UPDATES** |                                                             |
| ------------------------------------ | ----------------------------------------------------------- |
| Saddle Blog                          | [https://blog.saddle.finance/](https://blog.saddle.finance) |
| Discord                              | <https://discord.gg/qEtPn5pBvk>                             |
| Twitter                              | <https://twitter.com/saddlefinance>                         |
| GitHub                               | <https://github.com/saddle-finance>                         |
| Telegram                             | <https://t.me/saddle_finance>                               |

### **How do I report a bug?**

Our goal is to provide you with the safest Saddle protocol. We encourage the community to help us find bugs or vulnerabilities in the protocol. The bounty reward is up to **US$ 50,000**. Report your findings via any one of these channels.

| REPORT HERE                    | LINK                                  |
| ------------------------------ | ------------------------------------- |
| Discord (**#support** channel) | <https://discord.gg/qEtPn5pBvk>       |
| Telegram                       | <https://t.me/saddle_finance>         |
| Email                          | <security@saddle.finance>             |
| Immunify Bug Bounty            | <https://immunefi.com/bounty/saddle/> |

The [Terms and Conditions](https://immunefi.com/bounty/saddle/) cover your participation in the Bug Bounty Program. By submitting any vulnerabilities to Saddle Finance or otherwise participating in the Program in any manner, you accept these Terms.

## **SADDLE TOKEN (SDL)**

Frequently asked questions and answers regarding Saddle governance token. Still have questions? [Join our Discord](https://discord.gg/qEtPn5pBvk).

### **What is** SDL token used for?

SDL is the governance token for Saddle Finance. It is also used to reward and incentivize the Saddle community. Read all about the governance process [here](https://docs.saddle.finance/sdl-token#_toc87947035).

### How many SDL tokens are available?

The max supply of 1 billion SDL has been minted at genesis and will become available over the course of 2-3 years. Check out the [tokenomics section](https://docs.saddle.finance/sdl-token#_toc87947029) for the allocation and vesting details.

{% hint style="info" %}
Find SDL token code [here](https://github.com/saddle-finance/saddle-contract/blob/master/contracts/SDL.sol)
{% endhint %}

### How do I get SDL tokens?

The token is initially non-transferable for a period of between 3 to 12 months. During this lockup period, the only way to earn SDL is by LPing in Saddle’s incentivized pools or by participating in the bounties4bandits (b4b) program. Learn more [here](https://docs.saddle.finance/sdl-token#_toc87947031).

Once the lockup period ends, you'll be able to buy SDL on an exchange.

### Are there time locks on the SDL tokens?

There are two time locks on the SDL Token:

1. A non-transfer period of 3 to 12 months
2. A vesting period of 2 to 3 years

The reason for time lock is to allow community members to earn more and deter short-term profit-seekers and mercenaries. More details [here](https://docs.saddle.finance/sdl-token).

### Are there time locks on any Saddle smart contracts?

No, all contracts that have admin functionalities are owned by the community multisig and do not have any time locks so the multisig can act quickly in case of an emergency.

### When does SDL token begin to vest?

If you received SDL tokens in the airdrop, they have already began to vest. The vesting period is 2-3 years, further details are available [here](https://docs.saddle.finance/sdl-token#_toc87947030).

{% hint style="info" %}
Find SDL token vesting code [here](https://github.com/saddle-finance/saddle-contract/blob/master/contracts/Vesting.sol) and [here](https://github.com/saddle-finance/saddle-contract/blob/master/contracts/RetroactiveVesting.sol)
{% endhint %}

### Is there a deadline to claim SDL tokens after the vesting period?

After the vesting period ends, users have 1 year to claim the SDL tokens. After 1 year, all unclaimed goes to the protocol treasury.

### When can I trade SDL tokens?

SDL tokens are initially non-transferable / non-tradable. Wallets that received the airdrop can vote with their tokens, but they cannot transfer between wallets or different users. If governance does not vote to make SDL transferable early (vote can happen as early as 3 months from now), then 12 months after token launch, SDL will automatically unlock. That means before the end of 2022, the SDL token will be unlocked and operate as typical (transferable) ERC-20.

### How do I claim my SDL?

Go to [saddle.exchange](https://saddle.exchange) (set your network to Ethereum mainnet) and click the SDL icon (top right) to open the claim UI to view and claim there.

![Open the SDL claim UI by clicking the SDL icon on the top right](/files/5WDFPV2nkAi6YytDjkGk)

### Why can't I claim my SDL on Arbitrum?

As of time of writing, **SDL is only claimable on mainnet.** The claim UI on Arbitrum is just meant to be a preview of your SDL rewards. They will be claimable once SDL is supported on the network (estimated Q1, 2022).

## **PEGGED VALUE ASSETS**

Frequently asked questions and answers regarding Saddle pegged value assets and tokens. Still have questions? [Join our Discord](https://discord.gg/qEtPn5pBvk).

### **What are Pegged Value Crypto Assets (Pegged Assets) ?**

Pegged value crypto assets (pegged assets) are tokens having their value pegged to an underlying asset. For example, the value of a stablecoin or tokenized bitcoin is supposed to be $1 or 1 BTC, respectively.

Pegged assets fix this value using different mechanisms:

* Some assets, like Synthetix sBTC or sUSD, maintain their peg synthetically (in this case, via collateralization of Synthetix’s SNX tokens)
* Other assets maintain their peg by being backed by and redeemable for the actual underlying asset, either permissionlessly (e.g., tBTC) or through a centralized custodian (e.g., WBTC, USDC).

Because of the different approaches and the associated risks, the prices of pegged assets of the same type may vary slightly.

### **What are Stablecoins?**

Stablecoins are cryptocurrencies whose value is pegged to another asset class to stabilize its price. The pegged asset can be a fiat currency like US$, or a real-world commodity like gold. Based on the pegging mechanism, stablecoins can be divided into several groups:

* Fiat-collateralized stablecoins – E.g., USDC, USDT, BUSD
* Commodity-collateralized stablecoins – E.g., DGX (backed by Gold), SRC (Real Estate)
* Crypto-collateralized stablecoins – E.g., DAI
* Algorithmic stablecoins – E.g., FRAX, AMPL

### **What is Tokenized Bitcoin?**

Tokenized bitcoin is BTC “sent” from the Bitcoin blockchain to the Ethereum blockchain. BTC is held in a deposit contract which “mints” a token on Ethereum. The minted Bitcoin token on Ethereum has the same value as the regular BTC and can be used to the full capability of an ERC-20 token.

Some examples of tokenized bitcoin include tBTC, renBTC, wBTC, and sBTC.

### **What are Wrapped Tokens?**

Blockchain networks differ in functionality and inter-operability of tokens is a challenge. [Wrapped](https://wrapped.com) tokens serve as a bridge between different blockchains.

***Wrapping*** (minting) is done by sending an asset to the custodian's deposit address and by submitting a wrapping request.

***Unwrapping*** (burning) an asset is done by submitting a request to the custodian. Once unwrapped, the custodian will send the equivalent underlying asset (minus applicable fees) to the user's account.

Some examples of wrapped tokens include wBTC, wETH, and wCUSD.

### **What are Synthetic Tokens (Synths)?**

Synthetix is a protocol for issuing and trading synthetic assets on the Ethereum blockchain. [Synths](https://www.synthetix.io/synths) are *ERC-20 tokens*, providing exposure to a range of assets. Each synth tracks the price of an external asset (fiat currency, cryptocurrency, commodities, etc). For example:

* sBTC synth tracks the price of Bitcoin (BTC) through price feeds supplied by an oracle.
* sUSD synth tracks the price of a single US Dollar (USD). This synth is always valued at $1 in the debt repayment mechanism of Synthetix.
* sCHF tracks the price of the Swiss Franc (CHF) through price feeds supplied by an oracle.

Synths provide exposure to an asset (at a clear price) without holding the asset. With synths, traders can get exposure to assets which don’t exist on-chain.

### **What are Virtual Synths?**

Virtual synths are an additional feature introduced by Synthetix. vSynths [allow](https://sips.synthetix.io/sips/sip-89/) the proceeds of unsettled exchanges to be transferable by tokenizing them. This helps Synthetix overcome the composability challenge. Learn more about [vSynths](https://blog.saddle.finance/low-slippage-trades-across-saddle-btc-eth-and-usd-pools-via-virtual-swap/).

### **What tokens are currently supported by Saddle?**

Currently, these are the pegged assets we support. Our support for pegged value crypto assets keeps growing. Please visit [https://saddle.exchange/](https://saddle.exchange) to check the tokens supported.

| **Pegged Asset** | **Website**                                         |
| ---------------- | --------------------------------------------------- |
| alETH, alUSD     | [https://www.alchemix.fi/](https://www.alchemix.fi) |
| DAI              | [https://makerdao.com/](https://makerdao.com)       |
| FEI              | [https://fei.money/](https://fei.money)             |
| FRAX             | [https://frax.finance/](https://frax.finance)       |
| LUSD             | [https://www.liquity.org/](https://www.liquity.org) |
| renBTC           | [https://renproject.io/](https://renproject.io)     |
| sBTC, sETH, sUSD | [https://synthetix.io/](https://synthetix.io)       |
| tBTC             | [https://tbtc.network/](https://tbtc.network)       |
| USDC             | <https://www.centre.io/usdc>                        |
| USDT             | [https://tether.to/](https://tether.to)             |
| wBTC             | [https://wbtc.network/](https://wbtc.network)       |
| wCUSD            | [https://celo.org/](https://celo.org)               |
| WETH             | [https://weth.io/](https://weth.io)                 |

### **Will Saddle support other assets? When?**

Absolutely yes. Our mission is to unlock deep on-chain liquidity between pegged value crypto assets. We keep adding [partners ](https://docs.saddle.finance/build-with-saddle)and assets to realise our mission.

**Follow us**, if you haven’t already, for the latest updates on new assets and pools.

| [**BLOG**](https://blog.saddle.finance) | [**DISCORD**](https://discord.gg/qEtPn5pBvk) | [**TWITTER**](https://twitter.com/saddlefinance) | [**GITHUB**](https://github.com/saddle-finance) | [**TELEGRAM**](https://t.me/saddle_finance) |
| --------------------------------------- | -------------------------------------------- | ------------------------------------------------ | ----------------------------------------------- | ------------------------------------------- |

**Collaborate with us** if you are working on an exciting DeFi project. Check out the [Build with Saddle](https://docs.saddle.finance/build-with-saddle) section for details.

### **What are the risks with Pegged Value Crypto Assets?**

Investing in cryptocurrencies is risky. The cryptocurrency assets in the various Saddle protocols are an integral part of the Saddle ecosystem. Any risks to the assets have a cascading effect on Saddle. Before we accept a cryptocurrency for the liquidity pools, we evaluate the [underlying risks](https://docs.saddle.finance/asset-specific-risks) for the assets and operations of the asset. If one or more risks are significant, we don’t accept the cryptocurrency for the Saddle pools. The three main risk evaluation parameters are:

* Smart-contract risks
* Counter-party risks
* Market risks

Check out the [asset specific risk](https://docs.saddle.finance/asset-specific-risks) section to know more.

## **LIQUIDITY POOLS & SWAPS**

Frequently asked questions and answers regarding Saddle Liquidity Pools and Saddle Swaps. Still have questions? [Join our Discord](https://discord.gg/qEtPn5pBvk).

### **What is a Decentralized Exchange (DEX)?**

Saddle is a decentralized exchange. A cryptocurrency exchange is a marketplace for trading cryptocurrencies. Broadly, two types of cryptocurrency exchanges exist:

* ***Centralized Exchanges (CEX)***: A cryptocurrency exchange owned and governed by a 3rd party. E.g., Binance, Coinbase, and Bitfinex.
* ***Decentralized Exchanges (DEX)***: A cryptocurrency exchange, unlike CEX, is not owned or governed by a 3rd party. A DEX acts as a peer-to-peer (P2P) platform, facilitating trade with no central party. E.g., Saddle, Uniswap, Sushiswap, and Mdex.

### **What is an Automated Market Maker?**

Market makers are essential in an exchange to provide liquidity, control spreads, and maintain slippages. Since cryptocurrency exchanges work 24x7, the need for automated market makers rose. [AMMs ](https://docs.saddle.finance/automated-market-makers)democratized cryptocurrency trading by doing away with order books and institutional market makers. Instead, AMMs execute trade automatically using algorithms and liquidity pools.

### **What is the Constant Product Formula?**

[Constant product formula](https://docs.saddle.finance/automated-market-makers#constant-product-formula) is probably the simplest and the earliest AMM algorithm to come into the market. Uniswap popularized the mathematical formula:

```
                                          x * y = k
```

where **x** is the amount of Token#1 in the liquidity pool, **y** is the amount of Token#2 in the liquidity pool, and **k** is a fixed constant.

Given the volatile nature of cryptocurrency, the market price of the tokens also fluctuates. The constant product formula *does not update* the price of the tokens in the pool with the market movement. This resulted in the risk of higher slippages.

### **What is the Constant Sum Formula?**

To address the slippage issue, AMMs explored the constant sum formula as an option. [Constant sum formula](https://docs.saddle.finance/automated-market-makers#constant-sum-formula) solves for the equation:

```
                                      x + y = k
```

where **x** is the amount of Token#1 in the liquidity pool, **y** is the amount of Token#2 in the liquidity pool, and **k** is a fixed constant.

While the constant sum formula solves the slippage problem, it provides only *fixed liquidity*. For markets to function well, they need a constant supply of liquidity and hence this model didn’t suit the purpose well.

### **What is the StableSwap Formula?**

First introduced by [Curve](https://curve.fi/whitepaper), the Stableswap is a hybrid algorithm. The [Stableswap ](https://docs.saddle.finance/automated-market-makers#stableswap-algorithm)hybrid combines both Constant Product and Constant Sum models:

* **Constant Sum:** When the liquidity pool portfolio is balanced, the algorithm functions as a Constant Sum formula; **x + y = k**.
* **Constant Product:** As the liquidity pool portfolio becomes imbalanced, the StableSwap algorithm functions as a Constant Product formula; **x \* y = k**.

{% hint style="info" %}
Find Saddle's StableSwap implementation code [here](https://github.com/saddle-finance/saddle-contract/blob/master/contracts/Swap.sol)
{% endhint %}

### **What are Dynamic Pegs?**

The Constant Product formula *does not update* the price of the tokens in the pool with the market movement. The Stableswap formula motivates swaps around price ratio 1.0, well suited for stablecoins. Dynamic pegs are the next evolution of AMMs.

Dynamic pegs will bring the benefits of Stableswaps to cryptocurrency assets, which aren’t pegged to another asset. By using an automatic price change mechanism, the algorithm will move the price based on real-time profit margin calculations to adjust for slippages. Thus, benefiting both the traders and the AMMs.

### **What is a Saddle Pool?**

Instead of an order book, AMMs use [liquidity pools](https://docs.saddle.finance/saddle-pools) to facilitate trade. Liquidity pool, a smart contract, is a fund of tokens (or coins).

In AMMs, traders interact with the smart contracts, to enable liquidity and price discovery. Because of the permissionless nature, AMMs allow anyone to provide liquidity to the liquidity pool. The liquidity pool smart contract holds two or more tokens and allows anyone to deposit and withdraw funds from them, but only according to specific mathematical rules.

### **Who is a Liquidity Provider?**

Liquidity providers (LPs) contribute assets (cryptocurrency tokens and coins) to liquidity pools.

In exchange for providing the tokens, the LPs normally earn a [fee](https://docs.saddle.finance/saddle-incentives). Now, when a trade executes on an AMM, the trade executes against the liquidity pool. This eliminates the need for an order book and for the buyer and seller to be present at that moment in time.

### **What is a Base Pool and Metapool?**

Saddle pools are of two types – base and metapools.

* ***Base pools*** contain two or more tokens and implement the StableSwap algorithm.
* ***Metapools*** contain one token to trade with another underlying Base pool. Metapools provide the flexibility for liquidity providers to get exposure to the metapool asset for additional rewards. For example, in the sUSD Pool, we pool the single token sUSD alongside Stablecoin Pool V2 (DAI, USDC, USDT). Adding the single asset to the metapool, however, does not dilute the liquidity of the underlying base pool.

### **How to provide Liquidity to a Metapool?**

You can provide liquidity to a metapool in two ways - as individual assets or as LP tokens from the base pool .

* **Step 1:** Go to <https://saddle.exchange/#/pools>
* **Step 2:** Choose the metapool from the list of pools available

![](/files/-MkBvxUtIpfETwxSa0Co)

* **Step 3:** Click on *Deposit*

**Option 1 :** Deposit individual assets

![](/files/LJSnuoyoLTCHPqQAxkzI)

**Option 2** : Deposit LP tokens from the base pool

![](/files/-MkBv36MbMA88IpcEexm)

### **What is Front-Running?**

While synths are great, they came with a limitation. Many decentralized exchanges (DEX) suffer from [front-running](https://blog.saddle.finance/low-slippage-trades-across-saddle-btc-eth-and-usd-pools-via-virtual-swap/). Because of constraints on Ethereum, there is a latency and cost in sourcing and updating the real-world asset price for the synths. Front-runners can see the difference between price of the asset in the real-world and on-chain. They see an arbitrage opportunity and over-pay for Ethereum gas fee to prioritize their orders in the queue, before the on-chain price reflects the real-world.

### **What is Composability?**

In DeFi, composability is the ability of open-source protocols to interact and combine creatively to form new products and services. There are two key aspects for composability to work:

* ***Standardization***: The ability of DeFi protocols to connect and communicate in a standardized and open way.
* ***Atomicity***: The need for the DeFi protocols to connect instantly within a single transaction.

To overcome the front-running challenge, a [time delay](https://blog.synthetix.io/how-fee-reclamation-rebates-work/) was introduced before a trader gets the underlying asset. While the solution was successful in addressing the front-running issue, introducing rebate and reclamation presented significant friction because of a second transaction required to settle the exchange. The need for two transactions breaks down the property of composability (atomicity in particular).

### **What are Virtual Synths (vSynths)?**

Virtual synths ([vSynth](https://blog.saddle.finance/low-slippage-trades-across-saddle-btc-eth-and-usd-pools-via-virtual-swap/)) were introduced to address the composability issue. Virtual synths are an additional feature introduced by Synthetix. vSynths [allow](https://sips.synthetix.io/sips/sip-89/) the proceeds of unsettled exchanges to be transferable by tokenizing them. This helps Synthetix overcome the composability challenge.

### **What is Virtual Swap?**

Virtual swaps are a new feature in Saddle pools leveraging Synthetix’s vSynths. This version 2 is an upgrade over the siloed version 1 synth pools. With implementing vSynth logic in Saddle’s AMM, it’s possible to use synths as *bridges between pools*.

**Saddle Synths: Version 1**

![](/files/-MkC-XwRZsoS2AAB2P0O)

**Saddle Synths: Version 2**

![](/files/sICclNqpRJcuHODuu2go)

### **Where can I find Saddle’s Contract Addresses?**

The Saddle’s Contract Addresses are listed [here](https://docs.saddle.finance/contracts).

## **WORKING WITH SADDLE POOLS**

Frequently asked questions and answers regarding working with Saddle pools, fees, and technical details. Still have questions? [Join our Discord](https://discord.gg/qEtPn5pBvk).

### **Can I** withdraw from a paused Saddle pool?

You can withdraw your assets from the paused pool. When withdrawing, you need to withdraw proportionally all assets of the pool (combo).

Withdrawing a single asset is fundamentally a swap and therefore not allowed in the paused pools.

### **Why is the pool paused?**

A pool can be paused for a variety of reasons, including, but not limited to:

* One (or more) of the assets in a pool is [depegged](https://docs.saddle.finance/saddle-pools#market-risks)
* One (or more) of the assets has a [vulnerability ](https://docs.saddle.finance/saddle-pools#technical-risks)that's open for exploitation
* Smart contract [vulnerability](https://blog.saddle.finance/metapool-exploit-fix-is-live/)
* Suspicious activity going on (e.g., malicious bots)

**Note**: The pause function of a pool can be triggered only by the [multisig](https://docs.saddle.finance/smart-contract-audit#saddle-admin-keys-security).

### **What is Slippage?**

Slippage is the difference between the expected price of a trade and the execution price. This happens as there is a time delay between the trade request and execution in the market. Slippage can occur at any time but is amplified during periods of high volatility and with large volume trades.

In case of large trades, we recommend the use of aggregators like [1inch](https://1inch.io), [Matcha](https://matcha.xyz), or [Paraswap](https://paraswap.io) to limit the slippage.

### **What is Max Slippage?**

With max slippage setting, you can specify the maximum % of price movement you can accept for the trade. Your order will not execute if the slippage is beyond your maximum specified. The default for Saddle is 0.1%, but you can set it to any % you want.

![](/files/-MkBv36PREYFDrhGDlT7)

### **What is Price Impact?**

Price impact is the difference between the current market price and estimated execution price due to order size.

### **What is A parameter (Amplification Coefficient)?**

The StableSwap algorithm is a hybrid of Constant Product and Constant Sum formula. To simplify, for the purposes of [understanding](https://serenityfund.medium.com/company-watch-curves-formula-for-stablecoins-swap-and-the-magic-amplification-coefficient-d998ed1e184b), you can consider a StableSwap algorithm as:

**StableSwap = ( Constant Sum \* A ) + Constant Product**

A parameter, or amplification coefficient, is a configurable setting which determines how flat the liquidity curve for each pool is.

When:

* **A is small or 0**: The StableSwap algorithm functions as a Constant Product function
* **A is large or infinite**: The StableSwap algorithm functions as a Constant Sum function

For example, consider A = 1 vs. A = 10:

![A Parameter](/files/621gEQfLfnt7Z12NnDJ2)

The A parameter gives the flexibility to the fund managers to balance the pool stability by changing the amplification coefficient. Pools with more volatile assets will use lower A values.

{% hint style="info" %}
Find Saddle's implementation of A parameter [here](https://github.com/saddle-finance/saddle-contract/blob/38328fba920abd10bfe3ac9fde98e7c9cc50af9a/contracts/AmplificationUtils.sol)
{% endhint %}

### **What is the Gas Fee?**

[Gas](https://www.gasnow.org) refers to the unit that measures the amount of computational effort required to execute specific operations on the [Ethereum network](https://ethereum.org/en/developers/docs/gas/). Since each Ethereum transaction requires computational resources to execute, each transaction requires a fee. Gas refers to the fee required to successfully conduct a transaction on Ethereum.

Gas fees are paid in Ethereum's native currency, ether (ETH). Gas prices are denoted in gwei, which itself is a denomination of ETH - each gwei is equal to 0.000000001 ETH (10-9 ETH). For example, instead of saying that your gas costs 0.000000001 ether, you can say your gas costs 1 gwei. The word 'gwei' itself means 'giga-wei', and it is equal to 1,000,000,000 wei.

![](/files/-MkBvxV-T3vO1sVqmK01)

### **Why is Gas so expensive?**

Ethereum network is a popular destination for most decentralized apps (dApps). The popularity has led to enormous activity of Ethereum which results in high gas fees, i.e., higher transaction (gas) fees to miners. The good news is the [London Upgrade](https://eips.ethereum.org/EIPS/eip-1559) of Ethereum alters the way transaction fees are calculated, ideally smoothing them out and making them less volatile. There are also [Layer-2 solutions](https://ethereum.org/en/developers/docs/scaling/layer-2-rollups/) being actively explored to reduce the load on Ethereum network.

Additionally, here are a few [other ways](https://blog.makerdao.com/four-ways-defi-users-can-pay-less-in-ethereum-gas-fees/) to keep control over the Gas fees:

* Combine related transactions to save on gas
* Plan ahead and process your transactions when Ethereum network is not at its peak
* Choose a transaction speed (slow or fast) to minimize the gas fee

### **Where can I see the TVL and Stats for Saddle’s pools?**

The total value locked (TVL) details and stats are available alongside the Saddle Pools.

![](/files/z0ZvMVOeOBrXbrFfwJJD)

For more stats and analytics, you can check out the [DeFi analytics tools](https://docs.saddle.finance/saddle-protocol-stats).

### **Should I deposit into a pool if the assets are imbalanced?**

Yes, you may deposit into the pool if the assets are imbalanced. In fact, if you deposit underweight assets, you’ll get bonus LP tokens.

### **How do I withdraw the liquidity I provided?**

If at any point you want to withdraw your assets, head out to <https://saddle.exchange/#/pools>

* **Step 1:** Choose the pool on the top navigation bar
* **Step 2:** Click on *Withdraw*

![](/files/wuFqVAHDUhZi3uj7tx2D)

* **Step 3:** Enter the amount you’d like to withdraw from one or more of the assets listed in the Saddle pool.
* **Step 4:** Click *Advanced Options* to select options like slippage and gas.

![](/files/NXDf3ydReanhLyVqdoUx)

* **Step 5:** Click *Withdraw* and review the details and confirm the transaction.

### **What risks are there to depositing in Saddle’s pools?**

As with any investment, traditional or DeFi, providing liquidity to the pools carries a risk. Typically, the risks include risk of smart contracts, risks associated with the tokens/Stablecoins in the liquidity pools, and/or the risks associated with the AMMs. We outline the risks in the Saddle pool risk [section](https://docs.saddle.finance/saddle-pools#saddle-pool-risks).

### **Why is my approval/transaction stuck?**

The first thing you need to do when a transaction’s [stuck](https://medium.com/@jgm.orinoco/releasing-stuck-ethereum-transactions-1390149f297d) is to *not send any new transaction*. All new transactions will also get stuck until the pending old transactions are confirmed. Then you have the option to speed up or cancel the stuck transaction. The options for speeding up or cancelling are dependent on the wallet you use.

* Metamask : [Instructions](https://metamask.zendesk.com/hc/en-us/articles/360015489251-How-to-Speed-Up-or-Cancel-a-Pending-Transaction)
* Coinbase : [Instructions](https://help.coinbase.com/en/wallet/sending-and-receiving/adjusting-miner-fees)
* Trust Wallet: [Instructions](https://www.publish0x.com/the-crypt/quick-guide-to-fixing-stuck-ethereum-transactions-xgdvgkv)

**Note:** If you don’t find the options to speed up or cancel in your wallet, be sure to check with the wallet provider. In the event your wallet provider doesn’t support the speed or cancel feature, here are a few alternate options ([MEW](https://kb.myetherwallet.com/en/transactions/checking-or-replacing-a-tx-after-sending/), [MYCRYPTO](https://support.mycrypto.com/how-to/sending/checking-or-replacing-a-transaction-after-it-has-been-sent)) to explore.

### **How can I see my liquidity provider fees?**

The liquidity providers fees come in two forms - trading fees and flash loan fees (where applicable). You can see the fees in the trading window of the pools.

![](/files/qtq4TCbKyQr0agnNlJHE)

For real-time view on the trading fees over a period, you can check out the stats here: <https://www.tokenterminal.com/terminal/projects/saddle-finance>

## **SADDLE REWARDS & INCENTIVES**

Frequently asked questions and answers regarding Saddle rewards and incentives. Still have questions? [Join our Discord](https://discord.gg/qEtPn5pBvk).

### **What is Yield Farming?**

[Yield farming](https://docs.saddle.finance/yield-farming-tools) is an incentive mechanism to put an individual’s cryptocurrency assets to work and generate high returns. Liquidity providers, in yield farming protocols, stake or lock up their assets to earn rewards and higher interests.

### **What are Saddle’s liquidity provider rewards?**

Saddle rewards the liquidity providers for their contribution to the liquidity pool. Depending on the liquidity pool, the rewards structure varies. There are many ways to earn rewards – interest from trading fees, interest from lending, and pool specific incentives. Refer to the [incentives ](https://docs.saddle.finance/saddle-incentives)section for details.

### **What are LP Tokens?**

Liquidity provider tokens (LP tokens) are tokens issued to liquidity providers. LP tokens are used to track individual contributions (proportional share of liquidity) to the overall liquidity pool.

### **What is the difference between APR and APY?**

Both [APY and APR](https://docs.saddle.finance/saddle-incentives#apy-and-apr) refer to yield or interest rates.

* **Annual Percentage Yield (APY):** APY refers to the amount of interest a liquidity provider earns over one year. APY is like an interest rate, but the biggest benefit of APY is the *compounding*.
* **Annual Percentage Rate (APR):** APR does not factor compounding and represents the annual interest rate.

Let’s take a scenario of 1% interest each month. Therefore,

| **APR at 1% interest per month**               | **APY at 1% interest per month**                  |
| ---------------------------------------------- | ------------------------------------------------- |
| APR = Periodic Rate x No. of Periods in a Year | APY = (1 + Periodic Rate) `Number of periods` – 1 |
| APR = 1% X 12 months                           | APY = (1+1%)`12` -1                               |
| 12.00%                                         | 12.68%                                            |

### **How much will I earn for LPing Saddle’s pools?**

Depending on the liquidity pool, the rewards structure varies. Refer to the [incentives ](https://docs.saddle.finance/saddle-incentives)section for details.

### **What additional rewards can I get for LPing Saddle’s pools?**

Depending on the liquidity pool, the rewards structure varies. Refer to the [incentives ](https://docs.saddle.finance/saddle-incentives)section for details.

### **Where do I go to Stake/Unstake?**

Depending on the liquidity pool, the staking/unstaking process varies. The typical process is as shown below:

![](/files/rAanUqjIhaVuxSL9nlgF)

| **Saddle Pool** | **Rewards**                 | **Link**                                                                     |
| --------------- | --------------------------- | ---------------------------------------------------------------------------- |
| BTC Pool        | KEEP Rewards                | [KEEP Liquidity Rewards Dashboard](https://dashboard.keep.network/liquidity) |
| alETH Pool      | ALCX Rewards                | [Alchemix Staking Dashboard](https://app.alchemix.fi/farms)                  |
| D4 Pool         | ALCX/FXS/LQTY/TRIBE Rewards | [FRAX Staking Dashboard](about:blank)                                        |

For further details, refer to the [incentives ](https://docs.saddle.finance/saddle-incentives)section.


# Glossary

Terms and definitions used across Saddle.

This Glossary consists of terms and definitions used across Saddle. The objective of this section is to build a common vocabulary for ease of reference and knowledge.

## **MARKET**

***Buyer**:* A person or an organization buying, planning to buy, or agrees to buy assets.

***Seller**:* A person or an organization selling, planning to sell, or agrees to sell assets.

***Broker-Dealer**:* A person or an organization buying and/or selling on behalf of its customers or for their own. The person/organization acts as a *broker (or agent)* when executing orders on behalf of the client and acts as a *dealer (or principal)* when trades for their own account.

***Supply & Demand:*** Supply and demand form the foundation for markets. Supply and demand directly affect the price of the traded asset. Buyers typically look for the lowest price and sellers the highest. Markets are where buyers and sellers strive to achieve a proper balance (exceptional situations excluded).

***Bid:*** Buyers make a bid, specifying the price they will pay and the quantity required.

***Ask:*** Sellers offer an ask price, specifying the price they will sell and the quantity available.

***Bid-Ask Spread***: The difference between the Ask and the Bid. For example, if the sellers’ ask is $55 and the buyers’ bid is $53, the bid-ask spread is $2. The bid-ask spread determines the market liquidity. For heavily traded assets, the bid-ask spread will be tighter (narrow). However, for assets with little demand or sparsely traded, the bid-ask spread may be high or even unknown.

***Liquidity:*** Refers to how easily and quickly assets are bought or sold *without* affecting the asset's price. If there is a high volume of trade, the bid-ask spread should be narrow for the asset traded. Therefore, liquid. Contrarily, when there is a wide (or unknown) bid-ask spread, then the asset is illiquid.

***Market Maker**:* Market makers (MM) help keep the market functioning by actively buying and selling assets. MMs can be an individual or an organization providing liquidity to the market by transacting on both sides of the market (buy and sell). For example, the MM might offer a Bid for $20/stock and Ask for $20.05/stock. Market makers earn a profit through the bid-ask spread and carry a risk of price variations during Buy-Hold-Sell cycle. The common type of market maker are the brokerage houses.

***Slippage***: Slippage is the difference between the expected price of a trade and the execution price. This happens as there is a time delay between the trade request and execution in the market. Slippage results from a change in bid-ask spread. During this time, if the bid-ask spread changes, then slippage occurs. Slippage can occur at any time but is amplified during periods of high volatility and with large volume trades.

***Order Book**:* Most modern financial markets are order-driven (buy-sell) markets. At the heart of the trade is an order book; an electronic register of the list of buy and sell orders. A typical order book has three parts – buy orders, sell orders, and order history. The order book helps improve market transparency, help traders make informed decisions, and identifies participants and price of a trade.

***Exchange***: Exchange is a market where trading is conducted. For example, New York Stock Exchange (NYSE), London Stock Exchange (LSE), or the Cryptocurrency exchanges like Saddle, Binance, Coinbase, or Uniswap.

## **CRYPTOCURRENCY EXCHANGE**

***Cryptocurrency Exchange***: A cryptocurrency exchange is a marketplace for trading cryptocurrencies. Broadly, two types of cryptocurrency exchanges exist:

***Centralized Exchanges (CEX)***: A cryptocurrency exchange owned and governed by a 3rd party. E.g., Binance, Coinbase, and Bitfinex.

***Decentralized Exchanges (DEX)***: A cryptocurrency exchange, unlike CEX, is not owned or governed by a 3rd party. A DEX acts as a peer-to-peer (P2P) platform, facilitating trade with no central party. E.g., Saddle, Uniswap, Sushiswap, and Mdex.

***Automated Market Makers (AMM)***: Market makers are essential in an exchange to provide liquidity, control spreads, and maintain slippages. Since cryptocurrency exchanges work 24x7, the need for automated market makers rose. AMMs democratized cryptocurrency trading by doing away with order books and institutional market makers. Instead, AMMs execute trade automatically using algorithms and liquidity pools.

***Permissionless:*** Unlike traditional exchanges, permissionless networks require no permission to join and interact with the blockchain network. Permissionless AMMs allow anyone with an internet connection to become a part of the market to trade.

***Liquidity Pools***: Instead of an order book, AMMs use liquidity pools to facilitate trade. Liquidity pool, a smart contract, is a fund of tokens (or coins). In AMMs, traders interact with the smart contracts, to enable liquidity and price discovery. Because of the permissionless nature, AMMs allow anyone to provide liquidity to the liquidity pool. The liquidity pool smart contract holds two or more tokens and allows anyone to deposit and withdraw funds from them, but only according to specific mathematical rules.

***Liquidity Providers***: Liquidity providers contribute assets (cryptocurrency tokens and coins) to liquidity pools. In exchange for providing the tokens, the LPs normally earn a fee. Now, when a trade executes on an AMM, the trade executes against the liquidity pool. This eliminates the need for an order book and for the buyer and seller to be present at that moment in time.

***Yield Farming***: Yield farming is an incentive mechanism to put an individual’s cryptocurrency assets to work and generate high returns. Liquidity providers, in yield farming protocols, stake or lock up their assets to earn rewards and higher interests.

***Constant Product Formula***: Constant product formula is probably the simplest and the earliest algorithm to come into the market. Uniswap popularized the mathematical formula: x \* y = k, where x is the amount of Token#1 in the liquidity pool, y is the amount of Token#2 in the liquidity pool, and k is a fixed constant.

***Constant Sum Formula:*** Constant sum formula solves for the equation: x + y = k, where **x** is the amount of Token#1 in the liquidity pool, **y** is the amount of Token#2 in the liquidity pool, and **k** is a fixed constant.

***StableSwap:*** First introduced by [Curve](https://curve.fi/whitepaper), the Stableswap is a hybrid algorithm. The Stableswap hybrid combines both Constant Product and Constant Sum models. When the liquidity pool portfolio is balanced, the algorithm functions as a Constant Sum formula; **x + y = k**. As the liquidity pool portfolio becomes imbalanced, the StableSwap algorithm functions as a Constant Product formula; **x \* y = k**.

## **PEGGED-VALUE ASSETS**

***Pegged-Value Assets***: Saddle facilitates trades of pegged-value assets, where the price is pegged to an underlying asset, bringing in stability to the price in an otherwise volatile cryptocurrency market.

***Stablecoin:*** Stablecoins (e.g., USDT, USDC, DAI) are a good example of pegged value assets. The value of the stablecoin is fixed to an asset such as a fiat currency (e.g., 1 DAI = 1 US$).

***Dynamic Pegs***: Dynamic pegs are the next evolution of AMMs. Dynamic pegs will bring the benefits of Stableswaps to cryptocurrency assets which aren’t pegged to another asset. By using an automatic price change mechanism, the algorithm will move the price based on real-time profit margin calculations, to adjust for slippages.

### Pegged-Value Assets in Saddle Pools

***alETH***: alETH is an ERC20 token, backed 4:1 by ETH.

***alUSD***: A yield-backed synthetic stablecoin minted via Alchemix Finance, a DAO-governed synthetic asset platform.

***DAI***: DAI is soft pegged to the USD algorithmically.

***FEI***: A scalable and decentralized stablecoin that leverages protocol-controlled value (PCV) for peg maintenance while maintaining highly liquid secondary markets.

***FRAX***: A fractional-algorithmic stablecoin that is partially backed by collateral and partially stabilized algorithmically.

***LUSD***: The USD-pegged stablecoin of the Liquity decentralized borrowing protocol.

***renBTC***: renBTC is an ERC20 token backed 1:1 by Bitcoin. Ren also decentralizes the custody of the BTC.

***sBTC***: sBTC differs from the rest, as Bitcoins does not back it. The value of sBTC is kept stable through an over-collateralization mechanism leveraging Synthetix SNX tokens.

***sETH***: sETH is a short position built through the dYdX protocol and can be traded like any ERC20 token. sETH is tied to USD-backed stablecoin DAI.

***sUSD***: A synthetic stablecoin on the Synthetix platform, whose value tracks the US Dollar.

***tBTC***: tBTC is backed 1:1 by Bitcoin and truly decentralized.

***USDC***: USDC is an ERC20 token pegged 1:1 to the US dollars (USD)

***USDT***: USDT, like USDC, is pegged 1:1 to the USD.

***wBTC***: Wrapped BTC is an ERC20 token backed 1:1 by the actual Bitcoin.

***wCUSD:*** Wrapped Celo Dollars is an ERC20 token representing a 1:1 share of Celo Dollar.

***WETH***: Wrapped ETH is an ERC20 token backed 1:1 by ETH, allowing trade directly with ALT coins.

## **SADDLE POOL**

***Saddle Pools***: Saddle Pools are the liquidity pools in Saddle Finance. Saddle pools are of two types – base and metapools.

***Base pools:*** Base pools contain two or more tokens and Saddle base pools implement the StableSwap algorithm.

***Metapools:*** These pools contain one token to trade with another underlying Base pool. For example, in the sUSD Pool, we pool the single token sUSD alongside Stablecoin Pool V2 (DAI, USDC, USDT). Adding the single asset to the metapool, however, does not dilute the liquidity of the underlying base pool.

***BTC Pool***: Saddle BTC pool currently supports four wrapped variants of Bitcoin, enabling Bitcoin users to take part in the Ethereum DeFi ecosystem.

***alETH Pool***: The ETH pool on Saddle is of alETH – a synthetic ETH backed asset by Alchemix. alETH is a multi-pool currently supporting three variants of Ethereum, enabling seamless and cheap switch between pegged-value ETH assets (backed or wrapped).

***Stablecoin Pool V2***: The Stablecoin pool contains three stablecoins, unlocking deep on-chain liquidity between pegged value crypto assets.

***D4 Pool***: The Saddle D4 (decentralized) pool consists entirely of permissionless, decentralized stablecoins. Stablecoins like USDC, USDT, and Dai are not permissionless – centralized organizations manage them with varying degrees of transparency.

***sUSD Pool***: The Saddle sUSD Pool is a metapool. In this pool, we pooled the single token sUSD alongside Stablecoin Pool V2 (DAI, USDC, USDT). Adding the single asset to the metapool, however, does not dilute the liquidity of the underlying base pool.

***saddleUSD-V2***: A base pool (Stablecoin Pool V2) on Saddle comprising the stablecoins USDT, USDC, and DAI.

***wCUSD Pool***: A metapool. In this pool, we pooled the single token wCUSD alongside Stablecoin Pool V2 (DAI, USDC, USDT).

## **SADDLE VIRTUAL SWAPS**

***Virtual swaps V1***: A key property of synths is we can exchange them with extremely low slippage. For example, to bridge USD, ETH, and BTC pools, synths can act as a common asset. We can exchange the synths with infinite liquidity, allowing them to act as a *liquid bridge* between any pool that contains sUSD, sBTC, or sETH. The issue is, Synthetix’s fee reclamation and rebate mechanism [prevents](https://research.synthetix.io/t/virtual-synths-sip/202) atomic transactions (to mitigate front running of oracle price updates) for a Synth <> Synth exchange, breaking composability.

***Virtual swaps V2***: Virtual swaps (Saddle Synths V2) are a new feature in Saddle pools leveraging Synthetix’s vSynths. With the implementation of vSynth logic in Saddle’s AMM, it’s possible to use synths as *bridges between pools*. The advantages of Virtual swaps V2 over V1 are the support for atomic transactions - aggregators can now be used without breaking the transaction flow. ***Note:** Currently, Virtual Swaps V2 are not live yet.*

***Synths***: Synths differ from asset backed cryptocurrencies like stablecoins. For instance, US Dollars back DAI stablecoin. If you own 1 DAI, then in a way you own US$ 1. But owning sBTC synth doesn’t mean you own the equivalent Bitcoin. Rather, the owner only has the exposure to the BTC price. Synthetix works on an *over-collateralization* model; each synth is collateralized by more value than it represents to absorb any sharp price changes.

***Front-Running***: While synths are great, they came with a limitation. Front-running. Many decentralized exchanges (DEX) suffer from front-running. Because of constraints on Ethereum, there is a latency and cost in sourcing and updating the real-world asset price for the synths. [Front-runners](https://en.wikipedia.org/wiki/Front_running) can see the difference between price of the asset in the real-world and on-chain. They see an arbitrage opportunity and over-pay for Ethereum gas fee to prioritize their orders in the queue, before the on-chain price reflects the real-world.

***Composability***: In DeFi, composability is the ability of open-source protocols to interact and combine creatively to form new products and services. There are two key aspects for composability to work Standardization and Atomicity.

***Standardization***: The ability of DeFi protocols to connect and communicate in a standardized and open way.

***Atomicity***: The need for the DeFi protocols to connect instantly within a single transaction.

## **SADDLE FEES**

***Trading fee**:* The trading fee applies to every trade and the prevailing fee is displayed in the pool information. Typically, the fee is 0.04%. However, the fee may vary depending on the pool.

***Admin fee**:* The admin fee is calculated as a % of the trading fee.

***Gas fee**:* The fee payable to Ethereum network to confirm the transactions. The gas fee varies depending on the speed of confirmation time required and represented in gwei (1 gwei = 10`-9` ETH).

***Flash Loan Fees***: Some of the Saddle pools support flash loans. The flash loan fees, typically 0.08%, are a part of the trading fees earned by liquidity providers.

## **INCENTIVES**

***Earned Fees***: Any earnings of Trading Fees and/or Flash Loan Fees from providing liquidity to the Saddle pools.

***Incentives***: The incentives from the Saddle protocol and/or partners protocols. For e.g., KEEP, ALCX. *Note: Currently there are no Saddle protocol specific incentives.*

***Rewards***: Refers collectively to both earned fees and incentives.

***Annual Percentage Yield (APY)*****:** APY refers to the amount of interest a liquidity provider earns over one year. APY is like an interest rate, but the biggest benefit of APY is the *compounding*.

***Annual Percentage Rate (APR)*****:** APR does not factor compounding and represents the annual interest rate.

***LP Tokens***: Liquidity provider tokens or LP tokens are tokens issued to liquidity providers. LP tokens are used to track individual contributions (proportional share of liquidity) to the overall liquidity pool. For example, if you provide liquidity to Saddle BTC Pool V2, you’ll receive ***saddleBTC-V2*** LP tokens.

***Staking LP Tokens***: Staking is the process of locking LP tokens in a cryptocurrency wallet to support the operations of the crypto network. By staking LP tokens, stakers gain rewards from the network.

***KEEP Rewards***: Once you provide liquidity to the BTC pool, you will receive KEEP LP tokens representing your share of the liquidity pool. You can further stake the KEEP LP tokens to earn rewards.

***ALCX Rewards***: Once you provide liquidity to the alETH pool, you will receive ALCX LP tokens representing your share of the liquidity pool. You can further stake the ALCX LP tokens to earn rewards.

***ALCX/FXS/LQTY/TRIBE Rewards***: Once you provide liquidity to the D4 pool, you will receive four LP tokens (ALCX/FXS/LQTY/TRIBE) representing your share of the liquidity pool. You can further stake the LP tokens to earn rewards.


# How to Flash-loan Assets from Saddle

Some of our pools allow flash-loaning assets for a small fee.

```
function flashLoan(
    address receiver,
    IERC20 token,
    uint256 amount,
    bytes memory params
) external;
```

Caller must provide a valid receiver address that inherits [IFlashLoanReceiver interface](https://github.com/saddle-finance/saddle-contract/blob/master/contracts/interfaces/IFlashLoanReceiver.sol).

```
function executeOperation(
    address pool,
    address token,
    uint256 amount,
    uint256 fee,
    bytes calldata params
) external;
```

Upon finishing `executeOperation`, the pool must have the initial liquidity back along with the associated fee. If the requirement is not met, then the transaction will fail.

We provide a [basic example of a flashloan borrower contract](https://github.com/saddle-finance/saddle-contract/blob/master/contracts/helper/FlashLoanBorrowerExample.sol).

## Flash-loan Supported Pools

* vETH2 pool (`0xdec2157831D6ABC3Ec328291119cc91B337272b5`)
* alETH pool (`0xa6018520EAACC06C30fF2e1B3ee2c7c22e64196a`)
* D4 pool (`0xC69DDcd4DFeF25D8a793241834d4cc4b3668EAD6`)

## Do you have any flashloan countermeasures implemented?

For flashloan safety, we have 2 safety measures in place:

* Prevent reentrancy into the same pool. You cant flashloan money out of a pool and use that fund to trade through the same pool.
* Ensure the returned amount is always higher than borrowed amount. The transaction will revert if the borrower does not pay up by end of the transaction.

Our flash loan implementation is based on [Aave](https://aave.com/)'s [IFlashLoanReceiver.sol](https://github.com/aave/aave-protocol/blob/4b4545fb583fd4f400507b10f3c3114f45b8a037/contracts/flashloan/interfaces/IFlashLoanReceiver.sol).


# Contract Addresses

All Saddle protocol smart contracts are immutable.

## Mainnet

### Pools & Gauges

| Contract Name                           | Contract Address                                                                                                           |
| --------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| `4Pool`                                 | [0x101CD330D088634B6F64c2eb4276e63Bf1BbfDE3](https://etherscan.io/address/0x101CD330D088634B6F64c2eb4276e63Bf1BbfDE3#code) |
| `4PoolLPToken`                          | [0x1B4ab394327FDf9524632dDf2f0F04F9FA1Fe2eC](https://etherscan.io/address/0x1B4ab394327FDf9524632dDf2f0F04F9FA1Fe2eC#code) |
| `ALETHPool`                             | [0xa6018520EAACC06C30fF2e1B3ee2c7c22e64196a](https://etherscan.io/address/0xa6018520EAACC06C30fF2e1B3ee2c7c22e64196a#code) |
| `ALETHPoolLPToken`                      | [0xc9da65931ABf0Ed1b74Ce5ad8c041C4220940368](https://etherscan.io/address/0xc9da65931ABf0Ed1b74Ce5ad8c041C4220940368#code) |
| `LiquidityGaugeV5_ALETHPool`            | [0x8B701e9B3a1887fE9b0C7936a8233b39408e69f6](https://etherscan.io/address/0x8B701e9B3a1887fE9b0C7936a8233b39408e69f6#code) |
| `BTCPool`                               | [0x4f6A43Ad7cba042606dECaCA730d4CE0A57ac62e](https://etherscan.io/address/0x4f6A43Ad7cba042606dECaCA730d4CE0A57ac62e#code) |
| `BTCPoolLPToken`                        | [0xC28DF698475dEC994BE00C9C9D8658A548e6304F](https://etherscan.io/address/0xC28DF698475dEC994BE00C9C9D8658A548e6304F#code) |
| `BTCPoolV2`                             | [0xdf3309771d2BF82cb2B6C56F9f5365C8bD97c4f2](https://etherscan.io/address/0xdf3309771d2BF82cb2B6C56F9f5365C8bD97c4f2#code) |
| `BTCPoolV2LPToken`                      | [0xF32E91464ca18fc156aB97a697D6f8ae66Cd21a3](https://etherscan.io/address/0xF32E91464ca18fc156aB97a697D6f8ae66Cd21a3#code) |
| `LiquidityGaugeV5_BTCPoolV2`            | [0x17Bde8EBf1E9FDA85b9Bd1a104266b394E9Db33e](https://etherscan.io/address/0x17Bde8EBf1E9FDA85b9Bd1a104266b394E9Db33e#code) |
| `D4Pool`                                | [0xC69DDcd4DFeF25D8a793241834d4cc4b3668EAD6](https://etherscan.io/address/0xC69DDcd4DFeF25D8a793241834d4cc4b3668EAD6#code) |
| `D4PoolLPToken`                         | [0xd48cF4D7FB0824CC8bAe055dF3092584d0a1726A](https://etherscan.io/address/0xd48cF4D7FB0824CC8bAe055dF3092584d0a1726A#code) |
| `LiquidityGaugeV5_D4Pool`               | [0x702c1b8Ec3A77009D5898e18DA8F8959B6dF2093](https://etherscan.io/address/0x702c1b8Ec3A77009D5898e18DA8F8959B6dF2093#code) |
| `Frax3Pool`                             | [0x8cAEa59f3Bf1F341f89c51607E4919841131e47a](https://etherscan.io/address/0x8cAEa59f3Bf1F341f89c51607E4919841131e47a#code) |
| `Frax3PoolLPToken`                      | [0x0785aDDf5F7334aDB7ec40cD785EBF39bfD91520](https://etherscan.io/address/0x0785aDDf5F7334aDB7ec40cD785EBF39bfD91520#code) |
| `LiquidityGaugeV5_Frax3Pool`            | [0x13Ba45c2B686c6db7C2E28BD3a9E8EDd24B894eD](https://etherscan.io/address/0x13Ba45c2B686c6db7C2E28BD3a9E8EDd24B894eD#code) |
| `FRAXalUSDMetaPool`                     | [0xFB516cF3710fC6901F2266aAEB8834cF5e4E9558](https://etherscan.io/address/0xFB516cF3710fC6901F2266aAEB8834cF5e4E9558#code) |
| `FRAXalUSDMetaPoolDeposit`              | [0xe9154791883Df07e1328B636BCedfcCb80fefa38](https://etherscan.io/address/0xe9154791883Df07e1328B636BCedfcCb80fefa38#code) |
| `FRAXalUSDMetaPoolLPToken`              | [0x3cF7b9479a01eeB3bbfC43581fa3bb21cd888e2A](https://etherscan.io/address/0x3cF7b9479a01eeB3bbfC43581fa3bb21cd888e2A#code) |
| `LiquidityGaugeV5_FRAXalUSDMetaPool`    | [0x953693DCB2E9DDC0c1398C1b540b81b63ceA5e16](https://etherscan.io/address/0x953693DCB2E9DDC0c1398C1b540b81b63ceA5e16#code) |
| `FRAXBPPool`                            | [0x13Cc34Aa8037f722405285AD2C82FE570bfa2bdc](https://etherscan.io/address/0x13Cc34Aa8037f722405285AD2C82FE570bfa2bdc#code) |
| `FRAXBPPoolLPToken`                     | [0x927E6f04609A45B107C789aF34BA90Ebbf479f7f](https://etherscan.io/address/0x927E6f04609A45B107C789aF34BA90Ebbf479f7f#code) |
| `LiquidityGaugeV5_FRAXBPPool`           | [0xB2Ac3382dA625eb41Fc803b57743f941a484e2a6](https://etherscan.io/address/0xB2Ac3382dA625eb41Fc803b57743f941a484e2a6#code) |
| `FRAXsUSDMetaPool`                      | [0x69baA0d7c2e864b74173922Ca069Ac79d3be1556](https://etherscan.io/address/0x69baA0d7c2e864b74173922Ca069Ac79d3be1556#code) |
| `FRAXsUSDMetaPoolDeposit`               | [0x7D6c760cBde5a9Ad47510A86b9DCc58F9473CdD8](https://etherscan.io/address/0x7D6c760cBde5a9Ad47510A86b9DCc58F9473CdD8#code) |
| `FRAXsUSDMetaPoolLPToken`               | [0x6Ac7a4cB3BFa90DC651CD53EB098e23c88d04e77](https://etherscan.io/address/0x6Ac7a4cB3BFa90DC651CD53EB098e23c88d04e77#code) |
| `LiquidityGaugeV5_FRAXsUSDMetaPool`     | [0x104F44551386d603217450822443456229F73aE4](https://etherscan.io/address/0x104F44551386d603217450822443456229F73aE4#code) |
| `FRAXUSDTMetaPool`                      | [0xC765Cd3d015626244AD63B5FB63a97c5634643b9](https://etherscan.io/address/0xC765Cd3d015626244AD63B5FB63a97c5634643b9#code) |
| `FRAXUSDTMetaPoolDeposit`               | [0xAbf69CDE7B3725c12B8703005342EB5DD8a95D61](https://etherscan.io/address/0xAbf69CDE7B3725c12B8703005342EB5DD8a95D61#code) |
| `FRAXUSDTMetaPoolLPToken`               | [0x486DFCfdbF9025c062110E8c0344a15279aD0a85](https://etherscan.io/address/0x486DFCfdbF9025c062110E8c0344a15279aD0a85#code) |
| `LiquidityGaugeV5_FRAXUSDTMetaPool`     | [0x6EC5DD7D8E396973588f0dEFD79dCA04F844d57C](https://etherscan.io/address/0x6EC5DD7D8E396973588f0dEFD79dCA04F844d57C#code) |
| `FRAXUSXMetaPool`                       | [0x1dcB69a2b9148C641a43F731fCee123e2be30bAb](https://etherscan.io/address/0x1dcB69a2b9148C641a43F731fCee123e2be30bAb#code) |
| `FRAXUSXMetaPoolDeposit`                | [0x4F0E41a37cE2ff1fA654cC93Eb03F9d16E65fD11](https://etherscan.io/address/0x4F0E41a37cE2ff1fA654cC93Eb03F9d16E65fD11#code) |
| `FRAXUSXMetaPoolLPToken`                | [0xAaD59B28CC76eD4c9F7C83E697E5cC925fB0B920](https://etherscan.io/address/0xAaD59B28CC76eD4c9F7C83E697E5cC925fB0B920#code) |
| `LiquidityGaugeV5_FRAXUSXMetaPool`      | [0x9585a54297beAa83F044866678b13d388D0180bf](https://etherscan.io/address/0x9585a54297beAa83F044866678b13d388D0180bf#code) |
| `SUSDMetaPool`                          | [0x0C8BAe14c9f9BF2c953997C881BEfaC7729FD314](https://etherscan.io/address/0x0C8BAe14c9f9BF2c953997C881BEfaC7729FD314#code) |
| `SUSDMetaPoolDeposit`                   | [0x1e35ebF875f8A2185EDf22da02e7dBCa0F5558aB](https://etherscan.io/address/0x1e35ebF875f8A2185EDf22da02e7dBCa0F5558aB#code) |
| `SUSDMetaPoolLPToken`                   | [0x8Fa31c1b33De16bf05c38AF20329f22D544aD64c](https://etherscan.io/address/0x8Fa31c1b33De16bf05c38AF20329f22D544aD64c#code) |
| `SUSDMetaPoolUpdated`                   | [0x824dcD7b044D60df2e89B1bB888e66D8BCf41491](https://etherscan.io/address/0x824dcD7b044D60df2e89B1bB888e66D8BCf41491#code) |
| `SUSDMetaPoolUpdatedDeposit`            | [0xc66Ed5d7800579220c71f21B1cCa2006B3a95900](https://etherscan.io/address/0xc66Ed5d7800579220c71f21B1cCa2006B3a95900#code) |
| `SUSDMetaPoolUpdatedLPToken`            | [0xb6214a9d18f5Bf34A23a355114A03bE4f7D804fa](https://etherscan.io/address/0xb6214a9d18f5Bf34A23a355114A03bE4f7D804fa#code) |
| `SUSDMetaPoolV3`                        | [0x4568727f50c7246ded8C39214Ed6FF3c157f080D](https://etherscan.io/address/0x4568727f50c7246ded8C39214Ed6FF3c157f080D#code) |
| `SUSDMetaPoolV3Deposit`                 | [0xB98fd1f66884cD5786b37cDE040B9f0cf763866f](https://etherscan.io/address/0xB98fd1f66884cD5786b37cDE040B9f0cf763866f#code) |
| `SUSDMetaPoolV3LPToken`                 | [0x444F94460a641429CDa4e38E02E51642Cc38276A](https://etherscan.io/address/0x444F94460a641429CDa4e38E02E51642Cc38276A#code) |
| `LiquidityGaugeV5_SUSDMetaPoolV3`       | [0x2683190e31e8ce47467c98ff1DBc018aCDD43C2f](https://etherscan.io/address/0x2683190e31e8ce47467c98ff1DBc018aCDD43C2f#code) |
| `TBTCMetaPool`                          | [0xf74ebe6e5586275dc4CeD78F5DBEF31B1EfbE7a5](https://etherscan.io/address/0xf74ebe6e5586275dc4CeD78F5DBEF31B1EfbE7a5#code) |
| `TBTCMetaPoolDeposit`                   | [0xee1ec4e1C6e39C31dAaf3db2A62A397bdf3fe2f1](https://etherscan.io/address/0xee1ec4e1C6e39C31dAaf3db2A62A397bdf3fe2f1#code) |
| `TBTCMetaPoolLPToken`                   | [0x122Eca07139EB368245A29FB702c9ff11E9693B7](https://etherscan.io/address/0x122Eca07139EB368245A29FB702c9ff11E9693B7#code) |
| `TBTCMetaPoolUpdated`                   | [0xA0b4a2667dD60d5CdD7EcFF1084F0CeB8dD84326](https://etherscan.io/address/0xA0b4a2667dD60d5CdD7EcFF1084F0CeB8dD84326#code) |
| `TBTCMetaPoolUpdatedDeposit`            | [0x05383312655856E25b851c15fA856dB7e270F0cF](https://etherscan.io/address/0x05383312655856E25b851c15fA856dB7e270F0cF#code) |
| `TBTCMetaPoolUpdatedLPToken`            | [0x3f2f811605bC6D701c3Ad6E501be13461c560320](https://etherscan.io/address/0x3f2f811605bC6D701c3Ad6E501be13461c560320#code) |
| `TBTCMetaPoolV3`                        | [0xfa9ED0309Bf79Eb84C847819F0B3CB84F6d351Af](https://etherscan.io/address/0xfa9ED0309Bf79Eb84C847819F0B3CB84F6d351Af#code) |
| `TBTCMetaPoolV3Deposit`                 | [0x4946DE721ce70D4B7aa226aA0Fe869C935769388](https://etherscan.io/address/0x4946DE721ce70D4B7aa226aA0Fe869C935769388#code) |
| `TBTCMetaPoolV3LPToken`                 | [0xA2E81Eb93F0F9814ae9A3bea2D2A63408f2709C1](https://etherscan.io/address/0xA2E81Eb93F0F9814ae9A3bea2D2A63408f2709C1#code) |
| `LiquidityGaugeV5_TBTCMetaPoolV3`       | [0xB79B4fCF7cB4A1c4064Ff5b48F71A331880ab53a](https://etherscan.io/address/0xB79B4fCF7cB4A1c4064Ff5b48F71A331880ab53a#code) |
| `SimpleRewarder_T_TBTCMetaPoolV3`       | [0xc09d3Bb5c87e8A8b239cDa9551279801a92c317F](https://etherscan.io/address/0xc09d3Bb5c87e8A8b239cDa9551279801a92c317F#code) |
| `USDPool`                               | [0x3911F80530595fBd01Ab1516Ab61255d75AEb066](https://etherscan.io/address/0x3911F80530595fBd01Ab1516Ab61255d75AEb066#code) |
| `USDPoolLPToken`                        | [0x76204f8CFE8B95191A3d1CfA59E267EA65e06FAC](https://etherscan.io/address/0x76204f8CFE8B95191A3d1CfA59E267EA65e06FAC#code) |
| `USDPoolV2`                             | [0xaCb83E0633d6605c5001e2Ab59EF3C745547C8C7](https://etherscan.io/address/0xaCb83E0633d6605c5001e2Ab59EF3C745547C8C7#code) |
| `USDPoolV2LPToken`                      | [0x5f86558387293b6009d7896A61fcc86C17808D62](https://etherscan.io/address/0x5f86558387293b6009d7896A61fcc86C17808D62#code) |
| `LiquidityGaugeV5_USDPoolV2`            | [0x7B2025Bf8c5ee8Baad9da8C3E3Ee45E96ed8b8EA](https://etherscan.io/address/0x7B2025Bf8c5ee8Baad9da8C3E3Ee45E96ed8b8EA#code) |
| `USXPool`                               | [0x2bFf1B48CC01284416E681B099a0CDDCA0231d72](https://etherscan.io/address/0x2bFf1B48CC01284416E681B099a0CDDCA0231d72#code) |
| `USXPoolLPToken`                        | [0x1AE28a6ACA177c29b5773e91fbf74AfB0B7fE5C9](https://etherscan.io/address/0x1AE28a6ACA177c29b5773e91fbf74AfB0B7fE5C9#code) |
| `LiquidityGaugeV5_USXPool`              | [0x50d745c2a2918A47A363A2d32becd6BBC1A53ece](https://etherscan.io/address/0x50d745c2a2918A47A363A2d32becd6BBC1A53ece#code) |
| `VETH2Pool`                             | [0xdec2157831D6ABC3Ec328291119cc91B337272b5](https://etherscan.io/address/0xdec2157831D6ABC3Ec328291119cc91B337272b5#code) |
| `VETH2PoolLPToken`                      | [0xe37E2a01feA778BC1717d72Bd9f018B6A6B241D5](https://etherscan.io/address/0xe37E2a01feA778BC1717d72Bd9f018B6A6B241D5#code) |
| `WCUSDMetaPool`                         | [0x3F1d224557afA4365155ea77cE4BC32D5Dae2174](https://etherscan.io/address/0x3F1d224557afA4365155ea77cE4BC32D5Dae2174#code) |
| `WCUSDMetaPoolDeposit`                  | [0x401AFbc31ad2A3Bc0eD8960d63eFcDEA749b4849](https://etherscan.io/address/0x401AFbc31ad2A3Bc0eD8960d63eFcDEA749b4849#code) |
| `WCUSDMetaPoolLPToken`                  | [0x78179d49C13c4ECa14C69545ec172Ba0179EAE6B](https://etherscan.io/address/0x78179d49C13c4ECa14C69545ec172Ba0179EAE6B#code) |
| `WCUSDMetaPoolUpdated`                  | [0xc02D481B52Ae04Ebc76a8882441cfAED45eb8342](https://etherscan.io/address/0xc02D481B52Ae04Ebc76a8882441cfAED45eb8342#code) |
| `WCUSDMetaPoolUpdatedDeposit`           | [0x9898D87368DE0Bf1f10bbea8dE46c00cC3a2F9F1](https://etherscan.io/address/0x9898D87368DE0Bf1f10bbea8dE46c00cC3a2F9F1#code) |
| `WCUSDMetaPoolUpdatedLPToken`           | [0x5F7872490a9B405946376dd40fCbDeF521F13e3f](https://etherscan.io/address/0x5F7872490a9B405946376dd40fCbDeF521F13e3f#code) |
| `WCUSDMetaPoolV3`                       | [0xB62222B941e9B652BE3632EEa062cb0ff66b1d1c](https://etherscan.io/address/0xB62222B941e9B652BE3632EEa062cb0ff66b1d1c#code) |
| `WCUSDMetaPoolV3Deposit`                | [0x671D5942F901F5C60e4EbaD1c3bF284A4d28c675](https://etherscan.io/address/0x671D5942F901F5C60e4EbaD1c3bF284A4d28c675#code) |
| `WCUSDMetaPoolV3LPToken`                | [0x0dB8b09c13FE21913faF463274cE8e0a51719f16](https://etherscan.io/address/0x0dB8b09c13FE21913faF463274cE8e0a51719f16#code) |
| `LiquidityGaugeV5_WCUSDMetaPoolV3`      | [0x3dC88ee38db8C7b6DCEB447E4348e51bd87ced93](https://etherscan.io/address/0x3dC88ee38db8C7b6DCEB447E4348e51bd87ced93#code) |
| `SushiSwapPairSDLFRAX`                  | [0x65a094427dee5067782739870f92527e27501bcb](https://etherscan.io/address/0x65a094427dee5067782739870f92527e27501bcb#code) |
| `SushiSwapPairSDLWETH`                  | [0x0C6F06b32E6Ae0C110861b8607e67dA594781961](https://etherscan.io/address/0x0C6F06b32E6Ae0C110861b8607e67dA594781961#code) |
| `LiquidityGaugeV5_SushiSwapPairSDLWETH` | [0xc64F8A9fe7BabecA66D3997C9d15558BF4817bE3](https://etherscan.io/address/0xc64F8A9fe7BabecA66D3997C9d15558BF4817bE3#code) |

### Gauge Utilities

| Contract Name      | Contract Address                                                                                                           |
| ------------------ | -------------------------------------------------------------------------------------------------------------------------- |
| `Gauge Controller` | [0x99Cb6c36816dE2131eF2626bb5dEF7E5cc8b9B14](https://etherscan.io/address/0x99Cb6c36816dE2131eF2626bb5dEF7E5cc8b9B14#code) |
| `Gauge Helper`     | [0x8020E4134AD6a694AdbE9521a12C751e67CE9861](https://etherscan.io/address/0x8020E4134AD6a694AdbE9521a12C751e67CE9861#code) |
| `Gauge Minter`     | [0x358fE82370a1B9aDaE2E3ad69D6cF9e503c96018](https://etherscan.io/address/0x358fE82370a1B9aDaE2E3ad69D6cF9e503c96018#code) |

### Token

| Contract Name        | Contract Address                                                                                                           |
| -------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| `MiniChefV2`         | [0x691ef79e40d909C715BE5e9e93738B3fF7D58534](https://etherscan.io/address/0x691ef79e40d909C715BE5e9e93738B3fF7D58534#code) |
| `RetroactiveVesting` | [0x5DCA270671935cf3dF78bd8373C22BE250198a03](https://etherscan.io/address/0x5DCA270671935cf3dF78bd8373C22BE250198a03#code) |
| `SDL`                | [0xf1Dc500FdE233A4055e25e5BbF516372BC4F6871](https://etherscan.io/address/0xf1Dc500FdE233A4055e25e5BbF516372BC4F6871#code) |
| `veSDL`              | [0xD2751CdBED54B87777E805be36670D7aeAe73bb2](https://etherscan.io/address/0xD2751CdBED54B87777E805be36670D7aeAe73bb2#code) |
| `Vesting`            | [0xf8504e92428d65E56e495684A38f679C1B1DC30b](https://etherscan.io/address/0xf8504e92428d65E56e495684A38f679C1B1DC30b#code) |

### Virtual Swaps

| Contract Name  | Contract Address                                                                                                           |
| -------------- | -------------------------------------------------------------------------------------------------------------------------- |
| `Bridge`       | [0xa5bD85ed9fA27ba23BfB702989e7218E44fd4706](https://etherscan.io/address/0xa5bD85ed9fA27ba23BfB702989e7218E44fd4706#code) |
| `SynthSwapper` | [0xdf815Ea6b066Ac9f3107d8863a6c19aA2a5d24d3](https://etherscan.io/address/0xdf815Ea6b066Ac9f3107d8863a6c19aA2a5d24d3#code) |

### Other

| Contract Name             | Contract Address                                                                                                           |
| ------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| `Allowlist`               | [0xf5d2E84E816175dfB2C38Bd7549D4BD37b1C0559](https://etherscan.io/address/0xf5d2E84E816175dfB2C38Bd7549D4BD37b1C0559#code) |
| `FeeDistributor`          | [0xabd040A92d29CDC59837e79651BB2979EA66ce04](https://etherscan.io/address/0xabd040A92d29CDC59837e79651BB2979EA66ce04#code) |
| `GeneralizedSwapMigrator` | [0x46866D274E6D9015c5FDc098CE270803e11e3eF4](https://etherscan.io/address/0x46866D274E6D9015c5FDc098CE270803e11e3eF4#code) |
| `MultiCall`               | [0xeefba1e63905ef1d7acba5a8513c70307c1ce441](https://etherscan.io/address/0xeefba1e63905ef1d7acba5a8513c70307c1ce441#code) |
| `MultiCall2`              | [0x5ba1e12693dc8f9c48aad8770482f4739beed696](https://etherscan.io/address/0x5ba1e12693dc8f9c48aad8770482f4739beed696#code) |
| `MathUtils`               | [0xc0409EC303b727Bc1F511d7F8C71FD5Ead96De1c](https://etherscan.io/address/0xc0409EC303b727Bc1F511d7F8C71FD5Ead96De1c#code) |
| `MasterRegistry`          | [0xc5ad17b98D7fe73B6dD3b0df5b3040457E68C045](https://etherscan.io/address/0xc5ad17b98D7fe73B6dD3b0df5b3040457E68C045#code) |
| `PoolRegistry`            | [0xFb4DE84c4375d7c8577327153dE88f58F69EeC81](https://etherscan.io/address/0xFb4DE84c4375d7c8577327153dE88f58F69EeC81#code) |
| `VeSDLRewards`            | [0xc7b10D3B08CEB05d8ff58a3c781225D9a72078Ae](https://etherscan.io/address/0xc7b10D3B08CEB05d8ff58a3c781225D9a72078Ae#code) |

## Arbitrum

### Pools

| Contract Name             | Contract Address                                                                                                          |
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| `USDPool`                 | [0xBea9F78090bDB9e662d8CB301A00ad09A5b756e9](https://arbiscan.io/address/0xBea9F78090bDB9e662d8CB301A00ad09A5b756e9#code) |
| `USDPoolLPToken`          | [0xc969dD0A7AB0F8a0C5A69C0839dB39b6C928bC08](https://arbiscan.io/address/0xc969dD0A7AB0F8a0C5A69C0839dB39b6C928bC08#code) |
| `USDPoolV2`               | [0xfeEa4D1BacB0519E8f952460A70719944fe56Ee0](https://arbiscan.io/address/0xfeEa4D1BacB0519E8f952460A70719944fe56Ee0#code) |
| `USDPoolV2LPToken`        | [0x0a20c2FFa10cD43F67D06170422505b7D6fC0953](https://arbiscan.io/address/0x0a20c2FFa10cD43F67D06170422505b7D6fC0953#code) |
| `USDSMetaPool`            | [0x5dD186f8809147F96D3ffC4508F3C82694E58c9c](https://arbiscan.io/address/0x5dD186f8809147F96D3ffC4508F3C82694E58c9c#code) |
| `USDSMetaPoolDeposit`     | [0xDCA5b16A96f984ffb2A3022cfF339eb049126101](https://arbiscan.io/address/0xDCA5b16A96f984ffb2A3022cfF339eb049126101#code) |
| `USDSMetaPoolLPToken`     | [0xa815b134294580692482E321dD1A191aC1454192](https://arbiscan.io/address/0xa815b134294580692482E321dD1A191aC1454192#code) |
| `FRAXBPPool`              | [0x401AFbc31ad2A3Bc0eD8960d63eFcDEA749b4849](https://arbiscan.io/address/0x401AFbc31ad2A3Bc0eD8960d63eFcDEA749b4849#code) |
| `FRAXBPPoolLPToken`       | [0x896935B02D3cBEb152192774e4F1991bb1D2ED3f](https://arbiscan.io/address/0x896935B02D3cBEb152192774e4F1991bb1D2ED3f#code) |
| `FRAXUSDsMetaPool`        | [0xa5bD85ed9fA27ba23BfB702989e7218E44fd4706](https://arbiscan.io/address/0xa5bD85ed9fA27ba23BfB702989e7218E44fd4706#code) |
| `FRAXUSDsMetaPoolDeposit` | [0x1D434f50acf16BA013BE3536e9A3CDb5D7d4e694](https://arbiscan.io/address/0x1D434f50acf16BA013BE3536e9A3CDb5D7d4e694#code) |
| `FRAXUSDsMetaPoolLPToken` | [0x1e491122f3C096392b40a4EA27aa1a29360d38a1](https://arbiscan.io/address/0x1e491122f3C096392b40a4EA27aa1a29360d38a1#code) |
| `FRAXUSDTMetaPool`        | [0xf8504e92428d65E56e495684A38f679C1B1DC30b](https://arbiscan.io/address/0xf8504e92428d65E56e495684A38f679C1B1DC30b#code) |
| `FRAXUSDTMetaPoolDeposit` | [0xc8DFCFC329E19fDAF43a338aD6038dBA02a5079B](https://arbiscan.io/address/0xc8DFCFC329E19fDAF43a338aD6038dBA02a5079B#code) |
| `FRAXUSDTMetaPoolLPToken` | [0x166680852ae9Dec3d63374c5eBf89E974448BFE9](https://arbiscan.io/address/0x166680852ae9Dec3d63374c5eBf89E974448BFE9#code) |
| `FRAXUSXMetaPool`         | [0xb2a2764D0DCAB445E24f4b813bE3f6ef8AE5f84D](https://arbiscan.io/address/0xb2a2764D0DCAB445E24f4b813bE3f6ef8AE5f84D#code) |
| `FRAXUSXMetaPoolDeposit`  | [0x18d2469A9788FAFD0df277a0044Da5ea637a3760](https://arbiscan.io/address/0x18d2469A9788FAFD0df277a0044Da5ea637a3760#code) |
| `FRAXUSXMetaPoolLPToken`  | [0x721DaC7d5ACc8Aa62946fd583C1F999e1570b97D](https://arbiscan.io/address/0x721DaC7d5ACc8Aa62946fd583C1F999e1570b97D#code) |

### Token

| Contract Name | Contract Address                                                                                                          |
| ------------- | ------------------------------------------------------------------------------------------------------------------------- |
| `MiniChefV2`  | [0x2069043d7556B1207a505eb459D18d908DF29b55](https://arbiscan.io/address/0x2069043d7556B1207a505eb459D18d908DF29b55#code) |
| `SDL`         | [0x75c9bc761d88f70156daf83aa010e84680baf131](https://arbiscan.io/address/0x75c9bc761d88f70156daf83aa010e84680baf131#code) |

### Other

| Contract Name    | Contract Address                                                                                                          |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------- |
| `MasterRegistry` | [0xaB94A2c0D8F044AA439A5654f06b5797928396cF](https://arbiscan.io/address/0xaB94A2c0D8F044AA439A5654f06b5797928396cF#code) |
| `PoolRegistry`   | [0x38262c17a06A6B3588d3E5b70dfa768C06bf4ef1](https://arbiscan.io/address/0x38262c17a06A6B3588d3E5b70dfa768C06bf4ef1#code) |

## Evmos

### Pools

| Contract Name          | Contract Address                                                                                                       |
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `3pool`                | [0x1275203FB58Fc25bC6963B13C2a1ED1541563aF0](https://evm.evmos.org/address/0x1275203FB58Fc25bC6963B13C2a1ED1541563aF0) |
| `3poolLPToken`         | [0x9c673F50CEe126FcC9F7378Ed46c33f5DEDEc0fC](https://evm.evmos.org/address/0x9c673F50CEe126FcC9F7378Ed46c33f5DEDEc0fC) |
| `4Pool`                | [0x81272C5c573919eF0C719D6d63317a4629F161da](https://evm.evmos.org/address/0x81272C5c573919eF0C719D6d63317a4629F161da) |
| `4PoolLPToken`         | [0x9A34c72Bb85f0Da63578aC18047325E2a246f273](https://evm.evmos.org/address/0x9A34c72Bb85f0Da63578aC18047325E2a246f273) |
| `BTCPool`              | [0x7003102c75587E8D29c56124060463Ef319407D0](https://evm.evmos.org/address/0x7003102c75587E8D29c56124060463Ef319407D0) |
| `BTCPoolLPToken`       | [0xa6018520EAACC06C30fF2e1B3ee2c7c22e64196a](https://evm.evmos.org/address/0xa6018520EAACC06C30fF2e1B3ee2c7c22e64196a) |
| `CelarUSDTPool`        | [0x79cb59c7B6bd0e5ef99189efD9065500eAbc1a4b](https://evm.evmos.org/address/0x79cb59c7B6bd0e5ef99189efD9065500eAbc1a4b) |
| `CelarUSDTPoolLPToken` | [0xfd9c6a9cAf5A884C76Ea802A2634Fb914D1Bc022](https://evm.evmos.org/address/0xfd9c6a9cAf5A884C76Ea802A2634Fb914D1Bc022) |
| `Frax3Pool`            | [0x21d4365834B7c61447e142ef6bCf01136cBD01c6](https://evm.evmos.org/address/0x21d4365834B7c61447e142ef6bCf01136cBD01c6) |
| `Frax3PoolLPToken`     | [0x2801fE8f9DE3a4aD6098a5B95d5165676bb01f82](https://evm.evmos.org/address/0x2801fE8f9DE3a4aD6098a5B95d5165676bb01f82) |
| `TBTCMetaPool`         | [0xdb5c5A6162115Ce9a188E7D773C4D011F421BbE5](https://evm.evmos.org/address/0xdb5c5A6162115Ce9a188E7D773C4D011F421BbE5) |
| `TBTCMetaPoolDeposit`  | [0xFdA5D2ad8b6d3884AbB799DA66f57175E8706941](https://evm.evmos.org/address/0xFdA5D2ad8b6d3884AbB799DA66f57175E8706941) |
| `TBTCMetaPoolLPToken`  | [0x21EA072844fd4aBEd72539750c054E009D877f72](https://evm.evmos.org/address/0x21EA072844fd4aBEd72539750c054E009D877f72) |

### Token

| Contract Name | Contract Address                                                                                                       |
| ------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `MiniChefV2`  | [0x0232e0b6df048c8CC4037c52Bc90cf943c9C8cC6](https://evm.evmos.org/address/0x0232e0b6df048c8CC4037c52Bc90cf943c9C8cC6) |
| `SDL`         | [0x3344e55C6DDE2A01F4ED893f97bAC1f99EC24f8B](https://evm.evmos.org/address/0x3344e55C6DDE2A01F4ED893f97bAC1f99EC24f8B) |

### Other

| Contract Name    | Contract Address                                                                                                       |
| ---------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `MasterRegistry` | [0xBa684B8E05415726Ee1fFE197eaf1b82E4d44418](https://evm.evmos.org/address/0xBa684B8E05415726Ee1fFE197eaf1b82E4d44418) |
| `PoolRegistry`   | [0x9c560A6879E4D3a8a88C8f6f39ebf028Ad7860Ab](https://evm.evmos.org/address/0x9c560A6879E4D3a8a88C8f6f39ebf028Ad7860Ab) |

## Fantom

### Pools

| Contract Name              | Contract Address                                                                                                          |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| `FRAXalUSDMetaPool`        | [0x4E1484607760118ebE2Ab07C0c71f1B4D9671e01](https://ftmscan.com/address/0x4E1484607760118ebE2Ab07C0c71f1B4D9671e01#code) |
| `FRAXalUSDMetaPoolDeposit` | [0x0E510c9b20a5D136E75f7FD2a5F344BD98f9d875](https://ftmscan.com/address/0x0E510c9b20a5D136E75f7FD2a5F344BD98f9d875#code) |
| `FRAXalUSDMetaPoolLPToken` | [0xd7D1b50c8ef77d9aB410723f81363C8B252C729F](https://ftmscan.com/address/0xd7D1b50c8ef77d9aB410723f81363C8B252C729F#code) |
| `FRAXUSDTMetaPool`         | [0xdb5c5A6162115Ce9a188E7D773C4D011F421BbE5](https://ftmscan.com/address/0xdb5c5A6162115Ce9a188E7D773C4D011F421BbE5#code) |
| `FRAXUSDTMetaPoolDeposit`  | [0x4A5208F83A17E030a18830521E4064E80728c4FC](https://ftmscan.com/address/0x4A5208F83A17E030a18830521E4064E80728c4FC#code) |
| `FRAXUSDTMetaPoolLPToken`  | [0x21EA072844fd4aBEd72539750c054E009D877f72](https://ftmscan.com/address/0x21EA072844fd4aBEd72539750c054E009D877f72#code) |
| `USDPool`                  | [0xBea9F78090bDB9e662d8CB301A00ad09A5b756e9](https://ftmscan.com/address/0xBea9F78090bDB9e662d8CB301A00ad09A5b756e9#code) |
| `USDPoolLPToken`           | [0xc969dd0a7ab0f8a0c5a69c0839db39b6c928bc08](https://ftmscan.com/address/0xc969dd0a7ab0f8a0c5a69c0839db39b6c928bc08#code) |

## Kava

### Pools

| Contract Name     | Contract Address                                                                                                                    |
| ----------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `3Pool`           | [0xA500b0e1360462eF777804BCAe6CE2BfB524dD2e](https://explorer.kava.io/address/0xA500b0e1360462eF777804BCAe6CE2BfB524dD2e/contracts) |
| `3PoolLPToken`    | [0x619535e015f0e46c5984a0B45FD71C0549F001Fc](https://explorer.kava.io/address/0x619535e015f0e46c5984a0B45FD71C0549F001Fc/contracts) |
| `USDTPool`        | [0x5847f8177221268d279Cf377D0E01aB3FD993628](https://explorer.kava.io/address/0x5847f8177221268d279Cf377D0E01aB3FD993628/contracts) |
| `USDTPoolLPToken` | [0xcCf860874cbF2d615192a4C4455580B4d622D3B9](https://explorer.kava.io/address/0xcCf860874cbF2d615192a4C4455580B4d622D3B9/contracts) |

## Optimism

### Pools

| Contract Name             | Contract Address                                                                                                                      |
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `FRAXBP`                  | [0xF6C2e0aDc659007Ba7c48446F5A4e4E94dfe08b5](https://optimistic.etherscan.io/address/0xF6C2e0aDc659007Ba7c48446F5A4e4E94dfe08b5#code) |
| `FRAXBPLPToken`           | [0xf74ebe6e5586275dc4CeD78F5DBEF31B1EfbE7a5](https://optimistic.etherscan.io/address/0xf74ebe6e5586275dc4CeD78F5DBEF31B1EfbE7a5#code) |
| `FRAXsUSDMetaPool`        | [0x250184dDDEC6d38E28ac12B481c9016867226E9D](https://optimistic.etherscan.io/address/0x250184dDDEC6d38E28ac12B481c9016867226E9D#code) |
| `FRAXsUSDMetaPoolDeposit` | [0xdf815Ea6b066Ac9f3107d8863a6c19aA2a5d24d3](https://optimistic.etherscan.io/address/0xdf815Ea6b066Ac9f3107d8863a6c19aA2a5d24d3#code) |
| `FRAXsUSDMetaPoolLPToken` | [0x205c9B8c1fCa803B779b1eB4B887Aa0E00FE629F](https://optimistic.etherscan.io/address/0x205c9B8c1fCa803B779b1eB4B887Aa0E00FE629F#code) |
| `FRAXUSDTMetaPool`        | [0xa9a84238098Dc3d1529228E6c74dBE7EbdF117a5](https://optimistic.etherscan.io/address/0xa9a84238098Dc3d1529228E6c74dBE7EbdF117a5#code) |
| `FRAXUSDTMetaPoolDeposit` | [0x3F1d224557afA4365155ea77cE4BC32D5Dae2174](https://optimistic.etherscan.io/address/0x3F1d224557afA4365155ea77cE4BC32D5Dae2174#code) |
| `FRAXUSDTMetaPoolLPToken` | [0xb63d7B0D835ca6eFf89ab774498ed6dD0D71e93e](https://optimistic.etherscan.io/address/0xb63d7B0D835ca6eFf89ab774498ed6dD0D71e93e#code) |
| `FRAXUSXMetaPool`         | [0xe184F7E575a5Beb8f2409E8e2218Cd770ddDa2A6](https://optimistic.etherscan.io/address/0xe184F7E575a5Beb8f2409E8e2218Cd770ddDa2A6#code) |
| `FRAXUSXMetaPoolDeposit`  | [0xB10Ac31a6e613c6fcB5522c19f4bdBCFFa94f89d](https://optimistic.etherscan.io/address/0xB10Ac31a6e613c6fcB5522c19f4bdBCFFa94f89d#code) |
| `FRAXUSXMetaPoolLPToken`  | [0xf349fB2b5eD45864e1d9ad34a483Eb37aC6e0034](https://optimistic.etherscan.io/address/0xf349fB2b5eD45864e1d9ad34a483Eb37aC6e0034#code) |
| `FRAXMetaPool`            | [0xc55E8C79e5A6c3216D4023769559D06fa9A7732e](https://optimistic.etherscan.io/address/0xc55E8C79e5A6c3216D4023769559D06fa9A7732e#code) |
| `FRAXMetaPoolDeposit`     | [0x88Cc4aA0dd6Cf126b00C012dDa9f6F4fd9388b17](https://optimistic.etherscan.io/address/0x88Cc4aA0dd6Cf126b00C012dDa9f6F4fd9388b17#code) |
| `FRAXMetaPoolLPToken`     | [0xfF5fa61Eb9b5cDD63bdFa16EF029d5313457925A](https://optimistic.etherscan.io/address/0xfF5fa61Eb9b5cDD63bdFa16EF029d5313457925A#code) |
| `USDPool`                 | [0x5847f8177221268d279Cf377D0E01aB3FD993628](https://optimistic.etherscan.io/address/0x5847f8177221268d279Cf377D0E01aB3FD993628#code) |
| `USDPoolLPToken`          | [0xcCf860874cbF2d615192a4C4455580B4d622D3B9](https://optimistic.etherscan.io/address/0xcCf860874cbF2d615192a4C4455580B4d622D3B9#code) |

### Token

| Contract Name | Contract Address                                                                                                                      |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `MiniChefV2`  | [0x220d6bEedeA6a6317DaE19d39cd62EB7bb0ae5e4](https://optimistic.etherscan.io/address/0x220d6bEedeA6a6317DaE19d39cd62EB7bb0ae5e4#code) |
| `SDL`         | [0xae31207ac34423c41576ff59bfb4e036150f9cf7](https://optimistic.etherscan.io/address/0xae31207ac34423c41576ff59bfb4e036150f9cf7#code) |

### Other

| Contract Name    | Contract Address                                                                                                                      |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `MasterRegistry` | [0x0E510c9b20a5D136E75f7FD2a5F344BD98f9d875](https://optimistic.etherscan.io/address/0x0E510c9b20a5D136E75f7FD2a5F344BD98f9d875#code) |
| `PoolRegistry`   | [0x4E1484607760118ebE2Ab07C0c71f1B4D9671e01](https://optimistic.etherscan.io/address/0x4E1484607760118ebE2Ab07C0c71f1B4D9671e01#code) |


# Solidity Docs


# StakeableTokenWrapper

A wrapper for an ERC-20 that can be staked and withdrawn.

In this contract, staked tokens don't do anything- instead other contracts can inherit from this one to add functionality. / c

## Functions:

* [`constructor(contract IERC20 _stakedToken)`](#StakeableTokenWrapper-constructor-contract-IERC20-)
* [`balanceOf(address account)`](#StakeableTokenWrapper-balanceOf-address-)
* [`stake(uint256 amount)`](#StakeableTokenWrapper-stake-uint256-)
* [`withdraw(uint256 amount)`](#StakeableTokenWrapper-withdraw-uint256-)

## Events:

* [`Staked(address user, uint256 amount)`](#StakeableTokenWrapper-Staked-address-uint256-)
* [`Withdrawn(address user, uint256 amount)`](#StakeableTokenWrapper-Withdrawn-address-uint256-)

## Function `constructor(contract IERC20 _stakedToken)` <a href="#stakeabletokenwrapper-constructor-contract-ierc20" id="stakeabletokenwrapper-constructor-contract-ierc20"></a>

Creates a new StakeableTokenWrapper with given `_stakedToken` address

### Parameters:

* `_stakedToken`: address of a token that will be used to stake /

## Function `balanceOf(address account) → uint256` <a href="#stakeabletokenwrapper-balanceof-address" id="stakeabletokenwrapper-balanceof-address"></a>

Read how much `account` has staked in this contract

### Parameters:

* `account`: address of an account

### Return Values:

* amount of total staked ERC20(this.stakedToken) by `account` /

## Function `stake(uint256 amount)` <a href="#stakeabletokenwrapper-stake-uint256" id="stakeabletokenwrapper-stake-uint256"></a>

Stakes given `amount` in this contract

### Parameters:

* `amount`: amount of ERC20(this.stakedToken) to stake /

## Function `withdraw(uint256 amount)` <a href="#stakeabletokenwrapper-withdraw-uint256" id="stakeabletokenwrapper-withdraw-uint256"></a>

Withdraws given `amount` from this contract

### Parameters:

* `amount`: amount of ERC20(this.stakedToken) to withdraw /

## Event `Staked(address user, uint256 amount)` <a href="#stakeabletokenwrapper-staked-address-uint256" id="stakeabletokenwrapper-staked-address-uint256"></a>

No description

## Event `Withdrawn(address user, uint256 amount)` <a href="#stakeabletokenwrapper-withdrawn-address-uint256" id="stakeabletokenwrapper-withdrawn-address-uint256"></a>

No description


# MathUtils

A library to be used in conjunction with SafeMath. Contains functions for calculating differences between two uint256.

## Functions:


# Swap

This contract is responsible for custody of closely pegged assets (eg. group of stablecoins) and automatic market making system. Users become an LP (Liquidity Provider) by depositing their tokens in desired ratios for an exchange of the pool token that represents their share of the pool. Users can burn pool tokens and withdraw their share of token(s).

Each time a swap between the pooled tokens happens, a set fee incurs which effectively gets distributed to the LPs.

In case of emergencies, admin can pause additional deposits, swaps, or single-asset withdraws - which stops the ratio of the tokens in the pool from changing. Users can always withdraw their tokens via multi-asset withdraws.

Most of the logic is stored as a library `SwapUtils` for the sake of reducing contract's deployment size.

## Functions:

* [`initialize(contract IERC20[] _pooledTokens, uint8[] decimals, string lpTokenName, string lpTokenSymbol, uint256 _a, uint256 _fee, uint256 _adminFee, address lpTokenTargetAddress)`](#Swap-initialize-contract-IERC20---uint8---string-string-uint256-uint256-uint256-address-)
* [`getA()`](#Swap-getA--)
* [`getAPrecise()`](#Swap-getAPrecise--)
* [`getToken(uint8 index)`](#Swap-getToken-uint8-)
* [`getTokenIndex(address tokenAddress)`](#Swap-getTokenIndex-address-)
* [`getTokenBalance(uint8 index)`](#Swap-getTokenBalance-uint8-)
* [`getVirtualPrice()`](#Swap-getVirtualPrice--)
* [`calculateSwap(uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx)`](#Swap-calculateSwap-uint8-uint8-uint256-)
* [`calculateTokenAmount(uint256[] amounts, bool deposit)`](#Swap-calculateTokenAmount-uint256---bool-)
* [`calculateRemoveLiquidity(uint256 amount)`](#Swap-calculateRemoveLiquidity-uint256-)
* [`calculateRemoveLiquidityOneToken(uint256 tokenAmount, uint8 tokenIndex)`](#Swap-calculateRemoveLiquidityOneToken-uint256-uint8-)
* [`getAdminBalance(uint256 index)`](#Swap-getAdminBalance-uint256-)
* [`swap(uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx, uint256 minDy, uint256 deadline)`](#Swap-swap-uint8-uint8-uint256-uint256-uint256-)
* [`addLiquidity(uint256[] amounts, uint256 minToMint, uint256 deadline)`](#Swap-addLiquidity-uint256---uint256-uint256-)
* [`removeLiquidity(uint256 amount, uint256[] minAmounts, uint256 deadline)`](#Swap-removeLiquidity-uint256-uint256---uint256-)
* [`removeLiquidityOneToken(uint256 tokenAmount, uint8 tokenIndex, uint256 minAmount, uint256 deadline)`](#Swap-removeLiquidityOneToken-uint256-uint8-uint256-uint256-)
* [`removeLiquidityImbalance(uint256[] amounts, uint256 maxBurnAmount, uint256 deadline)`](#Swap-removeLiquidityImbalance-uint256---uint256-uint256-)
* [`withdrawAdminFees()`](#Swap-withdrawAdminFees--)
* [`setAdminFee(uint256 newAdminFee)`](#Swap-setAdminFee-uint256-)
* [`setSwapFee(uint256 newSwapFee)`](#Swap-setSwapFee-uint256-)
* [`rampA(uint256 futureA, uint256 futureTime)`](#Swap-rampA-uint256-uint256-)
* [`stopRampA()`](#Swap-stopRampA--)

## Events:

* [`TokenSwap(address buyer, uint256 tokensSold, uint256 tokensBought, uint128 soldId, uint128 boughtId)`](#Swap-TokenSwap-address-uint256-uint256-uint128-uint128-)
* [`AddLiquidity(address provider, uint256[] tokenAmounts, uint256[] fees, uint256 invariant, uint256 lpTokenSupply)`](#Swap-AddLiquidity-address-uint256---uint256---uint256-uint256-)
* [`RemoveLiquidity(address provider, uint256[] tokenAmounts, uint256 lpTokenSupply)`](#Swap-RemoveLiquidity-address-uint256---uint256-)
* [`RemoveLiquidityOne(address provider, uint256 lpTokenAmount, uint256 lpTokenSupply, uint256 boughtId, uint256 tokensBought)`](#Swap-RemoveLiquidityOne-address-uint256-uint256-uint256-uint256-)
* [`RemoveLiquidityImbalance(address provider, uint256[] tokenAmounts, uint256[] fees, uint256 invariant, uint256 lpTokenSupply)`](#Swap-RemoveLiquidityImbalance-address-uint256---uint256---uint256-uint256-)
* [`NewAdminFee(uint256 newAdminFee)`](#Swap-NewAdminFee-uint256-)
* [`NewSwapFee(uint256 newSwapFee)`](#Swap-NewSwapFee-uint256-)
* [`NewWithdrawFee(uint256 newWithdrawFee)`](#Swap-NewWithdrawFee-uint256-)
* [`RampA(uint256 oldA, uint256 newA, uint256 initialTime, uint256 futureTime)`](#Swap-RampA-uint256-uint256-uint256-uint256-)
* [`StopRampA(uint256 currentA, uint256 time)`](#Swap-StopRampA-uint256-uint256-)

## Function `initialize(contract IERC20[] _pooledTokens, uint8[] decimals, string lpTokenName, string lpTokenSymbol, uint256 _a, uint256 _fee, uint256 _adminFee, address lpTokenTargetAddress)` <a href="#swap-initialize-contract-ierc20-uint8-string-string-uint256-uint256-uint256-address" id="swap-initialize-contract-ierc20-uint8-string-string-uint256-uint256-uint256-address"></a>

Initializes this Swap contract with the given parameters. This will also clone a LPToken contract that represents users' LP positions. The owner of LPToken will be this contract - which means only this contract is allowed to mint/burn tokens.

### Parameters:

* `_pooledTokens`: an array of ERC20s this pool will accept
* `decimals`: the decimals to use for each pooled token, eg 8 for WBTC. Cannot be larger than POOL\_PRECISION\_DECIMALS
* `lpTokenName`: the long-form name of the token to be deployed
* `lpTokenSymbol`: the short symbol for the token to be deployed
* `_a`: the amplification coefficient \_ n \_ (n - 1). See the StableSwap paper for details
* `_fee`: default swap fee to be initialized with
* `_adminFee`: default adminFee to be initialized with
* `lpTokenTargetAddress`: the address of an existing LPToken contract to use as a target

## Function `getA() → uint256` <a href="#swap-geta" id="swap-geta"></a>

Return A, the amplification coefficient \_ n \_ (n - 1)

See the StableSwap paper for details

### Return Values:

* A parameter

## Function `getAPrecise() → uint256` <a href="#swap-getaprecise" id="swap-getaprecise"></a>

Return A in its raw precision form

See the StableSwap paper for details

### Return Values:

* A parameter in its raw precision form

## Function `getToken(uint8 index) → contract IERC20` <a href="#swap-gettoken-uint8" id="swap-gettoken-uint8"></a>

Return address of the pooled token at given index. Reverts if tokenIndex is out of range.

### Parameters:

* `index`: the index of the token

### Return Values:

* address of the token at given index

## Function `getTokenIndex(address tokenAddress) → uint8` <a href="#swap-gettokenindex-address" id="swap-gettokenindex-address"></a>

Return the index of the given token address. Reverts if no matching token is found.

### Parameters:

* `tokenAddress`: address of the token

### Return Values:

* the index of the given token address

## Function `getTokenBalance(uint8 index) → uint256` <a href="#swap-gettokenbalance-uint8" id="swap-gettokenbalance-uint8"></a>

Return current balance of the pooled token at given index

### Parameters:

* `index`: the index of the token

### Return Values:

* current balance of the pooled token at given index with token's native precision

## Function `getVirtualPrice() → uint256` <a href="#swap-getvirtualprice" id="swap-getvirtualprice"></a>

Get the virtual price, to help calculate profit

### Return Values:

* the virtual price, scaled to the POOL\_PRECISION\_DECIMALS

## Function `calculateSwap(uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx) → uint256` <a href="#swap-calculateswap-uint8-uint8-uint256" id="swap-calculateswap-uint8-uint8-uint256"></a>

Calculate amount of tokens you receive on swap

### Parameters:

* `tokenIndexFrom`: the token the user wants to sell
* `tokenIndexTo`: the token the user wants to buy
* `dx`: the amount of tokens the user wants to sell. If the token charges a fee on transfers, use the amount that gets transferred after the fee.

### Return Values:

* amount of tokens the user will receive

## Function `calculateTokenAmount(uint256[] amounts, bool deposit) → uint256` <a href="#swap-calculatetokenamount-uint256-bool" id="swap-calculatetokenamount-uint256-bool"></a>

A simple method to calculate prices from deposits or withdrawals, excluding fees but including slippage. This is helpful as an input into the various "min" parameters on calls to fight front-running

This shouldn't be used outside frontends for user estimates.

### Parameters:

* `amounts`: an array of token amounts to deposit or withdrawal, corresponding to pooledTokens. The amount should be in each pooled token's native precision. If a token charges a fee on transfers, use the amount that gets transferred after the fee.
* `deposit`: whether this is a deposit or a withdrawal

### Return Values:

* token amount the user will receive

## Function `calculateRemoveLiquidity(uint256 amount) → uint256[]` <a href="#swap-calculateremoveliquidity-uint256" id="swap-calculateremoveliquidity-uint256"></a>

A simple method to calculate amount of each underlying tokens that is returned upon burning given amount of LP tokens

### Parameters:

* `amount`: the amount of LP tokens that would be burned on withdrawal

### Return Values:

* array of token balances that the user will receive

## Function `calculateRemoveLiquidityOneToken(uint256 tokenAmount, uint8 tokenIndex) → uint256 availableTokenAmount` <a href="#swap-calculateremoveliquidityonetoken-uint256-uint8" id="swap-calculateremoveliquidityonetoken-uint256-uint8"></a>

Calculate the amount of underlying token available to withdraw when withdrawing via only single token

### Parameters:

* `tokenAmount`: the amount of LP token to burn
* `tokenIndex`: index of which token will be withdrawn

### Return Values:

* availableTokenAmount calculated amount of underlying token available to withdraw

## Function `getAdminBalance(uint256 index) → uint256` <a href="#swap-getadminbalance-uint256" id="swap-getadminbalance-uint256"></a>

This function reads the accumulated amount of admin fees of the token with given index

### Parameters:

* `index`: Index of the pooled token

### Return Values:

* s token balance in the token's precision

## Function `swap(uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx, uint256 minDy, uint256 deadline) → uint256` <a href="#swap-swap-uint8-uint8-uint256-uint256-uint256" id="swap-swap-uint8-uint8-uint256-uint256-uint256"></a>

Swap two tokens using this pool

### Parameters:

* `tokenIndexFrom`: the token the user wants to swap from
* `tokenIndexTo`: the token the user wants to swap to
* `dx`: the amount of tokens the user wants to swap from
* `minDy`: the min amount the user would like to receive, or revert.
* `deadline`: latest timestamp to accept this transaction

## Function `addLiquidity(uint256[] amounts, uint256 minToMint, uint256 deadline) → uint256` <a href="#swap-addliquidity-uint256-uint256-uint256" id="swap-addliquidity-uint256-uint256-uint256"></a>

Add liquidity to the pool with the given amounts of tokens

### Parameters:

* `amounts`: the amounts of each token to add, in their native precision
* `minToMint`: the minimum LP tokens adding this amount of liquidity should mint, otherwise revert. Handy for front-running mitigation
* `deadline`: latest timestamp to accept this transaction

### Return Values:

* amount of LP token user minted and received

## Function `removeLiquidity(uint256 amount, uint256[] minAmounts, uint256 deadline) → uint256[]` <a href="#swap-removeliquidity-uint256-uint256-uint256" id="swap-removeliquidity-uint256-uint256-uint256"></a>

Burn LP tokens to remove liquidity from the pool. Withdraw fee that decays linearly over period of 4 weeks since last deposit will apply.

Liquidity can always be removed, even when the pool is paused.

### Parameters:

* `amount`: the amount of LP tokens to burn
* `minAmounts`: the minimum amounts of each token in the pool acceptable for this burn. Useful as a front-running mitigation
* `deadline`: latest timestamp to accept this transaction

### Return Values:

* amounts of tokens user received

## Function `removeLiquidityOneToken(uint256 tokenAmount, uint8 tokenIndex, uint256 minAmount, uint256 deadline) → uint256` <a href="#swap-removeliquidityonetoken-uint256-uint8-uint256-uint256" id="swap-removeliquidityonetoken-uint256-uint8-uint256-uint256"></a>

Remove liquidity from the pool all in one token. Withdraw fee that decays linearly over period of 4 weeks since last deposit will apply.

### Parameters:

* `tokenAmount`: the amount of the token you want to receive
* `tokenIndex`: the index of the token you want to receive
* `minAmount`: the minimum amount to withdraw, otherwise revert
* `deadline`: latest timestamp to accept this transaction

### Return Values:

* amount of chosen token user received

## Function `removeLiquidityImbalance(uint256[] amounts, uint256 maxBurnAmount, uint256 deadline) → uint256` <a href="#swap-removeliquidityimbalance-uint256-uint256-uint256" id="swap-removeliquidityimbalance-uint256-uint256-uint256"></a>

Remove liquidity from the pool, weighted differently than the pool's current balances. Withdraw fee that decays linearly over period of 4 weeks since last deposit will apply.

### Parameters:

* `amounts`: how much of each token to withdraw
* `maxBurnAmount`: the max LP token provider is willing to pay to remove liquidity. Useful as a front-running mitigation.
* `deadline`: latest timestamp to accept this transaction

### Return Values:

* amount of LP tokens burned

## Function `withdrawAdminFees()` <a href="#swap-withdrawadminfees" id="swap-withdrawadminfees"></a>

Withdraw all admin fees to the contract owner

## Function `setAdminFee(uint256 newAdminFee)` <a href="#swap-setadminfee-uint256" id="swap-setadminfee-uint256"></a>

Update the admin fee. Admin fee takes portion of the swap fee.

### Parameters:

* `newAdminFee`: new admin fee to be applied on future transactions

## Function `setSwapFee(uint256 newSwapFee)` <a href="#swap-setswapfee-uint256" id="swap-setswapfee-uint256"></a>

Update the swap fee to be applied on swaps

### Parameters:

* `newSwapFee`: new swap fee to be applied on future transactions

## Function `rampA(uint256 futureA, uint256 futureTime)` <a href="#swap-rampa-uint256-uint256" id="swap-rampa-uint256-uint256"></a>

Start ramping up or down A parameter towards given futureA and futureTime Checks if the change is too rapid, and commits the new A value only when it falls under the limit range.

### Parameters:

* `futureA`: the new A to ramp towards
* `futureTime`: timestamp when the new A should be reached

## Function `stopRampA()` <a href="#swap-stoprampa" id="swap-stoprampa"></a>

Stop ramping A immediately. Reverts if ramp A is already stopped.

## Event `TokenSwap(address buyer, uint256 tokensSold, uint256 tokensBought, uint128 soldId, uint128 boughtId)` <a href="#swap-tokenswap-address-uint256-uint256-uint128-uint128" id="swap-tokenswap-address-uint256-uint256-uint128-uint128"></a>

No description

## Event `AddLiquidity(address provider, uint256[] tokenAmounts, uint256[] fees, uint256 invariant, uint256 lpTokenSupply)` <a href="#swap-addliquidity-address-uint256-uint256-uint256-uint256" id="swap-addliquidity-address-uint256-uint256-uint256-uint256"></a>

No description

## Event `RemoveLiquidity(address provider, uint256[] tokenAmounts, uint256 lpTokenSupply)` <a href="#swap-removeliquidity-address-uint256-uint256" id="swap-removeliquidity-address-uint256-uint256"></a>

No description

## Event `RemoveLiquidityOne(address provider, uint256 lpTokenAmount, uint256 lpTokenSupply, uint256 boughtId, uint256 tokensBought)` <a href="#swap-removeliquidityone-address-uint256-uint256-uint256-uint256" id="swap-removeliquidityone-address-uint256-uint256-uint256-uint256"></a>

No description

## Event `RemoveLiquidityImbalance(address provider, uint256[] tokenAmounts, uint256[] fees, uint256 invariant, uint256 lpTokenSupply)` <a href="#swap-removeliquidityimbalance-address-uint256-uint256-uint256-uint256" id="swap-removeliquidityimbalance-address-uint256-uint256-uint256-uint256"></a>

No description

## Event `NewAdminFee(uint256 newAdminFee)` <a href="#swap-newadminfee-uint256" id="swap-newadminfee-uint256"></a>

No description

## Event `NewSwapFee(uint256 newSwapFee)` <a href="#swap-newswapfee-uint256" id="swap-newswapfee-uint256"></a>

No description

## Event `NewWithdrawFee(uint256 newWithdrawFee)` <a href="#swap-newwithdrawfee-uint256" id="swap-newwithdrawfee-uint256"></a>

No description

## Event `RampA(uint256 oldA, uint256 newA, uint256 initialTime, uint256 futureTime)` <a href="#swap-rampa-uint256-uint256-uint256-uint256" id="swap-rampa-uint256-uint256-uint256-uint256"></a>

No description

## Event `StopRampA(uint256 currentA, uint256 time)` <a href="#swap-stoprampa-uint256-uint256" id="swap-stoprampa-uint256-uint256"></a>

No description


# Allowlist

This contract is a registry holding information about how much each swap contract should contain upto. Swap.sol will rely on this contract to determine whether the pool cap is reached and also whether a user's deposit limit is reached.

## Functions:

* [`constructor(bytes32 merkleRoot_)`](#Allowlist-constructor-bytes32-)
* [`getPoolAccountLimit(address poolAddress)`](#Allowlist-getPoolAccountLimit-address-)
* [`getPoolCap(address poolAddress)`](#Allowlist-getPoolCap-address-)
* [`isAccountVerified(address account)`](#Allowlist-isAccountVerified-address-)
* [`verifyAddress(address account, bytes32[] merkleProof)`](#Allowlist-verifyAddress-address-bytes32---)
* [`setPoolAccountLimit(address poolAddress, uint256 accountLimit)`](#Allowlist-setPoolAccountLimit-address-uint256-)
* [`setPoolCap(address poolAddress, uint256 poolCap)`](#Allowlist-setPoolCap-address-uint256-)
* [`updateMerkleRoot(bytes32 merkleRoot_)`](#Allowlist-updateMerkleRoot-bytes32-)

## Events:

* [`PoolCap(address poolAddress, uint256 poolCap)`](#Allowlist-PoolCap-address-uint256-)
* [`PoolAccountLimit(address poolAddress, uint256 accountLimit)`](#Allowlist-PoolAccountLimit-address-uint256-)
* [`NewMerkleRoot(bytes32 merkleRoot)`](#Allowlist-NewMerkleRoot-bytes32-)

## Function `constructor(bytes32 merkleRoot_)` <a href="#allowlist-constructor-bytes32" id="allowlist-constructor-bytes32"></a>

Creates this contract and sets the PoolCap of 0x0 with uint256(0x54dd1e) for crude checking whether an address holds this contract.

### Parameters:

* `merkleRoot_`: bytes32 that represent a merkle root node. This is generated off chain with the list of qualifying addresses.

## Function `getPoolAccountLimit(address poolAddress) → uint256` <a href="#allowlist-getpoolaccountlimit-address" id="allowlist-getpoolaccountlimit-address"></a>

Returns the max mintable amount of the lp token per account in given pool address.

### Parameters:

* `poolAddress`: address of the pool

### Return Values:

* max mintable amount of the lp token per account

## Function `getPoolCap(address poolAddress) → uint256` <a href="#allowlist-getpoolcap-address" id="allowlist-getpoolcap-address"></a>

Returns the maximum total supply of the pool token for the given pool address.

### Parameters:

* `poolAddress`: address of the pool

## Function `isAccountVerified(address account) → bool` <a href="#allowlist-isaccountverified-address" id="allowlist-isaccountverified-address"></a>

Returns true if the given account's existence has been verified against any of the past or the present merkle tree. Note that if it has been verified in the past, this function will return true even if the current merkle tree does not contain the account.

### Parameters:

* `account`: the address to check if it has been verified

### Return Values:

* a boolean value representing whether the account has been verified in the past or the present merkle tree

## Function `verifyAddress(address account, bytes32[] merkleProof) → bool` <a href="#allowlist-verifyaddress-address-bytes32" id="allowlist-verifyaddress-address-bytes32"></a>

Checks the existence of keccak256(account) as a node in the merkle tree inferred by the merkle root node stored in this contract. Pools should use this function to check if the given address qualifies for depositing. If the given account has already been verified with the correct merkleProof, this function will return true when merkleProof is empty. The verified status will be overwritten if the previously verified user calls this function with an incorrect merkleProof.

### Parameters:

* `account`: address to confirm its existence in the merkle tree
* `merkleProof`: data that is used to prove the existence of given parameters. This is generated during the creation of the merkle tree. Users should retrieve this data off-chain.

### Return Values:

* a boolean value that corresponds to whether the address with the proof has been verified in the past or if they exist in the current merkle tree.

## Function `setPoolAccountLimit(address poolAddress, uint256 accountLimit)` <a href="#allowlist-setpoolaccountlimit-address-uint256" id="allowlist-setpoolaccountlimit-address-uint256"></a>

Sets the account limit of allowed deposit amounts for the given pool

### Parameters:

* `poolAddress`: address of the pool
* `accountLimit`: the max number of the pool token a single user can mint

## Function `setPoolCap(address poolAddress, uint256 poolCap)` <a href="#allowlist-setpoolcap-address-uint256" id="allowlist-setpoolcap-address-uint256"></a>

Sets the max total supply of LPToken for the given pool address

### Parameters:

* `poolAddress`: address of the pool
* `poolCap`: the max total supply of the pool token

## Function `updateMerkleRoot(bytes32 merkleRoot_)` <a href="#allowlist-updatemerkleroot-bytes32" id="allowlist-updatemerkleroot-bytes32"></a>

Updates the merkle root that is stored in this contract. This can only be called by the owner. If more addresses are added to the list, a new merkle tree and a merkle root node should be generated, and merkleRoot should be updated accordingly.

### Parameters:

* `merkleRoot_`: a new merkle root node that contains a list of deposit allowed addresses

## Event `PoolCap(address poolAddress, uint256 poolCap)` <a href="#allowlist-poolcap-address-uint256" id="allowlist-poolcap-address-uint256"></a>

No description

## Event `PoolAccountLimit(address poolAddress, uint256 accountLimit)` <a href="#allowlist-poolaccountlimit-address-uint256" id="allowlist-poolaccountlimit-address-uint256"></a>

No description

## Event `NewMerkleRoot(bytes32 merkleRoot)` <a href="#allowlist-newmerkleroot-bytes32" id="allowlist-newmerkleroot-bytes32"></a>

No description


# SwapUtils

A library to be used within Swap.sol. Contains functions responsible for custody and AMM functionalities.

Contracts relying on this library must initialize SwapUtils.Swap struct then use this library for SwapUtils.Swap struct. Note that this library contains both functions called by users and admins. Admin functions should be protected within contracts using this library.

## Functions:

* [`calculateWithdrawOneToken(struct SwapUtils.Swap self, uint256 tokenAmount, uint8 tokenIndex)`](#SwapUtils-calculateWithdrawOneToken-struct-SwapUtils-Swap-uint256-uint8-)
* [`getVirtualPrice(struct SwapUtils.Swap self)`](#SwapUtils-getVirtualPrice-struct-SwapUtils-Swap-)
* [`calculateSwap(struct SwapUtils.Swap self, uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx)`](#SwapUtils-calculateSwap-struct-SwapUtils-Swap-uint8-uint8-uint256-)
* [`calculateRemoveLiquidity(struct SwapUtils.Swap self, uint256 amount)`](#SwapUtils-calculateRemoveLiquidity-struct-SwapUtils-Swap-uint256-)
* [`calculateTokenAmount(struct SwapUtils.Swap self, uint256[] amounts, bool deposit)`](#SwapUtils-calculateTokenAmount-struct-SwapUtils-Swap-uint256---bool-)
* [`getAdminBalance(struct SwapUtils.Swap self, uint256 index)`](#SwapUtils-getAdminBalance-struct-SwapUtils-Swap-uint256-)
* [`swap(struct SwapUtils.Swap self, uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx, uint256 minDy)`](#SwapUtils-swap-struct-SwapUtils-Swap-uint8-uint8-uint256-uint256-)
* [`addLiquidity(struct SwapUtils.Swap self, uint256[] amounts, uint256 minToMint)`](#SwapUtils-addLiquidity-struct-SwapUtils-Swap-uint256---uint256-)
* [`removeLiquidity(struct SwapUtils.Swap self, uint256 amount, uint256[] minAmounts)`](#SwapUtils-removeLiquidity-struct-SwapUtils-Swap-uint256-uint256---)
* [`removeLiquidityOneToken(struct SwapUtils.Swap self, uint256 tokenAmount, uint8 tokenIndex, uint256 minAmount)`](#SwapUtils-removeLiquidityOneToken-struct-SwapUtils-Swap-uint256-uint8-uint256-)
* [`removeLiquidityImbalance(struct SwapUtils.Swap self, uint256[] amounts, uint256 maxBurnAmount)`](#SwapUtils-removeLiquidityImbalance-struct-SwapUtils-Swap-uint256---uint256-)
* [`withdrawAdminFees(struct SwapUtils.Swap self, address to)`](#SwapUtils-withdrawAdminFees-struct-SwapUtils-Swap-address-)
* [`setAdminFee(struct SwapUtils.Swap self, uint256 newAdminFee)`](#SwapUtils-setAdminFee-struct-SwapUtils-Swap-uint256-)
* [`setSwapFee(struct SwapUtils.Swap self, uint256 newSwapFee)`](#SwapUtils-setSwapFee-struct-SwapUtils-Swap-uint256-)

## Events:

* [`TokenSwap(address buyer, uint256 tokensSold, uint256 tokensBought, uint128 soldId, uint128 boughtId)`](#SwapUtils-TokenSwap-address-uint256-uint256-uint128-uint128-)
* [`AddLiquidity(address provider, uint256[] tokenAmounts, uint256[] fees, uint256 invariant, uint256 lpTokenSupply)`](#SwapUtils-AddLiquidity-address-uint256---uint256---uint256-uint256-)
* [`RemoveLiquidity(address provider, uint256[] tokenAmounts, uint256 lpTokenSupply)`](#SwapUtils-RemoveLiquidity-address-uint256---uint256-)
* [`RemoveLiquidityOne(address provider, uint256 lpTokenAmount, uint256 lpTokenSupply, uint256 boughtId, uint256 tokensBought)`](#SwapUtils-RemoveLiquidityOne-address-uint256-uint256-uint256-uint256-)
* [`RemoveLiquidityImbalance(address provider, uint256[] tokenAmounts, uint256[] fees, uint256 invariant, uint256 lpTokenSupply)`](#SwapUtils-RemoveLiquidityImbalance-address-uint256---uint256---uint256-uint256-)
* [`NewAdminFee(uint256 newAdminFee)`](#SwapUtils-NewAdminFee-uint256-)
* [`NewSwapFee(uint256 newSwapFee)`](#SwapUtils-NewSwapFee-uint256-)

## Function `calculateWithdrawOneToken(struct SwapUtils.Swap self, uint256 tokenAmount, uint8 tokenIndex) → uint256` <a href="#swaputils-calculatewithdrawonetoken-struct-swaputils-swap-uint256-uint8" id="swaputils-calculatewithdrawonetoken-struct-swaputils-swap-uint256-uint8"></a>

Calculate the dy, the amount of selected token that user receives and the fee of withdrawing in one token

### Parameters:

* `tokenAmount`: the amount to withdraw in the pool's precision
* `tokenIndex`: which token will be withdrawn
* `self`: Swap struct to read from

### Return Values:

* the amount of token user will receive

## Function `getVirtualPrice(struct SwapUtils.Swap self) → uint256` <a href="#swaputils-getvirtualprice-struct-swaputils-swap" id="swaputils-getvirtualprice-struct-swaputils-swap"></a>

Get the virtual price, to help calculate profit

### Parameters:

* `self`: Swap struct to read from

### Return Values:

* the virtual price, scaled to precision of POOL\_PRECISION\_DECIMALS

## Function `calculateSwap(struct SwapUtils.Swap self, uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx) → uint256 dy` <a href="#swaputils-calculateswap-struct-swaputils-swap-uint8-uint8-uint256" id="swaputils-calculateswap-struct-swaputils-swap-uint8-uint8-uint256"></a>

Externally calculates a swap between two tokens.

### Parameters:

* `self`: Swap struct to read from
* `tokenIndexFrom`: the token to sell
* `tokenIndexTo`: the token to buy
* `dx`: the number of tokens to sell. If the token charges a fee on transfers, use the amount that gets transferred after the fee.

### Return Values:

* dy the number of tokens the user will get

## Function `calculateRemoveLiquidity(struct SwapUtils.Swap self, uint256 amount) → uint256[]` <a href="#swaputils-calculateremoveliquidity-struct-swaputils-swap-uint256" id="swaputils-calculateremoveliquidity-struct-swaputils-swap-uint256"></a>

A simple method to calculate amount of each underlying tokens that is returned upon burning given amount of LP tokens

### Parameters:

* `amount`: the amount of LP tokens that would to be burned on withdrawal

### Return Values:

* array of amounts of tokens user will receive

## Function `calculateTokenAmount(struct SwapUtils.Swap self, uint256[] amounts, bool deposit) → uint256` <a href="#swaputils-calculatetokenamount-struct-swaputils-swap-uint256-bool" id="swaputils-calculatetokenamount-struct-swaputils-swap-uint256-bool"></a>

A simple method to calculate prices from deposits or withdrawals, excluding fees but including slippage. This is helpful as an input into the various "min" parameters on calls to fight front-running

This shouldn't be used outside frontends for user estimates.

### Parameters:

* `self`: Swap struct to read from
* `amounts`: an array of token amounts to deposit or withdrawal, corresponding to pooledTokens. The amount should be in each pooled token's native precision. If a token charges a fee on transfers, use the amount that gets transferred after the fee.
* `deposit`: whether this is a deposit or a withdrawal

### Return Values:

* if deposit was true, total amount of lp token that will be minted and if deposit was false, total amount of lp token that will be burned

## Function `getAdminBalance(struct SwapUtils.Swap self, uint256 index) → uint256` <a href="#swaputils-getadminbalance-struct-swaputils-swap-uint256" id="swaputils-getadminbalance-struct-swaputils-swap-uint256"></a>

return accumulated amount of admin fees of the token with given index

### Parameters:

* `self`: Swap struct to read from
* `index`: Index of the pooled token

### Return Values:

* admin balance in the token's precision

## Function `swap(struct SwapUtils.Swap self, uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx, uint256 minDy) → uint256` <a href="#swaputils-swap-struct-swaputils-swap-uint8-uint8-uint256-uint256" id="swaputils-swap-struct-swaputils-swap-uint8-uint8-uint256-uint256"></a>

swap two tokens in the pool

### Parameters:

* `self`: Swap struct to read from and write to
* `tokenIndexFrom`: the token the user wants to sell
* `tokenIndexTo`: the token the user wants to buy
* `dx`: the amount of tokens the user wants to sell
* `minDy`: the min amount the user would like to receive, or revert.

### Return Values:

* amount of token user received on swap

## Function `addLiquidity(struct SwapUtils.Swap self, uint256[] amounts, uint256 minToMint) → uint256` <a href="#swaputils-addliquidity-struct-swaputils-swap-uint256-uint256" id="swaputils-addliquidity-struct-swaputils-swap-uint256-uint256"></a>

Add liquidity to the pool

### Parameters:

* `self`: Swap struct to read from and write to
* `amounts`: the amounts of each token to add, in their native precision
* `minToMint`: the minimum LP tokens adding this amount of liquidity should mint, otherwise revert. Handy for front-running mitigation allowed addresses. If the pool is not in the guarded launch phase, this parameter will be ignored.

### Return Values:

* amount of LP token user received

## Function `removeLiquidity(struct SwapUtils.Swap self, uint256 amount, uint256[] minAmounts) → uint256[]` <a href="#swaputils-removeliquidity-struct-swaputils-swap-uint256-uint256" id="swaputils-removeliquidity-struct-swaputils-swap-uint256-uint256"></a>

Burn LP tokens to remove liquidity from the pool.

Liquidity can always be removed, even when the pool is paused.

### Parameters:

* `self`: Swap struct to read from and write to
* `amount`: the amount of LP tokens to burn
* `minAmounts`: the minimum amounts of each token in the pool acceptable for this burn. Useful as a front-running mitigation

### Return Values:

* amounts of tokens the user received

## Function `removeLiquidityOneToken(struct SwapUtils.Swap self, uint256 tokenAmount, uint8 tokenIndex, uint256 minAmount) → uint256` <a href="#swaputils-removeliquidityonetoken-struct-swaputils-swap-uint256-uint8-uint256" id="swaputils-removeliquidityonetoken-struct-swaputils-swap-uint256-uint8-uint256"></a>

Remove liquidity from the pool all in one token.

### Parameters:

* `self`: Swap struct to read from and write to
* `tokenAmount`: the amount of the lp tokens to burn
* `tokenIndex`: the index of the token you want to receive
* `minAmount`: the minimum amount to withdraw, otherwise revert

### Return Values:

* amount chosen token that user received

## Function `removeLiquidityImbalance(struct SwapUtils.Swap self, uint256[] amounts, uint256 maxBurnAmount) → uint256` <a href="#swaputils-removeliquidityimbalance-struct-swaputils-swap-uint256-uint256" id="swaputils-removeliquidityimbalance-struct-swaputils-swap-uint256-uint256"></a>

Remove liquidity from the pool, weighted differently than the pool's current balances.

### Parameters:

* `self`: Swap struct to read from and write to
* `amounts`: how much of each token to withdraw
* `maxBurnAmount`: the max LP token provider is willing to pay to remove liquidity. Useful as a front-running mitigation.

### Return Values:

* actual amount of LP tokens burned in the withdrawal

## Function `withdrawAdminFees(struct SwapUtils.Swap self, address to)` <a href="#swaputils-withdrawadminfees-struct-swaputils-swap-address" id="swaputils-withdrawadminfees-struct-swaputils-swap-address"></a>

withdraw all admin fees to a given address

### Parameters:

* `self`: Swap struct to withdraw fees from
* `to`: Address to send the fees to

## Function `setAdminFee(struct SwapUtils.Swap self, uint256 newAdminFee)` <a href="#swaputils-setadminfee-struct-swaputils-swap-uint256" id="swaputils-setadminfee-struct-swaputils-swap-uint256"></a>

Sets the admin fee

adminFee cannot be higher than 100% of the swap fee

### Parameters:

* `self`: Swap struct to update
* `newAdminFee`: new admin fee to be applied on future transactions

## Function `setSwapFee(struct SwapUtils.Swap self, uint256 newSwapFee)` <a href="#swaputils-setswapfee-struct-swaputils-swap-uint256" id="swaputils-setswapfee-struct-swaputils-swap-uint256"></a>

update the swap fee

fee cannot be higher than 1% of each swap

### Parameters:

* `self`: Swap struct to update
* `newSwapFee`: new swap fee to be applied on future transactions

## Event `TokenSwap(address buyer, uint256 tokensSold, uint256 tokensBought, uint128 soldId, uint128 boughtId)` <a href="#swaputils-tokenswap-address-uint256-uint256-uint128-uint128" id="swaputils-tokenswap-address-uint256-uint256-uint128-uint128"></a>

No description

## Event `AddLiquidity(address provider, uint256[] tokenAmounts, uint256[] fees, uint256 invariant, uint256 lpTokenSupply)` <a href="#swaputils-addliquidity-address-uint256-uint256-uint256-uint256" id="swaputils-addliquidity-address-uint256-uint256-uint256-uint256"></a>

No description

## Event `RemoveLiquidity(address provider, uint256[] tokenAmounts, uint256 lpTokenSupply)` <a href="#swaputils-removeliquidity-address-uint256-uint256" id="swaputils-removeliquidity-address-uint256-uint256"></a>

No description

## Event `RemoveLiquidityOne(address provider, uint256 lpTokenAmount, uint256 lpTokenSupply, uint256 boughtId, uint256 tokensBought)` <a href="#swaputils-removeliquidityone-address-uint256-uint256-uint256-uint256" id="swaputils-removeliquidityone-address-uint256-uint256-uint256-uint256"></a>

No description

## Event `RemoveLiquidityImbalance(address provider, uint256[] tokenAmounts, uint256[] fees, uint256 invariant, uint256 lpTokenSupply)` <a href="#swaputils-removeliquidityimbalance-address-uint256-uint256-uint256-uint256" id="swaputils-removeliquidityimbalance-address-uint256-uint256-uint256-uint256"></a>

No description

## Event `NewAdminFee(uint256 newAdminFee)` <a href="#swaputils-newadminfee-uint256" id="swaputils-newadminfee-uint256"></a>

No description

## Event `NewSwapFee(uint256 newSwapFee)` <a href="#swaputils-newswapfee-uint256" id="swaputils-newswapfee-uint256"></a>

No description


# OwnerPausable

An ownable contract allows the owner to pause and unpause the contract without a delay.

Only methods using the provided modifiers will be paused.

## Functions:

* [`pause()`](#OwnerPausable-pause--)
* [`unpause()`](#OwnerPausable-unpause--)

## Function `pause()` <a href="#ownerpausable-pause" id="ownerpausable-pause"></a>

Pause the contract. Revert if already paused.

## Function `unpause()` <a href="#ownerpausable-unpause" id="ownerpausable-unpause"></a>

Unpause the contract. Revert if already unpaused.


# LPToken

This token is an ERC20 detailed token with added capability to be minted by the owner. It is used to represent user's shares when providing liquidity to swap contracts.

Only Swap contracts should initialize and own LPToken contracts.

## Functions:

* [`initialize(string name, string symbol)`](#LPToken-initialize-string-string-)
* [`mint(address recipient, uint256 amount)`](#LPToken-mint-address-uint256-)

## Function `initialize(string name, string symbol) → bool` <a href="#lptoken-initialize-string-string" id="lptoken-initialize-string-string"></a>

Initializes this LPToken contract with the given name and symbol

The caller of this function will become the owner. A Swap contract should call this in its initializer function.

### Parameters:

* `name`: name of this token
* `symbol`: symbol of this token

## Function `mint(address recipient, uint256 amount)` <a href="#lptoken-mint-address-uint256" id="lptoken-mint-address-uint256"></a>

Mints the given amount of LPToken to the recipient.

only owner can call this mint function

### Parameters:

* `recipient`: address of account to receive the tokens
* `amount`: amount of tokens to mint


# Interfaces


# ISwap

## Functions:

* [`getA()`](#ISwap-getA--)
* [`getAllowlist()`](#ISwap-getAllowlist--)
* [`getToken(uint8 index)`](#ISwap-getToken-uint8-)
* [`getTokenIndex(address tokenAddress)`](#ISwap-getTokenIndex-address-)
* [`getTokenBalance(uint8 index)`](#ISwap-getTokenBalance-uint8-)
* [`getVirtualPrice()`](#ISwap-getVirtualPrice--)
* [`isGuarded()`](#ISwap-isGuarded--)
* [`calculateSwap(uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx)`](#ISwap-calculateSwap-uint8-uint8-uint256-)
* [`calculateTokenAmount(uint256[] amounts, bool deposit)`](#ISwap-calculateTokenAmount-uint256---bool-)
* [`calculateRemoveLiquidity(uint256 amount)`](#ISwap-calculateRemoveLiquidity-uint256-)
* [`calculateRemoveLiquidityOneToken(uint256 tokenAmount, uint8 tokenIndex)`](#ISwap-calculateRemoveLiquidityOneToken-uint256-uint8-)
* [`initialize(contract IERC20[] pooledTokens, uint8[] decimals, string lpTokenName, string lpTokenSymbol, uint256 a, uint256 fee, uint256 adminFee, address lpTokenTargetAddress)`](#ISwap-initialize-contract-IERC20---uint8---string-string-uint256-uint256-uint256-address-)
* [`swap(uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx, uint256 minDy, uint256 deadline)`](#ISwap-swap-uint8-uint8-uint256-uint256-uint256-)
* [`addLiquidity(uint256[] amounts, uint256 minToMint, uint256 deadline)`](#ISwap-addLiquidity-uint256---uint256-uint256-)
* [`removeLiquidity(uint256 amount, uint256[] minAmounts, uint256 deadline)`](#ISwap-removeLiquidity-uint256-uint256---uint256-)
* [`removeLiquidityOneToken(uint256 tokenAmount, uint8 tokenIndex, uint256 minAmount, uint256 deadline)`](#ISwap-removeLiquidityOneToken-uint256-uint8-uint256-uint256-)
* [`removeLiquidityImbalance(uint256[] amounts, uint256 maxBurnAmount, uint256 deadline)`](#ISwap-removeLiquidityImbalance-uint256---uint256-uint256-)

## Function `getA() → uint256` <a href="#iswap-geta" id="iswap-geta"></a>

No description

## Function `getAllowlist() → contract IAllowlist` <a href="#iswap-getallowlist" id="iswap-getallowlist"></a>

No description

## Function `getToken(uint8 index) → contract IERC20` <a href="#iswap-gettoken-uint8" id="iswap-gettoken-uint8"></a>

No description

## Function `getTokenIndex(address tokenAddress) → uint8` <a href="#iswap-gettokenindex-address" id="iswap-gettokenindex-address"></a>

No description

## Function `getTokenBalance(uint8 index) → uint256` <a href="#iswap-gettokenbalance-uint8" id="iswap-gettokenbalance-uint8"></a>

No description

## Function `getVirtualPrice() → uint256` <a href="#iswap-getvirtualprice" id="iswap-getvirtualprice"></a>

No description

## Function `isGuarded() → bool` <a href="#iswap-isguarded" id="iswap-isguarded"></a>

No description

## Function `calculateSwap(uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx) → uint256` <a href="#iswap-calculateswap-uint8-uint8-uint256" id="iswap-calculateswap-uint8-uint8-uint256"></a>

No description

## Function `calculateTokenAmount(uint256[] amounts, bool deposit) → uint256` <a href="#iswap-calculatetokenamount-uint256-bool" id="iswap-calculatetokenamount-uint256-bool"></a>

No description

## Function `calculateRemoveLiquidity(uint256 amount) → uint256[]` <a href="#iswap-calculateremoveliquidity-uint256" id="iswap-calculateremoveliquidity-uint256"></a>

No description

## Function `calculateRemoveLiquidityOneToken(uint256 tokenAmount, uint8 tokenIndex) → uint256 availableTokenAmount` <a href="#iswap-calculateremoveliquidityonetoken-uint256-uint8" id="iswap-calculateremoveliquidityonetoken-uint256-uint8"></a>

No description

## Function `initialize(contract IERC20[] pooledTokens, uint8[] decimals, string lpTokenName, string lpTokenSymbol, uint256 a, uint256 fee, uint256 adminFee, address lpTokenTargetAddress)` <a href="#iswap-initialize-contract-ierc20-uint8-string-string-uint256-uint256-uint256-address" id="iswap-initialize-contract-ierc20-uint8-string-string-uint256-uint256-uint256-address"></a>

No description

## Function `swap(uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx, uint256 minDy, uint256 deadline) → uint256` <a href="#iswap-swap-uint8-uint8-uint256-uint256-uint256" id="iswap-swap-uint8-uint8-uint256-uint256-uint256"></a>

No description

## Function `addLiquidity(uint256[] amounts, uint256 minToMint, uint256 deadline) → uint256` <a href="#iswap-addliquidity-uint256-uint256-uint256" id="iswap-addliquidity-uint256-uint256-uint256"></a>

No description

## Function `removeLiquidity(uint256 amount, uint256[] minAmounts, uint256 deadline) → uint256[]` <a href="#iswap-removeliquidity-uint256-uint256-uint256" id="iswap-removeliquidity-uint256-uint256-uint256"></a>

No description

## Function `removeLiquidityOneToken(uint256 tokenAmount, uint8 tokenIndex, uint256 minAmount, uint256 deadline) → uint256` <a href="#iswap-removeliquidityonetoken-uint256-uint8-uint256-uint256" id="iswap-removeliquidityonetoken-uint256-uint8-uint256-uint256"></a>

No description

## Function `removeLiquidityImbalance(uint256[] amounts, uint256 maxBurnAmount, uint256 deadline) → uint256` <a href="#iswap-removeliquidityimbalance-uint256-uint256-uint256" id="iswap-removeliquidityimbalance-uint256-uint256-uint256"></a>

No description


# IAllowlist

## Functions:

* [`getPoolAccountLimit(address poolAddress)`](#IAllowlist-getPoolAccountLimit-address-)
* [`getPoolCap(address poolAddress)`](#IAllowlist-getPoolCap-address-)
* [`verifyAddress(address account, bytes32[] merkleProof)`](#IAllowlist-verifyAddress-address-bytes32---)

## Function `getPoolAccountLimit(address poolAddress) → uint256` <a href="#iallowlist-getpoolaccountlimit-address" id="iallowlist-getpoolaccountlimit-address"></a>

No description

## Function `getPoolCap(address poolAddress) → uint256` <a href="#iallowlist-getpoolcap-address" id="iallowlist-getpoolcap-address"></a>

No description

## Function `verifyAddress(address account, bytes32[] merkleProof) → bool` <a href="#iallowlist-verifyaddress-address-bytes32" id="iallowlist-verifyaddress-address-bytes32"></a>

No description


# ISwapV1

## Functions:

* [`getA()`](#ISwapV1-getA--)
* [`getAllowlist()`](#ISwapV1-getAllowlist--)
* [`getToken(uint8 index)`](#ISwapV1-getToken-uint8-)
* [`getTokenIndex(address tokenAddress)`](#ISwapV1-getTokenIndex-address-)
* [`getTokenBalance(uint8 index)`](#ISwapV1-getTokenBalance-uint8-)
* [`getVirtualPrice()`](#ISwapV1-getVirtualPrice--)
* [`isGuarded()`](#ISwapV1-isGuarded--)
* [`calculateSwap(uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx)`](#ISwapV1-calculateSwap-uint8-uint8-uint256-)
* [`calculateTokenAmount(address account, uint256[] amounts, bool deposit)`](#ISwapV1-calculateTokenAmount-address-uint256---bool-)
* [`calculateRemoveLiquidity(address account, uint256 amount)`](#ISwapV1-calculateRemoveLiquidity-address-uint256-)
* [`calculateRemoveLiquidityOneToken(address account, uint256 tokenAmount, uint8 tokenIndex)`](#ISwapV1-calculateRemoveLiquidityOneToken-address-uint256-uint8-)
* [`initialize(contract IERC20[] pooledTokens, uint8[] decimals, string lpTokenName, string lpTokenSymbol, uint256 a, uint256 fee, uint256 adminFee, uint256 withdrawFee, address lpTokenTargetAddress)`](#ISwapV1-initialize-contract-IERC20---uint8---string-string-uint256-uint256-uint256-uint256-address-)
* [`swap(uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx, uint256 minDy, uint256 deadline)`](#ISwapV1-swap-uint8-uint8-uint256-uint256-uint256-)
* [`addLiquidity(uint256[] amounts, uint256 minToMint, uint256 deadline)`](#ISwapV1-addLiquidity-uint256---uint256-uint256-)
* [`removeLiquidity(uint256 amount, uint256[] minAmounts, uint256 deadline)`](#ISwapV1-removeLiquidity-uint256-uint256---uint256-)
* [`removeLiquidityOneToken(uint256 tokenAmount, uint8 tokenIndex, uint256 minAmount, uint256 deadline)`](#ISwapV1-removeLiquidityOneToken-uint256-uint8-uint256-uint256-)
* [`removeLiquidityImbalance(uint256[] amounts, uint256 maxBurnAmount, uint256 deadline)`](#ISwapV1-removeLiquidityImbalance-uint256---uint256-uint256-)
* [`updateUserWithdrawFee(address recipient, uint256 transferAmount)`](#ISwapV1-updateUserWithdrawFee-address-uint256-)

## Function `getA() → uint256` <a href="#iswapv1-geta" id="iswapv1-geta"></a>

No description

## Function `getAllowlist() → contract IAllowlist` <a href="#iswapv1-getallowlist" id="iswapv1-getallowlist"></a>

No description

## Function `getToken(uint8 index) → contract IERC20` <a href="#iswapv1-gettoken-uint8" id="iswapv1-gettoken-uint8"></a>

No description

## Function `getTokenIndex(address tokenAddress) → uint8` <a href="#iswapv1-gettokenindex-address" id="iswapv1-gettokenindex-address"></a>

No description

## Function `getTokenBalance(uint8 index) → uint256` <a href="#iswapv1-gettokenbalance-uint8" id="iswapv1-gettokenbalance-uint8"></a>

No description

## Function `getVirtualPrice() → uint256` <a href="#iswapv1-getvirtualprice" id="iswapv1-getvirtualprice"></a>

No description

## Function `isGuarded() → bool` <a href="#iswapv1-isguarded" id="iswapv1-isguarded"></a>

No description

## Function `calculateSwap(uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx) → uint256` <a href="#iswapv1-calculateswap-uint8-uint8-uint256" id="iswapv1-calculateswap-uint8-uint8-uint256"></a>

No description

## Function `calculateTokenAmount(address account, uint256[] amounts, bool deposit) → uint256` <a href="#iswapv1-calculatetokenamount-address-uint256-bool" id="iswapv1-calculatetokenamount-address-uint256-bool"></a>

No description

## Function `calculateRemoveLiquidity(address account, uint256 amount) → uint256[]` <a href="#iswapv1-calculateremoveliquidity-address-uint256" id="iswapv1-calculateremoveliquidity-address-uint256"></a>

No description

## Function `calculateRemoveLiquidityOneToken(address account, uint256 tokenAmount, uint8 tokenIndex) → uint256 availableTokenAmount` <a href="#iswapv1-calculateremoveliquidityonetoken-address-uint256-uint8" id="iswapv1-calculateremoveliquidityonetoken-address-uint256-uint8"></a>

No description

## Function `initialize(contract IERC20[] pooledTokens, uint8[] decimals, string lpTokenName, string lpTokenSymbol, uint256 a, uint256 fee, uint256 adminFee, uint256 withdrawFee, address lpTokenTargetAddress)` <a href="#iswapv1-initialize-contract-ierc20-uint8-string-string-uint256-uint256-uint256-uint256-address" id="iswapv1-initialize-contract-ierc20-uint8-string-string-uint256-uint256-uint256-uint256-address"></a>

No description

## Function `swap(uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx, uint256 minDy, uint256 deadline) → uint256` <a href="#iswapv1-swap-uint8-uint8-uint256-uint256-uint256" id="iswapv1-swap-uint8-uint8-uint256-uint256-uint256"></a>

No description

## Function `addLiquidity(uint256[] amounts, uint256 minToMint, uint256 deadline) → uint256` <a href="#iswapv1-addliquidity-uint256-uint256-uint256" id="iswapv1-addliquidity-uint256-uint256-uint256"></a>

No description

## Function `removeLiquidity(uint256 amount, uint256[] minAmounts, uint256 deadline) → uint256[]` <a href="#iswapv1-removeliquidity-uint256-uint256-uint256" id="iswapv1-removeliquidity-uint256-uint256-uint256"></a>

No description

## Function `removeLiquidityOneToken(uint256 tokenAmount, uint8 tokenIndex, uint256 minAmount, uint256 deadline) → uint256` <a href="#iswapv1-removeliquidityonetoken-uint256-uint8-uint256-uint256" id="iswapv1-removeliquidityonetoken-uint256-uint8-uint256-uint256"></a>

No description

## Function `removeLiquidityImbalance(uint256[] amounts, uint256 maxBurnAmount, uint256 deadline) → uint256` <a href="#iswapv1-removeliquidityimbalance-uint256-uint256-uint256" id="iswapv1-removeliquidityimbalance-uint256-uint256-uint256"></a>

No description

## Function `updateUserWithdrawFee(address recipient, uint256 transferAmount)` <a href="#iswapv1-updateuserwithdrawfee-address-uint256" id="iswapv1-updateuserwithdrawfee-address-uint256"></a>

No description


# ISwapGuarded

## Functions:

* [`getA()`](#ISwapGuarded-getA--)
* [`getAllowlist()`](#ISwapGuarded-getAllowlist--)
* [`getToken(uint8 index)`](#ISwapGuarded-getToken-uint8-)
* [`getTokenIndex(address tokenAddress)`](#ISwapGuarded-getTokenIndex-address-)
* [`getTokenBalance(uint8 index)`](#ISwapGuarded-getTokenBalance-uint8-)
* [`getVirtualPrice()`](#ISwapGuarded-getVirtualPrice--)
* [`isGuarded()`](#ISwapGuarded-isGuarded--)
* [`calculateSwap(uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx)`](#ISwapGuarded-calculateSwap-uint8-uint8-uint256-)
* [`calculateTokenAmount(uint256[] amounts, bool deposit)`](#ISwapGuarded-calculateTokenAmount-uint256---bool-)
* [`calculateRemoveLiquidity(uint256 amount)`](#ISwapGuarded-calculateRemoveLiquidity-uint256-)
* [`calculateRemoveLiquidityOneToken(uint256 tokenAmount, uint8 tokenIndex)`](#ISwapGuarded-calculateRemoveLiquidityOneToken-uint256-uint8-)
* [`swap(uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx, uint256 minDy, uint256 deadline)`](#ISwapGuarded-swap-uint8-uint8-uint256-uint256-uint256-)
* [`addLiquidity(uint256[] amounts, uint256 minToMint, uint256 deadline, bytes32[] merkleProof)`](#ISwapGuarded-addLiquidity-uint256---uint256-uint256-bytes32---)
* [`removeLiquidity(uint256 amount, uint256[] minAmounts, uint256 deadline)`](#ISwapGuarded-removeLiquidity-uint256-uint256---uint256-)
* [`removeLiquidityOneToken(uint256 tokenAmount, uint8 tokenIndex, uint256 minAmount, uint256 deadline)`](#ISwapGuarded-removeLiquidityOneToken-uint256-uint8-uint256-uint256-)
* [`removeLiquidityImbalance(uint256[] amounts, uint256 maxBurnAmount, uint256 deadline)`](#ISwapGuarded-removeLiquidityImbalance-uint256---uint256-uint256-)
* [`updateUserWithdrawFee(address recipient, uint256 transferAmount)`](#ISwapGuarded-updateUserWithdrawFee-address-uint256-)

## Function `getA() → uint256` <a href="#iswapguarded-geta" id="iswapguarded-geta"></a>

No description

## Function `getAllowlist() → contract IAllowlist` <a href="#iswapguarded-getallowlist" id="iswapguarded-getallowlist"></a>

No description

## Function `getToken(uint8 index) → contract IERC20` <a href="#iswapguarded-gettoken-uint8" id="iswapguarded-gettoken-uint8"></a>

No description

## Function `getTokenIndex(address tokenAddress) → uint8` <a href="#iswapguarded-gettokenindex-address" id="iswapguarded-gettokenindex-address"></a>

No description

## Function `getTokenBalance(uint8 index) → uint256` <a href="#iswapguarded-gettokenbalance-uint8" id="iswapguarded-gettokenbalance-uint8"></a>

No description

## Function `getVirtualPrice() → uint256` <a href="#iswapguarded-getvirtualprice" id="iswapguarded-getvirtualprice"></a>

No description

## Function `isGuarded() → bool` <a href="#iswapguarded-isguarded" id="iswapguarded-isguarded"></a>

No description

## Function `calculateSwap(uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx) → uint256` <a href="#iswapguarded-calculateswap-uint8-uint8-uint256" id="iswapguarded-calculateswap-uint8-uint8-uint256"></a>

No description

## Function `calculateTokenAmount(uint256[] amounts, bool deposit) → uint256` <a href="#iswapguarded-calculatetokenamount-uint256-bool" id="iswapguarded-calculatetokenamount-uint256-bool"></a>

No description

## Function `calculateRemoveLiquidity(uint256 amount) → uint256[]` <a href="#iswapguarded-calculateremoveliquidity-uint256" id="iswapguarded-calculateremoveliquidity-uint256"></a>

No description

## Function `calculateRemoveLiquidityOneToken(uint256 tokenAmount, uint8 tokenIndex) → uint256 availableTokenAmount` <a href="#iswapguarded-calculateremoveliquidityonetoken-uint256-uint8" id="iswapguarded-calculateremoveliquidityonetoken-uint256-uint8"></a>

No description

## Function `swap(uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx, uint256 minDy, uint256 deadline) → uint256` <a href="#iswapguarded-swap-uint8-uint8-uint256-uint256-uint256" id="iswapguarded-swap-uint8-uint8-uint256-uint256-uint256"></a>

No description

## Function `addLiquidity(uint256[] amounts, uint256 minToMint, uint256 deadline, bytes32[] merkleProof) → uint256` <a href="#iswapguarded-addliquidity-uint256-uint256-uint256-bytes32" id="iswapguarded-addliquidity-uint256-uint256-uint256-bytes32"></a>

No description

## Function `removeLiquidity(uint256 amount, uint256[] minAmounts, uint256 deadline) → uint256[]` <a href="#iswapguarded-removeliquidity-uint256-uint256-uint256" id="iswapguarded-removeliquidity-uint256-uint256-uint256"></a>

No description

## Function `removeLiquidityOneToken(uint256 tokenAmount, uint8 tokenIndex, uint256 minAmount, uint256 deadline) → uint256` <a href="#iswapguarded-removeliquidityonetoken-uint256-uint8-uint256-uint256" id="iswapguarded-removeliquidityonetoken-uint256-uint8-uint256-uint256"></a>

No description

## Function `removeLiquidityImbalance(uint256[] amounts, uint256 maxBurnAmount, uint256 deadline) → uint256` <a href="#iswapguarded-removeliquidityimbalance-uint256-uint256-uint256" id="iswapguarded-removeliquidityimbalance-uint256-uint256-uint256"></a>

No description

## Function `updateUserWithdrawFee(address recipient, uint256 transferAmount)` <a href="#iswapguarded-updateuserwithdrawfee-address-uint256" id="iswapguarded-updateuserwithdrawfee-address-uint256"></a>

No description


# ISwapFlashLoan

## Functions:

* [`flashLoan(address receiver, contract IERC20 token, uint256 amount, bytes params)`](#ISwapFlashLoan-flashLoan-address-contract-IERC20-uint256-bytes-)

## Function `flashLoan(address receiver, contract IERC20 token, uint256 amount, bytes params)` <a href="#iswapflashloan-flashloan-address-contract-ierc20-uint256-bytes" id="iswapflashloan-flashloan-address-contract-ierc20-uint256-bytes"></a>

No description


# IMetaSwap

## Functions:

* [`getA()`](#IMetaSwap-getA--)
* [`getToken(uint8 index)`](#IMetaSwap-getToken-uint8-)
* [`getTokenIndex(address tokenAddress)`](#IMetaSwap-getTokenIndex-address-)
* [`getTokenBalance(uint8 index)`](#IMetaSwap-getTokenBalance-uint8-)
* [`getVirtualPrice()`](#IMetaSwap-getVirtualPrice--)
* [`isGuarded()`](#IMetaSwap-isGuarded--)
* [`calculateSwap(uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx)`](#IMetaSwap-calculateSwap-uint8-uint8-uint256-)
* [`calculateSwapUnderlying(uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx)`](#IMetaSwap-calculateSwapUnderlying-uint8-uint8-uint256-)
* [`calculateTokenAmount(uint256[] amounts, bool deposit)`](#IMetaSwap-calculateTokenAmount-uint256---bool-)
* [`calculateRemoveLiquidity(uint256 amount)`](#IMetaSwap-calculateRemoveLiquidity-uint256-)
* [`calculateRemoveLiquidityOneToken(uint256 tokenAmount, uint8 tokenIndex)`](#IMetaSwap-calculateRemoveLiquidityOneToken-uint256-uint8-)
* [`initialize(contract IERC20[] _pooledTokens, uint8[] decimals, string lpTokenName, string lpTokenSymbol, uint256 _a, uint256 _fee, uint256 _adminFee, address lpTokenTargetAddress)`](#IMetaSwap-initialize-contract-IERC20---uint8---string-string-uint256-uint256-uint256-address-)
* [`initializeMetaSwap(contract IERC20[] _pooledTokens, uint8[] decimals, string lpTokenName, string lpTokenSymbol, uint256 _a, uint256 _fee, uint256 _adminFee, address lpTokenTargetAddress, contract ISwap baseSwap)`](#IMetaSwap-initializeMetaSwap-contract-IERC20---uint8---string-string-uint256-uint256-uint256-address-contract-ISwap-)
* [`swap(uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx, uint256 minDy, uint256 deadline)`](#IMetaSwap-swap-uint8-uint8-uint256-uint256-uint256-)
* [`swapUnderlying(uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx, uint256 minDy, uint256 deadline)`](#IMetaSwap-swapUnderlying-uint8-uint8-uint256-uint256-uint256-)
* [`addLiquidity(uint256[] amounts, uint256 minToMint, uint256 deadline)`](#IMetaSwap-addLiquidity-uint256---uint256-uint256-)
* [`removeLiquidity(uint256 amount, uint256[] minAmounts, uint256 deadline)`](#IMetaSwap-removeLiquidity-uint256-uint256---uint256-)
* [`removeLiquidityOneToken(uint256 tokenAmount, uint8 tokenIndex, uint256 minAmount, uint256 deadline)`](#IMetaSwap-removeLiquidityOneToken-uint256-uint8-uint256-uint256-)
* [`removeLiquidityImbalance(uint256[] amounts, uint256 maxBurnAmount, uint256 deadline)`](#IMetaSwap-removeLiquidityImbalance-uint256---uint256-uint256-)

## Function `getA() → uint256` <a href="#imetaswap-geta" id="imetaswap-geta"></a>

No description

## Function `getToken(uint8 index) → contract IERC20` <a href="#imetaswap-gettoken-uint8" id="imetaswap-gettoken-uint8"></a>

No description

## Function `getTokenIndex(address tokenAddress) → uint8` <a href="#imetaswap-gettokenindex-address" id="imetaswap-gettokenindex-address"></a>

No description

## Function `getTokenBalance(uint8 index) → uint256` <a href="#imetaswap-gettokenbalance-uint8" id="imetaswap-gettokenbalance-uint8"></a>

No description

## Function `getVirtualPrice() → uint256` <a href="#imetaswap-getvirtualprice" id="imetaswap-getvirtualprice"></a>

No description

## Function `isGuarded() → bool` <a href="#imetaswap-isguarded" id="imetaswap-isguarded"></a>

No description

## Function `calculateSwap(uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx) → uint256` <a href="#imetaswap-calculateswap-uint8-uint8-uint256" id="imetaswap-calculateswap-uint8-uint8-uint256"></a>

No description

## Function `calculateSwapUnderlying(uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx) → uint256` <a href="#imetaswap-calculateswapunderlying-uint8-uint8-uint256" id="imetaswap-calculateswapunderlying-uint8-uint8-uint256"></a>

No description

## Function `calculateTokenAmount(uint256[] amounts, bool deposit) → uint256` <a href="#imetaswap-calculatetokenamount-uint256-bool" id="imetaswap-calculatetokenamount-uint256-bool"></a>

No description

## Function `calculateRemoveLiquidity(uint256 amount) → uint256[]` <a href="#imetaswap-calculateremoveliquidity-uint256" id="imetaswap-calculateremoveliquidity-uint256"></a>

No description

## Function `calculateRemoveLiquidityOneToken(uint256 tokenAmount, uint8 tokenIndex) → uint256 availableTokenAmount` <a href="#imetaswap-calculateremoveliquidityonetoken-uint256-uint8" id="imetaswap-calculateremoveliquidityonetoken-uint256-uint8"></a>

No description

## Function `initialize(contract IERC20[] _pooledTokens, uint8[] decimals, string lpTokenName, string lpTokenSymbol, uint256 _a, uint256 _fee, uint256 _adminFee, address lpTokenTargetAddress)` <a href="#imetaswap-initialize-contract-ierc20-uint8-string-string-uint256-uint256-uint256-address" id="imetaswap-initialize-contract-ierc20-uint8-string-string-uint256-uint256-uint256-address"></a>

No description

## Function `initializeMetaSwap(contract IERC20[] _pooledTokens, uint8[] decimals, string lpTokenName, string lpTokenSymbol, uint256 _a, uint256 _fee, uint256 _adminFee, address lpTokenTargetAddress, contract ISwap baseSwap)` <a href="#imetaswap-initializemetaswap-contract-ierc20-uint8-string-string-uint256-uint256-uint256-address-con" id="imetaswap-initializemetaswap-contract-ierc20-uint8-string-string-uint256-uint256-uint256-address-con"></a>

No description

## Function `swap(uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx, uint256 minDy, uint256 deadline) → uint256` <a href="#imetaswap-swap-uint8-uint8-uint256-uint256-uint256" id="imetaswap-swap-uint8-uint8-uint256-uint256-uint256"></a>

No description

## Function `swapUnderlying(uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx, uint256 minDy, uint256 deadline) → uint256` <a href="#imetaswap-swapunderlying-uint8-uint8-uint256-uint256-uint256" id="imetaswap-swapunderlying-uint8-uint8-uint256-uint256-uint256"></a>

No description

## Function `addLiquidity(uint256[] amounts, uint256 minToMint, uint256 deadline) → uint256` <a href="#imetaswap-addliquidity-uint256-uint256-uint256" id="imetaswap-addliquidity-uint256-uint256-uint256"></a>

No description

## Function `removeLiquidity(uint256 amount, uint256[] minAmounts, uint256 deadline) → uint256[]` <a href="#imetaswap-removeliquidity-uint256-uint256-uint256" id="imetaswap-removeliquidity-uint256-uint256-uint256"></a>

No description

## Function `removeLiquidityOneToken(uint256 tokenAmount, uint8 tokenIndex, uint256 minAmount, uint256 deadline) → uint256` <a href="#imetaswap-removeliquidityonetoken-uint256-uint8-uint256-uint256" id="imetaswap-removeliquidityonetoken-uint256-uint8-uint256-uint256"></a>

No description

## Function `removeLiquidityImbalance(uint256[] amounts, uint256 maxBurnAmount, uint256 deadline) → uint256` <a href="#imetaswap-removeliquidityimbalance-uint256-uint256-uint256" id="imetaswap-removeliquidityimbalance-uint256-uint256-uint256"></a>

No description


# IFlashLoanReceiver

Interface for the Saddle fee IFlashLoanReceiver. Modified from Aave's IFlashLoanReceiver interface. <https://github.com/aave/aave-protocol/blob/4b4545fb583fd4f400507b10f3c3114f45b8a037/contracts/flashloan/interfaces/IFlashLoanReceiver.sol>

implement this interface to develop a flashloan-compatible flashLoanReceiver contract

## Functions:

* [`executeOperation(address pool, address token, uint256 amount, uint256 fee, bytes params)`](#IFlashLoanReceiver-executeOperation-address-address-uint256-uint256-bytes-)

## Function `executeOperation(address pool, address token, uint256 amount, uint256 fee, bytes params)` <a href="#iflashloanreceiver-executeoperation-address-address-uint256-uint256-bytes" id="iflashloanreceiver-executeoperation-address-address-uint256-uint256-bytes"></a>

No description


# Helper


# Test


# TestSwapReturnValues

## Functions:

* [`constructor(contract ISwap swapContract, contract IERC20 lpTokenContract, uint8 numOfTokens)`](#TestSwapReturnValues-constructor-contract-ISwap-contract-IERC20-uint8-)
* [`test_swap(uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx, uint256 minDy)`](#TestSwapReturnValues-test_swap-uint8-uint8-uint256-uint256-)
* [`test_addLiquidity(uint256[] amounts, uint256 minToMint)`](#TestSwapReturnValues-test_addLiquidity-uint256---uint256-)
* [`test_removeLiquidity(uint256 amount, uint256[] minAmounts)`](#TestSwapReturnValues-test_removeLiquidity-uint256-uint256---)
* [`test_removeLiquidityImbalance(uint256[] amounts, uint256 maxBurnAmount)`](#TestSwapReturnValues-test_removeLiquidityImbalance-uint256---uint256-)
* [`test_removeLiquidityOneToken(uint256 tokenAmount, uint8 tokenIndex, uint256 minAmount)`](#TestSwapReturnValues-test_removeLiquidityOneToken-uint256-uint8-uint256-)

## Function `constructor(contract ISwap swapContract, contract IERC20 lpTokenContract, uint8 numOfTokens)` <a href="#testswapreturnvalues-constructor-contract-iswap-contract-ierc20-uint8" id="testswapreturnvalues-constructor-contract-iswap-contract-ierc20-uint8"></a>

No description

## Function `test_swap(uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx, uint256 minDy)` <a href="#testswapreturnvalues-test_swap-uint8-uint8-uint256-uint256" id="testswapreturnvalues-test_swap-uint8-uint8-uint256-uint256"></a>

No description

## Function `test_addLiquidity(uint256[] amounts, uint256 minToMint)` <a href="#testswapreturnvalues-test_addliquidity-uint256-uint256" id="testswapreturnvalues-test_addliquidity-uint256-uint256"></a>

No description

## Function `test_removeLiquidity(uint256 amount, uint256[] minAmounts)` <a href="#testswapreturnvalues-test_removeliquidity-uint256-uint256" id="testswapreturnvalues-test_removeliquidity-uint256-uint256"></a>

No description

## Function `test_removeLiquidityImbalance(uint256[] amounts, uint256 maxBurnAmount)` <a href="#testswapreturnvalues-test_removeliquidityimbalance-uint256-uint256" id="testswapreturnvalues-test_removeliquidityimbalance-uint256-uint256"></a>

No description

## Function `test_removeLiquidityOneToken(uint256 tokenAmount, uint8 tokenIndex, uint256 minAmount)` <a href="#testswapreturnvalues-test_removeliquidityonetoken-uint256-uint8-uint256" id="testswapreturnvalues-test_removeliquidityonetoken-uint256-uint8-uint256"></a>

No description


# GenericERC20

This contract simulates a generic ERC20 token that is mintable and burnable.

## Functions:

* [`constructor(string name_, string symbol_, uint8 decimals_)`](#GenericERC20-constructor-string-string-uint8-)
* [`mint(address recipient, uint256 amount)`](#GenericERC20-mint-address-uint256-)

## Function `constructor(string name_, string symbol_, uint8 decimals_)` <a href="#genericerc20-constructor-string-string-uint8" id="genericerc20-constructor-string-string-uint8"></a>

Deploy this contract with given name, symbol, and decimals

the caller of this constructor will become the owner of this contract

### Parameters:

* `name_`: name of this token
* `symbol_`: symbol of this token
* `decimals_`: number of decimals this token will be based on

## Function `mint(address recipient, uint256 amount)` <a href="#genericerc20-mint-address-uint256" id="genericerc20-mint-address-uint256"></a>

Mints given amount of tokens to recipient

only owner can call this mint function

### Parameters:

* `recipient`: address of account to receive the tokens
* `amount`: amount of tokens to mint


# Multicall

## Functions:

* [`aggregate(struct Multicall.Call[] calls)`](#Multicall-aggregate-struct-Multicall-Call---)
* [`getEthBalance(address addr)`](#Multicall-getEthBalance-address-)
* [`getBlockHash(uint256 blockNumber)`](#Multicall-getBlockHash-uint256-)
* [`getLastBlockHash()`](#Multicall-getLastBlockHash--)
* [`getCurrentBlockTimestamp()`](#Multicall-getCurrentBlockTimestamp--)
* [`getCurrentBlockDifficulty()`](#Multicall-getCurrentBlockDifficulty--)
* [`getCurrentBlockGasLimit()`](#Multicall-getCurrentBlockGasLimit--)
* [`getCurrentBlockCoinbase()`](#Multicall-getCurrentBlockCoinbase--)

## Function `aggregate(struct Multicall.Call[] calls) → uint256 blockNumber, bytes[] returnData` <a href="#multicall-aggregate-struct-multicall-call" id="multicall-aggregate-struct-multicall-call"></a>

No description

## Function `getEthBalance(address addr) → uint256 balance` <a href="#multicall-getethbalance-address" id="multicall-getethbalance-address"></a>

No description

## Function `getBlockHash(uint256 blockNumber) → bytes32 blockHash` <a href="#multicall-getblockhash-uint256" id="multicall-getblockhash-uint256"></a>

No description

## Function `getLastBlockHash() → bytes32 blockHash` <a href="#multicall-getlastblockhash" id="multicall-getlastblockhash"></a>

No description

## Function `getCurrentBlockTimestamp() → uint256 timestamp` <a href="#multicall-getcurrentblocktimestamp" id="multicall-getcurrentblocktimestamp"></a>

No description

## Function `getCurrentBlockDifficulty() → uint256 difficulty` <a href="#multicall-getcurrentblockdifficulty" id="multicall-getcurrentblockdifficulty"></a>

No description

## Function `getCurrentBlockGasLimit() → uint256 gaslimit` <a href="#multicall-getcurrentblockgaslimit" id="multicall-getcurrentblockgaslimit"></a>

No description

## Function `getCurrentBlockCoinbase() → address coinbase` <a href="#multicall-getcurrentblockcoinbase" id="multicall-getcurrentblockcoinbase"></a>

No description


# Multicall2

## Functions:

* [`aggregate(struct Multicall2.Call[] calls)`](#Multicall2-aggregate-struct-Multicall2-Call---)
* [`blockAndAggregate(struct Multicall2.Call[] calls)`](#Multicall2-blockAndAggregate-struct-Multicall2-Call---)
* [`getBlockHash(uint256 blockNumber)`](#Multicall2-getBlockHash-uint256-)
* [`getBlockNumber()`](#Multicall2-getBlockNumber--)
* [`getCurrentBlockCoinbase()`](#Multicall2-getCurrentBlockCoinbase--)
* [`getCurrentBlockDifficulty()`](#Multicall2-getCurrentBlockDifficulty--)
* [`getCurrentBlockGasLimit()`](#Multicall2-getCurrentBlockGasLimit--)
* [`getCurrentBlockTimestamp()`](#Multicall2-getCurrentBlockTimestamp--)
* [`getEthBalance(address addr)`](#Multicall2-getEthBalance-address-)
* [`getLastBlockHash()`](#Multicall2-getLastBlockHash--)
* [`tryAggregate(bool requireSuccess, struct Multicall2.Call[] calls)`](#Multicall2-tryAggregate-bool-struct-Multicall2-Call---)
* [`tryBlockAndAggregate(bool requireSuccess, struct Multicall2.Call[] calls)`](#Multicall2-tryBlockAndAggregate-bool-struct-Multicall2-Call---)

## Function `aggregate(struct Multicall2.Call[] calls) → uint256 blockNumber, bytes[] returnData` <a href="#multicall2-aggregate-struct-multicall2-call" id="multicall2-aggregate-struct-multicall2-call"></a>

No description

## Function `blockAndAggregate(struct Multicall2.Call[] calls) → uint256 blockNumber, bytes32 blockHash, struct Multicall2.Result[] returnData` <a href="#multicall2-blockandaggregate-struct-multicall2-call" id="multicall2-blockandaggregate-struct-multicall2-call"></a>

No description

## Function `getBlockHash(uint256 blockNumber) → bytes32 blockHash` <a href="#multicall2-getblockhash-uint256" id="multicall2-getblockhash-uint256"></a>

No description

## Function `getBlockNumber() → uint256 blockNumber` <a href="#multicall2-getblocknumber" id="multicall2-getblocknumber"></a>

No description

## Function `getCurrentBlockCoinbase() → address coinbase` <a href="#multicall2-getcurrentblockcoinbase" id="multicall2-getcurrentblockcoinbase"></a>

No description

## Function `getCurrentBlockDifficulty() → uint256 difficulty` <a href="#multicall2-getcurrentblockdifficulty" id="multicall2-getcurrentblockdifficulty"></a>

No description

## Function `getCurrentBlockGasLimit() → uint256 gaslimit` <a href="#multicall2-getcurrentblockgaslimit" id="multicall2-getcurrentblockgaslimit"></a>

No description

## Function `getCurrentBlockTimestamp() → uint256 timestamp` <a href="#multicall2-getcurrentblocktimestamp" id="multicall2-getcurrentblocktimestamp"></a>

No description

## Function `getEthBalance(address addr) → uint256 balance` <a href="#multicall2-getethbalance-address" id="multicall2-getethbalance-address"></a>

No description

## Function `getLastBlockHash() → bytes32 blockHash` <a href="#multicall2-getlastblockhash" id="multicall2-getlastblockhash"></a>

No description

## Function `tryAggregate(bool requireSuccess, struct Multicall2.Call[] calls) → struct Multicall2.Result[] returnData` <a href="#multicall2-tryaggregate-bool-struct-multicall2-call" id="multicall2-tryaggregate-bool-struct-multicall2-call"></a>

No description

## Function `tryBlockAndAggregate(bool requireSuccess, struct Multicall2.Call[] calls) → uint256 blockNumber, bytes32 blockHash, struct Multicall2.Result[] returnData` <a href="#multicall2-tryblockandaggregate-bool-struct-multicall2-call" id="multicall2-tryblockandaggregate-bool-struct-multicall2-call"></a>

No description


# FlashLoanBorrowerExample

## Functions:

* [`executeOperation(address pool, address token, uint256 amount, uint256 fee, bytes params)`](#FlashLoanBorrowerExample-executeOperation-address-address-uint256-uint256-bytes-)
* [`flashLoan(contract ISwapFlashLoan swap, contract IERC20 token, uint256 amount, bytes params)`](#FlashLoanBorrowerExample-flashLoan-contract-ISwapFlashLoan-contract-IERC20-uint256-bytes-)

## Function `executeOperation(address pool, address token, uint256 amount, uint256 fee, bytes params)` <a href="#flashloanborrowerexample-executeoperation-address-address-uint256-uint256-bytes" id="flashloanborrowerexample-executeoperation-address-address-uint256-uint256-bytes"></a>

No description

## Function `flashLoan(contract ISwapFlashLoan swap, contract IERC20 token, uint256 amount, bytes params)` <a href="#flashloanborrowerexample-flashloan-contract-iswapflashloan-contract-ierc20-uint256-bytes" id="flashloanborrowerexample-flashloan-contract-iswapflashloan-contract-ierc20-uint256-bytes"></a>

No description


# Meta


# MetaSwap

This contract is responsible for custody of closely pegged assets (eg. group of stablecoins) and automatic market making system. Users become an LP (Liquidity Provider) by depositing their tokens in desired ratios for an exchange of the pool token that represents their share of the pool. Users can burn pool tokens and withdraw their share of token(s).

Each time a swap between the pooled tokens happens, a set fee incurs which effectively gets distributed to the LPs.

In case of emergencies, admin can pause additional deposits, swaps, or single-asset withdraws - which stops the ratio of the tokens in the pool from changing. Users can always withdraw their tokens via multi-asset withdraws.

MetaSwap is a modified version of Swap that allows Swap's LP token to be utilized in pooling with other tokens. As an example, if there is a Swap pool consisting of \[DAI, USDC, USDT], then a MetaSwap pool can be created with \[sUSD, BaseSwapLPToken] to allow trades between either the LP token or the underlying tokens and sUSD. Note that when interacting with MetaSwap, users cannot deposit or withdraw via underlying tokens. In that case, `MetaSwapDeposit.sol` can be additionally deployed to allow interacting with unwrapped representations of the tokens.

Most of the logic is stored as a library `MetaSwapUtils` for the sake of reducing contract's deployment size.

## Functions:

* [`getVirtualPrice()`](#MetaSwap-getVirtualPrice--)
* [`calculateSwap(uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx)`](#MetaSwap-calculateSwap-uint8-uint8-uint256-)
* [`calculateSwapUnderlying(uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx)`](#MetaSwap-calculateSwapUnderlying-uint8-uint8-uint256-)
* [`calculateTokenAmount(uint256[] amounts, bool deposit)`](#MetaSwap-calculateTokenAmount-uint256---bool-)
* [`calculateRemoveLiquidityOneToken(uint256 tokenAmount, uint8 tokenIndex)`](#MetaSwap-calculateRemoveLiquidityOneToken-uint256-uint8-)
* [`initialize(contract IERC20[] _pooledTokens, uint8[] decimals, string lpTokenName, string lpTokenSymbol, uint256 _a, uint256 _fee, uint256 _adminFee, address lpTokenTargetAddress)`](#MetaSwap-initialize-contract-IERC20---uint8---string-string-uint256-uint256-uint256-address-)
* [`initializeMetaSwap(contract IERC20[] _pooledTokens, uint8[] decimals, string lpTokenName, string lpTokenSymbol, uint256 _a, uint256 _fee, uint256 _adminFee, address lpTokenTargetAddress, contract ISwap baseSwap)`](#MetaSwap-initializeMetaSwap-contract-IERC20---uint8---string-string-uint256-uint256-uint256-address-contract-ISwap-)
* [`swap(uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx, uint256 minDy, uint256 deadline)`](#MetaSwap-swap-uint8-uint8-uint256-uint256-uint256-)
* [`swapUnderlying(uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx, uint256 minDy, uint256 deadline)`](#MetaSwap-swapUnderlying-uint8-uint8-uint256-uint256-uint256-)
* [`addLiquidity(uint256[] amounts, uint256 minToMint, uint256 deadline)`](#MetaSwap-addLiquidity-uint256---uint256-uint256-)
* [`removeLiquidityOneToken(uint256 tokenAmount, uint8 tokenIndex, uint256 minAmount, uint256 deadline)`](#MetaSwap-removeLiquidityOneToken-uint256-uint8-uint256-uint256-)
* [`removeLiquidityImbalance(uint256[] amounts, uint256 maxBurnAmount, uint256 deadline)`](#MetaSwap-removeLiquidityImbalance-uint256---uint256-uint256-)

## Events:

* [`TokenSwapUnderlying(address buyer, uint256 tokensSold, uint256 tokensBought, uint128 soldId, uint128 boughtId)`](#MetaSwap-TokenSwapUnderlying-address-uint256-uint256-uint128-uint128-)

## Function `getVirtualPrice() → uint256` <a href="#metaswap-getvirtualprice" id="metaswap-getvirtualprice"></a>

Get the virtual price, to help calculate profit

### Return Values:

* the virtual price, scaled to the POOL\_PRECISION\_DECIMALS

## Function `calculateSwap(uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx) → uint256` <a href="#metaswap-calculateswap-uint8-uint8-uint256" id="metaswap-calculateswap-uint8-uint8-uint256"></a>

Calculate amount of tokens you receive on swap

### Parameters:

* `tokenIndexFrom`: the token the user wants to sell
* `tokenIndexTo`: the token the user wants to buy
* `dx`: the amount of tokens the user wants to sell. If the token charges a fee on transfers, use the amount that gets transferred after the fee.

### Return Values:

* amount of tokens the user will receive

## Function `calculateSwapUnderlying(uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx) → uint256` <a href="#metaswap-calculateswapunderlying-uint8-uint8-uint256" id="metaswap-calculateswapunderlying-uint8-uint8-uint256"></a>

Calculate amount of tokens you receive on swap. For this function, the token indices are flattened out so that underlying tokens are represented.

### Parameters:

* `tokenIndexFrom`: the token the user wants to sell
* `tokenIndexTo`: the token the user wants to buy
* `dx`: the amount of tokens the user wants to sell. If the token charges a fee on transfers, use the amount that gets transferred after the fee.

### Return Values:

* amount of tokens the user will receive

## Function `calculateTokenAmount(uint256[] amounts, bool deposit) → uint256` <a href="#metaswap-calculatetokenamount-uint256-bool" id="metaswap-calculatetokenamount-uint256-bool"></a>

A simple method to calculate prices from deposits or withdrawals, excluding fees but including slippage. This is helpful as an input into the various "min" parameters on calls to fight front-running

This shouldn't be used outside frontends for user estimates.

### Parameters:

* `amounts`: an array of token amounts to deposit or withdrawal, corresponding to pooledTokens. The amount should be in each pooled token's native precision. If a token charges a fee on transfers, use the amount that gets transferred after the fee.
* `deposit`: whether this is a deposit or a withdrawal

### Return Values:

* token amount the user will receive

## Function `calculateRemoveLiquidityOneToken(uint256 tokenAmount, uint8 tokenIndex) → uint256` <a href="#metaswap-calculateremoveliquidityonetoken-uint256-uint8" id="metaswap-calculateremoveliquidityonetoken-uint256-uint8"></a>

Calculate the amount of underlying token available to withdraw when withdrawing via only single token

### Parameters:

* `tokenAmount`: the amount of LP token to burn
* `tokenIndex`: index of which token will be withdrawn

### Return Values:

* availableTokenAmount calculated amount of underlying token available to withdraw

## Function `initialize(contract IERC20[] _pooledTokens, uint8[] decimals, string lpTokenName, string lpTokenSymbol, uint256 _a, uint256 _fee, uint256 _adminFee, address lpTokenTargetAddress)` <a href="#metaswap-initialize-contract-ierc20-uint8-string-string-uint256-uint256-uint256-address" id="metaswap-initialize-contract-ierc20-uint8-string-string-uint256-uint256-uint256-address"></a>

This overrides Swap's initialize function to prevent initializing without the address of the base Swap contract.

### Parameters:

* `_pooledTokens`: an array of ERC20s this pool will accept
* `decimals`: the decimals to use for each pooled token, eg 8 for WBTC. Cannot be larger than POOL\_PRECISION\_DECIMALS
* `lpTokenName`: the long-form name of the token to be deployed
* `lpTokenSymbol`: the short symbol for the token to be deployed
* `_a`: the amplification coefficient \_ n \_ (n - 1). See the StableSwap paper for details
* `_fee`: default swap fee to be initialized with
* `_adminFee`: default adminFee to be initialized with

## Function `initializeMetaSwap(contract IERC20[] _pooledTokens, uint8[] decimals, string lpTokenName, string lpTokenSymbol, uint256 _a, uint256 _fee, uint256 _adminFee, address lpTokenTargetAddress, contract ISwap baseSwap)` <a href="#metaswap-initializemetaswap-contract-ierc20-uint8-string-string-uint256-uint256-uint256-address-cont" id="metaswap-initializemetaswap-contract-ierc20-uint8-string-string-uint256-uint256-uint256-address-cont"></a>

Initializes this MetaSwap contract with the given parameters. MetaSwap uses an existing Swap pool to expand the available liquidity. \_pooledTokens array should contain the base Swap pool's LP token as the last element. For example, if there is a Swap pool consisting of \[DAI, USDC, USDT]. Then a MetaSwap pool can be created with \[sUSD, BaseSwapLPToken] as \_pooledTokens.

This will also deploy the LPToken that represents users' LP position. The owner of LPToken will be this contract - which means only this contract is allowed to mint new tokens.

### Parameters:

* `_pooledTokens`: an array of ERC20s this pool will accept. The last element must be an existing Swap pool's LP token's address.
* `decimals`: the decimals to use for each pooled token, eg 8 for WBTC. Cannot be larger than POOL\_PRECISION\_DECIMALS
* `lpTokenName`: the long-form name of the token to be deployed
* `lpTokenSymbol`: the short symbol for the token to be deployed
* `_a`: the amplification coefficient \_ n \_ (n - 1). See the StableSwap paper for details
* `_fee`: default swap fee to be initialized with
* `_adminFee`: default adminFee to be initialized with

## Function `swap(uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx, uint256 minDy, uint256 deadline) → uint256` <a href="#metaswap-swap-uint8-uint8-uint256-uint256-uint256" id="metaswap-swap-uint8-uint8-uint256-uint256-uint256"></a>

Swap two tokens using this pool

### Parameters:

* `tokenIndexFrom`: the token the user wants to swap from
* `tokenIndexTo`: the token the user wants to swap to
* `dx`: the amount of tokens the user wants to swap from
* `minDy`: the min amount the user would like to receive, or revert.
* `deadline`: latest timestamp to accept this transaction

## Function `swapUnderlying(uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx, uint256 minDy, uint256 deadline) → uint256` <a href="#metaswap-swapunderlying-uint8-uint8-uint256-uint256-uint256" id="metaswap-swapunderlying-uint8-uint8-uint256-uint256-uint256"></a>

Swap two tokens using this pool and the base pool.

### Parameters:

* `tokenIndexFrom`: the token the user wants to swap from
* `tokenIndexTo`: the token the user wants to swap to
* `dx`: the amount of tokens the user wants to swap from
* `minDy`: the min amount the user would like to receive, or revert.
* `deadline`: latest timestamp to accept this transaction

## Function `addLiquidity(uint256[] amounts, uint256 minToMint, uint256 deadline) → uint256` <a href="#metaswap-addliquidity-uint256-uint256-uint256" id="metaswap-addliquidity-uint256-uint256-uint256"></a>

Add liquidity to the pool with the given amounts of tokens

### Parameters:

* `amounts`: the amounts of each token to add, in their native precision
* `minToMint`: the minimum LP tokens adding this amount of liquidity should mint, otherwise revert. Handy for front-running mitigation
* `deadline`: latest timestamp to accept this transaction

### Return Values:

* amount of LP token user minted and received

## Function `removeLiquidityOneToken(uint256 tokenAmount, uint8 tokenIndex, uint256 minAmount, uint256 deadline) → uint256` <a href="#metaswap-removeliquidityonetoken-uint256-uint8-uint256-uint256" id="metaswap-removeliquidityonetoken-uint256-uint8-uint256-uint256"></a>

Remove liquidity from the pool all in one token. Withdraw fee that decays linearly over period of 4 weeks since last deposit will apply.

### Parameters:

* `tokenAmount`: the amount of the token you want to receive
* `tokenIndex`: the index of the token you want to receive
* `minAmount`: the minimum amount to withdraw, otherwise revert
* `deadline`: latest timestamp to accept this transaction

### Return Values:

* amount of chosen token user received

## Function `removeLiquidityImbalance(uint256[] amounts, uint256 maxBurnAmount, uint256 deadline) → uint256` <a href="#metaswap-removeliquidityimbalance-uint256-uint256-uint256" id="metaswap-removeliquidityimbalance-uint256-uint256-uint256"></a>

Remove liquidity from the pool, weighted differently than the pool's current balances. Withdraw fee that decays linearly over period of 4 weeks since last deposit will apply.

### Parameters:

* `amounts`: how much of each token to withdraw
* `maxBurnAmount`: the max LP token provider is willing to pay to remove liquidity. Useful as a front-running mitigation.
* `deadline`: latest timestamp to accept this transaction

### Return Values:

* amount of LP tokens burned

## Event `TokenSwapUnderlying(address buyer, uint256 tokensSold, uint256 tokensBought, uint128 soldId, uint128 boughtId)` <a href="#metaswap-tokenswapunderlying-address-uint256-uint256-uint128-uint128" id="metaswap-tokenswapunderlying-address-uint256-uint256-uint128-uint128"></a>

No description


# MetaSwapDeposit

This contract flattens the LP token in a MetaSwap pool for easier user access. MetaSwap must be deployed before this contract can be initialized successfully.

For example, suppose there exists a base Swap pool consisting of \[DAI, USDC, USDT]. Then a MetaSwap pool can be created with \[sUSD, BaseSwapLPToken] to allow trades between either the LP token or the underlying tokens and sUSD.

MetaSwapDeposit flattens the LP token and remaps them to a single array, allowing users to ignore the dependency on BaseSwapLPToken. Using the above example, MetaSwapDeposit can act as a Swap containing \[sUSD, DAI, USDC, USDT] tokens.

## Functions:

* [`initialize(contract ISwap _baseSwap, contract IMetaSwap _metaSwap, contract IERC20 _metaLPToken)`](#MetaSwapDeposit-initialize-contract-ISwap-contract-IMetaSwap-contract-IERC20-)
* [`swap(uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx, uint256 minDy, uint256 deadline)`](#MetaSwapDeposit-swap-uint8-uint8-uint256-uint256-uint256-)
* [`addLiquidity(uint256[] amounts, uint256 minToMint, uint256 deadline)`](#MetaSwapDeposit-addLiquidity-uint256---uint256-uint256-)
* [`removeLiquidity(uint256 amount, uint256[] minAmounts, uint256 deadline)`](#MetaSwapDeposit-removeLiquidity-uint256-uint256---uint256-)
* [`removeLiquidityOneToken(uint256 tokenAmount, uint8 tokenIndex, uint256 minAmount, uint256 deadline)`](#MetaSwapDeposit-removeLiquidityOneToken-uint256-uint8-uint256-uint256-)
* [`removeLiquidityImbalance(uint256[] amounts, uint256 maxBurnAmount, uint256 deadline)`](#MetaSwapDeposit-removeLiquidityImbalance-uint256---uint256-uint256-)
* [`calculateTokenAmount(uint256[] amounts, bool deposit)`](#MetaSwapDeposit-calculateTokenAmount-uint256---bool-)
* [`calculateRemoveLiquidity(uint256 amount)`](#MetaSwapDeposit-calculateRemoveLiquidity-uint256-)
* [`calculateRemoveLiquidityOneToken(uint256 tokenAmount, uint8 tokenIndex)`](#MetaSwapDeposit-calculateRemoveLiquidityOneToken-uint256-uint8-)
* [`getToken(uint8 index)`](#MetaSwapDeposit-getToken-uint8-)
* [`calculateSwap(uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx)`](#MetaSwapDeposit-calculateSwap-uint8-uint8-uint256-)

## Function `initialize(contract ISwap _baseSwap, contract IMetaSwap _metaSwap, contract IERC20 _metaLPToken)` <a href="#metaswapdeposit-initialize-contract-iswap-contract-imetaswap-contract-ierc20" id="metaswapdeposit-initialize-contract-iswap-contract-imetaswap-contract-ierc20"></a>

Sets the address for the base Swap contract, MetaSwap contract, and the MetaSwap LP token contract.

### Parameters:

* `_baseSwap`: the address of the base Swap contract
* `_metaSwap`: the address of the MetaSwap contract
* `_metaLPToken`: the address of the MetaSwap LP token contract

## Function `swap(uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx, uint256 minDy, uint256 deadline) → uint256` <a href="#metaswapdeposit-swap-uint8-uint8-uint256-uint256-uint256" id="metaswapdeposit-swap-uint8-uint8-uint256-uint256-uint256"></a>

Swap two underlying tokens using the meta pool and the base pool

### Parameters:

* `tokenIndexFrom`: the token the user wants to swap from
* `tokenIndexTo`: the token the user wants to swap to
* `dx`: the amount of tokens the user wants to swap from
* `minDy`: the min amount the user would like to receive, or revert.
* `deadline`: latest timestamp to accept this transaction

## Function `addLiquidity(uint256[] amounts, uint256 minToMint, uint256 deadline) → uint256` <a href="#metaswapdeposit-addliquidity-uint256-uint256-uint256" id="metaswapdeposit-addliquidity-uint256-uint256-uint256"></a>

Add liquidity to the pool with the given amounts of tokens

### Parameters:

* `amounts`: the amounts of each token to add, in their native precision
* `minToMint`: the minimum LP tokens adding this amount of liquidity should mint, otherwise revert. Handy for front-running mitigation
* `deadline`: latest timestamp to accept this transaction

### Return Values:

* amount of LP token user minted and received

## Function `removeLiquidity(uint256 amount, uint256[] minAmounts, uint256 deadline) → uint256[]` <a href="#metaswapdeposit-removeliquidity-uint256-uint256-uint256" id="metaswapdeposit-removeliquidity-uint256-uint256-uint256"></a>

Burn LP tokens to remove liquidity from the pool. Withdraw fee that decays linearly over period of 4 weeks since last deposit will apply.

Liquidity can always be removed, even when the pool is paused.

### Parameters:

* `amount`: the amount of LP tokens to burn
* `minAmounts`: the minimum amounts of each token in the pool acceptable for this burn. Useful as a front-running mitigation
* `deadline`: latest timestamp to accept this transaction

### Return Values:

* amounts of tokens user received

## Function `removeLiquidityOneToken(uint256 tokenAmount, uint8 tokenIndex, uint256 minAmount, uint256 deadline) → uint256` <a href="#metaswapdeposit-removeliquidityonetoken-uint256-uint8-uint256-uint256" id="metaswapdeposit-removeliquidityonetoken-uint256-uint8-uint256-uint256"></a>

Remove liquidity from the pool all in one token. Withdraw fee that decays linearly over period of 4 weeks since last deposit will apply.

### Parameters:

* `tokenAmount`: the amount of the token you want to receive
* `tokenIndex`: the index of the token you want to receive
* `minAmount`: the minimum amount to withdraw, otherwise revert
* `deadline`: latest timestamp to accept this transaction

### Return Values:

* amount of chosen token user received

## Function `removeLiquidityImbalance(uint256[] amounts, uint256 maxBurnAmount, uint256 deadline) → uint256` <a href="#metaswapdeposit-removeliquidityimbalance-uint256-uint256-uint256" id="metaswapdeposit-removeliquidityimbalance-uint256-uint256-uint256"></a>

Remove liquidity from the pool, weighted differently than the pool's current balances. Withdraw fee that decays linearly over period of 4 weeks since last deposit will apply.

### Parameters:

* `amounts`: how much of each token to withdraw
* `maxBurnAmount`: the max LP token provider is willing to pay to remove liquidity. Useful as a front-running mitigation.
* `deadline`: latest timestamp to accept this transaction

### Return Values:

* amount of LP tokens burned

## Function `calculateTokenAmount(uint256[] amounts, bool deposit) → uint256` <a href="#metaswapdeposit-calculatetokenamount-uint256-bool" id="metaswapdeposit-calculatetokenamount-uint256-bool"></a>

A simple method to calculate prices from deposits or withdrawals, excluding fees but including slippage. This is helpful as an input into the various "min" parameters on calls to fight front-running. When withdrawing from the base pool in imbalanced fashion, the recommended slippage setting is 0.2% or higher.

This shouldn't be used outside frontends for user estimates.

### Parameters:

* `amounts`: an array of token amounts to deposit or withdrawal, corresponding to pooledTokens. The amount should be in each pooled token's native precision. If a token charges a fee on transfers, use the amount that gets transferred after the fee.
* `deposit`: whether this is a deposit or a withdrawal

### Return Values:

* token amount the user will receive

## Function `calculateRemoveLiquidity(uint256 amount) → uint256[]` <a href="#metaswapdeposit-calculateremoveliquidity-uint256" id="metaswapdeposit-calculateremoveliquidity-uint256"></a>

A simple method to calculate amount of each underlying tokens that is returned upon burning given amount of LP tokens

### Parameters:

* `amount`: the amount of LP tokens that would be burned on withdrawal

### Return Values:

* array of token balances that the user will receive

## Function `calculateRemoveLiquidityOneToken(uint256 tokenAmount, uint8 tokenIndex) → uint256` <a href="#metaswapdeposit-calculateremoveliquidityonetoken-uint256-uint8" id="metaswapdeposit-calculateremoveliquidityonetoken-uint256-uint8"></a>

Calculate the amount of underlying token available to withdraw when withdrawing via only single token

### Parameters:

* `tokenAmount`: the amount of LP token to burn
* `tokenIndex`: index of which token will be withdrawn

### Return Values:

* availableTokenAmount calculated amount of underlying token available to withdraw

## Function `getToken(uint8 index) → contract IERC20` <a href="#metaswapdeposit-gettoken-uint8" id="metaswapdeposit-gettoken-uint8"></a>

Returns the address of the pooled token at given index. Reverts if tokenIndex is out of range. This is a flattened representation of the pooled tokens.

### Parameters:

* `index`: the index of the token

### Return Values:

* address of the token at given index

## Function `calculateSwap(uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx) → uint256` <a href="#metaswapdeposit-calculateswap-uint8-uint8-uint256" id="metaswapdeposit-calculateswap-uint8-uint8-uint256"></a>

Calculate amount of tokens you receive on swap

### Parameters:

* `tokenIndexFrom`: the token the user wants to sell
* `tokenIndexTo`: the token the user wants to buy
* `dx`: the amount of tokens the user wants to sell. If the token charges a fee on transfers, use the amount that gets transferred after the fee.

### Return Values:

* amount of tokens the user will receive


# MetaSwapUtils

A library to be used within MetaSwap.sol. Contains functions responsible for custody and AMM functionalities.

MetaSwap is a modified version of Swap that allows Swap's LP token to be utilized in pooling with other tokens. As an example, if there is a Swap pool consisting of \[DAI, USDC, USDT]. Then a MetaSwap pool can be created with \[sUSD, BaseSwapLPToken] to allow trades between either the LP token or the underlying tokens and sUSD.

Contracts relying on this library must initialize SwapUtils.Swap struct then use this library for SwapUtils.Swap struct. Note that this library contains both functions called by users and admins. Admin functions should be protected within contracts using this library.

## Functions:

* [`calculateWithdrawOneToken(struct SwapUtils.Swap self, struct MetaSwapUtils.MetaSwap metaSwapStorage, uint256 tokenAmount, uint8 tokenIndex)`](#MetaSwapUtils-calculateWithdrawOneToken-struct-SwapUtils-Swap-struct-MetaSwapUtils-MetaSwap-uint256-uint8-)
* [`getVirtualPrice(struct SwapUtils.Swap self, struct MetaSwapUtils.MetaSwap metaSwapStorage)`](#MetaSwapUtils-getVirtualPrice-struct-SwapUtils-Swap-struct-MetaSwapUtils-MetaSwap-)
* [`calculateSwap(struct SwapUtils.Swap self, struct MetaSwapUtils.MetaSwap metaSwapStorage, uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx)`](#MetaSwapUtils-calculateSwap-struct-SwapUtils-Swap-struct-MetaSwapUtils-MetaSwap-uint8-uint8-uint256-)
* [`calculateSwapUnderlying(struct SwapUtils.Swap self, struct MetaSwapUtils.MetaSwap metaSwapStorage, uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx)`](#MetaSwapUtils-calculateSwapUnderlying-struct-SwapUtils-Swap-struct-MetaSwapUtils-MetaSwap-uint8-uint8-uint256-)
* [`calculateTokenAmount(struct SwapUtils.Swap self, struct MetaSwapUtils.MetaSwap metaSwapStorage, uint256[] amounts, bool deposit)`](#MetaSwapUtils-calculateTokenAmount-struct-SwapUtils-Swap-struct-MetaSwapUtils-MetaSwap-uint256---bool-)
* [`swap(struct SwapUtils.Swap self, struct MetaSwapUtils.MetaSwap metaSwapStorage, uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx, uint256 minDy)`](#MetaSwapUtils-swap-struct-SwapUtils-Swap-struct-MetaSwapUtils-MetaSwap-uint8-uint8-uint256-uint256-)
* [`swapUnderlying(struct SwapUtils.Swap self, struct MetaSwapUtils.MetaSwap metaSwapStorage, uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx, uint256 minDy)`](#MetaSwapUtils-swapUnderlying-struct-SwapUtils-Swap-struct-MetaSwapUtils-MetaSwap-uint8-uint8-uint256-uint256-)
* [`addLiquidity(struct SwapUtils.Swap self, struct MetaSwapUtils.MetaSwap metaSwapStorage, uint256[] amounts, uint256 minToMint)`](#MetaSwapUtils-addLiquidity-struct-SwapUtils-Swap-struct-MetaSwapUtils-MetaSwap-uint256---uint256-)
* [`removeLiquidityOneToken(struct SwapUtils.Swap self, struct MetaSwapUtils.MetaSwap metaSwapStorage, uint256 tokenAmount, uint8 tokenIndex, uint256 minAmount)`](#MetaSwapUtils-removeLiquidityOneToken-struct-SwapUtils-Swap-struct-MetaSwapUtils-MetaSwap-uint256-uint8-uint256-)
* [`removeLiquidityImbalance(struct SwapUtils.Swap self, struct MetaSwapUtils.MetaSwap metaSwapStorage, uint256[] amounts, uint256 maxBurnAmount)`](#MetaSwapUtils-removeLiquidityImbalance-struct-SwapUtils-Swap-struct-MetaSwapUtils-MetaSwap-uint256---uint256-)

## Events:

* [`TokenSwap(address buyer, uint256 tokensSold, uint256 tokensBought, uint128 soldId, uint128 boughtId)`](#MetaSwapUtils-TokenSwap-address-uint256-uint256-uint128-uint128-)
* [`TokenSwapUnderlying(address buyer, uint256 tokensSold, uint256 tokensBought, uint128 soldId, uint128 boughtId)`](#MetaSwapUtils-TokenSwapUnderlying-address-uint256-uint256-uint128-uint128-)
* [`AddLiquidity(address provider, uint256[] tokenAmounts, uint256[] fees, uint256 invariant, uint256 lpTokenSupply)`](#MetaSwapUtils-AddLiquidity-address-uint256---uint256---uint256-uint256-)
* [`RemoveLiquidityOne(address provider, uint256 lpTokenAmount, uint256 lpTokenSupply, uint256 boughtId, uint256 tokensBought)`](#MetaSwapUtils-RemoveLiquidityOne-address-uint256-uint256-uint256-uint256-)
* [`RemoveLiquidityImbalance(address provider, uint256[] tokenAmounts, uint256[] fees, uint256 invariant, uint256 lpTokenSupply)`](#MetaSwapUtils-RemoveLiquidityImbalance-address-uint256---uint256---uint256-uint256-)
* [`NewAdminFee(uint256 newAdminFee)`](#MetaSwapUtils-NewAdminFee-uint256-)
* [`NewSwapFee(uint256 newSwapFee)`](#MetaSwapUtils-NewSwapFee-uint256-)
* [`NewWithdrawFee(uint256 newWithdrawFee)`](#MetaSwapUtils-NewWithdrawFee-uint256-)

## Function `calculateWithdrawOneToken(struct SwapUtils.Swap self, struct MetaSwapUtils.MetaSwap metaSwapStorage, uint256 tokenAmount, uint8 tokenIndex) → uint256 dy` <a href="#metaswaputils-calculatewithdrawonetoken-struct-swaputils-swap-struct-metaswaputils-metaswap-uint256" id="metaswaputils-calculatewithdrawonetoken-struct-swaputils-swap-struct-metaswaputils-metaswap-uint256"></a>

Calculate how much the user would receive when withdrawing via single token

### Parameters:

* `self`: Swap struct to read from
* `metaSwapStorage`: MetaSwap struct to read from
* `tokenAmount`: the amount to withdraw in the pool's precision
* `tokenIndex`: which token will be withdrawn

### Return Values:

* dy the amount of token user will receive

## Function `getVirtualPrice(struct SwapUtils.Swap self, struct MetaSwapUtils.MetaSwap metaSwapStorage) → uint256` <a href="#metaswaputils-getvirtualprice-struct-swaputils-swap-struct-metaswaputils-metaswap" id="metaswaputils-getvirtualprice-struct-swaputils-swap-struct-metaswaputils-metaswap"></a>

Get the virtual price, to help calculate profit

### Parameters:

* `self`: Swap struct to read from
* `metaSwapStorage`: MetaSwap struct to read from

### Return Values:

* the virtual price, scaled to precision of BASE\_VIRTUAL\_PRICE\_PRECISION

## Function `calculateSwap(struct SwapUtils.Swap self, struct MetaSwapUtils.MetaSwap metaSwapStorage, uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx) → uint256 dy` <a href="#metaswaputils-calculateswap-struct-swaputils-swap-struct-metaswaputils-metaswap-uint8-uint8-uint256" id="metaswaputils-calculateswap-struct-swaputils-swap-struct-metaswaputils-metaswap-uint8-uint8-uint256"></a>

Externally calculates a swap between two tokens. The SwapUtils.Swap storage and MetaSwap storage should be from the same MetaSwap contract.

### Parameters:

* `self`: Swap struct to read from
* `metaSwapStorage`: MetaSwap struct from the same contract
* `tokenIndexFrom`: the token to sell
* `tokenIndexTo`: the token to buy
* `dx`: the number of tokens to sell. If the token charges a fee on transfers, use the amount that gets transferred after the fee.

### Return Values:

* dy the number of tokens the user will get

## Function `calculateSwapUnderlying(struct SwapUtils.Swap self, struct MetaSwapUtils.MetaSwap metaSwapStorage, uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx) → uint256` <a href="#metaswaputils-calculateswapunderlying-struct-swaputils-swap-struct-metaswaputils-metaswap-uint8-uint" id="metaswaputils-calculateswapunderlying-struct-swaputils-swap-struct-metaswaputils-metaswap-uint8-uint"></a>

Calculates the expected return amount from swapping between the pooled tokens and the underlying tokens of the base Swap pool.

### Parameters:

* `self`: Swap struct to read from
* `metaSwapStorage`: MetaSwap struct from the same contract
* `tokenIndexFrom`: the token to sell
* `tokenIndexTo`: the token to buy
* `dx`: the number of tokens to sell. If the token charges a fee on transfers, use the amount that gets transferred after the fee.

### Return Values:

* dy the number of tokens the user will get

## Function `calculateTokenAmount(struct SwapUtils.Swap self, struct MetaSwapUtils.MetaSwap metaSwapStorage, uint256[] amounts, bool deposit) → uint256` <a href="#metaswaputils-calculatetokenamount-struct-swaputils-swap-struct-metaswaputils-metaswap-uint256-bool" id="metaswaputils-calculatetokenamount-struct-swaputils-swap-struct-metaswaputils-metaswap-uint256-bool"></a>

A simple method to calculate prices from deposits or withdrawals, excluding fees but including slippage. This is helpful as an input into the various "min" parameters on calls to fight front-running

This shouldn't be used outside frontends for user estimates.

### Parameters:

* `self`: Swap struct to read from
* `metaSwapStorage`: MetaSwap struct to read from
* `amounts`: an array of token amounts to deposit or withdrawal, corresponding to pooledTokens. The amount should be in each pooled token's native precision. If a token charges a fee on transfers, use the amount that gets transferred after the fee.
* `deposit`: whether this is a deposit or a withdrawal

### Return Values:

* if deposit was true, total amount of lp token that will be minted and if deposit was false, total amount of lp token that will be burned

## Function `swap(struct SwapUtils.Swap self, struct MetaSwapUtils.MetaSwap metaSwapStorage, uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx, uint256 minDy) → uint256` <a href="#metaswaputils-swap-struct-swaputils-swap-struct-metaswaputils-metaswap-uint8-uint8-uint256-uint256" id="metaswaputils-swap-struct-swaputils-swap-struct-metaswaputils-metaswap-uint8-uint8-uint256-uint256"></a>

swap two tokens in the pool

### Parameters:

* `self`: Swap struct to read from and write to
* `metaSwapStorage`: MetaSwap struct to read from and write to
* `tokenIndexFrom`: the token the user wants to sell
* `tokenIndexTo`: the token the user wants to buy
* `dx`: the amount of tokens the user wants to sell
* `minDy`: the min amount the user would like to receive, or revert.

### Return Values:

* amount of token user received on swap

## Function `swapUnderlying(struct SwapUtils.Swap self, struct MetaSwapUtils.MetaSwap metaSwapStorage, uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx, uint256 minDy) → uint256` <a href="#metaswaputils-swapunderlying-struct-swaputils-swap-struct-metaswaputils-metaswap-uint8-uint8-uint256" id="metaswaputils-swapunderlying-struct-swaputils-swap-struct-metaswaputils-metaswap-uint8-uint8-uint256"></a>

Swaps with the underlying tokens of the base Swap pool. For this function, the token indices are flattened out so that underlying tokens are represented in the indices.

Since this calls multiple external functions during the execution, it is recommended to protect any function that depends on this with reentrancy guards.

### Parameters:

* `self`: Swap struct to read from and write to
* `metaSwapStorage`: MetaSwap struct to read from and write to
* `tokenIndexFrom`: the token the user wants to sell
* `tokenIndexTo`: the token the user wants to buy
* `dx`: the amount of tokens the user wants to sell
* `minDy`: the min amount the user would like to receive, or revert.

### Return Values:

* amount of token user received on swap

## Function `addLiquidity(struct SwapUtils.Swap self, struct MetaSwapUtils.MetaSwap metaSwapStorage, uint256[] amounts, uint256 minToMint) → uint256` <a href="#metaswaputils-addliquidity-struct-swaputils-swap-struct-metaswaputils-metaswap-uint256-uint256" id="metaswaputils-addliquidity-struct-swaputils-swap-struct-metaswaputils-metaswap-uint256-uint256"></a>

Add liquidity to the pool

### Parameters:

* `self`: Swap struct to read from and write to
* `metaSwapStorage`: MetaSwap struct to read from and write to
* `amounts`: the amounts of each token to add, in their native precision
* `minToMint`: the minimum LP tokens adding this amount of liquidity should mint, otherwise revert. Handy for front-running mitigation allowed addresses. If the pool is not in the guarded launch phase, this parameter will be ignored.

### Return Values:

* amount of LP token user received

## Function `removeLiquidityOneToken(struct SwapUtils.Swap self, struct MetaSwapUtils.MetaSwap metaSwapStorage, uint256 tokenAmount, uint8 tokenIndex, uint256 minAmount) → uint256` <a href="#metaswaputils-removeliquidityonetoken-struct-swaputils-swap-struct-metaswaputils-metaswap-uint256-ui" id="metaswaputils-removeliquidityonetoken-struct-swaputils-swap-struct-metaswaputils-metaswap-uint256-ui"></a>

Remove liquidity from the pool all in one token.

### Parameters:

* `self`: Swap struct to read from and write to
* `metaSwapStorage`: MetaSwap struct to read from and write to
* `tokenAmount`: the amount of the lp tokens to burn
* `tokenIndex`: the index of the token you want to receive
* `minAmount`: the minimum amount to withdraw, otherwise revert

### Return Values:

* amount chosen token that user received

## Function `removeLiquidityImbalance(struct SwapUtils.Swap self, struct MetaSwapUtils.MetaSwap metaSwapStorage, uint256[] amounts, uint256 maxBurnAmount) → uint256` <a href="#metaswaputils-removeliquidityimbalance-struct-swaputils-swap-struct-metaswaputils-metaswap-uint256-u" id="metaswaputils-removeliquidityimbalance-struct-swaputils-swap-struct-metaswaputils-metaswap-uint256-u"></a>

Remove liquidity from the pool, weighted differently than the pool's current balances.

### Parameters:

* `self`: Swap struct to read from and write to
* `metaSwapStorage`: MetaSwap struct to read from and write to
* `amounts`: how much of each token to withdraw
* `maxBurnAmount`: the max LP token provider is willing to pay to remove liquidity. Useful as a front-running mitigation.

### Return Values:

* actual amount of LP tokens burned in the withdrawal

## Event `TokenSwap(address buyer, uint256 tokensSold, uint256 tokensBought, uint128 soldId, uint128 boughtId)` <a href="#metaswaputils-tokenswap-address-uint256-uint256-uint128-uint128" id="metaswaputils-tokenswap-address-uint256-uint256-uint128-uint128"></a>

No description

## Event `TokenSwapUnderlying(address buyer, uint256 tokensSold, uint256 tokensBought, uint128 soldId, uint128 boughtId)` <a href="#metaswaputils-tokenswapunderlying-address-uint256-uint256-uint128-uint128" id="metaswaputils-tokenswapunderlying-address-uint256-uint256-uint128-uint128"></a>

No description

## Event `AddLiquidity(address provider, uint256[] tokenAmounts, uint256[] fees, uint256 invariant, uint256 lpTokenSupply)` <a href="#metaswaputils-addliquidity-address-uint256-uint256-uint256-uint256" id="metaswaputils-addliquidity-address-uint256-uint256-uint256-uint256"></a>

No description

## Event `RemoveLiquidityOne(address provider, uint256 lpTokenAmount, uint256 lpTokenSupply, uint256 boughtId, uint256 tokensBought)` <a href="#metaswaputils-removeliquidityone-address-uint256-uint256-uint256-uint256" id="metaswaputils-removeliquidityone-address-uint256-uint256-uint256-uint256"></a>

No description

## Event `RemoveLiquidityImbalance(address provider, uint256[] tokenAmounts, uint256[] fees, uint256 invariant, uint256 lpTokenSupply)` <a href="#metaswaputils-removeliquidityimbalance-address-uint256-uint256-uint256-uint256" id="metaswaputils-removeliquidityimbalance-address-uint256-uint256-uint256-uint256"></a>

No description

## Event `NewAdminFee(uint256 newAdminFee)` <a href="#metaswaputils-newadminfee-uint256" id="metaswaputils-newadminfee-uint256"></a>

No description

## Event `NewSwapFee(uint256 newSwapFee)` <a href="#metaswaputils-newswapfee-uint256" id="metaswaputils-newswapfee-uint256"></a>

No description

## Event `NewWithdrawFee(uint256 newWithdrawFee)` <a href="#metaswaputils-newwithdrawfee-uint256" id="metaswaputils-newwithdrawfee-uint256"></a>

No description


# Guarded


# SwapGuarded

This contract is responsible for custody of closely pegged assets (eg. group of stablecoins) and automatic market making system. Users become an LP (Liquidity Provider) by depositing their tokens in desired ratios for an exchange of the pool token that represents their share of the pool. Users can burn pool tokens and withdraw their share of token(s).

Each time a swap between the pooled tokens happens, a set fee incurs which effectively gets distributed to the LPs.

In case of emergencies, admin can pause additional deposits, swaps, or single-asset withdraws - which stops the ratio of the tokens in the pool from changing. Users can always withdraw their tokens via multi-asset withdraws.

Most of the logic is stored as a library `SwapUtils` for the sake of reducing contract's deployment size.

## Functions:

* [`constructor(contract IERC20[] _pooledTokens, uint8[] decimals, string lpTokenName, string lpTokenSymbol, uint256 _a, uint256 _fee, uint256 _adminFee, uint256 _withdrawFee, contract IAllowlist _allowlist)`](#SwapGuarded-constructor-contract-IERC20---uint8---string-string-uint256-uint256-uint256-uint256-contract-IAllowlist-)
* [`getA()`](#SwapGuarded-getA--)
* [`getAPrecise()`](#SwapGuarded-getAPrecise--)
* [`getToken(uint8 index)`](#SwapGuarded-getToken-uint8-)
* [`getTokenIndex(address tokenAddress)`](#SwapGuarded-getTokenIndex-address-)
* [`getAllowlist()`](#SwapGuarded-getAllowlist--)
* [`getDepositTimestamp(address user)`](#SwapGuarded-getDepositTimestamp-address-)
* [`getTokenBalance(uint8 index)`](#SwapGuarded-getTokenBalance-uint8-)
* [`getVirtualPrice()`](#SwapGuarded-getVirtualPrice--)
* [`calculateSwap(uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx)`](#SwapGuarded-calculateSwap-uint8-uint8-uint256-)
* [`calculateTokenAmount(address account, uint256[] amounts, bool deposit)`](#SwapGuarded-calculateTokenAmount-address-uint256---bool-)
* [`calculateRemoveLiquidity(address account, uint256 amount)`](#SwapGuarded-calculateRemoveLiquidity-address-uint256-)
* [`calculateRemoveLiquidityOneToken(address account, uint256 tokenAmount, uint8 tokenIndex)`](#SwapGuarded-calculateRemoveLiquidityOneToken-address-uint256-uint8-)
* [`calculateCurrentWithdrawFee(address user)`](#SwapGuarded-calculateCurrentWithdrawFee-address-)
* [`getAdminBalance(uint256 index)`](#SwapGuarded-getAdminBalance-uint256-)
* [`swap(uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx, uint256 minDy, uint256 deadline)`](#SwapGuarded-swap-uint8-uint8-uint256-uint256-uint256-)
* [`addLiquidity(uint256[] amounts, uint256 minToMint, uint256 deadline, bytes32[] merkleProof)`](#SwapGuarded-addLiquidity-uint256---uint256-uint256-bytes32---)
* [`removeLiquidity(uint256 amount, uint256[] minAmounts, uint256 deadline)`](#SwapGuarded-removeLiquidity-uint256-uint256---uint256-)
* [`removeLiquidityOneToken(uint256 tokenAmount, uint8 tokenIndex, uint256 minAmount, uint256 deadline)`](#SwapGuarded-removeLiquidityOneToken-uint256-uint8-uint256-uint256-)
* [`removeLiquidityImbalance(uint256[] amounts, uint256 maxBurnAmount, uint256 deadline)`](#SwapGuarded-removeLiquidityImbalance-uint256---uint256-uint256-)
* [`updateUserWithdrawFee(address recipient, uint256 transferAmount)`](#SwapGuarded-updateUserWithdrawFee-address-uint256-)
* [`withdrawAdminFees()`](#SwapGuarded-withdrawAdminFees--)
* [`setAdminFee(uint256 newAdminFee)`](#SwapGuarded-setAdminFee-uint256-)
* [`setSwapFee(uint256 newSwapFee)`](#SwapGuarded-setSwapFee-uint256-)
* [`setDefaultWithdrawFee(uint256 newWithdrawFee)`](#SwapGuarded-setDefaultWithdrawFee-uint256-)
* [`rampA(uint256 futureA, uint256 futureTime)`](#SwapGuarded-rampA-uint256-uint256-)
* [`stopRampA()`](#SwapGuarded-stopRampA--)
* [`disableGuard()`](#SwapGuarded-disableGuard--)
* [`isGuarded()`](#SwapGuarded-isGuarded--)

## Events:

* [`TokenSwap(address buyer, uint256 tokensSold, uint256 tokensBought, uint128 soldId, uint128 boughtId)`](#SwapGuarded-TokenSwap-address-uint256-uint256-uint128-uint128-)
* [`AddLiquidity(address provider, uint256[] tokenAmounts, uint256[] fees, uint256 invariant, uint256 lpTokenSupply)`](#SwapGuarded-AddLiquidity-address-uint256---uint256---uint256-uint256-)
* [`RemoveLiquidity(address provider, uint256[] tokenAmounts, uint256 lpTokenSupply)`](#SwapGuarded-RemoveLiquidity-address-uint256---uint256-)
* [`RemoveLiquidityOne(address provider, uint256 lpTokenAmount, uint256 lpTokenSupply, uint256 boughtId, uint256 tokensBought)`](#SwapGuarded-RemoveLiquidityOne-address-uint256-uint256-uint256-uint256-)
* [`RemoveLiquidityImbalance(address provider, uint256[] tokenAmounts, uint256[] fees, uint256 invariant, uint256 lpTokenSupply)`](#SwapGuarded-RemoveLiquidityImbalance-address-uint256---uint256---uint256-uint256-)
* [`NewAdminFee(uint256 newAdminFee)`](#SwapGuarded-NewAdminFee-uint256-)
* [`NewSwapFee(uint256 newSwapFee)`](#SwapGuarded-NewSwapFee-uint256-)
* [`NewWithdrawFee(uint256 newWithdrawFee)`](#SwapGuarded-NewWithdrawFee-uint256-)
* [`RampA(uint256 oldA, uint256 newA, uint256 initialTime, uint256 futureTime)`](#SwapGuarded-RampA-uint256-uint256-uint256-uint256-)
* [`StopRampA(uint256 currentA, uint256 time)`](#SwapGuarded-StopRampA-uint256-uint256-)

## Function `constructor(contract IERC20[] _pooledTokens, uint8[] decimals, string lpTokenName, string lpTokenSymbol, uint256 _a, uint256 _fee, uint256 _adminFee, uint256 _withdrawFee, contract IAllowlist _allowlist)` <a href="#swapguarded-constructor-contract-ierc20-uint8-string-string-uint256-uint256-uint256-uint256-contract" id="swapguarded-constructor-contract-ierc20-uint8-string-string-uint256-uint256-uint256-uint256-contract"></a>

Deploys this Swap contract with given parameters as default values. This will also deploy a LPToken that represents users LP position. The owner of LPToken will be this contract - which means only this contract is allowed to mint new tokens.

### Parameters:

* `_pooledTokens`: an array of ERC20s this pool will accept
* `decimals`: the decimals to use for each pooled token, eg 8 for WBTC. Cannot be larger than POOL\_PRECISION\_DECIMALS
* `lpTokenName`: the long-form name of the token to be deployed
* `lpTokenSymbol`: the short symbol for the token to be deployed
* `_a`: the amplification coefficient \_ n \_ (n - 1). See the StableSwap paper for details
* `_fee`: default swap fee to be initialized with
* `_adminFee`: default adminFee to be initialized with
* `_withdrawFee`: default withdrawFee to be initialized with
* `_allowlist`: address of allowlist contract for guarded launch

## Function `getA() → uint256` <a href="#swapguarded-geta" id="swapguarded-geta"></a>

Return A, the amplification coefficient \_ n \_ (n - 1)

See the StableSwap paper for details

### Return Values:

* A parameter

## Function `getAPrecise() → uint256` <a href="#swapguarded-getaprecise" id="swapguarded-getaprecise"></a>

Return A in its raw precision form

See the StableSwap paper for details

### Return Values:

* A parameter in its raw precision form

## Function `getToken(uint8 index) → contract IERC20` <a href="#swapguarded-gettoken-uint8" id="swapguarded-gettoken-uint8"></a>

Return address of the pooled token at given index. Reverts if tokenIndex is out of range.

### Parameters:

* `index`: the index of the token

### Return Values:

* address of the token at given index

## Function `getTokenIndex(address tokenAddress) → uint8` <a href="#swapguarded-gettokenindex-address" id="swapguarded-gettokenindex-address"></a>

Return the index of the given token address. Reverts if no matching token is found.

### Parameters:

* `tokenAddress`: address of the token

### Return Values:

* the index of the given token address

## Function `getAllowlist() → contract IAllowlist` <a href="#swapguarded-getallowlist" id="swapguarded-getallowlist"></a>

Reads and returns the address of the allowlist that is set during deployment of this contract

### Return Values:

* the address of the allowlist contract casted to the IAllowlist interface

## Function `getDepositTimestamp(address user) → uint256` <a href="#swapguarded-getdeposittimestamp-address" id="swapguarded-getdeposittimestamp-address"></a>

Return timestamp of last deposit of given address

### Return Values:

* timestamp of the last deposit made by the given address

## Function `getTokenBalance(uint8 index) → uint256` <a href="#swapguarded-gettokenbalance-uint8" id="swapguarded-gettokenbalance-uint8"></a>

Return current balance of the pooled token at given index

### Parameters:

* `index`: the index of the token

### Return Values:

* current balance of the pooled token at given index with token's native precision

## Function `getVirtualPrice() → uint256` <a href="#swapguarded-getvirtualprice" id="swapguarded-getvirtualprice"></a>

Get the virtual price, to help calculate profit

### Return Values:

* the virtual price, scaled to the POOL\_PRECISION\_DECIMALS

## Function `calculateSwap(uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx) → uint256` <a href="#swapguarded-calculateswap-uint8-uint8-uint256" id="swapguarded-calculateswap-uint8-uint8-uint256"></a>

Calculate amount of tokens you receive on swap

### Parameters:

* `tokenIndexFrom`: the token the user wants to sell
* `tokenIndexTo`: the token the user wants to buy
* `dx`: the amount of tokens the user wants to sell. If the token charges a fee on transfers, use the amount that gets transferred after the fee.

### Return Values:

* amount of tokens the user will receive

## Function `calculateTokenAmount(address account, uint256[] amounts, bool deposit) → uint256` <a href="#swapguarded-calculatetokenamount-address-uint256-bool" id="swapguarded-calculatetokenamount-address-uint256-bool"></a>

A simple method to calculate prices from deposits or withdrawals, excluding fees but including slippage. This is helpful as an input into the various "min" parameters on calls to fight front-running

This shouldn't be used outside frontends for user estimates.

### Parameters:

* `account`: address that is depositing or withdrawing tokens
* `amounts`: an array of token amounts to deposit or withdrawal, corresponding to pooledTokens. The amount should be in each pooled token's native precision. If a token charges a fee on transfers, use the amount that gets transferred after the fee.
* `deposit`: whether this is a deposit or a withdrawal

### Return Values:

* token amount the user will receive

## Function `calculateRemoveLiquidity(address account, uint256 amount) → uint256[]` <a href="#swapguarded-calculateremoveliquidity-address-uint256" id="swapguarded-calculateremoveliquidity-address-uint256"></a>

A simple method to calculate amount of each underlying tokens that is returned upon burning given amount of LP tokens

### Parameters:

* `account`: the address that is withdrawing tokens
* `amount`: the amount of LP tokens that would be burned on withdrawal

### Return Values:

* array of token balances that the user will receive

## Function `calculateRemoveLiquidityOneToken(address account, uint256 tokenAmount, uint8 tokenIndex) → uint256 availableTokenAmount` <a href="#swapguarded-calculateremoveliquidityonetoken-address-uint256-uint8" id="swapguarded-calculateremoveliquidityonetoken-address-uint256-uint8"></a>

Calculate the amount of underlying token available to withdraw when withdrawing via only single token

### Parameters:

* `account`: the address that is withdrawing tokens
* `tokenAmount`: the amount of LP token to burn
* `tokenIndex`: index of which token will be withdrawn

### Return Values:

* availableTokenAmount calculated amount of underlying token available to withdraw

## Function `calculateCurrentWithdrawFee(address user) → uint256` <a href="#swapguarded-calculatecurrentwithdrawfee-address" id="swapguarded-calculatecurrentwithdrawfee-address"></a>

Calculate the fee that is applied when the given user withdraws. The withdraw fee decays linearly over period of 4 weeks. For example, depositing and withdrawing right away will charge you the full amount of withdraw fee. But withdrawing after 4 weeks will charge you no additional fees.

returned value should be divided by FEE\_DENOMINATOR to convert to correct decimals

### Parameters:

* `user`: address you want to calculate withdraw fee of

### Return Values:

* current withdraw fee of the user

## Function `getAdminBalance(uint256 index) → uint256` <a href="#swapguarded-getadminbalance-uint256" id="swapguarded-getadminbalance-uint256"></a>

This function reads the accumulated amount of admin fees of the token with given index

### Parameters:

* `index`: Index of the pooled token

### Return Values:

* s token balance in the token's precision

## Function `swap(uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx, uint256 minDy, uint256 deadline) → uint256` <a href="#swapguarded-swap-uint8-uint8-uint256-uint256-uint256" id="swapguarded-swap-uint8-uint8-uint256-uint256-uint256"></a>

Swap two tokens using this pool

### Parameters:

* `tokenIndexFrom`: the token the user wants to swap from
* `tokenIndexTo`: the token the user wants to swap to
* `dx`: the amount of tokens the user wants to swap from
* `minDy`: the min amount the user would like to receive, or revert.
* `deadline`: latest timestamp to accept this transaction

## Function `addLiquidity(uint256[] amounts, uint256 minToMint, uint256 deadline, bytes32[] merkleProof) → uint256` <a href="#swapguarded-addliquidity-uint256-uint256-uint256-bytes32" id="swapguarded-addliquidity-uint256-uint256-uint256-bytes32"></a>

Add liquidity to the pool with given amounts during guarded launch phase. Only users with valid address and proof can successfully call this function. When this function is called after the guarded release phase is over, the merkleProof is ignored.

### Parameters:

* `amounts`: the amounts of each token to add, in their native precision
* `minToMint`: the minimum LP tokens adding this amount of liquidity should mint, otherwise revert. Handy for front-running mitigation
* `deadline`: latest timestamp to accept this transaction
* `merkleProof`: data generated when constructing the allowlist merkle tree. Users can get this data off chain. Even if the address is in the allowlist, users must include a valid proof for this call to succeed. If the pool is no longer in the guarded release phase, this parameter is ignored.

### Return Values:

* amount of LP token user minted and received

## Function `removeLiquidity(uint256 amount, uint256[] minAmounts, uint256 deadline) → uint256[]` <a href="#swapguarded-removeliquidity-uint256-uint256-uint256" id="swapguarded-removeliquidity-uint256-uint256-uint256"></a>

Burn LP tokens to remove liquidity from the pool. Withdraw fee that decays linearly over period of 4 weeks since last deposit will apply.

Liquidity can always be removed, even when the pool is paused.

### Parameters:

* `amount`: the amount of LP tokens to burn
* `minAmounts`: the minimum amounts of each token in the pool acceptable for this burn. Useful as a front-running mitigation
* `deadline`: latest timestamp to accept this transaction

### Return Values:

* amounts of tokens user received

## Function `removeLiquidityOneToken(uint256 tokenAmount, uint8 tokenIndex, uint256 minAmount, uint256 deadline) → uint256` <a href="#swapguarded-removeliquidityonetoken-uint256-uint8-uint256-uint256" id="swapguarded-removeliquidityonetoken-uint256-uint8-uint256-uint256"></a>

Remove liquidity from the pool all in one token. Withdraw fee that decays linearly over period of 4 weeks since last deposit will apply.

### Parameters:

* `tokenAmount`: the amount of the token you want to receive
* `tokenIndex`: the index of the token you want to receive
* `minAmount`: the minimum amount to withdraw, otherwise revert
* `deadline`: latest timestamp to accept this transaction

### Return Values:

* amount of chosen token user received

## Function `removeLiquidityImbalance(uint256[] amounts, uint256 maxBurnAmount, uint256 deadline) → uint256` <a href="#swapguarded-removeliquidityimbalance-uint256-uint256-uint256" id="swapguarded-removeliquidityimbalance-uint256-uint256-uint256"></a>

Remove liquidity from the pool, weighted differently than the pool's current balances. Withdraw fee that decays linearly over period of 4 weeks since last deposit will apply.

### Parameters:

* `amounts`: how much of each token to withdraw
* `maxBurnAmount`: the max LP token provider is willing to pay to remove liquidity. Useful as a front-running mitigation.
* `deadline`: latest timestamp to accept this transaction

### Return Values:

* amount of LP tokens burned

## Function `updateUserWithdrawFee(address recipient, uint256 transferAmount)` <a href="#swapguarded-updateuserwithdrawfee-address-uint256" id="swapguarded-updateuserwithdrawfee-address-uint256"></a>

Updates the user withdraw fee. This function can only be called by the pool token. Should be used to update the withdraw fee on transfer of pool tokens. Transferring your pool token will reset the 4 weeks period. If the recipient is already holding some pool tokens, the withdraw fee will be discounted in respective amounts.

### Parameters:

* `recipient`: address of the recipient of pool token
* `transferAmount`: amount of pool token to transfer

## Function `withdrawAdminFees()` <a href="#swapguarded-withdrawadminfees" id="swapguarded-withdrawadminfees"></a>

Withdraw all admin fees to the contract owner

## Function `setAdminFee(uint256 newAdminFee)` <a href="#swapguarded-setadminfee-uint256" id="swapguarded-setadminfee-uint256"></a>

Update the admin fee. Admin fee takes portion of the swap fee.

### Parameters:

* `newAdminFee`: new admin fee to be applied on future transactions

## Function `setSwapFee(uint256 newSwapFee)` <a href="#swapguarded-setswapfee-uint256" id="swapguarded-setswapfee-uint256"></a>

Update the swap fee to be applied on swaps

### Parameters:

* `newSwapFee`: new swap fee to be applied on future transactions

## Function `setDefaultWithdrawFee(uint256 newWithdrawFee)` <a href="#swapguarded-setdefaultwithdrawfee-uint256" id="swapguarded-setdefaultwithdrawfee-uint256"></a>

Update the withdraw fee. This fee decays linearly over 4 weeks since user's last deposit.

### Parameters:

* `newWithdrawFee`: new withdraw fee to be applied on future deposits

## Function `rampA(uint256 futureA, uint256 futureTime)` <a href="#swapguarded-rampa-uint256-uint256" id="swapguarded-rampa-uint256-uint256"></a>

Start ramping up or down A parameter towards given futureA and futureTime Checks if the change is too rapid, and commits the new A value only when it falls under the limit range.

### Parameters:

* `futureA`: the new A to ramp towards
* `futureTime`: timestamp when the new A should be reached

## Function `stopRampA()` <a href="#swapguarded-stoprampa" id="swapguarded-stoprampa"></a>

Stop ramping A immediately. Reverts if ramp A is already stopped.

## Function `disableGuard()` <a href="#swapguarded-disableguard" id="swapguarded-disableguard"></a>

Disables the guarded launch phase, removing any limits on deposit amounts and addresses

## Function `isGuarded() → bool` <a href="#swapguarded-isguarded" id="swapguarded-isguarded"></a>

Reads and returns current guarded status of the pool

### Return Values:

* guarded\_ boolean value indicating whether the deposits should be guarded

## Event `TokenSwap(address buyer, uint256 tokensSold, uint256 tokensBought, uint128 soldId, uint128 boughtId)` <a href="#swapguarded-tokenswap-address-uint256-uint256-uint128-uint128" id="swapguarded-tokenswap-address-uint256-uint256-uint128-uint128"></a>

No description

## Event `AddLiquidity(address provider, uint256[] tokenAmounts, uint256[] fees, uint256 invariant, uint256 lpTokenSupply)` <a href="#swapguarded-addliquidity-address-uint256-uint256-uint256-uint256" id="swapguarded-addliquidity-address-uint256-uint256-uint256-uint256"></a>

No description

## Event `RemoveLiquidity(address provider, uint256[] tokenAmounts, uint256 lpTokenSupply)` <a href="#swapguarded-removeliquidity-address-uint256-uint256" id="swapguarded-removeliquidity-address-uint256-uint256"></a>

No description

## Event `RemoveLiquidityOne(address provider, uint256 lpTokenAmount, uint256 lpTokenSupply, uint256 boughtId, uint256 tokensBought)` <a href="#swapguarded-removeliquidityone-address-uint256-uint256-uint256-uint256" id="swapguarded-removeliquidityone-address-uint256-uint256-uint256-uint256"></a>

No description

## Event `RemoveLiquidityImbalance(address provider, uint256[] tokenAmounts, uint256[] fees, uint256 invariant, uint256 lpTokenSupply)` <a href="#swapguarded-removeliquidityimbalance-address-uint256-uint256-uint256-uint256" id="swapguarded-removeliquidityimbalance-address-uint256-uint256-uint256-uint256"></a>

No description

## Event `NewAdminFee(uint256 newAdminFee)` <a href="#swapguarded-newadminfee-uint256" id="swapguarded-newadminfee-uint256"></a>

No description

## Event `NewSwapFee(uint256 newSwapFee)` <a href="#swapguarded-newswapfee-uint256" id="swapguarded-newswapfee-uint256"></a>

No description

## Event `NewWithdrawFee(uint256 newWithdrawFee)` <a href="#swapguarded-newwithdrawfee-uint256" id="swapguarded-newwithdrawfee-uint256"></a>

No description

## Event `RampA(uint256 oldA, uint256 newA, uint256 initialTime, uint256 futureTime)` <a href="#swapguarded-rampa-uint256-uint256-uint256-uint256" id="swapguarded-rampa-uint256-uint256-uint256-uint256"></a>

No description

## Event `StopRampA(uint256 currentA, uint256 time)` <a href="#swapguarded-stoprampa-uint256-uint256" id="swapguarded-stoprampa-uint256-uint256"></a>

No description


# SwapUtilsGuarded

A library to be used within Swap.sol. Contains functions responsible for custody and AMM functionalities.

Contracts relying on this library must initialize SwapUtils.Swap struct then use this library for SwapUtils.Swap struct. Note that this library contains both functions called by users and admins. Admin functions should be protected within contracts using this library.

## Functions:

* [`getA(struct SwapUtilsGuarded.Swap self)`](#SwapUtilsGuarded-getA-struct-SwapUtilsGuarded-Swap-)
* [`getAPrecise(struct SwapUtilsGuarded.Swap self)`](#SwapUtilsGuarded-getAPrecise-struct-SwapUtilsGuarded-Swap-)
* [`getDepositTimestamp(struct SwapUtilsGuarded.Swap self, address user)`](#SwapUtilsGuarded-getDepositTimestamp-struct-SwapUtilsGuarded-Swap-address-)
* [`calculateWithdrawOneToken(struct SwapUtilsGuarded.Swap self, address account, uint256 tokenAmount, uint8 tokenIndex)`](#SwapUtilsGuarded-calculateWithdrawOneToken-struct-SwapUtilsGuarded-Swap-address-uint256-uint8-)
* [`getVirtualPrice(struct SwapUtilsGuarded.Swap self)`](#SwapUtilsGuarded-getVirtualPrice-struct-SwapUtilsGuarded-Swap-)
* [`calculateSwap(struct SwapUtilsGuarded.Swap self, uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx)`](#SwapUtilsGuarded-calculateSwap-struct-SwapUtilsGuarded-Swap-uint8-uint8-uint256-)
* [`calculateRemoveLiquidity(struct SwapUtilsGuarded.Swap self, address account, uint256 amount)`](#SwapUtilsGuarded-calculateRemoveLiquidity-struct-SwapUtilsGuarded-Swap-address-uint256-)
* [`calculateCurrentWithdrawFee(struct SwapUtilsGuarded.Swap self, address user)`](#SwapUtilsGuarded-calculateCurrentWithdrawFee-struct-SwapUtilsGuarded-Swap-address-)
* [`calculateTokenAmount(struct SwapUtilsGuarded.Swap self, address account, uint256[] amounts, bool deposit)`](#SwapUtilsGuarded-calculateTokenAmount-struct-SwapUtilsGuarded-Swap-address-uint256---bool-)
* [`getAdminBalance(struct SwapUtilsGuarded.Swap self, uint256 index)`](#SwapUtilsGuarded-getAdminBalance-struct-SwapUtilsGuarded-Swap-uint256-)
* [`swap(struct SwapUtilsGuarded.Swap self, uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx, uint256 minDy)`](#SwapUtilsGuarded-swap-struct-SwapUtilsGuarded-Swap-uint8-uint8-uint256-uint256-)
* [`addLiquidity(struct SwapUtilsGuarded.Swap self, uint256[] amounts, uint256 minToMint, bytes32[] merkleProof)`](#SwapUtilsGuarded-addLiquidity-struct-SwapUtilsGuarded-Swap-uint256---uint256-bytes32---)
* [`updateUserWithdrawFee(struct SwapUtilsGuarded.Swap self, address user, uint256 toMint)`](#SwapUtilsGuarded-updateUserWithdrawFee-struct-SwapUtilsGuarded-Swap-address-uint256-)
* [`removeLiquidity(struct SwapUtilsGuarded.Swap self, uint256 amount, uint256[] minAmounts)`](#SwapUtilsGuarded-removeLiquidity-struct-SwapUtilsGuarded-Swap-uint256-uint256---)
* [`removeLiquidityOneToken(struct SwapUtilsGuarded.Swap self, uint256 tokenAmount, uint8 tokenIndex, uint256 minAmount)`](#SwapUtilsGuarded-removeLiquidityOneToken-struct-SwapUtilsGuarded-Swap-uint256-uint8-uint256-)
* [`removeLiquidityImbalance(struct SwapUtilsGuarded.Swap self, uint256[] amounts, uint256 maxBurnAmount)`](#SwapUtilsGuarded-removeLiquidityImbalance-struct-SwapUtilsGuarded-Swap-uint256---uint256-)
* [`withdrawAdminFees(struct SwapUtilsGuarded.Swap self, address to)`](#SwapUtilsGuarded-withdrawAdminFees-struct-SwapUtilsGuarded-Swap-address-)
* [`setAdminFee(struct SwapUtilsGuarded.Swap self, uint256 newAdminFee)`](#SwapUtilsGuarded-setAdminFee-struct-SwapUtilsGuarded-Swap-uint256-)
* [`setSwapFee(struct SwapUtilsGuarded.Swap self, uint256 newSwapFee)`](#SwapUtilsGuarded-setSwapFee-struct-SwapUtilsGuarded-Swap-uint256-)
* [`setDefaultWithdrawFee(struct SwapUtilsGuarded.Swap self, uint256 newWithdrawFee)`](#SwapUtilsGuarded-setDefaultWithdrawFee-struct-SwapUtilsGuarded-Swap-uint256-)
* [`rampA(struct SwapUtilsGuarded.Swap self, uint256 futureA_, uint256 futureTime_)`](#SwapUtilsGuarded-rampA-struct-SwapUtilsGuarded-Swap-uint256-uint256-)
* [`stopRampA(struct SwapUtilsGuarded.Swap self)`](#SwapUtilsGuarded-stopRampA-struct-SwapUtilsGuarded-Swap-)

## Events:

* [`TokenSwap(address buyer, uint256 tokensSold, uint256 tokensBought, uint128 soldId, uint128 boughtId)`](#SwapUtilsGuarded-TokenSwap-address-uint256-uint256-uint128-uint128-)
* [`AddLiquidity(address provider, uint256[] tokenAmounts, uint256[] fees, uint256 invariant, uint256 lpTokenSupply)`](#SwapUtilsGuarded-AddLiquidity-address-uint256---uint256---uint256-uint256-)
* [`RemoveLiquidity(address provider, uint256[] tokenAmounts, uint256 lpTokenSupply)`](#SwapUtilsGuarded-RemoveLiquidity-address-uint256---uint256-)
* [`RemoveLiquidityOne(address provider, uint256 lpTokenAmount, uint256 lpTokenSupply, uint256 boughtId, uint256 tokensBought)`](#SwapUtilsGuarded-RemoveLiquidityOne-address-uint256-uint256-uint256-uint256-)
* [`RemoveLiquidityImbalance(address provider, uint256[] tokenAmounts, uint256[] fees, uint256 invariant, uint256 lpTokenSupply)`](#SwapUtilsGuarded-RemoveLiquidityImbalance-address-uint256---uint256---uint256-uint256-)
* [`NewAdminFee(uint256 newAdminFee)`](#SwapUtilsGuarded-NewAdminFee-uint256-)
* [`NewSwapFee(uint256 newSwapFee)`](#SwapUtilsGuarded-NewSwapFee-uint256-)
* [`NewWithdrawFee(uint256 newWithdrawFee)`](#SwapUtilsGuarded-NewWithdrawFee-uint256-)
* [`RampA(uint256 oldA, uint256 newA, uint256 initialTime, uint256 futureTime)`](#SwapUtilsGuarded-RampA-uint256-uint256-uint256-uint256-)
* [`StopRampA(uint256 currentA, uint256 time)`](#SwapUtilsGuarded-StopRampA-uint256-uint256-)

## Function `getA(struct SwapUtilsGuarded.Swap self) → uint256` <a href="#swaputilsguarded-geta-struct-swaputilsguarded-swap" id="swaputilsguarded-geta-struct-swaputilsguarded-swap"></a>

Return A, the amplification coefficient \_ n \_ (n - 1)

See the StableSwap paper for details

### Parameters:

* `self`: Swap struct to read from

### Return Values:

* A parameter

## Function `getAPrecise(struct SwapUtilsGuarded.Swap self) → uint256` <a href="#swaputilsguarded-getaprecise-struct-swaputilsguarded-swap" id="swaputilsguarded-getaprecise-struct-swaputilsguarded-swap"></a>

Return A in its raw precision

See the StableSwap paper for details

### Parameters:

* `self`: Swap struct to read from

### Return Values:

* A parameter in its raw precision form

## Function `getDepositTimestamp(struct SwapUtilsGuarded.Swap self, address user) → uint256` <a href="#swaputilsguarded-getdeposittimestamp-struct-swaputilsguarded-swap-address" id="swaputilsguarded-getdeposittimestamp-struct-swaputilsguarded-swap-address"></a>

Retrieves the timestamp of last deposit made by the given address

### Parameters:

* `self`: Swap struct to read from

### Return Values:

* timestamp of last deposit

## Function `calculateWithdrawOneToken(struct SwapUtilsGuarded.Swap self, address account, uint256 tokenAmount, uint8 tokenIndex) → uint256, uint256` <a href="#swaputilsguarded-calculatewithdrawonetoken-struct-swaputilsguarded-swap-address-uint256-uint8" id="swaputilsguarded-calculatewithdrawonetoken-struct-swaputilsguarded-swap-address-uint256-uint8"></a>

Calculate the dy, the amount of selected token that user receives and the fee of withdrawing in one token

### Parameters:

* `account`: the address that is withdrawing
* `tokenAmount`: the amount to withdraw in the pool's precision
* `tokenIndex`: which token will be withdrawn
* `self`: Swap struct to read from

### Return Values:

* the amount of token user will receive and the associated swap fee

## Function `getVirtualPrice(struct SwapUtilsGuarded.Swap self) → uint256` <a href="#swaputilsguarded-getvirtualprice-struct-swaputilsguarded-swap" id="swaputilsguarded-getvirtualprice-struct-swaputilsguarded-swap"></a>

Get the virtual price, to help calculate profit

### Parameters:

* `self`: Swap struct to read from

### Return Values:

* the virtual price, scaled to precision of POOL\_PRECISION\_DECIMALS

## Function `calculateSwap(struct SwapUtilsGuarded.Swap self, uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx) → uint256 dy` <a href="#swaputilsguarded-calculateswap-struct-swaputilsguarded-swap-uint8-uint8-uint256" id="swaputilsguarded-calculateswap-struct-swaputilsguarded-swap-uint8-uint8-uint256"></a>

Externally calculates a swap between two tokens.

### Parameters:

* `self`: Swap struct to read from
* `tokenIndexFrom`: the token to sell
* `tokenIndexTo`: the token to buy
* `dx`: the number of tokens to sell. If the token charges a fee on transfers, use the amount that gets transferred after the fee.

### Return Values:

* dy the number of tokens the user will get

## Function `calculateRemoveLiquidity(struct SwapUtilsGuarded.Swap self, address account, uint256 amount) → uint256[]` <a href="#swaputilsguarded-calculateremoveliquidity-struct-swaputilsguarded-swap-address-uint256" id="swaputilsguarded-calculateremoveliquidity-struct-swaputilsguarded-swap-address-uint256"></a>

A simple method to calculate amount of each underlying tokens that is returned upon burning given amount of LP tokens

### Parameters:

* `account`: the address that is removing liquidity. required for withdraw fee calculation
* `amount`: the amount of LP tokens that would to be burned on withdrawal

### Return Values:

* array of amounts of tokens user will receive

## Function `calculateCurrentWithdrawFee(struct SwapUtilsGuarded.Swap self, address user) → uint256` <a href="#swaputilsguarded-calculatecurrentwithdrawfee-struct-swaputilsguarded-swap-address" id="swaputilsguarded-calculatecurrentwithdrawfee-struct-swaputilsguarded-swap-address"></a>

Calculate the fee that is applied when the given user withdraws. Withdraw fee decays linearly over 4 weeks.

### Parameters:

* `user`: address you want to calculate withdraw fee of

### Return Values:

* current withdraw fee of the user

## Function `calculateTokenAmount(struct SwapUtilsGuarded.Swap self, address account, uint256[] amounts, bool deposit) → uint256` <a href="#swaputilsguarded-calculatetokenamount-struct-swaputilsguarded-swap-address-uint256-bool" id="swaputilsguarded-calculatetokenamount-struct-swaputilsguarded-swap-address-uint256-bool"></a>

A simple method to calculate prices from deposits or withdrawals, excluding fees but including slippage. This is helpful as an input into the various "min" parameters on calls to fight front-running

This shouldn't be used outside frontends for user estimates.

### Parameters:

* `self`: Swap struct to read from
* `account`: address of the account depositing or withdrawing tokens
* `amounts`: an array of token amounts to deposit or withdrawal, corresponding to pooledTokens. The amount should be in each pooled token's native precision. If a token charges a fee on transfers, use the amount that gets transferred after the fee.
* `deposit`: whether this is a deposit or a withdrawal

### Return Values:

* if deposit was true, total amount of lp token that will be minted and if deposit was false, total amount of lp token that will be burned

## Function `getAdminBalance(struct SwapUtilsGuarded.Swap self, uint256 index) → uint256` <a href="#swaputilsguarded-getadminbalance-struct-swaputilsguarded-swap-uint256" id="swaputilsguarded-getadminbalance-struct-swaputilsguarded-swap-uint256"></a>

return accumulated amount of admin fees of the token with given index

### Parameters:

* `self`: Swap struct to read from
* `index`: Index of the pooled token

### Return Values:

* admin balance in the token's precision

## Function `swap(struct SwapUtilsGuarded.Swap self, uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx, uint256 minDy) → uint256` <a href="#swaputilsguarded-swap-struct-swaputilsguarded-swap-uint8-uint8-uint256-uint256" id="swaputilsguarded-swap-struct-swaputilsguarded-swap-uint8-uint8-uint256-uint256"></a>

swap two tokens in the pool

### Parameters:

* `self`: Swap struct to read from and write to
* `tokenIndexFrom`: the token the user wants to sell
* `tokenIndexTo`: the token the user wants to buy
* `dx`: the amount of tokens the user wants to sell
* `minDy`: the min amount the user would like to receive, or revert.

### Return Values:

* amount of token user received on swap

## Function `addLiquidity(struct SwapUtilsGuarded.Swap self, uint256[] amounts, uint256 minToMint, bytes32[] merkleProof) → uint256` <a href="#swaputilsguarded-addliquidity-struct-swaputilsguarded-swap-uint256-uint256-bytes32" id="swaputilsguarded-addliquidity-struct-swaputilsguarded-swap-uint256-uint256-bytes32"></a>

Add liquidity to the pool

### Parameters:

* `self`: Swap struct to read from and write to
* `amounts`: the amounts of each token to add, in their native precision
* `minToMint`: the minimum LP tokens adding this amount of liquidity should mint, otherwise revert. Handy for front-running mitigation
* `merkleProof`: bytes32 array that will be used to prove the existence of the caller's address in the list of allowed addresses. If the pool is not in the guarded launch phase, this parameter will be ignored.

### Return Values:

* amount of LP token user received

## Function `updateUserWithdrawFee(struct SwapUtilsGuarded.Swap self, address user, uint256 toMint)` <a href="#swaputilsguarded-updateuserwithdrawfee-struct-swaputilsguarded-swap-address-uint256" id="swaputilsguarded-updateuserwithdrawfee-struct-swaputilsguarded-swap-address-uint256"></a>

Update the withdraw fee for `user`. If the user is currently not providing liquidity in the pool, sets to default value. If not, recalculate the starting withdraw fee based on the last deposit's time & amount relative to the new deposit.

### Parameters:

* `self`: Swap struct to read from and write to
* `user`: address of the user depositing tokens
* `toMint`: amount of pool tokens to be minted

## Function `removeLiquidity(struct SwapUtilsGuarded.Swap self, uint256 amount, uint256[] minAmounts) → uint256[]` <a href="#swaputilsguarded-removeliquidity-struct-swaputilsguarded-swap-uint256-uint256" id="swaputilsguarded-removeliquidity-struct-swaputilsguarded-swap-uint256-uint256"></a>

Burn LP tokens to remove liquidity from the pool.

Liquidity can always be removed, even when the pool is paused.

### Parameters:

* `self`: Swap struct to read from and write to
* `amount`: the amount of LP tokens to burn
* `minAmounts`: the minimum amounts of each token in the pool acceptable for this burn. Useful as a front-running mitigation

### Return Values:

* amounts of tokens the user received

## Function `removeLiquidityOneToken(struct SwapUtilsGuarded.Swap self, uint256 tokenAmount, uint8 tokenIndex, uint256 minAmount) → uint256` <a href="#swaputilsguarded-removeliquidityonetoken-struct-swaputilsguarded-swap-uint256-uint8-uint256" id="swaputilsguarded-removeliquidityonetoken-struct-swaputilsguarded-swap-uint256-uint8-uint256"></a>

Remove liquidity from the pool all in one token.

### Parameters:

* `self`: Swap struct to read from and write to
* `tokenAmount`: the amount of the lp tokens to burn
* `tokenIndex`: the index of the token you want to receive
* `minAmount`: the minimum amount to withdraw, otherwise revert

### Return Values:

* amount chosen token that user received

## Function `removeLiquidityImbalance(struct SwapUtilsGuarded.Swap self, uint256[] amounts, uint256 maxBurnAmount) → uint256` <a href="#swaputilsguarded-removeliquidityimbalance-struct-swaputilsguarded-swap-uint256-uint256" id="swaputilsguarded-removeliquidityimbalance-struct-swaputilsguarded-swap-uint256-uint256"></a>

Remove liquidity from the pool, weighted differently than the pool's current balances.

### Parameters:

* `self`: Swap struct to read from and write to
* `amounts`: how much of each token to withdraw
* `maxBurnAmount`: the max LP token provider is willing to pay to remove liquidity. Useful as a front-running mitigation.

### Return Values:

* actual amount of LP tokens burned in the withdrawal

## Function `withdrawAdminFees(struct SwapUtilsGuarded.Swap self, address to)` <a href="#swaputilsguarded-withdrawadminfees-struct-swaputilsguarded-swap-address" id="swaputilsguarded-withdrawadminfees-struct-swaputilsguarded-swap-address"></a>

withdraw all admin fees to a given address

### Parameters:

* `self`: Swap struct to withdraw fees from
* `to`: Address to send the fees to

## Function `setAdminFee(struct SwapUtilsGuarded.Swap self, uint256 newAdminFee)` <a href="#swaputilsguarded-setadminfee-struct-swaputilsguarded-swap-uint256" id="swaputilsguarded-setadminfee-struct-swaputilsguarded-swap-uint256"></a>

Sets the admin fee

adminFee cannot be higher than 100% of the swap fee

### Parameters:

* `self`: Swap struct to update
* `newAdminFee`: new admin fee to be applied on future transactions

## Function `setSwapFee(struct SwapUtilsGuarded.Swap self, uint256 newSwapFee)` <a href="#swaputilsguarded-setswapfee-struct-swaputilsguarded-swap-uint256" id="swaputilsguarded-setswapfee-struct-swaputilsguarded-swap-uint256"></a>

update the swap fee

fee cannot be higher than 1% of each swap

### Parameters:

* `self`: Swap struct to update
* `newSwapFee`: new swap fee to be applied on future transactions

## Function `setDefaultWithdrawFee(struct SwapUtilsGuarded.Swap self, uint256 newWithdrawFee)` <a href="#swaputilsguarded-setdefaultwithdrawfee-struct-swaputilsguarded-swap-uint256" id="swaputilsguarded-setdefaultwithdrawfee-struct-swaputilsguarded-swap-uint256"></a>

update the default withdraw fee. This also affects deposits made in the past as well.

### Parameters:

* `self`: Swap struct to update
* `newWithdrawFee`: new withdraw fee to be applied

## Function `rampA(struct SwapUtilsGuarded.Swap self, uint256 futureA_, uint256 futureTime_)` <a href="#swaputilsguarded-rampa-struct-swaputilsguarded-swap-uint256-uint256" id="swaputilsguarded-rampa-struct-swaputilsguarded-swap-uint256-uint256"></a>

Start ramping up or down A parameter towards given futureA\* and futureTime\* Checks if the change is too rapid, and commits the new A value only when it falls under the limit range.

### Parameters:

* `self`: Swap struct to update
* `futureA_`: the new A to ramp towards
* `futureTime_`: timestamp when the new A should be reached

## Function `stopRampA(struct SwapUtilsGuarded.Swap self)` <a href="#swaputilsguarded-stoprampa-struct-swaputilsguarded-swap" id="swaputilsguarded-stoprampa-struct-swaputilsguarded-swap"></a>

Stops ramping A immediately. Once this function is called, rampA() cannot be called for another 24 hours

### Parameters:

* `self`: Swap struct to update

## Event `TokenSwap(address buyer, uint256 tokensSold, uint256 tokensBought, uint128 soldId, uint128 boughtId)` <a href="#swaputilsguarded-tokenswap-address-uint256-uint256-uint128-uint128" id="swaputilsguarded-tokenswap-address-uint256-uint256-uint128-uint128"></a>

No description

## Event `AddLiquidity(address provider, uint256[] tokenAmounts, uint256[] fees, uint256 invariant, uint256 lpTokenSupply)` <a href="#swaputilsguarded-addliquidity-address-uint256-uint256-uint256-uint256" id="swaputilsguarded-addliquidity-address-uint256-uint256-uint256-uint256"></a>

No description

## Event `RemoveLiquidity(address provider, uint256[] tokenAmounts, uint256 lpTokenSupply)` <a href="#swaputilsguarded-removeliquidity-address-uint256-uint256" id="swaputilsguarded-removeliquidity-address-uint256-uint256"></a>

No description

## Event `RemoveLiquidityOne(address provider, uint256 lpTokenAmount, uint256 lpTokenSupply, uint256 boughtId, uint256 tokensBought)` <a href="#swaputilsguarded-removeliquidityone-address-uint256-uint256-uint256-uint256" id="swaputilsguarded-removeliquidityone-address-uint256-uint256-uint256-uint256"></a>

No description

## Event `RemoveLiquidityImbalance(address provider, uint256[] tokenAmounts, uint256[] fees, uint256 invariant, uint256 lpTokenSupply)` <a href="#swaputilsguarded-removeliquidityimbalance-address-uint256-uint256-uint256-uint256" id="swaputilsguarded-removeliquidityimbalance-address-uint256-uint256-uint256-uint256"></a>

No description

## Event `NewAdminFee(uint256 newAdminFee)` <a href="#swaputilsguarded-newadminfee-uint256" id="swaputilsguarded-newadminfee-uint256"></a>

No description

## Event `NewSwapFee(uint256 newSwapFee)` <a href="#swaputilsguarded-newswapfee-uint256" id="swaputilsguarded-newswapfee-uint256"></a>

No description

## Event `NewWithdrawFee(uint256 newWithdrawFee)` <a href="#swaputilsguarded-newwithdrawfee-uint256" id="swaputilsguarded-newwithdrawfee-uint256"></a>

No description

## Event `RampA(uint256 oldA, uint256 newA, uint256 initialTime, uint256 futureTime)` <a href="#swaputilsguarded-rampa-uint256-uint256-uint256-uint256" id="swaputilsguarded-rampa-uint256-uint256-uint256-uint256"></a>

No description

## Event `StopRampA(uint256 currentA, uint256 time)` <a href="#swaputilsguarded-stoprampa-uint256-uint256" id="swaputilsguarded-stoprampa-uint256-uint256"></a>

No description


# OwnerPausable

An ownable contract allows the owner to pause and unpause the contract without a delay.

Only methods using the provided modifiers will be paused.

## Functions:

* [`pause()`](#OwnerPausable-pause--)
* [`unpause()`](#OwnerPausable-unpause--)

## Function `pause()` <a href="#ownerpausable-pause" id="ownerpausable-pause"></a>

Pause the contract. Revert if already paused.

## Function `unpause()` <a href="#ownerpausable-unpause" id="ownerpausable-unpause"></a>

Unpause the contract. Revert if already unpaused.


# LPTokenGuarded

This token is an ERC20 detailed token with added capability to be minted by the owner. It is used to represent user's shares when providing liquidity to swap contracts.

## Functions:

* [`constructor(string name_, string symbol_, uint8 decimals_)`](#LPTokenGuarded-constructor-string-string-uint8-)
* [`mint(address recipient, uint256 amount, bytes32[] merkleProof)`](#LPTokenGuarded-mint-address-uint256-bytes32---)

## Function `constructor(string name_, string symbol_, uint8 decimals_)` <a href="#lptokenguarded-constructor-string-string-uint8" id="lptokenguarded-constructor-string-string-uint8"></a>

Deploys LPToken contract with given name, symbol, and decimals

the caller of this constructor will become the owner of this contract

### Parameters:

* `name_`: name of this token
* `symbol_`: symbol of this token
* `decimals_`: number of decimals this token will be based on

## Function `mint(address recipient, uint256 amount, bytes32[] merkleProof)` <a href="#lptokenguarded-mint-address-uint256-bytes32" id="lptokenguarded-mint-address-uint256-bytes32"></a>

Mints the given amount of LPToken to the recipient. During the guarded release phase, the total supply and the maximum number of the tokens that a single account can mint are limited.

only owner can call this mint function

### Parameters:

* `recipient`: address of account to receive the tokens
* `amount`: amount of tokens to mint
* `merkleProof`: the bytes32 array data that is used to prove recipient's address exists in the merkle tree stored in the allowlist contract. If the pool is not guarded, this parameter is ignored.


# Allowlist

This contract is a registry holding information about how much each swap contract should contain upto. Swap.sol will rely on this contract to determine whether the pool cap is reached and also whether a user's deposit limit is reached.

## Functions:

* [`constructor(bytes32 merkleRoot_)`](#Allowlist-constructor-bytes32-)
* [`getPoolAccountLimit(address poolAddress)`](#Allowlist-getPoolAccountLimit-address-)
* [`getPoolCap(address poolAddress)`](#Allowlist-getPoolCap-address-)
* [`isAccountVerified(address account)`](#Allowlist-isAccountVerified-address-)
* [`verifyAddress(address account, bytes32[] merkleProof)`](#Allowlist-verifyAddress-address-bytes32---)
* [`setPoolAccountLimit(address poolAddress, uint256 accountLimit)`](#Allowlist-setPoolAccountLimit-address-uint256-)
* [`setPoolCap(address poolAddress, uint256 poolCap)`](#Allowlist-setPoolCap-address-uint256-)
* [`updateMerkleRoot(bytes32 merkleRoot_)`](#Allowlist-updateMerkleRoot-bytes32-)

## Events:

* [`PoolCap(address poolAddress, uint256 poolCap)`](#Allowlist-PoolCap-address-uint256-)
* [`PoolAccountLimit(address poolAddress, uint256 accountLimit)`](#Allowlist-PoolAccountLimit-address-uint256-)
* [`NewMerkleRoot(bytes32 merkleRoot)`](#Allowlist-NewMerkleRoot-bytes32-)

## Function `constructor(bytes32 merkleRoot_)` <a href="#allowlist-constructor-bytes32" id="allowlist-constructor-bytes32"></a>

Creates this contract and sets the PoolCap of 0x0 with uint256(0x54dd1e) for crude checking whether an address holds this contract.

### Parameters:

* `merkleRoot_`: bytes32 that represent a merkle root node. This is generated off chain with the list of qualifying addresses.

## Function `getPoolAccountLimit(address poolAddress) → uint256` <a href="#allowlist-getpoolaccountlimit-address" id="allowlist-getpoolaccountlimit-address"></a>

Returns the max mintable amount of the lp token per account in given pool address.

### Parameters:

* `poolAddress`: address of the pool

### Return Values:

* max mintable amount of the lp token per account

## Function `getPoolCap(address poolAddress) → uint256` <a href="#allowlist-getpoolcap-address" id="allowlist-getpoolcap-address"></a>

Returns the maximum total supply of the pool token for the given pool address.

### Parameters:

* `poolAddress`: address of the pool

## Function `isAccountVerified(address account) → bool` <a href="#allowlist-isaccountverified-address" id="allowlist-isaccountverified-address"></a>

Returns true if the given account's existence has been verified against any of the past or the present merkle tree. Note that if it has been verified in the past, this function will return true even if the current merkle tree does not contain the account.

### Parameters:

* `account`: the address to check if it has been verified

### Return Values:

* a boolean value representing whether the account has been verified in the past or the present merkle tree

## Function `verifyAddress(address account, bytes32[] merkleProof) → bool` <a href="#allowlist-verifyaddress-address-bytes32" id="allowlist-verifyaddress-address-bytes32"></a>

Checks the existence of keccak256(account) as a node in the merkle tree inferred by the merkle root node stored in this contract. Pools should use this function to check if the given address qualifies for depositing. If the given account has already been verified with the correct merkleProof, this function will return true when merkleProof is empty. The verified status will be overwritten if the previously verified user calls this function with an incorrect merkleProof.

### Parameters:

* `account`: address to confirm its existence in the merkle tree
* `merkleProof`: data that is used to prove the existence of given parameters. This is generated during the creation of the merkle tree. Users should retrieve this data off-chain.

### Return Values:

* a boolean value that corresponds to whether the address with the proof has been verified in the past or if they exist in the current merkle tree.

## Function `setPoolAccountLimit(address poolAddress, uint256 accountLimit)` <a href="#allowlist-setpoolaccountlimit-address-uint256" id="allowlist-setpoolaccountlimit-address-uint256"></a>

Sets the account limit of allowed deposit amounts for the given pool

### Parameters:

* `poolAddress`: address of the pool
* `accountLimit`: the max number of the pool token a single user can mint

## Function `setPoolCap(address poolAddress, uint256 poolCap)` <a href="#allowlist-setpoolcap-address-uint256" id="allowlist-setpoolcap-address-uint256"></a>

Sets the max total supply of LPToken for the given pool address

### Parameters:

* `poolAddress`: address of the pool
* `poolCap`: the max total supply of the pool token

## Function `updateMerkleRoot(bytes32 merkleRoot_)` <a href="#allowlist-updatemerkleroot-bytes32" id="allowlist-updatemerkleroot-bytes32"></a>

Updates the merkle root that is stored in this contract. This can only be called by the owner. If more addresses are added to the list, a new merkle tree and a merkle root node should be generated, and merkleRoot should be updated accordingly.

### Parameters:

* `merkleRoot_`: a new merkle root node that contains a list of deposit allowed addresses

## Event `PoolCap(address poolAddress, uint256 poolCap)` <a href="#allowlist-poolcap-address-uint256" id="allowlist-poolcap-address-uint256"></a>

No description

## Event `PoolAccountLimit(address poolAddress, uint256 accountLimit)` <a href="#allowlist-poolaccountlimit-address-uint256" id="allowlist-poolaccountlimit-address-uint256"></a>

No description

## Event `NewMerkleRoot(bytes32 merkleRoot)` <a href="#allowlist-newmerkleroot-bytes32" id="allowlist-newmerkleroot-bytes32"></a>

No description


# VirtualSwap


# Bridge

This contract is responsible for cross-asset swaps using the Synthetix protocol as the bridging exchange. There are three types of supported cross-asset swaps, tokenToSynth, synthToToken, and tokenToToken.

1. tokenToSynth Swaps a supported token in a saddle pool to any synthetic asset (e.g. tBTC -> sAAVE).
2. synthToToken Swaps any synthetic asset to a suported token in a saddle pool (e.g. sDEFI -> USDC).
3. tokenToToken Swaps a supported token in a saddle pool to one in another pool (e.g. renBTC -> DAI).

Due to the settlement periods of synthetic assets, the users must wait until the trades can be completed. Users will receive an ERC721 token that represents pending cross-asset swap. Once the waiting period is over, the trades can be settled and completed by calling the `completeToSynth` or the `completeToToken` function. In the cases of pending `synthToToken` or `tokenToToken` swaps, the owners of the pending swaps can also choose to withdraw the bridging synthetic assets instead of completing the swap.

## Functions:

* [`constructor(address synthSwapperAddress)`](#Bridge-constructor-address-)
* [`getProxyAddressFromTargetSynthKey(bytes32 synthKey)`](#Bridge-getProxyAddressFromTargetSynthKey-bytes32-)
* [`getPendingSwapInfo(uint256 itemId)`](#Bridge-getPendingSwapInfo-uint256-)
* [`withdraw(uint256 itemId, uint256 amount)`](#Bridge-withdraw-uint256-uint256-)
* [`completeToSynth(uint256 itemId)`](#Bridge-completeToSynth-uint256-)
* [`calcCompleteToToken(uint256 itemId, uint256 swapAmount)`](#Bridge-calcCompleteToToken-uint256-uint256-)
* [`completeToToken(uint256 itemId, uint256 swapAmount, uint256 minAmount, uint256 deadline)`](#Bridge-completeToToken-uint256-uint256-uint256-uint256-)
* [`calcTokenToSynth(contract ISwap swap, uint8 tokenFromIndex, bytes32 synthOutKey, uint256 tokenInAmount)`](#Bridge-calcTokenToSynth-contract-ISwap-uint8-bytes32-uint256-)
* [`tokenToSynth(contract ISwap swap, uint8 tokenFromIndex, bytes32 synthOutKey, uint256 tokenInAmount, uint256 minAmount)`](#Bridge-tokenToSynth-contract-ISwap-uint8-bytes32-uint256-uint256-)
* [`calcSynthToToken(contract ISwap swap, bytes32 synthInKey, uint8 tokenToIndex, uint256 synthInAmount)`](#Bridge-calcSynthToToken-contract-ISwap-bytes32-uint8-uint256-)
* [`synthToToken(contract ISwap swap, bytes32 synthInKey, uint8 tokenToIndex, uint256 synthInAmount, uint256 minMediumSynthAmount)`](#Bridge-synthToToken-contract-ISwap-bytes32-uint8-uint256-uint256-)
* [`calcTokenToToken(contract ISwap[2] swaps, uint8 tokenFromIndex, uint8 tokenToIndex, uint256 tokenFromAmount)`](#Bridge-calcTokenToToken-contract-ISwap-2--uint8-uint8-uint256-)
* [`tokenToToken(contract ISwap[2] swaps, uint8 tokenFromIndex, uint8 tokenToIndex, uint256 tokenFromAmount, uint256 minMediumSynthAmount)`](#Bridge-tokenToToken-contract-ISwap-2--uint8-uint8-uint256-uint256-)
* [`setSynthIndex(contract ISwap swap, uint8 synthIndex, bytes32 currencyKey)`](#Bridge-setSynthIndex-contract-ISwap-uint8-bytes32-)
* [`getSynthIndex(contract ISwap swap)`](#Bridge-getSynthIndex-contract-ISwap-)
* [`getSynthAddress(contract ISwap swap)`](#Bridge-getSynthAddress-contract-ISwap-)
* [`getSynthKey(contract ISwap swap)`](#Bridge-getSynthKey-contract-ISwap-)
* [`updateExchangerCache()`](#Bridge-updateExchangerCache--)

## Events:

* [`SynthIndex(address swap, uint8 synthIndex, bytes32 currencyKey, address synthAddress)`](#Bridge-SynthIndex-address-uint8-bytes32-address-)
* [`TokenToSynth(address requester, uint256 itemId, contract ISwap swapPool, uint8 tokenFromIndex, uint256 tokenFromInAmount, bytes32 synthToKey)`](#Bridge-TokenToSynth-address-uint256-contract-ISwap-uint8-uint256-bytes32-)
* [`SynthToToken(address requester, uint256 itemId, contract ISwap swapPool, bytes32 synthFromKey, uint256 synthFromInAmount, uint8 tokenToIndex)`](#Bridge-SynthToToken-address-uint256-contract-ISwap-bytes32-uint256-uint8-)
* [`TokenToToken(address requester, uint256 itemId, contract ISwap[2] swapPools, uint8 tokenFromIndex, uint256 tokenFromAmount, uint8 tokenToIndex)`](#Bridge-TokenToToken-address-uint256-contract-ISwap-2--uint8-uint256-uint8-)
* [`Settle(address requester, uint256 itemId, contract IERC20 settleFrom, uint256 settleFromAmount, contract IERC20 settleTo, uint256 settleToAmount, bool isFinal)`](#Bridge-Settle-address-uint256-contract-IERC20-uint256-contract-IERC20-uint256-bool-)
* [`Withdraw(address requester, uint256 itemId, contract IERC20 synth, uint256 synthAmount, bool isFinal)`](#Bridge-Withdraw-address-uint256-contract-IERC20-uint256-bool-)

## Function `constructor(address synthSwapperAddress)` <a href="#bridge-constructor-address" id="bridge-constructor-address"></a>

Deploys this contract and initializes the master version of the SynthSwapper contract. The address to the Synthetix protocol's Exchanger contract is also set on deployment.

## Function `getProxyAddressFromTargetSynthKey(bytes32 synthKey) → contract IERC20` <a href="#bridge-getproxyaddressfromtargetsynthkey-bytes32" id="bridge-getproxyaddressfromtargetsynthkey-bytes32"></a>

Returns the address of the proxy contract targeting the synthetic asset with the given `synthKey`.

### Parameters:

* `synthKey`: the currency key of the synth

### Return Values:

* address of the proxy contract

## Function `getPendingSwapInfo(uint256 itemId) → enum Bridge.PendingSwapType swapType, uint256 secsLeft, address synth, uint256 synthBalance, address tokenTo` <a href="#bridge-getpendingswapinfo-uint256" id="bridge-getpendingswapinfo-uint256"></a>

Returns various information of a pending swap represented by the given `itemId`. Information includes the type of the pending swap, the number of seconds left until it can be settled, the address and the balance of the synth this swap currently holds, and the address of the destination token.

### Parameters:

* `itemId`: ID of the pending swap

### Return Values:

* swapType the type of the pending virtual swap, secsLeft number of seconds left until this swap can be settled, synth address of the synth this swap uses, synthBalance amount of the synth this swap holds, tokenTo the address of the destination token

## Function `withdraw(uint256 itemId, uint256 amount)` <a href="#bridge-withdraw-uint256-uint256" id="bridge-withdraw-uint256-uint256"></a>

Settles and withdraws the synthetic asset without swapping it to a token in a Saddle pool. Only the owner of the ERC721 token of `itemId` can call this function. Reverts if the given `itemId` does not represent a `synthToToken` or a `tokenToToken` swap.

### Parameters:

* `itemId`: ID of the pending swap
* `amount`: the amount of the synth to withdraw

## Function `completeToSynth(uint256 itemId)` <a href="#bridge-completetosynth-uint256" id="bridge-completetosynth-uint256"></a>

Completes the pending `tokenToSynth` swap by settling and withdrawing the synthetic asset. Reverts if the given `itemId` does not represent a `tokenToSynth` swap.

### Parameters:

* `itemId`: ERC721 token ID representing a pending `tokenToSynth` swap

## Function `calcCompleteToToken(uint256 itemId, uint256 swapAmount) → uint256` <a href="#bridge-calccompletetotoken-uint256-uint256" id="bridge-calccompletetotoken-uint256-uint256"></a>

Calculates the expected amount of the token to receive on calling `completeToToken()` with the given `swapAmount`.

### Parameters:

* `itemId`: ERC721 token ID representing a pending `SynthToToken` or `TokenToToken` swap
* `swapAmount`: the amount of bridging synth to swap from

### Return Values:

* expected amount of the token the user will receive

## Function `completeToToken(uint256 itemId, uint256 swapAmount, uint256 minAmount, uint256 deadline)` <a href="#bridge-completetotoken-uint256-uint256-uint256-uint256" id="bridge-completetotoken-uint256-uint256-uint256-uint256"></a>

Completes the pending `SynthToToken` or `TokenToToken` swap by settling the bridging synth and swapping it to the desired token. Only the owners of the pending swaps can call this function.

### Parameters:

* `itemId`: ERC721 token ID representing a pending `SynthToToken` or `TokenToToken` swap
* `swapAmount`: the amount of bridging synth to swap from
* `minAmount`: the minimum amount of the token to receive - reverts if this amount is not reached
* `deadline`: the timestamp representing the deadline for this transaction - reverts if deadline is not met

## Function `calcTokenToSynth(contract ISwap swap, uint8 tokenFromIndex, bytes32 synthOutKey, uint256 tokenInAmount) → uint256` <a href="#bridge-calctokentosynth-contract-iswap-uint8-bytes32-uint256" id="bridge-calctokentosynth-contract-iswap-uint8-bytes32-uint256"></a>

Calculates the expected amount of the desired synthetic asset the caller will receive after completing a `TokenToSynth` swap with the given parameters. This calculation does not consider the settlement periods.

### Parameters:

* `swap`: the address of a Saddle pool to use to swap the given token to a bridging synth
* `tokenFromIndex`: the index of the token to swap from
* `synthOutKey`: the currency key of the desired synthetic asset
* `tokenInAmount`: the amount of the token to swap form

### Return Values:

* the expected amount of the desired synth

## Function `tokenToSynth(contract ISwap swap, uint8 tokenFromIndex, bytes32 synthOutKey, uint256 tokenInAmount, uint256 minAmount) → uint256` <a href="#bridge-tokentosynth-contract-iswap-uint8-bytes32-uint256-uint256" id="bridge-tokentosynth-contract-iswap-uint8-bytes32-uint256-uint256"></a>

Initiates a cross-asset swap from a token supported in the `swap` pool to any synthetic asset. The caller will receive an ERC721 token representing their ownership of the pending cross-asset swap.

### Parameters:

* `swap`: the address of a Saddle pool to use to swap the given token to a bridging synth
* `tokenFromIndex`: the index of the token to swap from
* `synthOutKey`: the currency key of the desired synthetic asset
* `tokenInAmount`: the amount of the token to swap form
* `minAmount`: the amount of the token to swap form

### Return Values:

* ID of the ERC721 token sent to the caller

## Function `calcSynthToToken(contract ISwap swap, bytes32 synthInKey, uint8 tokenToIndex, uint256 synthInAmount) → uint256, uint256` <a href="#bridge-calcsynthtotoken-contract-iswap-bytes32-uint8-uint256" id="bridge-calcsynthtotoken-contract-iswap-bytes32-uint8-uint256"></a>

Calculates the expected amount of the desired token the caller will receive after completing a `SynthToToken` swap with the given parameters. This calculation does not consider the settlement periods or any potential changes of the `swap` pool composition.

### Parameters:

* `swap`: the address of a Saddle pool to use to swap the given token to a bridging synth
* `synthInKey`: the currency key of the synth to swap from
* `tokenToIndex`: the index of the token to swap to
* `synthInAmount`: the amount of the synth to swap form

### Return Values:

* the expected amount of the bridging synth and the expected amount of the desired token

## Function `synthToToken(contract ISwap swap, bytes32 synthInKey, uint8 tokenToIndex, uint256 synthInAmount, uint256 minMediumSynthAmount) → uint256` <a href="#bridge-synthtotoken-contract-iswap-bytes32-uint8-uint256-uint256" id="bridge-synthtotoken-contract-iswap-bytes32-uint8-uint256-uint256"></a>

Initiates a cross-asset swap from a synthetic asset to a supported token. The caller will receive an ERC721 token representing their ownership of the pending cross-asset swap.

### Parameters:

* `swap`: the address of a Saddle pool to use to swap the given token to a bridging synth
* `synthInKey`: the currency key of the synth to swap from
* `tokenToIndex`: the index of the token to swap to
* `synthInAmount`: the amount of the synth to swap form
* `minMediumSynthAmount`: the minimum amount of the bridging synth at pre-settlement stage

### Return Values:

* the ID of the ERC721 token sent to the caller

## Function `calcTokenToToken(contract ISwap[2] swaps, uint8 tokenFromIndex, uint8 tokenToIndex, uint256 tokenFromAmount) → uint256, uint256` <a href="#bridge-calctokentotoken-contract-iswap-2-uint8-uint8-uint256" id="bridge-calctokentotoken-contract-iswap-2-uint8-uint8-uint256"></a>

Calculates the expected amount of the desired token the caller will receive after completing a `TokenToToken` swap with the given parameters. This calculation does not consider the settlement periods or any potential changes of the pool compositions.

### Parameters:

* `swaps`: the addresses of the two Saddle pools used to do the cross-asset swap
* `tokenFromIndex`: the index of the token in the first `swaps` pool to swap from
* `tokenToIndex`: the index of the token in the second `swaps` pool to swap to
* `tokenFromAmount`: the amount of the token to swap from

### Return Values:

* the expected amount of bridging synth at pre-settlement stage and the expected amount of the desired token

## Function `tokenToToken(contract ISwap[2] swaps, uint8 tokenFromIndex, uint8 tokenToIndex, uint256 tokenFromAmount, uint256 minMediumSynthAmount) → uint256` <a href="#bridge-tokentotoken-contract-iswap-2-uint8-uint8-uint256-uint256" id="bridge-tokentotoken-contract-iswap-2-uint8-uint8-uint256-uint256"></a>

Initiates a cross-asset swap from a token in one Saddle pool to one in another. The caller will receive an ERC721 token representing their ownership of the pending cross-asset swap.

### Parameters:

* `swaps`: the addresses of the two Saddle pools used to do the cross-asset swap
* `tokenFromIndex`: the index of the token in the first `swaps` pool to swap from
* `tokenToIndex`: the index of the token in the second `swaps` pool to swap to
* `tokenFromAmount`: the amount of the token to swap from
* `minMediumSynthAmount`: the minimum amount of the bridging synth at pre-settlement stage

### Return Values:

* the ID of the ERC721 token sent to the caller

## Function `setSynthIndex(contract ISwap swap, uint8 synthIndex, bytes32 currencyKey)` <a href="#bridge-setsynthindex-contract-iswap-uint8-bytes32" id="bridge-setsynthindex-contract-iswap-uint8-bytes32"></a>

Registers the index and the address of the supported synth from the given `swap` pool. The matching currency key must be supplied for a successful registration.

### Parameters:

* `swap`: the address of the pool that contains the synth
* `synthIndex`: the index of the supported synth in the given `swap` pool
* `currencyKey`: the currency key of the synth in bytes32 form

## Function `getSynthIndex(contract ISwap swap) → uint8` <a href="#bridge-getsynthindex-contract-iswap" id="bridge-getsynthindex-contract-iswap"></a>

Returns the index of the supported synth in the given `swap` pool. Reverts if the `swap` pool is not registered.

### Parameters:

* `swap`: the address of the pool that contains the synth

### Return Values:

* the index of the supported synth

## Function `getSynthAddress(contract ISwap swap) → address` <a href="#bridge-getsynthaddress-contract-iswap" id="bridge-getsynthaddress-contract-iswap"></a>

Returns the address of the supported synth in the given `swap` pool. Reverts if the `swap` pool is not registered.

### Parameters:

* `swap`: the address of the pool that contains the synth

### Return Values:

* the address of the supported synth

## Function `getSynthKey(contract ISwap swap) → bytes32` <a href="#bridge-getsynthkey-contract-iswap" id="bridge-getsynthkey-contract-iswap"></a>

Returns the currency key of the supported synth in the given `swap` pool. Reverts if the `swap` pool is not registered.

### Parameters:

* `swap`: the address of the pool that contains the synth

### Return Values:

* the currency key of the supported synth

## Function `updateExchangerCache()` <a href="#bridge-updateexchangercache" id="bridge-updateexchangercache"></a>

Updates the stored address of the `EXCHANGER` contract. When the Synthetix team upgrades their protocol, a new Exchanger contract is deployed. This function manually updates the stored address.

## Event `SynthIndex(address swap, uint8 synthIndex, bytes32 currencyKey, address synthAddress)` <a href="#bridge-synthindex-address-uint8-bytes32-address" id="bridge-synthindex-address-uint8-bytes32-address"></a>

No description

## Event `TokenToSynth(address requester, uint256 itemId, contract ISwap swapPool, uint8 tokenFromIndex, uint256 tokenFromInAmount, bytes32 synthToKey)` <a href="#bridge-tokentosynth-address-uint256-contract-iswap-uint8-uint256-bytes32" id="bridge-tokentosynth-address-uint256-contract-iswap-uint8-uint256-bytes32"></a>

No description

## Event `SynthToToken(address requester, uint256 itemId, contract ISwap swapPool, bytes32 synthFromKey, uint256 synthFromInAmount, uint8 tokenToIndex)` <a href="#bridge-synthtotoken-address-uint256-contract-iswap-bytes32-uint256-uint8" id="bridge-synthtotoken-address-uint256-contract-iswap-bytes32-uint256-uint8"></a>

No description

## Event `TokenToToken(address requester, uint256 itemId, contract ISwap[2] swapPools, uint8 tokenFromIndex, uint256 tokenFromAmount, uint8 tokenToIndex)` <a href="#bridge-tokentotoken-address-uint256-contract-iswap-2-uint8-uint256-uint8" id="bridge-tokentotoken-address-uint256-contract-iswap-2-uint8-uint256-uint8"></a>

No description

## Event `Settle(address requester, uint256 itemId, contract IERC20 settleFrom, uint256 settleFromAmount, contract IERC20 settleTo, uint256 settleToAmount, bool isFinal)` <a href="#bridge-settle-address-uint256-contract-ierc20-uint256-contract-ierc20-uint256-bool" id="bridge-settle-address-uint256-contract-ierc20-uint256-contract-ierc20-uint256-bool"></a>

No description

## Event `Withdraw(address requester, uint256 itemId, contract IERC20 synth, uint256 synthAmount, bool isFinal)` <a href="#bridge-withdraw-address-uint256-contract-ierc20-uint256-bool" id="bridge-withdraw-address-uint256-contract-ierc20-uint256-bool"></a>

No description


# Proxy


# SynthSwapper

Replacement of Virtual Synths in favor of gas savings. Allows swapping synths via the Synthetix protocol or Saddle's pools. The `Bridge.sol` contract will deploy minimal clones of this contract upon initiating any cross-asset swaps.

## Functions:

* [`constructor()`](#SynthSwapper-constructor--)
* [`initialize()`](#SynthSwapper-initialize--)
* [`swapSynth(bytes32 sourceKey, uint256 synthAmount, bytes32 destKey)`](#SynthSwapper-swapSynth-bytes32-uint256-bytes32-)
* [`swapSynthToToken(contract ISwap swap, contract IERC20 tokenFrom, uint8 tokenFromIndex, uint8 tokenToIndex, uint256 tokenFromAmount, uint256 minAmount, uint256 deadline, address recipient)`](#SynthSwapper-swapSynthToToken-contract-ISwap-contract-IERC20-uint8-uint8-uint256-uint256-uint256-address-)
* [`withdraw(contract IERC20 token, address recipient, uint256 withdrawAmount, bool shouldDestroy)`](#SynthSwapper-withdraw-contract-IERC20-address-uint256-bool-)
* [`destroy()`](#SynthSwapper-destroy--)

## Function `constructor()` <a href="#synthswapper-constructor" id="synthswapper-constructor"></a>

Initializes the contract when deploying this directly. This prevents others from calling initialize() on the target contract and setting themself as the owner.

## Function `initialize()` <a href="#synthswapper-initialize" id="synthswapper-initialize"></a>

Sets the `owner` as the caller of this function

## Function `swapSynth(bytes32 sourceKey, uint256 synthAmount, bytes32 destKey) → uint256` <a href="#synthswapper-swapsynth-bytes32-uint256-bytes32" id="synthswapper-swapsynth-bytes32-uint256-bytes32"></a>

Swaps the synth to another synth via the Synthetix protocol.

### Parameters:

* `sourceKey`: currency key of the source synth
* `synthAmount`: amount of the synth to swap
* `destKey`: currency key of the destination synth

### Return Values:

* amount of the destination synth received

## Function `swapSynthToToken(contract ISwap swap, contract IERC20 tokenFrom, uint8 tokenFromIndex, uint8 tokenToIndex, uint256 tokenFromAmount, uint256 minAmount, uint256 deadline, address recipient) → contract IERC20, uint256` <a href="#synthswapper-swapsynthtotoken-contract-iswap-contract-ierc20-uint8-uint8-uint256-uint256-uint256-add" id="synthswapper-swapsynthtotoken-contract-iswap-contract-ierc20-uint8-uint8-uint256-uint256-uint256-add"></a>

Approves the given `tokenFrom` and swaps it to another token via the given `swap` pool.

### Parameters:

* `swap`: the address of a pool to swap through
* `tokenFrom`: the address of the stored synth
* `tokenFromIndex`: the index of the token to swap from
* `tokenToIndex`: the token the user wants to swap to
* `tokenFromAmount`: the amount of the token to swap
* `minAmount`: the min amount the user would like to receive, or revert.
* `deadline`: latest timestamp to accept this transaction
* `recipient`: the address of the recipient

## Function `withdraw(contract IERC20 token, address recipient, uint256 withdrawAmount, bool shouldDestroy)` <a href="#synthswapper-withdraw-contract-ierc20-address-uint256-bool" id="synthswapper-withdraw-contract-ierc20-address-uint256-bool"></a>

Withdraws the given amount of `token` to the `recipient`.

### Parameters:

* `token`: the address of the token to withdraw
* `recipient`: the address of the account to receive the token
* `withdrawAmount`: the amount of the token to withdraw
* `shouldDestroy`: whether this contract should be destroyed after this call

## Function `destroy()` <a href="#synthswapper-destroy" id="synthswapper-destroy"></a>

Destroys this contract. Only owner can call this function.


# Target


