# Uniswap v2

* Uniswap is an _automated liquidity protocol_ powered by a [constant product formula](https://docs.uniswap.org/contracts/V2/concepts/protocol-overview/glossary#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](https://eips.ethereum.org/EIPS/eip-20) tokens.
* Anyone can become a liquidity provider (LP) for a pool by depositing an equivalent value of each underlying token in return for pool tokens. These tokens track pro-rata LP shares of the total reserves, and can be redeemed for the underlying assets at any time

<figure><img src="https://3023085841-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FPx19QJfp3ypeVgsH4aV5%2Fuploads%2F4Dd698YWaStLsTLK1A3j%2Funiswap.png?alt=media&#x26;token=548d6f8d-ce84-494b-8b8f-474a1cf8df6c" alt=""><figcaption></figcaption></figure>

### Constant Product

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.

### Architecture&#x20;

[**Uniswap V2 Core**](https://github.com/Uniswap/uniswap-v2-core) are the essential Uniswap V2 smart contracts:

* [**UniswapV2Pair.sol**](https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2Pair.sol) **-** implements core swapping and liquidity provision functionality
* [**UniswapV2Factory.sol**](https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2Factory.sol) **-** deploys [**UniswapV2Pair.sol**](https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2Pair.sol) contracts for any ERC20 token/ERC20 token pair

[**Uniswap V2 Periphery**](https://github.com/Uniswap/uniswap-v2-periphery) (periphery) is an initial set of helpers, including:

* [**A router contract**](https://github.com/Uniswap/uniswap-v2-periphery/blob/master/contracts/UniswapV2Router01.sol) that performs the safety checks needed for safely swapping, adding, and removing liquidity.
* [**A migrator contract**](https://github.com/Uniswap/uniswap-v2-periphery/blob/master/contracts/UniswapV2Migrator.sol) that can remove liquidity from Uniswap V1 and deposit it into Uniswap V2 in a single transaction.
* [**A library contract**](https://github.com/Uniswap/uniswap-v2-periphery/blob/master/contracts/libraries/UniswapV2Library.sol) that can be used in the creation of other helper contracts.
* [**An example oracle contract**](https://github.com/Uniswap/uniswap-v2-periphery/blob/master/contracts/examples/ExampleOracleSimple.sol) that creates a simple TWAP from Uniswap V2 cumulative prices.
* [**An example flash swap contract**](https://github.com/Uniswap/uniswap-v2-periphery/blob/master/contracts/examples/ExampleFlashSwap.sol) 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.



### Core Contracts

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

```solidity
function createPair(address tokenA, address tokenB) 
		external returns (address pair) {
				bytes memory bytecode = type(UniswapV2Pair).creationCode;
        bytes32 salt = keccak256(abi.encodePacked(token0, token1));
        assembly {
            pair := create2(0, add(bytecode, 32), mload(bytecode), salt)
        }
		}
```

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

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

### Design Decisions

**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](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/pair#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~~](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/pair-erc-20#totalsupply) ~~is forevermore bounded.~~
* For the first LP provision, LP tokens are burnt so the market maker cannot “rug”.
