Uniswap v2
Last updated
Last updated
Uniswap is an automated liquidity protocol powered by a constant product formula and implemented in a system of non-upgradeable smart contracts.
Each Uniswap smart contract, or pair, manages a liquidity pool made up of reserves of two ERC-20 tokens.
Anyone can become a liquidity provider (LP) for a pool by depositing an equivalent value of each underlying token in return for pool tokens. These tokens track pro-rata LP shares of the total reserves, and can be redeemed for the underlying assets at any time
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.
Uniswap 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
Because the relative price of the two pair assets can only be changed through trading, divergences between the Uniswap price and external prices create arbitrage opportunities. This mechanism ensures that Uniswap prices always trend toward the market-clearing price.
Uniswap V2 Core are the essential Uniswap V2 smart contracts:
UniswapV2Pair.sol - implements core swapping and liquidity provision functionality
UniswapV2Factory.sol - deploys UniswapV2Pair.sol contracts for any ERC20 token/ERC20 token pair
Uniswap V2 Periphery (periphery) is an initial set of helpers, including:
A router contract that performs the safety checks needed for safely swapping, adding, and removing liquidity.
A migrator contract that can remove liquidity from Uniswap V1 and deposit it into Uniswap V2 in a single transaction.
A library contract that can be used in the creation of other helper contracts.
An example oracle contract that creates a simple TWAP from Uniswap V2 cumulative prices.
An example flash swap contract that withdraws ERC20 tokens, executes arbitrary code, and then pays for them.
Logic related to trader security or ease-of-use is implemented in external helper contracts. External helpers can be improved and replaced without needing to migrate liquidity, which improves on the flexibility and modularity of Uniswap.
Singleton Factory
Holds the generic bytecode responsible for powering pairs
Create one and only one smart contract per unique token pair
Contains logic to turn on the protocol charge
Create Pair Function:
checks that token A and token B are different addresses
check that neither are the zero address
check that pair does not already exist
get bytecode for pair contract
calculate create2 salt for these two token addresses
deploy pair contract using create2
initialise the pair contract with the token addresses
update the pair mapping to track created pairs
Pairs
Serve as automated market makers
Keep track of pool token balances
Expose data which can be used to build decentralized price oracles
Swap Function:
to
address: the user
why are there two out
tokens
checks that input token amounts are positive
checks that pool has sufficient tokens to transfer to caller
checks that caller has sent sufficient amount of input tokens
calculate and remove 0.3% uniswap fee from input tokens
Sending Tokens
typically, smart contracts require the user to give approval of the token contract to itself, before calling transferFrom
on the token
however, this is not how v2 pair contracts accept tokens
v2 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.
tokens must be transferred to the pair before calling any token-requiring method (except in Flash Swaps)
WETH
Unlike Uniswap V1 pools, V2 pairs do not support ETH directly, so ETH⇄ERC-20 pairs must be emulated with WETH
motivation behind this choice was to remove ETH-specific code in the core to have a leaner codebase
The router convert ETH to WETH so that users may utilise it directly.
Minimum Liquidity
To ameliorate rounding errors and increase the theoretical minimum tick size (smallest increment) for liquidity provision, pairs burn the first MINIMUM_LIQUIDITY (returns 1000 for all pairs) pool tokens.
For most pairs, this will represent a trivial value. The burning happens automatically during the first liquidity provision, after which point the totalSupply is forevermore bounded.
For the first LP provision, LP tokens are burnt so the market maker cannot “rug”.