# About WhiteSwap

**WhiteSwap** is a decentralized exchange (DEX) built on the Ethereum blockchain. It allows users to trade cryptocurrencies, earn rewards through liquidity provision, and participate in community governance through its native governance token, WSD. WhiteSwap was launched in 2020 as a fork of the Uniswap V2 protocol.&#x20;

&#x20;

The concept behind WhiteSwap is to provide a decentralized exchange platform that operates on the different blockchain networks, such as Ethereum, Tron and Polygon. <br>

WhiteSwap allows users to trade a variety of cryptocurrencies in a secure and transparent manner without the need for intermediaries such as banks or traditional exchanges.

One of the unique features of WhiteSwap is its focus on incentivizing users to participate in the platform. This is done through the use of liquidity pools, which allow users to contribute to the exchange's liquidity in exchange for rewards in the form of liquidity pair tokens. In addition, WhiteSwap also offers yield farming, where users can stake their tokens in farming pools to earn additional rewards. Crypto projects can conduct liquidity mining campaigns and incentivize liquidity provision.&#x20;

&#x20;

WhiteSwap also utilizes an automated market maker (AMM) system to determine the value of assets being traded. This means that the price of an asset is determined by a mathematical formula based on the amount of assets in the liquidity pool, rather than relying on the traditional supply and demand mechanics of a centralized exchange.

&#x20;

WhiteSwap offers various services such as:

* **Swapping.** Users can swap one cryptocurrency for another on the platform. This process is carried out by smart contracts on the Ethereum blockchain, which execute the trade automatically and securely.
* **Liquidity provision.** WhiteSwap is a liquidity provider, which means users can add liquidity to the platform by depositing an equal value of two tokens in a liquidity pool. In return, they receive liquidity provider (LP) tokens, which represent their share of the pool. LP tokens can be used to redeem a proportional amount of the liquidity provided, plus any trading fees generated by the pool.
* **Farming.** WhiteSwap offers a yield farming mechanism where users can earn rewards for providing liquidity to certain pools.
* **Staking.** Users can also stake their WSD tokens to earn rewards. The rewards are generated by the trading fees on the platform and distributed to the WSD stakers.
* **Governance.** WSD token holders can participate in the governance of the WhiteSwap platform by voting on proposals and making decisions on the future development of the platform.

\ <br>


# Protocol Overview


# How WhiteSwap Works

![](https://2789760586-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MKoVw6vJHMOtwEpKtdG%2F-MNNSzq-geBzgOPMvdCv%2F-MNNp6prV2xnBeyyz6DC%2FHow%20WhiteSwap%20works%201.png?alt=media\&token=2a238818-53b1-4d95-9307-38c3b21ab666)

WhiteSwap is an *automated liquidity protocol* powered by a [constant product formula](/protocol-overview/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 **decentralization**, **censorship resistance**, and **security**. WhiteSwap is **open-source software** licensed under the [GPL](https://en.wikipedia.org/wiki/GNU_General_Public_License).

Each WhiteSwap smart contract, or pair, manages a liquidity pool made up of reserves of two [ERC20](https://eips.ethereum.org/EIPS/eip-20) tokens.

Anyone can become a liquidity provider for a pool by depositing an equivalent value of each underlying token in return for pool tokens. These tokens track pro-rata liquidity provider (LP) shares of the total reserves, and can be redeemed for the underlying assets at any time.

![](https://2789760586-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MKoVw6vJHMOtwEpKtdG%2F-MNNSzq-geBzgOPMvdCv%2F-MNNpA7IfDDAbu0-o19X%2FHow%20WhiteSwap%20works%202.png?alt=media\&token=ee24ee99-bdb9-4612-91d5-69c663c0a66e)

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

![](https://2789760586-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MKoVw6vJHMOtwEpKtdG%2F-MNNSzq-geBzgOPMvdCv%2F-MNNpE2xVsc_5BtecQnv%2FHow%20WhiteSwap%20works%203.png?alt=media\&token=d23c34e8-f802-42b2-9564-9f0dc377f5fd)

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

## Further reading <a href="#further-reading" id="further-reading"></a>

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

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


# Eсosystem Participants

[<br>](https://uniswap.org/static/5c04b34a07f986c19f875674de8db66f/6bf9f/participants.jpg)

![](https://2789760586-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MKoVw6vJHMOtwEpKtdG%2F-MLloHeyHp8daEZFQL3d%2F-MLloOqvdhXAI0s9ywSM%2FE%D1%81osystem%20Participants.jpg?alt=media\&token=9c96ba75-30c7-4f1c-80a6-f25eaad1c84e)

The WhiteSwap ecosystem is primarily comprised of three types of users: liquidity providers, traders, and developers. Liquidity providers are incentivized to contribute [ERC20](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](/advanced-topics/fees) (which goes to liquidity providers). Developers can integrate directly with WhiteSwap 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 <a href="#liquidity-providers" id="liquidity-providers"></a>

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

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

## Traders <a href="#traders" id="traders"></a>

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 WhiteSwap protocol.
* Arbitrage bots seek profits by comparing prices across different platforms to find an edge. (Though it might seem extractive, these bots actually help equalize prices across broader Ethereum markets and keep things fair).
* DApp users buy tokens on WhiteSwap for use in other applications on Ethereum.
* Smart contracts execute trades on the protocol by implementing swap functionality (from products like DEX aggregators to custom Solidity scripts).

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

## Developers/Projects <a href="#developersprojects" id="developersprojects"></a>

There are many ways WhiteSwap may be used in the wider Ethereum ecosystem, and some examples include:

* The open-source, accessible nature of WhiteSwap means there are UX experiments and front-ends built to offer access to WhiteSwap functionality.
* Wallets often integrate swapping and liquidity provision functionality as a core offering of their product.
* DEX (decentralized exchange) aggregators pull liquidity from many liquidity protocols to offer traders the best prices but splitting their trades.
* 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, many others.

## WhiteSwap Team and Community <a href="#uniswap-team-and-community" id="uniswap-team-and-community"></a>

The WhiteSwap team, along with the broader WhiteSwap community, drives development of the protocol and ecosystem.


# Smart Contracts

**Governor (**[0x1D734e5de4c4a4b70538Bb52D9A08a8E9468b26f](https://etherscan.io/address/0x1D734e5de4c4a4b70538Bb52D9A08a8E9468b26f))

The contract that governs the protocol through voting. It can push proposals and apply changes through the timelock contract.

**Timelock** ([0x60944aFF520C44Df6d877aE379aBB7Aa704b0b8F](https://etherscan.io/address/0x60944aFF520C44Df6d877aE379aBB7Aa704b0b8F))

This is the administrator of all other contracts and is managed by the Governor contract. For security purposes, code changes have a deferral period. The default deferral period is fixed at 5 days ( 120 hours). This period can change through governance voting.

**Router** ([0x463672ffdED540f7613d3e8248e3a8a51bAF7217](https://etherscan.io/address/0x463672ffdED540f7613d3e8248e3a8a51bAF7217))

This facilitates interaction with smart contracts, allowing references to functions of the code as domain names.

**Factory** ([0x69bd16aE6F507bd3Fc9eCC984d50b04F029EF677](https://etherscan.io/address/0x69bd16aE6F507bd3Fc9eCC984d50b04F029EF677))

Creates new pairs and includes the Protocol Fee switch (which sends 0.05% to the FeeTo address).

**Controller (**[0xA9229c9D3720CD359cEc51A259003C845E4C8224](https://etherscan.io/address/0xA9229c9D3720CD359cEc51A259003C845E4C8224))

Allows updating of the pairs code.

**Escrow** ([0x39D34833d45A973e80D66E07E93512a8c508372C](https://etherscan.io/address/0x39D34833d45A973e80D66E07E93512a8c508372C))

Issues governance tokens into circulation according to the established schedule.

**Staking** ([0x3bAEFcF105f234b62F6793931903503B8dd4af5d](https://etherscan.io/address/0x3bAEFcF105f234b62F6793931903503B8dd4af5d))

A smart contract that provides a reward for staking LP tokens in governance tokens.


# Glossary

#### Automated market maker <a href="#automated-market-maker" id="automated-market-maker"></a>

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

#### Constant product formula <a href="#constant-product-formula" id="constant-product-formula"></a>

The automated market making algorithm used by WhiteSwap. See [x\*y=k](/protocol-overview/glossary#x--y--k).

#### ERC20 <a href="#erc20" id="erc20"></a>

ERC20 tokens are fungible tokens on Ethereum. WhiteSwap 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 WhiteSwap 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 WhiteSwap, 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 WhiteSwap 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 WhiteSwap 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

![](https://2789760586-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MKoVw6vJHMOtwEpKtdG%2F-MNNSzq-geBzgOPMvdCv%2F-MNNqzZvAU-1_DgT6RSw%2FPool%203.png?alt=media\&token=d7f82c44-ee6a-475e-b6cf-7b622c434eee)

## Introduction <a href="#introduction" id="introduction"></a>

Token swaps in WhiteSwap are a simple way to trade one ERC20 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 WhiteSwap works.

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

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

This rule is the [constant product formula](/protocol-overview/glossary#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 <a href="#anatomy-of-a-swap" id="anatomy-of-a-swap"></a>

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

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

## Receiving tokens <a href="#receiving-tokens" id="receiving-tokens"></a>

As is probably clear from the function signature, WhiteSwap 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 <a href="#sending-tokens" id="sending-tokens"></a>

What’s not as clear is how WhiteSwap *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 WhiteSwap pairs accept tokens. Instead, pairs check their token balances at the *end* of every interaction. Then, at the beginning of the *next* interaction, current balances are differenced against the stored values to determine the amount of tokens that were sent by the current interactor.&#x20;

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

## Developer resource <a href="#developer-resources" id="developer-resources"></a>

* To see how to execute a swap from an interface read [Trading (SDK)](/developer-guides/javascript-sdk/trading)


# Pools

![](https://2789760586-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MKoVw6vJHMOtwEpKtdG%2F-MNNSzq-geBzgOPMvdCv%2F-MNNqVTtKnAs26ipNR4Q%2FPool%201.png?alt=media\&token=3d88a4fa-1a6b-4d1d-9b02-77c367508259)

## Introduction <a href="#introduction" id="introduction"></a>

Each WhiteSwap 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 <a href="#pool-tokens" id="pool-tokens"></a>

![](https://2789760586-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MKoVw6vJHMOtwEpKtdG%2F-MNNSzq-geBzgOPMvdCv%2F-MNNqb1xR75m_Ip2__GB%2FPool%202.png?alt=media\&token=33156bea-1f1e-46b5-bf87-2f57baad8733)

Whenever liquidity is deposited into a pool, special tokens known as *liquidity tokens* are minted to the provider’s address, in proportion to how much liquidity they contributed to the pool. These tokens are a representation of a liquidity provider’s contribution to a pool. Whenever a trade occurs, the 0.3% fee which is levied is distributed *pro-rata* to all LPs in the pool at the moment of the trade. To receive the underlying liquidity back, plus any fees that were accrued while their liquidity was locked, LPs must burn their liquidity tokens.

Liquidity providers can also choose to sell, transfer, or otherwise use their liquidity tokens in any way they see fit.

Learn more with advanced topics:

[Understanding Returns](/advanced-topics/understanding-returns)

[Fees](/advanced-topics/fees)

## Why pools? <a href="#why-pools" id="why-pools"></a>

WhiteSwap 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, WhiteSwap 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 infrastrucural trade-offs presented by a platform like Ethereum, order books are not the native architecture for implementing a liquidity protocol on a blockchain.

WhiteSwap focuses on the strengths of Ethereum to re-imagine 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 WhiteSwap protocol through the interface (which in turn interacts with the underlying contracts), developers can interact directly with the smart contracts and integrate WhiteSwap functionality into their own applications without relying on intermediaries or needing permission.


# Flash Swaps

WhiteSwap flash swaps allow you to withdraw up to the full reserves of any ERC20 token on WhiteSwap 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 WhiteSwap.

## Examples <a href="#examples" id="examples"></a>

### Capital Free Arbitrage <a href="#capital-free-arbitrage" id="capital-free-arbitrage"></a>

One particularly interesting use case for flash swaps is capital-free arbitrage. It’s well-known that an integral part of WhiteSwap's design is to create incentives for arbitrageurs to trade the WhiteSwap 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 WhiteSwap is 200 DAI (which is calculated by calling `getAmountIn` with 1 ETH specified as an exact output), and on Oasis (or any other trading venue), 1 ETH buys 220 DAI. To anyone with 200 DAI available, this situation represents a risk-free profit of 20 DAI. Unfortunately, you may not have 200 DAI lying around. With flash swaps, however, this risk-free profit is available for anyone to take as long as they’re able to pay gas fees.

#### Withdrawing ETH from WhiteSwap <a href="#withdrawing-eth-from-uniswap" id="withdrawing-eth-from-uniswap"></a>

The first step is to *optimistically* withdraw 1 ETH from WhiteSwap 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 WhiteSwap 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 WhiteSwap market price is far enough above or below this external price, the following example contains code that calculates the amount to trade over WhiteSwap for maximum profit: [`ExampleSwapToPrice.sol`](https://github.com/WhiteSwap/whiteswap-contracts/blob/main/contracts/examples/ExampleFlashSwap.sol).

#### Trade at External Venue <a href="#trade-at-external-venue" id="trade-at-external-venue"></a>

Once we’ve obtained our temporary capital of 1 ETH from WhiteSwap , we now can trade this for 220 DAI on Oasis. Once we’ve received the DAI, we need to pay WhiteSwap 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 WhiteSwap pair, you’re left with 20 DAI of profit!

### Instant Leverage <a href="#instant-leverage" id="instant-leverage"></a>

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

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 WhiteSwap as a liquidity source for the DAI-to-ETH component of this process. However, looping through protocols in this way isn’t particularly elegant, and can be gas-intensive.

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


# Oracles

## Introduction <a href="#introduction" id="introduction"></a>

WhiteSwap enables building highly decentralized and manipulation-resistant on-chain price oracles.

Price oracles are crucial to the viability and security of DeFi protocols. Oracle designs between different projects 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 main attack vector.

Some of these vulnerabilities have been discussed [here](https://samczsun.com/taking-undercollateralized-loans-for-fun-and-for-profit/). A lack of a robust price oracle has held back both the adoption of DeFi and made it difficult and costly for new entrants to launch new derivative products.

Enter WhiteSwap. As liquidity and trade volume on the protocol continue to grow, WhiteSwap's on-chain trade history is becoming an evermore valuable, accurate, and robust source of price information. This insight has been formalized into the Price Oracle mechanism in WhiteSwap.

## Why Oracles? <a href="#why-oracles" id="why-oracles"></a>

On-chain price feeds are a critical component for many decentralized financial applications including those similar to derivatives, lending, margin trading, prediction markets, and more.

## WhiteSwap Solution <a href="#uniswap-v2-solution" id="uniswap-v2-solution"></a>

WhiteSwap includes a number of improvements for price feeds built on top of it. 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 was set by the last transaction 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 be able to 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 a number of challenges and [has not been observed to date](https://arxiv.org/abs/1912.01798).

This alone is not enough. If significant value settles based on the price resulting from this mechanism, then the profit of an attack likely can outweigh the loss.

Instead, WhiteSwap 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 WhiteSwap price for every second in the entire history of the contract.**

![](https://2789760586-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MKoVw6vJHMOtwEpKtdG%2F-MNNSzq-geBzgOPMvdCv%2F-MNNqB0aUeEU_lr1LHxQ%2FOracles%201.png?alt=media\&token=31990cce-dd96-4ca9-862c-cfb0125f9bdb)

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

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

![](https://2789760586-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MKoVw6vJHMOtwEpKtdG%2F-MNNSzq-geBzgOPMvdCv%2F-MNNqElvgoHxKcK6uoNp%2FOracles%201-1.png?alt=media\&token=2e4ed701-5cca-48c6-83ea-b78efe204539)

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 WhiteSwap, as well as (approx. linear) with the length of time over which you average.
* 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 WhiteSwap 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/WhiteSwap/whiteswap-contracts/blob/main/contracts/examples/ExampleOracleSimple.sol) of a 24 hr TWAP Oracle built on WhiteSwap!

In summary, WhiteSwap introduces a 2 new variables in each pair, `price0CumulativeLast` and `price1CumulativeLast`, which store the prices of `token0` and `token1` respectively, multiplied by for how long they were observed (in seconds). These variables are cumulative, meaning they are ever-increasing. They are updated with the first `swap`/`mint`/`burn` of each block.

You can use these either of these new variables to compute an average price between 2 observations. To do so, take the difference (i.e. subtraction) of two observations, and divide by the time elapsed between them. This is the basis of building oracles on top of WhiteSwap.

### Manipulation Resistance <a href="#manipulation-resistance" id="manipulation-resistance"></a>

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

Other factors such as network congestion can reduce the cost of attack. For a more in-depth review of the security of WhiteSwap price oracles, read the [security audit section on Oracle Integrity](https://ws.exchange/assets/WhiteSwap-SC-Audit-Report-v2.pdf).

### Using WhiteSwap Price Oracles <a href="#using-uniswap-v2-price-oracles" id="using-uniswap-v2-price-oracles"></a>

Importantly, WhiteSwap is not opinionated on how you use the new cumulative price variables, allowing you to build oracles that compute different kinds of price averages and over different periods.


# Farming

## Introduction

We have developed a farming pool proposal with the aim of offering a sustainable avenue for cryptocurrency investors to generate passive income. Through the utilization of liquidity pooling and yield farming strategies, we are confident that our farming pools proposal can provide superior returns and minimize risks when compared to conventional investment options.

To ensure the utmost security and transparency, our proposal will be audited by Hacken.io.&#x20;

In our pursuit of yield farming, we will adhere to a community-driven governance model, where decisions will be made in the best interest of our users.

## Description

The farming pool serves as a liquidity mining mechanism that empowers liquidity pool creators to distribute additional tokens from their project to users.

Within the farming pool, users have the opportunity to stake their liquidity in a liquidity pool and, in return, receive LP tokens. These LP tokens can then be further staked in the farming pool contract, where users will be rewarded with additional tokens as an incentive.<br>

To establish a farm pool on WhiteSwap, any user can complete a request form. Within this form, users need to specify their desired existing liquidity pool on WhiteSwap and provide the corresponding link. Additionally, users must choose a reward token from a linked pair of liquidity pools, selecting either token A or token B as a reward token to distribute. It is also necessary to indicate the start and end dates of the farming pool and commit to locking up a minimum of 5000 WSD tokens for at least one year or for the entire duration of the farming pool if it extends beyond one year. Once the expiration date is reached, users can retrieve their tokens.\
\
The WhiteSwap team will deduct 5% of the 5000 WSD tokens as the protocol revenue, that will further be redistributed back to WSD token holders after the upcoming WSD staking update.<br>

The farming pools update proposal will be live for your vote shortly.


# WSD Staking

<figure><img src="https://2789760586-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MKoVw6vJHMOtwEpKtdG%2Fuploads%2F1xHw7IqZxBTXrKhZ0nvY%2Fimage.png?alt=media&amp;token=5fa11bd7-d99a-4280-b3e0-471592d0d59b" alt=""><figcaption></figcaption></figure>

## Introduction

Soon, users will have the opportunity to stake their WSD tokens and receive reward tokens in the form of additional WSD tokens. This is the second part of the protocol update, we will publish the staking update governance proposal soon after the farming update proposal.

### Why staking?

Here's how it works: When users stake their WSD tokens, we will implement a mechanism where we charge a percentage from each swap made on our platform. Specifically, we will deduct 0.06% from the 0.3% swap fee for the purpose of conducting a buyback of WSD tokens. These bought-back tokens will then be issued as rewards to our staking users.

What sets our staking functionality apart is its broad reach. We have extended support for multiple blockchain networks, including Ethereum, Tron, and Polygon. This means that the 0.06% charge will be applied to each swap made in every liquidity pool across these supported blockchain networks.

With our staking functionality, users can enjoy the benefits of passive income by staking their WSD tokens and receiving rewards in return.\
\
The staking update governance proposal will be live shortly after the upcoming farming pools proposal.

Stay tuned for the launch of this exciting feature that will enable users to maximize their holdings and get their share of the protocol's revenue while actively participating in our platform.

<br>


# Advanced Topics


# Fees

### Liquidity provider fees <a href="#liquidity-provider-fees" id="liquidity-provider-fees"></a>

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

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

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

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

### Protocol Fees <a href="#protocol-fees" id="protocol-fees"></a>

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

### Protocol Charge Calculation <a href="#protocol-charge-calculation" id="protocol-charge-calculation"></a>

In the future, it is possible that a protocol-wide charge of 0.06% per trade will take effect. This represents 1/5th (20%) 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? <a href="#how-are-prices-determined" id="how-are-prices-determined"></a>

As we learned in [Protocol Overview](/protocol-overview), each pair on WhiteSwap 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](/protocol-overview/glossary#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 WhiteSwap Handles Prices <a href="#how-uniswap-handles-prices" id="how-uniswap-handles-prices"></a>

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, WhiteSwap pairs simply and transparently ensure their own safety, a nice separation of concerns. One downstream benefit is that WhiteSwap 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 WhiteSwap, *trades must be priced in the periphery*. The good news is that the library contract provides a variety of functions designed to make this quite simple, and all swapping functions in the router contract are designed with this in mind.

## Pricing Trades <a href="#pricing-trades" id="pricing-trades"></a>

When swapping tokens on WhiteSwap, 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 WhiteSwap 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 WhiteSwap frontend ensures 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 WhiteSwap oracles](/core-concepts/oracles).

### Exact Input <a href="#exact-input" id="exact-input"></a>

If you’d like to send an exact amount of input tokens in exchange for as many output tokens as possible, you’ll want to use getAmountsOut. The equivalent SDK function is [getOutputAmount](/reference/sdk/pair#getoutputamount), or [minimumAmountOut](/reference/sdk/trade#minimumamountout-since-204) for slippage calculations.

### Exact Output <a href="#exact-output" id="exact-output"></a>

If you’d like to receive an exact amount of output tokens for as few input tokens as possible, you’ll want to use getAmountsIn. The equivalent SDK function is [getInputAmount](/reference/sdk/pair#getinputamount), or [maximumAmountIn](/reference/sdk/trade#maximumamountin-since-204) for slippage calculations.

### Swap to Price <a href="#swap-to-price" id="swap-to-price"></a>

For this more advanced use case, see [ExampleSwapToPrice.sol](https://github.com/WhiteSwap/whiteswap-contracts/blob/main/contracts/examples/ExampleSwapToPrice.sol)


# Understanding Returns

WhiteSwap incentivizes users to add liquidity to pools by rewarding providers with fees on trades. Market making, in general, is a complex activity that has the risk of losing money (compared to just **hodling**) in the case of big directional moves of the underlying asset price.

## Risks <a href="#risks" id="risks"></a>

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.


# Security

## Audit & Formal Verification <a href="#audit--formal-verification" id="audit--formal-verification"></a>

Between October 30th, 2020 – November 5 th, 2020, Hacken team reviewed and formally verified crucial components of the smart contracts for Whiteswap.

Their past work includes formal verification, security assessment, blockchain protocol security.

The scope of work includes:

* Commonly known vulnerabilities scanning
* Analysis of code functionality
* Manual audit

&#x20;[Read the report->](https://ws.exchange/assets/WhiteSwap-SC-Audit-Report-v2.pdf)

## Bug Bounty <a href="#bug-bounty" id="bug-bounty"></a>

WhiteSwap has an open and ongoing bug bounty program. [Read about Bug Bounty](https://ws.exchange/bug-bounty)

## Considerations When Building on WhiteSwap <a href="#considerations-when-building-on-uniswap" id="considerations-when-building-on-uniswap"></a>

When integrating WhiteSwap 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 WhiteSwap. The first involves so-called “static” errors: accidentally sending too many tokens to a pair during a swap (or requesting too few tokens back), allowing transactions to linger in the mempool long enough for the sender’s expectations about prices to no longer be true, etc. These errors are typically addressed with fairly straightforward logic checks. *Performing these checks is the primary reason for the existence of routers*. Those who interact directly with pairs must perform these checks themselves (with the help of the Library).

The second risk category is “dynamic”, and involves runtime pricing. Because Ethereum transactions occur in an adversarial environment, naively written smart contracts *can be exploited for profit*. For example, if a smart contract checks the asset ratio in a WhiteSwap pool at runtime and trades against it, assuming that the ratio represents the “fair” or “market” price of these assets, *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 extremely liquid pools and/or at low values).

The best way to protect against these attacks is to introduce a price oracle. The best “oracle” is simply *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 trades on their own behalf*. However, it is often the case that a trusted price observation cannot be obtained (e.g. in multi-step, programmatic interactions involving WhiteSwap). Without a price oracle, these interactions are forced to trade at whatever the (potentially manipulated) rate on WhiteSwap is. However, an oracle can bound manipulation, and is a sine qua non. Determining the ideal oracle for a given setting is out of scope, but for details on the WhiteSwap approach to oracles, see [Oracles](/core-concepts/oracles).


# Research

Because the concept of AMMs is so new, many people have begun researching related projects in  academic settings. The following are some related publications.

## An analysis of Uniswap markets <a href="#an-analysis-of-uniswap-markets" id="an-analysis-of-uniswap-markets"></a>

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 <a href="#improved-price-oracles-constant-function-market-makers" id="improved-price-oracles-constant-function-market-makers"></a>

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 <a href="#pintail-research" id="pintail-research"></a>

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 <a href="#liquidity-provider-returns-in-geometric-mean-markets" id="liquidity-provider-returns-in-geometric-mean-markets"></a>

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)

This is a stub. Help us expand it by submitting a PR using the github link below!

## The Replicating Portfolio of a Constant Product Market <a href="#the-replicating-portfolio-of-a-constant-product-market" id="the-replicating-portfolio-of-a-constant-product-market"></a>

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>


# Governance


# Overview

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

[`governance`](https://github.com/WhiteSwap/whiteswap-contracts/tree/main/contracts/governance)

## Documentation <a href="#documentation" id="documentation"></a>

For reference material on the WhiteSwap Governance system, which was forked from the Compound Governance system, please see [their documentation](https://compound.finance/docs/governance).\
\
All of the contracts are linked [here](https://github.com/WhiteSwap/whiteswap-contracts/tree/main/build).

## WSD Address <a href="#uni-address" id="uni-address"></a>

`WSD` is deployed at 0x0423d7C27D1dDE7Eb4aaE02Dae6B651C7225e6f9[^1] on the Ethereum [mainnet](https://etherscan.io/address/0x77b8ae2E83c7d044d159878445841E2A9777Af38).

### ABI <a href="#abi" id="abi"></a>

```
import WSGov from 'build/WSGov.json'
```

## Timelock <a href="#timelock" id="timelock"></a>

`Timelock` is deployed at `0x60944aFF520C44Df6d877aE379aBB7Aa704b0b8F` on the Ethereum [mainnet](https://etherscan.io/address/0x60944aFF520C44Df6d877aE379aBB7Aa704b0b8F), and the [Rinkeby](https://rinkeby.etherscan.io/address/0x60944aFF520C44Df6d877aE379aBB7Aa704b0b8F) testnet. It was built from commit [ab27e08](https://github.com/WhiteSwap/whiteswap-contracts/commit/aa27e089804de2b8fbe54f56287a661395c3f70b).

### ABI <a href="#abi-1" id="abi-1"></a>

```
import Timelock from '/build/Timelock.json'
```

## GovernorAlpha <a href="#governoralpha" id="governoralpha"></a>

`GovernorAlpha` is deployed at `0x1D734e5de4c4a4b70538Bb52D9A08a8E9468b26f` on the Ethereum [mainnet](https://etherscan.io/address/0x1D734e5de4c4a4b70538Bb52D9A08a8E9468b26f), and the [Rinkeby](https://rinkeby.etherscan.io/address/0x1D734e5de4c4a4b70538Bb52D9A08a8E9468b26f) testnet. It was built from commit [ab27e08](https://github.com/WhiteSwap/whiteswap-contracts/commit/aa27e089804de2b8fbe54f56287a661395c3f70b).

### ABI <a href="#abi-2" id="abi-2"></a>

```
import GovernorAlpha from '/build/GovernorAlpha.json'
```

## &#x20;<a href="#miscellaneous-addresses" id="miscellaneous-addresses"></a>

[^1]: Token contract address


# Process

This document is a living document which represents the current process guidelines for developing and advancing WhiteSwap Governance Proposals.

### Process <a href="#process" id="process"></a>

WhiteSwap has a couple governance venues, each serving its own purpose.

1\. [*gov.ws.exchange*](https://gov.ws.exchange/)

<https://gov.ws.exchange/> is a Discourse-hosted forum for governance-related discussion. Community members must register for an account before sharing or liking posts. New members are required to enter 4 topics and read 15 posts over the course of 10 minutes before they are permitted to post themselves.

2\. [*Snapshot*](https://snapshot.page/#/wse.eth)

Snapshot is a simple voting interface that allows users to signal sentiment off-chain. Votes on snapshot are weighted by the number of WSD delegated to the address used to vote.

3\. [*Governance Portal*](https://ws.exchange/vote)

The formal governance portal can be accessed directly through the WhiteSwap app interface. Votes are delegated and cast through the portal.

Below we outline a preliminary draft for the WhiteSwap governance process, detailing exactly where these venues fit in. These processes are subject to change according to feedback from the WhiteSwap community.

#### Phase 1: Temperature Check — Discourse <a href="#phase-1-temperature-check--discoursesnapshot" id="phase-1-temperature-check--discoursesnapshot"></a>

The purpose of the Temperature Check is to determine if there is sufficient will to make changes to the status quo.

To create a Temperature Check:\
Ask a general, non-biased question to the community on <https://gov.ws.exchange/> about a potential change (example: "Should WhiteSwap governance add liquidity mining for XYZ token?"). Forum posts should be labeled as follows: "Temperature Check - \[Your Title Here]". The forum post should include a link to the associated Snapshot poll.

If the Temperature check does not suggest a change from the status quo, the topic will be closed on the governance site. If the Temperature Check does suggest a change, proceed to Stage 2: Consensus Check.

#### Phase 2: Consensus Check — Discourse/Snapshot <a href="#phase-2-consensus-check--discoursesnapshot" id="phase-2-consensus-check--discoursesnapshot"></a>

The purpose of the Consensus Check is to establish formal discussion around a potential proposal.

To create a Consensus Check:

1. Use feedback from the Temperature Check post and create a new Snapshot poll which covers the options which have gained support. This poll can either be binary or multiple choice but you are required to include the option ”Make no change” or its equivalent. Set the poll duration to 5 days.
2. Create a new topic in the Proposal Discussion category on <https://gov.ws.exchange/> titled ”Consensus Check — \[Your Title Here]”. This will alert the community that this topic has already passed Temperature Check. Any topics beginning with Consensus Check that have not passed Temperature Check will immediately be removed by moderators. Make sure that the discussion thread links to the Temperature Check thread.
3. Reach out to your network to build support for the proposal. Discuss the proposal and actively solicit delegates to vote on it. Be willing to respond to questions on the Consensus Check topic. Share your view point, although try to remain as impartial as possible.

#### Phase 3: Governance Proposal — Governance Portal <a href="#phase-3-governance-proposal--governance-portal" id="phase-3-governance-proposal--governance-portal"></a>

Phase 3 — Governance Proposal — is the final step of the governance process. The proposal should be based on the winning outcome from the Consensus Check and can consist of one or multiple actions, up to a maximum of 10 actions per proposal. Your proposal must be done in a format described in step 4.&#x20;

To create a Governance Proposal:

1. Write the code for your proposal, which will be voted on through the Governance Portal. More resources can be found [here](https://compound.finance/docs/governance#propose)**.** All proposed code should be audited by a professional auditor. This auditing process may be paid or reimbursed by the community treasury.
2. Ensure that you have at least 5 million WSD delegated to your address in order to submit a proposal, or find someone who has enough WSD to meet the proposal threshold to propose on your behalf.
3. Create a topic in the Proposal Discussion category on <https://gov.ws.exchange/> titled "Governance Proposal — \[Your Title Here]" and link to any relevant discussion threads as well as the code audit report. Topics that begin with "Governance Proposal" that have not successfully passed through the Temperature Check and Consensus Check stages will be removed by moderators.
4. Create a description in .json format {"discource": " ", "description":" "} . It needs to have key "discourse" with the link to the forum discussion, and key "description" with details of the proposal in markdown format.&#x20;
5. Call the propose() function of the Governor Alpha to deploy your proposal.

Once the propose() function has been called, a seven-day voting period will start. Ongoing discussion can take place in the <https://gov.ws.exchange/> forum. If the proposal passes successfully, a two day timelock will follow before the proposed code is executed.

### Soft Governance <a href="#soft-governance" id="soft-governance"></a>

The process described above lays out a structure for those wishing to host a formal vote around a particular issue.

However, governing this system also requires a degree of "meta governance", discussions that inform the direction of and the implementation processes behind policy but which don’t qualify as policy themselves.

The community may discuss new ideas and strategies for governance — including changes to the three-step process outlined above — in the ”Governance-Meta” category. On-chain voting is not necessary to make updates to off-chain processes.


# Glossary

**WSD:** An ERC20 token that designates the weight of a user’s voting rights. The more WSD a user has in their wallet, the more weight their delegation or vote on a proposal holds.

**Delegation:** WSD holders cannot vote or create proposals until they delegate their voting rights to an address. Delegation can be given to one address at a time, including the holder’s own address. Note that delegation does not lock tokens; it simply adds votes to the chosen delegation address.

**Proposal:** A proposal is executable code that modifies the governance contract or treasury and how they work. In order to create a proposal, a user must have at least 0.5% (5 MM WSD) of all WSD delegated to their address. Proposals are stored in the "proposals" mapping of the Governor smart contract. All proposals are subject to a 7-day voting period. If the proposer does not maintain their vote weight balance throughout the voting period, the proposal may be canceled by anyone.

**Quorum:** In order for a vote to pass, it must achieve quorum of 4% of all WSD (40 MM) voting in the affirmative. The purpose of the quorum is to ensure that the only measures that pass have adequate voter participation.

**Voting:** Users can vote for or against single proposals once they have voting rights delegated to their address. Votes can be cast while a proposal is in the "Active" state. Votes can be submitted immediately using "castVote" or submitted later with "castVoteBySig" (For more info on castVoteBySig and offline signatures, see EIP-712). If the majority of votes (and a 4% quorum of WSD) vote for a proposal, the proposal may be queued in the Timelock.

**Voting Period:** Once a proposal has been put forward, WhiteSwap community members will have a 7-day period (the Voting Period) to cast their votes.

**Timelock:** All governance and other administrative actions are required to sit in the Timelock for a minimum of 5 days, after which they can be implemented.


# Introducing WSD

### What’s a Governance Token?

Governance tokens give their holders the power to influence the direction in which the project will move. This means the users are a direct stakeholder in the DeFi platforms.

### What’s the use of Governance Tokens?

On-chain governance gives every stakeholder an opportunity to discuss and vote on how to manage the protocol. When any changes are proposed, the governance token holders can support or disagree with them by voting. The system is the following: each governance token equals one vote. It means that the more tokens a holder has, the easier they can sway over the protocol.

***WSD holders will have immediate ownership of:***

* WhiteSwap governance
* WSD community treasury
* The protocol fee switch
* WhiteSwap Default Token List

***Initial governance parameters are as follows:***

* 0.5% of WSD total supply (delegated) to submit a governance proposal
* 4% of WSD supply required to vote ’yes’ to reach quorum
* 7 day voting period
* 5 day timelock delay on execution


# Allocation & Vesting

The current total supply is capped at 1 billion WSD and will become accessible over the course of five years. The initial token allocation is as follows:

* 70% to [WhiteSwap community](/governance-token/community-treasury) members: 700,000,000 WSD
* 13% to the foundation with four-year vesting: 130,000,000 WSD
* 13% to the investors with four-year vesting: 130,000,000 WSD
* 3% to the team members with four-year vesting: 30,000,000 WSD
* 1% to the advisors with four-year vesting: 10,000,000 WSD

***Community, team, foundation, investors and advisor tokens are subject to vesting, according to the following schedule via the*** [***new vesting smart contract:***](https://etherscan.io/address/0xb8be4e77a93016f6aa37785eb0521fcf606e7d97)

<table><thead><tr><th width="160">Timeline</th><th width="149">Investors</th><th width="150">Foundation</th><th width="150">Team</th><th>Advisors</th></tr></thead><tbody><tr><td></td><td></td><td></td><td></td><td></td></tr></tbody></table>

| 416,665 |
| ------- |
| 416,665 |
| 416,665 |
| 416,665 |
| 416,665 |
| 416,665 |
| 416,665 |
| 416,665 |
| 416,665 |
| 416,665 |
| 416,665 |
| 416,665 |
| 416,665 |
| 416,665 |
| 416,665 |
| 416,665 |
| 416,665 |
| 416,665 |
| 416,665 |
| 416,665 |
| 416,665 |
| 416,665 |
| 416,665 |
| 416705  |

| 1,250,000 |
| --------- |
| 1,250,000 |
| 1,250,000 |
| 1,250,000 |
| 1,250,000 |
| 1,250,000 |
| 1,250,000 |
| 1,250,000 |
| 1,250,000 |
| 1,250,000 |
| 1,250,000 |
| 1,250,000 |
| 1,250,000 |
| 1,250,000 |
| 1,250,000 |
| 1,250,000 |
| 1,250,000 |
| 1,250,000 |
| 1,250,000 |
| 1,250,000 |
| 1,250,000 |
| 1,250,000 |
| 1,250,000 |
| 1,250,000 |

| 5,416,665 |
| --------- |
| 5,416,665 |
| 5,416,665 |
| 5,416,665 |
| 5,416,665 |
| 5,416,665 |
| 5,416,665 |
| 5,416,665 |
| 5,416,665 |
| 5,416,665 |
| 5,416,665 |
| 5,416,665 |
| 5,416,665 |
| 5,416,665 |
| 5,416,665 |
| 5,416,665 |
| 5,416,665 |
| 5,416,665 |
| 5,416,665 |
| 5,416,665 |
| 5,416,665 |
| 5,416,665 |
| 5,416,665 |
| 5,416,705 |

| 5,416,665 |
| --------- |
| 5,416,665 |
| 5,416,665 |
| 5,416,665 |
| 5,416,665 |
| 5,416,665 |
| 5,416,665 |
| 5,416,665 |
| 5,416,665 |
| 5,416,665 |
| 5,416,665 |
| 5,416,665 |
| 5,416,665 |
| 5,416,665 |
| 5,416,665 |
| 5,416,665 |
| 5,416,665 |
| 5,416,665 |
| 5,416,665 |
| 5,416,665 |
| 5,416,665 |
| 5,416,665 |
| 5,416,665 |
| 5,416,705 |

| 2025 Q1 |
| ------- |
| 2025 Q2 |
| 2025 Q3 |
| 2025 Q4 |
| 2026 Q1 |
| 2026 Q2 |
| 2026 Q3 |
| 2026 Q4 |
| 2027 Q1 |
| 2027 Q2 |
| 2027 Q3 |
| 2027 Q4 |
| 2028 Q1 |
| 2028 Q2 |
| 2028 Q3 |
| 2028 Q4 |
| 2029 Q1 |
| 2029 Q2 |
| 2029 Q3 |
| 2029 Q4 |
| 2030 Q1 |
| 2030 Q2 |
| 2030 Q3 |
| 2030 Q4 |


# Community Treasury

WSD will vest to the governance treasury on a continuous basis according to the following schedule.<br>

| Year / Quarter | WSD |
| -------------- | --- |
|                |     |

| 0          |
| ---------- |
| 90,000,000 |
| 5,000,000  |
| 5,000,000  |
| 21,428,571 |
| 21,428,571 |
| 21,428,571 |
| 21,428,571 |
| 21,428,571 |
| 21,428,571 |
| 21,428,571 |
| 21,428,571 |
| 21,428,571 |
| 21,428,571 |
| 21,428,571 |
| 21,428,571 |
| 21,428,571 |
| 21,428,571 |
| 21,428,571 |
| 21,428,571 |
| 21,428,571 |
| 21,428,571 |
| 21,428,571 |
| 21,428,571 |
| 21,428,571 |
| 21,428,571 |
| 21,428,571 |
| 21,428,571 |
| 21,428,571 |
| 21,428,571 |
| 21,428,571 |
| 21,428,583 |

| 2023 Q1 |
| ------- |
| 2023 Q2 |
| 2023 Q3 |
| 2023 Q4 |
| 2024 Q1 |
| 2024 Q2 |
| 2024 Q3 |
| 2024 Q4 |
| 2025 Q1 |
| 2025 Q2 |
| 2025 Q3 |
| 2025 Q4 |
| 2026 Q1 |
| 2026 Q2 |
| 2026 Q3 |
| 2026 Q4 |
| 2027 Q1 |
| 2027 Q2 |
| 2027 Q3 |
| 2027 Q4 |
| 2028 Q1 |
| 2028 Q2 |
| 2028 Q3 |
| 2028 Q4 |
| 2029 Q1 |
| 2029 Q2 |
| 2029 Q3 |
| 2029 Q4 |
| 2030 Q1 |
| 2030 Q2 |
| 2030 Q3 |
| 2030 Q4 |

<br>


# Token Listing

**Listing Token Functionality on WhiteSwap**

**Introduction**

The purpose of this description is to outline the mechanism and process of listing a token on the WhiteSwap platform. Listing a token on WhiteSwap offers users the opportunity to showcase their tokens, ensuring security verification by WhiteSwap, and actively participate in the WhiteSwap ecosystem. It also grants users the ability to create farming pools, thereby unlocking additional earning potential.

Values of token listing:

* Create farming pool;
* White list of token.

**Listing Token Process on WhiteSwap**

The following steps outline the process for successfully listing a token on WhiteSwap:

**Step 1: User Access**

Any user has the opportunity to list the token by visiting either the WhiteSwap landing page or its main page.

**Step 2: Navigation and Initiating Listing**

Users easily navigate the WhiteSwap landing page or its main page and click on the "[Token Listing](https://app.ws.exchange/eth/mainnet/token-listing)" button, conveniently positioned in the landing page's footer or at the upper right corner of the main WhiteSwap page.

**Step 3: Form Submission**

The website directs users to a form where they are required to fill in the token-related information. Users must carefully complete all the necessary fields in the form.

**Step 4: Preparation of Required Documentation**

Before filling out the form, users need to prepare the following documentation and information:

* Security Audit Report from an auditing company, providing assurance of the token's security.
* Whitepaper detailing the tokenomics and utility value.
* Project documentation representing information about token’s technology, underlying principles, development team, and future plans.
* Social media data related to the token, such as links to official social media channels, enabling users to gather additional information about the token.
* Willingness to answer a few open-ended questions honestly, which may be asked during the application review process.

**Step 5: Form Submission and Review**

After completing the form, users submit it for review. The submitted token listing application undergoes thorough a review process.

**Step 6: Administrator Decision**

The administrator carefully reviews the submitted application and makes a decision to approve or reject the token listing on WhiteSwap.

**Step 7: Payment of Listing Fee**

If the token listing application is approved, the user is required to pay a listing fee of 100 WSD tokens. This fee supports the maintenance and development of the WhiteSwap platform.

**Step 8: Payment Notification**

Upon approval, the user receives an email containing a payment link for the listing fee.

**Step 9: Token Listing**

After successful payment, the token is listed on the WhiteSwap platform, becoming available for trading and exchange.

**Step 10: Token Display**

The listed token is displayed on the WhiteSwap infoportal, where users can access detailed information about the token.

**Step 11: Liquidity Pool Availability**

Tokens that have successfully completed the listing process and have a corresponding pair in the liquidity pool become eligible for creating a farming pool on WhiteSwap.


# Javascript SDK


# SDK Quick Start

The WhiteSwap SDK exists to help developers build on top of WhiteSwap. 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 <a href="#installation" id="installation"></a>

The easiest way to consume the SDK is via npm. To install it in your project, simply run `yarn add @whiteswap/sdk` (or `npm install @whiteswap/sdk`).

## Usage <a href="#usage" id="usage"></a>

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) <a href="#es6-import" id="es6-import"></a>

```
import { ChainId } from '@whiteswap/sdk'
console.log(`The chainId of mainnet is ${ChainId.MAINNET}.`)
```

### CommonJS (require) <a href="#commonjs-require" id="commonjs-require"></a>

```
const WHITESWAP = require('@whiteswap/sdk')
console.log(`The chainId of mainnet is ${WHITESWAP.ChainId.MAINNET}.`)
```

## Reference

Comprehensive reference material for the SDK is available [here](/reference/sdk).


# Fetching Data

Looking for a [quickstart](/developer-guides/javascript-sdk/sdk-quick-start)?

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 <a href="#case-1-tokens" id="case-1-tokens"></a>

Unsurprisingly, the SDK needs some notion of an ERC20 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 <a href="#identifying-data" id="identifying-data"></a>

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 `0x6B175474E89094C44Da98b954EedeAC495271d0F`. Note that it’s very important to externally verify token addresses. Don’t use addresses from sources you don’t trust!

### Required Data <a href="#required-data" id="required-data"></a>

The next piece of data we need is **decimals**.

#### Provided by the User <a href="#provided-by-the-user" id="provided-by-the-user"></a>

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:

```
import { ChainId, Token } from '@whiteswap/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:

```
import { ChainId } from '@whiteswap/sdk'

async function getDecimals(chainId: ChainId, tokenAddress: string): Promise<number> {
  // implementation details
}
```

#### Fetched by the SDK <a href="#fetched-by-the-sdk" id="fetched-by-the-sdk"></a>

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](/reference/sdk/fetcher#fetchtokendata):

```
import { ChainId, Token, Fetcher } from '@whiteswap/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 <a href="#optional-data" id="optional-data"></a>

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:

```
import { ChainId, Token } from '@whiteswap/sdk'

const DAI = new Token(
  ChainId.MAINNET,
  '0x6B175474E89094C44Da98b954EedeAC495271d0F',
  18,
  'DAI',
  'Dai Stablecoin'
)
```

or:

```
import { ChainId, Token, Fetcher } from '@whiteswap/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 <a href="#case-2-pairs" id="case-2-pairs"></a>

Now that we’ve explored how to define a token, let’s talk about pairs. To read more about what WhiteSwap pairs are, see Pair smart contract.

As an example, let’s try to represent the DAI-WETH pair.

### Identifying Data <a href="#identifying-data-1" id="identifying-data-1"></a>

Each pair consists of two tokens (see previous section). Note that WETH used by the router is [exported by the SDK](/reference/sdk/other-exports#weth).

### Required Data <a href="#required-data-1" id="required-data-1"></a>

The data we need is the *reserves* of the pair. To read more about reserves, see getReserves.

#### Provided by the User <a href="#provided-by-the-user-1" id="provided-by-the-user-1"></a>

One option here is to simply pass in values which we’ve fetched ourselves to create a [Pair](/protocol-overview/glossary#pair):

```
import { ChainId, Token, WETH, Pair, TokenAmount } from '@whiteswap/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 <a href="#fetched-by-the-sdk-1" id="fetched-by-the-sdk-1"></a>

If we don’t want to look up the value ourselves, we can ask the SDK to look them up for us with [Fetcher.fetchPairData](/reference/sdk/fetcher#fetchpairdata):

```
import { ChainId, Token, WETH, Fetcher } from '@whiteswap/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](/developer-guides/javascript-sdk/sdk-quick-start)?

Let’s talk pricing. This guide will focus on the two most important WhiteSwap prices: the **mid price** and the **execution price**.

## Mid Price <a href="#mid-price" id="mid-price"></a>

The mid price, in the context of WhiteSwap, 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 <a href="#direct" id="direct"></a>

The simplest way to get the DAI-WETH mid price is to observe the pair directly:

```
import { ChainId, Token, WETH, Fetcher, Route } from '@whiteswap/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])

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](/reference/sdk/fractions#price).

### Indirect <a href="#indirect" id="indirect"></a>

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:

```
import { ChainId, Token, WETH, Fetcher, Route } from '@whiteswap/sdk'

const USDC = new Token(ChainId.MAINNET, '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', 6)
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 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 <a href="#execution-price" id="execution-price"></a>

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:

```
import { ChainId, Token, WETH, Fetcher, Trade, Route, TokenAmount, TradeType } from '@whiteswap/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 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](/developer-guides/javascript-sdk/sdk-quick-start)?

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 WhiteSwap. Nearly everything you need to safely transact with WhiteSwap is provided by the [Trade](/reference/sdk/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 WhiteSwap router.

## Sending a Transaction to the Router <a href="#sending-a-transaction-to-the-router" id="sending-a-transaction-to-the-router"></a>

Let’s say we want to trade 1 WETH for as much DAI as possible:

```
import { ChainId, Token, WETH, Fetcher, Trade, Route, TokenAmount, TradeType } from '@whiteswap/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 WhiteSwap 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:

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

```
import { Percent } from '@whiteswap/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 <a href="#getpair" id="getpair"></a>

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 <a href="#create2" id="create2"></a>

Thanks to some [fancy footwork in the factory](/reference/smart-contracts), 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](/reference/smart-contracts)                    |
| `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 <a href="#examples" id="examples"></a>

#### TypeScript <a href="#typescript" id="typescript"></a>

This example makes use of the [WhiteSwap SDK](/reference/sdk). In reality, the SDK computes pair addresses behind the scenes, obviating the need to compute them manually like this.

```
import { FACTORY_ADDRESS, INIT_CODE_HASH } from '@whiteswap/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'
)
```


# API


# API Overview

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

### Resources <a href="#resources" id="resources"></a>

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

WhiteSwap [Subgraph](https://github.com/WhiteSwap/whiteswap-subgraph) - source code for deployed subgraph.

### Usage <a href="#usage" id="usage"></a>

The subgraph provides a snapshot of the current state of WhiteSwap and also tracks historical data. It is currently used to power [info.ws.exchange](https://info.ws.exchange/). **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 <a href="#making-queries" id="making-queries"></a>

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


# 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 WhiteSwap Subgraph, and descriptions for the available fields.

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

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

#### WhiteSwap Factory <a href="#uniswap-factory" id="uniswap-factory"></a>

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

| Field Name        | Value Type      | Description                                                                                    |
| ----------------- | --------------- | ---------------------------------------------------------------------------------------------- |
| id                | ID              | factory address                                                                                |
| pairCount         | Int             | amount of pairs created by the WhiteSwap factory                                               |
| pairs             | \[Pair]         | array of all pairs in WhiteSwap (stored as IDs)                                                |
| 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                                               |
| mostLiquidTokens  | \[TokenDayData] | array of tokens across WhiteSwap with most liquidity - used as a reference for historical data |

#### Token <a href="#token" id="token"></a>

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                                               |
| 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                                                                                     |
| allPairs        | \[Pair]        | array of all pairs token is included in (stored as IDs)                                           |
| mostLiquidPairs | \[PairDayData] | array of pairs token is included in with most liquidity - used as a reference for historical data |

#### Pair <a href="#pair" id="pair"></a>

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              | WhiteSwapFactory                      | reference to WhiteSwap 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         |
| 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 |
| mints                | \[Mint]                               | array of all Mint events on this pair                            |
| burns \[Burn]        | array of all Burn events on this pair |                                                                  |
| swaps                | \[Swap]                               | array of all Swap events on this pair                            |

#### User <a href="#user" id="user"></a>

A user entity is created for any address that provides liquidity to a pool on WhiteSwap. This entity can be used to track open positions for users. LiquidityPosition 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 |

#### LiquidityPosition <a href="#liquiditypositiion" id="liquiditypositiion"></a>

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 concatenated with pair address          |
| user                  | User       | reference to user                                    |
| pair                  | Pair       | reference to the pair liquidity is being provided on |
| poolOwnership         | BigDecimal | percentage of pool owned in this position            |
| liquidityTokenBalance | BigDecimal | amount of LP tokens minted for this position         |

#### Transaction <a href="#transaction" id="transaction"></a>

Transaction entities are created for each Ethereum transaction that contains an interaction within WhiteSwap contracts. This subgraph tracks Mint, Burn, and Swap events on the WhiteSwap 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 <a href="#mint" id="mint"></a>

Mint entities are created for every emitted Mint event on the WhiteSwap 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 <a href="#burn" id="burn"></a>

Burn entities are created for every emitted Burn event on the WhiteSwap 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 <a href="#swap" id="swap"></a>

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 <a href="#bundle" id="bundle"></a>

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 <a href="#historical-entities" id="historical-entities"></a>

The subgraph tracks aggregated information grouped by days to provide insights to daily activity on WhiteSwap. 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.

#### WhiteSwapDayData <a href="#uniswapdaydata" id="uniswapdaydata"></a>

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 WhiteSwap                                          |
| txCount           | BigInt           | number of transactions throughout this day                                       |

#### Pair Day Data <a href="#pair-day-data" id="pair-day-data"></a>

Tracks pair data across each day.

| Field Name        | Value Type | Description                                                                          |
| ----------------- | ---------- | ------------------------------------------------------------------------------------ |
| id                | ID         | pair contract address concatenated with day id (day start timestamp in unix / 86400) |
| 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)                          |
| 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 <a href="#tokendaydata" id="tokendaydata"></a>

Tracks token data aggregated across all pairs that include token.

| Field Name          | Value Type     | Description                                                                                                                            |
| ------------------- | -------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| id                  | ID             | token address concatenated with day id (day start timestamp in unix / 86400)                                                           |
| 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 WhiteSwap, 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/whiteswapfi/whiteswap).

#### Global Data <a href="#global-data" id="global-data"></a>

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

**Global Stats**

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

```
{
 whiteswapFactory(id: "0x69bd16ae6f507bd3fc9ecc984d50b04f029ef677"){
   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.

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

#### Pair Data <a href="#pair-data" id="pair-data"></a>

**Pair Overview**

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

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

**All pairs in WhiteSwap**

The Graph limits entity return amounts to 1000 per query as of now. To get all pairs on WhiteSwap, 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 WhiteSwap.

```
{
 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: "0xfbc24cd5dea5570f1d65022009f7ad9f7d3f8ade" }
) {
     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: "0xfbc24cd5dea5570f1d65022009f7ad9f7d3f8ade",
     date_gt: 1592505859
   }
 ) {
     date
     dailyVolumeToken0
     dailyVolumeToken1
     dailyVolumeUSD
     reserveUSD
 }
}
```

#### Token Data <a href="#token-data" id="token-data"></a>

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 WhiteSwap can be queried.

**Token Overview**

Get a snapshot of the current stats on a token in WhiteSwap. This query fetches current stats on DAI.

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

**All Tokens in WhiteSwap**

Similar to fetching all pairs (see above), you can query all tokens in WhiteSwap. 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 USDT/USDC pair address.

```
allPairs = [
 "0xfbc24cd5dea5570f1d65022009f7ad9f7d3f8ade",
 "0x87fb8dfa3f2a9ca6b5eb5965928cc6a3214eee18"
]
```

```
query($allPairs: [Bytes]!) {
 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 <a href="#eth-price" id="eth-price"></a>

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

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


# SDK


# Getting Started

The pages that follow contain technical reference information on the WhiteSwap SDK. Looking for a [quickstart](/developer-guides/javascript-sdk/sdk-quick-start) instead? You may also want to jump into a [guide](/developer-guides/javascript-sdk/fetching-data), 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 initialization 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 <a href="#code" id="code"></a>

The [source code is available on GitHub](https://github.com/WhiteSwap/whiteswap-sdk).

### Dependencies <a href="#dependencies" id="dependencies"></a>

The SDK declares its dependencies as [peer dependencies](https://github.com/WhiteSwap/whiteswap-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`](/reference/sdk/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

```
constructor(chainId: ChainId, address: string, decimals: number, symbol?: string, name?: string)
```

The Token entity represents an ERC20 token at a specific address on a specific chain.

## Example <a href="#example" id="example"></a>

```
import { ChainId, Token } from '@whiteswap/sdk'

const token = new Token(ChainId.MAINNET, '0xc0FFee0000000000000000000000000000000000', 18, 'HOT', 'Caffeine')
```

## Properties <a href="#properties" id="properties"></a>

### chainId <a href="#chainid" id="chainid"></a>

```
chainId: ChainId
```

See [ChainId](/reference/sdk/other-exports#chainid).

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

```
address: string
```

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

```
decimals: number
```

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

```
symbol?: string
```

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

```
name?: string
```

## Methods <a href="#methods" id="methods"></a>

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

```
equals(other: Token): boolean
```

Checks if the current instance is equal to another (has an identical chainId and address).

### sortsBefore <a href="#sortsbefore" id="sortsbefore"></a>

```
sortsBefore(other: Token): boolean
```

Checks if the current instance sorts before another, by address.


# Pair

```
constructor(tokenAmountA: TokenAmount, tokenAmountB: TokenAmount)
```

The Pair entity represents a WhiteSwap pair with a balance of each of its pair tokens.

## Example <a href="#example" id="example"></a>

```
import { ChainId, Token, TokenAmount, Pair } from '@whiteswap/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 <a href="#static-methods" id="static-methods"></a>

### getAddress <a href="#getaddress" id="getaddress"></a>

```
getAddress(tokenA: Token, tokenB: Token): string
```

Computes the pair address for the passed [Token](/reference/sdk/token)s. See [Pair Addresses](/developer-guides/javascript-sdk/pair-addresses).

## Properties <a href="#properties" id="properties"></a>

### liquidityToken <a href="#liquiditytoken" id="liquiditytoken"></a>

```
liquidityToken: Token
```

A Token representing the liquidity token for the pair. See [Pair (ERC-20)](https://github.com/WhiteSwap/whiteswap-contracts/blob/main/contracts/WSERC20.sol).

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

```
token0: Token
```

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

```
token1: Token
```

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

```
reserve0: TokenAmount
```

The reserve of token0.

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

```
reserve1: TokenAmount
```

The reserve of token1.

## Methods <a href="#methods" id="methods"></a>

### reserveOf <a href="#reserveof" id="reserveof"></a>

```
reserveOf(token: Token): TokenAmount
```

Returns reserve0 or reserve1, depending on whether token0 or token1 is passed in.

### getOutputAmount <a href="#getoutputamount" id="getoutputamount"></a>

```
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 <a href="#getinputamount" id="getinputamount"></a>

```
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 <a href="#getliquidityminted" id="getliquidityminted"></a>

```
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 <a href="#getliquidityvalue" id="getliquidityvalue"></a>

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

```
constructor(pairs: Pair[], input: Token)
```

The Route entity represents one or more ordered WhiteSwap pairs with a fully specified path from input token to output token.

## Example <a href="#example" id="example"></a>

```
import { ChainId, Token, TokenAmount, Pair, Route } from '@whiteswap/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 <a href="#properties" id="properties"></a>

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

```
pairs: Pair[]
```

The ordered pairs that the route is comprised of.

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

```
path: Token[]
```

The full path from input token to output token.

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

```
input: string
```

The input token.

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

```
output: string
```

The output token.

### midPrice <a href="#midprice" id="midprice"></a>

```
midPrice: Price
```

Returns the current mid price along the route.


# Trade

```
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 <a href="#example" id="example"></a>

```
import { ChainId, Token, TokenAmount, Pair, TradeType, Route } from '@whiteswap/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 <a href="#properties" id="properties"></a>

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

```
route: Route
```

The [path](/reference/sdk/route#path) property of the route should be passed as the path parameter to router functions.

### tradeType <a href="#tradetype" id="tradetype"></a>

```
tradeType: TradeType
```

`TradeType.EXACT_INPUT` corresponds to `swapExact*For*` router functions. `TradeType.EXACT_OUTPUT` corresponds to `swap*ForExact*` router functions.

### inputAmount <a href="#inputamount" id="inputamount"></a>

```
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 <a href="#outputamount" id="outputamount"></a>

```
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 <a href="#executionprice" id="executionprice"></a>

```
executionPrice: Price
```

The average price that the trade would execute at.

### nextMidPrice <a href="#nextmidprice" id="nextmidprice"></a>

```
nextMidPrice: Price
```

What the new mid price would be if the trade were to execute.

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

```
slippage: Percent
```

The slippage incurred by the trade.

* Strictly > .30%.

## Methods <a href="#methods" id="methods"></a>

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) <a href="#minimumamountout-since-204" id="minimumamountout-since-204"></a>

```
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) <a href="#maximumamountin-since-204" id="maximumamountin-since-204"></a>

```
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 <a href="#static-methods" id="static-methods"></a>

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 <a href="#besttradeexactin" id="besttradeexactin"></a>

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.

```
Trade.bestTradeExactIn(
    pairs: Pair[],
    amountIn: TokenAmount,
    tokenOut: Token,
    { maxNumResults = 3, maxHops = 3 }: BestTradeOptions = {}): Trade[]
```

### bestTradeExactOut <a href="#besttradeexactout" id="besttradeexactout"></a>

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.

```
Trade.bestTradeExactOut(
    pairs: Pair[],
    tokenIn: Token,
    amountOut: TokenAmount,
    { maxNumResults = 3, maxHops = 3 }: BestTradeOptions = {}): Trade[]
```


# Fractions

## Fraction <a href="#fraction" id="fraction"></a>

```
constructor(numerator: BigintIsh, denominator: BigintIsh = ONE)
```

The base class which all subsequent fraction classes extend. **Not meant to be used directly.**

### Properties <a href="#properties" id="properties"></a>

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

```
numerator: JSBI
```

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

```
denominator: JSBI
```

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

```
quotient: JSBI
```

Performs floor division.

### Methods <a href="#methods" id="methods"></a>

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

```
invert(): Fraction
```

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

```
add(other: Fraction | BigintIsh): Fraction
```

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

```
subtract(other: Fraction | BigintIsh): Fraction
```

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

```
multiply(other: Fraction | BigintIsh): Fraction
```

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

```
divide(other: Fraction | BigintIsh): Fraction
```

#### toSignificant <a href="#tosignificant" id="tosignificant"></a>

```
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 <a href="#tofixed" id="tofixed"></a>

```
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 <a href="#percent" id="percent"></a>

Responsible for formatting percentages (10% instead of 0.1).

### Example <a href="#example" id="example"></a>

```
import { Percent } from '@whiteswap/sdk'

const percent = new Percent('60', '100')
console.log(percent.toSignificant(2)) // 60
```

#### toSignificant <a href="#tosignificant-1" id="tosignificant-1"></a>

See [toSignificant](/reference/sdk/fractions#tosignificant).

#### toFixed <a href="#tofixed-1" id="tofixed-1"></a>

See [toFixed](/reference/sdk/fractions#tofixed).

## TokenAmount <a href="#tokenamount" id="tokenamount"></a>

```
constructor(token: Token, amount: BigintIsh)
```

Responsible for formatting token amounts with specific decimal places.

### Example <a href="#example-1" id="example-1"></a>

```
import { Token, TokenAmount } from '@whiteswap/sdk'

const FRIED = new Token(ChainId.MAINNET, '0xfa1aFe1000000000000000000000000000000000', 18, 'FRIED', 'Beans')

const tokenAmount = new TokenAmount(FRIED, '3000000000000000000')
console.log(tokenAmount.toExact()) // 3
```

### Properties <a href="#properties-1" id="properties-1"></a>

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

```
token: Token
```

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

```
raw: JSBI
```

Returns the full token amount, unadjusted for decimals.

### Methods <a href="#methods-1" id="methods-1"></a>

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

```
add(other: TokenAmount): TokenAmount
```

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

```
subtract(other: TokenAmount): TokenAmount
```

#### toSignificant <a href="#tosignificant-2" id="tosignificant-2"></a>

See [toSignificant](/reference/sdk/fractions#tosignificant-2).

#### toFixed <a href="#tofixed-2" id="tofixed-2"></a>

See [toFixed](/reference/sdk/fractions#tofixed-1).

#### toExact <a href="#toexact" id="toexact"></a>

```
toExact(format: object = { groupSeparator: '' }): string
```

## Price <a href="#price" id="price"></a>

```
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 <a href="#example-2" id="example-2"></a>

```
import { ChainId, WETH as WETHs, Token, Price } from '@whiteswap/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 <a href="#static-methods" id="static-methods"></a>

#### fromRoute <a href="#fromroute" id="fromroute"></a>

```
fromRoute(route: Route): Price
```

### Properties <a href="#properties-2" id="properties-2"></a>

#### baseToken <a href="#basetoken" id="basetoken"></a>

```
baseToken: Token
```

#### quoteToken <a href="#quotetoken" id="quotetoken"></a>

```
quoteToken: Token
```

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

```
scalar: Fraction
```

Used to adjust the price for the decimals of the base and quote tokens.

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

```
raw: Fraction
```

Returns the raw price, unadjusted for decimals.

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

```
adjusted: Fraction
```

Returns the price, adjusted for decimals.

### Methods <a href="#methods-2" id="methods-2"></a>

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

```
invert(): Price
```

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

```
multiply(other: Price): Price
```

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

```
quote(tokenAmount: TokenAmount): TokenAmount
```

Given an asset amount, returns an equivalent value of the other asset, according to the current price.

#### toSignificant <a href="#tosignificant-3" id="tosignificant-3"></a>

See [toSignificant](/reference/sdk/fractions#tosignificant).

#### toFixed <a href="#tofixed-3" id="tofixed-3"></a>

See [toFixed](/reference/sdk/fractions#tofixed).


# 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 <a href="#static-methods" id="static-methods"></a>

### fetchTokenData <a href="#fetchtokendata" id="fetchtokendata"></a>

```
async fetchTokenData(
  chainId: ChainId,
  address: string,
  provider = getDefaultProvider(getNetwork(chainId)),
  symbol?: string,
  name?: string
): Promise<Token>
```

Initializes 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 <a href="#fetchpairdata" id="fetchpairdata"></a>

```
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 <a href="#jsbi" id="jsbi"></a>

```
import { JSBI } from '@whiteswap/sdk'
// import JSBI from 'jsbi'
```

The default export from [jsbi](https://github.com/GoogleChromeLabs/jsbi).

## BigintIsh <a href="#bigintish" id="bigintish"></a>

```
import { BigintIsh } from '@whiteswap/sdk'
// type BigintIsh = JSBI | bigint | string
```

A union type comprised of all types that can be cast to a JSBI instance.

## ChainId <a href="#chainid" id="chainid"></a>

```
import { ChainId } from '@whiteswap/sdk'
// enum ChainId {
//   MAINNET = 1,
//   ROPSTEN = 3,
//   RINKEBY = 4,
//   GÖRLI = 5,
//   KOVAN = 42
// }
```

A enum denominating supported chain IDs.

## TradeType <a href="#tradetype" id="tradetype"></a>

```
import { TradeType } from '@whiteswap/sdk'
// enum TradeType {
//   EXACT_INPUT,
//   EXACT_OUTPUT
// }
```

A enum denominating supported trade types.

## Rounding <a href="#rounding" id="rounding"></a>

```
import { Rounding } from '@whiteswap/sdk'
// enum Rounding {
//   ROUND_DOWN,
//   ROUND_HALF_UP,
//   ROUND_UP
// }
```

A enum denominating supported rounding options.

## FACTORY\_ADDRESS <a href="#factory_address" id="factory_address"></a>

```
import { FACTORY_ADDRESS } from '@whiteswap/sdk'
```

The factory address.

## INIT\_CODE\_HASH <a href="#init_code_hash" id="init_code_hash"></a>

```
import { INIT_CODE_HASH } from '@whiteswap/sdk'
```

See Pair Addresses.

## MINIMUM\_LIQUIDITY <a href="#minimum_liquidity" id="minimum_liquidity"></a>

```
import { MINIMUM_LIQUIDITY } from '@whiteswap/sdk'
```

## InsufficientReservesError <a href="#insufficientreserveserror" id="insufficientreserveserror"></a>

```
import { InsufficientReservesError } from '@whiteswap/sdk'
```

## InsufficientInputAmountError <a href="#insufficientinputamounterror" id="insufficientinputamounterror"></a>

```
import { InsufficientInputAmountError } from '@whiteswap/sdk'
```

## WETH <a href="#weth" id="weth"></a>

```
import { WETH } from '@whiteswap/sdk'
```

An object whose values are WETH [Token](/reference/sdk/token) instances, indexed by [ChainId](/reference/sdk/other-exports#chainid).


# Smart Contracts

Up-to-date contract addresses:

| **Ethereum**         |                                                                                                                       |
| -------------------- | --------------------------------------------------------------------------------------------------------------------- |
| Router               | [0x981B14110cE9bf3FC88595227d51699b0A1448D0](https://etherscan.io/address/0x981B14110cE9bf3FC88595227d51699b0A1448D0) |
| Router logic         | 0x79e036400de16cEF7aA543470F6749a5203e8A76                                                                            |
| Factory              | 0x69bd16aE6F507bd3Fc9eCC984d50b04F029EF677                                                                            |
| Factory logic        | 0xfbacbc64e684c0c5bf572fc6d42458c3e3fd1d1d                                                                            |
| Pair logic           | 0x524818CB8081941B618613c6F990C17Bb3DA0866                                                                            |
| Controller           | 0xA9229c9D3720CD359cEc51A259003C845E4C8224                                                                            |
| Governance           | 0x0423d7c27d1dde7eb4aae02dae6b651c7225e6f9                                                                            |
| Governor Alpha       | 0x5a2b018352a1bd9831de2cbe5e8f24333bccbb8b                                                                            |
| WSD Vesting (Escrow) | [0xB8BE4e77A93016F6aA37785Eb0521fCf606E7D97](https://etherscan.io/address/0xb8be4e77a93016f6aa37785eb0521fcf606e7d97) |

| **Tron** |                                                   |
| -------- | ------------------------------------------------- |
| Router   | <p>TEx8NGKMLTHFWYWEMKAZbJbdcaLdDGyLD4</p><p> </p> |
| Factory  | TZENwkSudHRjeufNrQYAPtCmcuNRw2HNYT                |

| **Polygon** |                                            |
| ----------- | ------------------------------------------ |
| Router      | 0xDaFb251f372D040F0DA0f9B787623aAE9cF1ACB6 |
| Factory     | 0x3f0b5743bba8a552a3aa1e7907f4f44047e93f8f |


