Introduction
Without liquidity providers, DEXs and liquidity pools will not exist — these crucial users provide the bedrock for DeFi to run on, and they do so not without taking any risks.
Let us explore more about the risks of providing liquidity to LP pools with the following thought exercise:
Given that 1 ETH = 1000 USDC. You contributed as a liquidity provider to a Uniswap V2 ETH/USDC pool of 5 ETH and 5000 USDC. The combined value is $10,000. Weeks later, the price of 1 ETH = 1500 USDC. Explain what happens to the funds you contributed to the liquidity provider pool?
To understand what happens to the liquidity funds contributed, let us revisit the fundamentals of liquidity pools, by first understanding how provided liquidity is tracked.
What are liquidity tokens?
As covered in Liquidity Pools 101: What is Price Impact
, most DEXs use the constant product formula (x * y = k)
, pioneered by Uniswap, for their AMMs — this means that the pair reserve ratio in a liquidity pool must always follow an invariant k
:
$$ \text{Token } x \text{ Reserve } = \frac{k}{\text{Token } y \text{ Reserve }} \quad \text{ or } \quad \text{Token } y \text{ Reserve } = \frac{k}{\text{Token } x \text{ Reserve}} $$
As such, when we deposit liquidity into a pool on Uniswap (via the function addLiquidity in the Router02 smart contract), it is required that we follow the pair price ratio of the pool.
To illustrate, if a pool of has 10,000 Token X to 2,000 Token Y, then any liquidity deposits we make must follow this 5 : 1 ratio.
Once we have deposited liquity, the same addLiquidity
function then issues back liquidity tokens specific to the pool, as a way to keep track on the amount of liquidity provided. Every withdrawal of liquidity involves burning liquidity tokens, and every deposit of liquidity involves minting new liquidity tokens — so that a provider’s relative percentage share of the liquidity pool remains correct.
The formula to calculate the amount of liquidity tokens to be issued can be found in the UniswapV2Pair.sol contract, on line 123:
liquidity = Math.min(amount0.mul(_totalSupply) / _reserve0,
amount1.mul(_totalSupply) / _reserve1)
In plain maths, it translates to:
$$ liquidityTokensMinted = totalLiquidityTokenSupply \cdot \frac{\text{Token } x \text{ Deposited}}{\text{Token } x \text{ Reserve}} $$
or vice versa with Token y
. The Math.min()
function is there for a safeguard check, as it is technically not needed since both calculations should be equal.
With this, we can now calculate the amount of liquidity tokens issued to us.
Calculation of amount of LP tokens issued for the question
The question states,
Given that 1 ETH = 1000 USDC. You contributed as a liquidity provider to a Uniswap V2 ETH/USDC pool of 5 ETH and 5000 USDC. The combined value is $10,000.
Based on the constant product formula, we would have deposited an amount following a ratio of 1 ETH : 1000 USDC.
Let’s assume that we deposited 0.5 ETH and 500 USDC — this is equivalent to
$$ \text{Relative pct. of pool} = \frac{\text{Token } x \text{ Deposited}}{\text{Token } x \text{ Reserve}} = \frac{0.5 \text{ ETH}}{5 - 0.5 \text{ ETH}} \quad or \quad \frac{500 \text{ USDC}}{5000 - 500 \text{ USDC}} = 11.1111 \text{ pct.} $$
Let’s also assume that there were a total supply of 1500 liquidity tokens for this pool before we deposited (the default minimum liquidity tokens in a Uniswap V2 pool is 1000 ) — this would give us:
$$ liquidityTokensMinted = 1500 \cdot 11.1111 \text{ pct. } = 166.6667 \text{ LP tokens} $$
This would bring the totalLiquidityTokenSupply to (166.6667 + 1500) = 1666.6667 LP tokens. This 166.6667 LP tokens are a way to tell the smart contract that we are now owed a relative (166.6667 / 1666.6667) = 10% of liquidity within the pool. Of course, this relative percentage will decrease if there are other depositors down the road.
What happens when price of 1 ETH is now 1500 USDC?
The question then states,
Weeks later, the price of 1 ETH = 1500 USDC. Explain what happens to the funds you contributed to the liquidity provider pool?
The constant product of the pool is :
$$ \text{Constant product } k = 5 \cdot 5000 = 25000 $$
Let’s assume that the price increase of ETH is due to a decrease in ETH liquidity in the pool, and assume that the pool currently has 4 ETH, this would mean:
$$ \text{USDC Reserve} = \frac{k}{\text{ETH Reserve}} = \frac{25000}{4} = 6250 $$
This means our assumed pool composition is now
$$ 4 \text{ ETH} : 6250 \text{ USDC} $$
Now, if we were to withdraw our liquidity with this new pool composition, and assuming total liquidity token supply is unchanged, we would get:
$$ \text{Token x received} = \frac{liquidityTokensMinted}{totalLiquidityTokenSupply} \cdot \text{Token x Reserve} $$
$$ \text{ETH received} = \frac{166.6667}{1666.6667} \cdot 4 = 0.4 $$
$$ \text{USDC received} = \frac{166.6667}{1666.6667} \cdot 6250 = 625 $$
We would receive 0.4 ETH and 625 USDC, compared to what we initially deposited (0.5 ETH and 500 USDC). If we calculate based on USDC value, we would now receive an equivalent of (0.4 * 1500) + 625 = 1225 USDC, compared to our initial deposit of (0.5 * 1000) + 500 = 1000 USDC — a profit of 225 USDC or +22.5%.
Now, this brings the question of what happens if the price of ETH decreases against USDC instead?
Risks of providing liquidity: impermanent loss, price slippage & price impact
Let’s illustrate this case with the following exercise.
If the price of 1 ETH is 500 USDC instead, and assuming the original 5 ETH in the pool stays constant, we can use the price ratio to calculate how much USDC is in the pool:
$$ \text{Original Price Ratio} = 1 \text{ ETH} : 1000 \text{USDC} $$
$$ \text{New Price Ratio} = 1 \text{ ETH} : 500 \text{ USDC} $$
$$ \text{New USDC Reserve} = \text{ETH Reserve} \cdot \text{New Price Ratio} = 5 \cdot 500 = 2500 $$
This means we now have a pool composition of 5 ETH : 2500 USDC. Since we know we have 166.6667 LP tokens out of 1666.6667 LP tokens in supply, We can now calculate, using the formula in the above section, our returned liquidity:
$$ \text{ETH received} = \frac{166.6667 \text{ LP tokens}}{1666.6667 \text{ LP tokens}} * 5 = 0.5 $$
$$ \text{USDC received} = \frac{166.6667 \text{ LP tokens}}{1666.6667 \text{ LP tokens}} * 2500 = 250 $$
We would receive 0.5 ETH and 250 USDC, or an equivalent of (0.5 ETH * 500) + 250 = 500 USDC — this is a loss of 500 USDC or -50% from our initial deposit, on paper. This loss is what is termed impermanent loss, because when the price ratio returns back to original, then the loss on paper would be gone.
Impermanent loss is mainly caused by:
- Price slippage — A mismatch between the wider market price of tokens with the internal prices of the liquidity pool, due to outside market factors — this will correct itself to match the price in the wider market due to arbitrage opportunities.
- Price impact — In cases of large price slippage caused by a market dump, traders will make large swaps with high price impact on DEXs in an attempt to exit “bad bags” and protect their holdings’ value, thus causing a liquidity drain in the pools. A good example of this is the June 2022 stETH decoupling event where investors rushed to exit their stETH tokens for ETH on Curve’s stETH:ETH pool .
Conclusion
Ultimately, supplying liquidity to pools implies that one is taking a bet on each asset’s wider market price & relative price within DEXs.
In the thought exercise, we provided liquidity to the ETH-USDC pool — since USDC is a stable coin, we are then essentially betting that ETH’s value against USD will increase in the future, with the hopes that it will grow our liquidity provided, as shown above.
With that, we have covered a solid understanding of the risks of providing liquidity to LP pools and hopefully gained a better appreciation for liquidity providers — so thank you and let’s keep the money flowing!