Uniswap V2 Explained

Prerequisites

  1. Knowledge of Uniswap V1

Problems of Uniswap V1

  1. Requires ETH as a token in every pool:

    1. Every liquidity provider faces the risk of ETH depreciating.

    2. For a trader to swap from ERC20 tokenA to ERC20 tokenB, they will have to perform two swaps : tokenA to ETH in poolA and then ETH to tokenB in poolB. Hence they would have to pay the swap fee 2 times.

  2. Failure as a price Oracle : The pricing function of Uniswap V1 depended on the spot balances ETH and Token balance of the pool. This meant that a contract retrieving the price of a token from Uniswap could be easily misguided by an attacker. Let us see an example of this. Suppose there is another exchange called SecondaryExchange which performs swaps based on the price it receives from Uniswap. Let us assume the price of ETH/USDC is 2000 in Uniswap/open market and that there is currently 1000 ETH and 2000000 USDC in Uniswap's ETH/USDC pool. The secondary exchange also contains a pool for ETH and USDC and determines the swap amount based on the price it receives from Uniswap. In this case, an attacker could make a transaction performing a swap of 500 ETH in Uniswap. This would lead to the reserves of the pool shifting to 500ETH and 4000000 USDC. In the same transaction, the attacker could make a swap of another 500 ETH on the secondary exchange. Since the SecondaryExchange depends on Uniswap for the price, it would give out 4000000 USDC although the actual price in the open market is only 2000 USDC. To avoid the loss he would be making due to the first swap, the attacker can then make a swap of 2000000 USDC in Uniswap and claim back his 500ETH. Since all these can be done in a single transaction, the arbitrageurs will not be able to intervene. Hence the attacker would be gaining 2000000 USDC at the expense of SecondaryExchange.

Uniswap V2 solves these problems and also introduces Flash Swaps, Meta Transactions for Pool Shares and a switchable protocol fee.

ERC20-ERC20 Pools

In Unsiwap V2, each ERC20 pair will have its own pool. The traders benefit from only having to pay the swap fees once and the liquidity providers benefit from not being compelled to hold on to ETH. This also enables multiple routes to swap from tokenA to tokenB. Let us assume I need to perform a swap from USDC to LINK token. In case the liquidity in the USDC/LINK pool is low, but the liquidity in USDC/DAI and DAI/LINK pools are high, I could route my swap via the two pools which could eventually result in a better LINK output.

Hardened Price Oracle

As seen above, Uniswap V1 as a price oracle was flawed. Unsiwap V2 came up with a solution to the price manipulation problem. Instead of using the current reserves, what if we use the reserves as per the last block for oracle purposes? So in Block 6, we will show the price as (reserve1/reserve0) where reserve1 and reserve0 are the token1 and token0 reserves of the pool after the last transaction of Block 5. In such an implementation the above-mentioned attack will be unfavorable for the attacker. To successfully misguide the dependent contract, the attacker will have to make a huge swap and ensure that it is the last transaction of Block 5. In case the transaction is not the last one, arbitrageurs could use this opportunity resulting in a loss for the attacker. But a miner can ensure that his transaction is placed last. So if a miner is an attacker, he can make a huge swap and place it as the last transaction of Block 5. Then the price oracle will be displaying the manipulated price for the entirety of Block 6 and the attacker can now misguide the oracle-dependent entity. Here unlike the first case, the attacker will also incur some loss because in Block 6 the arbitrageurs can exploit the price difference caused by the attacker's swap making it impossible for the attacker to swap back and recover. But this is still a bad solution. As long as the price oracle is dependent on a single transaction, it will be manipulatable. Hence Uniswap decided to use the cumulative price instead. Instead of storing the spot price, it will be storing the sum of second-wise prices. We shall see an example for this. Let us assume some things:

  1. The cumulative sum as of Block 5 was 110.

  2. Let reserve1 and reserve0 after the last transaction of Block 5 be 4 and 2.

  3. Block 5 was mined at timestamp 1678990705

If Block 6 was mined at 1678990720 , it would then update the oracle price to 110 + (4/2) * 15 ie. [current cumulative price sum] + [reserve1/reserve0 after the last transaction of previous block] * [no. of seconds since the last block]. Hence the effect of a single swap on the price oracle will be extremely diminished. Unless the attacker can ensure that he makes the last transaction of Block 5 and the first transaction of Block 6, the loss incurred by the manipulating swap will mostly refrain him from making a profit. Since the price oracle returns the cumulative sum, the dependent entities will have to checkpoint the prices at different times in order to obtain the average prices at for those time intervals.

Flash Swaps

As a new feature, Uniswap V2 enables flash swaps. So if a trader wants to obtain 10 LINK for 2 ETH, he can now first obtain 10 LINK and then pay the 2 ETH later. Well not really later, he will have to pay the 2 ETH in the same transaction itself but that can be done after obtaining the LINK tokens. This is useful in scenarios where users spot an opportunity to make more than 2 ETH with 10 LINK. In that case the user can first get the 10 LINK tokens , redeem the opportunity hence receiving more than 2 ETH and then returning back the 2 ETH, making profit in ETH out of nothing. This is possible since a transaction is atomic and hence eventually if the pool doesn't receive 2 ETH, it will revert the entire transaction rolling back the transfer of 10 LINK.

Meta Transaction for Pool Shares

Each liquidity provider owns liquidity tokens corresponding to their share of the pool. These tokens, like the standard ERC20 token, can be transferred to other addresses. Uniswap V2 allows off-chain transfer of these tokens using signed messages.

Switchable Protocol Fee

Uniswap V1 had a fixed 0.3% fee on all swaps. And this fee would be added to the liquidity and then eventually handed over to the liquidity providers when they withdraw their assets. Uniswap V2 also has a switchable protocol fee. In case the protocol fee is turned on, the split of the 0.3% swap fee will be 0.25% for liquidity providers and 0.05% to an address that is set by the governance.