DEV Community

liamlo-dev
liamlo-dev

Posted on

Uniswap Deep Dive 1:

Before we start

For introduction, please read
Uniswap V2 Overview by Uniswap
Uniswap V2 Contract Walk-through

For source code,
Uniswap V2 Core and Uniswap V2 Peripheral

Overview

Uniswap V2 Core has 3 contracts: Factory, Pair, WETH and Uniswap V2 Periphery has 1 contract: Router.

Factory contract (UniswapV2Factory.sol)

It is responsible for creating trading pairs and saving the addresses of all trading pairs.

Pair contract (UniswapV2Pair.sol)

It saves the pool information of a single trading pair, including the addresses of the two ERC20 tokens in each trading pair, and their respective reserve.
It handles mint, burn and swap operations.
UniswapV2Pair itself is also an unique ERC20 token. Whenever liquidity is deposited into a pool, unique tokens known as liquidity tokens are minted and sent to the provider's address. These tokens represent a given liquidity provider's contribution to a pool. The proportion of the pool's liquidity provided determines the number of liquidity tokens the provider receives. If the provider is minting a new pool, the number of liquidity tokens they will receive will equal sqrt(x * y), where x and y represent the amount of each token provided.
totalSupply of pair token === sqrt(reserve1 * reserve2) [not sure]

WETH contract

This contract is a special ERC20, for the sole purpose to facilitate users to directly trade between ETH and ERC20. Think of WETH as a fully guaranteed bond: the ETH stored in this contract is always equal to the WETH it issued (unless someone sent ETH to it directly using WETH_address.transfer ).
WETH is created because the trading pair of the Pair contract are always ERC20 tokens and it does not support trading between ETH and ERC20.
It has 2 methods, deposit() and withdraw(). The former is to deposit ETH to get WETH, and the latter is to destroy WETH to get ETH. But these two methods are usually called by the Router, such as the swapExactETHForTokens function in the Router

function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)
                external
                virtual
                override
                payable
                ensure(deadline)
                returns (uint[] memory amounts)
            {
                require(path[0] == WETH, 'UniswapV2Router: INVALID_PATH');
                amounts = UniswapV2Library.getAmountsOut(factory, msg.value, path);
                require(amounts[amounts.length - 1] >= amountOutMin, 'UniswapV2Router: INSUFFICIENT_OUTPUT_AMOUNT');
                IWETH(WETH).deposit{value: amounts[0]}();
                assert(IWETH(WETH).transfer(UniswapV2Library.pairFor(factory, path[0], path[1]), amounts[0]));
                _swap(amounts, path, to);
            }
Enter fullscreen mode Exit fullscreen mode

Top comments (0)