# Welcome to DoveSwap

Glad to see you here

## Welcome

Welcome to the DoveSwap protocol docs. We're building the most user-friendly experience in DeFi for the zkEVM space.&#x20;

The pages here contain conceptual and technical documentation of the DoveSwap protocol.

If you are new to DoveSwap, you might want to check out the [Protocol overview](/overview) first.

## Quick links

{% content-ref url="/pages/SoPt7G2Ex4i6kKrH3fpN" %}
[Overview](/overview)
{% endcontent-ref %}

{% content-ref url="/pages/SsrYSG9opSuXdQBCwh5b" %}
[Core Concepts](/concepts/core-concepts)
{% endcontent-ref %}


# Overview

## Overview

DoveSwap is an *automated liquidity protocol* powered by a constant product formula and implemented in a system of non-upgradeable smart contracts on the Polygon zkEVM blockchain. It obviates the need for trusted intermediaries, prioritizing **decentralization**, **censorship resistance**, and **security**. \
\
Each DoveSwap smart contract, or pair, manages a liquidity pool made up of reserves of two ERC-20 tokens. \
\
Anyone can become a liquidity provider (LP) for a pool by depositing an equivalent value of each underlying token in return for pool tokens. These tokens track pro-rata LP shares of the total reserves, and can be redeemed for the underlying assets at any time.\
\
Pairs act as automated market makers, standing ready to accept one token for the other as long as the “constant product” formula is preserved. This formula, most simply expressed as `x * y = k`, states that trades must not change the product (`k`) of a pair’s reserve balances (`x` and `y`). Because `k` remains unchanged from the reference frame of a trade, it is often referred to as the invariant. This formula has the desirable property that larger trades (relative to reserves) execute at exponentially worse rates than smaller ones.

In practice, DoveSwap applies a 0.30% fee to trades, which is added to reserves. As a result, each trade actually increases `k`. This functions as a payout to LPs, which is realized when they burn their pool tokens to withdraw their portion of total reserves. In the future, this fee may be reduced to 0.25%, with the remaining 0.05% withheld as a protocol-wide charge.

Because the relative price of the two pair assets can only be changed through trading, divergences between the DoveSwap price and external prices create arbitrage opportunities. This mechanism ensures that DoveSwap prices always trend toward the market-clearing price.

## Further reading

To see how token swaps work in practice, and to walk through the lifecycle of a swap, check out Swaps. Or, to see how liquidity pools work, see [Pools](/concepts/core-concepts/pools).

Ultimately, of course, the DoveSwap protocol is just smart contract code running on Ethereum. To understand how they work, head over to [Smart Contracts](/technical-reference/smart-contracts).


# Ecosystem Participants

The DoveSwap ecosystem is primarily comprised of three types of users: liquidity providers, traders, and developers. Liquidity providers are incentivized to contribute [ERC-20](https://eips.ethereum.org/EIPS/eip-20) tokens to common liquidity pools. Traders can swap these tokens for one another for a fixed [0.30% fee](/concepts/advanced-concepts/fees) (which goes to liquidity providers). Developers can integrate directly with Uniswap smart contracts to power new and exciting interactions with tokens, trading interfaces, retail experiences, and more.

In total, interactions between these classes create a positive feedback loop, fueling digital economies by defining a common language through which tokens can be pooled, traded and used.

## Liquidity Providers

Liquidity providers, or LPs, are not a homogenous group:

* Passive LPs are token holders who wish to passively invest their assets to accumulate trading fees.
* Professional LPs are focused on market making as their primary strategy. They usually develop custom tools and ways of tracking their liquidity positions across different DeFi projects.
* Token projects sometimes choose to become LPs to create a liquid marketplace for their token. This allows tokens to be bought and sold more easily, and unlocks interoperability with other DeFi projects through DoveSwap.
* Finally, some DeFi pioneers are exploring complex liquidity provision interactions like incentivized liquidity, liquidity as collateral, and other experimental strategies. DoveSwap is the perfect protocol for projects to experiment with these kinds of ideas.

## Traders

There are a several categories of traders in the protocol ecosystem:

* Speculators use a variety of community built tools and products to swap tokens using liquidity pulled from the DoveSwap protocol.
* Arbitrage bots seek profits by comparing prices across different platforms to find an edge. (Though it might seem extractive, these bots actually help equalize prices across broader Ethereum markets and keep things fair.)
* DAPP users buy tokens on DoveSwap for use in other applications on Ethereum.
* Smart contracts that execute trades on the protocol by implementing swap functionality (from products like DEX aggregators to custom Solidity scripts).

In all cases, trades are subject to the same flat fee for trading on the protocol. Each is important for increasing the accuracy of prices and incentivizing liquidity.


# Glossary

#### Automated market maker[​](https://docs.uniswap.org/contracts/v2/concepts/protocol-overview/glossary#automated-market-maker) <a href="#automated-market-maker" id="automated-market-maker"></a>

An automated market maker is a smart contract on Ethereum that holds on-chain liquidity reserves. Users can trade against these reserves at prices set by an automated market making formula.

#### Constant product formula[​](https://docs.uniswap.org/contracts/v2/concepts/protocol-overview/glossary#constant-product-formula) <a href="#constant-product-formula" id="constant-product-formula"></a>

The automated market making algorithm used by DoveSwap. See [x\*y=k](#x--y--k).

#### ERC20[​](https://docs.uniswap.org/contracts/v2/concepts/protocol-overview/glossary#erc20) <a href="#erc20" id="erc20"></a>

ERC20 tokens are fungible tokens on Ethereum. DoveSwap supports all standard ERC20 implementations.

#### Factory[​](https://docs.uniswap.org/contracts/v2/concepts/protocol-overview/glossary#factory) <a href="#factory" id="factory"></a>

A smart contract that deploys a unique smart contract for any ERC20/ERC20 trading pair.

#### Pair[​](https://docs.uniswap.org/contracts/v2/concepts/protocol-overview/glossary#pair) <a href="#pair" id="pair"></a>

A smart contract deployed from the DoveSwap Factory that enables trading between two ERC20 tokens.

#### Pool[​](https://docs.uniswap.org/contracts/v2/concepts/protocol-overview/glossary#pool) <a href="#pool" id="pool"></a>

Liquidity within a pair is pooled across all liquidity providers.

#### Liquidity provider / LP[​](https://docs.uniswap.org/contracts/v2/concepts/protocol-overview/glossary#liquidity-provider--lp) <a href="#liquidity-provider--lp" id="liquidity-provider--lp"></a>

A liquidity provider is someone who deposits an equivalent value of two ERC20 tokens into the liquidity pool within a pair. Liquidity providers take on price risk and are compensated with fees.

#### Mid price[​](https://docs.uniswap.org/contracts/v2/concepts/protocol-overview/glossary#mid-price) <a href="#mid-price" id="mid-price"></a>

The price between what users can buy and sell tokens at a given moment. In DoveSwap this is the ratio of the two ERC20 token reserves.

#### Price impact[​](https://docs.uniswap.org/contracts/v2/concepts/protocol-overview/glossary#price-impact) <a href="#price-impact" id="price-impact"></a>

The difference between the mid-price and the execution price of a trade.

#### Slippage[​](https://docs.uniswap.org/contracts/v2/concepts/protocol-overview/glossary#slippage) <a href="#slippage" id="slippage"></a>

The amount the price moves in a trading pair between when a transaction is submitted and when it is executed.

#### Core[​](https://docs.uniswap.org/contracts/v2/concepts/protocol-overview/glossary#core) <a href="#core" id="core"></a>

Smart contracts that are essential for DoveSwap to exist. Upgrading to a new version of core would require a liquidity migration.

#### Periphery[​](https://docs.uniswap.org/contracts/v2/concepts/protocol-overview/glossary#periphery) <a href="#periphery" id="periphery"></a>

External smart contracts that are useful, but not required for DoveSwap to exist. New periphery contracts can always be deployed without migrating liquidity.

#### Flash swap[​](https://docs.uniswap.org/contracts/v2/concepts/protocol-overview/glossary#flash-swap) <a href="#flash-swap" id="flash-swap"></a>

A trade that uses the tokens being purchased before paying for them.

#### `x * y = k`[​](https://docs.uniswap.org/contracts/v2/concepts/protocol-overview/glossary#x--y--k) <a href="#x--y--k" id="x--y--k"></a>

The constant product formula.

#### Invariant[​](https://docs.uniswap.org/contracts/v2/concepts/protocol-overview/glossary#invariant) <a href="#invariant" id="invariant"></a>

The "k" value in the constant product formula


# Core Concepts

{% content-ref url="/pages/bLXUkwWymnZtfy5dnlzO" %}
[Swaps](/concepts/core-concepts/swaps)
{% endcontent-ref %}

{% content-ref url="/pages/zHkC6QZ6jeBS4MvvbCIM" %}
[Pools](/concepts/core-concepts/pools)
{% endcontent-ref %}

{% content-ref url="/pages/9A8LweKTBnhGBIb40drW" %}
[Flash Swaps](/concepts/core-concepts/flash-swaps)
{% endcontent-ref %}


# Swaps

## Introduction

Token swaps in DoveSwap are a simple way to trade one ERC-20 token for another.

For end-users, swapping is intuitive: a user picks an input token and an output token. They specify an input amount, and the protocol calculates how much of the output token they’ll receive. They then execute the swap with one click, receiving the output token in their wallet immediately.

In this guide, we’ll look at what happens during a swap at the protocol level in order to gain a deeper understanding of how DoveSwap works.

Swaps in DoveSwap are different from trades on traditional platforms. DoveSwap does not use an order book to represent liquidity or determine prices. DoveSwap uses an automated market maker mechanism to provide instant feedback on rates and slippage.

As we learned in [Protocol Overview](/), each pair on DoveSwap is actually underpinned by a liquidity pool. Liquidity pools are smart contracts that hold balances of two unique tokens and enforces rules around depositing and withdrawing them.

This rule is the [constant product formula](/concepts/glossary#x--y--k). When either token is withdrawn (purchased), a proportional amount of the other must be deposited (sold), in order to maintain the constant.

### Anatomy of a swap[​](https://docs.uniswap.org/contracts/v2/concepts/core-concepts/swaps#anatomy-of-a-swap) <a href="#anatomy-of-a-swap" id="anatomy-of-a-swap"></a>

At the most basic level, all swaps in DoveSwap happen within a single function, aptly named `swap`:

{% code overflow="wrap" %}

```solidity
function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data);
```

{% endcode %}

## Receiving tokens

As is probably clear from the function signature, DoveSwap requires `swap` callers to *specify how many output tokens they would like to receive* via the `amount{0,1}Out` parameters, which correspond to the desired amount of `token{0,1}`.

## Sending Tokens

What’s not as clear is how DoveSwap *receives* tokens as payment for the swap. Typically, smart contracts which need tokens to perform some functionality require callers to first make an approval on the token contract, then call a function that in turn calls transferFrom on the token contract. This is *not* how DoveSwap pairs accept tokens. Instead, pairs check their token balances at the *end* of every interaction. Then, at the beginning of the *next* interaction, current balances are differenced against the stored values to determine the amount of tokens that were sent by the current interactor.&#x20;

The takeaway is that **tokens must be transferred to pairs before swap is called** (the one exception to this rule is [Flash Swaps](/concepts/core-concepts/flash-swaps)). This means that to safely use the `swap` function, it must be called from *another smart contract*. The alternative (transferring tokens to the pair and then calling `swap`) is not safe to do non-atomically because the sent tokens would be vulnerable to arbitrage.


# Pools

## Introduction

Each DoveSwap liquidity pool is a trading venue for a pair of ERC20 tokens. When a pool contract is created, its balances of each token are 0; in order for the pool to begin facilitating trades, someone must seed it with an initial deposit of each token. This first liquidity provider is the one who sets the initial price of the pool. They are incentivized to deposit an equal *value* of both tokens into the pool. To see why, consider the case where the first liquidity provider deposits tokens at a ratio different from the current market rate. This immediately creates a profitable arbitrage opportunity, which is likely to be taken by an external party.

When other liquidity providers add to an existing pool, they must deposit pair tokens proportional to the current price. If they don’t, the liquidity they added is at risk of being arbitraged as well. If they believe the current price is not correct, they may arbitrage it to the level they desire, and add liquidity at that price.

## Pool tokens

Whenever liquidity is deposited into a pool, unique tokens known as *liquidity tokens* are minted and sent to the provider's address. These tokens represent a given liquidity provider's contribution to a pool. The proportion of the pool's liquidity provided determines the number of liquidity tokens the provider receives. If the provider is minting a new pool, the number of liquidity tokens they will receive will equal sqrt(x \* y), where x and y represent the amount of each token provided.

Whenever a trade occurs, a 0.3% fee is charged to the transaction sender. This fee is distributed *pro-rata* to all LPs in the pool upon completion of the trade.

To retrieve the underlying liquidity, plus any fees accrued, liquidity providers must "burn" their liquidity tokens, effectively exchanging them for their portion of the liquidity pool, plus the proportional fee allocation.

As liquidity tokens are themselves tradable assets, liquidity providers may sell, transfer, or otherwise use their liquidity tokens in any way they see fit.

> Learn more with advanced topics:

* [Understanding Returns](/concepts/advanced-concepts/understanding-returns)
* [Fees](/concepts/advanced-concepts/fees)

## Why pools?

DoveSwap doesn’t use an order book to derive the price of an asset or to match buyers and sellers of tokens. Instead, DoveSwap uses what are called Liquidity Pools.

Liquidity is typically represented by discrete orders placed by individuals onto a centrally operated order book. A participant looking to provide liquidity or make markets must actively manage their orders, continuously updating them in response to the activity of others in the marketplace.

While order books are foundational to finance and work great for certain usecases, they suffer from a few important limitations that are especially magnified when applied to a decentralized or blockchain-native setting. Order books require intermediary infrastructure to host the orderbook and match orders. This creates points of control and adds additional layers of complexity. They also require active participation and management from market makers who usually use sophisticated infrastructure and algorithms, limiting participation to advanced traders. Order books were invented in a world with relatively few assets being traded, so it is not surprising they aren't ideal for an ecosystem where anyone can create their own token, and those tokens usually have low liquidity. In sum, with the infrastructural trade-offs presented by a platform like Ethereum, order books are not the native architecture for implementing a liquidity protocol on a blockchain.

It is important to reiterate that a Pool is just a smart contract, operated by users calling functions on it. Swapping tokens is calling `swap` on a Pool contract instance, while providing liquidity is calling `deposit`.

Just how end-users can interact with the DoveSwap protocol through the Interface (which in turn interacts with the underlying contracts), developers can interact directly with the smart contracts and integrate DoveSwap functionality into their own applications without relying on intermediaries or needing permission.


# Flash Swaps

DoveSwap flash swaps allow you to withdraw up to the full reserves of any ERC20 token on DoveSwap and execute arbitrary logic at no upfront cost, provided that by the end of the transaction you either:

* pay for the withdrawn ERC20 tokens with the corresponding pair tokens
* return the withdrawn ERC20 tokens along with a small fee

Flash swaps are incredibly useful because they obviate upfront capital requirements and unnecessary order-of-operations constraints for multi-step transactions involving DoveSwap.

## Examples

### Capital Free Arbitrage[​](https://docs.uniswap.org/contracts/v2/concepts/core-concepts/flash-swaps#capital-free-arbitrage) <a href="#capital-free-arbitrage" id="capital-free-arbitrage"></a>

One particularly interesting use case for flash swaps is capital-free arbitrage. It's well-known that an integral part of DoveSwap's design is to create incentives for arbitrageurs to trade the DoveSwap price to a "fair" market price. While game-theoretically sound, this strategy is accessible only to those with sufficient capital to take advantage of arbitrage opportunities. Flash swaps remove this barrier entirely, effectively democratizing arbitrage.

Imagine a scenario where the cost of buying 1 ETH on DoveSwap is 200 DAI (which is calculated by calling `getAmountIn` with 1 ETH specified as an exact output), and on Oasis (or any other trading venue), 1 ETH buys 220 DAI. To anyone with 200 DAI available, this situation represents a risk-free profit of 20 DAI. Unfortunately, you may not have 200 DAI lying around. With flash swaps, however, this risk-free profit is available for anyone to take as long as they're able to pay gas fees.

#### Withdrawing ETH from DoveSwap[​](https://docs.uniswap.org/contracts/v2/concepts/core-concepts/flash-swaps#withdrawing-eth-from-uniswap) <a href="#withdrawing-eth-from-uniswap" id="withdrawing-eth-from-uniswap"></a>

The first step is to *optimistically* withdraw 1 ETH from DoveSwap via a flash swap. This will serve as the capital that we use to execute our arbitrage. Note that in this scenario, we're assuming that:

* 1 ETH is the pre-calculated profit-maximizing trade
* The price has not changed on DoveSwap or Oasis since our calculation

It may be the case that we'd like to calculate the profit-maximizing trade on-chain at the moment of execution, which is robust to price movements. This can be somewhat complex, depending on the strategy being executed. However, one common strategy is trading as profitably as possible *against a fixed external price*. (This price may be e.g., the average execution price of one or more orders on Oasis.)&#x20;

#### Trade at External Venue[​](https://docs.uniswap.org/contracts/v2/concepts/core-concepts/flash-swaps#trade-at-external-venue) <a href="#trade-at-external-venue" id="trade-at-external-venue"></a>

Once we've obtained our temporary capital of 1 ETH from DoveSwap, we now can trade this for 220 DAI on Oasis. Once we've received the DAI, we need to pay DoveSwap back. We've mentioned that the amount required to cover 1 ETH is 200 DAI, calculated via `getAmountIn`. So, after sending 200 of the DAI back to the DoveSwap pair, you're left with 20 DAI of profit!

### Instant Leverage[​](https://docs.uniswap.org/contracts/v2/concepts/core-concepts/flash-swaps#instant-leverage) <a href="#instant-leverage" id="instant-leverage"></a>

Flash swaps can be used to improve the efficiency of levering up using lending protocols and DoveSwap.

Consider Maker in its simplest form: a system which accepts ETH as collateral and allows DAI to be minted against it while ensuring that the value of the ETH never drops below 150% of the value of the DAI.

Say we use this system to deposit a principal amount of 3 ETH, and mint the maximum amount of DAI. At a price of 1 ETH / 200 DAI, we receive 400 DAI. In theory, we could lever this position up by selling the DAI for more ETH, depositing this ETH, minting the maximum amount of DAI (which would be less this time), and repeating until we've reached our desired leverage level.

It's quite simple to use DoveSwap as a liquidity source for the DAI-to-ETH component of this process. However, looping through protocols in this way isn't particularly elegant, and can be gas-intensive.

Luckily, flash swaps enable us to withdraw the *full* ETH amount upfront. If we wanted 2x leverage against our 3 ETH principal, we could simply request 3 ETH in a flash swap and deposit 6 ETH into Maker. This gives us the ability to mint 800 DAI. If we mint as much as we need to cover our flash swap (say 605), the remainder serves as a safety margin against price movements.


# Oracles

A price oracle is any tool used to view price information about a given asset. When you look at stock prices on your phone, you are using your phone as a price oracle. Similarly, the app on your phone relies on devices to retrieve price information - likely several, which are aggregated and then displayed to you, the end-user. These are price oracles as well.

When building smart contracts that integrate with DeFi protocols, developers will inevitably run into the price oracle problem. What is the best way to retrieve the price of a given asset on-chain?

Many oracle designs on Ethereum have been implemented on an ad-hoc basis, with varying degrees of decentralization and security. Because of this, the ecosystem has witnessed numerous high-profile hacks where the oracle implementation is the primary attack vector. Some of these vulnerabilities are discussed [here](https://samczsun.com/taking-undercollateralized-loans-for-fun-and-for-profit/).

While there is no one size fits all solution, DoveSwap enables developers to build highly decentralized and manipulation-resistant on-chain price oracles, which may solve many of the demands necessary for building robust protocols.

## DoveSwap solution

DoveSwap includes several improvements for supporting manipulation-resistant public price feeds. First, every pair measures (but does not store) the market price at the beginning of each block, before any trades take place. This price is expensive to manipulate because it is set by the last transaction, whether it is a mint, swap, or burn, in a previous block.

**To set the measured price to one that is out of sync with the global market price, an attacker has to make a bad trade at the end of a previous block** , typically with no guarantee that they will arbitrage it back in the next block. Attackers will lose money to arbitrageurs unless they can “selfishly” mine two blocks in a row. This type of attack presents several challenges and [has not been observed to date](https://arxiv.org/abs/1912.01798).

Unfortunately, this alone is not enough. If significant value settles based on the price resulting from this mechanism, an attack’s profit will likely outweigh the loss.

Instead, DoveSwap adds this end-of-block price to a single cumulative-price variable in the core contract weighted by the amount of time this price existed. **This variable represents a sum of the DoveSwap price for every second in the entire history of the contract.**

This variable can be used by external contracts to track accurate time-weighted average prices (TWAPs) across any time interval.

The TWAP is constructed by reading the cumulative price from an ERC20 token pair at the beginning and at the end of the desired interval. The difference in this cumulative price can then be divided by the length of the interval to create a TWAP for that period.

TWAPs can be used directly or as the basis for moving averages (EMAs and SMAs) as needed.

A few notes:

* For a 10-minute TWAP, sample once every 10 minutes. For a 1-week TWAP, sample once every week.
* For a simple TWAP, the cost of manipulation increases (approx. linear) with liquidity on DoveSwap, as well as (approx. linear) with the length of time over which you average.
* The Cost of an attack is relatively simple to estimate. Moving the price 5% on a 1-hour TWAP is approximately equal to the amount lost to arbitrage and fees for moving the price 5% every block for 1 hour.

## Manipulation resistance[​](https://docs.uniswap.org/contracts/v2/concepts/core-concepts/oracles#manipulation-resistance) <a href="#manipulation-resistance" id="manipulation-resistance"></a>

The cost of manipulating the price for a specific time period can be roughly estimated as the amount lost to arbitrage and fees every block for the entire period. For larger liquidity pools and over longer time periods, this attack is impractical, as the cost of manipulation typically exceeds the value at stake.

Other factors, such as network congestion, can reduce the cost of attack.


# Advanced Concepts

{% content-ref url="/pages/QIvpvLxo28xGvjOtFhGD" %}
[Fees](/concepts/advanced-concepts/fees)
{% endcontent-ref %}

{% content-ref url="/pages/CNZQ8m5E8UwnLcGvFAVz" %}
[Pricing](/concepts/advanced-concepts/pricing)
{% endcontent-ref %}

{% content-ref url="/pages/0i6qLEuvlQSXvDuytMs0" %}
[Understanding Returns](/concepts/advanced-concepts/understanding-returns)
{% endcontent-ref %}


# Fees

### Liquidity provider fees[​](https://docs.uniswap.org/contracts/v2/concepts/advanced-topics/fees#liquidity-provider-fees) <a href="#liquidity-provider-fees" id="liquidity-provider-fees"></a>

There is a **0.3%** fee for swapping tokens. **This fee is split by liquidity providers proportional to their contribution to liquidity reserves.**

Swapping fees are immediately deposited into liquidity reserves. This increases the value of liquidity tokens, functioning as a payout to all liquidity providers proportional to their share of the pool. Fees are collected by burning liquidity tokens to remove a proportional share of the underlying reserves.

Since fees are added to liquidity pools, the invariant increases at the end of every trade. Within a single transaction, the invariant represents `token0_pool / token1_pool` at the end of the previous transaction.

There are many community-developed tools to determine returns. You can also read more in the docs about how to think about [LP returns](/concepts/advanced-concepts/understanding-returns).

### Protocol Fees[​](https://docs.uniswap.org/contracts/v2/concepts/advanced-topics/fees#protocol-fees) <a href="#protocol-fees" id="protocol-fees"></a>

At the moment there are no protocol fees. However, it is possible for a 0.05% fee to be turned on in the future.

### Protocol Charge Calculation[​](https://docs.uniswap.org/contracts/v2/concepts/advanced-topics/fees#protocol-charge-calculation) <a href="#protocol-charge-calculation" id="protocol-charge-calculation"></a>

In the future, it is possible that a protocol-wide charge of 0.05% per trade will take effect. This represents ⅙th (16.6̅%) of the 0.30% fee. The fee is in effect if [feeTo](/technical-reference/smart-contracts/factory#feeto) is not `address(0)` (`0x0000000000000000000000000000000000000000`), indicating that feeTo is the recipient of the charge.

This amount would not affect the fee paid by traders, but would affect the amount received by liquidity providers.

Rather than calculating this charge on swaps, which would significantly increase gas costs for all users, the charge is instead calculated when liquidity is added or removed.&#x20;


# Pricing

## How are prices determined?

As we learned in [Protocol Overview](/overview), each pair on DoveSwap is actually underpinned by a liquidity pool. Liquidity pools are smart contracts that hold balances of two unique tokens and enforces rules around depositing and withdrawing them. The primary rule is the [constant product formula](/concepts/glossary#x--y--k). When a token is withdrawn (bought), a proportional amount must be deposited (sold) to maintain the constant. The ratio of tokens in the pool, in combination with the constant product formula, ultimately determine the price that a swap executes at.

## Pricing Trades

When swapping tokens on DoveSwap, it's common to want to receive as many output tokens as possible for an *exact input amount*, or to pay as few input tokens as possible for an *exact output amount*. In order to calculate these amounts, a contract must look up the *current reserves* of a pair, in order to understand what the current price is. However, it is *not safe to perform this lookup and rely on the results without access to an external price*.

Say a smart contract naively wants to send 10 DAI to the DAI/WETH pair and receive as much WETH as it can get, given the current reserve ratio. If, when called, the naive smart contract simply looks up the current price and executes the trade, it is *vulnerable to front-running and will likely suffer an economic loss*. To see why, consider a malicious actor who sees this transaction before it is confirmed. They could execute a swap which dramatically changes the DAI/WETH price immediately before the naive swap goes through, wait for the naive swap to execute at a bad rate, and then swap to change the price back to what it was before the naive swap. This attack is fairly cheap and low-risk, and can typically be performed for a profit.

To prevent these types of attacks, it's vital to submit swaps *that have access to knowledge about the "fair" price their swap should execute at*. In other words, swaps need access to an *oracle*, to be sure that the best execution they can get from DoveSwap is close enough to what the oracle considers the "true" price. While this may sound complicated, the oracle can be as simple as an *off-chain observation of the current market price of a pair*. Because of arbitrage, it's typically the case that the ratio of the intra-block reserves of a pair is close to the "true" market price. So, if a user submits a trade with this knowledge in mind, they can ensure that the losses due to front-running are tightly bounded. This is how, for example, the DoveSwap frontend ensure trade safety. It calculates the optimal input/output amounts given observed intra-block prices, and uses the router to perform the swap, which guarantees the swap will execute at a rate no less that `x`% worse than the observed intra-block rate, where `x` is a user-specified slippage tolerance (0.5% by default).

### Exact Input[​](https://docs.uniswap.org/contracts/v2/concepts/advanced-topics/pricing#exact-input) <a href="#exact-input" id="exact-input"></a>

If you'd like to send an exact amount of input tokens in exchange for as many output tokens as possible, you'll want to use [getAmountsOut](/technical-reference/smart-contracts/router#getamountsout).&#x20;

### Exact Output[​](https://docs.uniswap.org/contracts/v2/concepts/advanced-topics/pricing#exact-output) <a href="#exact-output" id="exact-output"></a>

If you'd like to receive an exact amount of output tokens for as few input tokens as possible, you'll want to use [getAmountsIn](/technical-reference/smart-contracts/router#getamountsin).


# Understanding Returns

DoveSwap incentivizes users to add liquidity to trading pools by rewarding providers with the fees generated when other users trade with those pools. Market making, in general, is a complex activity. There is a risk of losing money during large and sustained movement in the underlying asset price compared to simply holding an asset.

## Risks

To understand the risks associated with providing liquidity you can read <https://medium.com/@pintail/uniswap-a-good-deal-for-liquidity-providers-104c0b6816f2> to get an in-depth look at how to conceptualize a liquidity position.

## Example from the article

> Consider the case where a liquidity provider adds 10,000 DAI and 100 WETH to a pool (for a total value of $20,000), the liquidity pool is now 100,000 DAI and 1,000 ETH in total. Because the amount supplied is equal to 10% of the total liquidity, the contract mints and sends the market maker “liquidity tokens” which entitle them to 10% of the liquidity available in the pool. These are not speculative tokens to be traded. They are merely an accounting or bookkeeping tool to keep track of how much the liquidity providers are owed. If others subsequently add/withdraw coins, new liquidity tokens are minted/burned such that everyone’s relative percentage share of the liquidity pool remains the same.
>
> **Now let’s assume the price trades on Coinbase from $100 to $150. The Uniswap contract should reflect this change as well after some arbitrage. Traders will add DAI and remove ETH until the new ratio is now 150:1.**
>
> What happens to the liquidity provider? The contract reflects something closer to 122,400 DAI and 817 ETH (to check these numbers are accurate, 122,400 \* 817 = 100,000,000 (our constant product) and 122,400 / 817 = 150, our new price). Withdrawing the 10% that we are entitled to would now yield 12,240 DAI and 81.7 ETH. The total market value here is $24,500. Roughly $500 worth of profit was missed out on as a result of the market making.
>
> **Obviously no one wants to provide liquidity out of charitable means, and the revenue isn’t dependent on the ability to flip out of good trades (there is no flipping). Instead, 0.3% of all trade volume is distributed proportionally to all liquidity providers. By default, these fees are put back into the liquidity pool, but can be collected any time. It’s difficult to know what the trade-off is between revenues from fees and losses from directional movements without knowing the amount of in-between trades. The more chop and back and forth, the better.**
>
> ### Why is my liquidity worth less than I put in?[​](https://docs.uniswap.org/contracts/v2/concepts/advanced-topics/understanding-returns#why-is-my-liquidity-worth-less-than-i-put-in) <a href="#why-is-my-liquidity-worth-less-than-i-put-in" id="why-is-my-liquidity-worth-less-than-i-put-in"></a>
>
> To understand why the value of a liquidity provider’s stake can go down despite income from fees, we need to look a bit more closely at the formula used by Uniswap to govern trading. The formula really is very simple. If we neglect trading fees, we have the following:
>
> * `eth_liquidity_pool * token_liquidity_pool = constant_product`
>
> In other words, the number of tokens a trader receives for their ETH and vice versa is calculated such that after the trade, the product of the two liquidity pools is the same as it was before the trade. The consequence of this formula is that for trades which are very small in value compared to the size of the liquidity pool we have:
>
> * `eth_price = token_liquidity_pool / eth_liquidity_pool`
>
> Combining these two equations, we can work out the size of each liquidity pool at any given price, assuming constant total liquidity:
>
> * `eth_liquidity_pool = sqrt(constant_product / eth_price)`
> * `token_liquidity_pool = sqrt(constant_product * eth_price)`
>
> So let’s look at the impact of a price change on a liquidity provider. To keep things simple, let’s imagine our liquidity provider supplies 1 ETH and 100 DAI to the Uniswap DAI exchange, giving them 1% of a liquidity pool which contains 100 ETH and 10,000 DAI. This implies a price of 1 ETH = 100 DAI. Still neglecting fees, let’s imagine that after some trading, the price has changed; 1 ETH is now worth 120 DAI. What is the new value of the liquidity provider’s stake? Plugging the numbers into the formulae above, we have:
>
> * `eth_liquidity_pool = 91.2871`
> * `dai_liquidity_pool = 10954.4511`
>
> "Since our liquidity provider has 1% of the liquidity tokens, this means they can now claim 0.9129 ETH and 109.54 DAI from the liquidity pool. But since DAI is approximately equivalent to USD, we might prefer to convert the entire amount into DAI to understand the overall impact of the price change. At the current price then, our liquidity is worth a total of 219.09 DAI. What if the liquidity provider had just held onto their original 1 ETH and 100 DAI? Well, now we can easily see that, at the new price, the total value would be 220 DAI. So our liquidity provider lost out by 0.91 DAI by providing liquidity to Uniswap instead of just holding onto their initial ETH and DAI."
>
> "Of course, if the price were to return to the same value as when the liquidity provider added their liquidity, this loss would disappear. **For this reason, we can call it an** impermanent los&#x73;**.** Using the equations above, we can derive a formula for the size of the impermanent loss in terms of the price ratio between when liquidity was supplied and now. We get the following:"
>
> * "`impermanent_loss = 2 * sqrt(price_ratio) / (1+price_ratio) — 1`"
> * "Which we can plot out to get a general sense of the scale of the impermanent loss at different price ratios:" ![](https://firebasestorage.googleapis.com/v0/b/firescript-577a2.appspot.com/o/imgs%2Fapp%2Fdnazarov%2FOscQ_nmzbA.png?alt=media\&token=4dff866e-a740-4121-9da4-9c9105baa404)
> * "Or to put it another way:"
>   * "a 1.25x price change results in a 0.6% loss relative to HODL"
>   * "a 1.50x price change results in a 2.0% loss relative to HODL"
>   * "a 1.75x price change results in a 3.8% loss relative to HODL"
>   * "a 2x price change results in a 5.7% loss relative to HODL"
>   * "a 3x price change results in a 13.4% loss relative to HODL"
>   * "a 4x price change results in a 20.0% loss relative to HODL"
>   * "a 5x price change results in a 25.5% loss relative to HODL"
> * "N.B. The loss is the same whichever direction the price change occurs in (i.e. a doubling in price results in the same loss as a halving)." -->


# Swapping tokens

## Step 1 - Bridge Assets From Mainnet&#x20;

![](https://1796161266-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F8BpmQExDAYT2HDv70fOg%2Fuploads%2FKl88TagrpJ41zxJV09z6%2Fimage.png?alt=media\&token=34547023-455f-406e-b885-395e9590f396)

Polygon zkEVM is a layer 2 solution for Ethereum. This means that you must first bridge assets you already have on ETH over. You can use the official zkEVM bridge linked on our site for convenience!

## Step 2 - Swap!

Select the tokens you want, and swap!


# Adding Liquidity

## Step 1 - Select the pools you are interested in

![](https://1796161266-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F8BpmQExDAYT2HDv70fOg%2Fuploads%2FSDZgQEKxfsCB88nkv3VI%2Fimage.png?alt=media\&token=6d43bb12-b4a3-4e10-a54b-9c2231432d8b)

Browse the supported pools on DoveSwap, and add liquidity to the pools you are most interested in!

## Step 2 - Choose your amount

![](https://1796161266-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F8BpmQExDAYT2HDv70fOg%2Fuploads%2FXZTOrAiBO4vIMC0YZUWq%2Fimage.png?alt=media\&token=823d43b1-c6e9-42e8-8413-b0fb987e8cc2)

Choose the amount of liquidity you wish to add. Remember you need BOTH assets to add liqudity! If you don't have enough of a certain asset, you might want to head to the Swap page to get more

## Step 3 - Profit

![](https://1796161266-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F8BpmQExDAYT2HDv70fOg%2Fuploads%2FtHXQFd4AKmWg8UJ8DQJ4%2Fimage.png?alt=media\&token=4cf6a8cd-3513-4ca4-a12a-449dc8409910)

Liquidity Providers (that's you now!) get 0.3% of all trades in the pool. Yay!&#x20;


# Smart Contracts

{% content-ref url="/pages/cROFPRMMKwiT0RHDtKus" %}
[Factory](/technical-reference/smart-contracts/factory)
{% endcontent-ref %}

{% content-ref url="/pages/VW4HFDZc29Trox9RpfJL" %}
[Pair](/technical-reference/smart-contracts/pair)
{% endcontent-ref %}

{% content-ref url="/pages/povnZRBWM298FOfIqjgG" %}
[Pair (ERC-20)](/technical-reference/smart-contracts/pair-erc-20)
{% endcontent-ref %}

{% content-ref url="/pages/nA84ozVVHIW2PWJtGsEO" %}
[Library](/technical-reference/smart-contracts/library)
{% endcontent-ref %}

{% content-ref url="/pages/arZny6u63gY14wse61zz" %}
[Router](/technical-reference/smart-contracts/router)
{% endcontent-ref %}


# Factory

## Address

`DoveSwapFactory` is deployed at `0xeA2709fCD78141976803C3aecA23eCEa3Cb9cb41` on the Polygon zkEVM Mainnet

## Events

### PairCreated[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/factory#paircreated) <a href="#paircreated" id="paircreated"></a>

```solidity
event PairCreated(address indexed token0, address indexed token1, address pair, uin
```

Emitted each time a pair is created via [createPair](#createpair).

* `token0` is guaranteed to be strictly less than `token1` by sort order.
* The final `uint` log value will be `1` for the first pair created, `2` for the second, etc. (see [allPairs](#allpairs)/[getPair](#getpair)).

## Read-Only Functions

### getPair[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/factory#getpair) <a href="#getpair" id="getpair"></a>

```solidity
function getPair(address tokenA, address tokenB) external view returns (address pair);
```

Returns the address of the pair for `tokenA` and `tokenB`, if it has been created, else `address(0)` (`0x0000000000000000000000000000000000000000`).

* `tokenA` and `tokenB` are interchangeable.
* Pair addresses can also be calculated deterministically via the SDK.

### allPairs[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/factory#allpairs) <a href="#allpairs" id="allpairs"></a>

```solidity
function allPairs(uint) external view returns (address pair);
```

Returns the address of the `n`th pair (`0`-indexed) created through the factory, or `address(0)` (`0x0000000000000000000000000000000000000000`) if not enough pairs have been created yet.

* Pass `0` for the address of the first pair created, `1` for the second, etc.

### allPairsLength[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/factory#allpairslength) <a href="#allpairslength" id="allpairslength"></a>

```solidity
function allPairsLength() external view returns (uint);
```

Returns the total number of pairs created through the factory so far.

### feeTo[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/factory#feeto) <a href="#feeto" id="feeto"></a>

```solidity
function feeTo() external view returns (address);
```

See [Protocol Charge Calculation](/concepts/advanced-concepts/fees).

### feeToSetter[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/factory#feetosetter) <a href="#feetosetter" id="feetosetter"></a>

```solidity
function feeToSetter() external view returns (address);
```

The address allowed to change [feeTo](#feeto).

## State-Changing Functions

### createPair[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/factory#createpair) <a href="#createpair" id="createpair"></a>

```solidity
function createPair(address tokenA, address tokenB) external returns (address pair);
```

Creates a pair for `tokenA` and `tokenB` if one doesn't exist already.

* `tokenA` and `tokenB` are interchangeable.
* Emits [PairCreated](#paircreated).


# Pair

This documentation covers DoveSwap-specific functionality. For ERC-20 functionality, see [Pair (ERC-20)](/technical-reference/smart-contracts/pair-erc-20).

## Events

### Mint[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/pair#mint) <a href="#mint" id="mint"></a>

```solidity
event Mint(address indexed sender, uint amount0, uint amount1);
```

Emitted each time liquidity tokens are created via [mint](#mint-1).

### Burn[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/pair#burn) <a href="#burn" id="burn"></a>

```solidity
event Burn(address indexed sender, uint amount0, uint amount1, address indexed to);
```

Emitted each time liquidity tokens are destroyed via [burn](#burn-1).

### Swap[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/pair#swap) <a href="#swap" id="swap"></a>

```solidity
event Swap(
  address indexed sender,
  uint amount0In,
  uint amount1In,
  uint amount0Out,
  uint amount1Out,
  address indexed to
);
```

Emitted each time a swap occurs via [swap](#swap-1).

### Sync[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/pair#sync) <a href="#sync" id="sync"></a>

```solidity
event Sync(uint112 reserve0, uint112 reserve1);
```

Emitted each time reserves are updated via [mint](#mint-1), [burn](#burn-1), [swap](#swap-1), or [sync](#sync-1).

## Read-Only Functions

### MINIMUM\_LIQUIDITY[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/pair#minimum_liquidity) <a href="#minimum_liquidity" id="minimum_liquidity"></a>

```solidity
function MINIMUM_LIQUIDITY() external pure returns (uint);
```

Returns `1000` for all pairs. See [Minimum Liquidity](#minimum_liquidity).

### factory[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/pair#factory) <a href="#factory" id="factory"></a>

```solidity
function factory() external view returns (address);
```

Returns the [factory address](/technical-reference/smart-contracts/factory#address).

### token0[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/pair#token0) <a href="#token0" id="token0"></a>

```solidity
function token0() external view returns (address);
```

Returns the address of the pair token with the lower sort order.

### token1[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/pair#token1) <a href="#token1" id="token1"></a>

```solidity
function token1() external view returns (address);
```

Returns the address of the pair token with the higher sort order.

### getReserves[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/pair#getreserves) <a href="#getreserves" id="getreserves"></a>

```solidity
function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
```

Returns the reserves of token0 and token1 used to price trades and distribute liquidity. See [Pricing](https://docs.uniswap.org/contracts/v2/concepts/advanced-topics/pricing). Also returns the `block.timestamp` (mod `2**32`) of the last block during which an interaction occured for the pair.

### price0CumulativeLast[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/pair#price0cumulativelast) <a href="#price0cumulativelast" id="price0cumulativelast"></a>

```solidity
function price0CumulativeLast() external view returns (uint);
```

See [Oracles](/concepts/core-concepts/oracles).

### price1CumulativeLast[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/pair#price1cumulativelast) <a href="#price1cumulativelast" id="price1cumulativelast"></a>

```solidity
function price1CumulativeLast() external view returns (uint);
```

See [Oracles](/concepts/core-concepts/oracles).

### kLast[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/pair#klast) <a href="#klast" id="klast"></a>

```solidity
function kLast() external view returns (uint);
```

Returns the product of the reserves as of the most recent liquidity event. See [Protocol Charge Calculation](/concepts/advanced-concepts/fees).

## State-Changing Functions

### mint[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/pair#mint-1) <a href="#mint-1" id="mint-1"></a>

```solidity
function mint(address to) external returns (uint liquidity);
```

Creates pool tokens.

* Emits [Mint](#mint), [Sync](#sync), [Transfer](/technical-reference/smart-contracts/pair-erc-20#transfer).

### burn[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/pair#burn-1) <a href="#burn-1" id="burn-1"></a>

```solidity
function burn(address to) external returns (uint amount0, uint amount1);
```

Destroys pool tokens.

* Emits [Burn](#burn), [Sync](#sync), [Transfer](/technical-reference/smart-contracts/pair-erc-20#transfer).

### swap[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/pair#swap-1) <a href="#swap-1" id="swap-1"></a>

```solidity
function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
```

Swaps tokens. For regular swaps, `data.length` must be `0`. Also see [Flash Swaps](/concepts/core-concepts/flash-swaps).

* Emits [Swap](#swap), [Sync](#sync).

### skim[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/pair#skim) <a href="#skim" id="skim"></a>

```solidity
function skim(address to) external;
```

Functions as a recovery mechanism in case enough tokens are sent to an pair to overflow the two uint112 storage slots for reserves, which could otherwise cause trades to fail. `skim()` allows a user to withdraw the difference between the current balance of the pair and 2\*\*112−1 to the caller, if that difference is greater than 0

### sync[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/pair#sync-1) <a href="#sync-1" id="sync-1"></a>

```solidity
function sync() external;
```

Functions as a recovery mechanism in the case that a token asynchronously deflates the balance of a pair. In this case, trades will receive sub-optimal rates, and if no liquidity provider is willing to rectify the situation, the pair is stuck. `sync()` exists to set the reserves of the contract to the current balances, providing a somewhat graceful recoveryfrom this situation

* Emits [Sync](#sync).


# Pair (ERC-20)

This documentation covers ERC-20 functionality for denominating pool tokens. For DoveSwap-specific functionality, see [Pair](/technical-reference/smart-contracts/pair).

## Events

### Approval[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/Pair-ERC-20#approval) <a href="#approval" id="approval"></a>

```solidity
event Approval(address indexed owner, address indexed spender, uint value);
```

Emitted each time an approval occurs via [approve](#approve) or [permit](#permit).

### Transfer[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/Pair-ERC-20#transfer) <a href="#transfer" id="transfer"></a>

```solidity
event Transfer(address indexed from, address indexed to, uint value);
```

Emitted each time a transfer occurs via [transfer](#transfer-1), [transferFrom](#transferfrom), [mint](/technical-reference/smart-contracts/pair#mint-1), or [burn](/technical-reference/smart-contracts/pair#burn-1).

## Read-Only Functions

### name[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/Pair-ERC-20#name) <a href="#name" id="name"></a>

```solidity
function name() external pure returns (string memory);
```

Returns `DoveSwap LP` for all pairs.

### symbol[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/Pair-ERC-20#symbol) <a href="#symbol" id="symbol"></a>

```solidity
function symbol() external pure returns (string memory);
```

Returns `DOV-LP` for all pairs.

### decimals[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/Pair-ERC-20#decimals) <a href="#decimals" id="decimals"></a>

```solidity
function decimals() external pure returns (uint8);sol
```

Returns `18` for all pairs.

### totalSupply[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/Pair-ERC-20#totalsupply) <a href="#totalsupply" id="totalsupply"></a>

```solidity
function totalSupply() external view returns (uint);
```

Returns the total amount of pool tokens for a pair.

### balanceOf[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/Pair-ERC-20#balanceof) <a href="#balanceof" id="balanceof"></a>

```solidity
function balanceOf(address owner) external view returns (uint);
```

Returns the amount of pool tokens owned by an address.

### allowance[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/Pair-ERC-20#allowance) <a href="#allowance" id="allowance"></a>

```solidity
function allowance(address owner, address spender) external view returns (uint);
```

Returns the amount of liquidity tokens owned by an address that a spender is allowed to transfer via [transferFrom](/technical-reference/smart-contracts/pair-erc-20#transferfrom).

### DOMAIN\_SEPARATOR[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/Pair-ERC-20#domain_separator) <a href="#domain_separator" id="domain_separator"></a>

```solidity
function DOMAIN_SEPARATOR() external view returns (bytes32);
```

Returns a domain separator for use in [permit](/technical-reference/smart-contracts/pair-erc-20#permit).

### PERMIT\_TYPEHASH[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/Pair-ERC-20#permit_typehash) <a href="#permit_typehash" id="permit_typehash"></a>

```solidity
function PERMIT_TYPEHASH() external view returns (bytes32);
```

Returns a typehash for use in [permit](/technical-reference/smart-contracts/pair-erc-20#permit).

### nonces[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/Pair-ERC-20#nonces) <a href="#nonces" id="nonces"></a>

```solidity
function nonces(address owner) external view returns (uint);
```

Returns the current nonce for an address for use in [permit](/technical-reference/smart-contracts/pair-erc-20#permit).

## State-Changing Functions

### approve[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/Pair-ERC-20#approve) <a href="#approve" id="approve"></a>

```solidity
function approve(address spender, uint value) external returns (bool);
```

Lets `msg.sender` set their allowance for a spender.

* Emits [Approval](#approval).

### transfer[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/Pair-ERC-20#transfer-1) <a href="#transfer-1" id="transfer-1"></a>

```solidity
function transfer(address to, uint value) external returns (bool);
```

Lets `msg.sender` send pool tokens to an address.

* Emits [Transfer](#transfer).

### transferFrom[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/Pair-ERC-20#transferfrom) <a href="#transferfrom" id="transferfrom"></a>

```solidity
function transferFrom(address from, address to, uint value) external returns (bool);
```

Sends pool tokens from one address to another.

* Requires approval.
* Emits [Transfer](#transfer).

### permit[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/Pair-ERC-20#permit) <a href="#permit" id="permit"></a>

```solidity
function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;
```

Sets the allowance for a spender where approval is granted via a signature.

* Emits [Approval](#approval).


# Library

## Internal Functions

### sortTokens[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/library#sorttokens) <a href="#sorttokens" id="sorttokens"></a>

```solidity
function sortTokens(address tokenA, address tokenB) internal pure returns (address token0, address token1);
```

Sorts token addresses.

### pairFor[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/library#pairfor) <a href="#pairfor" id="pairfor"></a>

```solidity
function pairFor(address factory, address tokenA, address tokenB) internal pure returns (address pair);
```

Calculates the address for a pair without making any external calls.

### getReserves[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/library#getreserves) <a href="#getreserves" id="getreserves"></a>

```solidity
function getReserves(address factory, address tokenA, address tokenB) internal view returns (uint reserveA, uint reserveB);
```

Calls [getReserves](/technical-reference/smart-contracts/pair#getreserves) on the pair for the passed tokens, and returns the results sorted in the order that the parameters were passed in.

### quote[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/library#quote) <a href="#quote" id="quote"></a>

```solidity
function quote(uint amountA, uint reserveA, uint reserveB) internal pure returns (uint amountB);
```

Given some asset amount and reserves, returns an amount of the other asset representing equivalent value.

* Useful for calculating optimal token amounts before calling [mint](/technical-reference/smart-contracts/pair#mint-1).

### getAmountOut[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/library#getamountout) <a href="#getamountout" id="getamountout"></a>

```solidity
function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) internal pure returns (uint amountOut);
```

Given an *input* asset amount, returns the maximum *output* amount of the other asset (accounting for fees) given reserves.

* Used in [getAmountsOut](#getamountsout).

### getAmountIn[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/library#getamountin) <a href="#getamountin" id="getamountin"></a>

```solidity
function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) internal pure returns (uint amountIn);
```

Returns the minimum *input* asset amount required to buy the given *output* asset amount (accounting for fees) given reserves.

* Used in [getAmountsIn](#getamountsin).

### getAmountsOut[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/library#getamountsout) <a href="#getamountsout" id="getamountsout"></a>

```solidity
function getAmountsOut(uint amountIn, address[] memory path) internal view returns (uint[] memory amounts);
```

Given an *input* asset amount and an array of token addresses, calculates all subsequent maximum *output* token amounts by calling [getReserves](#getreserves) for each pair of token addresses in the path in turn, and using these to call [getAmountOut](#getamountout).

* Useful for calculating optimal token amounts before calling [swap](/technical-reference/smart-contracts/pair#swap-1).

### getAmountsIn[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/library#getamountsin) <a href="#getamountsin" id="getamountsin"></a>

```solidity
function getAmountsIn(address factory, uint amountOut, address[] memory path) internal view returns (uint[] memory amounts);
```

Given an *output* asset amount and an array of token addresses, calculates all preceding minimum *input* token amounts by calling [getReserves](#getreserves) for each pair of token addresses in the path in turn, and using these to call [getAmountIn](#getamountin).

* Useful for calculating optimal token amounts before calling [swap](/technical-reference/smart-contracts/pair#swap-1).


# Router

## Address

`DoveSwapRouter02` is deployed at `0xc4212b4f901C8Afac75A27C8E8be7b9fa82D74d8on` on Polygon zkEVM Mainnet.&#x20;

## Read-Only Functions

### factory[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/router-02#factory) <a href="#factory" id="factory"></a>

```solidity
function factory() external pure returns (address);
```

Returns [factory address](#factory).

### WETH[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/router-02#weth) <a href="#weth" id="weth"></a>

```solidity
function WETH() external pure returns (address);
```

Returns the [canonical WETH address](https://blog.0xproject.com/canonical-weth-a9aa7d0279dd) on zkEVM Mainnet.

### quote[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/router-02#quote) <a href="#quote" id="quote"></a>

See [quote](/technical-reference/smart-contracts/library#quote).

### getAmountOut[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/router-02#getamountout) <a href="#getamountout" id="getamountout"></a>

See [getAmountOut](/technical-reference/smart-contracts/library#getamountout).

### getAmountIn[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/router-02#getamountin) <a href="#getamountin" id="getamountin"></a>

See [getAmountIn](/technical-reference/smart-contracts/library#getamountin).

### getAmountsOut[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/router-02#getamountsout) <a href="#getamountsout" id="getamountsout"></a>

```solidity
function getAmountsOut(uint amountIn, address[] memory path) public view returns (uint[] memory amounts);
```

See [getAmountsOut](/technical-reference/smart-contracts/library#getamountsout).

### getAmountsIn[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/router-02#getamountsin) <a href="#getamountsin" id="getamountsin"></a>

```solidity
function getAmountsIn(uint amountOut, address[] memory path) public view returns (uint[] memory amounts);
```

See [getAmountsIn](/technical-reference/smart-contracts/library#getamountsout).

## State-Changing Functions

### addLiquidity[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/router-02#addliquidity) <a href="#addliquidity" id="addliquidity"></a>

```solidity
function addLiquidity(
  address tokenA,
  address tokenB,
  uint amountADesired,
  uint amountBDesired,
  uint amountAMin,
  uint amountBMin,
  address to,
  uint deadline
) external returns (uint amountA, uint amountB, uint liquidity);
```

Adds liquidity to an ERC-20⇄ERC-20 pool.

* To cover all possible scenarios, `msg.sender` should have already given the router an allowance of at least amountADesired/amountBDesired on tokenA/tokenB.
* Always adds assets at the ideal ratio, according to the price when the transaction is executed.
* If a pool for the passed tokens does not exists, one is created automatically, and exactly amountADesired/amountBDesired tokens are added.

| Name           | Type      |                                                                                                                |
| -------------- | --------- | -------------------------------------------------------------------------------------------------------------- |
| tokenA         | `address` | A pool token.                                                                                                  |
| tokenB         | `address` | A pool token.                                                                                                  |
| amountADesired | `uint`    | The amount of tokenA to add as liquidity if the B/A price is <= amountBDesired/amountADesired (A depreciates). |
| amountBDesired | `uint`    | The amount of tokenB to add as liquidity if the A/B price is <= amountADesired/amountBDesired (B depreciates). |
| amountAMin     | `uint`    | Bounds the extent to which the B/A price can go up before the transaction reverts. Must be <= amountADesired.  |
| amountBMin     | `uint`    | Bounds the extent to which the A/B price can go up before the transaction reverts. Must be <= amountBDesired.  |
| to             | `address` | Recipient of the liquidity tokens.                                                                             |
| deadline       | `uint`    | Unix timestamp after which the transaction will revert.                                                        |
|                |           |                                                                                                                |
| amountA        | `uint`    | The amount of tokenA sent to the pool.                                                                         |
| amountB        | `uint`    | The amount of tokenB sent to the pool.                                                                         |
| liquidity      | `uint`    | The amount of liquidity tokens minted.                                                                         |

### addLiquidityETH[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/router-02#addliquidityeth) <a href="#addliquidityeth" id="addliquidityeth"></a>

```solidity
function addLiquidityETH(
  address token,
  uint amountTokenDesired,
  uint amountTokenMin,
  uint amountETHMin,
  address to,
  uint deadline
) external payable returns (uint amountToken, uint amountETH, uint liquidity);ol
```

Adds liquidity to an ERC-20⇄WETH pool with ETH.

* To cover all possible scenarios, `msg.sender` should have already given the router an allowance of at least amountTokenDesired on token.
* Always adds assets at the ideal ratio, according to the price when the transaction is executed.
* `msg.value` is treated as a amountETHDesired.
* Leftover ETH, if any, is returned to `msg.sender`.
* If a pool for the passed token and WETH does not exists, one is created automatically, and exactly amountTokenDesired/`msg.value` tokens are added.

| Name                           | Type      |                                                                                                                           |
| ------------------------------ | --------- | ------------------------------------------------------------------------------------------------------------------------- |
| token                          | `address` | A pool token.                                                                                                             |
| amountTokenDesired             | `uint`    | The amount of token to add as liquidity if the WETH/token price is <= `msg.value`/amountTokenDesired (token depreciates). |
| `msg.value` (amountETHDesired) | `uint`    | The amount of ETH to add as liquidity if the token/WETH price is <= amountTokenDesired/`msg.value` (WETH depreciates).    |
| amountTokenMin                 | `uint`    | Bounds the extent to which the WETH/token price can go up before the transaction reverts. Must be <= amountTokenDesired.  |
| amountETHMin                   | `uint`    | Bounds the extent to which the token/WETH price can go up before the transaction reverts. Must be <= `msg.value`.         |
| to                             | `address` | Recipient of the liquidity tokens.                                                                                        |
| deadline                       | `uint`    | Unix timestamp after which the transaction will revert.                                                                   |
|                                |           |                                                                                                                           |
| amountToken                    | `uint`    | The amount of token sent to the pool.                                                                                     |
| amountETH                      | `uint`    | The amount of ETH converted to WETH and sent to the pool.                                                                 |
| liquidity                      | `uint`    | The amount of liquidity tokens minted.                                                                                    |

### removeLiquidity[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/router-02#removeliquidity) <a href="#removeliquidity" id="removeliquidity"></a>

```solidity
function removeLiquidity(
  address tokenA,
  address tokenB,
  uint liquidity,
  uint amountAMin,
  uint amountBMin,
  address to,
  uint deadline
) external returns (uint amountA, uint amountB);
```

Removes liquidity from an ERC-20⇄ERC-20 pool.

* `msg.sender` should have already given the router an allowance of at least liquidity on the pool.

| Name       | Type      |                                                                                       |
| ---------- | --------- | ------------------------------------------------------------------------------------- |
| tokenA     | `address` | A pool token.                                                                         |
| tokenB     | `address` | A pool token.                                                                         |
| liquidity  | `uint`    | The amount of liquidity tokens to remove.                                             |
| amountAMin | `uint`    | The minimum amount of tokenA that must be received for the transaction not to revert. |
| amountBMin | `uint`    | The minimum amount of tokenB that must be received for the transaction not to revert. |
| to         | `address` | Recipient of the underlying assets.                                                   |
| deadline   | `uint`    | Unix timestamp after which the transaction will revert.                               |
|            |           |                                                                                       |
| amountA    | `uint`    | The amount of tokenA received.                                                        |
| amountB    | `uint`    | The amount of tokenB received.                                                        |

### removeLiquidityETH[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/router-02#removeliquidityeth) <a href="#removeliquidityeth" id="removeliquidityeth"></a>

```solidity
function removeLiquidityETH(
  address token,
  uint liquidity,
  uint amountTokenMin,
  uint amountETHMin,
  address to,
  uint deadline
) external returns (uint amountToken, uint amountETH);
```

Removes liquidity from an ERC-20⇄WETH pool and receive ETH.

* `msg.sender` should have already given the router an allowance of at least liquidity on the pool.

| Name           | Type      |                                                                                      |
| -------------- | --------- | ------------------------------------------------------------------------------------ |
| token          | `address` | A pool token.                                                                        |
| liquidity      | `uint`    | The amount of liquidity tokens to remove.                                            |
| amountTokenMin | `uint`    | The minimum amount of token that must be received for the transaction not to revert. |
| amountETHMin   | `uint`    | The minimum amount of ETH that must be received for the transaction not to revert.   |
| to             | `address` | Recipient of the underlying assets.                                                  |
| deadline       | `uint`    | Unix timestamp after which the transaction will revert.                              |
|                |           |                                                                                      |
| amountToken    | `uint`    | The amount of token received.                                                        |
| amountETH      | `uint`    | The amount of ETH received.                                                          |

### removeLiquidityWithPermit[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/router-02#removeliquiditywithpermit) <a href="#removeliquiditywithpermit" id="removeliquiditywithpermit"></a>

```solidity
function removeLiquidityWithPermit(
  address tokenA,
  address tokenB,
  uint liquidity,
  uint amountAMin,
  uint amountBMin,
  address to,
  uint deadline,
  bool approveMax, uint8 v, bytes32 r, bytes32 s
) external returns (uint amountA, uint amountB);
```

Removes liquidity from an ERC-20⇄ERC-20 pool without pre-approval, thanks to [permit](/technical-reference/smart-contracts/pair-erc-20#permit).

| Name       | Type      |                                                                                       |
| ---------- | --------- | ------------------------------------------------------------------------------------- |
| tokenA     | `address` | A pool token.                                                                         |
| tokenB     | `address` | A pool token.                                                                         |
| liquidity  | `uint`    | The amount of liquidity tokens to remove.                                             |
| amountAMin | `uint`    | The minimum amount of tokenA that must be received for the transaction not to revert. |
| amountBMin | `uint`    | The minimum amount of tokenB that must be received for the transaction not to revert. |
| to         | `address` | Recipient of the underlying assets.                                                   |
| deadline   | `uint`    | Unix timestamp after which the transaction will revert.                               |
| approveMax | `bool`    | Whether or not the approval amount in the signature is for liquidity or `uint(-1)`.   |
| v          | `uint8`   | The v component of the permit signature.                                              |
| r          | `bytes32` | The r component of the permit signature.                                              |
| s          | `bytes32` | The s component of the permit signature.                                              |
|            |           |                                                                                       |
| amountA    | `uint`    | The amount of tokenA received.                                                        |
| amountB    | `uint`    | The amount of tokenB received.                                                        |

### removeLiquidityETHWithPermit[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/router-02#removeliquidityethwithpermit) <a href="#removeliquidityethwithpermit" id="removeliquidityethwithpermit"></a>

```solidity
function removeLiquidityETHWithPermit(
  address token,
  uint liquidity,
  uint amountTokenMin,
  uint amountETHMin,
  address to,
  uint deadline,
  bool approveMax, uint8 v, bytes32 r, bytes32 s
) external returns (uint amountToken, uint amountETH);
```

Removes liquidity from an ERC-20⇄WETTH pool and receive ETH without pre-approval, thanks to [permit](/technical-reference/smart-contracts/pair-erc-20#permit).

| Name           | Type      |                                                                                      |
| -------------- | --------- | ------------------------------------------------------------------------------------ |
| token          | `address` | A pool token.                                                                        |
| liquidity      | `uint`    | The amount of liquidity tokens to remove.                                            |
| amountTokenMin | `uint`    | The minimum amount of token that must be received for the transaction not to revert. |
| amountETHMin   | `uint`    | The minimum amount of ETH that must be received for the transaction not to revert.   |
| to             | `address` | Recipient of the underlying assets.                                                  |
| deadline       | `uint`    | Unix timestamp after which the transaction will revert.                              |
| approveMax     | `bool`    | Whether or not the approval amount in the signature is for liquidity or `uint(-1)`.  |
| v              | `uint8`   | The v component of the permit signature.                                             |
| r              | `bytes32` | The r component of the permit signature.                                             |
| s              | `bytes32` | The s component of the permit signature.                                             |
|                |           |                                                                                      |
| amountToken    | `uint`    | The amount of token received.                                                        |
| amountETH      | `uint`    | The amount of ETH received.                                                          |

### removeLiquidityETHSupportingFeeOnTransferTokens[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/router-02#removeliquidityethsupportingfeeontransfertokens) <a href="#removeliquidityethsupportingfeeontransfertokens" id="removeliquidityethsupportingfeeontransfertokens"></a>

```solidity
function removeLiquidityETHSupportingFeeOnTransferTokens(
  address token,
  uint liquidity,
  uint amountTokenMin,
  uint amountETHMin,
  address to,
  uint deadline
) external returns (uint amountETH);
```

Identical to [removeLiquidityETH](#removeliquidityeth), but succeeds for tokens that take a fee on transfer.

* `msg.sender` should have already given the router an allowance of at least liquidity on the pool.

| Name           | Type      |                                                                                      |
| -------------- | --------- | ------------------------------------------------------------------------------------ |
| token          | `address` | A pool token.                                                                        |
| liquidity      | `uint`    | The amount of liquidity tokens to remove.                                            |
| amountTokenMin | `uint`    | The minimum amount of token that must be received for the transaction not to revert. |
| amountETHMin   | `uint`    | The minimum amount of ETH that must be received for the transaction not to revert.   |
| to             | `address` | Recipient of the underlying assets.                                                  |
| deadline       | `uint`    | Unix timestamp after which the transaction will revert.                              |
|                |           |                                                                                      |
| amountETH      | `uint`    | The amount of ETH received.                                                          |

### removeLiquidityETHWithPermitSupportingFeeOnTransferTokens[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/router-02#removeliquidityethwithpermitsupportingfeeontransfertokens) <a href="#removeliquidityethwithpermitsupportingfeeontransfertokens" id="removeliquidityethwithpermitsupportingfeeontransfertokens"></a>

```solidity
function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(
  address token,
  uint liquidity,
  uint amountTokenMin,
  uint amountETHMin,
  address to,
  uint deadline,
  bool approveMax, uint8 v, bytes32 r, bytes32 s
) external returns (uint amountETH);
```

Identical to [removeLiquidityETHWithPermit](#removeliquiditywithpermit), but succeeds for tokens that take a fee on transfer.

| Name           | Type      |                                                                                      |
| -------------- | --------- | ------------------------------------------------------------------------------------ |
| token          | `address` | A pool token.                                                                        |
| liquidity      | `uint`    | The amount of liquidity tokens to remove.                                            |
| amountTokenMin | `uint`    | The minimum amount of token that must be received for the transaction not to revert. |
| amountETHMin   | `uint`    | The minimum amount of ETH that must be received for the transaction not to revert.   |
| to             | `address` | Recipient of the underlying assets.                                                  |
| deadline       | `uint`    | Unix timestamp after which the transaction will revert.                              |
| approveMax     | `bool`    | Whether or not the approval amount in the signature is for liquidity or `uint(-1)`.  |
| v              | `uint8`   | The v component of the permit signature.                                             |
| r              | `bytes32` | The r component of the permit signature.                                             |
| s              | `bytes32` | The s component of the permit signature.                                             |
|                |           |                                                                                      |
| amountETH      | `uint`    | The amount of ETH received.                                                          |

### swapExactTokensForTokens[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/router-02#swapexacttokensfortokens) <a href="#swapexacttokensfortokens" id="swapexacttokensfortokens"></a>

```solidity
function swapExactTokensForTokens(
  uint amountIn,
  uint amountOutMin,
  address[] calldata path,
  address to,
  uint deadline
) external returns (uint[] memory amounts);so
```

Swaps an exact amount of input tokens for as many output tokens as possible, along the route determined by the path. The first element of path is the input token, the last is the output token, and any intermediate elements represent intermediate pairs to trade through (if, for example, a direct pair does not exist).

* `msg.sender` should have already given the router an allowance of at least amountIn on the input token.

| Name         | Type                 |                                                                                                                                      |
| ------------ | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| amountIn     | `uint`               | The amount of input tokens to send.                                                                                                  |
| amountOutMin | `uint`               | The minimum amount of output tokens that must be received for the transaction not to revert.                                         |
| path         | `address[] calldata` | An array of token addresses. `path.length` must be >= 2. Pools for each consecutive pair of addresses must exist and have liquidity. |
| to           | `address`            | Recipient of the output tokens.                                                                                                      |
| deadline     | `uint`               | Unix timestamp after which the transaction will revert.                                                                              |
|              |                      |                                                                                                                                      |
| amounts      | `uint[] memory`      | The input token amount and all subsequent output token amounts.                                                                      |

### swapTokensForExactTokens[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/router-02#swaptokensforexacttokens) <a href="#swaptokensforexacttokens" id="swaptokensforexacttokens"></a>

```solidity
function swapTokensForExactTokens(
  uint amountOut,
  uint amountInMax,
  address[] calldata path,
  address to,
  uint deadline
) external returns (uint[] memory amounts);
```

Receive an exact amount of output tokens for as few input tokens as possible, along the route determined by the path. The first element of path is the input token, the last is the output token, and any intermediate elements represent intermediate tokens to trade through (if, for example, a direct pair does not exist).

* `msg.sender` should have already given the router an allowance of at least amountInMax on the input token.

| Name        | Type                 |                                                                                                                                      |
| ----------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| amountOut   | `uint`               | The amount of output tokens to receive.                                                                                              |
| amountInMax | `uint`               | The maximum amount of input tokens that can be required before the transaction reverts.                                              |
| path        | `address[] calldata` | An array of token addresses. `path.length` must be >= 2. Pools for each consecutive pair of addresses must exist and have liquidity. |
| to          | `address`            | Recipient of the output tokens.                                                                                                      |
| deadline    | `uint`               | Unix timestamp after which the transaction will revert.                                                                              |
|             |                      |                                                                                                                                      |
| amounts     | `uint[] memory`      | The input token amount and all subsequent output token amounts.                                                                      |

### swapExactETHForTokens[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/router-02#swapexactethfortokens) <a href="#swapexactethfortokens" id="swapexactethfortokens"></a>

```solidity
function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)
  external
  payable
  returns (uint[] memory amounts);
```

Swaps an exact amount of ETH for as many output tokens as possible, along the route determined by the path. The first element of path must be [WETH](#weth), the last is the output token, and any intermediate elements represent intermediate pairs to trade through (if, for example, a direct pair does not exist).

| Name                   | Type                 |                                                                                                                                      |
| ---------------------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `msg.value` (amountIn) | `uint`               | The amount of ETH to send.                                                                                                           |
| amountOutMin           | `uint`               | The minimum amount of output tokens that must be received for the transaction not to revert.                                         |
| path                   | `address[] calldata` | An array of token addresses. `path.length` must be >= 2. Pools for each consecutive pair of addresses must exist and have liquidity. |
| to                     | `address`            | Recipient of the output tokens.                                                                                                      |
| deadline               | `uint`               | Unix timestamp after which the transaction will revert.                                                                              |
|                        |                      |                                                                                                                                      |
| amounts                | `uint[] memory`      | The input token amount and all subsequent output token amounts.                                                                      |

### swapTokensForExactETH[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/router-02#swaptokensforexacteth) <a href="#swaptokensforexacteth" id="swaptokensforexacteth"></a>

```solidity
function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline)
  external
  returns (uint[] memory amounts);
```

Receive an exact amount of ETH for as few input tokens as possible, along the route determined by the path. The first element of path is the input token, the last must be [WETH](#weth), and any intermediate elements represent intermediate pairs to trade through (if, for example, a direct pair does not exist).

* `msg.sender` should have already given the router an allowance of at least amountInMax on the input token.
* If the to address is a smart contract, it must have the ability to receive ETH.

| Name        | Type                 |                                                                                                                                      |
| ----------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| amountOut   | `uint`               | The amount of ETH to receive.                                                                                                        |
| amountInMax | `uint`               | The maximum amount of input tokens that can be required before the transaction reverts.                                              |
| path        | `address[] calldata` | An array of token addresses. `path.length` must be >= 2. Pools for each consecutive pair of addresses must exist and have liquidity. |
| to          | `address`            | Recipient of ETH.                                                                                                                    |
| deadline    | `uint`               | Unix timestamp after which the transaction will revert.                                                                              |
|             |                      |                                                                                                                                      |
| amounts     | `uint[] memory`      | The input token amount and all subsequent output token amounts.                                                                      |

### swapExactTokensForETH[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/router-02#swapexacttokensforeth) <a href="#swapexacttokensforeth" id="swapexacttokensforeth"></a>

```solidity
function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline)
  external
  returns (uint[] memory amounts
```

Swaps an exact amount of tokens for as much ETH as possible, along the route determined by the path. The first element of path is the input token, the last must be [WETH](#weth), and any intermediate elements represent intermediate pairs to trade through (if, for example, a direct pair does not exist).

* If the to address is a smart contract, it must have the ability to receive ETH.

| Name         | Type                 |                                                                                                                                      |
| ------------ | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| amountIn     | `uint`               | The amount of input tokens to send.                                                                                                  |
| amountOutMin | `uint`               | The minimum amount of output tokens that must be received for the transaction not to revert.                                         |
| path         | `address[] calldata` | An array of token addresses. `path.length` must be >= 2. Pools for each consecutive pair of addresses must exist and have liquidity. |
| to           | `address`            | Recipient of the ETH.                                                                                                                |
| deadline     | `uint`               | Unix timestamp after which the transaction will revert.                                                                              |
|              |                      |                                                                                                                                      |
| amounts      | `uint[] memory`      | The input token amount and all subsequent output token amounts.                                                                      |

### swapETHForExactTokens[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/router-02#swapethforexacttokens) <a href="#swapethforexacttokens" id="swapethforexacttokens"></a>

```solidity
function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline)
  external
  payable
  returns (uint[] memory amounts);
```

Receive an exact amount of tokens for as little ETH as possible, along the route determined by the path. The first element of path must be [WETH](#weth), the last is the output token and any intermediate elements represent intermediate pairs to trade through (if, for example, a direct pair does not exist).

* Leftover ETH, if any, is returned to `msg.sender`.

| Name                      | Type                 |                                                                                                                                      |
| ------------------------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| amountOut                 | `uint`               | The amount of tokens to receive.                                                                                                     |
| `msg.value` (amountInMax) | `uint`               | The maximum amount of ETH that can be required before the transaction reverts.                                                       |
| path                      | `address[] calldata` | An array of token addresses. `path.length` must be >= 2. Pools for each consecutive pair of addresses must exist and have liquidity. |
| to                        | `address`            | Recipient of the output tokens.                                                                                                      |
| deadline                  | `uint`               | Unix timestamp after which the transaction will revert.                                                                              |
|                           |                      |                                                                                                                                      |
| amounts                   | `uint[] memory`      | The input token amount and all subsequent output token amounts.                                                                      |

### swapExactTokensForTokensSupportingFeeOnTransferTokens[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/router-02#swapexacttokensfortokenssupportingfeeontransfertokens) <a href="#swapexacttokensfortokenssupportingfeeontransfertokens" id="swapexacttokensfortokenssupportingfeeontransfertokens"></a>

```solidity
function swapExactTokensForTokensSupportingFeeOnTransferTokens(
  uint amountIn,
  uint amountOutMin,
  address[] calldata path,
  address to,
  uint deadline
) external;
```

Identical to [swapExactTokensForTokens](#swapexacttokensfortokens), but succeeds for tokens that take a fee on transfer.

* `msg.sender` should have already given the router an allowance of at least amountIn on the input token.

| Name         | Type                 |                                                                                                                                      |
| ------------ | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| amountIn     | `uint`               | The amount of input tokens to send.                                                                                                  |
| amountOutMin | `uint`               | The minimum amount of output tokens that must be received for the transaction not to revert.                                         |
| path         | `address[] calldata` | An array of token addresses. `path.length` must be >= 2. Pools for each consecutive pair of addresses must exist and have liquidity. |
| to           | `address`            | Recipient of the output tokens.                                                                                                      |
| deadline     | `uint`               | Unix timestamp after which the transaction will revert.                                                                              |

### swapExactETHForTokensSupportingFeeOnTransferTokens[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/router-02#swapexactethfortokenssupportingfeeontransfertokens) <a href="#swapexactethfortokenssupportingfeeontransfertokens" id="swapexactethfortokenssupportingfeeontransfertokens"></a>

```solidity
function swapExactETHForTokensSupportingFeeOnTransferTokens(
  uint amountOutMin,
  address[] calldata path,
  address to,
  uint deadline
) external payable;
```

Identical to [swapExactETHForTokens](#swapexactethfortokens), but succeeds for tokens that take a fee on transfer.

| Name                   | Type                 |                                                                                                                                      |
| ---------------------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `msg.value` (amountIn) | `uint`               | The amount of ETH to send.                                                                                                           |
| amountOutMin           | `uint`               | The minimum amount of output tokens that must be received for the transaction not to revert.                                         |
| path                   | `address[] calldata` | An array of token addresses. `path.length` must be >= 2. Pools for each consecutive pair of addresses must exist and have liquidity. |
| to                     | `address`            | Recipient of the output tokens.                                                                                                      |
| deadline               | `uint`               | Unix timestamp after which the transaction will revert.                                                                              |

### swapExactTokensForETHSupportingFeeOnTransferTokens[​](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/router-02#swapexacttokensforethsupportingfeeontransfertokens) <a href="#swapexacttokensforethsupportingfeeontransfertokens" id="swapexacttokensforethsupportingfeeontransfertokens"></a>

```solidity
function swapExactTokensForETHSupportingFeeOnTransferTokens(
  uint amountIn,
  uint amountOutMin,
  address[] calldata path,
  address to,
  uint deadline
) external;
```

Identical to [swapExactTokensForETH](#swapexacttokensforeth), but succeeds for tokens that take a fee on transfer.

* If the to address is a smart contract, it must have the ability to receive ETH.

| Name         | Type                 |                                                                                                                                      |
| ------------ | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| amountIn     | `uint`               | The amount of input tokens to send.                                                                                                  |
| amountOutMin | `uint`               | The minimum amount of output tokens that must be received for the transaction not to revert.                                         |
| path         | `address[] calldata` | An array of token addresses. `path.length` must be >= 2. Pools for each consecutive pair of addresses must exist and have liquidity. |
| to           | `address`            | Recipient of the ETH.                                                                                                                |
| deadline     | `uint`               | Unix timestamp after which the transaction will revert.                                                                              |


# Governance

Coming soon!


