# What is Quickswap?

<figure><img src="/files/8m0AeOHFoHgML5BpOKx6" alt=""><figcaption></figcaption></figure>

## Overview

QuickSwap is the leading DEX with deployments on:

* Polygon PoS
* Base
* Polygon zkEVM
* Manta Pacific
* Immutable zkEVM
* Soneium
* X Layer
* Somnia

Users can swap, LP, farm, stake, and trade perpetual swaps at fast speeds with extremely low transaction fees. Home to the DragonFi ecosystem, QuickSwap aims to provide a comprehensive suite of products and services that extend beyond just DeFi, including a decentralised Perpetual Exchange, Gaming Hub, and more.

## Origins

QuickSwap was created to solve the high gas fees & slow transaction times associated with using DEXs (decentralised exchanges) on other networks such as Ethereum.

Launching in October 2021, QuickSwap is supported by some of the industry’s most prominent thought leaders in the fields of Ethereum token & contract standards and Layer 2 scaling. It was kickstarted by a team of professionals who are experts in blockchain:

* Nick Mudge is an Ethereum contract programmer, code reviewer, security auditor, standards author, and web developer with over 6 years of active blockchain programming experience. Nick participated in the discussions that developed the ERC721 standard and is the author of [EIP-2535 Diamond Standard](https://eips.ethereum.org/EIPS/eip-2535), in addition to [ERC1538](https://eips.ethereum.org/EIPS/eip-1538) and [ERC998](https://eips.ethereum.org/EIPS/eip-998) Ethereum contract standards
* Sameep Singhania is the Co-Founder and Director of the blockchain development and consulting company Ginete Technologies. He is an experienced blockchain developer who has devoted the past two years of his life to assisting businesses explore synergies with, and integrate, blockchain. Sameep is focused on facilitating widespread adoption of decentralised technologies
* Roc Zacharias is also the Co-Founder of QuickSwap and serves as CEO of Lunar Digital Assets, a blockchain marketing firm. He's also a core contributor to the Dogechain project & has played an instrumental role in driving QuickSwap's growth & adoption.


# Quickswap AMM

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

QuickSwap is an *automated liquidity protocol* powered by a [constant product formula](https://docs.quickswap.exchange/concepts/protocol-overview/04-glossary#constant-product-formula) and implemented in a system of non-upgradeable smart contracts on the [Ethereum](https://ethereum.org/) blockchain. It obviates the need for trusted intermediaries, prioritizing **decentralisation**, **censorship resistance**, and **security**. QuickSwap is **open-source software** licensed under the [GPL](https://en.wikipedia.org/wiki/GNU_General_Public_License).

Each Quickswap smart contract, or pair, manages a liquidity pool made up of reserves of two [ERC-20](https://eips.ethereum.org/EIPS/eip-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.

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

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, QuickSwap 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 realised 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.

<figure><img src="/files/2hd56exI9C2yNFwy1Uar" alt=""><figcaption></figcaption></figure>

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


# Ecosystem Participants

<figure><img src="/files/1QLLb8j6bbgJK6PuxJCi" alt=""><figcaption></figcaption></figure>

The QuickSwap ecosystem is primarily comprised of three types of users: LPs (liquidity providers), traders, and developers. LPs are incentivised 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](https://docs.quickswap.exchange/concepts/advanced-topics/01-fees) (which goes to liquidity providers). Developers can integrate directly with QuickSwap 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 (LPs)

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 while unlocking interoperability with other DeFi projects through QuickSwap.
* Finally, some DeFi pioneers are exploring complex liquidity provision interactions like incentivised liquidity, liquidity as collateral, and other experimental strategies. QuickSwap 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 QuickSwap protocol.
* Arbitrage bots seek profits by comparing prices across different platforms to find an edge. (Though it might seem extractive, these bots actually help equalise prices across broader Ethereum markets and keep things fair.)
* dApp users buy tokens on QuickSwap 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 incentivising liquidity.

## Developers/Projects

QuickSwap is broadly used in the wider Polygon ecosystem, including the following:

* Its open-source, accessible nature means there are countless UX experiments and front-ends built to offer access to QuickSwap functionality. You can find QuickSwap functions in most of the major DeFi dashboard projects; there are also many [Uniswap-specific tools](https://github.com/Uniswap/universe) built by the community.
* Wallets often integrate swapping and liquidity provision functionality as a core offering of their product.
* DEX aggregators pull liquidity from many liquidity protocols to offer traders the best prices but splitting their trades. QuickSwap is the biggest single decentralised liquidity source for these projects.
* Smart contract developers use the suite of functions available to invent new DeFi tools and other various experimental ideas. See projects like [Unisocks](https://unisocks.exchange/) or [Zora](https://ourzora.com/), among many others.

## QuickSwap Team & Community <a href="#quickswap-team-and-community" id="quickswap-team-and-community"></a>

The QuickSwap team, along with the broader community, drives development of the protocol and ecosystem. QuickSwap is a fully decentralised protocol, where decisions on the future of the DEX are made by the community of QUICK holders via governance proposals & votes.&#x20;


# Key Features

## Liquidity Hub

Liquidity Hub is a decentralised optimisation layer that operates above Automated Market Makers (AMMs). This layer mitigates the problem of fragmented liquidity in DeFi, enabling Quickswap to tap into external liquidity sources in order to provide better prices on swaps.\
\
**More info here:** <https://www.orbs.com/liquidity-hub/>

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

## V3 Concentrated Liquidity Model

QuickSwap acquired a V3 license from Algebra and is currently deployed on all chains on the DEX. V3 is different from V2 in that users need to set their liquidity within specific designated price ranges - this allows for greater capital efficiency, although a manual rebalancing of the portfolio is required if liquidity falls out of range (regular V3).

## V3 Active Liquidity Management

QuickSwap integrated with Gamma in January 2023 to enable V3 active liquidity management, meaning user LP positions are automatically managed by the protocol, allowing them to earn auto-compounding rewards without having to manually adjust their portfolios when prices fall out of range. Users can also stake their LP tokens in select Gamma V3 farms, allowing them to earn additional yield in farming rewards.

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

Unipilot also launched their active liquidity management solution for Dogechain LPs & farms on QuickSwap in June 2023, bringing similar features to the Dogechain blockchain for the shibe community.

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

## Cross-Chain Swaps

Complete seamless cross-chain swaps with support for 11 different networks using [Squid's](https://t.co/Os7AF0To0c) integrated widget, powered by [Axelar Network](https://t.co/5ibc7viFj3).

{% embed url="<https://video.twimg.com/ext_tw_video/1650852055727108097/pu/vid/1280x720/QNDFS5OuRBIjzp06.mp4?tag=12>" %}


# Swap

Fast speeds and low transaction speeds - that's what the QuickSwap dragons have been know for since the inception of our DEX! The default swap option is **Best Trade.**  When clicking on Best Trade, you'll be shown the other swap types as well:&#x20;

* Best Trade
* V2 Market
* V3 Market
* Limit
* dTWAP

There is also the option to choose **cross-chain**, which will load the custom widget where you can seamlessly swap from one blockchain to another in one click.

## Best Trade

{% hint style="info" %}
Taxed tokens are not possible to trade using best trade. please choose V2 Market for swapping these tokens
{% endhint %}

Choosing **Best Trade** ensures you get the best possible trade route. Using this option, your swap will use the most efficient path, utilising all V2 & V3 liquidity pools. These swaps are powered by Paraswap's API for maximum efficiency.

<figure><img src="/files/qcvue1DjvR7CQfH1u12A" alt=""><figcaption><p>Swap Page</p></figcaption></figure>

## V2 Market

Choosing Market (V2), the trade only uses V2 liquidity for your swap - these swaps are conducted using the Quickswap V2 router.

<figure><img src="/files/QHV1WM3hGbSngbc80lvE" alt=""><figcaption><p>Market (V2) Swap</p></figcaption></figure>

## V3 Market

Choosing Market (V3), the trade only uses V3 liquidity for your swap - these swaps are conducted using the QuickSwap V3 router.

<figure><img src="/files/RpKKiJhlf5mQr0K9LX8s" alt=""><figcaption><p>Market (V3) Swap</p></figcaption></figure>

## Limit Orders

Limit orders are provided by a third party integration with Orbs Network, allowing you to set your desired price target to purchase or sell your digital assets on QuickSwap.&#x20;

## Cross-Chain Swaps

Users can swap tokens across different blockchain ecosystems in just a few clicks thanks to QuickSwap's cross-chain swap feature. It's available through a widget & router developed by Squid & powered by Axelar.

## dTWAP

dTWAP orders are also available on QuickSwap, giving expert dragons more advanced DeFi trading features, powered by Orbs Network. With dTWAP orders, traders can set their own parameters, including position size, trade duration, intervals, and much more. Once a trade order is placed, all trades are executed at different intervals to provide the best market price for the user.

{% content-ref url="/pages/O5xCeJhMQmbYECDhp0Lk" %}
[How To Swap](/how-to-guides/how-to-swap)
{% endcontent-ref %}


# Pools

Liquidity providing to pools on QuickSwap allows users to earn a 0.25% fee on trades proportional to their share of the pool. LPs are critical to the QuickSwap ecosystem, allowing participants within the ecosystem more seamlessly swap across ERC-20 tokens.

## V2

When providing liquidity on V2, users simply deposit 2 tokens (each of an equal dollar value) to the respective pool. From there, no further action is needed - rewards are earned in the form of fees. This is the most standard form of liquidity providing & decentralised liquidity pools, similar to how other DEXs work at the basic level.&#x20;

## V3

V3 operates differently than V2 in that when users deposit their tokens into a pool, they need to select between 2 ranges (narrow or wide) for their liquidity. Once the tokens have been deposited & the LP position has been created, the LP needs to be manually adjusted if it falls out of the designated price range.&#x20;

Although this process is more manual, it provides greater depth & capital efficiency when compared to V2.&#x20;

## V3 Active Liquidity Management

QuickSwap has integrated with Gamma to offer V3 active liquidity management to all LPs on V3. Instead of needing to manually adjust your LP position when prices fall out of range, Gamma's technology automatically rebalances your liquidity in range to ensure you're earning the highest amount of rewards while also removing the manual process that comes with V3.&#x20;

Gamma also auto-compounds your rewards as time goes on, leaving your liquidity management on autopilot.


# Farms

## Farming on QuickSwap

QuickSwap's V3 & V2 farms allow you to deposit your LP tokens to earn additional farming rewards for select token pairs. Farms are a great way to make more out of your LP position and can be accessed here: <https://dapp.quickswap.exchange/farm?chainId=8453>&#x20;

## Gamma Farms

Gamma farms allow users to earn farming rewards on top of the trading fees they receive for LPing, which have a specific tab on the QuickSwap website. Only select token pairs with LPs using Gamma from V3 can participate in these farms.

Please note that Gamma has only been enabled for V3 pools & farms on Polygon PoS (mainnet) & zkEVM.

## Unipilot Farms

Unipilot has enabled its own active liquidity management feature for QuickSwap's Dogechain farms, allowing the dragon & shibe communities to earn rewards while having their portfolios actively managed. This is the newest farming feature available on QuickSwap and is only currently available on Unipilot's UI.


# Bonds

QuickSwap Bonds are a tool designed to deepen liquidity on the DEX, introduce creative and effective incentives for LPs, and provide members of the QuickSwap community with a new way to earn in return for their liquidity or tokens. This technology is available on Polygon PoS and powered by ApeBond.

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

**See here to purchase your first Bond:** <https://dapp.quickswap.exchange/bonds?chainId=137>&#x20;

So how exactly do Bonds work? They're a win-win for both users and projects:

* Project can grow protocol-owned liquidity (POL) by selling tokens at a discount to users through vesting NFTs, helping increase their sustainability&#x20;
* Users provide LP tokens or specific assets to purchase the Bond and receive the NFT (which is a representation of their position as they hold the discounted tokens), giving them a new way to acquire these assets

By purchasing Bonds, users have the potential to get a positive ROI (Return on Investment), as they receive their chosen project's tokens at a discount.

> There are two types: Liquidity and Reserve Bonds. Liquidity Bonds can be purchased by creating an LP or using the Zap function (buying with a single token, indicated by the lightning bolt symbol). Reserve Bonds can be purchased through a single token.

It's important to note that the token discounts for particular Bonds (and their respective value) may vary over designated periods - users can claim their tokens as they vest until the end of the term. All discounts depend on supply and demand, so in the end, users may receive a positive or negative ROI depending on market conditions.

Best of all, it helps bring communities together! Projects get to attract new users by offering Bonds while users get to explore new and exciting project tokens at a discount on QuickSwap!


# Perps

Enter the world of decentralised leverage trading on Polygon and Base. QuickSwap is bringing the industry alive with advanced perps DEXs.

## **QuickPerps: Base and Polygon**

[Quickperps](https://www.qperps.exchange/trade) is a cutting-edge perpetual DEX powered by [Orbs](https://www.orbs.com/) and hosted by QUICKSWAP that gives users access to (up to) 150x leverage trading over a range of more than 300 crypto assets.

QuickPerps offers an exchange-grade trading interface that rivals the look, feel, and responsiveness of platforms like Binance and Hyperliquid. Not a generic widget bolted onto a page; a professional trading terminal that runs on TradingView charts. Trusted by millions of traders as the top charting platform, TradingView can help you dive into crypto heatmap analysis, follow the crypto universe, and break down market movements with interactive visual tools and additional indicators.

It includes the full suite of order types serious traders expect: market and limit orders, stop-loss and take-profit, advanced brackets, matching the tools available on leading centralized exchanges.

Combined with one-click trading, account abstraction, and gasless flows, traders get the polish of a CEX with the self-custody and transparency of on-chain.

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

#### TEE-Verified Execution <a href="#under-the-hood-tee-verified-execution" id="under-the-hood-tee-verified-execution"></a>

At the core of Orb's architecture is a Trusted Execution Environment (TEE) designed to serve as the authoritative engine for all state transitions. Every trade, every position update, every liquidation runs inside this environment, with remote attestation ensuring the execution logic has not been tampered with. The TEE-based execution layer will be progressively integrated into Orbs' Layer-3 infrastructure as part of the broader 2.0 rollout.\
\
The architecture breaks down into several core components:<br>

* **Hedger:** Trusted, whitelisted hedgers with high-SLA guarantees take the operational counterparty role, hedging across both centralized exchanges, including Binance USD-M futures, and leading on-chain perpetual markets. This multi-venue approach delivers deep execution from day one without relying on external solver networks.

* **Liquidator:** Real-time solvency monitoring with automatic position liquidation when maintenance margin thresholds are breached. Cross-margin risk calculations use the same shared formulas across the entire stack, so there is no discrepancy between what a trader sees and what the system enforces.

* **Price Oracle:** A signed mark-price feed inside the TEE drives risk calculations, funding rates, and liquidation decisions. Prices are cryptographically signed with EIP-712 and verified on every operation, creating a verifiable audit trail for every price input that affects the system.<br>

* **On-Chain Rollup Settlement:** All state, including user positions, balances, pending orders, and system configuration, lives in a unified Merkle tree. State roots are committed on-chain via a rollup contract, so every transition from order placement to settlement is verifiable. The result is the transparency of on-chain with the performance of off-chain execution.


# Quickperps Trading Guide

How to Trade on Quickperps

#### Step 1: Connect Your Wallet and Create an Account

1. Go to the [Quickperps](https://www.qperps.exchange/trade/BTCUSDT) page and click the top-right corner to connect your wallet.<br>

   <figure><img src="/files/dZTVGAUlfXVCX095A5nA" alt=""><figcaption></figcaption></figure>
2. Accept T\&C and Enable Trading <br>

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

### Step 2: Make a Deposit

1. Click “Deposit” located at the bottom of the page.\ <br>

   <figure><img src="/files/THP3NtsCXBJNcr0JGusr" alt=""><figcaption></figcaption></figure>
2. Enter the amount of USDC you want to deposit and click “Approve Collateral.”\ <br>

   <figure><img src="/files/1fylaBBP5pPbG10HV89D" alt=""><figcaption></figcaption></figure>
3. Approve the transaction through your wallet\ <br>

   <figure><img src="/files/1CbU2lP2y0Vd3rDSay5r" alt=""><figcaption></figcaption></figure>
4. Confirm again via your wallet to complete the process.
5. You can now see your USDC balance displayed in the top-right corner of the page.\ <br>

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

### Step 3: Set Up Your Position

1. Select a trading pair you want to trade (e.g, BTC/USDT) from the dropdown menu.\ <br>

   <figure><img src="/files/R2B2Ng2GGfi10RpHJxtz" alt=""><figcaption></figcaption></figure>
2. Set up your position using the following parameters:\ <br>

   <figure><img src="/files/0jvRPgiDLWwQFUQyiAJR" alt=""><figcaption></figcaption></figure>

* Order Type: Choose Limit or Market.
* Direction: Choose Long (expect price to rise) or Short (expect price to fall).
* Price and Amount: Enter the desired values.
* Leverage: Adjust the leverage (up to 150x) based on your risk tolerance. QuickPerps supports high leverage for advanced traders looking to maximize potential gains, but remember that this also increases risk.
* TP/SL (Take Profit / Stop Loss): Set your target profit and stop loss to manage risk.

3. Once all details are correct, click the confirmation button below the settings section.\ <br>

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

4. Double-check your position details, then click the button to open your trade.\ <br>

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

5. Your active position will now appear in the lower section of the page.\ <br>

   <figure><img src="/files/6X7dX9XonqNp3rhNQZdN" alt=""><figcaption></figcaption></figure>

### Step 4: Close Your Position

1. In the position bar, choose how to "Close” (Limit or Market), or Reverse (it closes and opens same size in the opposite direction).

   <figure><img src="/files/VfHbwoC3a4lrLEx74R2w" alt=""><figcaption></figcaption></figure>
2. After reviewing the details, choose “Close Position” or “Instant Close”.\ <br>

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

A “Close Successful” notification will appear, confirming the closure.

### Disclaimer

Please note that Quickswap does not provide any financial advice. Trading futures is risky and may lead to significant gains or losses. Make sure to conduct your own research and fully understand the risks before setting up any positions.


# Charts by Trading View

QuickPerps, the decentralized perpetual derivatives platform, proudly utilizes TradingView as our chart provider. Below is a comprehensive guide on navigating TradingView charts to enhance your trading experience\ <br>

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

In this guide, we will provide a basic introduction to using TradingView charts. You will learn how to view different time frames, select various chart types, compare different tickers, use indicators, reset charts, utilize drawing tools, as well as take a snapshot of your graph.

### Time Frames

Firstly, in the top left section, you'll find the time frame selection. The time frame determines the length of time each bar or candlestick represents on the chart. For example, a 1-hour time frame means each bar represents one hour of trading activity. We'll use the [BTC/USD chart](https://www.tradingview.com/symbols/BTCUSD/) as an example.

<figure><img src="/files/94kfDDLvyT9jhLmVLmeZ" alt=""><figcaption></figcaption></figure>

Time frames play a crucial role in understanding market movements. Short-term time frames, such as 1-minute or 5-minute charts, are ideal for day traders looking to capitalize on quick, intra-day price fluctuations. Medium-term time frames, like the 1-hour or 4-hour charts, suit swing traders who hold positions for several days to weeks. Long-term time frames, such as daily, weekly, or monthly charts, are best for investors focused on long-term trends and holding positions for months or years. Choosing the right time frame depends on your trading style and strategy. If you are a day trader, short-term charts will be more useful, while long-term investors will benefit from longer time frames. Combining multiple time frames can provide a more comprehensive view of the market, allowing traders to see both the broader trend and finer details for better decision-making.

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

You can "favorite" your favorite time frames by clicking on the star symbol, which pins them for easier selection next time. This feature allows you to quickly access the time frames you use most frequently.

### Chart Types

Beside the time frame section, you can select the chart types. Popular chart types include line charts, bar charts, and candlestick charts.

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

Different chart types are used to provide various perspectives on price movements, helping traders make informed decisions. For example, a line chart, which connects closing prices over a period, is simple and easy to read, making it great for identifying overall trends. However, it lacks detail on price fluctuations within the selected time frame. In contrast, candlestick charts offer more information, showing opening, closing, high, and low prices for each period, but they can be more complex to interpret. Selecting the appropriate chart type is essential for tailoring your analysis to your trading strategy.

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

To change our hollow bar chart to a line chart, we simply select the corresponding chart type in our dropdown menu.

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

### Asset Comparison

Beside the chart type section, there is an option to add multiple charts on a single graph. This allows traders to compare different assets simultaneously, providing insights into their relative strength and correlations.

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

For instance, we could add the [ETH Chart](https://www.tradingview.com/symbols/ETHUSD/) beside the [BTC chart](https://www.tradingview.com/symbols/BTCUSD/).

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

This comparison helps identify which asset is stronger or weaker. Observing relative strength can indicate bullish or bearish trends. From this chart, we could make the inference that Ethereum is showing relative weakness to Bitcoin, while at the same time being correlated to Bitcoin, and could suggest it does not offer much diversification for a risk-sensitive investor. Overall, comparing symbols helps to identify relative strength, correlations, and trends, aiding in decision-making and portfolio management.

### Drawing Tools

TradingView offers the ability to draw freely on your chart or use pre-drawn tools like Fibonacci retracements. These tools, found on the left side of the chart, help traders annotate and analyze price movements by highlighting trends and identifying key support and resistance levels.

On QuickPerps TradingView charts, you can find 11 drawing tools from top to bottom.

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

Some of the more popular ones include:

Trend Line Tool: Trend lines enable you to highlight the direction of movement and significant price levels.

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

The Trend Line tool on TradingView allows you to draw lines to mark the direction of price movements and significant levels. By selecting the tool and clicking to set start and end points, you can easily create trend lines that help identify market direction, support, and resistance levels. This tool is useful for spotting trends, potential breakout points, and reversals, enhancing your technical analysis and trading strategy. Gann and Fibonacci Tools: These tools automatically create levels based on Fibonacci sequences and Gann theory.

<figure><img src="/files/3Ff47EXlofUPyB668Z8A" alt=""><figcaption></figcaption></figure>

The Fibonacci Retracement tool on TradingView allows traders to quickly and easily draw key levels on a chart with just a few clicks and drags. By selecting the tool and then clicking on the start and end points of a significant price move, the tool automatically plots the Fibonacci levels. These levels help traders identify potential areas of support and resistance, making it easier to anticipate possible reversal points in the price action. This automated feature saves time and enhances the precision of technical analysis.

Forecasting and Measurement Tools: These tools help measure chart distances, predict price movements, and assess trading positions.

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

Forecasting tools on TradingView, such as Long Position and Short Position, allow traders to simulate potential trade scenarios. By selecting these tools and setting entry, stop-loss, and target levels, traders can visualize potential profit and loss, helping them evaluate risk and reward before executing trades.

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

You can easily adjust your forecasted risk, entry, profit, and stop levels by clicking on the settings icon that appears when you hover your mouse over the forecasting drawing on your chart. This feature allows for precise customization of your trade parameters.

### Indicators

TradingView on QuickPerps offers a myriad of indicators to enhance your trading analysis. Indicators are tools that help traders interpret price movements and predict future trends. Free users of TradingView can use up to 2 indicators on the chart. Some of the more popular indicators are:

1. Moving Average (MA): This indicator smooths out price data to identify the direction of the trend over a specific period, helping traders to spot trends and reversals.

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

For example, this graph uses 2 Simple Moving Averages, 50 days (blue) and 200 days (Yellow) on the daily chart.

The 50-day SMA represents the short-term trend, while the 200-day SMA reflects the long-term trend.

When the short-term SMA (50-day) crosses above the long-term SMA (200-day), it could suggest a bullish signal, indicating potential upward momentum. Conversely, when the short-term SMA crosses below the long-term SMA, it suggests a bearish signal, indicating potential downward momentum. This crossover strategy helps traders identify trend reversals and make informed trading decisions.

You can change the time period as well as the style of the Moving Averages by hovering near the indicators and clicking the settings icon.

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

2. Relative Strength Index (RSI): RSI measures the speed and change of price movements, indicating overbought or oversold conditions, which can signal potential reversals.

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

The RSI is displayed below the main price chart. The default RSI overbought and oversold levels are typically set at 70 and 30, respectively. However, these levels can be adjusted based on the trader's preference or the specific characteristics of the asset being analyzed. The RSI helps traders identify potential reversal points. For instance, when the RSI crosses above 70, it might signal that the asset is overbought and a bearish reversal could be imminent. Conversely, when the RSI crosses below 30, it might indicate that the asset is oversold and a bullish reversal could be expected. This makes the RSI a valuable tool for timing entry and exit points in trading strategies.

&#x20;3\. Bollinger Bands: This indicator consists of a middle band (a moving average) and two outer bands that represent standard deviations. Bollinger Bands help traders identify volatility and potential price breakouts.

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

### Deleting Indicators and resetting scale and resetting chart:

To delete indicators, simply hover your mouse near the indicators section and click the “trash can” icon that appears.

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

To reset the chart to the default scale, you can click at the settings button at the bottom right and then select “Reset price scale”. Alternatively, you can press ‘Alt + R’ to reset the price scale.

To get a clean new chart, you can simply refresh the whole page.

### Taking a snapshot

To take a picture of your graph, you can click the camera icon in the upper-right corner of the graph, which allows you to either download the image or copy the image to your clipboard.

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

For a more detailed guide on how to use TradingView's charting functions, you can visit [their official website](https://www.tradingview.com/support/).

*Disclaimer: This article is a guide on how to use TradingView and does not constitute financial advice. We do not ensure the accuracy of the content.*


# Quickswap Perps Legal Disclaimer And Terms Of Service

Legal disclaimer for Quickswap Perps

### LEGAL DISCLAIMER

***

These Terms of Service (the "Terms" or the "Agreement") establish a legally binding agreement between you ("User," "Guest," "Customer," "you," or "your") and Quickswap Corp. ("Company," "we," "us," or "our"). By accessing or using <https://www.qperps.exchange> (the "Website" or "Platform") or any products and services offered on or through it (the "Services"), you accept these Terms on behalf of yourself or the entity you represent.

Please read these Terms carefully before using the Website, Platform, or any Services. If you do not agree with any provision, you must not access or use the Website, the Platform, or the Services.

For any questions or comments regarding these Terms, please contact:

<legal@quickswap.exchange>.

### ELIGIBILITY AND RESTRICTED AREAS

To be eligible to use or access the Website, Platform, or any Services, you must be of legal age to enter into a binding contract (at least 18 years old in most jurisdictions or the applicable age of majority in your country of residence). If you are acting on behalf of a legal entity, you represent and warrant that such entity is duly organized and validly existing, and that you are authorized to act on its behalf.

\
The following persons or entities (collectively, "Ineligible Persons") are strictly prohibited from accessing or using the Website, Platform, or Services:

* Any individual or entity that is a citizen, resident, domiciled in, located in, or operating from the United States of America (including any state, territory, or the District of Columbia), the United Kingdom, or any country identified by the Financial Action Task Force (FATF) as having strategic deficiencies in Anti-Money Laundering (AML) or Countering the Financing of Terrorism (CFT) measures (including, but not limited to, Iran, North Korea, Myanmar, Russia, Belarus, Syria, Cuba, Zimbabwe, and other jurisdictions on FATF’s "High-Risk" or "Grey" lists).
* Any individual or entity listed on sanctions administered by the United Nations, European Union, OFAC (U.S. Treasury), UK OFSI, or other relevant regulatory authorities.

  Any Ineligible Person must immediately cease using or accessing the Website, the Platform, or the Services. The Company is not responsible for fraudulent, deceptive, or malicious actions taken by Ineligible Persons to circumvent these restrictions (e.g., through VPNs or false declarations of residency).

### GENERAL

1. **Description of Services:**&#x20;

The Platform provides a decentralized interface for trading cryptocurrency perpetual contracts, enabling users to open and manage leveraged positions based on the price movements of various cryptocurrencies. The Platform provides market data, trading tools, and smart contract interactions that facilitate decentralized perpetual trading.

2. **Account Responsibility:**

You may need to create an account or connect a crypto wallet to use certain features. You are solely responsible for safeguarding your access credentials (including private keys or wallet access). The Company is not liable for any unauthorized access or loss resulting from your failure to maintain account security.

3. **Trading Risks:**

Perpetual contracts are complex financial instruments that carry significant risk. Trading them may result in the loss of all invested capital. You should evaluate your financial situation and consult independent professionals before trading.

4. **Amendments:**

We reserve the right to amend these Terms at any time by posting updates on the Website. Continued use of the Platform constitutes acceptance of any such modifications.

### TERMS OF USE

All capitalized terms herein have the meanings assigned to them in this Agreement. Your use of the Website, Platform, and Services is subject to these Terms, our Privacy Policy, and any other applicable policies posted on the Website.

### ACKNOWLEDGEMENT OF RISK

By accessing or using the Website, Platform, and Services, you expressly acknowledge and accept the risks described in Schedule 1 (Risk Disclosures). You agree that you assume full responsibility for any losses or damages arising from such risks, and that the Company shall not be held liable under any circumstances for trading losses, market volatility, or smart contract vulnerabilities.

### LIMITATION OF LIABILITY

To the fullest extent permitted by law: (i) the Company and its affiliates shall not be liable for any indirect, incidental, consequential, special, punitive, or exemplary damages; (ii) the total aggregate liability of the Company shall not exceed the amount of fees paid by you (if any) during the preceding twelve (12) months; and (iii) the Services are provided “as is” and “as available” without any warranties of any kind, whether express or implied.

### NO FINANCIAL OR INVESTMENT ADVICE

All content provided through QuickSwap.Exchange is for informational purposes only and does not constitute financial, investment, trading, or legal advice. Users should conduct their own due diligence and consult licensed professionals before making financial decisions.

### INDEMNIFICATION

You agree to indemnify, defend, and hold the Company and its affiliates, officers, directors, employees, and agents harmless from and against any and all claims, losses, liabilities, damages, costs, and expenses (including reasonable attorneys’ fees) arising out of or related to (a) your breach of these Terms; (b) your misuse of the Platform or Services; or (c) your violation of applicable laws or third-party rights.

### GOVERNING LAW AND DISPUTE RESOLUTION

These Terms shall be governed by and construed in accordance with the laws of the Republic of Panama. Any dispute arising out of or related to these Terms shall be resolved exclusively in the courts of that jurisdiction. Before initiating any legal action, you agree to first contact <legal@quickswap.exchange> and allow a thirty (30) day period for amicable resolution.

### SCHEDULE 1 — RISK DISCLOSURES

* Market Volatility: Crypto and perpetual contracts are highly volatile and may result in significant or total losses.
* Leverage Risk: Leverage amplifies both profits and losses. Small market movements can cause liquidation.
* Technology Risks: Smart contract exploits, software bugs, and network congestion may cause loss of funds.
* Regulatory Risks: Future regulation or enforcement actions may affect your ability to access or use the Services.
* Counterparty and Liquidity Risks: Lack of liquidity or smart contract malfunction can lead to partial or total loss.
* Internet and Transmission Risks: Connectivity issues or cyberattacks may disrupt your transactions.
* Legal and Tax Risks: You are solely responsible for understanding and complying with all applicable tax and legal obligations.
* AML/CFT Compliance Risks: Trading activities may be monitored and restricted to ensure compliance with AML/CFT standards.
* Unforeseen Risks: Decentralized finance is experimental. There may be additional risks not currently foreseeable.

### CONTACT INFORMATION

For all legal and compliance inquiries, contact: <legal@quickswap.exchange>

<br>

<br>


# Quick Utility Dashboard

The Quick Dashboard serves as the central utility hub for the QUICK token across the QuickSwap ecosystem. From one interface, users can stake QUICK, bridge QUICK between supported networks, convert legacy QUICK into the new QUICK token, and monitor treasury and burn activity.\
\
The dashboard is designed to make core token operations accessible in a single location while providing transparency around token supply, market data, and protocol treasury holdings.\
\
<https://dapp.quickswap.exchange/dashboard?chainId=8453><br>

Had a position in the legacy Dragon's Lair? You can still access it [here](https://dapp.quickswap.exchange/dashboard?tab=staking\&chainId=137).

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


# QUICK Staking

The **QUICK Staking** section enables users to stake their QUICK tokens and earn rewards. It's important to note that projects that contribute rewards to staking pools have end dates to rewards programs, which can be found by clicking on the tab & reviewing the details.

#### How It Works

Users can deposit QUICK into available staking [pools](https://dapp.quickswap.exchange/dashboard?chainId=8453) and receive rewards over time. Depending on the staking campaign, rewards may be distributed in:

* **QUICK tokens**
* **Partner ecosystem tokens**
* **Protocol incentive tokens**
* Other participating reward assets

Rewards are typically allocated based on the amount of QUICK staked and the duration of participation.

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


# Bridge QUICK

The **Bridge QUICK** section allows users to move QUICK tokens between supported blockchain [networks.](https://dapp.quickswap.exchange/dashboard?chainId=137\&tab=bridge_quick)

#### How It Works

Users can select a source network and destination network to transfer their QUICK tokens. The bridge facilitates cross-chain movement while maintaining token accessibility across multiple ecosystems.

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

#### Key Features

* Transfer QUICK between supported chains
* Simple network selection and transfer process
* Track bridge transactions and status

#### Benefits

* Access QuickSwap services on different chains
* Consolidate holdings where needed


# Convert Old QUICK

The **Convert** section allows holders of legacy QUICK tokens to upgrade to the new QUICK [token](https://dapp.quickswap.exchange/dashboard?chainId=137\&tab=convert).

#### How It Works

Users holding Old QUICK can convert their tokens through the conversion interface. Once converted, users gain access to the latest QuickSwap utility features, including staking and future ecosystem incentives.<br>

<figure><img src="/files/2AnOg5uXlnjDizjgQxTR" alt=""><figcaption></figcaption></figure>

#### Key Features

* One-way conversion from Old QUICK to New QUICK
* Simple conversion process


# Treasury

The [Treasury tab](https://dapp.quickswap.exchange/dashboard?chainId=137\&tab=treasury) provides transparency into QuickSwap Treasury Holdings and Burn Activity.

This section is designed to improve transparency by showing how protocol-owned assets are managed and how token burn events affect the QUICK supply over time.\ <br>

<figure><img src="/files/9tVCKb7YXe53lXF0E41e" alt=""><figcaption></figcaption></figure>

**Burn Activity**

Monitor token burn events that permanently remove QUICK from circulation.<br>

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


# Governance

QuickSwap is a fully decentralised project & ecosystem that is driven by a DAO-based model. That means QUICK token holders have the ability to vote on governance proposals put forth by the QuickSwap team, giving them decision-making power over the future of the protocol.

Take a look at QuickSwap's Snapshot page to see previous proposals, votes, & results: <https://snapshot.org/#/quickvote.eth>

Each proposal begins with a formal governance discussion, which takes place on both the QuickSwap Discord & Reddit channels. From there, once the community has had time to share their thoughts among themselves & the QuickSwap team, the discussion moves into a formal governance vote where QUICK holders can vote.

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


# Roadmap

QuickSwap's updated 2023 - 2025 roadmap outlines some of the flaming hot updates and developments the dragons have planned for the next few years. Milestones include new product integrations, enhanced DEX and perpetual swap features, additional chain deployments, and much more!

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


# Social Media

At QuickSwap, we love to share everything & anything about our project with frens! To get the latest updates to stay up to speed with the dragon army, make sure to follow us on our social media channels:

* [Twitter (X)](https://twitter.com/QuickswapDEX) :bird:
* [Telegram Chat](https://t.me/QuickSwapDEX) :speech\_balloon:
* [Telegram Announcements](https://t.me/QuickSwapAnnouncements) :speaking\_head:
* [Discord](https://discord.gg/dSMd7AFH36) :keyboard:
* [Reddit](https://www.reddit.com/r/QuickSwap/) :space\_invader:
* [Blog](https://blog.quickswap.exchange/) :eyes:
* [TikTok ](https://www.tiktok.com/@quickswapofficial):video\_camera:
* [YouTube ](https://www.youtube.com/channel/UCrPlF-DBwD-UzLFDzJ4Z5Fw):arrow\_forward:


# Contracts & Addresses

Below is a comprehensive summary of all QuickSwap contracts & addresses

### Polygon

<table data-header-hidden><thead><tr><th width="264"></th><th></th></tr></thead><tbody><tr><td>TokenSwap (swap QUICK OLD for NEW</td><td>0x333068D06563a8DfDBF330A0e04A9d128e98bf5a</td></tr><tr><td>Dragons Lair (dQUICK)</td><td>0x958d208Cdf087843e9AD98d23823d32E17d723A1</td></tr></tbody></table>

### **Polygon POS V2**

<table data-header-hidden><thead><tr><th width="264"></th><th></th></tr></thead><tbody><tr><td>V2 router address</td><td>0xa5E0829CaCEd8fFDD4De3c43696c57F7D7A678ff</td></tr><tr><td>V2 Factory address</td><td>0x5757371414417b8C6CAad45bAeF941aBc7d3Ab32</td></tr></tbody></table>

### **Polygon POS V3 Algebra**

<table data-header-hidden><thead><tr><th width="264"></th><th></th></tr></thead><tbody><tr><td>Core factory address</td><td>0x411b0fAcC3489691f28ad58c47006AF5E3Ab3A28</td></tr><tr><td>Pool deployer</td><td>0x2D98E2FA9da15aa6dC9581AB097Ced7af697CB92</td></tr><tr><td>Quoter address</td><td>0xa15F0D7377B2A0C0c10db057f641beD21028FC89</td></tr><tr><td>Swap router</td><td>0xf5b509bB0909a69B1c207E495f687a596C168E12</td></tr><tr><td>Non fungible position manager</td><td>0x8eF88E4c7CfbbaC1C163f7eddd4B578792201de6</td></tr><tr><td>Multicall address</td><td>0x6ccb9426CeceE2903FbD97fd833fD1D31c100292</td></tr><tr><td>Migrator Address</td><td>0x157B9913E00204f8c980bb00aa62E22b0dAb1a63</td></tr><tr><td>Real staker address</td><td>0x32CFF674763b06B983C0D55Ef2e41B84D16855bb</td></tr><tr><td>Finite farming</td><td>0x9923f42a02A82dA63EE0DbbC5f8E311e3DD8A1f8</td></tr><tr><td>Infinite farming</td><td>0x8a26436e41d0b5fc4C6Ed36C1976fafBe173444E</td></tr><tr><td>farming center</td><td>0x7F281A8cdF66eF5e9db8434Ec6D97acc1bc01E78</td></tr><tr><td>V2 factory address</td><td>0x5757371414417b8C6CAad45bAeF941aBc7d3Ab32</td></tr></tbody></table>

### **Polygon POS V4 Algebra**

<table data-header-hidden><thead><tr><th width="289"></th><th></th></tr></thead><tbody><tr><td>AlgebraFactory</td><td>0x134c1dBE4860A9cAaf89002574fFe814772D9904</td></tr><tr><td>AlgebraPoolDeployer</td><td>0x96B31b1d17dee49e70B950dE33FFF83728f5c181</td></tr><tr><td>AlgebraCommunityVault</td><td>0x60f418049322Ef88CEFB44Ff344468153552a223</td></tr><tr><td>AlgebraVaultFactoryStub</td><td>0x35622b9802b71f341762cF6f46a7e301931fc7c5</td></tr><tr><td>PluginFactory</td><td>0xfe2041D7779a28Fc6bF39223A952baD0BEFFD525</td></tr><tr><td>EntryPoint</td><td>0xfcfE065bc131Fa8Bb31A227b2fF4F0EC47D3F1a2</td></tr><tr><td>TickLens</td><td>0x28aDcf283d392e3902F49A7E9A78E40D64348290</td></tr><tr><td>Quoter</td><td>0x4666599D48E8C72B91a73f9aDE04eda17C5FDBa7</td></tr><tr><td>QuoterV2</td><td>0xa062c2754864F67a259b346D0D7567b2ed406e6E</td></tr><tr><td>SwapRouter</td><td>0x96FeF39089380F4319e8eF01aA8338615C36f1BB</td></tr><tr><td>NonfungibleTokenPositionDescriptor</td><td>0xC13b7CeAFc4D5ff531353c731Ef8Ec3D3D65f741</td></tr><tr><td>Proxy</td><td>0x3ff1b17b115b303c5547Fc1465C16cf08E8DAa22</td></tr><tr><td>NonfungiblePositionManager</td><td>0x7219C5d9928DB34973b5397d0b6ef00622dD3E8f</td></tr><tr><td>AlgebraInterfaceMulticall</td><td>0x42375083Fe3a4f77ce95aF733C266d6bD5BD122A</td></tr><tr><td>AlgebraEternalFarming</td><td>0x182B9d43269c4502e0fCcef198404df1bfBD54e8</td></tr><tr><td>FarmingCenter</td><td>0x24A089AD55D688c18dbA7E7514F5D2083B926e21</td></tr></tbody></table>

### BASE V2

<table data-header-hidden><thead><tr><th width="264"></th><th></th></tr></thead><tbody><tr><td>V2 router address</td><td>0x4a012af2b05616Fb390ED32452641C3F04633bb5</td></tr><tr><td>V2 Factory address</td><td>0xEC6540261aaaE13F236A032d454dc9287E52e56A</td></tr></tbody></table>

### BASE V4 Algebra

<table data-header-hidden><thead><tr><th width="289"></th><th></th></tr></thead><tbody><tr><td>AlgebraFactory</td><td>0xC5396866754799B9720125B104AE01d935Ab9C7b</td></tr><tr><td>AlgebraPoolDeployer</td><td>0xE08026Fd8537d67C501199610c42D08bB34eAa75</td></tr><tr><td>AlgebraCommunityVault</td><td>0x0cA6d588D9E3a14f62eF88afcd6B3d0AD13af1f0</td></tr><tr><td>AlgebraVaultFactoryStub</td><td>0xdD3ef767f7c071937D8fAFa1BF2B27F5c190B139</td></tr><tr><td>PluginFactory</td><td>0xD3712643eC7138DD09aE6322e7626ad99542Cc04</td></tr><tr><td>EntryPoint</td><td>0xb9ce7698cE3dCf21cc88bf7dCc1fE20C85E4226E</td></tr><tr><td>TickLens</td><td>0xC73e303fb323DDFB446E2Cc8c0f1B8199e7930f4</td></tr><tr><td>Quoter</td><td>0xA8a1dA1279ea63535c7B3BE8D20241483BC61009</td></tr><tr><td>QuoterV2</td><td>0x23E0583a3a000d567bB3848115065c1890D87fb5</td></tr><tr><td>SwapRouter</td><td>0xe6c9bb24ddB4aE5c6632dbE0DE14e3E474c6Cb04</td></tr><tr><td>NonfungibleTokenPositionDescriptor</td><td>0x095EB76d5934958b21EEc5142025bEb6A7763c16</td></tr><tr><td>Proxy</td><td>0xb30067E958F6c9DD9b362A082279c331dD6c98D1</td></tr><tr><td>NonfungiblePositionManager</td><td>0x84715977598247125C3D6E2e85370d1F6fDA1eaF</td></tr><tr><td>AlgebraInterfaceMulticall</td><td>0xD55AbC52a0d9901AD07FEbe2903d05601E2a34dD</td></tr><tr><td>AlgebraEternalFarming</td><td>0x0987A3dC376a33ED720e15D2eC62eA6179D51141</td></tr><tr><td>FarmingCenter</td><td>0x431fB6b15be099Bb3cDEb0986E23e68eae150303</td></tr></tbody></table>

### **Dogechain V2**

<table data-header-hidden><thead><tr><th width="272"></th><th></th></tr></thead><tbody><tr><td>V2 factory address</td><td>0xC3550497E591Ac6ed7a7E03ffC711CfB7412E57F</td></tr><tr><td>Swap router</td><td>0xAF96E63f965374dB6514e8CF595fB0a3f4d7763c</td></tr></tbody></table>

### **Dogechain V3 Algebra**

<table data-header-hidden><thead><tr><th width="269"></th><th></th></tr></thead><tbody><tr><td>Core factory address</td><td>0xd2480162Aa7F02Ead7BF4C127465446150D58452</td></tr><tr><td>Pool deployer</td><td>0x56c2162254b0E4417288786eE402c2B41d4e181e</td></tr><tr><td>Quoter address</td><td>0xd8E1E7009802c914b0d39B31Fc1759A865b727B1</td></tr><tr><td>Swap router</td><td>0x4aE2bD0666c76C7f39311b9B3e39b53C8D7C43Ea</td></tr><tr><td>Non fungible position manager</td><td></td></tr><tr><td>Multicall address</td><td>0x0110B3b142031F85a80Afdc9C7bcAA80dAfe7C63</td></tr><tr><td>Migrator Address</td><td>0xB9aFAa5c407DdebA5098193F31CE23D21cFD9657</td></tr><tr><td>Finite farming</td><td>0x481FcFa00Ee6b2384FF0B3c3b5b29aD911c1AAA7</td></tr><tr><td>Infinite farming</td><td>0xC712F63E4D57ED1684FB4b428a1DFF10e3338F25</td></tr><tr><td>farming center</td><td>0x82831E9565cb574375596eFc090da465283E22A4</td></tr><tr><td>V2 factory address</td><td>0xC3550497E591Ac6ed7a7E03ffC711CfB7412E57F</td></tr></tbody></table>

### **zkEVM V3 Algebra**

<table data-header-hidden><thead><tr><th width="267"></th><th></th></tr></thead><tbody><tr><td>Core factory address</td><td>0x4B9f4d2435Ef65559567e5DbFC1BbB37abC43B57</td></tr><tr><td>Pool deployer</td><td>0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270</td></tr><tr><td>Quoter address</td><td>0x55BeE1bD3Eb9986f6d2d963278de09eE92a3eF1D</td></tr><tr><td>Swap router</td><td>0xF6Ad3CcF71Abb3E12beCf6b3D2a74C963859ADCd</td></tr><tr><td>Non fungible position manager</td><td>0xd8E1E7009802c914b0d39B31Fc1759A865b727B1</td></tr><tr><td>Multicall address</td><td>0x61530d6E1c7A47BBB3e48e8b8EdF7569DcFeE121</td></tr><tr><td>Migrator Address</td><td>0x4aE2bD0666c76C7f39311b9B3e39b53C8D7C43Ea</td></tr><tr><td>Finite farming</td><td>0x17bE2Ed4409d8e6c22d46dE599f7C9Af40bD0759</td></tr><tr><td>Infinite farming</td><td>0x1fd3f47B363f5b844eD7B7FAB6ceb679A367621E</td></tr><tr><td>farming center</td><td>0x481FcFa00Ee6b2384FF0B3c3b5b29aD911c1AAA7</td></tr></tbody></table>

### **zkEVM V3 Uni**

<table data-header-hidden><thead><tr><th width="270"></th><th></th></tr></thead><tbody><tr><td>Core factory address</td><td>0xD9a2AD9E927Bd7014116CC5c7328f028D4318178</td></tr><tr><td>Quoter address</td><td>0xB18FB423Fb241CE0DE345d74904f97D60792FFd8</td></tr><tr><td>Swap router</td><td>0x1E7E4c855520b2106320952A570a3e5E3E618101</td></tr><tr><td>Non fungible position manager</td><td>0x331F3a300b7115A45ba31E3428AC002267BB6D77</td></tr><tr><td>Multicall address</td><td>0x61530d6E1c7A47BBB3e48e8b8EdF7569DcFeE121</td></tr></tbody></table>

### **Manta** Pacific **V3 Uni**

<table data-header-hidden><thead><tr><th width="271">Manta Uni V3</th><th></th></tr></thead><tbody><tr><td>Core factory address</td><td>0x56c2162254b0E4417288786eE402c2B41d4e181e</td></tr><tr><td>Quoter address</td><td>0x3005827fB92A0cb7D0f65738D6D645d98A4Ad96b</td></tr><tr><td>Swap router</td><td>0xfdE3eaC61C5Ad5Ed617eB1451cc7C3a0AC197564</td></tr><tr><td>Non fungible position manager</td><td>0xa5E0829CaCEd8fFDD4De3c43696c57F7D7A678ff</td></tr><tr><td>Multicall address</td><td>0x1FD671daC06DF1431E79d772037E93bdB2dfeb48</td></tr></tbody></table>

### Astar zkEVM V3 Uni

<table data-header-hidden><thead><tr><th width="271"></th><th></th></tr></thead><tbody><tr><td>Core factory address</td><td>0x56c2162254b0E4417288786eE402c2B41d4e181e</td></tr><tr><td>Quoter address</td><td>0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270</td></tr><tr><td>Swap router</td><td>0x4B9f4d2435Ef65559567e5DbFC1BbB37abC43B57</td></tr><tr><td>Non fungible position manager</td><td>0xF6Ad3CcF71Abb3E12beCf6b3D2a74C963859ADCd</td></tr><tr><td>Multicall address</td><td>0xc7efb32470dEE601959B15f1f923e017C6A918cA</td></tr></tbody></table>

### Immutable zkEVM V3 Uni

<table data-header-hidden><thead><tr><th width="271"></th><th></th></tr></thead><tbody><tr><td>Core factory address</td><td>0x56c2162254b0E4417288786eE402c2B41d4e181e</td></tr><tr><td>Quoter address</td><td>0xE9CC37904875B459Fa5D0FE37680d36F1ED55e38</td></tr><tr><td>Swap router</td><td>0x6c28AeF8977c9B773996d0e8376d2EE379446F2f</td></tr><tr><td>Non fungible position manager</td><td>0xa5E0829CaCEd8fFDD4De3c43696c57F7D7A678ff</td></tr><tr><td>Multicall address</td><td>0xc7efb32470dEE601959B15f1f923e017C6A918cA</td></tr></tbody></table>

### X Layer V3 Algebra

<table data-header-hidden><thead><tr><th width="271"></th><th></th></tr></thead><tbody><tr><td>Core factory address</td><td>0xd2480162Aa7F02Ead7BF4C127465446150D58452</td></tr><tr><td>Pool deployer</td><td>0x56c2162254b0E4417288786eE402c2B41d4e181e</td></tr><tr><td>Quoter address</td><td>0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270</td></tr><tr><td>Swap router</td><td>0x4B9f4d2435Ef65559567e5DbFC1BbB37abC43B57</td></tr><tr><td>Non fungible position manager</td><td>0xF6Ad3CcF71Abb3E12beCf6b3D2a74C963859ADCd</td></tr><tr><td>Multicall address</td><td>0xc7efb32470dEE601959B15f1f923e017C6A918cA</td></tr></tbody></table>

### Soneium Mainnet V4 Algebra

<table data-header-hidden><thead><tr><th width="289"></th><th></th></tr></thead><tbody><tr><td>AlgebraFactory</td><td>0x8Ff309F68F6Caf77a78E9C20d2Af7Ed4bE2D7093</td></tr><tr><td>AlgebraPoolDeployer</td><td>0x7B446Bfb3763Ed0892f08893Eb06Dda79aB28CB9</td></tr><tr><td>AlgebraCommunityVault</td><td>0x756c880Bb7A36628F11c234465994EF97d5CE064</td></tr><tr><td>AlgebraVaultFactoryStub</td><td>0x5A7ea62A5EB316DD3Aa00FAD3873f97b692109fF</td></tr><tr><td>PluginFactory</td><td>0x980dc694Fb758C5Db4a8A035212072bC962adFD9</td></tr><tr><td>EntryPoint</td><td>0xbDcFc56aEA5AEc541F5eB34FbeC07838175C1138</td></tr><tr><td>TickLens</td><td>0x9AfA76331a01b1b25289306fbD72A4e032FDFe06</td></tr><tr><td>Quoter</td><td>0x4c5663252bBAB0a3B303a711823aD70a0ec9aE31</td></tr><tr><td>QuoterV2</td><td>0x22e5195BcC9b0C87f330FbCE2755B263662578E2</td></tr><tr><td>SwapRouter</td><td>0xeba58c20629ddab41e21a3E4E2422E583ebD9719</td></tr><tr><td>NonfungibleTokenPositionDescriptor</td><td>0x9F90F50186414DAB83b222A4ae01D75041Ab15bd</td></tr><tr><td>Proxy</td><td>0xBF450784Fc69FBD4E75B0795FD0a65E38316BE64</td></tr><tr><td>NonfungiblePositionManager</td><td>0x0629B3c6E1cCfF2e31e3A9Bd67ec96b23BE6f1e9</td></tr><tr><td>AlgebraInterfaceMulticall</td><td>0x2E4C17aEE528084e6dB16882d24fc1Dd0Ef20D97</td></tr><tr><td>AlgebraEternalFarming</td><td>0x69504bA6AB62B9Ed441469920acEC07D1df765C5</td></tr><tr><td>FarmingCenter</td><td>0x94e1B396F844d890F8c84c3f581462399a74550A</td></tr></tbody></table>

### Somnia Mainnet V4 Algebra

<table data-header-hidden><thead><tr><th width="289"></th><th></th></tr></thead><tbody><tr><td>AlgebraFactory</td><td>0x0ccff3D02A3a200263eC4e0Fdb5E60a56721B8Ae</td></tr><tr><td>AlgebraPoolDeployer</td><td>0x0361B4883FfD676BB0a4642B3139D38A33e452f5</td></tr><tr><td>AlgebraCommunityVault</td><td>0xBC8e2d40B90F27Fd9d54005bb38A2770fe9180eF</td></tr><tr><td>AlgebraVaultFactoryStub</td><td>0xE7Fe2F9B4fbfebB1A5f1f44857425A3f2598599C</td></tr><tr><td>PluginFactory</td><td>0x57Fd247Ce7922067710452923806F52F4b1c2D34</td></tr><tr><td>EntryPoint</td><td>0x69cfa238cDD06F4519d70e78272D880646c51F95</td></tr><tr><td>TickLens</td><td>0xc868a65f702E1d55CDD2F426DCF97D29A2dA90B9</td></tr><tr><td>Quoter</td><td>0xd86C6620300f59f3C6566b3Fb9269674fd5c5264</td></tr><tr><td>QuoterV2</td><td>0xcB68373404a835268D3ED76255C8148578A82b77</td></tr><tr><td>SwapRouter</td><td>0x1582f6f3D26658F7208A799Be46e34b1f366CE44</td></tr><tr><td>NonfungibleTokenPositionDescriptor</td><td>0xfa49223107Ad26c7a91957f2c5b239bC5d02C153</td></tr><tr><td>Proxy</td><td>0xD4ba86fbf231ecBc99d99Cd74C998C5f73d4D641</td></tr><tr><td>NonfungiblePositionManager</td><td>0xfE02219e0578B1E4831CDE7C3CB36f71AEb4A833</td></tr><tr><td>AlgebraInterfaceMulticall</td><td>0x5793c5bA2E1821a817336DAd9bf8bfC9406d3045</td></tr><tr><td>AlgebraEternalFarming</td><td>0xFd4D18867d21cD0b0db5918cEf1a3fea55D7D317</td></tr><tr><td>FarmingCenter</td><td>0xEf181Ea0d1223CFEe104439213AF3F1Be6788850</td></tr></tbody></table>

### Mantra Mainnet V4 Algebra

<table data-header-hidden><thead><tr><th width="289"></th><th></th></tr></thead><tbody><tr><td>AlgebraFactory</td><td>0x10253594A832f967994b44f33411940533302ACb</td></tr><tr><td>AlgebraPoolDeployer</td><td>0xd7cB0E0692f2D55A17bA81c1fE5501D66774fC4A</td></tr><tr><td>AlgebraCommunityVault</td><td>0x4439199c3743161ca22bB8F8B6deC5bF6fF65b04</td></tr><tr><td>AlgebraVaultFactoryStub</td><td>0x955B95b8532fe75DDCf2161f61127Be74A768158</td></tr><tr><td>PluginFactory</td><td>0xFe3BEcd788320465ab649015F34F7771220A88b2</td></tr><tr><td>EntryPoint</td><td>0x4A3BC48C156384f9564Fd65A53a2f3D534D8f2b7</td></tr><tr><td>TickLens</td><td>0x13fcE0acbe6Fb11641ab753212550574CaD31415</td></tr><tr><td>Quoter</td><td>0x03f8B4b140249Dc7B2503C928E7258CCe1d91F1A</td></tr><tr><td>QuoterV2</td><td>0xa77aD9f635a3FB3bCCC5E6d1A87cB269746Aba17</td></tr><tr><td>SwapRouter</td><td>0x3012E9049d05B4B5369D690114D5A5861EbB85cb</td></tr><tr><td>NonfungibleTokenPositionDescriptor</td><td>0xD637cbc214Bc3dD354aBb309f4fE717ffdD0B28C</td></tr><tr><td>Proxy</td><td>0x6AD6A4f233F1E33613e996CCc17409B93fF8bf5f</td></tr><tr><td>NonfungiblePositionManager</td><td>0x69D57B9D705eaD73a5d2f2476C30c55bD755cc2F</td></tr><tr><td>AlgebraInterfaceMulticall</td><td>0xB4F9b6b019E75CBe51af4425b2Fc12797e2Ee2a1</td></tr><tr><td>AlgebraEternalFarming</td><td>0x50FCbF85d23aF7C91f94842FeCd83d16665d27bA</td></tr><tr><td>FarmingCenter</td><td>0x658E287E9C820484f5808f687dC4863B552de37D</td></tr></tbody></table>


# QUICK

QuickSwap's native token is QUICK, helping power the DragonFi ecosystem. It's use cases are governance (for decentralised community voting) & staking in the Dragon's Lair, which are only available to New QUICK token holders - the existing Old QUICK token does not have any utility but can seamlessly be converted to New QUICK via [QuickSwap's converter](https://quickswap.exchange/#/convert).&#x20;

### QUICK Tokenomics

* **Total Supply:** 1B
* **Current Circulating Supply:**  706,098,650  (70.6%)

QUICK is a fair launch, community-governed project. There was no seed round, no private round, no pre-sale, and no public sale (ICO/IDO/IEO) - 96.75% of the total supply was reserved for the QuickSwap community.

### **Rewards**

90% of QUICK tokens either already have been or will be distributed through a liquidity mining rewards program.

To motivate new projects and communities to come out to Layer 2 and try Polygon, QuickSwap provides incentivised trading pools. Those who provide liquidity for an incentivised trading pool are rewarded with QUICK tokens in addition to a percentage of the fees generated from swaps.

QUICK mining rewards will run for another 3.5 years (4 years total). Gradually, the token emissions will slow down with less being distributed as years pass. This encourages early adoption while also incentivising the community’s continued growth over time.

QuickSwap's treasury holds the majority of the funds that will pay out liquidity mining rewards for the next 3.5 years. This wallet is equipped with multisig, and it requires 3 out of 4 signatures from Nick Mudge, Sameep Singhania, Roc Zacharias (LDA), and Sandeep Nailwal (Matic) - this is to increase security and to eliminate the chance of a future rug pull.


# DD

After QuickSwap launched its Dogechain extension in 2022, a governance proposal was put in place to create a new DogeDragon (DD) token that would be available on the platform to be used as liquidity mining rewards and for other unique/fun activities for QuickSwap on Dogechain.

This was a completely new token (not bridged) and is only available on Dogechain. DD has a **maximum supply of 1 billion tokens** and was brought to life with the intention of being an experimental memecoin, along with having similar tokenomics to QUICK.

**Here's a quick breakdown of DD's tokenomics (across the 1 billion supply):**

* 50% (500 million) to be distributed to Dragon’s Lair stakers over 4 years
* 40% (400 million) to be distributed for pairs on QuickSwap’s Dogechain extension (to be distributed for up to 4 years)
* 3% (30 million) reserved for the QuickSwap Foundation for the team’s development, growth, and expansion
* 3% (30 million) reserved for LDA for use in marketing, PR, and business development
* 2% (20 million) to Sameep Singhania — QuickSwap Co-Founder and Lead Developer
* 2% (20 million) to Roc Zacharias — QuickSwap Co-Founder, CEO of Lunar Digital Assets, and Dogechain Contributor

Trading fees on QuickSwap's Dogechain extension would be distributed as follows:

* 90% to liquidity providers
* 3.4% to Dragon’s Lair stakers
* 3.4% to DogeDragon’s Lair stakers
* 1.7% to the QuickSwap Foundation
* 1.5% to Algebra’s developers (which they say they will distribute to ALGB stakers)

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


# Supported Chains

QuickSwap currently supports 11 different blockchains for all your favorite DeFi features:

### Polygon PoS (mainnet) <img src="/files/Y2zNquwvapzOtS2W8Ouf" alt="" data-size="line">

{% embed url="<https://polygon.technology/polygon-pos>" %}

QuickSwap initially launched on the Polygon blockchain & has made its mark as the network's leading DEX & AMM. Currently, users can swap their favorite ERC-20 tokens, provide liquidity, farm,  and stake with low gas fees & fast transaction speeds.

<figure><img src="/files/2TGEzQUGilmHW7FHO5oW" alt=""><figcaption></figcaption></figure>

### Polygon zkEVM <img src="/files/OZwJgozUG9KYBEi6CUAJ" alt="" data-size="line">

{% embed url="<https://polygon.technology/polygon-zkevm>" %}

In March 2023, Polygon deployed their new zkEVM Mainnet Beta infrastructure to the world. QuickSwap became the first DEX to launch on this new chain & bring Polygon zkEVM DeFi to the broader community by offering token swaps, LPing, and farming.&#x20;

QuickPerps, a decentralised Perpetual Exchange, is also built on QuickSwap's Polygon zkEVM extension, allowing users to trade perpetual swap contracts with up to 50x leverage.

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

### Dogechain <img src="/files/SFTutMAl5V2AJBHNOCWt" alt="" data-size="line">

{% embed url="<https://dogechain.dog/>" %}

Live since Q3/Q4 2022, QuickSwap supports DogeFi on the Dogechain blockchain, allowing users to swap, LP, farm, and stake on the popular memecoin chain. Both projects are working together to explore future collaborations & DeFi features to enhance utility on the chain.

<figure><img src="/files/3uzh58LrrAXi4JDzPIN5" alt=""><figcaption></figcaption></figure>

### Manta Pacific L2 Rollup <img src="/files/QcIpJwaRCkowu09MGn4o" alt="" data-size="line">&#x20;

{% embed url="<https://pacific.manta.network/>" %}

QuickSwap launched on Manta during November 2023. In addition to making its mark as QuickSwap’s fourth Polygon deployment following PoS, Dogechain, and zkEVM, the launch on Manta Pacific is a significant milestone in the growth of both QuickSwap and Manta Network, bringing the power of dragons and mantas together!

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

### Immutable zkEVM <img src="/files/SIMqjqfbmcMwVmVUmqW4" alt="" data-size="line">

{% embed url="<https://www.immutable.com/products/immutable-zkevm>" %}

QuickSwap has recently launched on Immutable zkEVM mainnet - the Layer 2  EVM ZK-rollup Web3 gaming chain of the future, powered by Polygon. Built for gamers and developers, now available to dragons for DeFi.

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

### Soneium <img src="/files/mAm2VsOMyKCoy8NL8jhd" alt="" data-size="line">

{% embed url="<https://soneium.org/en/>" %}

Soneium is now live on the DEX! A huge milestone and step forward for the dragon community. QuickSwap is aiming to help drive adoption for Soneium chain via its current DEX infrastructure.

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

### X Layer <img src="/files/bvLO5WioNMNFsd5bgepz" alt="" data-size="line">

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

The birth of a new Citadel on the dragon DEX, expanding the Polygon CDK family.

Swap and LP to earn trading fees on X Layer via QuickSwap now. Get ready to experience DeFi on the network at its very best.

X Layer is a ZK-powered Layer 2 network designed to connect the OKX and Ethereum communities, built using the Polygon CDK tech stack.

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

### Base <img src="/files/X71elKxP27iwYVoGh8jB" alt="" data-size="line">

{% embed url="<https://www.base.org/>" %}

QuickSwap has recently launched on Base mainnet. Base, Coinbase’s flagship EVM Layer 2, went on an absolute tear only a few months after its launch in August 2023 and has been continuing to astronomically grow ever since in TVL, volume, users, and builders. Swap and LP to earn trading fees on Base via QuickSwap now

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

### Somnia ![](/files/8LT0v0RjJfwGrVlyh49r)

{% embed url="<https://browser.somnia.network/>" %}

QuickSwap has recently launched on Somnia mainnet. A powerful EVM Layer 1 chain offering sub-second finality and sub-cent fees, setting a new standard for optimum performance in Web3. Swap and LP to earn trading fees on Somnia via QuickSwap now

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

### Mantra <img src="/files/H25fLv30C3m9pcbf0S5m" alt="" data-size="line">

{% embed url="<https://mantrachain.io/>" %}

QuickSwap has recently launched on Mantra mainnet. MANTRA Chain allows RWAs to be owned on-chain and traded as digital assets, opening the door to greater access for market participants. RWAs are a hot narrative right now, and DeFi for RWAs is still in its infancy. MANTRA holds a Virtual Asset Service Provider (VASP) license from Dubai’s Virtual Assets Regulatory Authority (VARA) to operate as a Virtual Asset Exchange and provide broker-dealer, management, and investment services. Swap and LP to earn trading fees on Mantra via QuickSwap now

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


# Supported Wallets

QuickSwap supports many popular Web3 wallets to bring in the broader DeFi community & make the DragonFi ecosystem as accessible as possible. Just go to <https://quickswap.exchange/#/> & connect your wallet in the upper right-hand corner to get started!!

Here's a current list of the wallets we support & have integrated (more are on the way!):

* [**MetaMask**](https://metamask.io/) :fox:
* [**Trust Wallet**](https://trustwallet.com/) :dividers:
* [**Phantom Wallet**](https://phantom.app/) :ghost:
* [**Brave Wallet**](https://brave.com/wallet/) :lion\_face:
* [**Gnosis Safe App**](https://app.safe.global/) :lock\_with\_ink\_pen:
* [**Coinbase Wallet**](https://www.coinbase.com/wallet) :blue\_heart:
* [**WalletConnect**](https://walletconnect.com/) :link:
* [**ZenGo**](https://zengo.com/) :zap:
* [**Venly**](https://www.venly.io/) :white\_check\_mark:
* [**BitKeep Wallet**](https://bitkeep.com/en/index) :fire:


# How To Swap

{% hint style="info" %}
This swapping guide applies to: Best Trade, Market (V2), Market (V3)&#x20;
{% endhint %}

After choosing a swap type, select your assets to swap and type in the amount. In this example, we will swap DAI for QUICK.

After choosing your assets, you will have to **allow QuickSwap to access your assets** by confirming the transaction from your wallet. Click on “**Approve**” and them click on “**Swap**”.

<figure><img src="/files/821XC6NB3btmgIPZQBD1" alt=""><figcaption></figcaption></figure>

The wallet confirmation should look something like this:

<figure><img src="https://miro.medium.com/v2/resize:fit:656/0*tG-hVC1E3jSkF155" alt="" width="188"><figcaption><p>Metamask Transaction Confirm</p></figcaption></figure>

Go back to QuickSwap and click on “**Swap”** to complete the exchange.

A popup window will appear to ask you to confirm the swap.

<figure><img src="https://miro.medium.com/v2/resize:fit:700/0*i3xBdGZiu5TUEDRG" alt=""><figcaption><p>Quickswap Confirm Transaction</p></figcaption></figure>

After you click on “**Confirm Swap”** you will be prompted to confirm your transaction from your wallet. Once more, you will have to confirm the transaction from your wallet. You will shortly get a confirmation from QuickSwap saying that your transaction was completed.

<figure><img src="https://miro.medium.com/v2/resize:fit:700/0*mFm500dJPNJTBJlR" alt=""><figcaption><p>Quickswap Transaction Complete</p></figcaption></figure>


# dLIMIT Guide

## Introduction To Limit Orders

A limit order is a tool from CeFi in which users can buy or sell assets at a specified price or better, instead of relying on the market price at the time of execution. In a limit order, while the price is guaranteed, the order being executed is not - limit orders will be executed only if the price meets the order qualifications.

Quickswap has integrated the dLIMIT protocol, powered by Orbs, that brings this order type to DeFi in a decentralised manner. Users can use this tool to create decentralised limit orders by following the directions below.&#x20;

The dLIMIT protocol for DEXs ensures that limit orders are executed at an optimal price and at fair fees, in a decentralised and reliable manner.

## How To Set Up A Limit Order

1. Go to the exchange [page](https://quickswap.exchange/#/swap?currency0=ETH\&currency1=0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174\&swapIndex=0\&isProMode=false) and select the limit order option.

<figure><img src="https://lh3.googleusercontent.com/bDoL4OLqX__ik2B-xrJdV5tI5PiII4o_JktcMyBU_8UpZ0j2diyCXl-nlDksUsxTVL6Cl5jFd_Kg5PQuIn-19HWF9b9CMWUa9luxORWQvn6aZSaxJbOho1PZ_DUnOsyAnLLy3kYN-0EOAIZc4H4BUn8" alt=""><figcaption></figcaption></figure>

2. Select the “From” and “To” tokens you wish to trade. In this example we chose USDC and ETH respectively, meaning we want to buy ETH with USDC.

<figure><img src="https://lh6.googleusercontent.com/ZZnCd9OlyNGpHk5XAsuTvjlNNVCQ0fWbhzpvJL99gENZvaGJIA_qgS2dO-DEf6ZQDBCUMQ85_-XGl1wtHWF7DlO8rjk8TqlN6EhSTMS2K53G4GvoXzCIVL9-KhiAjx0XIGRsqd-ABTpVwxxun5O0BGo" alt=""><figcaption></figcaption></figure>

3. Enter the amount you wish to trade. Notice the limit price will show the current market price which will then estimate the output amount of destination tokens (ETH)

<figure><img src="https://lh3.googleusercontent.com/nOyfjkAOTMca_NkIMFJw61ediM87QZn1XqgPp98WBm4AJxwMa386sofI9Ox6JZ_SudkVYz9mCwNDPNF_58iLTxFV_te8vqviKF0Tna-EOyrJUfgrgfPQs5zqCVdZOTZcuHtB-pW29L0axBP1Gxs4ZXg" alt=""><figcaption></figcaption></figure>

4. Set the desired limit price. Trades will ONLY be executed when the available market price is better than or equal to the limit price. The destination token output amount will update accordingly. Press “Approve”.

{% hint style="info" %}
In the example below, we wish to buy ETH when the price is $1,900 or better. The amount of ETH received will be equal or greater than 0.2368 ETH. Only bids equal or better than this amount will be eligible to fill the order. This amount takes into account gas costs and fees.

**Important note:** As the fees are paid from the output token amount, the limit price includes the gas & trading fees and so users should take this into account when setting up the price. For example, a very small order’s gas fees can total a very large percentage of the order output, reflecting an actual limit price that is not competitive with the spot market price.
{% endhint %}

<figure><img src="https://lh3.googleusercontent.com/qvkM8vLNN_Za_9kIO6tOY_KCn2Yipv4uOeHlSnp2rBmuMcX6f28rojgDLHy_jWHdveQRtMvVjtHmX4ldi4QsfBWmTQFw_gaJxRPCkhZ5SM89tniqL-L7URYekBsKJ43uTNDWSqGgRogzoJ-vrak9xpY" alt=""><figcaption></figcaption></figure>

5. Press “Place order”. Double check your order details, accept the disclaimer and press “Confirm order”.

<figure><img src="https://lh6.googleusercontent.com/4doj0gqW7CfWA1fG_PltL82Of457hoKkXWXd0jVNf36kKxaYzWaNSl8Qf2-DM4zUE82-YFDH_ZaIzJ28Vn-YGGQ8ZiASaV2xLfupozvqU1wS9FcaHtnsrG7K_q5vNPKf5DgdAduZ2m7F-VeZ96m_Tcc" alt=""><figcaption></figcaption></figure>

6. Once the transaction is through, you will be able to see your order in the order history section, under “Open orders”. Users can set up real-time notifications to get an alert when their limit order gets filled using the[ Open DeFi Notification Protocol](https://www.orbs.com/notifications/).

<figure><img src="https://lh4.googleusercontent.com/pW4x5JrH7wdxJhxjHZSpAMZqBRA96FgcYcNYor-z2pI1Kp_tU48WVaN-njmUA1no8DpqQ5WnTw_SjoqirCMzUjMhBFKUO-nPdFGebrQd9NDJ0YYflvkMG9jlXwaKkrvXmrceCd07R2KmNg8G9l6moGE" alt=""><figcaption></figcaption></figure>

7. Open orders can be canceled at any time by expanding the order and clicking the “Cancel Order” button.

<figure><img src="https://lh3.googleusercontent.com/XXmawMJXN9KcQb3BSUNGHVh6lsiG6kSmsG1LRs63L2khxrnDklUcV8dJypBD2ITszLGn6-2D4tLui9nXG9dOPrcnXP4GKb4P622RqKoWHOChL8XXPm1aetTND2Q3Rqium4L6JidP-iQhmaQCWj7S1Oc" alt=""><figcaption></figcaption></figure>

## Things To Take Into Consideration

* Your order may not be executed if the available market price is worse than the limit price you have set.
* The trades are based on a decentralised protocol that utilises off-chain takers which compete to fill orders. These takers are entitled to request a fee, which the protocol removes for the winning taker from the output tokens.&#x20;
* Takers may take into account gas fees for your transactions when setting their fees, which may result in fluctuations in the fee amounts.
* When specifying a limit price, users will see in the UI the minimum amount of destination tokens they will receive if the order is filled. Only takers making bids equal or better than this amount will be eligible to fill the order. This amount takes into account gas costs and trading fees.

## How Does The dLIMIT Protocol Work?

The dLIMIT protocol defines two main actors:&#x20;

### Makers

The first entity in the dLIMIT protocol are DEX traders that submit new orders to the dLIMIT EVM contract. They set all order parameters including the limit price. The dLIMIT contract enforces these requirements in a trustless manner.

### Takers

Incentivised third-party participants that monitor all live orders and submit bids on the best path to execute their next segment. The dLIMIT contract selects the best bid and guarantees that the path that provides the best price to makers is the one executed.

The protocol has been designed such that the presence of one honest taker (i.e, a taker who charges only reimbursement for gas fees) should result in an output amount that is as close as possible to spot market prices.

## Powered By Orbs

The dLIMIT protocol is developed by [Orbs](https://www.orbs.com/) and powered by Orbs’ [L3 technology](https://www.orbs.com/overview/).

Orbs Network has many independent validators running Proof-of-Stake consensus with over $100 million staked. The network has been running in mainnet since 2019. All Orbs Network validators are takers and participate as honest bidders in the protocol, guaranteeing that orders are executed 24/7 with high redundancy and best price.

## Troubleshooting & FAQ

Still unsure of something? Having trouble with your order? Be sure to check the [FAQ](https://www.orbs.com/dtwap-and-dlimit-faq/) section, or join the telegram [support group](https://t.me/dTWAPSupportGroup).

## Additional Resources

You can find more information about dLIMIT in the following links:

* [FAQ](https://www.orbs.com/dtwap-and-dlimit-faq/)
* dLIMIT telegram [support group](https://t.me/dTWAPSupportGroup)
* [dLIMIT webpage](https://www.orbs.com/dlimit/)
* [Whitepaper](https://www.orbs.com/white-papers/dTWAP/)
* [Github](https://github.com/orbs-network/twap)
* PeckShield [security audit](https://github.com/orbs-network/twap/blob/master/Audit-Report-PeckShield.pdf)


# dTWAP Guide

## Introduction To dTWAP

TWAP (Time-weighted Average Price) is a common order type used in CeFi that breaks an order into smaller trade sizes and executes them at regular intervals. The main goal of a TWAP order is to reduce the order’s price impact. It can also be useful if a user wants to implement a dollar-cost averaging strategy (DCA) and buy a certain token on a consistent schedule (i.e. once a month).

Therefore, TWAP is best used when the order size is large compared to the available liquidity, or when a user anticipates a high price volatility period with no clear up or downward trend.

Quickswap has integrated the dTWAP protocol, powered by Orbs, that brings this order type to DeFi in a decentralised manner. Users can use this tool to create dTWAP orders by following the directions below.&#x20;

## How To Set Up A dTWAP Order

1. Go to the exchange [page](https://quickswap.exchange/#/swap?currency0=ETH\&currency1=0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174\&swapIndex=0\&isProMode=false) and select the TWAP order option.

<figure><img src="https://lh4.googleusercontent.com/iSkb1VE70_A7WY6xjmRpGZASr1Ea41E-6tP_WqNhzDvsJSxZcoN2iEnL7NCp302ToHqIcBkwL92jkYU9oP-bCtCpvQenAMejrA3ahsYwLY9szNMEvsR1R8Ble-MsG9QiC7AIibXPkjdJgHLaRvMXdjQ" alt=""><figcaption></figcaption></figure>

2. Select the “From” and “To” tokens and enter the amount you wish to trade.

{% hint style="info" %}
In this example we chose 400 USDC as the “From” tokens and ETH for the “To” tokens, meaning we want to buy ETH with 400 USDC.
{% endhint %}

<figure><img src="https://lh6.googleusercontent.com/cFjNbiZWjyU0hr_sNiKVjkWOKKp9PlLgJCs4FB1RqbLsn6NhFGVRCA3o1fxRX_2XQeI97u3MxOzwMQ08UrGZKsqe2m5NdNatE4sRTcmEe68ZmyvRSKAKJikK9q9sxS2gOzzF-HiHx6sPkwS31ag6kRg" alt=""><figcaption></figcaption></figure>

3. The UI enables both dTWAP-market orders, which execute all trades at the available market price, and dTWAP-limit orders, which only execute individual trades if they are within the price limit set by the user.&#x20;

{% hint style="info" %}
In this example we chose to execute the TWAP orders at market price.
{% endhint %}

<figure><img src="https://lh3.googleusercontent.com/CPwwIpzMgETKlREUDjTOgYB-TZbWrngZWDnL36M534fbbgCWr-MQXM25aXAgxlIobJ5QZeYcx0AOZmMknRZuEEF54Wv47C81jAy_p85kRKlO7kauLjBuLYawx0DtsoQ-RkuCcZMhSHy-Aj4tkwpcjk0" alt=""><figcaption></figcaption></figure>

4. Next, we specify the TWAP parameters. There are 3 main parameters that control the effectiveness of the dTWAP order:

### Total trades

Allows the user to specify the number of individual trades that their order will be broken into. The UI slider starts with 1 trade and allows the user to increase the amount of individual trades, or allows the user to manually input the total trades in the input field directly.\
\
Users should note that there is a certain tradeoff when specifying this parameter: more trades means smaller individual trade size, which means smaller price impact. However, more trades also means more transactions and higher overall gas fees.

In the example, we set the total trades to 4, meaning we broke down the total trade size of 400 USDC into 4 smaller trades of 100 USDC each.&#x20;

### Trade Interval

Sets the time gap between each individual trade. The UI starts with the minimum allowed (2 mins), which leaves the minimum amount of time for the taker bidding war and block settlement between each chunk. The user can set it to be any duration desired. A trade will never execute before this time elapses after the previous trade.

Again users should be mindful when setting this parameter: longer intervals would allow arbitrageurs a longer window to close any price discrepancies on the affected pools and bring the reserves back to equilibrium (on par with spot price). However, it would take longer for the order to be filled would add uncertainty to the final fill price, especially in times of heightened volatility

In the example, we set the trade interval to 2 minutes, meaning there will be 2 minutes of delay between each individual trade.

### Max Duration

The maximum time during which the total amount of all individual trades making up the full dTWAP order may be executed. After this deadline the trade expires, regardless of actual amounts swapped.&#x20;

Note that all chunks may not execute in limit orders, depending on whether the price stays within the set parameters.&#x20;

The default recommended duration is calculated by multiplying the number of intervals by the trade interval, and then doubling this amount in order to serve as a buffer to allow sufficient time for on-chain activity. (note that setting a duration that is shorter than the above default may result in a partially filled order).

In the example, we set the Max. duration to 16 mins.

We left the max. duration at the default 16 mins which means that the TWAP order will be cancelled after 16 mins.

{% hint style="info" %}
As can be seen, these parameters provide significant flexibility in customising each order, taking into account factors like market conditions, current gas fees, etc.
{% endhint %}

<figure><img src="https://lh6.googleusercontent.com/XBqkHnLeNsnGE1OXv_k0AE5U5Vjsv1dM18wQsw5xK44vVRlrUHxEBJJfQy8APgr8_7dd2DX6_BpOwCHTwIkT3jHXRwRT7Lo1I0IiN7BvRLyJapTBGChUUO0W123LSfWPYNDDzYTuESneebpeGSV8OIs" alt=""><figcaption></figcaption></figure>

5. Press “Place order”. Double check your order details, accept the disclaimer and press “Confirm order”.

<figure><img src="https://lh5.googleusercontent.com/kCnS0AnGKdb3hySec22yw7aukrbrgjfjHCYP0P_-odGgWmQ2SdiStrMBOXPYm25yOb79LYgh6NUJ2gKem_Ea0fCnYnsOgxQ4piUgvfSwLqhvbJPtwcUY6pHduw9jPWQ02eeunA_3H87vSenDcVPjSgI" alt=""><figcaption></figcaption></figure>

6. Once the transaction is processed, you will be able to see your order’s status in the order history section, under “Open orders”. Users can set up real-time notifications to get an alert when their TWAP order gets filled using the[ Open DeFi Notification Protocol](https://www.orbs.com/notifications/).

{% hint style="info" %}
Open orders can be cancelled at any time by expanding the order and clicking the “Cancel Order” button.
{% endhint %}

<figure><img src="https://lh5.googleusercontent.com/EFCaNbBPls4OWSNKqzObDL5skUKj8Fjk6mGOimyBZfzTISrTiQZAaoZlYGOAtdQt51kxYgVctoGMNkTODKWykziPRlIx1VEeXgq4xcgP0g1l-HFHai8jobz9s8LW1MJ4Dd502dIYZ4xkHRtjun_Vzn8" alt=""><figcaption></figcaption></figure>

## Things To Take Into Consideration

* Orders are executed in smaller trades over a specified period of time and are subject to market conditions and other risks.
* Your trade may be executed at a price that is significantly different from the current market price (although not worse than your limit price, if you set one), which could result in significant losses. If the available market price is worse than the limit price you have set, some of the trades of your order may not be executed, resulting in a partially filled order.
* The trades are based on a decentralised protocol that utilises off-chain takers which compete to fill orders. These takers are entitled to request a fee, which the protocol removes for the winning taker from the output tokens.&#x20;
* Takers may take into account gas fees for your transactions when setting their fees, which may result in fluctuations in the fee amounts.

## How Does The dTWAP Protocol Work?

The dTWAP protocol defines two main actors:&#x20;

### Makers

The first entity in the dTWAP protocol are DEX traders that submit new orders to the dTWAP EVM contract. They set all order parameters such as limit price and expiration. Maker orders are sent to the dTWAP smart contract, which enforces these requirements in a trustless manner.

### Takers

Incentivised third-party participants that monitor all live orders and submit bids on the best path to execute their next segment. The dTWAP contract selects the best bid and guarantees that the path that provides the best price to makers is the one executed.&#x20;

The protocol has been designed such that the presence of one honest taker (i.e, a taker who charges only reimbursement for gas fees) should result in an output amount that is as close as possible to spot market prices.

## Powered By Orbs

The dTWAP protocol is developed by [Orbs](https://www.orbs.com/) and powered by Orbs’ [L3 technology](https://www.orbs.com/overview/).

Orbs Network has many independent validators running Proof-of-Stake consensus with over $100 million staked. The network has been running in mainnet since 2019. All Orbs Network validators are takers and participate as honest bidders in the protocol, guaranteeing that orders are executed 24/7 with high redundancy and best price.

## Troubleshooting & FAQ

Still unsure of something? Having trouble with your order? Be sure to check the [FAQ](https://www.orbs.com/dtwap-and-dlimit-faq/) section.

## Additional Resources

You can find more information about dTWAP in the following links:

* [FAQ](https://www.orbs.com/dtwap-and-dlimit-faq/)&#x20;
* dTWAP telegram [support group](https://t.me/dTWAPSupportGroup)
* [dTWAP webpage](https://www.orbs.com/dtwap/)
* [Whitepaper](https://www.orbs.com/white-papers/dTWAP/)
* [Github](https://github.com/orbs-network/twap)
* PeckShield [security audit](https://github.com/orbs-network/twap/blob/master/Audit-Report-PeckShield.pdf)


# LP (Liquidity Providing)

Learn to provide liquidity on QuickSwap like a pro! Users can LP on any supported chain on the QuickSwap DEX - note that ALM (Automated Liquidity Management) strategies and integrations are currently offered only on Polygon PoS, Polygon zkEVM, and Dogechain.

Here's a quick walkthrough of how to LP on QuickSwap through multiple different ways.

**Gamma V3 Pools**

1\. Visit <https://dapp.quickswap.exchange/pool?chainId=8453> and connect your Web3 wallet. You'll be automatically connected to QuickSwap's V3, where you can switch to the Polygon PoS or zkEVM networks in order to use Gamma.

![image12](https://blog.quickswap.exchange/images/quickswap/Articles/image12.png)

2\. Under **Supply Liquidity,** select your token pair to continue (in this example, we’ll be using MATIC/USDC).

![image6](https://blog.quickswap.exchange/images/quickswap/Articles/image6.png)

3\. Now it's time to select a strategy using the “autoMatic” feature (narrow or wide through QuickSwap's [Gamma V3 active liquidity management solution](https://quickswap-layer2.medium.com/quickswap-integrates-with-gamma-to-enable-active-v3-liquidity-management-f1d784ea8d2b)) - you can also manually input your designated price ranges.

![image4](https://blog.quickswap.exchange/images/quickswap/Articles/image13.png)

4\. Next, enter your deposit amounts for your selected token pair (if you’re depositing MATIC as in this example, you’ll need to take an extra step and wrap it to WMATIC). Once complete, click **Preview** to continue.

![image4](https://blog.quickswap.exchange/images/quickswap/Articles/image4.png)

5\. A popup will appear. Review the details and when everything looks good, click **Confirm.** Complete the transaction in your Web3 wallet to finish providing liquidity.

![image5](https://blog.quickswap.exchange/images/quickswap/Articles/image5.png)

You're done! To represent your position, you now have LP tokens that allow you to earn trading fees as rewards.

Check the right side of the page to view your LP positions.

![image3](https://blog.quickswap.exchange/images/quickswap/Articles/image3.png)

**LP on V3: New Token Pairs**

When depositing supported token pairs in QuickSwap V3 pools, users can earn a weighted average of 0.01% to 1.5% of trading fees pending volatility, liquidity concentration, total liquidity, and other key metrics.

For token pairs that haven't already been created, users can create new liquidity on V3:

1\. Visit <https://dapp.quickswap.exchange/pool?chainId=8453> and connect your Web3 wallet. Switch to any network on QuickSwap supporting V3

2\. Select the token pair you want to provide liquidity to. For this example, we will use FTM/DERC. In some cases, you will need to set the initial price by manually calculating one token’s value relative to the other if the system can’t auto-fetch.&#x20;

Once you’re done, click **Confirm**.

![image11](https://blog.quickswap.exchange/images/quickswap/Articles/image11.png)

3\. Next, select your price range. You can choose between **Full Range, Safe, Common,** and **Expert.** You can manually adjust these ranges further if you’d like. Please note that if you’re the only LP and your prices go out of range, users will only be able to trade the token pair one way.&#x20;

![image11](https://blog.quickswap.exchange/images/quickswap/Articles/image11.png)

4\. Enter the proportional deposit amounts for which you want to provide liquidity. Next, approve both tokens (if not already enabled), click **Preview,** and confirm the transaction in your wallet to complete the process.

![image9](https://blog.quickswap.exchange/images/quickswap/Articles/image9.png)


# How to LP on QuickSwap on Base V4

In this tutorial, users will learn how to provide liquidity on QuickSwap on Base V4, using Planet IX’s AIX in the AIX-ETH pool as an example (which also has a corresponding farm for this LP pair)<br>

1. **Connect to Base:** Go to the [Pool](https://dapp.quickswap.exchange/pool) page, click “Select Network,” and choose Base from the dropdown menu. Next, make sure you’re on the V4 tab (it should be the default).<br>
2. **Connect Wallet:** Click “Connect Wallet” and select your Web3 wallet provider. Then make sure you have ETH in your wallet to pay gas fees on the Base Network.

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

3. **Swap into AIX:** To LP, you’ll need to have both tokens in your wallet. Assuming you already have ETH, select “AIX” from the dropdown menu under “Receive”, and click “Swap”.\
   To complete this step, you will need to confirm the transaction on the swap interface and subsequently in your Web3 wallet.<br>

<p align="center"><img src="/files/UfGakPZDUZIjtvM7WrOz" alt=""><img src="/files/LZcubva1xxwb6YiZQRMR" alt=""><br></p>

4. **Enter Pools:** Now that you have AIX and ETH in your wallet, you’re ready to move forward. To begin the LP process, click on the “Pool” tab in the horizontal menu bar at the top of the page.<br>
5. **Set Liquidity Parameters:** For (1), select AIX and ETH. For (2), you can either create your own manual LP strategy or use the automatic strategy provided by one of the third-party ALMs.\
   In this example, Steer Protocol’s Wide strategy is selected for (3) and (4) respectively.\
   \
   Lastly, for (5), input the amounts you would like to LP in the corresponding boxes.<br>
6. **Provide Liquidity:** When you are ready to open your LP position on QuickSwap on Base, click the blue “Create position” button.<br>

   To complete this step, you will need to confirm the transaction on the LP interface and subsequently in your Web3 wallet.<br>

<figure><img src="/files/yNv4okDGsb4XATUjRJzz" alt=""><figcaption><p>Note: to arrive at the “Create position” button, you may have to complete transactions to approve AIX and ETH in your wallet, as well as to Wrap ETH, in order to be able to proceed to providing liquidity.<br></p></figcaption></figure>

7. **Monitor Your Position:** To monitor the performance of your position, click on “Your positions” toward the upper right side of the screen. A new page will open where you can gauge the performance of your LP position in real time.\
   \
   Note that if you deposited LP into a corresponding farm on the ‘Farms’ page, your liquidity position will automatically begin earning farm rewards.<br>

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

\
Congratulations! You’ve now officially opened an LP position on QuickSwap on Base V4.<br>


# Farm

Once you've provided liquidity on QuickSwap, users have the opportunity to earn additional rewards through QuickSwap V3 farms. In order to earn rewards, simply stake your LP tokens in the corresponding Gamma V3 farm with the matching token pair.

\*Note that Gamma V3 farms are only available on Polygon PoS and Polygon zkEVM. Unipilot has also integrated its V3 auto liquidity management solution on Dogechain, so make sure to switch to the correct network depending on which product you want to use.

Here's how you can get started:

1\. Go to <https://dapp.quickswap.exchange/farm?chainId=8453>. Next, either stay on the **Gamma Farms** page (default) or click on **QuickSwap Farms** (regular V3 farms).&#x20;

For this example, we’ll use Gamma Farms, but the farming process is identical for both.

![image14](https://blog.quickswap.exchange/images/quickswap/Articles/image14.png)

2\. Find the farm that matches your LP token pair and click the drop-down menu. On the left, enter the number of LP tokens you want to stake, click **Approve.**

Complete the transaction in your wallet, and click **Stake LP Tokens** to finish the process.

![image8](https://blog.quickswap.exchange/images/quickswap/Articles/image10.png)

3\. Your LP tokens have now been staked and you’ll immediately begin earning farming rewards in dQUICK and WMATIC (or whichever reward token the farm provides).

![image8](https://blog.quickswap.exchange/images/quickswap/Articles/image8.png)

<br>


# Stake

Staking on QuickSwap allows users to stake their QUICK tokens to earn rewards, one of the several utilities of the native token.

To begin staking, simply go to the Dragon's Lair tab on the QuickSwap website and click **Stake** on the left-hand side of the page. From there, select the amount of QUICK you want to stake and approve the transaction.

\*Note that QUICK staking is only available on Polygon PoS, and the APY may vary.

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


# API


# API Overview

This section explains the Uniswap Subgraph and how to interact with it. The Uniswap subgraph indexes data from the Uniswap contracts over time. It organizes data about pairs, tokens, Uniswap as a whole, and more. The subgraph updates any time a transaction is made on Uniswap. The subgraph runs on [The Graph](https://thegraph.com/) protocol's hosted service and can be openly queried.

### Resources[#](broken://pages/TKtf6qoyPR0SWADoG9xz)

[Subgraph Explorer](https://thegraph.com/explorer/subgraph/uniswap/uniswap-v2) - sandbox for querying data and endpoints for developers.

[Uniswap V2 Subgraph](https://github.com/Uniswap/uniswap-v2-subgraph) - source code for deployed subgraph.

### Usage[#](broken://pages/TKtf6qoyPR0SWADoG9xz)

The subgraph provides a snapshot of the current state of Uniswap and also tracks historical data. It is currently used to power [uniswap.info](https://uniswap.info/). **It is not intended to be used as a data source for structuring transactions (contracts should be referenced directly for the most reliable live data).**

### Making Queries[#](broken://pages/TKtf6qoyPR0SWADoG9xz)

To learn more about querying a subgraph refer to [The Graph's documentation](https://thegraph.com/docs/introduction).

### Versions[#](broken://pages/TKtf6qoyPR0SWADoG9xz)

The [Uniswap V2 Subgraph](https://thegraph.com/explorer/subgraph/uniswap/uniswap-v2) only tracks data on Uniswap V2. For Uniswap V1 information see the [V1 Subgraph](https://thegraph.com/explorer/subgraph/graphprotocol/uniswap).


# Entities

Entities define the schema of the subgraph, and represent the data that can be queried. Within each entity are sets of fields that store useful information related to the entity. Below is a list of the available entities within the Uniswap Subgraph, and descriptions for the available fields.

To see an interactive sandbox of all entities see the [Graph Explorer](https://thegraph.com/explorer/subgraph/uniswap/uniswap-v2).

Each entity is defined with a value type, which will always be a base AssemblyScript type, or a custom type provided by The Graph's custom TypeScript library. For more information on value types see [here](https://thegraph.com/docs/assemblyscript-api#api-reference).

#### Uniswap Factory[#](broken://pages/6y9aAXBriajopM7uD6xn)

The Uniswap Factory entity is responsible for storing aggregate information across all Uniswap pairs. It can be used to view stats about total liquidity, volume, amount of pairs and more. There is only one UniswapFactory entity in the subgraph.

| Field Name        | Value Type | Description                                                     |
| ----------------- | ---------- | --------------------------------------------------------------- |
| id                | ID         | factory address                                                 |
| pairCount         | Int        | amount of pairs created by the Uniswap factory                  |
| totalVolumeUSD    | BigDecimal | all time USD volume across all pairs (USD is derived)           |
| totalVolumeETH    | BigDecimal | all time volume in ETH across all pairs (ETH is derived)        |
| totalLiquidityUSD | BigDecimal | total liquidity across all pairs stored as a derived USD amount |
| totalLiquidityETH | BigDecimal | total liquidity across all pairs stored as a derived ETH amount |
| txCount           | BigInt     | all time amount of transactions across all pairs                |

#### Token[#](broken://pages/6y9aAXBriajopM7uD6xn)

Stores aggregated information for a specific token across all pairs that token is included in.

| Field Name         | Value Type | Description                                                                                                  |
| ------------------ | ---------- | ------------------------------------------------------------------------------------------------------------ |
| id                 | ID         | token address                                                                                                |
| symbol             | String     | token symbol                                                                                                 |
| name               | String     | token name                                                                                                   |
| decimals           | BigInt     | token decimals                                                                                               |
| tradeVolume        | BigDecimal | amount of token traded all time across all pairs                                                             |
| tradeVolumeUSD     | BigDecimal | amount of token in USD traded all time across pairs (only for tokens with liquidity above minimum threshold) |
| untrackedVolumeUSD | BigDecimal | amount of token in USD traded all time across pairs (no minimum liquidity threshold)                         |
| txCount            | BigInt     | amount of transactions all time in pairs including token                                                     |
| totalLiquidity     | BigDecimal | total amount of token provided as liquidity across all pairs                                                 |
| derivedETH         | BigDecimal | ETH per token                                                                                                |

#### Pair[#](broken://pages/6y9aAXBriajopM7uD6xn)

Information about a pair. Includes references to each token within the pair, volume information, liquidity information, and more. The pair entity mirrors the pair smart contract, and also contains aggregated information about use.

| Field Name           | Value Type           | Description                                                                                                         |
| -------------------- | -------------------- | ------------------------------------------------------------------------------------------------------------------- |
| id                   | ID                   | pair contract address                                                                                               |
| factory              | UniswapFactory       | reference to Uniswap factory entity                                                                                 |
| token0               | Token                | reference to token0 as stored in pair contract                                                                      |
| token1               | Token                | reference to token1 as stored in pair contract                                                                      |
| reserve0             | BigDecimal           | reserve of token0                                                                                                   |
| reserve1             | BigDecimal           | reserve of token1                                                                                                   |
| totalSupply          | BigDecimal           | total supply of liquidity token distributed to LPs                                                                  |
| reserveETH           | BigDecimal           | total liquidity in pair stored as an amount of ETH                                                                  |
| reserveUSD           | BigDecimal           | total liquidity amount in pair stored as an amount of USD                                                           |
| trackedReserveETH    | BigDecimal           | total liquidity with only tracked amount (see tracked amounts)                                                      |
| token0Price          | BigDecimal           | token0 per token1                                                                                                   |
| token1Price          | BigDecimal           | token1 per token0                                                                                                   |
| volumeToken0         | BigDecimal           | amount of token0 swapped on this pair                                                                               |
| volumeToken1         | BigDecimal           | amount of token1 swapped on this pair                                                                               |
| volumeUSD            | BigDecimal           | total amount swapped all time in this pair stored in USD (only tracked if USD liquidity is above minimum threshold) |
| untrackedVolumeUSD   | BigDecimal           | total amount swapped all time in this pair stored in USD, no minimum liquidity threshold                            |
| txCount              | BigInt               | all time amount of transactions on this pair                                                                        |
| createdAtTimestamp   | BigInt               | timestamp contract was created                                                                                      |
| createdAtBlockNumber | BigInt               | Ethereum block contract was created                                                                                 |
| liquidityPositions   | \[LiquidityPosition] | array of liquidity providers, used as a reference to LP entities                                                    |

#### User[#](broken://pages/6y9aAXBriajopM7uD6xn)

A user entity is created for any address that provides liquidity to a pool on Uniswap. This entity can be used to track open positions for users. LiquidyPosition entities can be referenced to get specific data about each position.

| Field Name         | Value Type           | Description                                    |
| ------------------ | -------------------- | ---------------------------------------------- |
| id                 | ID                   | user address                                   |
| liquidityPositions | \[LiquidityPosition] | array of all liquidity positions user has open |
| usdSwapped         | BigDecimal           | total USD value swapped                        |

#### LiquidityPositiion[#](broken://pages/6y9aAXBriajopM7uD6xn)

This entity is used to store data about a user's liquidity position. This information, along with information from the pair itself can be used to provide position sizes, token deposits, and more.

| Field Name            | Value Type | Description                                            |
| --------------------- | ---------- | ------------------------------------------------------ |
| id                    | ID         | user address and pair address concatenated with a dash |
| user                  | User       | reference to user                                      |
| pair                  | Pair       | reference to the pair liquidity is being provided on   |
| liquidityTokenBalance | BigDecimal | amount of LP tokens minted for this position           |

#### Transaction[#](broken://pages/6y9aAXBriajopM7uD6xn)

Transaction entities are created for each Ethereum transaction that contains an interaction within Uniswap contracts. This subgraph tracks Mint, Burn, and Swap events on the Uniswap core contracts. Each transaction contains 3 arrays, and at least one of these arrays has a length of 1.

| Field Name  | Value Type | Description                                               |
| ----------- | ---------- | --------------------------------------------------------- |
| id          | ID         | Ethereum transaction hash                                 |
| blockNumber | BigInt     | block transaction was mined in                            |
| timestamp   | BigInt     | timestamp for transaction                                 |
| mints       | \[Mint]    | array of Mint events within the transaction, 0 or greater |
| burns       | \[Burn]    | array of Burn events within transaction, 0 or greater     |
| swaps       | \[Swap]    | array of Swap events within transaction, 0 or greater     |

#### Mint[#](broken://pages/6y9aAXBriajopM7uD6xn)

Mint entities are created for every emitted Mint event on the Uniswap core contracts. The Mint entity stores key data about the event like token amounts, who sent the transaction, who received the liquidity, and more. This entity can be used to track liquidity provisions on pairs.

| Field Name   | Value Type  | Description                                                 |
| ------------ | ----------- | ----------------------------------------------------------- |
| id           | ID          | Transaction hash plus index in the transaction mint array   |
| transaction  | Transaction | reference to the transaction Mint was included in           |
| timestamp    | BigInt      | timestamp of Mint, used to sort recent liquidity provisions |
| pair         | Pair        | reference to pair                                           |
| to           | Bytes       | recipient of liquidity tokens                               |
| liquidity    | BigDecimal  | amount of liquidity tokens minted                           |
| sender       | Bytes       | address that initiated the liquidity provision              |
| amount0      | BigDecimal  | amount of token0 provided                                   |
| amount1      | BigDecimal  | amount of token1 provided                                   |
| logIndex     | BigInt      | index in the transaction event was emitted                  |
| amountUSD    | BigDecimal  | derived USD value of token0 amount plus token1 amount       |
| feeTo        | Bytes       | address of fee recipient (if fee is on)                     |
| feeLiquidity | BigDecimal  | amount of liquidity sent to fee recipient (if fee is on)    |

#### Burn[#](broken://pages/6y9aAXBriajopM7uD6xn)

Burn entities are created for every emitted Burn event on the Uniswap core contracts. The Burn entity stores key data about the event like token amounts, who burned LP tokens, who received tokens, and more. This entity can be used to track liquidity removals on pairs.

| Field Name   | Value Type  | Description                                               |
| ------------ | ----------- | --------------------------------------------------------- |
| id           | ID          | Transaction hash plus index in the transaction burn array |
| transaction  | Transaction | reference to the transaction Burn was included in         |
| timestamp    | BigInt      | timestamp of Burn, used to sort recent liquidity removals |
| pair         | Pair        | reference to pair                                         |
| to           | Bytes       | recipient of tokens                                       |
| liquidity    | BigDecimal  | amount of liquidity tokens burned                         |
| sender       | Bytes       | address that initiated the liquidity removal              |
| amount0      | BigDecimal  | amount of token0 removed                                  |
| amount1      | BigDecimal  | amount of token1 removed                                  |
| logIndex     | BigInt      | index in the transaction event was emitted                |
| amountUSD    | BigDecimal  | derived USD value of token0 amount plus token1 amount     |
| feeTo        | Bytes       | address of fee recipient (if fee is on)                   |
| feeLiquidity | BigDecimal  | amount of tokens sent to fee recipient (if fee is on)     |

#### Swap[#](broken://pages/6y9aAXBriajopM7uD6xn)

Swap entities are created for each token swap within a pair. The Swap entity can be used to get things like swap size (in tokens and USD), sender, recipient and more. See the Swap overview page for more information on amounts.

| Field Name  | Value Type  | Description                                           |
| ----------- | ----------- | ----------------------------------------------------- |
| id          | ID          | transaction hash plus index in Transaction swap array |
| transaction | Transaction | reference to transaction swap was included in         |
| timestamp   | BigInt      | timestamp of swap, used for sorted lookups            |
| pair        | Pair        | reference to pair                                     |
| sender      | Bytes       | address that initiated the swap                       |
| amount0In   | BigDecimal  | amount of token0 sold                                 |
| amount1In   | BigDecimal  | amount of token1 sold                                 |
| amount0Out  | BigDecimal  | amount of token0 received                             |
| amount1Out  | BigDecimal  | amount of token1 received                             |
| to          | Bytes       | recipient of output tokens                            |
| logIndex    | BigInt      | event index within transaction                        |
| amountUSD   | BigDecimal  | derived amount of tokens sold in USD                  |

#### Bundle[#](broken://pages/6y9aAXBriajopM7uD6xn)

The Bundle is used as a global store of derived ETH price in USD. Because there is no guaranteed common base token across pairs, a global reference of USD price is useful for deriving other USD values. The Bundle entity stores an updated weighted average of ETH<->Stablecoin pair prices. This provides a strong estimate for the USD price of ETH that can be used in other places in the subgraph.

| Field Name | Value Type | Description                                           |
| ---------- | ---------- | ----------------------------------------------------- |
| id         | ID         | constant 1                                            |
| ethPrice   | BigDecimal | derived price of ETH in USD based on stablecoin pairs |

### Historical Entities[#](broken://pages/6y9aAXBriajopM7uD6xn)

The subgraph tracks aggregated information grouped by days to provide insights to daily activity on Uniswap. While [time travel queries](https://blocklytics.org/blog/ethereum-blocks-subgraph-made-for-time-travel/) can be used for direct comparison against values in the past, it is much more expensive to query grouped data. For this reason the subgraph tracks information grouped in daily buckets, using timestamps provided by contract events. These entities can be used to query things like total volume on a given day, price of a token on a given day, etc.

For each DayData type, a new entity is created each day.

#### UniswapDayData[#](broken://pages/6y9aAXBriajopM7uD6xn)

Tracks data across all pairs aggregated into a daily bucket.

| Field Name        | Value Type       | Description                                                                      |
| ----------------- | ---------------- | -------------------------------------------------------------------------------- |
| id                | ID               | unix timestamp for start of day / 86400 giving a unique day index                |
| date              | Int              | unix timestamp for start of day                                                  |
| dailyVolumeETH    | BigDecimal       | total volume across all pairs on this day, stored as a derived amount of ETH     |
| dailyVolumeUSD    | BigDecimal       | total volume across all pairs on this day, stored as a derived amount of USD     |
| totalVolumeETH    | BigDecimal       | all time volume across all pairs in ETH up to and including this day             |
| totalLiquidityETH | BigDecimal       | total liquidity across all pairs in ETH up to and including this day             |
| totalVolumeUSD    | BigDecimal       | all time volume across all pairs in USD up to and including this day             |
| totalLiquidityUSD | BigDecimal       | total liquidity across all pairs in USD up to and including this day             |
| maxStored         | Int              | reference used to store most liquid tokens, used for historical liquidity charts |
| mostLiquidTokens  | \[TokenDayData!] | tokens with most liquidity in Uniswap                                            |
| txCount           | BigInt           | number of transactions throughout this day                                       |

#### Pair Day Data[#](broken://pages/6y9aAXBriajopM7uD6xn)

Tracks pair data across each day.

| Field Name        | Value Type | Description                                                                                     |
| ----------------- | ---------- | ----------------------------------------------------------------------------------------------- |
| id                | ID         | pair contract address and day id (day start timestamp in unix / 86400) concatenated with a dash |
| date              | Int        | unix timestamp for start of day                                                                 |
| pairAddress       | Bytes      | address for pair contract                                                                       |
| token0            | Token      | reference to token0                                                                             |
| token1            | Token      | reference to token1                                                                             |
| reserve0          | BigDecimal | reserve of token0 (updated during each transaction on pair)                                     |
| reserve1          | BigDecimal | reserve of token1 (updated during each transaction on pair)                                     |
| totalSupply       | BigDecimal | total supply of liquidity token distributed to LPs                                              |
| reserveUSD        | BigDecimal | reserve of token0 plus token1 stored as a derived USD amount                                    |
| dailyVolumeToken0 | BigDecimal | total amount of token0 swapped throughout day                                                   |
| dailyVolumeToken1 | BigDecimal | total amount of token1 swapped throughout day                                                   |
| dailyVolumeUSD    | BigDecimal | total volume within pair throughout day                                                         |
| dailyTxns         | BigInt     | amount of transactions on pair throughout day                                                   |

#### TokenDayData[#](broken://pages/6y9aAXBriajopM7uD6xn)

Tracks token data aggregated across all pairs that include token.

| Field Name          | Value Type     | Description                                                                                                                            |
| ------------------- | -------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| id                  | ID             | token address and day id (day start timestamp in unix / 86400) concatenated with a dash                                                |
| date                | Int            | unix timestamp for start of day                                                                                                        |
| token               | Token          | reference to token entity                                                                                                              |
| dailyVolumeToken    | BigDecimal     | amount of token swapped across all pairs throughout day                                                                                |
| dailyVolumeETH      | BigDecimal     | amount of token swapped across all pairs throughout day stored as a derived amount of ETH                                              |
| dailyVolumeUSD      | BigDecimal     | amount of token swapped across all pairs throughout day stored as a derived amount of USD                                              |
| dailyTxns           | BigInt         | amount of transactions with this token across all pairs                                                                                |
| totalLiquidityToken | BigDecimal     | token amount of token deposited across all pairs                                                                                       |
| totalLiquidityETH   | BigDecimal     | token amount of token deposited across all pairs stored as amount of ETH                                                               |
| totalLiquidityUSD   | BigDecimal     | token amount of token deposited across all pairs stored as amount of USD                                                               |
| priceUSD            | BigDecimal     | price of token in derived USD                                                                                                          |
| maxStored           | Int            | amount of token deposited in pair with highest token liquidity - used only as a reference for storing most liquid pairs for this token |
| mostLiquidPairs     | \[PairDayData] | pairs with most liquidity for this token                                                                                               |


# Queries

The subgraph can be queried to retrieve important information about Uniswap, pairs, tokens, transactions, users, and more. This page will provide examples for common queries.

To try these queries and run your own visit the [subgraph sandbox](https://thegraph.com/explorer/subgraph/uniswap/uniswap-v2).

#### Global Data

To query global data you can pass in the Uniswap Factory address and select from available fields.

**Global Stats**

All time volume in USD, total liquidity in USD, all time transaction count.

```
{
 uniswapFactory(id: "0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f"){
   totalVolumeUSD
   totalLiquidityUSD
   txCount
 }
}
```

**Global Historical lookup**

To get a snapshot of past state, use The Graph's block query feature and query at a previous block. See this post to get more information about [fetching block numbers from timestamps](https://blocklytics.org/blog/ethereum-blocks-subgraph-made-for-time-travel/). This can be used to calculate things like 24hr volume.

```
{
 uniswapFactory(id: "0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f", block: {number: 10291203}){
   totalVolumeUSD
   totalLiquidityUSD
   txCount
 }
}
```

#### Pair Data

**Pair Overview**

Fetch a snapshot of the current state of the pair with common values. This example fetches the DAI/WETH pair.

```
{
 pair(id: "0xa478c2975ab1ea89e8196811f51a7b7ade33eb11"){
     token0 {
       id
       symbol
       name
       derivedETH
     }
     token1 {
       id
       symbol
       name
       derivedETH
     }
     reserve0
     reserve1
     reserveUSD
     trackedReserveETH
     token0Price
     token1Price
     volumeUSD
     txCount
 }
}
```

**All pairs in Uniswap**

The Graph limits entity return amounts to 1000 per query as of now. To get all pairs on Uniswap use a loop and graphql skip query to fetch multiple chunks of 1000 pairs. The query would look like this (where skip is some incrementing variable passed into your query).

```
{
 query pairs($skip: Int!) {
   pairs(first: 1000, skip: $skip) {
     id
   }
 }
}
```

**Most liquid pairs**

Order by liquidity to get the most liquid pairs in Uniswap.

```
{
 pairs(first: 1000, orderBy: reserveUSD, orderDirection: desc) {
   id
 }
}
```

**Recent Swaps within a Pair**

Get the last 100 swaps on a pair by fetching Swap events and passing in the pair address. You'll often want token information as well.

```
{
swaps(orderBy: timestamp, orderDirection: desc, where:
 { pair: "0xa478c2975ab1ea89e8196811f51a7b7ade33eb11" }
) {
     pair {
       token0 {
         symbol
       }
       token1 {
         symbol
       }
     }
     amount0In
     amount0Out
     amount1In
     amount1Out
     amountUSD
     to
 }
}
```

**Pair Daily Aggregated**

Day data is useful for building charts and historical views around entities. To get stats about a pair in daily buckets query for day entities bounded by timestamps. This query gets the first 100 days after the given unix timestamp on the DAI/WETH pair.

```
{
 pairDayDatas(first: 100, orderBy: date, orderDirection: asc,
   where: {
     pairAddress: "0xa478c2975ab1ea89e8196811f51a7b7ade33eb11",
     date_gt: 1592505859
   }
 ) {
     date
     dailyVolumeToken0
     dailyVolumeToken1
     dailyVolumeUSD
     reserveUSD
 }
}
```

#### Token Data

Token data can be fetched using the token contract address as an ID. Token data is aggregated across all pairs the token is included in. Any token that is included in some pair in Uniswap can be queried.

**Token Overview**

Get a snapshot of the current stats on a token in Uniswap. This query fetches current stats on DAI. The allPairs field gets the first 200 pairs DAI is included in sorted by liquidity in derived USD.

```
{
 token(id: "0x6b175474e89094c44da98b954eedeac495271d0f"){
   name
   symbol
   decimals
   derivedETH
   tradeVolumeUSD
   totalLiquidity
 }
}
```

**All Tokens in Uniswap**

Similar to fetching all pairs (see above), you can query all tokens in Uniswap. Because The Graph service limits return size to 1000 entities use graphql skip query. (Note this query will not work in the graph sandbox and more resembles the structure of a query you'd pass to some graphql middleware like [Apollo](https://www.apollographql.com/)).

```
{
 query tokens($skip: Int!) {
   tokens(first: 1000, skip: $skip) {
     id
     name
     symbol
   }
 }
}
```

**Token Transactions**

To get transactions that include a token you'll need to first fetch an array of pairs that the token is included in (this can be done with the allPairs field on the Token entity.) Once you have an array of pairs the token is included in, filter on that in the transaction lookup.

This query fetches the latest 30 mints, swaps, and burns involving DAI. The allPairs array could look something like this where we include the DAI/WETH pair address and the DAI/USDC pair address.

```
allPairs = [
 "0xa478c2975ab1ea89e8196811f51a7b7ade33eb11",
 "0xae461ca67b15dc8dc81ce7615e0320da1a9ab8d5"
]
```

```
query($allPairs: [String!]) {
 mints(first: 30, where: { pair_in: $allPairs }, orderBy: timestamp, orderDirection: desc) {
   transaction {
     id
     timestamp
   }
   to
   liquidity
   amount0
   amount1
   amountUSD
 }
 burns(first: 30, where: { pair_in: $allPairs }, orderBy: timestamp, orderDirection: desc) {
   transaction {
     id
     timestamp
   }
   to
   liquidity
   amount0
   amount1
   amountUSD
 }
 swaps(first: 30, where: { pair_in: $allPairs }, orderBy: timestamp, orderDirection: desc) {
   transaction {
     id
     timestamp
   }
   amount0In
   amount0Out
   amount1In
   amount1Out
   amountUSD
   to
 }
}
```

**Token Daily Aggregated**

Like pair and global daily lookups, tokens have daily entities that can be queries as well. This query gets daily information for DAI. Note that you may want to sort in ascending order to receive your days from oldest to most recent in the return array.

```
{
 tokenDayDatas(orderBy: date, orderDirection: asc,
  where: {
    token: "0x6b175474e89094c44da98b954eedeac495271d0f"
  }
 ) {
    id
    date
    priceUSD
    totalLiquidityToken
    totalLiquidityUSD
    totalLiquidityETH
    dailyVolumeETH
    dailyVolumeToken
    dailyVolumeUSD
 }
}
```

#### ETH Price

You can use the Bundle entity to query current USD price of ETH in Uniswap based on a weighted average of stablecoins.

```
{
 bundle(id: "1" ) {
   ethPrice
 }
}
```


# Smart Contracts

## Smart contracts

Quickswap V2 is a binary smart contract system. [Core](https://docs.quickswap.exchange/concepts/protocol-overview/03-smart-contracts#core) contracts provide fundamental safety guarantees for all parties interacting with Quickswap. [Periphery](https://docs.quickswap.exchange/concepts/protocol-overview/03-smart-contracts#periphery) contracts interact with one or more core contracts but are not themselves part of the core.

## Core <a href="#core" id="core"></a>

[Source code](https://github.com/Uniswap/uniswap-v2-core)

The core consists of a singleton [factory](https://docs.quickswap.exchange/concepts/protocol-overview/03-smart-contracts#factory) and many [pairs](https://docs.quickswap.exchange/concepts/protocol-overview/03-smart-contracts#pairs), which the factory is responsible for creating and indexing. These contracts are quite minimal, even brutalist. The simple rationale for this is that contracts with a smaller surface area are easier to reason about, less bug-prone, and more functionally elegant. Perhaps the biggest upside of this design is that many desired properties of the system can be asserted directly in the code, leaving little room for error. One downside, however, is that core contracts are somewhat user-unfriendly. In fact, interacting directly with these contracts is not recommended for most use cases. Instead, a periphery contract should be used.

### Factory <a href="#factory" id="factory"></a>

[Reference documentation](https://docs.quickswap.exchange/reference/smart-contracts/01-factory.md)

The factory holds the generic bytecode responsible for powering pairs. Its primary job is to create one and only one smart contract per unique token pair. It also contains logic to turn on the protocol charge.

### Pairs <a href="#pairs" id="pairs"></a>

[Reference documentation](https://docs.quickswap.exchange/reference/smart-contracts/02-pair.md)

[Reference documentation (ERC-20)](https://docs.quickswap.exchange/reference/smart-contracts/03-pair-erc-20.md)

Pairs have two primary purposes: serving as automated market makers and keeping track of pool token balances. They also expose data which can be used to build decentralized price oracles.

## Periphery <a href="#periphery" id="periphery"></a>

[Source code](https://github.com/Uniswap/uniswap-v2-periphery)

The periphery is a constellation of smart contracts designed to support domain-specific interactions with the core. Because of Quickswap's permissionless nature, the contracts described below have no special privileges, and are in fact only a small subset of the universe of possible periphery-like contracts. However, they are useful examples of how to safely and efficiently interact with Quickswap V2.

### Library <a href="#library" id="library"></a>

[Reference documentation](https://docs.quickswap.exchange/reference/smart-contracts/04-library.md)

The library provides a variety of convenience functions for fetching data and pricing.

### Router <a href="#router" id="router"></a>

[Reference documentation](https://docs.quickswap.exchange/reference/smart-contracts/06-router02.md)

The router, which uses the library, fully supports all the basic requirements of a front-end offering trading and liquidity management functionality. Notably, it natively supports multi-pair trades (e.g. x to y to z), treats ETH as a first-class citizen, and offers meta-transactions for removing liquidity.

## Design Decisions <a href="#design-decisions" id="design-decisions"></a>

The following sections describe some of the notable design decisions made in Quickswap V2. These are safe to skip unless you're interested in gaining a deep technical understanding of how V2 works under the hood, or writing smart contract integrations!

### Sending Tokens <a href="#sending-tokens" id="sending-tokens"></a>

Typically, smart contracts which need tokens to perform some functionality require would-be interactors 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 V2 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. See the [whitepaper](https://docs.quickswap.exchange/whitepaper.pdf) for a justification of why this is the case, but the takeaway is that **tokens must be transferred to the pair before calling any token-requiring method** (the one exception to this rule is [Flash Swaps](https://docs.quickswap.exchange/concepts/core-concepts/03-flash-swaps).

### MATIC <a href="#matic" id="matic"></a>

Matic⇄ERC-20 pairs must be emulated with WMATIC. The motivation behind this choice was to remove Matic-specific code in the core, resulting in a leaner codebase. End users can be kept fully ignorant of this implementation detail, however, by simply wrapping/unwrapping Matic in the periphery.

The router fully supports interacting with any WETH pair via ETH.

### Minimum Liquidity <a href="#minimum-liquidity" id="minimum-liquidity"></a>

To ameliorate rounding errors and increase the theoretical minimum tick size for liquidity provision, pairs burn the first [MINIMUM\_LIQUIDITY](https://docs.quickswap.exchange/reference/smart-contracts/02-pair.md#minimum_liquidity) pool tokens. For the vast majority of pairs, this will represent a trivial value. The burning happens automatically during the first liquidity provision, after which point the [totalSupply](https://docs.quickswap.exchange/reference/smart-contracts/pair-erc-20#totalsupply) is forevermore bounded.


# V2


# Factory

## Code

[`UniswapV2Factory.sol`](https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2Factory.sol)

## Address

`UniswapV2Factory` is deployed at `0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f` on the Ethereum [mainnet](https://etherscan.io/address/0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f), and the [Ropsten](https://ropsten.etherscan.io/address/0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f), [Rinkeby](https://rinkeby.etherscan.io/address/0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f), [Görli](https://goerli.etherscan.io/address/0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f), and [Kovan](https://kovan.etherscan.io/address/0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f) testnets. It was built from commit [8160750](https://github.com/Uniswap/uniswap-v2-core/tree/816075049f811f1b061bca81d5d040b96f4c07eb).

## Events

### PairCreated

```solidity
event PairCreated(address indexed token0, address indexed token1, address pair, uint);
```

Emitted each time a pair is created via [createPair](broken://pages/hpp8N0LYL0t2d9hY8wNh).

* `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](broken://pages/hpp8N0LYL0t2d9hY8wNh)/[getPair](broken://pages/hpp8N0LYL0t2d9hY8wNh)).

## Read-Only Functions

### getPair

```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, see Pair Addresses.

### allPairs

```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

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

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

### feeTo

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

See Protocol Charge Calculation.

### feeToSetter

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

The address allowed to change [feeTo](broken://pages/hpp8N0LYL0t2d9hY8wNh).

## State-Changing Functions

### createPair

```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](broken://pages/hpp8N0LYL0t2d9hY8wNh).

## Interface

```solidity
import '@uniswap/v2-core/contracts/interfaces/IUniswapV2Factory.sol';
```

```solidity
pragma solidity >=0.5.0;

interface IUniswapV2Factory {
  event PairCreated(address indexed token0, address indexed token1, address pair, uint);

  function getPair(address tokenA, address tokenB) external view returns (address pair);
  function allPairs(uint) external view returns (address pair);
  function allPairsLength() external view returns (uint);

  function feeTo() external view returns (address);
  function feeToSetter() external view returns (address);

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

## ABI

```typescript
import IUniswapV2Factory from '@uniswap/v2-core/build/IUniswapV2Factory.json'
```

<https://unpkg.com/@uniswap/v2-core@1.0.0/build/IUniswapV2Factory.json>


# Pair

This documentation covers Uniswap-specific functionality. For ERC-20 functionality, see Pair (ERC-20).

## Code

[`UniswapV2Pair.sol`](https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2Pair.sol)

## Address

See Pair Addresses.

## Events

### Mint

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

Emitted each time liquidity tokens are created via [mint](broken://pages/IptPgkQPJaqhPg8aUdq7).

### Burn

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

Emitted each time liquidity tokens are destroyed via [burn](broken://pages/IptPgkQPJaqhPg8aUdq7).

### Swap

```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](broken://pages/IptPgkQPJaqhPg8aUdq7).

### Sync

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

Emitted each time reserves are updated via [mint](broken://pages/IptPgkQPJaqhPg8aUdq7), [burn](broken://pages/IptPgkQPJaqhPg8aUdq7), [swap](broken://pages/IptPgkQPJaqhPg8aUdq7), or [sync](broken://pages/IptPgkQPJaqhPg8aUdq7).

## Read-Only Functions

### MINIMUM\_LIQUIDITY

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

Returns `1000` for all pairs. See Minimum Liquidity.

### factory

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

Returns the factory address.

### token0

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

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

### token1

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

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

### getReserves

```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. Also returns the `block.timestamp` (mod `2**32`) of the last block during which an interaction occured for the pair.

### price0CumulativeLast

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

See Oracles.

### price1CumulativeLast

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

See Oracles.

### kLast

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

Returns the product of the reserves as of the most recent liquidity event. See Protocol Charge Calculation.

## State-Changing Functions

### mint

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

Creates pool tokens.

* Emits [Mint](broken://pages/IptPgkQPJaqhPg8aUdq7), [Sync](broken://pages/IptPgkQPJaqhPg8aUdq7), Transfer.

### burn

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

Destroys pool tokens.

* Emits [Burn](broken://pages/IptPgkQPJaqhPg8aUdq7), [Sync](broken://pages/IptPgkQPJaqhPg8aUdq7), Transfer.

### swap

```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.

* Emits [Swap](broken://pages/IptPgkQPJaqhPg8aUdq7), [Sync](broken://pages/IptPgkQPJaqhPg8aUdq7).

### skim

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

See the whitepaper.

### sync

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

See the whitepaper.

* Emits [Sync](broken://pages/IptPgkQPJaqhPg8aUdq7).

## Interface

```solidity
import '@uniswap/v2-core/contracts/interfaces/IUniswapV2Pair.sol';
```

```solidity
pragma solidity >=0.5.0;

interface IUniswapV2Pair {
  event Approval(address indexed owner, address indexed spender, uint value);
  event Transfer(address indexed from, address indexed to, uint value);

  function name() external pure returns (string memory);
  function symbol() external pure returns (string memory);
  function decimals() external pure returns (uint8);
  function totalSupply() external view returns (uint);
  function balanceOf(address owner) external view returns (uint);
  function allowance(address owner, address spender) external view returns (uint);

  function approve(address spender, uint value) external returns (bool);
  function transfer(address to, uint value) external returns (bool);
  function transferFrom(address from, address to, uint value) external returns (bool);

  function DOMAIN_SEPARATOR() external view returns (bytes32);
  function PERMIT_TYPEHASH() external pure returns (bytes32);
  function nonces(address owner) external view returns (uint);

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

  event Mint(address indexed sender, uint amount0, uint amount1);
  event Burn(address indexed sender, uint amount0, uint amount1, address indexed to);
  event Swap(
      address indexed sender,
      uint amount0In,
      uint amount1In,
      uint amount0Out,
      uint amount1Out,
      address indexed to
  );
  event Sync(uint112 reserve0, uint112 reserve1);

  function MINIMUM_LIQUIDITY() external pure returns (uint);
  function factory() external view returns (address);
  function token0() external view returns (address);
  function token1() external view returns (address);
  function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
  function price0CumulativeLast() external view returns (uint);
  function price1CumulativeLast() external view returns (uint);
  function kLast() external view returns (uint);

  function mint(address to) external returns (uint liquidity);
  function burn(address to) external returns (uint amount0, uint amount1);
  function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
  function skim(address to) external;
  function sync() external;
}
```

## ABI

```typescript
import IUniswapV2Pair from '@uniswap/v2-core/build/IUniswapV2Pair.json'
```

<https://unpkg.com/@uniswap/v2-core@1.0.0/build/IUniswapV2Pair.json>


# Pair (ERC-20)

This documentation covers ERC-20 functionality for denominating pool tokens. For Uniswap-specific functionality, see Pair.

## Code

[`UniswapV2ERC20.sol`](https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)

## Events

### Approval

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

Emitted each time an approval occurs via [approve](broken://pages/RRMrmoJ1PW7FNlmln1Wy) or [permit](broken://pages/RRMrmoJ1PW7FNlmln1Wy).

### Transfer

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

Emitted each time a transfer occurs via [transfer](broken://pages/RRMrmoJ1PW7FNlmln1Wy), [transferFrom](broken://pages/RRMrmoJ1PW7FNlmln1Wy), mint, or burn.

## Read-Only Functions

### name

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

Returns `Uniswap V2` for all pairs.

### symbol

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

Returns `UNI-V2` for all pairs.

### decimals

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

Returns `18` for all pairs.

### totalSupply

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

Returns the total amount of pool tokens for a pair.

### balanceOf

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

Returns the amount of pool tokens owned by an address.

### allowance

```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](broken://pages/RRMrmoJ1PW7FNlmln1Wy).

### DOMAIN\_SEPARATOR

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

Returns a domain separator for use in [permit](broken://pages/RRMrmoJ1PW7FNlmln1Wy).

### PERMIT\_TYPEHASH

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

Returns a typehash for use in [permit](broken://pages/RRMrmoJ1PW7FNlmln1Wy).

### nonces

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

Returns the current nonce for an address for use in [permit](broken://pages/RRMrmoJ1PW7FNlmln1Wy).

## State-Changing Functions

### approve

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

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

* Emits [Approval](broken://pages/RRMrmoJ1PW7FNlmln1Wy).

### transfer

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

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

* Emits [Transfer](broken://pages/RRMrmoJ1PW7FNlmln1Wy).

### transferFrom

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

Sends pool tokens from one address to another.

* Requires approval.
* Emits [Transfer](broken://pages/RRMrmoJ1PW7FNlmln1Wy).

### permit

```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.

* See Using Permit.
* Emits [Approval](broken://pages/RRMrmoJ1PW7FNlmln1Wy).

## Interface

```solidity
import '@uniswap/v2-core/contracts/interfaces/IUniswapV2ERC20.sol';
```

```solidity
pragma solidity >=0.5.0;

interface IUniswapV2ERC20 {
  event Approval(address indexed owner, address indexed spender, uint value);
  event Transfer(address indexed from, address indexed to, uint value);

  function name() external pure returns (string memory);
  function symbol() external pure returns (string memory);
  function decimals() external pure returns (uint8);
  function totalSupply() external view returns (uint);
  function balanceOf(address owner) external view returns (uint);
  function allowance(address owner, address spender) external view returns (uint);

  function approve(address spender, uint value) external returns (bool);
  function transfer(address to, uint value) external returns (bool);
  function transferFrom(address from, address to, uint value) external returns (bool);

  function DOMAIN_SEPARATOR() external view returns (bytes32);
  function PERMIT_TYPEHASH() external pure returns (bytes32);
  function nonces(address owner) external view returns (uint);

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

## ABI

```typescript
import IUniswapV2ERC20 from '@uniswap/v2-core/build/IUniswapV2ERC20.json'
```

<https://unpkg.com/@uniswap/v2-core@1.0.0/build/IUniswapV2ERC20.json>


# Library

## Code

[`UniswapV2Library.sol`](https://github.com/Uniswap/uniswap-v2-periphery/blob/master/contracts/libraries/UniswapV2Library.sol)

## Internal Functions

### sortTokens

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

Sorts token addresses.

### pairFor

```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 (see Pair Addresses).

### getReserves

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

Calls getReserves on the pair for the passed tokens, and returns the results sorted in the order that the parameters were passed in.

### quote

```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.

### getAmountOut

```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](broken://pages/iAVxMCCpvWZ9JQIDWZa0).

### getAmountIn

```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](broken://pages/iAVxMCCpvWZ9JQIDWZa0).

### getAmountsOut

```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](broken://pages/iAVxMCCpvWZ9JQIDWZa0) for each pair of token addresses in the path in turn, and using these to call [getAmountOut](broken://pages/iAVxMCCpvWZ9JQIDWZa0).

* Useful for calculating optimal token amounts before calling swap.

### getAmountsIn

```solidity
function getAmountsIn(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](broken://pages/iAVxMCCpvWZ9JQIDWZa0) for each pair of token addresses in the path in turn, and using these to call [getAmountIn](broken://pages/iAVxMCCpvWZ9JQIDWZa0).

* Useful for calculating optimal token amounts before calling swap.


# Router02

Because routers are stateless and do not hold token balances, they can be replaced safely and trustlessly, if necessary. This may happen if more efficient smart contract patterns are discovered, or if additional functionality is desired. For this reason, routers have *release numbers*, starting at `01`. This is currently recommended release, `02`.

## Code

[`UniswapV2Router02.sol`](https://github.com/Uniswap/uniswap-v2-periphery/blob/master/contracts/UniswapV2Router02.sol)

## Address

`UniswapV2Router02` is deployed at `0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D` on the Ethereum [mainnet](https://etherscan.io/address/0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D), and the [Ropsten](https://ropsten.etherscan.io/address/0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D), [Rinkeby](https://rinkeby.etherscan.io/address/0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D), [Görli](https://goerli.etherscan.io/address/0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D), and [Kovan](https://kovan.etherscan.io/address/0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D) testnets. It was built from commit [6961711](https://github.com/Uniswap/uniswap-v2-periphery/tree/69617118cda519dab608898d62aaa79877a61004).

## Read-Only Functions

### factory

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

Returns factory address.

### WETH

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

Returns the [canonical WETH address](https://blog.0xproject.com/canonical-weth-a9aa7d0279dd) on the Ethereum [mainnet](https://etherscan.io/address/0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2), or the [Ropsten](https://ropsten.etherscan.io/address/0xc778417e063141139fce010982780140aa0cd5ab), [Rinkeby](https://rinkeby.etherscan.io/address/0xc778417e063141139fce010982780140aa0cd5ab), [Görli](https://goerli.etherscan.io/address/0xb4fbf271143f4fbf7b91a5ded31805e42b2208d6), or [Kovan](https://kovan.etherscan.io/address/0xd0a1e359811322d97991e03f863a0c30c2cf029c) testnets.

### quote

See quote.

### getAmountOut

See getAmountOut.

### getAmountIn

See getAmountIn.

### getAmountsOut

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

See getAmountsOut.

### getAmountsIn

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

See getAmountsIn.

## State-Changing Functions

### addLiquidity

```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

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

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

```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

```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

```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.

| 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

```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.

| 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

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

Identical to [removeLiquidityETH](broken://pages/JlwjmscAsNEtbcRpbtmN), 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

```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](broken://pages/JlwjmscAsNEtbcRpbtmN), 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

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

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

```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

```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](broken://pages/JlwjmscAsNEtbcRpbtmN), 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

```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](broken://pages/JlwjmscAsNEtbcRpbtmN), 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

```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](broken://pages/JlwjmscAsNEtbcRpbtmN), 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

```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](broken://pages/JlwjmscAsNEtbcRpbtmN), 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

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

Identical to [swapExactTokensForTokens](broken://pages/JlwjmscAsNEtbcRpbtmN), 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

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

Identical to [swapExactETHForTokens](broken://pages/JlwjmscAsNEtbcRpbtmN), 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

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

Identical to [swapExactTokensForETH](broken://pages/JlwjmscAsNEtbcRpbtmN), 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.                                                                              |

## Interface

```solidity
import '@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol';
```

```solidity
pragma solidity >=0.6.2;

interface IUniswapV2Router01 {
    function factory() external pure returns (address);
    function WETH() external pure returns (address);

    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);
    function addLiquidityETH(
        address token,
        uint amountTokenDesired,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline
    ) external payable returns (uint amountToken, uint amountETH, uint liquidity);
    function removeLiquidity(
        address tokenA,
        address tokenB,
        uint liquidity,
        uint amountAMin,
        uint amountBMin,
        address to,
        uint deadline
    ) external returns (uint amountA, uint amountB);
    function removeLiquidityETH(
        address token,
        uint liquidity,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline
    ) external returns (uint amountToken, uint amountETH);
    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);
    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);
    function swapExactTokensForTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external returns (uint[] memory amounts);
    function swapTokensForExactTokens(
        uint amountOut,
        uint amountInMax,
        address[] calldata path,
        address to,
        uint deadline
    ) external returns (uint[] memory amounts);
    function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)
        external
        payable
        returns (uint[] memory amounts);
    function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline)
        external
        returns (uint[] memory amounts);
    function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline)
        external
        returns (uint[] memory amounts);
    function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline)
        external
        payable
        returns (uint[] memory amounts);

    function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB);
    function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut);
    function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn);
    function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts);
    function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts);
}

interface IUniswapV2Router02 is IUniswapV2Router01 {
    function removeLiquidityETHSupportingFeeOnTransferTokens(
        address token,
        uint liquidity,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline
    ) external returns (uint amountETH);
    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);

    function swapExactTokensForTokensSupportingFeeOnTransferTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external;
    function swapExactETHForTokensSupportingFeeOnTransferTokens(
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external payable;
    function swapExactTokensForETHSupportingFeeOnTransferTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external;
}
```

## ABI

```typescript
import IUniswapV2Router02 from '@uniswap/v2-periphery/build/IUniswapV2Router02.json'
```

<https://unpkg.com/@uniswap/v2-periphery@1.1.0-beta.0/build/IUniswapV2Router02.json>


# Router01

UniswapV2Router01 should not be used any longer, because of the discovery of a low severity bug and the fact that some methods do not work with tokens that take fees on transfer. The current recommendation is to use UniswapV2Router02.

## Code

[`UniswapV2Router01.sol`](https://github.com/Uniswap/uniswap-v2-periphery/blob/master/contracts/UniswapV2Router01.sol)

## Address

`UniswapV2Router01` is deployed at `0xf164fC0Ec4E93095b804a4795bBe1e041497b92a` on the Ethereum [mainnet](https://etherscan.io/address/0xf164fC0Ec4E93095b804a4795bBe1e041497b92a), and the [Ropsten](https://ropsten.etherscan.io/address/0xf164fC0Ec4E93095b804a4795bBe1e041497b92a), [Rinkeby](https://rinkeby.etherscan.io/address/0xf164fC0Ec4E93095b804a4795bBe1e041497b92a), [Görli](https://goerli.etherscan.io/address/0xf164fC0Ec4E93095b804a4795bBe1e041497b92a), and [Kovan](https://kovan.etherscan.io/address/0xf164fC0Ec4E93095b804a4795bBe1e041497b92a) testnets. It was built from commit [2ad7da2](https://github.com/Uniswap/uniswap-v2-periphery/tree/2ad7da28a6f70ec4299364bc1608af8f30e7646b).

## Read-Only Functions

### factory

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

Returns factory address.

### WETH

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

Returns the [canonical WETH address](https://blog.0xproject.com/canonical-weth-a9aa7d0279dd) on the Ethereum [mainnet](https://etherscan.io/address/0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2), or the [Ropsten](https://ropsten.etherscan.io/address/0xc778417e063141139fce010982780140aa0cd5ab), [Rinkeby](https://rinkeby.etherscan.io/address/0xc778417e063141139fce010982780140aa0cd5ab), [Görli](https://goerli.etherscan.io/address/0xb4fbf271143f4fbf7b91a5ded31805e42b2208d6), or [Kovan](https://kovan.etherscan.io/address/0xd0a1e359811322d97991e03f863a0c30c2cf029c) testnets.

## State-Changing Functions

### addLiquidity

```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

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

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

```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

```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

```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.

| 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

```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.

| 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.                                                          |

### swapExactTokensForTokens

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

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

```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 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.

| 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

```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](broken://pages/mfOCAKXjnWqOvPFbEaNt), 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

```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](broken://pages/mfOCAKXjnWqOvPFbEaNt), 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

```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](broken://pages/mfOCAKXjnWqOvPFbEaNt), 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

```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](broken://pages/mfOCAKXjnWqOvPFbEaNt), 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.                                                                      |

### quote

See quote.

### getAmountOut

See getAmountOut.

### getAmountIn

**This function contains a low severity bug, do not use.**

### getAmountsOut

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

See getAmountsOut.

### getAmountsIn

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

See getAmountsIn.

## Interface

```solidity
import '@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router01.sol';
```

```solidity
pragma solidity >=0.6.2;

interface IUniswapV2Router01 {
  function factory() external pure returns (address);
  function WETH() external pure returns (address);

  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);
  function addLiquidityETH(
      address token,
      uint amountTokenDesired,
      uint amountTokenMin,
      uint amountETHMin,
      address to,
      uint deadline
  ) external payable returns (uint amountToken, uint amountETH, uint liquidity);
  function removeLiquidity(
      address tokenA,
      address tokenB,
      uint liquidity,
      uint amountAMin,
      uint amountBMin,
      address to,
      uint deadline
  ) external returns (uint amountA, uint amountB);
  function removeLiquidityETH(
      address token,
      uint liquidity,
      uint amountTokenMin,
      uint amountETHMin,
      address to,
      uint deadline
  ) external returns (uint amountToken, uint amountETH);
  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);
  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);
  function swapExactTokensForTokens(
      uint amountIn,
      uint amountOutMin,
      address[] calldata path,
      address to,
      uint deadline
  ) external returns (uint[] memory amounts);
  function swapTokensForExactTokens(
      uint amountOut,
      uint amountInMax,
      address[] calldata path,
      address to,
      uint deadline
  ) external returns (uint[] memory amounts);
  function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)
      external
      payable
      returns (uint[] memory amounts);
  function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline)
      external
      returns (uint[] memory amounts);
  function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline)
      external
      returns (uint[] memory amounts);
  function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline)
      external
      payable
      returns (uint[] memory amounts);

  function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB);
  function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut);
  function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn);
  function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts);
  function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts);
}
```

## ABI

```typescript
import IUniswapV2Router01 from '@uniswap/v2-periphery/build/IUniswapV2Router01.json'
```

<https://unpkg.com/@uniswap/v2-periphery@1.0.0-beta.0/build/IUniswapV2Router01.json>


# Common Errors

This document covers a few error codes freqeuently encountered while building on Uniswap V2.

## UniswapV2: K

This is an error that is frequently encountered, and requires a bit of context to understand it.

The Uniswap constant product formula is “X \* Y = K”. Where X and Y represent the respective reserve balances of two ERC-20 tokens, and “K” represents the product of the reserves. It is this “K” to which the “K” error refers.

In essence, the “K” error means that a trade was attempted that somehow left the trading pair with less reserves than should be there, and as a result the transaction is reverted.

This can have a few different causes.

### Fee On Transfer Tokens

The most common examples are caused by “fee on transfer” tokens.

#### Inclusive Fee On Transfer Tokens

In most cases, a fee on transfer token burns or diverts a small portion of every transfer such that the recipient of the transfer ends up with slightly less than the sender gave. This is called an “inclusive” fee on transfer.

In the case of inclusive fee on transfer tokens, you can use the corresponding swap functions in the router contract which end with [“SupportingFeeOnTransfer”](https://uniswap.org/docs/v2/smart-contracts/router02/#swapexacttokensfortokenssupportingfeeontransfertokens). These functions succeed by adjusting the “amountOutMin” parameter to check the recipient amount rather than the sending amount when calculating the invariant.

#### Exclusive Fee On Transfer Tokens

The other type, “exclusive” fee on transfer tokens, work by sending an additional transfer from the sending address after the primary transfer. Because the router contract cannot anticipate this trailing transfer when calculating the invariant, the transaction will either revert, or partially succeed by sending the primary transfer but breaking the pool upon the trailing transfer.

In the case of exclusive fee on transfer tokens, the SupportingFeeOnTransfer functions may work, but there will be some tokens designed in such a way that they fundamentally break the router. If you are still getting a “K” error when using these functions, you may need to make a fork of the router contract that accommodates your token design.

### Rebasing Tokens

The less common instance of the “K” error is as a result of rebasing tokens.

Rebasing tokens can alter the balance of any addresses holding their tokens arbitrarily. This usually works at pre specified intervals and as a result of a handful of variables used in the economics of a rebasing token.

Rebasing tokens typically work in two ways.

#### Negative Rebasing Tokens

A negative rebasing token, the more common variant, deflates the balances of token owners. Because the rebasing is not triggered by transfers, the router cannot expect when or how a rebasing will happen. Once it does, the pair reserves will be unbalanced, and the next person to transact with the pair will bear the cost of the delta as a result of the rebasing.

Needless to say, an unenviable position.

Negative rebasing tokens have solved this error by altering their token contract to call [sync](https://uniswap.org/docs/v2/smart-contracts/pair/#sync) on the trading pair at the end of every transaction involving the Uniswap router contract. Those interested in forking the router contract should anticipate that negative rebasing tokens will break the pair until the token contracts are updated to accommodate your new router.

#### Positive Rebasing Tokens

Positive rebasing tokens arbitrarily increase the balances of token holders. When a positive rebase happens, it creates a surplus that is unaccounted for in the trading pair. Because the extra tokens are unaccounted for in the trading pair, anyone can call skim() on the trading pair and effectively steal the positive difference from the rebalance.

While positive rebalancing does not break any functionality of Uniswap, those interested in them should be aware that the positive balance found in any pair will be freely available for taking.

#### A Note on Rebasing Tokens

For those interested in building a rebasing token, a word of caution: many contracts involving decentralised trading and liquidity provisioning will break upon interacting with your token. An example approach that will lead to much easier integration in future protocols can be found in [CHAI](https://chai.money/about.html). CHAI uses a wrapper function that contains the rebalancing within the wrapper, such that the redeemable token can be easily integrated into many different systems.

## UniswapV2: LOCKED

The LOCKED error is a guard built into the router contract that prevents customised reentrancy contracts from attempting to return malicious code into the router contract at the end of a transaction.

This error is commonly encountered when using Ganache CLI to fork the Ethereum mainnet to a local instance as a part of a development environment. The error is a bug in Ganache-Cli that will hopefully be fixed in a future release by the truffle team.

A temporary fix is available by simply restarting the local fork.

## No Access To Archive Node

This is an error with either Metamask or Ganache-CLI. It usually occurs after a local fork is instantiated and contracts are deployed but there is one failed transaction.

A temporary fix is available by restarting the local fork and resetting metamask.

## UniswapV2: TRANSFER\_FAILED

This means the core contract was unable to send tokens to the recipient. This is most likely due to a scam token, where the token owner has maliciously disabled the transfer function in a way that allows users to buy the token, but not sell them.

## UniswapV2: EXPIRED

This is a result of a transaction that took too long to be broadcast to the mainnet.

Uniswap does not set gas prices natively, so most users default to the suggested gas prices in metamask. Sometimes metamask gets it wrong, though, and sets the gas price too low. If a swap takes more than 20 minutes to execute, the core contract won’t allow it to go through.

Finding accurate gas prices can be a challenge, for the time being, we like [Gas Now](https://www.gasnow.org/).

## Action Requires an Active Reserve

VM Exception While Processing Transaction: Action Requires an Active Reserve

This is potentially a ganache bug encountered when working on flash swaps. We haven't figured out the source of it yet.

## Unable To Approve Transaction On The Front End

There are rare circumstances where users are unable to approve a token on the Uniswap front end.

This is a result of some token contracts taking steps to defend against malicious contracts that attempt to front run approvals and steal a users tokens. It happens only when the user is trying to increase an approval allowance from a preallocated amount to a larger one, and only happens with a few token contracts.

The solution is have the user manually set the router contract approval amount to zero, then to the number they want. The easiest way to do this is through Etherscan.


# V3


# Position Manager

Contract to create v3 positions

### Code[#](https://docs.quickswap.exchange/reference/smart-contracts/v3/position-manager#code)

[`NonfungiblePositionManager.sol`](https://polygonscan.com/address/0x8eF88E4c7CfbbaC1C163f7eddd4B578792201de6)

### Address <a href="#address" id="address"></a>

`NonfungiblePositionManager` is deployed at `0x8eF88E4c7CfbbaC1C163f7eddd4B578792201de6` on the Polygon [mainnet](https://polygonscan.com/address/0x8eF88E4c7CfbbaC1C163f7eddd4B578792201de6).

## Events <a href="#events" id="events"></a>

### IncreaseLiquidity <a href="#increaseliquidity" id="increaseliquidity"></a>

`event IncreaseLiquidity(uint256 indexed tokenId, uint128 liquidity, uint128 actualLiquidity, uint256 amount0, uint256 amount1, address pool);`

Emitted when a position NFT is created via [mint](https://docs.quickswap.exchange/reference/smart-contracts/v3/position-manager#mint) or liquidity is increased for a position NFT.

* `tokenId` The ID of the token for which liquidity was increased.
* `liquidity` The amount by which liquidity for the NFT position was increased
* `actualLiquidity` The actual liquidity that was added into a pool. Could differ from `liquidity` when using FeeOnTransfer tokens
* `amount0` The amount of token0 that was paid for the increase in liquidity
* `amount1` The amount of token1 that was paid for the increase in liquidity

### DecreaseLiquidit <a href="#decreaseliquidity" id="decreaseliquidity"></a>

`event DecreaseLiquidity(uint256 indexed tokenId, uint128 liquidity, uint256 amount0, uint256 amount1);`

Emitted when liquidity is removed from a position NFT.

* `tokenId` The ID of the token for which liquidity was decreased
* `liquidity` The amount by which liquidity for the NFT position was decreased
* `amount0` The amount of token0 that was accounted for the decrease in liquidity
* `amount1` The amount of token1 that was accounted for the decrease in liquidity

### Collect <a href="#collect" id="collect"></a>

`event Collect(uint256 indexed tokenId, address recipient, uint256 amount0, uint256 amount1);`

Emitted when tokens are collected for a position NFT. The amounts reported may not be exactly equivalent to the amounts transferred, due to rounding behavior

* `tokenId` The ID of the token for which underlying tokens were collected
* `recipient` The address of the account that received the collected tokens
* `amount0` The amount of token0 owed to the position that was collected
* `amount1` The amount of token1 owed to the position that was collected

## Read-Only Functions <a href="#read-only-functions" id="read-only-functions"></a>

### positions <a href="#positions" id="positions"></a>

`function positions(uint256 tokenId) external view override returns (uint96 nonce, address operator, address token0, address token1, int24 tickLower, int24 tickUpper, uint128 liquidity, uint256 feeGrowthInside0LastX128, uint256 feeGrowthInside1LastX128, uint128 tokensOwed0 uint128 tokensOwed1);`

Returns the position information associated with a given token ID. Throws if the token ID is not valid.

Params

* `tokenId` The ID of the token that represents the position

Returns

* `nonce` The nonce for permits
* `operator` The address that is approved for spending
* `token0` The address of the token0 for a specific pool
* `token1` The address of the token1 for a specific pool
* `tickLower` The lower end of the tick range for the position
* `tickUpper` The higher end of the tick range for the position
* `liquidity` The liquidity of the position
* `feeGrowthInside0LastX128` The fee growth of token0 as of the last action on the individual position
* `feeGrowthInside1LastX128` The fee growth of token1 as of the last action on the individual position
* `tokensOwed0` The uncollected amount of token0 owed to the position as of the last computation
* `tokensOwed1` The uncollected amount of token1 owed to the position as of the last computation

## State-Changing Functions <a href="#state-changing-functions" id="state-changing-functions"></a>

### mint <a href="#mint" id="mint"></a>

`struct MintParams {address token0;address token1;int24 tickLower;int24 tickUpper;uint256 amount0Desired;uint256 amount1Desired;uint256 amount0Min;uint256 amount1Min;address recipient;uint256 deadline;}function mint(MintParams calldata params) external payable override checkDeadline(params.deadline) returns (uint256 tokenId, uint128 liquidity, uint256 amount0, uint256 amount1)`

Creates a new position wrapped in a NFT. Call this when the pool does exist and is initialised. Note that if the pool is created but not initialised a method does not exist, i.e. the pool is assumed to be initialised.

Params

* `params` The params necessary to mint a position, encoded as `MintParams` in calldata

Returns

* `tokenId` The ID of the token that represents the minted position
* `liquidity` The amount of liquidity for this position
* `amount0` The amount of token0
* `amount1` The amount of token1
* Emits [IncreaseLiquidity](https://docs.quickswap.exchange/reference/smart-contracts/v3/position-manager#increaseliquidity).

### increaseLiquidity <a href="#increaseliquidity-1" id="increaseliquidity-1"></a>

`struct IncreaseLiquidityParams {uint256 tokenId;uint256 amount0Desired;uint256 amount1Desired;uint256 amount0Min;uint256 amount1Min;uint256 deadline;}function increaseLiquidity(IncreaseLiquidityParams calldata params) external payable override checkDeadline(params.deadline) returns (uint128 liquidity, uint256 amount0, uint256 amount1)`

Increases the amount of liquidity in a position, with tokens paid by the `msg.sender`

Params

* `tokenId` The ID of the token for which liquidity is being increased
* `amount0Desired` The desired amount of token0 to be spent
* `amount1Desired` The desired amount of token1 to be spent
* `amount0Min` The minimum amount of token0 to spend, which serves as a slippage check,
* `amount1Min` The minimum amount of token1 to spend, which serves as a slippage check,
* `deadline` The time by which the transaction must be included to effect the change

Returns

* `liquidity` The new liquidity amount as a result of the increase
* `amount0` The amount of token0 to achieve resulting liquidity
* `amount1` The amount of token1 to achieve resulting liquidity
* Emits [IncreaseLiquidity](https://docs.quickswap.exchange/reference/smart-contracts/v3/position-manager#increaseliquidity).

### decreaseLiquidity <a href="#decreaseliquidity-1" id="decreaseliquidity-1"></a>

`struct DecreaseLiquidityParams {uint256 tokenId;uint128 liquidity;uint256 amount0Min;uint256 amount1Min;uint256 deadline;}function decreaseLiquidity(DecreaseLiquidityParams calldata params) external payable override isAuthorizedForToken(params.tokenId) checkDeadline(params.deadline) returns (uint256 amount0, uint256 amount1)`

Remove the amount of liquidity in a position and accounts it to the position

Params

* `tokenId` The ID of the token for which liquidity is being decreased
* `liquidity` The amount by which liquidity will be decreased
* `amount0Min` The minimum amount of token0 that should be accounted for the burned liquidity
* `amount1Min` The minimum amount of token1 that should be accounted for the burned liquidity
* `deadline` The time by which the transaction must be included to effect the change

Returns

* `amount0` The amount of token0 accounted to the position's tokens owed
* `amount1` The amount of token1 accounted to the position's tokens owed
* Emits [DecreaseLiquidity](https://docs.quickswap.exchange/reference/smart-contracts/v3/position-manager#decreaseliquidity).

### collect <a href="#collect-1" id="collect-1"></a>

`struct CollectParams {uint256 tokenId;address recipient;uint128 amount0Max;uint128 amount1Max;}function collect(CollectParams calldata params) external payable override isAuthorizedForToken(params.tokenId) returns (uint256 amount0, uint256 amount1)`

Collects up to a maximum amount of fees owed to a specific position to the recipient

Params

* `tokenId` The ID of the NFT for which tokens are being collected
* `recipient` The account that should receive the tokens
* `amount0Max` The maximum amount of token0 to collect
* `amount1Max` The maximum amount of token1 to collect

Returns

* `amount0` The amount of fees collected in token0
* `amount1` The amount of fees collected in token1
* Emits [Collect](https://docs.quickswap.exchange/reference/smart-contracts/v3/position-manager#collect).

### burn <a href="#burn" id="burn"></a>

`function burn(uint256 tokenId) external payable;`

Burns a token ID, which deletes it from the NFT contract. The token must have 0 liquidity and all tokens must be collected first.

* `tokenId` The ID of the token that is being burned

## Interface <a href="#interface" id="interface"></a>

```
pragma solidity >=0.5.0;

interface INonfungiblePositionManager is
    IPoolInitializer,
    IPeripheryPayments,
    IPeripheryImmutableState,
    IERC721Metadata,
    IERC721Enumerable,
    IERC721Permit
{
    event IncreaseLiquidity(
        uint256 indexed tokenId,
        uint128 liquidity,
        uint128 actualLiquidity,
        uint256 amount0,
        uint256 amount1,
        address pool
    );
    event DecreaseLiquidity(uint256 indexed tokenId, uint128 liquidity, uint256 amount0, uint256 amount1);
    
    event Collect(uint256 indexed tokenId, address recipient, uint256 amount0, uint256 amount1);

    function positions(uint256 tokenId)
        external
        view
        returns (
            uint96 nonce,
            address operator,
            address token0,
            address token1,
            int24 tickLower,
            int24 tickUpper,
            uint128 liquidity,
            uint256 feeGrowthInside0LastX128,
            uint256 feeGrowthInside1LastX128,
            uint128 tokensOwed0,
            uint128 tokensOwed1
        );

    struct MintParams {
        address token0;
        address token1;
        int24 tickLower;
        int24 tickUpper;
        uint256 amount0Desired;
        uint256 amount1Desired;
        uint256 amount0Min;
        uint256 amount1Min;
        address recipient;
        uint256 deadline;
    }

    function mint(MintParams calldata params)
        external
        payable
        returns (
            uint256 tokenId,
            uint128 liquidity,
            uint256 amount0,
            uint256 amount1
        );

    struct IncreaseLiquidityParams {
        uint256 tokenId;
        uint256 amount0Desired;
        uint256 amount1Desired;
        uint256 amount0Min;
        uint256 amount1Min;
        uint256 deadline;
    }

    function increaseLiquidity(IncreaseLiquidityParams calldata params)
        external
        payable
        returns (
            uint128 liquidity,
            uint256 amount0,
            uint256 amount1
        );

    struct DecreaseLiquidityParams {
        uint256 tokenId;
        uint128 liquidity;
        uint256 amount0Min;
        uint256 amount1Min;
        uint256 deadline;
    }

    function decreaseLiquidity(DecreaseLiquidityParams calldata params)
        external
        payable
        returns (uint256 amount0, uint256 amount1);

    struct CollectParams {
        uint256 tokenId;
        address recipient;
        uint128 amount0Max;
        uint128 amount1Max;
    }

    function collect(CollectParams calldata params) external payable returns (uint256 amount0, uint256 amount1);

    /// @notice Burns a token ID, which deletes it from the NFT contract. The token must have 0 liquidity and all tokens
    /// must be collected first.
    /// @param tokenId The ID of the token that is being burned
    function burn(uint256 tokenId) external payable;
}
```


# Factory

## Factory

### Code <a href="#code" id="code"></a>

[`AlgebraFactory.sol`](https://polygonscan.com/address/0x411b0fAcC3489691f28ad58c47006AF5E3Ab3A28)

### Address <a href="#address" id="address"></a>

`AlgebraFactory` is deployed at `0x411b0fAcC3489691f28ad58c47006AF5E3Ab3A28` on the Polygon [mainnet](https://polygonscan.com/address/0x411b0fAcC3489691f28ad58c47006AF5E3Ab3A28).

## Events <a href="#events" id="events"></a>

### Owner[#](https://docs.quickswap.exchange/reference/smart-contracts/v3/01-factory#owner) <a href="#owner" id="owner"></a>

`event Owner(address indexed newOwner);`

Emitted when the owner of the factory is changed

* `newOwner` The owner after the owner was changed

### VaultAddress <a href="#vaultaddress" id="vaultaddress"></a>

`event VaultAddress(address indexed newVaultAddress);`

Emitted when the vault address is changed

* `newVaultAddress` The vault address after the address was changed

### Pool <a href="#pool" id="pool"></a>

`event Pool(address indexed token0, address indexed token1, address pool);`

Emitted when a pool is created

* `token0` The first token of the pool by address sort order
* `token1` The second token of the pool by address sort order
* `pool` The address of the created pool

### FarmingAddress <a href="#farmingaddress" id="farmingaddress"></a>

`event FarmingAddress(address indexed newFarmingAddress);`

Emitted when the farming address is changed

* `newFarmingAddress` The farming address after the address was changed

### FeeConfiguration <a href="#feeconfiguration" id="feeconfiguration"></a>

`event FeeConfiguration(uint16 alpha1, uint16 alpha2, uint32 beta1, uint32 beta2, uint16 gamma1, uint16 gamma2, uint32 volumeBeta, uint16 volumeGamma, uint16 baseFee);`

Emitted when the farming address is changed

* `newFarmingAddress` The farming address after the address was changed

## Read-Only Functions[#](https://docs.quickswap.exchange/reference/smart-contracts/v3/01-factory#read-only-functions) <a href="#read-only-functions" id="read-only-functions"></a>

### owner[#](https://docs.quickswap.exchange/reference/smart-contracts/v3/01-factory#owner-1) <a href="#owner-1" id="owner-1"></a>

`function owner() external view returns (address);`

Returns the address of the current factory owner. Can be changed by the current owner via setOwner

### poolDeployer <a href="#pooldeployer" id="pooldeployer"></a>

`function poolDeployer() external view returns (address);`

Returns the address of the poolDeployer

### farmingAddress <a href="#farmingaddress-1" id="farmingaddress-1"></a>

`function farmingAddress() external view returns (address);`

Is retrieved from the pools to restrict calling certain functions not by a tokenomics contract Returns the tokenomics contract address

### vaultAddress <a href="#vaultaddress-1" id="vaultaddress-1"></a>

`function vaultAddress() external view returns (address);`

### poolByPair <a href="#poolbypair" id="poolbypair"></a>

`function poolByPair(address tokenA, address tokenB) external view returns (address pool);`

Returns the pool address for a given pair of tokens and a fee, or address 0 if it does not exist. tokenA and tokenB may be passed in either token0/token1 or token1/token0 order

Params

* `tokenA` The contract address of either token0 or token1
* `tokenB` The contract address of the other token

Returns

* `pool` The pool address

## State-Changing Functions <a href="#state-changing-functions" id="state-changing-functions"></a>

### createPool <a href="#createpool" id="createpool"></a>

`function createPool(address tokenA, address tokenB) external returns (address pool);`

Creates a pool for the given two tokens and fee. tokenA and tokenB may be passed in either order: token0/token1 or token1/token0. tickSpacing is retrieved from the fee. The call will revert if the pool already exists, the fee is invalid, or the token arguments are invalid.

Params

* `tokenA` One of the two tokens in the desired pool
* `tokenB` The other of the two tokens in the desired pool

Returns

* `pool` The address of the newly created pool

### setOwner <a href="#setowner" id="setowner"></a>

`function setOwner(address _owner) external;`

Updates the owner of the factory. Must be called by the current owner

Params

* `_owner` The new owner of the factory

### setFarmingAddress <a href="#setfarmingaddress" id="setfarmingaddress"></a>

f`unction setFarmingAddress(address _farmingAddress) external;`

Updates tokenomics address on the factory

Params

* `_farmingAddress` The new tokenomics contract address

### setVaultAddress <a href="#setvaultaddress" id="setvaultaddress"></a>

`function setVaultAddress(address _vaultAddress) external;`

Updates vault address on the factory

Params

* `_vaultAddress` The new vault contract address

### setBaseFeeConfiguration <a href="#setbasefeeconfiguration" id="setbasefeeconfiguration"></a>

`function setBaseFeeConfiguration(uint16 alpha1, uint16 alpha2, uint32 beta1, uint32 beta2, uint16 gamma1, uint16 gamma2, uint32 volumeBeta, uint16 volumeGamma, uint16 baseFee) external;`

Changes initial fee configuration for new pools. Changes coefficients for sigmoids: α / (1 + e^( (β-x) / γ)) alpha1 + alpha2 + baseFee (max possible fee) must be <= type(uint16).max, gammas must be > 0

Params

* `alpha1` max value of the first sigmoid
* `alpha2` max value of the second sigmoid
* `beta1` shift along the x-axis for the first sigmoid
* `beta2` shift along the x-axis for the second sigmoid
* `gamma1` horizontal stretch factor for the first sigmoid
* `gamma2` horizontal stretch factor for the second sigmoid
* `volumeBeta` shift along the x-axis for the outer volume-sigmoid
* `volumeGamma` horizontal stretch factor the outer volume-sigmoid
* `baseFee` minimum possible fee


# Pool Deployer


# Quoter


# V3 Migrator


# Farming Center


# Limit Farming


# Pool


# Audits


# SDK


# Getting Started

The pages that follow contain technical reference information on the Uniswap SDK. Looking for a quickstart instead? You may also want to jump into a guide, which offers a friendlier introduction to the SDK!

The SDK is written in TypeScript, has a robust test suite, performs arbitrary precision arithmetic, and supports rounding to significant digits or fixed decimal places. The principal exports of the SDK are *entities*: classes that contain initialisation and validation checks, necessary data fields, and helper functions.

An important concept in the SDK is *fractions*. Because Solidity performs integer math, care must be taken in non-EVM environments to faithfully replicate the actual computation carried out on-chain. The first concern here is to ensure that an overflow-safe integer implementation is used. Ideally, the SDK would be able to use native [BigInt](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt)s. However, until support becomes more widespread, [JSBI](https://github.com/GoogleChromeLabs/jsbi) objects are used instead, with the idea that once BigInts proliferate, this dependency can be compiled away. The second concern is precision loss due to, for example, chained price ratio calculations. To address this issue, all math operations are performed as fraction operations, ensuring arbitrary precision up until the point that values are rounded for display purposes, or truncated to fit inside a fixed bit width.

The SDK works for all chains on which the factory is deployed.

### Code

The [source code is available on GitHub](https://github.com/Uniswap/uniswap-sdk).

### Dependencies

The SDK declares its dependencies as [peer dependencies](https://github.com/Uniswap/uniswap-sdk/blob/v2/package.json#L33). This is for two reasons:

* prevent installation of unused dependencies (e.g. `@ethersproject/providers` and `@ethersproject/contracts`, only used in `Fetcher`)
* prevent duplicate `@ethersproject` dependencies with conflicting versions

However, this means you must install these dependencies alongside the SDK, if you do not already have them installed.


# Token

```typescript
constructor(chainId: ChainId, address: string, decimals: number, symbol?: string, name?: string)
```

The Token entity represents an ERC-20 token at a specific address on a specific chain.

## Example

```typescript
import { ChainId, Token } from '@uniswap/sdk'

const token = new Token(ChainId.MAINNET, '0xc0FFee0000000000000000000000000000000000', 18, 'HOT', 'Caffeine')
```

## Properties

### chainId

```typescript
chainId: ChainId
```

See ChainId.

### address

```typescript
address: string
```

### decimals

```typescript
decimals: number
```

### symbol

```typescript
symbol?: string
```

### name

```typescript
name?: string
```

## Methods

### equals

```typescript
equals(other: Token): boolean
```

Checks if the current instance is equal to another (has an identical chainId and address).

### sortsBefore

```typescript
sortsBefore(other: Token): boolean
```

Checks if the current instance sorts before another, by address.


# Pair

```typescript
constructor(tokenAmountA: TokenAmount, tokenAmountB: TokenAmount)
```

The Pair entity represents a Uniswap pair with a balance of each of its pair tokens.

## Example

```typescript
import { ChainId, Token, TokenAmount, Pair } from '@uniswap/sdk'

const HOT = new Token(ChainId.MAINNET, '0xc0FFee0000000000000000000000000000000000', 18, 'HOT', 'Caffeine')
const NOT = new Token(ChainId.MAINNET, '0xDeCAf00000000000000000000000000000000000', 18, 'NOT', 'Caffeine')

const pair = new Pair(new TokenAmount(HOT, '2000000000000000000'), new TokenAmount(NOT, '1000000000000000000'))
```

## Static Methods

### getAddress

```typescript
getAddress(tokenA: Token, tokenB: Token): string
```

Computes the pair address for the passed Tokens. See Pair Addresses.

## Properties

### liquidityToken

```typescript
liquidityToken: Token
```

A Token representing the liquidity token for the pair. See Pair (ERC-20).

### token0

```typescript
token0: Token
```

See .

### token1

```typescript
token1: Token
```

See .

### reserve0

```typescript
reserve0: TokenAmount
```

The reserve of token0.

### reserve1

```typescript
reserve1: TokenAmount
```

The reserve of token1.

## Methods

### reserveOf

```typescript
reserveOf(token: Token): TokenAmount
```

Returns reserve0 or reserve1, depending on whether token0 or token1 is passed in.

### getOutputAmount

```typescript
getOutputAmount(inputAmount: TokenAmount): [TokenAmount, Pair]
```

Pricing function for exact input amounts. Returns maximum output amount based on current reserves and the new Pair that would exist if the trade were executed.

### getInputAmount

```typescript
getInputAmount(outputAmount: TokenAmount): [TokenAmount, Pair]
```

Pricing function for exact output amounts. Returns minimum input amount based on current reserves and the new Pair that would exist if the trade were executed.

### getLiquidityMinted

```typescript
getLiquidityMinted(totalSupply: TokenAmount, tokenAmountA: TokenAmount, tokenAmountB: TokenAmount): TokenAmount
```

Calculates the exact amount of liquidity tokens minted from a given amount of token0 and token1.

* totalSupply must be looked up on-chain.
* The value returned from this function *cannot* be used as an input to getLiquidityValue.

### getLiquidityValue

```typescript
getLiquidityValue(
  token: Token,
  totalSupply: TokenAmount,
  liquidity: TokenAmount,
  feeOn: boolean = false,
  kLast?: BigintIsh
): TokenAmount
```

Calculates the exact amount of token0 or token1 that the given amount of liquidity tokens represent.

* totalSupply must be looked up on-chain.
* If the protocol charge is on, feeOn must be set to true, and kLast must be provided from an on-chain lookup.
* Values returned from this function *cannot* be used as inputs to getLiquidityMinted.


# Route

```typescript
constructor(pairs: Pair[], input: Token)
```

The Route entity represents one or more ordered Uniswap pairs with a fully specified path from input token to output token.

## Example

```typescript
import { ChainId, Token, TokenAmount, Pair, Route } from '@uniswap/sdk'

const HOT = new Token(ChainId.MAINNET, '0xc0FFee0000000000000000000000000000000000', 18, 'HOT', 'Caffeine')
const NOT = new Token(ChainId.MAINNET, '0xDeCAf00000000000000000000000000000000000', 18, 'NOT', 'Caffeine')
const HOT_NOT = new Pair(new TokenAmount(HOT, '2000000000000000000'), new TokenAmount(NOT, '1000000000000000000'))

const route = new Route([HOT_NOT], NOT)
```

## Properties

### pairs

```typescript
pairs: Pair[]
```

The ordered pairs that the route is comprised of.

### path

```typescript
path: Token[]
```

The full path from input token to output token.

### input

```typescript
input: string
```

The input token.

### output

```typescript
output: string
```

The output token.

### midPrice

```typescript
midPrice: Price
```

Returns the current mid price along the route.


# Trade

```typescript
constructor(route: Route, amount: TokenAmount, tradeType: TradeType)
```

The Trade entity represents a fully specified trade along a route. This entity supplies all the information necessary to craft a router transaction.

## Example

```typescript
import { ChainId, Token, TokenAmount, Pair, TradeType, Route } from '@uniswap/sdk'

const HOT = new Token(ChainId.MAINNET, '0xc0FFee0000000000000000000000000000000000', 18, 'HOT', 'Caffeine')
const NOT = new Token(ChainId.MAINNET, '0xDeCAf00000000000000000000000000000000000', 18, 'NOT', 'Caffeine')
const HOT_NOT = new Pair(new TokenAmount(HOT, '2000000000000000000'), new TokenAmount(NOT, '1000000000000000000'))
const NOT_TO_HOT = new Route([HOT_NOT], NOT)

const trade = new Trade(NOT_TO_HOT, new TokenAmount(NOT, '1000000000000000'), TradeType.EXACT_INPUT)
```

## Properties

### route

```typescript
route: Route
```

The path property of the route should be passed as the path parameter to router functions.

### tradeType

```typescript
tradeType: TradeType
```

`TradeType.EXACT_INPUT` corresponds to `swapExact*For*` router functions. `TradeType.EXACT_OUTPUT` corresponds to `swap*ForExact*` router functions.

### inputAmount

```typescript
inputAmount: TokenAmount
```

For exact input trades, this value should be passed as amountIn to router functions. For exact output trades, this value should be multiplied by a factor >1, representing slippage tolerance, and passed as amountInMax to router functions.

### outputAmount

```typescript
outputAmount: TokenAmount
```

For exact output trades, this value should be passed as amountOut to router functions. For exact input trades, this value should be multiplied by a factor <1, representing slippage tolerance, and passed as amountOutMin to router functions.

### executionPrice

```typescript
executionPrice: Price
```

The average price that the trade would execute at.

### nextMidPrice

```typescript
nextMidPrice: Price
```

What the new mid price would be if the trade were to execute.

### slippage

```typescript
slippage: Percent
```

The slippage incurred by the trade.

* Strictly > .30%.

## Methods

In the context of the following two methods, slippage refers to the percent difference between the actual price and the trade `executionPrice`.

### minimumAmountOut (since 2.0.4)

```typescript
minimumAmountOut(slippageTolerance: Percent): TokenAmount
```

Returns the minimum amount of the output token that should be received from a trade, given the slippage tolerance.

Useful when constructing a transaction for a trade of type `EXACT_IN`.

### maximumAmountIn (since 2.0.4)

```typescript
maximumAmountIn(slippageTolerance: Percent): TokenAmount
```

Returns the maximum amount of the input token that should be spent on the trade, given the slippage tolerance.

Useful when constructing a transaction for a trade of type `EXACT_OUT`.

## Static methods

These static methods provide ways to construct ideal trades from lists of pairs. Note these methods do not perform any aggregation across routes, as routes are linear. It's possible that a better price can be had by combining multiple trades across different routes.

### bestTradeExactIn

Given a list of pairs, a fixed amount in, and token amount out, this method returns the best `maxNumResults` trades that swap an input token amount to an output token, making at most `maxHops` hops. The returned trades are sorted by output amount, in decreasing order, and all share the given input amount.

```typescript
Trade.bestTradeExactIn(
    pairs: Pair[],
    amountIn: TokenAmount,
    tokenOut: Token,
    { maxNumResults = 3, maxHops = 3 }: BestTradeOptions = {}): Trade[]
```

### bestTradeExactOut

Similar to the above method, but targets a fixed output token amount. The returned trades are sorted by input amount, in increasing order, and all share the given output amount.

```typescript
Trade.bestTradeExactOut(
    pairs: Pair[],
    tokenIn: Token,
    amountOut: TokenAmount,
    { maxNumResults = 3, maxHops = 3 }: BestTradeOptions = {}): Trade[]
```


# Fractions

## Fraction

```typescript
constructor(numerator: BigintIsh, denominator: BigintIsh = ONE)
```

The base class which all subsequent fraction classes extend. **Not meant to be used directly.**

### Properties

#### numerator

```typescript
numerator: JSBI
```

#### denominator

```typescript
denominator: JSBI
```

#### quotient

```typescript
quotient: JSBI
```

Performs floor division.

### Methods

#### invert

```typescript
invert(): Fraction
```

#### add

```typescript
add(other: Fraction | BigintIsh): Fraction
```

#### subtract

```typescript
subtract(other: Fraction | BigintIsh): Fraction
```

#### multiply

```typescript
multiply(other: Fraction | BigintIsh): Fraction
```

#### divide

```typescript
divide(other: Fraction | BigintIsh): Fraction
```

#### toSignificant

```typescript
toSignificant(
  significantDigits: number,
  format: object = { groupSeparator: '' },
  rounding: Rounding = Rounding.ROUND_HALF_UP
): string
```

Formats a fraction to the specified number of significant digits.

* For format options, see [toFormat](https://github.com/MikeMcl/toFormat).

#### toFixed

```typescript
toFixed(
  decimalPlaces: number,
  format: object = { groupSeparator: '' },
  rounding: Rounding = Rounding.ROUND_HALF_UP
): string
```

Formats a fraction to the specified number of decimal places.

* For format options, see [toFormat](https://github.com/MikeMcl/toFormat).

## Percent

Responsible for formatting percentages (10% instead of 0.1).

### Example

```typescript
import { Percent } from '@uniswap/sdk'

const percent = new Percent('60', '100')
console.log(percent.toSignificant(2)) // 60
```

#### toSignificant

See [toSignificant](broken://pages/VgTqcwQGOrcWZUO7rRzr).

#### toFixed

See [toFixed](broken://pages/VgTqcwQGOrcWZUO7rRzr).

## TokenAmount

```typescript
constructor(token: Token, amount: BigintIsh)
```

Responsible for formatting token amounts with specific decimal places.

### Example

```typescript
import { Token, TokenAmount } from '@uniswap/sdk'

const FRIED = new Token(ChainId.MAINNET, '0xfa1aFe1000000000000000000000000000000000', 18, 'FRIED', 'Beans')

const tokenAmount = new TokenAmount(FRIED, '3000000000000000000')
console.log(tokenAmount.toExact()) // 3
```

### Properties

#### token

```typescript
token: Token
```

#### raw

```typescript
raw: JSBI
```

Returns the full token amount, unadjusted for decimals.

### Methods

#### add

```typescript
add(other: TokenAmount): TokenAmount
```

#### subtract

```typescript
subtract(other: TokenAmount): TokenAmount
```

#### toSignificant

See [toSignificant](broken://pages/VgTqcwQGOrcWZUO7rRzr).

#### toFixed

See [toFixed](broken://pages/VgTqcwQGOrcWZUO7rRzr).

#### toExact

```typescript
toExact(format: object = { groupSeparator: '' }): string
```

## Price

```typescript
constructor(baseToken: Token, quoteToken: Token, denominator: BigintIsh, numerator: BigintIsh)
```

Responsible for denominating the relative price between two tokens. Denominator and numerator must be unadjusted for decimals.

### Example

```typescript
import { ChainId, WETH as WETHs, Token, Price } from '@uniswap/sdk'

const WETH = WETHs[ChainId.MAINNET]
const ABC = new Token(ChainId.MAINNET, '0xabc0000000000000000000000000000000000000', 18, 'ABC')

const price = new Price(WETH, ABC, '1000000000000000000', '123000000000000000000')
console.log(price.toSignificant(3)) // 123
```

This example shows the ETH/XYZ price, where ETH is the base token, and XYZ is the quote token. The price is constructed from an amount of XYZ (the numerator) / an amount of WETH (the denominator).

### Static Methods

#### fromRoute

```typescript
fromRoute(route: Route): Price
```

### Properties

#### baseToken

```typescript
baseToken: Token
```

#### quoteToken

```typescript
quoteToken: Token
```

#### scalar

```typescript
scalar: Fraction
```

Used to adjust the price for the decimals of the base and quote tokens.

#### raw

```typescript
raw: Fraction
```

Returns the raw price, unadjusted for decimals.

#### adjusted

```typescript
adjusted: Fraction
```

Returns the price, adjusted for decimals.

### Methods

#### invert

```typescript
invert(): Price
```

#### multiply

```typescript
multiply(other: Price): Price
```

#### quote

```typescript
quote(tokenAmount: TokenAmount): TokenAmount
```

Given an asset amount, returns an equivalent value of the other asset, according to the current price.

#### toSignificant

See [toSignificant](broken://pages/VgTqcwQGOrcWZUO7rRzr).

#### toFixed

See [toFixed](broken://pages/VgTqcwQGOrcWZUO7rRzr).


# Fetcher

The data fetching logic is split from the rest of the code for better tree-shaking, i.e. so that it does not get packaged into your code unless it is used. The SDK is otherwise unconcerned with how you get data from the blockchain.

This class contains static methods for constructing instances of pairs and tokens from on-chain data. It cannot be constructed.

## Static Methods

### fetchTokenData

```typescript
async fetchTokenData(
  chainId: ChainId,
  address: string,
  provider = getDefaultProvider(getNetwork(chainId)),
  symbol?: string,
  name?: string
): Promise<Token>
```

Initialises a class instance from a chainId and token address, if the decimals of the token are unknown and cannot be fetched externally. Decimals are fetched via an [ethers.js](https://github.com/ethers-io/ethers.js/) v5 provider. If not passed in, a default provider is used.

### fetchPairData

```typescript
async fetchPairData(
  tokenA: Token,
  tokenB: Token,
  provider = getDefaultProvider(getNetwork(tokenA.chainId))
): Promise<Pair>
```

Initializes a class instance from two Tokens, if the pair's balances of these tokens are unknown and cannot be fetched externally. Pair reserves are fetched via an [ethers.js](https://github.com/ethers-io/ethers.js/) v5 provider. If not passed in, a default provider is used.


# Other Exports

## JSBI

```typescript
import { JSBI } from '@uniswap/sdk'
// import JSBI from 'jsbi'
```

The default export from [jsbi](https://github.com/GoogleChromeLabs/jsbi).

## BigintIsh

```typescript
import { BigintIsh } from '@uniswap/sdk'
// type BigintIsh = JSBI | bigint | string
```

A union type comprised of all types that can be cast to a JSBI instance.

## ChainId

```typescript
import { ChainId } from '@uniswap/sdk'
// enum ChainId {
//   MAINNET = 1,
//   ROPSTEN = 3,
//   RINKEBY = 4,
//   GÖRLI = 5,
//   KOVAN = 42
// }
```

A enum denominating supported chain IDs.

## TradeType

```typescript
import { TradeType } from '@uniswap/sdk'
// enum TradeType {
//   EXACT_INPUT,
//   EXACT_OUTPUT
// }
```

A enum denominating supported trade types.

## Rounding

```typescript
import { Rounding } from '@uniswap/sdk'
// enum Rounding {
//   ROUND_DOWN,
//   ROUND_HALF_UP,
//   ROUND_UP
// }
```

A enum denominating supported rounding options.

## FACTORY\_ADDRESS

```typescript
import { FACTORY_ADDRESS } from '@uniswap/sdk'
```

The factory address.

## INIT\_CODE\_HASH

```typescript
import { INIT_CODE_HASH } from '@uniswap/sdk'
```

See Pair Addresses.

## MINIMUM\_LIQUIDITY

```typescript
import { MINIMUM_LIQUIDITY } from '@uniswap/sdk'
```

See Minimum Liquidity.

## InsufficientReservesError

```typescript
import { InsufficientReservesError } from '@uniswap/sdk'
```

## InsufficientInputAmountError

```typescript
import { InsufficientInputAmountError } from '@uniswap/sdk'
```

## WETH

```typescript
import { WETH } from '@uniswap/sdk'
```

An object whose values are WETH Token instances, indexed by [ChainId](broken://pages/cJ6SqfbzDOQAiVJdED6F).


# Guides


# Interface Integration


# Using the API

In this guide we will create a web interface that consumes and displays data from the Uniswap Subgraph. The goal is to provide a quick overview of a setup that you can extend to create your own UIs and analytics around Uniswap data.

Many different libraries can be used to create an interface and a connection to the subgraph graphql endpoint, but in this guide we will use [React](https://reactjs.org/) for the interface, and [Apollo Client](https://www.apollographql.com/docs/react/) for sending queries. We'll also be using yarn for dependency management.

#### Setup and Installs

We'll need to create the basic skeleton for the application. We'll use [create-react-app](https://reactjs.org/docs/create-a-new-react-app.html) for this. We'll also add the dependencies we need. Navigate to your root location in your command line and run:

```javascript
yarn create react-app uniswap-demo
cd uniswap-demo
yarn add  apollo-client apollo-cache-inmemory apollo-link-http graphql graphql-tag @apollo/react-hooks
yarn start
```

In your browser you should see the default React app running. In a text editor open `App.js` within `src` and replace the contents with this stripped down boilerplate. We'll add to this as we go.

```javascript
import React from 'react'
import './App.css'

function App() {
  return <div></div>
}

export default App
```

#### Graphql Client

We need to set up some middleware in order to make requests to the Uniswap subgraph and receive data. To do this we'll use Apollo and create a graphql client to handle this.

1. Add the imports shown below and instantiate a new client instance. Notice how we use the link to the Uniswap subgraph here.

```javascript
import React from "react"
import "./App.css"
import { ApolloClient } from "apollo-client"
import { InMemoryCache } from "apollo-cache-inmemory"
import { HttpLink } from "apollo-link-http"

export const client = new ApolloClient({
 link: new HttpLink({
   uri: "https://api.thegraph.com/subgraphs/name/uniswap/uniswap-v2"
 }),
 cache: new InMemoryCache(),
})

function App() {
 return <div></div>
}

export default App

```

2. We also need to add a context so that Apollo can handle requests properly. In your `index.js` file import the proper provider and wrap the root in it like this:

```javascript
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
import registerServiceWorker from './registerServiceWorker'
import './index.css'
import { ApolloProvider } from 'react-apollo'
import { client } from './App'

ReactDOM.render(
  <ApolloProvider client={client}>
    <App />
  </ApolloProvider>,
  document.getElementById('root')
)
registerServiceWorker()
```

#### Writing the queries

Next we'll construct our query and fetch data. For this example we will fetch some data about the Dai token on Uniswap V2. We'll get the current price, and total liquidity across all pairs. We'll be using the Dai address as an id in this query. We'll also fetch the USD price of ETH to help create USD conversion for Dai data.

1. First we need to define the query itself. We'll use `gql` to parse a query string into the GraphQL AST standard. Import the `gql` helper into the app and use it to create the query. Add the following to your `App.js` file:

```javascript
import gql from 'graphql-tag'

const DAI_QUERY = gql`
  query tokens($tokenAddress: Bytes!) {
    tokens(where: { id: $tokenAddress }) {
      derivedETH
      totalLiquidity
    }
  }
`

const ETH_PRICE_QUERY = gql`
  query ethPrice {
    bundle(id: "1") {
      ethPrice
    }
  }
`
```

We use an id of `1` for the bundle because there is only one hardcoded bundle in the subgraph.

#### Fetch data

Now we're ready to use these queries to fetch data from the Uniswap V2 subgraph. To do this we can use the `useQuery` hook which uses our client instance to fetch data, and gives us live info about the status of the request. To do this add the following to your `App.js` file:

```javascript
import { useQuery } from '@apollo/react-hooks'

const { loading, error, data: ethPriceData } = useQuery(ETH_PRICE_QUERY)
const { loading: daiLoading, error: daiError, data: daiData } = useQuery(DAI_QUERY, {
  variables: {
    tokenAddress: '0x6b175474e89094c44da98b954eedeac495271d0f'
  }
})
```

Notice we're using the Dai token address to fetch data about Dai.

#### Formatting Response

Now that we have our data we can format it and display it in the UI. First, we parse the return data to get the actual data that we want. Then we'll use it to get the USD price of Dai. Lastly we'll insert this data into the UI itself.

These queries will return an response object for each query. Within each one we're interested in the root field we defined in the query definition. For the `daiData` response we defined this as `tokens`, and for the `ethPriceData` query we defined this as `ethPrice`. Within each one we'll get an array of results. Because we're only querying for single entities we'll reference the `0` index in the data array.

Add the following lines to your `App.js` file to parse the responses:

```javascript
const daiPriceInEth = daiData && daiData.tokens[0].derivedETH
const daiTotalLiquidity = daiData && daiData.tokens[0].totalLiquidity
const ethPriceInUSD = ethPriceData && ethPriceData.bundles[0].ethPrice
```

#### Displaying in the UI

Finally we can use our parsed response data to hydrate the UI. We'll do this in two steps.

1. First we'll create loading states. To detect if a query is still pending a response we can reference the loading variables we've already defined. We'll add two loading states, one for the Dai price, and one for the Dai total liquidity. These may flicker fast because the time to query is fast.
2. Populate with loaded data. Once we detect that the queries have finished loading we can populate the UI with the real data.

To do this add the following lines in the return function of your `App.js` file:

```javascript
return (
  <div>
    <div>
      Dai price:{' '}
      {ethLoading || daiLoading
        ? 'Loading token data...'
        : '$' +
          // parse responses as floats and fix to 2 decimals
          (parseFloat(daiPriceInEth) * parseFloat(ethPriceInUSD)).toFixed(2)}
    </div>
    <div>
      Dai total liquidity:{' '}
      {daiLoading
        ? 'Loading token data...'
        : // display the total amount of DAI spread across all pools
          parseFloat(daiTotalLiquidity).toFixed(0)}
    </div>
  </div>
)
```

#### Next steps

This should render a very basic page with these two stats about the Dai token within Uniswap. This is a very basic example of what you can do with the Uniswap subgraph and we encourage you to build out more complex and interesting tools!

You can visit our [analytics site](https://uniswap.info/) to see a more advanced analytics page, or visit [the github](https://github.com/Uniswap/uniswap-info) for more detailed examples of using the Uniswap subgraph to create UIs.

#### Review

In the end your `App.js` file should look like this:

```javascript
import React, { useEffect } from 'react'
import './App.css'
import { ApolloClient } from 'apollo-client'
import { InMemoryCache } from 'apollo-cache-inmemory'
import { HttpLink } from 'apollo-link-http'
import { useQuery } from '@apollo/react-hooks'
import gql from 'graphql-tag'

export const client = new ApolloClient({
  link: new HttpLink({
    uri: 'https://api.thegraph.com/subgraphs/name/uniswap/uniswap-v2'
  }),
  fetchOptions: {
    mode: 'no-cors'
  },
  cache: new InMemoryCache()
})

const DAI_QUERY = gql`
  query tokens($tokenAddress: Bytes!) {
    tokens(where: { id: $tokenAddress }) {
      derivedETH
      totalLiquidity
    }
  }
`

const ETH_PRICE_QUERY = gql`
  query bundles {
    bundles(where: { id: "1" }) {
      ethPrice
    }
  }
`

function App() {
  const { loading: ethLoading, data: ethPriceData } = useQuery(ETH_PRICE_QUERY)
  const { loading: daiLoading, data: daiData } = useQuery(DAI_QUERY, {
    variables: {
      tokenAddress: '0x6b175474e89094c44da98b954eedeac495271d0f'
    }
  })

  const daiPriceInEth = daiData && daiData.tokens[0].derivedETH
  const daiTotalLiquidity = daiData && daiData.tokens[0].totalLiquidity
  const ethPriceInUSD = ethPriceData && ethPriceData.bundles[0].ethPrice

  return (
    <div>
      <div>
        Dai price:{' '}
        {ethLoading || daiLoading
          ? 'Loading token data...'
          : '$' +
            // parse responses as floats and fix to 2 decimals
            (parseFloat(daiPriceInEth) * parseFloat(ethPriceInUSD)).toFixed(2)}
      </div>
      <div>
        Dai total liquidity:{' '}
        {daiLoading
          ? 'Loading token data...'
          : // display the total amount of DAI spread across all pools
            parseFloat(daiTotalLiquidity).toFixed(0)}
      </div>
    </div>
  )
}

export default App
```


# Query Parameters

The Uniswap front-end supports URL query parameters to allow for custom linking to the Uniswap frontend. Users and developers can use these query parameters to link to the Uniswap frontend with custom prefilled settings.

Each Page has specific available URL parameters that can be set. Global parameters can be used on all pages.

A parameter used on an incorrect page will have no effect on frontend settings. Parameters not set with a URL parameter will be set to standard frontend defaults.

## Global

| Parameter | Type     | Description                      |
| --------- | -------- | -------------------------------- |
| theme     | `String` | Sets them to dark or light mode. |

### Theme Options

Theme can be set as `light` or `dark`.

### Example Usage

`https://quickswap.exchange/#/swap?theme=dark`

## Swap Page

| Parameter      | Type             | Description                                                            |
| -------------- | ---------------- | ---------------------------------------------------------------------- |
| inputCurrency  | `address`        | Input currency that will be swapped for output currency.               |
| outputCurrency | `address or ETH` | Output currency that input currency will be swapped for.               |
| exactAmount    | `number`         | The custom token amount to buy or sell.                                |
| exactField     | `string`         | The field to set custom token amount for. Must be `input` or `output`. |

### Defaults

ETH defaults as the input currency. When a different token is selected for either input or output ETH will default as the opposite selected currency.

### Constraints

Addresses must be valid ERC20 addresses. Slippage and amount values must be valid numbers accepted by the frontend (or error will prevent from swapping). Slippage can 0, or within the range 10->9999 bips (which converts to 0%, 0.01%->99%)

When selecting ETH as the output currency a user must also choose an inputCurrency that is not ETH (to prevent ETH being populated in both fields)

### Setting Amounts

Two parameters, exactField and exactAmount can be used to set specific token amounts to be sold or bought. Both fields must be set in the URL or there will be no effect on the settings.

### Example Usage

`https://quickswap.exchange/#/swap?exactField=input&exactAmount=10&inputCurrency=0x0F5D2fB29fb7d3CFeE444a200298f468908cC942`

## Pool Page

The Pool page is made up of 2 subroutes: `add`, `remove`.

### Add Liquidity

| Parameter | Type      | Description                                                                        |
| --------- | --------- | ---------------------------------------------------------------------------------- |
| Token0    | `address` | Pool to withdraw liquidity from. (Must be an ERC20 address with an existing token) |
| Token1    | `address` | Pool to withdraw liquidity from. (Must be an ERC20 address with an existing token) |

### Example Usage

`https://quickswap.exchange/#/add/0x6B175474E89094C44Da98b954EedeAC495271d0F-0xdAC17F958D2ee523a2206206994597C13D831ec7`

## Remove Liquidity

| Parameter | Type      | Description                                                                        |
| --------- | --------- | ---------------------------------------------------------------------------------- |
| Token0    | `address` | Pool to withdraw liquidity from. (Must be an ERC20 address with an existing token) |
| Token1    | `address` | Pool to withdraw liquidity from. (Must be an ERC20 address with an existing token) |

Dash seperated.

### Example Usage

`https://quickswap.exchange/#/remove/0x6B175474E89094C44Da98b954EedeAC495271d0F-0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2`


# Iframe Integration

Uniswap can be used within other sites as an iframe. An iframe shows an exact version of the uniswap frontend site and can have custom prefilled settings.

## Why You May Want This

Integrating the Uniswap site directly into your web application can be useful for a variety of reasons.

The interface allows users to buy, sell, send, or provide liquidity for ERC20 tokens. An iframe integration may be useful if your application provides services around these ERC20 tokens. (For example, users can buy DAI through a Uniswap iframe on your site, then allow users to lend that DAI on your site).

It can also be useful if your application requires users to acquire some token in order to use some service (For example, allow users to buy "REP" token so they can engage in prediction markets on the Augur Dapp).

## iframe vs. custom UI

One benefit of an iframe integration is that the your site will automatically keep up with any improvements/additions to the site. After the initital integration is setup no further work is needed to pull in updates as the exchange site is updated over time.

## Example

```
iframe src="https://quickswap.exchange/#/swap?exactField=input&exactAmount=10&inputCurrency=0x6b175474e89094c44da98b954eedeac495271d0f"  height="660px"   width="100%"
  style="
    border: 0;
    margin: 0 auto;
    margin-bottom: .5rem;
    display: block;
    border-radius: 10px;
    max-width: 960px;
    min-width: 300px;
  "
```

An example of an Iframe integration can be found on the FOAM site [https://map.foam.space/](https://map.foam.space/#/at/?lng=-74.0045300\&lat=40.6771800\&zoom=5.00)

To see the Iframe click the dropdown in the top right and click "get foam".

## Add To Your Site

To include a Uniswap iframe within your site just add an iframe element within your website code and link to the Uniswap frontent.

Linking to a ETH <-> DAI swap page would look something like this. To link to a token of your choice replace the address after "outputCurrency" with the token address of the token you want to link to.

```
<iframe
  src="https://app.uniswap.org/#/swap?outputCurrency=0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359"
  height="660px"
  width="100%"
  style="
    border: 0;
    margin: 0 auto;
    display: block;
    border-radius: 10px;
    max-width: 600px;
    min-width: 300px;
  "
  id="myId"
/>
```

You can customize the selected page, selected custom tokens and more using URL query parameters. See Custom Linking.


# Javascript SDK


# SDK Quick start

The Uniswap SDK exists to help developers build on top of Uniswap. It's designed to run in any environment that can execute JavaScript (think websites, node scripts, etc.). While simple enough to use in a hackathon project, it's also robust enough to power production applications.

## Installation

The easiest way to consume the SDK is via npm. To install it in your project, simply run `yarn add @uniswap/sdk` (or `npm install @uniswap/sdk`).

## Usage

To run code from the SDK in your application, use an `import` or `require` statement, depending on which your environment supports. Note that the guides following this page will use ES6 syntax.

### ES6 (import)

```typescript
import { ChainId } from '@uniswap/sdk'
console.log(`The chainId of mainnet is ${ChainId.MAINNET}.`)
```

### CommonJS (require)

```typescript
const UNISWAP = require('@uniswap/sdk')
console.log(`The chainId of mainnet is ${UNISWAP.ChainId.MAINNET}.`)
```

## Reference

Comprehensive reference material for the SDK is publicly available on the [Uniswap Labs github](https://github.com/Uniswap).


# Fetching Data

> Looking for a quickstart?

While the SDK is fully self-contained, there are two cases where it needs *on-chain data* to function. This guide will detail both of these cases, and offer some strategies that you can use to fetch this data.

## Case 1: Tokens

Unsurprisingly, the SDK needs some notion of an ERC-20 token to be able to function. This immediately raises the question of *where data about tokens comes from*.

As an example, let's try to represent DAI in a format the SDK can work with. To do so, we need at least 3 pieces of data: a **chainId**, a **token address**, and how many **decimals** the token has. We also may be interested in the **symbol** and/or **name** of the token.

### Identifying Data

The first two pieces of data — **chainId** and **token address** — must be provided by us. Thinking about it, this makes sense, as there's really no other way to unambiguously identify a token.

So, in the case of DAI, we know that the **chainId** is `1` (we're on mainnet), and the **token address** is `0x8f3cf7ad23cd3cadbd9735aff958023239c6a063`. Note that it's very important to externally verify token addresses. Don't use addresses from sources you don't trust!

### Required Data

The next piece of data we need is **decimals**.

#### Provided by the User

One option here is to simply pass in the correct value, which we may know is `18`. At this point, we're ready to represent DAI as a Token:

```typescript
import { ChainId, Token } from '@uniswap/sdk'

const chainId = ChainId.MAINNET
const tokenAddress = '0x6B175474E89094C44Da98b954EedeAC495271d0F' // must be checksummed
const decimals = 18

const DAI = new Token(chainId, tokenAddress, decimals)
```

If we don't know or don't want to hardcode the value, we could look it up ourselves via any method of retrieving on-chain data in a function that looks something like:

```typescript
import { ChainId } from '@uniswap/sdk'

async function getDecimals(chainId: ChainId, tokenAddress: string): Promise<number> {
  // implementation details
}
```

#### Fetched by the SDK

If we don't want to provide or look up the value ourselves, we can ask the SDK to look it up for us with Fetcher.fetchTokenData

```typescript
import { ChainId, Token, Fetcher } from '@uniswap/sdk'

const chainId = ChainId.MAINNET
const tokenAddress = '0x6B175474E89094C44Da98b954EedeAC495271d0F' // must be checksummed

// note that you may want/need to handle this async code differently,
// for example if top-level await is not an option
const DAI: Token = await Fetcher.fetchTokenData(chainId, tokenAddress)
```

By default, this method will use the [default provider defined by ethers.js](https://docs.ethers.io/v5/api/providers/#providers-getDefaultProvider). If you're already using ethers.js in your application, you may pass in your provider as a 3rd argument. If you're using another library, you'll have to fetch the data separately.

### Optional Data

Finally, we can talk about **symbol** and **name**. Because these fields aren't used anywhere in the SDK itself, they're optional, and can be provided if you want to use them in your application. However, the SDK will not fetch them for you, so you'll have to provide them:

```typescript
import { ChainId, Token } from '@uniswap/sdk'

const DAI = new Token(
  ChainId.MAINNET,
  '0x6B175474E89094C44Da98b954EedeAC495271d0F',
  18,
  'DAI',
  'Dai Stablecoin'
)
```

or:

```typescript
import { ChainId, Token, Fetcher } from '@uniswap/sdk'

// note that you may want/need to handle this async code differently,
// for example if top-level await is not an option
const DAI = await Fetcher.fetchTokenData(
  ChainId.MAINNET,
  '0x6B175474E89094C44Da98b954EedeAC495271d0F',
  undefined,
  'DAI',
  'Dai Stablecoin'
)
```

## Case 2: Pairs

Now that we've explored how to define a token, let's talk about pairs. To read more about what Uniswap pairs are, see Pair

As an example, let's try to represent the DAI-WETH pair.

### Identifying Data

Each pair consists of two tokens (see previous section). Note that WETH used by the router is exported by the SDK.

### Required Data

The data we need is the *reserves* of the pair. To read more about reserves, see getReserves.

#### Provided by the User

One option here is to simply pass in values which we've fetched ourselves to create a Pair:

```typescript
import { ChainId, Token, WETH, Pair, TokenAmount } from '@uniswap/sdk'

const DAI = new Token(ChainId.MAINNET, '0x6B175474E89094C44Da98b954EedeAC495271d0F', 18)

async function getPair(): Promise<Pair> {
  const pairAddress = Pair.getAddress(DAI, WETH[DAI.chainId])

  const reserves = [/* use pairAddress to fetch reserves here */]
  const [reserve0, reserve1] = reserves

  const tokens = [DAI, WETH[DAI.chainId]]
  const [token0, token1] = tokens[0].sortsBefore(tokens[1]) ? tokens : [tokens[1], tokens[0]]

  const pair = new Pair(new TokenAmount(token0, reserve0), new TokenAmount(token1, reserve1))
  return pair
}
```

Note that these values can change as frequently as every block, and should be kept up-to-date.

#### Fetched by the SDK

If we don't want to look up the value ourselves, we can ask the SDK to look them up for us with Fetcher.fetchTokenData:

```typescript
import { ChainId, Token, WETH, Fetcher } from '@uniswap/sdk'

const DAI = new Token(ChainId.MAINNET, '0x6B175474E89094C44Da98b954EedeAC495271d0F', 18)

// note that you may want/need to handle this async code differently,
// for example if top-level await is not an option
const pair = await Fetcher.fetchPairData(DAI, WETH[DAI.chainId])
```

By default, this method will use the [default provider defined by ethers.js](https://docs.ethers.io/v5/api/providers/#providers-getDefaultProvider). If you're already using ethers.js in your application, you may pass in your provider as a 3rd argument. If you're using another library, you'll have to fetch the data separately.

Note that these values can change as frequently as every block, and should be kept up-to-date.


# Pricing

> Looking for a quickstart?

Let's talk pricing. This guide will focus on the two most important Uniswap prices: the **mid price** and the **execution price**.

## Mid Price

The mid price, in the context of Uniswap, is the price that reflects the *ratio of reserves in one or more pairs*. There are three ways we can think about this price. Perhaps most simply, it defines the relative value of one token in terms of the other. It also represents the price at which you could theoretically trade an infinitesimal amount (ε) of one token for the other. Finally, it can be interpreted as the current *market-clearing or fair value price* of the assets.

Let's consider the mid price for DAI-WETH (that is, the amount of DAI per 1 WETH).

### Direct

The simplest way to get the DAI-WETH mid price is to observe the pair directly:

```typescript
import { ChainId, Token, WETH, Fetcher, Route } from "@uniswap/sdk";

const DAI = new Token(
  ChainId.MAINNET,
  "0x8f3cf7ad23cd3cadbd9735aff958023239c6a063",
  18
);

// note that you may want/need to handle this async code differently,
// for example if top-level await is not an option
const pair = await Fetcher.fetchPairData(DAI, WETH[DAI.chainId]);

const route = new Route([pair], WETH[DAI.chainId]);

console.log(route.midPrice.toSignificant(6)); // 201.306
console.log(route.midPrice.invert().toSignificant(6)); // 0.00496756
```

You may be wondering why we have to construct a *route* to get the mid price, as opposed to simply getting it from the pair (which, after all, includes all the necessary data). The reason is simple: a route forces us to be opinionated about the *direction* of trading. Routes consist of one or more pairs, and an input token (which fully defines a trading path). In this case, we passed WETH as the input token, meaning we're interested in a WETH -> DAI trade.

Now we understand that the mid price is going to be defined in terms of DAI/WETH. Not to worry though, if we need the WETH/DAI price, we can easily invert.

Finally, you may have noticed that we're formatting the price to 6 significant digits. This is because internally, prices are stored as exact-precision fractions, which can be converted to other representations on demand. For a full list of options, see Price.

### Indirect

For the sake of example, let's imagine a direct pair between DAI and WETH *doesn't exist*. In order to get a DAI-WETH mid price we'll need to pick a valid route. Imagine both DAI and WETH have pairs with a third token, USDC. In that case, we can calculate an indirect mid price through the USDC pairs:

```typescript
import { ChainId, Token, WETH, Fetcher, Route } from "@uniswap/sdk";

const USDC = new Token(
  ChainId.MAINNET,
  "0x2791bca1f2de4661ed88a30c99a7a9449aa84174",
  6
);
const DAI = new Token(
  ChainId.MAINNET,
  "0x8f3cf7ad23cd3cadbd9735aff958023239c6a063",
  18
);

// note that you may want/need to handle this async code differently,
// for example if top-level await is not an option
const USDCWETHPair = await Fetcher.fetchPairData(USDC, WETH[ChainId.MAINNET]);
const DAIUSDCPair = await Fetcher.fetchPairData(DAI, USDC);

const route = new Route([USDCWETHPair, DAIUSDCPair], WETH[ChainId.MAINNET]);

console.log(route.midPrice.toSignificant(6)); // 202.081
console.log(route.midPrice.invert().toSignificant(6)); // 0.00494851
```

## Execution Price

Mid prices are great representations of the *current* state of a route, but what about trades? It turns out that it makes sense to define another price, the *execution* price of a trade, as the ratio of assets sent/received.

Imagine we're interested in trading 1 WETH for DAI:

```typescript
import {
  ChainId,
  Token,
  WETH,
  Fetcher,
  Trade,
  Route,
  TokenAmount,
  TradeType,
} from "@uniswap/sdk";

const DAI = new Token(
  ChainId.MAINNET,
  "0x8f3cf7ad23cd3cadbd9735aff958023239c6a063",
  18
);

// note that you may want/need to handle this async code differently,
// for example if top-level await is not an option
const pair = await Fetcher.fetchPairData(DAI, WETH[DAI.chainId]);

const route = new Route([pair], WETH[DAI.chainId]);

const trade = new Trade(
  route,
  new TokenAmount(WETH[DAI.chainId], "1000000000000000000"),
  TradeType.EXACT_INPUT
);

console.log(trade.executionPrice.toSignificant(6));
console.log(trade.nextMidPrice.toSignificant(6));
```

Notice that we're constructing a trade of 1 WETH for as much DAI as possible, *given the current reserves of the direct pair*. The execution price represents the average DAI/WETH price for this trade. Of course, the reserves of any pair can change every block, which would affect the execution price.

Also notice that we're able to access the *next* mid price, if the trade were to complete successfully before the reserves changed.


# Trading

> Looking for a quickstart?

The SDK *cannot execute trades or send transactions on your behalf*. Rather, it offers utility classes and functions which make it easy to calculate the data required to safely interact with Uniswap. Nearly everything you need to safely transact with Uniswap is provided by the Trade entity. However, it is your responsibility to use this data to send transactions in whatever context makes sense for your application.

This guide will focus exclusively on sending a transaction to the currently recommended Uniswap router

## Sending a Transaction to the Router

Let's say we want to trade 1 WETH for as much DAI as possible:

```typescript
import { ChainId, Token, WETH, Fetcher, Trade, Route, TokenAmount, TradeType } from '@uniswap/sdk'

const DAI = new Token(ChainId.MAINNET, '0x6B175474E89094C44Da98b954EedeAC495271d0F', 18)

// note that you may want/need to handle this async code differently,
// for example if top-level await is not an option
const pair = await Fetcher.fetchPairData(DAI, WETH[DAI.chainId])

const route = new Route([pair], WETH[DAI.chainId])

const amountIn = '1000000000000000000' // 1 WETH

const trade = new Trade(route, new TokenAmount(WETH[DAI.chainId], amountIn), TradeType.EXACT_INPUT)
```

So, we've constructed a trade entity, but how do we use it to actually send a transaction? There are still a few pieces we need to put in place.

Before going on, we should explore how ETH works in the context of trading. Internally, the SDK uses WETH, as all Uniswap V2 pairs use WETH under the hood. However, it's perfectly possible for you as an end user to use ETH, and rely on the router to handle converting to/from WETH. So, let's use ETH.

The first step is selecting the appropriate router function. The names of router functions are intended to be self-explanatory; in this case we want swapExactETHForTokens, because we're swapping an exact amount of ETH for tokens.

That Solidity interface for this function is:

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

Jumping back to our trading code, we can construct all the necessary parameters:

```typescript
import { Percent } from '@uniswap/sdk'

const slippageTolerance = new Percent('50', '10000') // 50 bips, or 0.50%

const amountOutMin = trade.minimumAmountOut(slippageTolerance).raw // needs to be converted to e.g. hex
const path = [WETH[DAI.chainId].address, DAI.address]
const to = '' // should be a checksummed recipient address
const deadline = Math.floor(Date.now() / 1000) + 60 * 20 // 20 minutes from the current Unix time
const value = trade.inputAmount.raw // // needs to be converted to e.g. hex
```

The slippage tolerance encodes *how large of a price movement we're willing to tolerate before our trade will fail to execute*. Since Ethereum transactions are broadcast and confirmed in an adversarial environment, this tolerance is the best we can do to protect ourselves against price movements. We use this slippage tolerance to calculate the *minumum* amount of DAI we must receive before our trade reverts, thanks to minimumAmountOut. Note that this code calculates this worst-case outcome *assuming that the current price, i.e the route's mid price,* is fair (usually a good assumption because of arbitrage).

The path is simply the ordered list of token addresses we're trading through, in our case WETH and DAI (note that we use the WETH address, even though we're using ETH).

The to address is the address that will receive the DAI.

The deadline is the Unix timestamp after which the transaction will fail, to protect us in the case that our transaction takes a long time to confirm and we wish to rescind our trade.

The value is the amount of ETH that must be included as the `msg.value` in our transaction.


# Pair Addresses

## getPair

The most obvious way to get the address for a pair is to call getPair on the factory. If the pair exists, this function will return its address, else `address(0)` (`0x0000000000000000000000000000000000000000`).

* The "canonical" way to determine whether or not a pair exists.
* Requires an on-chain lookup.

## CREATE2

Thanks to some [fancy footwork in the factory](https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2Factory.sol#L32), we can also compute pair addresses *without any on-chain lookups* because of [CREATE2](https://eips.ethereum.org/EIPS/eip-1014). The following values are required for this technique:

|                        |                                                                      |
| ---------------------- | -------------------------------------------------------------------- |
| `address`              | The factory address                                                  |
| `salt`                 | `keccak256(abi.encodePacked(token0, token1))`                        |
| `keccak256(init_code)` | `0x96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f` |

* `token0` must be strictly less than `token1` by sort order.
* Can be computed offline.
* Requires the ability to perform `keccak256`.

### Examples

#### TypeScript

This example makes use of the Uniswap SDK. In reality, the SDK computes pair addresses behind the scenes, obviating the need to compute them manually like this.

```typescript
import { FACTORY_ADDRESS, INIT_CODE_HASH } from '@uniswap/sdk'
import { pack, keccak256 } from '@ethersproject/solidity'
import { getCreate2Address } from '@ethersproject/address'

const token0 = '0xCAFE000000000000000000000000000000000000' // change me!
const token1 = '0xF00D000000000000000000000000000000000000' // change me!

const pair = getCreate2Address(
  FACTORY_ADDRESS,
  keccak256(['bytes'], [pack(['address', 'address'], [token0, token1])]),
  INIT_CODE_HASH
)
```


# Smart Contract Integration


# Smart Contract Quick Start

Developing smart contracts for Ethereum involves a bevy of off-chain tools used for producing and testing bytecode that runs on the [Ethereum Virtual Machine (EVM)](https://eth.wiki/en/concepts/evm/ethereum-virtual-machine-\(evm\)-awesome-list). Some tools also include workflows for deploying this bytecode to the Ethereum network and testnets. There are many options for these tools. This guide walks you through writing and testing a simple smart contract that interacts with the Uniswap Protocol using one specific set of tools (`truffle` + `npm` + `mocha`).

### Requirements

To follow this guide, you must have the following installed:

* [nodejs >= v12.x & npm >= 6.x](https://nodejs.org/en/)

### Bootstrapping a project

You can start from scratch, but it's easier to use a tool like `truffle` to bootstrap an empty project. Create an empty directory and run `npx truffle init` inside that directory to unbox the default [Truffle box](https://www.trufflesuite.com/boxes).

```shell
mkdir demo
cd demo
npx truffle init
```

### Setting up npm

In order to reference the Uniswap V2 contracts, you should use the npm artifacts we deploy containing the core and periphery smart contracts and interfaces. To add npm dependencies, we first initialize the npm package. We can run `npm init` in the same directory to create a `package.json` file. You can accept all the defaults and change it later.

```shell
npm init
```

### Adding dependencies

Now that we have an npm package, we can add our dependencies. Let's add both the [`@uniswap/v2-core`](https://www.npmjs.com/package/@uniswap/v2-core) and [`@uniswap/v2-periphery`](https://www.npmjs.com/package/@uniswap/v2-periphery) packages.

```shell
npm i --save @uniswap/v2-core
npm i --save @uniswap/v2-periphery
```

If you check the `node_modules/@uniswap` directory, you can now find the Uniswap V2 contracts.

```shell
moody@MacBook-Pro ~/I/u/demo> ls node_modules/@uniswap/v2-core/contracts
UniswapV2ERC20.sol    UniswapV2Pair.sol     libraries/
UniswapV2Factory.sol  interfaces/           test/
moody@MacBook-Pro ~/I/u/demo> ls node_modules/@uniswap/v2-periphery/contracts/
UniswapV2Migrator.sol  examples/              test/
UniswapV2Router01.sol  interfaces/
UniswapV2Router02.sol  libraries/
```

These packages include both the smart contract source code and the build artifacts.

### Writing our contract

We can now get started writing our example contract. For writing Solidity, we recommend IntelliJ or VSCode with a solidity plugin, but you can use any text editor. Let's write a contract that returns the value of some amount of liquidity shares for a given token pair. First create a couple of files:

```shell
mkdir contracts/interfaces
touch contracts/interfaces/ILiquidityValueCalculator.sol
touch contracts/LiquidityValueCalculator.sol
```

This will be the interface of the contract we implement. Put it in `contracts/interfaces/ILiquidityValueCalculator.sol`.

```solidity
pragma solidity ^0.6.6;

interface ILiquidityValueCalculator {
    function computeLiquidityShareValue(uint liquidity, address tokenA, address tokenB) external returns (uint tokenAAmount, uint tokenBAmount);
}
```

Now let's start with the constructor. You need to know where the `UniswapV2Factory` is deployed in order to compute the address of the pair and look up the total supply of liquidity shares, plus the amounts for the reserves. We can store this as an address passed to the constructor.

The factory address is constant on mainnet and all testnets, so it may be tempting to make this value a constant in your contract, but since we need to unit test the contract it should be an argument. You can use solidity immutables to save on gas when accessing this variable.

```solidity
pragma solidity ^0.6.6;

import './interfaces/ILiquidityValueCalculator.sol';

contract LiquidityValueCalculator is ILiquidityValueCalculator {
    address public factory;
    constructor(address factory_) public {
        factory = factory_;
    }
}
```

Now we need to be able to look up the total supply of liquidity for a pair, and its token balances. Let's put this in a separate function. To implement it, we must:

1. Look up the pair address
2. Get the reserves of the pair
3. Get the total supply of the pair liquidity
4. Sort the reserves in the order of tokenA, tokenB

The `UniswapV2Library` has some helpful methods for this.

```solidity
pragma solidity ^0.6.6;

import './interfaces/ILiquidityValueCalculator.sol';
import '@uniswap/v2-periphery/contracts/libraries/UniswapV2Library.sol';
import '@uniswap/v2-core/contracts/interfaces/IUniswapV2Pair.sol';

contract LiquidityValueCalculator is ILiquidityValueCalculator {
    function pairInfo(address tokenA, address tokenB) internal view returns (uint reserveA, uint reserveB, uint totalSupply) {
        IUniswapV2Pair pair = IUniswapV2Pair(UniswapV2Library.pairFor(factory, tokenA, tokenB));
        totalSupply = pair.totalSupply();
        (uint reserves0, uint reserves1,) = pair.getReserves();
        (reserveA, reserveB) = tokenA == pair.token0() ? (reserves0, reserves1) : (reserves1, reserves0);
    } 
}
```

Finally we just need to compute the share value. We will leave that as an exercise to the reader.

```solidity
pragma solidity ^0.6.6;

import './interfaces/ILiquidityValueCalculator.sol';
import '@uniswap/v2-periphery/contracts/libraries/UniswapV2Library.sol';
import '@uniswap/v2-core/contracts/interfaces/IUniswapV2Pair.sol';

contract LiquidityValueCalculator is ILiquidityValueCalculator {
    address public factory;
    constructor(address factory_) public {
        factory = factory_;
    }

    function pairInfo(address tokenA, address tokenB) internal view returns (uint reserveA, uint reserveB, uint totalSupply) {
        IUniswapV2Pair pair = IUniswapV2Pair(UniswapV2Library.pairFor(factory, tokenA, tokenB));
        totalSupply = pair.totalSupply();
        (uint reserves0, uint reserves1,) = pair.getReserves();
        (reserveA, reserveB) = tokenA == pair.token0() ? (reserves0, reserves1) : (reserves1, reserves0);
    }
 
    function computeLiquidityShareValue(uint liquidity, address tokenA, address tokenB) external override returns (uint tokenAAmount, uint tokenBAmount) {
        revert('TODO');
    }
}
```

### Writing tests

In order to test your contract, you need to:

1. Bring up a testnet
2. Deploy the `UniswapV2Factory`
3. Deploy at least 2 ERC20 tokens for a pair
4. Create a pair for the factory
5. Deploy your `LiquidityValueCalculator` contract
6. Call `LiquidityValueCalculator#computeLiquidityShareValue`
7. Verify the result with an assertion

\#1 is handled for you automatically by the `truffle test` command.

Note you should only deploy the precompiled Uniswap contracts in the `build` directories for unit tests. This is because solidity appends a metadata hash to compiled contract artifacts which includes the hash of the contract source code path, and compilations on other machines will not result in the exact same bytecode. This is problematic because in Uniswap V2 we use the hash of the bytecode in the v2-periphery [`UniswapV2Library`](https://github.com/Uniswap/uniswap-v2-periphery/blob/master/contracts/libraries/UniswapV2Library.sol#L24), to compute the pair address.

To get the bytecode for deploying UniswapV2Factory, you can import the file via:

```javascript
const UniswapV2FactoryBytecode = require('@uniswap/v2-core/build/UniswapV2Factory.json').bytecode
```

We recommend using a standard ERC20 from `@openzeppelin/contracts` for deploying an ERC20.

You can read more about deploying contracts and writing tests using Truffle [here](https://www.trufflesuite.com/docs/truffle/testing/writing-tests-in-javascript).

### Compiling and deploying the contract

Learn more about compiling and deploying contracts using Truffle [here](https://www.trufflesuite.com/docs/truffle/getting-started/compiling-contracts) and [here](https://www.trufflesuite.com/docs/truffle/getting-started/running-migrations) respectively.

### WIP

This guide is a WIP. Please contribute to this guide with the edit button below!


# Implement A Swap

When trading from a smart contract, the most important thing to keep in mind is that access to an external price source is *required*. Without this, trades can be frontrun for considerable loss.

*Read* [*safety considerations*](broken://pages/SJYVcS73Qh7p2Xo8w0YM) *for more.*

## Using the Router

The easiest way to safely swap tokens is to use the router, which provides a variety of methods to safely swap to and from different assets. You'll notice that there is a function for each permutation of swapping to/from an exact amount of ETH/tokens.

First you must use an external price source to calculate the safety parameters for the function you'd like to call. This is either a minimum amount received when selling an exact input or the maximum amount you are willing to pay when a buying an exact output amount

It is also important to ensure that your contract controls enough ETH/tokens to make the swap, and has granted approval to the router to withdraw this many tokens.

*Check out the Pricing page for a more in depth discussion on getting prices.*

## Example

Imagine you want to swap 50 DAI for as much ETH as possible from your smart contract.

### transferFrom

Before swapping, our smart contracts needs to be in control of 50 DAI. The easiest way to accomplish this is by calling `transferFrom` on DAI with the owner set to `msg.sender`:

```solidity
uint amountIn = 50 * 10 ** DAI.decimals();
require(DAI.transferFrom(msg.sender, address(this), amountIn), 'transferFrom failed.');
```

### approve

Now that our contract owns 50 DAI, we need to approve to the router to withdraw this DAI:

```solidity
require(DAI.approve(address(UniswapV2Router02), amountIn), 'approve failed.');
```

### swapExactTokensForETH

Now we're ready to swap:

```solidity
// amountOutMin must be retrieved from an oracle of some kind
address[] memory path = new address[](2);
path[0] = address(DAI);
path[1] = UniswapV2Router02.WETH();
UniswapV2Router02.swapExactTokensForETH(amountIn, amountOutMin, path, msg.sender, block.timestamp);
```

## Safety Considerations

Because Ethereum transactions occur in an adversarial environment, smart contracts that do not perform safety checks *can be exploited for profit*. If a smart contract assumes that the current price on Uniswap is a "fair" price without performing safety checks, *it is vulnerable to manipulation*. A bad actor could e.g. easily insert transactions before and after the swap (a "sandwich" attack) causing the smart contract to trade at a much worse price, profit from this at the trader's expense, and then return the contracts to their original state. (One important caveat is that these types of attacks are mitigated by trading in extremely liquid pools, and/or at low values.)

The best way to protect against these attacks is to use an external price feed or "price oracle". The best "oracle" is simply *traders' off-chain observation of the current price*, which can be passed into the trade as a safety check. This strategy is best for situations *where users initiate trades on their own behalf*.

However, when an off-chain price can't be used, an on-chain oracle should be used instead. Determining the best oracle for a given situation is a not part of this guide, but for more details on the Uniswap V2 approach to oracles, see Oracles.


# Providing Liquidity

## Introduction

When providing liquidity from a smart contract, the most important thing to keep in mind is that tokens deposited into a pool at any rate other than the current reserve ratio *are vulnerable to being arbitraged*. As an example, if the ratio of x:y in a pair is 10:2 (i.e. the price is 5), and someone naively adds liquidity at 5:2 (a price of 2.5), the contract will simply accept all tokens (changing the price to 3.75 and opening up the market to arbitrage), but only issue pool tokens entitling the sender to the amount of assets sent at the proper ratio, in this case 5:1. To avoid donating to arbitrageurs, it is imperative to add liquidity at the current price. Luckily, it's easy to ensure that this condition is met!

## Using the Router

The easiest way to safely add liquidity to a pool is to use the router, which provides simple methods to safely add liquidity to a pool. If the liquidity is to be added to an ERC-20/ERC-20 pair, use addLiquidity. If WETH is involved, use addLiquidityETH.

These methods both require the caller to commit to a *belief about the current price*, which is encoded in the `amount*Desired` parameters. Typically, it's fairly safe to assume that the current fair market price is around what the current reserve ratio is for a pair (because of arbitrage). So, if a user wants to add 1 ETH to a pool, and the current DAI/WETH ratio of the pool is 200/1, it's reasonable to calculate that 200 DAI must be sent along with the ETH, which is an implicit commitment to the price of 200 DAI/1 WETH. However, it's important to note that this must be calculated *before the transaction is submitted*. It is *not safe* to look up the reserve ratio from within a transaction and rely on it as a price belief, as this ratio can be cheaply manipulated to your detriment.

However, it is still possible to submit a transaction which encodes a belief about the price which ends up being wrong because of a larger change in the true market price before the transaction is confirmed. For that reason, it's necessary to pass an additional set of parameters which encode the caller's tolerance to price changes. These `amount*Min` parameters should typically be set to percentages of the calculated desired price. So, at a 1% tolerance level, if our user sends a transaction with 1 ETH and 200 DAI, `amountETHMin` should be set to e.g. .99 ETH, and `amountTokenMin` should be set to 198 DAI. This means that, at worst, liquidity will be added at a rate between 198 DAI/1 ETH and 202.02 DAI/1 ETH (200 DAI/.99 ETH).

Once the price calculations have been made, it's important to ensure that your contract a) controls at least as many tokens/ETH as were passed as `amount*Desired` parameters, and b) has granted approval to the router to withdraw this many tokens.


# Building An Oracle

To build a price oracle on Uniswap V2, you must first understand the requirements for your use case. Once you understand the kind of price average you require, it is a matter of storing the cumulative price variable from the pair as often as necessary, and computing the average price using two or more observations of the cumulative price variables.

## Understanding requirements

To understand your requirements, you should first research the answer to the following questions:

* Is data freshness important? I.e.: must the price average include the current price?
* Are recent prices more important than historical prices? I.e.: is the current price given more weight than historical prices?

Note your answers for the following discussion.

## Oracle Strategies

### Fixed windows

In the case where data freshness is not important and recent prices are weighted equally with historical prices, it is enough to store the cumulative price once per period (e.g. once per 24 hours.)

Computing the average price over these data points gives you 'fixed windows', which can be updated after the lapse of each period. We wrote an example oracle of this kind [here](https://github.com/Uniswap/uniswap-v2-periphery/blob/master/contracts/examples/ExampleOracleSimple.sol).

ExampleOracleSimple.sol

This example does not limit the maximum size of the fixed window, i.e. it only requires that the window size is greater than 1 period (e.g. 24 hours).

### Moving averages

In the case where data freshness is important, you can use a sliding window in which the cumulative price variable is measured more often than once per period.

There are at least [two kinds of moving averages](https://www.investopedia.com/terms/m/movingaverage.asp#types-of-moving-averages) that you can compute using the Uniswap cumulative price variable.

[Simple moving averages](https://www.investopedia.com/terms/s/sma.asp) give equal weight to each price measurement. We have built an example of a sliding window oracle [here](https://github.com/Uniswap/uniswap-v2-periphery/blob/master/contracts/examples/ExampleSlidingWindowOracle.sol).

[Exponential moving averages](https://www.investopedia.com/terms/e/ema.asp) give more weight to the most recent price measurements. We do not yet have an example written for this type of oracle.

You may wish to use exponential moving averages where recent prices are more important than historical prices, e.g. in case of liquidations. However, note that putting more weight on recent prices makes the oracle cheaper to manipulate than weighting all price measurements equally.

### Computing average prices

To compute the average price given two cumulative price observations, take the difference between the cumulative price at the beginning and end of the period, and divide by the elapsed time between them in seconds. This will produce a [fixed point unsigned Q112x112](https://en.wikipedia.org/wiki/Fixed-point_arithmetic#Notation) number that represents the price of one asset relative to the other. This number is represented as a `uint224` where the upper 112 bits represent the integer amount, and the lower 112 bits represent the fractional amount.

Pairs contain both `price0CumulativeLast` and `price1CumulativeLast`, which are ratios of reserves of `token1`/`token0` and `token0`/`token1` respectively. I.e. the price of `token0` is expressed in terms of `token1`/`token0`, while the price of `token1` is expressed in terms of `token0`/`token1`.

## Getting the latest cumulative price

If you wish to compute the average price between a historical price cumulative observation and the current cumulative price, you should use the cumulative price values from the current block. If the cumulative price has not been updated in the current block, e.g. because there has not been any liquidity event (`mint`/`burn`/`swap`) on the pair in the current block, you can compute the cumulative price counterfactually.

We provide a library for use in oracle contracts that has the method [`UniswapV2OracleLibrary#currentCumulativePrices`](https://github.com/Uniswap/uniswap-v2-periphery/blob/master/contracts/libraries/UniswapV2OracleLibrary.sol#L16) for getting the cumulative price as of the current block. The current cumulative price returned by this method is computed *counterfactually*, meaning it requires no call to the relative gas-expensive `#sync` method on the pair. It is correct regardless of whether a swap has already executed in the current block.

## Notes on overflow

The `UniswapV2Pair` cumulative price variables are designed to eventually overflow, i.e. `price0CumulativeLast` and `price1CumulativeLast` and `blockTimestampLast` will overflow through 0.

This should not pose an issue to your oracle design, as the price average computation is concerned with differences (i.e. subtraction) between two separate observations of a cumulative price variable. Subtracting between two cumulative price values will result in a number that fits within the range of `uint256` as long as the observations are made for periods of max `2^32` seconds, or \~136 years.

`blockTimestampLast` is stored only in a `uint32`. For the same reason as described above, the pair can save a storage slot, and many SSTORES over the life of the pair, by storing only `block.timestamp % uint32(-1)`. This is feasible because the pair is only concerned with the time that elapses between each liquidity event when updating the cumulative prices, which is always expected to be less than `2^32` seconds.

When computing time elapsed within your own oracle, you can simply store the `block.timestamp` of your observations as `uint256`, and avoid dealing with overflow math for computing the time elapsed between observations. This is how the [ExampleSlidingWindowOracle](https://github.com/Uniswap/uniswap-v2-periphery/blob/master/contracts/examples/ExampleSlidingWindowOracle.sol) handles observation timestamps.

ExampleSlidingWindowOracle

### Integrating the oracle

To integrate an oracle into your contracts, you must ensure the oracle's observations of the cumulative price variable are kept up to date. As long as your oracle is up to date, you can depend on it to produce average prices. The process of keeping your oracle up to date is called 'maintenance'.

### Oracle maintenance

In order to measure average prices over a period, the oracle must have a way of referencing the cumulative price at the start and end of a period. The recommended way of doing this is by storing these prices in the oracle contract, and calling the oracle frequently enough to store the latest cumulative price.

Reliable oracle maintenance is a difficult task, and can become a point of failure in times of congestion. Instead, consider building this functionality directly into the critical calls of your own smart contracts, or incentivize oracle maintenance calls by other parties.

### No-maintenance option

It is possible to avoid regularly storing this cumulative price at the start of the period by utilizing storage proofs. However, this approach has limitations, especially in regard to gas cost and maximum length of the time period over which the average price can be measured. If you wish to try this approach, you can follow [this repository by Keydonix](https://github.com/Keydonix/uniswap-oracle/).

Keydonix: on-chain trustless and censorship resistant oracle

Keydonix has developed a general purpose price feed oracle built on Uniswap v2 that supports arbitrary time windows (up to 256 blocks) and doesn't require any active maintenance.


# Flash Swaps

Flash swaps are an integral feature of Uniswap V2. In fact, under the hood, all swaps are actually flash swaps! This simply means that pair contracts send output tokens to the recipient *before* enforcing that enough input tokens have been received. This is slightly atypical, as one might expect a pair to ensure it's received payment before delivery. However, because Ethereum transactions are *atomic*, we can roll back the entire swap if it turns out that the contract hasn't received enough tokens to make itself whole by the end of the transaction.

To see how this all works, let's start by examining the interface of the `swap` function:

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

For the sake of example, let's assume that we're dealing with a DAI/WETH pair, where DAI is `token0` and WETH is `token1`. `amount0Out` and `amount1Out` specify the amount of DAI and WETH that the `msg.sender` wants the pair to send to the `to` address (one of these amounts may be 0). At this point you may be wondering how the contract *receives* tokens. For a typical (non-flash) swap, it's actually the responsibility of `msg.sender` to ensure that enough WETH or DAI has *already been sent* to the pair before `swap` is called (in the context of trading, this is all handled neatly by a router contract). But when executing a flash swap, *tokens do not need to be sent to the contract before calling `swap`*. Instead, they must be sent from within a *callback function* that the pair triggers on the `to` address.

## Triggering a Flash Swap

To differentiate between the "typical" trading case and the flash swap case, pairs use the `data` parameter. Specifically, if `data.length` equals 0, the contract assumes that payment has already been received, and simply transfers the tokens to the `to` address. But, if `data.length` is greater than 0, the contract transfers the tokens and then calls the following function on the `to` address:

```solidity
function uniswapV2Call(address sender, uint amount0, uint amount1, bytes calldata data);
```

The logic behind this identification strategy is simple: the vast majority of valid flash swap use cases involve interactions with external protocols. The best way to pass information dictating how these interactions happen (function arguments, safety parameters, addresses, etc.) is via the `data` parameter. It's expected that `data` will be `abi.decode`d from within `uniswapV2Call`. In the rare case where no data is required, callers should ensure that `data.length` equals 1 (i.e. encode a single junk byte as `bytes`), and then ignore this argument in `uniswapV2Call`.

Pairs call `uniswapV2Call` with the `sender` argument set to the `msg.sender` of the `swap`. `amount0` and `amount1` are simply `amount0Out` and `amount1Out`.

## Using uniswapV2Call

There are several conditions that should be checked in all `uniswapV2Call` functions:

```solidity
function uniswapV2Call(address sender, uint amount0, uint amount1, bytes calldata data) {
  address token0 = IUniswapV2Pair(msg.sender).token0(); // fetch the address of token0
  address token1 = IUniswapV2Pair(msg.sender).token1(); // fetch the address of token1
  assert(msg.sender == IUniswapV2Factory(factoryV2).getPair(token0, token1)); // ensure that msg.sender is a V2 pair
  // rest of the function goes here!
}
```

The first 2 lines simply fetch the token addresses from the pair, and the 3rd ensures that the `msg.sender` is an actual Uniswap V2 pair address.

## Repayment

At the end of `uniswapV2Call`, contracts must return enough tokens to the pair to make it whole. Specifically, this means that the product of the pair reserves after the swap, discounting all token amounts sent by 0.3% LP fee, must be greater than before.

### Multi-Token

In the case where the token withdrawn is *not* the token returned (i.e. DAI was requested in the flash swap, and WETH was returned, or vice versa), the fee simplifies to the simple swap case. This means that the standard `getAmountIn` pricing function should be used to calculate e.g., the amount of WETH that must be returned in exchange for the amount of DAI that was requested out.

This type of fee calculation gives a slight advantage to the caller, as the fee derived from repayment in a corresponding token will always be slightly less than the fee derived from a direct token repayment, as a result of the difference between the amount required to pay back a swap, versus the amount withdrawn and then directly returned. The approximate comparison of fees is \~ 30 bps for a swap fee vs. 30.09 bps for a direct repayment.

### Single-Token

In the case where the token withdrawn is the *same* as the token returned (i.e. DAI was requested in the flash swap, used, then returned, or vice versa with WETH), the following condition must be satisfied:

`DAIReservePre - DAIWithdrawn + (DAIReturned * .997) >= DAIReservePre`

It may be more intuitive to rewrite this formula in terms of a "fee" levied on the *withdrawn* amount (despite the fact that Uniswap always levies fees on input amounts, in this case the *returned* amount, here we can simplify to an effective fee on the *withdrawn* amount). If we rearrange, the formula looks like:

`(DAIReturned * .997) - DAIWithdrawn >= 0`

`DAIReturned >= DAIWithdrawn / .997`

So, the effective fee on the withdrawn amount is `.003 / .997 ≈ 0.3009027%`.

## Resources

For further exploration of flash swaps, see the whitepaper.

## Example

A fully functional example of flash swaps is available: [`ExampleFlashSwap.sol`](https://github.com/Uniswap/uniswap-v2-periphery/blob/master/contracts/examples/ExampleFlashSwap.sol).

ExampleSwapToPrice.sol

## Interface

```solidity
import '@uniswap/v2-core/contracts/interfaces/IUniswapV2Callee.sol';
```

```solidity
pragma solidity >=0.5.0;

interface IUniswapV2Callee {
  function uniswapV2Call(address sender, uint amount0, uint amount1, bytes calldata data) external;
}
```


# V2 Pair Addresses

## V2 Pair Addresses

## getPair

The most obvious way to get the address for a pair is to call getPair on the factory. If the pair exists, this function will return its address, else `address(0)` (`0x0000000000000000000000000000000000000000`).

* The "canonical" way to determine whether or not a pair exists.
* Requires an on-chain lookup.

## CREATE2

Thanks to some [fancy footwork in the factory](https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2Factory.sol#L32), we can also compute pair addresses *without any on-chain lookups* because of [CREATE2](https://eips.ethereum.org/EIPS/eip-1014). The following values are required for this technique:

|                        |                                                                      |
| ---------------------- | -------------------------------------------------------------------- |
| `address`              | The factory address                                                  |
| `salt`                 | `keccak256(abi.encodePacked(token0, token1))`                        |
| `keccak256(init_code)` | `0x96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f` |

* `token0` must be strictly less than `token1` by sort order.
* Can be computed offline.
* Requires the ability to perform `keccak256`.

### Examples

#### Solidity

```solidity
address factory = 0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f;
address token0 = 0xCAFE000000000000000000000000000000000000; // change me!
address token1 = 0xF00D000000000000000000000000000000000000; // change me!

address pair = address(uint(keccak256(abi.encodePacked(
  hex'ff',
  factory,
  keccak256(abi.encodePacked(token0, token1)),
  hex'96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f'
))));
```


# Supporting Meta Transactions

All Uniswap V2 pool tokens support meta-transaction approvals via the permit function. This obviates the need for a blocking approve transaction before programmatic interactions with pool tokens can occur.

## ERC-712

In vanilla ERC-20 token contracts, owners may only register approvals by directly calling a function which uses `msg.sender` to permission itself. With meta-approvals, ownership and permissioning are derived from a signature passed into the function by the caller (sometimes referred to as the relayer). Because signing data with Ethereum private keys can be a tricky endeavor, Uniswap V2 relies on [ERC-712](https://eips.ethereum.org/EIPS/eip-712), a signature standard with widespread community support, to ensure user safety and wallet compatibility.

### Domain Separator

```solidity
keccak256(
  abi.encode(
    keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)'),
    keccak256(bytes(name)),
    keccak256(bytes('1')),
    chainId,
    address(this)
  )
);
```

* `name` is always `Uniswap V2`, see name.
* `chainId` is determined from the [ERC-1344](https://ethereum-magicians.org/t/eip-1344-add-chain-id-opcode/1131) `chainid` opcode.
* `address(this)` is the address of the pair, see Pair Addresses.

### Permit Typehash

```solidity
keccak256('Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)');`
```


# V3 Pool Addresses

## V3 Pool Addresses

## poolByPair

The most obvious way to get the address for a pool is to call poolByPair on the factory. If the pool exists, this function will return its address, else `address(0)` (`0x0000000000000000000000000000000000000000`).

* The "canonical" way to determine whether or not a pool exists.
* Requires an on-chain lookup.


# Subgraphs


# Glossary

#### Automated market maker

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 <a href="#constant-product-formula" id="constant-product-formula"></a>

The automated market making algorithm used by Quickswap. See [x\*y=k](https://docs.quickswap.exchange/concepts/protocol-overview/04-glossary#x--y--k).

#### ERC20 <a href="#erc20" id="erc20"></a>

ERC20 tokens are fungibile tokens on Ethereum and Polygon. Quickswap supports all standard ERC20 implementations.

#### Factory <a href="#factory" id="factory"></a>

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

#### Pair <a href="#pair" id="pair"></a>

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

#### Pool <a href="#pool" id="pool"></a>

Liquidity within a pair is pooled across all liquidity providers.

#### 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 <a href="#mid-price" id="mid-price"></a>

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

#### Price impact <a href="#price-impact" id="price-impact"></a>

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

#### 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 <a href="#core" id="core"></a>

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

#### Periphery <a href="#periphery" id="periphery"></a>

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

#### 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` <a href="#x--y--k" id="x--y--k"></a>

The constant product formula.

#### Invariant <a href="#invariant" id="invariant"></a>

The "k" value in the constant product formula


# Core Concepts

\\


# Swaps

## Introduction

Token swaps in Quickswap 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 Quickswap works.

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

As we learned in Protocol Overview, each pair on Quickswap 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. 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

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

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

## Receiving tokens

As is probably clear from the function signature, Quickswap 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 Quickswap *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 V2 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. See the whitepaper for a justification of why this is the case.

The takeaway is that **tokens must be transferred to pairs before swap is called** (the one exception to this rule is 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.

## Developer resources

* To see how to implement token swaps in a smart contract read Trading from a smart contract.
* To see how to execute a swap from an interface read Trading (SDK)


# Pools

## Introduction

Each Quickswap 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
* Fees

## Why pools?

Quickswap is unique in that it doesn’t use an order book to derive the price of an asset or to match buyers and sellers of tokens. Instead, Quickswap 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 use cases, 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.

Quickswap focuses on the strengths of Ethereum to reimagine token swaps from first principles.

A blockchain-native liquidity protocol should take advantage of the trusted code execution environment, the autonomous and perpetually running virtual machine, and an open, permissionless, and inclusive access model that produces an exponentially growing ecosystem of virtual assets.

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 Quickswap protocol through the Interface (which in turn interacts with the underlying contracts), developers can interact directly with the smart contracts and integrate Quickswap functionality into their own applications without relying on intermediaries or needing permission.

## Developer resources

* To see how to pool tokens in a smart contract read Providing Liquidity.


# Flash Swaps

Quickswap flash swaps allow you to withdraw up to the full reserves of any ERC20 token on Quickswap 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 Quickswap.

## Examples

### Capital Free Arbitrage

One particularly interesting use case for flash swaps is capital-free arbitrage. It's well-known that an integral part of Quickswap's design is to create incentives for arbitrageurs to trade the Quickswap 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 Quickswap 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 Matic from Quickswap

The first step is to *optimistically* withdraw 1 Matic from Quickswap 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 Quickswap 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.) If the Quickswap market price is far enough above or below this external price, the following example contains code that calculates the amount to trade over Quickswap for maximum profit: [`ExampleSwapToPrice.sol`](https://github.com/Quickswap/Quickswap-v2-periphery/blob/master/contracts/examples/ExampleSwapToPrice.sol).

ExampleSwapToPrice.sol

#### Trade at External Venue

Once we've obtained our temporary capital of 1 ETH from Quickswap, we now can trade this for 220 DAI on Oasis. Once we've received the DAI, we need to pay Quickswap 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 Quickswap pair, you're left with 20 DAI of profit!

### Instant Leverage

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

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 Quickswap 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.

## Developer resources

* To see how to integrate a flash swap in your smart contract read Using Flash Swaps.


# Oracles

## Introduction

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, Quickswap V2 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.

## Quickswap V2 solution

Quickswap V2 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, Quickswap V2 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 Quickswap 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 Quickswap, 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.

There are some nuances that are good to be aware of when using Quickswap V2 as an oracle, especially where manipulation resistance is concerned. The whitepaper elaborates on some of them. Additional oracle-focused developer guides and documentation will be released soon.

In the meantime, check out our [example implementation](https://github.com/Uniswap/uniswap-v2-periphery/blob/master/contracts/examples/ExampleOracleSimple.sol) of a 24 hr TWAP Oracle built on Quickswap V2!

### Manipulation resistance

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. For a more in-depth review of the security of Quickswap V2 price oracles, read the [security audit section on Oracle Integrity](https://uniswap.org/audit.html#org87c8b91).

## Building an oracle

To learn more about building oracles check out building an Oracle in the developer guides.


# Advanced Topics


# Fees

### Liquidity provider fees

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.

### Protocol Fees

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

More information about a potential future protocol fee can be found [here](https://uniswap.org/blog/uniswap-v2/#path-to-sustainability).

### Protocol Charge Calculation

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 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. See the whitepaper for more details.


# Pricing

## How are prices determined?

As we learned in Protocol Overview, each pair on Quickswap 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. 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.

## How Quickswap handles prices

In Quickswap V1, trades are always executed at the "best possible" price, calculated at execution time. Somewhat confusingly, this calculation is actually accomplished with one of two different formulas, depending on whether the trade specifies an exact *input* or *output* amount. Functionally, the difference between these two functions is miniscule, but the very existence of a difference increases conceptual complexity. Initial attempts to support both functions in V2 proved inelegant, and the decision was made to **not provide any pricing functions in the core**. Instead, pairs directly check whether the invariant was satisfied (accounting for fees) after every trade. This means that rather than relying on a pricing function to *also* enforce the invariant, V2 pairs simply and transparently ensure their own safety, a nice separation of concerns. One downstream benefit is that V2 pairs will more naturally support other flavors of trades which may emerge, (e.g. trading to a specific price at execution time).

At a high level, in Quickswap V2, *trades must be priced in the periphery*. The good news is that the library provides a variety of functions designed to make this quite simple, and all swapping functions in the router are designed with this in mind.

## Pricing Trades

When swapping tokens on Quickswap, 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 Quickswap 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 Quickswap 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).

There are, of course, other options for oracles, including native V2 oracles.

### Exact Input

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. The equivalent SDK function is getOutputAmount, or minimumAmountOut for slippage calculations.

### Exact Output

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. The equivalent SDK function is getInputAmount, or maximumAmountIn for slippage calculations.

### Swap to Price

For this more advanced use case, see ExampleSwapToPrice.sol.


# Understanding Returns

Quickswap 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 Quickswap 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?
>
> 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 Quickswap 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 Quickswap 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 Quickswap 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 loss.** 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)." -->


# Security

## Audit & Formal Verification

Between January 8 and April 30, a team of six engineers reviewed and formally verified crucial components of the smart contracts for Quickswap V2.

Their past work includes smart contract development on and formal verification of multi-collateral DAI.

The scope of work includes:

* Formal verification of the core smart contracts
* Code review of core smart contracts
* Numerical error analysis
* Code review of periphery smart contracts (during ongoing development)

The report also has a "Design Comments" section that we highly recommend for gaining a deep technical understanding of some one the choices made in Quickswap V2.

> [Read the report](https://uniswap.org/audit.html)

## Considerations when building on Quickswap

When integrating Quickswap V2 into another on-chain system, particular care must be taken to avoid security vulnerabilities, avenues for manipulations, and the potential loss of funds.

As a preliminary note: smart contract integrations can happen at two levels: directly with Pair contracts, or through the Router. Direct interactions offer maximal flexibility but require the most work to get right. Mediated interactions offer more limited capabilities but stronger safety guarantees.

There are two primary categories of risk associated with Quickswap V2. The first involves so-called "static" errors. These can include sending too many tokens to a pair during a swap (or requesting too few tokens back) or allowing transactions to linger in the mempool long enough for the sender's expectations about prices to no longer be accurate.

One may address these errors with fairly straightforward logic checks. Executing these logic checks is the primary purpose of routers. Those who interact directly with pairs must perform these checks themselves (with the help of the Library.

"Dynamic" risk, the second category, involves runtime pricing. Because Ethereum transactions occur in an adversarial environment, naively written smart contracts can, and will, be exploited for profit. For example, suppose a smart contract checks the asset ratio in a Quickswap pool at runtime and trades against it, assuming that the ratio represents the "fair" or "market" price of these assets. In that case, it is highly vulnerable to manipulation. A malicious actor could, e.g., trivially insert transactions before and after the naive transaction (a so-called "sandwich" attack), causing the smart contract to trade at a radically worse price, profit from this at the trader's expense, and then return the contracts to their original state, all at a low cost. (One important caveat is that these types of attacks are mitigated by trading in highly liquid pools, or at low values.)

The best way to protect against these attacks is to introduce a price oracle. An oracle is any device that returns desired information, in this case, a pair's spot price. The best "oracle" is simply a traders' off-chain observation of the prevailing price, which can be passed into the trade as a safety check. This strategy is best suited to retail trading venues where users initiate transactions on their own behalf. However, it is often the case that a trusted price observation is not available (e.g., in multi-step, programmatic interactions involving Quickswap). Without a price oracle, these interactions will be forced to trade at whatever the (potentially manipulated) rate on Quickswap is. For details on the Quickswap V2 approach to oracles, see Oracles.


# Math

This section will be expanded in the future. In the mean time, the [Uniswap V2 whitepaper](https://uniswap.org/whitepaper.pdf) has most relevant math for Quickswap V2.


# Research

The automated market maker is a new concept, and as such, new research comes out frequently. We've selected some of the most thoughtful here.

## Uniswap's Financial Alchemy

Authors: Dave White, Martin Tassy, Charlie Noyes, and Dan Robinson

> An automated market maker is a type of decentralized exchange that lets customers trade between on-chain assets like USDC and ETH. Uniswap is the most popular AMM on Ethereum. Like most AMMs, Uniswap facilitates trading between a particular pair of assets by holding reserves of both assets. It sets the trading price between them based on the size of its reserves in such a way that prices will stay in line with the broader market. Anybody who would like to can join the “pool” for a particular pair and become a liquidity provider, or LP, so-called because they provide liquid assets for others to trade against. LPs contribute assets to both reserves simultaneously, taking on some of the risk of trading in exchange for a share of the returns.

* [Uniswap's Financial Alchemy](https://research.paradigm.xyz/uniswaps-alchemy)

## An analysis of Uniswap markets

Authors: Guillermo Angeris, Hsien-Tang Kao, Rei Chiang, Charlie Noyes, Tarun Chitra

> Uniswap---and other constant product markets---appear to work well in practice despite their simplicity. In this paper, we give a simple formal analysis of constant product markets and their generalizations, showing that, under some common conditions, these markets must closely track the reference market price. We also show that Uniswap satisfies many other desirable properties and numerically demonstrate, via a large-scale agent-based simulation, that Uniswap is stable under a wide range of market conditions.

* [An analysis of Uniswap markets](https://arxiv.org/abs/1911.03380)

## Improved Price Oracles: Constant Function Market Makers

Authors: Guillermo Angeris, Tarun Chitra

> Automated market makers, first popularized by Hanson's logarithmic market scoring rule (or LMSR) for prediction markets, have become important building blocks, called 'primitives,' for decentralized finance. A particularly useful primitive is the ability to measure the price of an asset, a problem often known as the pricing oracle problem. In this paper, we focus on the analysis of a very large class of automated market makers, called constant function market makers (or CFMMs) which includes existing popular market makers such as Uniswap, Balancer, and Curve, whose yearly transaction volume totals to billions of dollars. We give sufficient conditions such that, under fairly general assumptions, agents who interact with these constant function market makers are incentivized to correctly report the price of an asset and that they can do so in a computationally efficient way. We also derive several other useful properties that were previously not known. These include lower bounds on the total value of assets held by CFMMs and lower bounds guaranteeing that no agent can, by any set of trades, drain the reserves of assets held by a given CFMM.

* [Improved Price Oracles: Constant Function Market Makers](https://arxiv.org/abs/2003.10001)

## Pintail research

Published [medium](https://medium.com/@pintail) articles by Pintail.

* [Understanding Uniswap Returns](https://medium.com/@pintail/understanding-uniswap-returns-cc593f3499ef)
* [Uniswap: A Good Deal for Liquidity Providers?](https://medium.com/@pintail/uniswap-a-good-deal-for-liquidity-providers-104c0b6816f2)

## Liquidity Provider Returns in Geometric Mean Markets

Authors: Alex Evans

> Geometric mean market makers (G3Ms), such as Uniswap and Balancer, comprise a popular class of automated market makers (AMMs) defined by the following rule: the reserves of the AMM before and after each trade must have the same (weighted) geometric mean. This paper extends several results known for constant-weight G3Ms to the general case of G3Ms with time-varying and potentially stochastic weights. These results include the returns and no-arbitrage prices of liquidity pool (LP) shares that investors receive for supplying liquidity to G3Ms. Using these expressions, we show how to create G3Ms whose LP shares replicate the payoffs of financial derivatives. The resulting hedges are model-independent and exact for derivative contracts whose payoff functions satisfy an elasticity constraint. These strategies allow LP shares to replicate various trading strategies and financial contracts, including standard options. G3Ms are thus shown to be capable of recreating a variety of active trading strategies through passive positions in LP shares.

* [Liquidity Provider Returns in Geometric Mean Markets](https://arxiv.org/abs/2006.08806)

## The Replicating Portfolio of a Constant Product Market

Authors: Joseph Clark

> We derive the replicating portfolio of a constant product market. This is structurally short volatility (selling options) which explains why positive transaction costs are needed to induce liquidity providers to participate. Where futures and options markets do not exist, this payoff can be used to create them.

* <https://papers.ssrn.com/sol3/papers.cfm?abstract_id=3550601>


