What is a liquidity pool?
A liquidity pool is a contract that holds reserves of two tokens. Users called Liquidity Providers (LPs) deposit both tokens in proportion to the current reserves, and in return receive LP tokens that represent their share of the pool. When traders swap through the pool, they pay a fee that accrues to LPs.
LP tokens
LP tokens are ERC-20 tokens. They're minted when you deposit liquidity and burned when you withdraw. The amount you receive reflects your proportional share of the pool at the time of deposit.
// Adding liquidity and minting LP tokens
function addLiquidity(
uint256 amountA,
uint256 amountB
) external returns (uint256 liquidity) {
tokenA.transferFrom(msg.sender, address(this), amountA);
tokenB.transferFrom(msg.sender, address(this), amountB);
uint256 totalSupply = lpToken.totalSupply();
if (totalSupply == 0) {
// First liquidity: mint sqrt(amountA * amountB) LP tokens
liquidity = Math.sqrt(amountA * amountB);
} else {
// Subsequent: mint proportional to smaller of the two ratios
liquidity = Math.min(
(amountA * totalSupply) / reserveA,
(amountB * totalSupply) / reserveB
);
}
require(liquidity > 0, 'Insufficient liquidity minted');
lpToken.mint(msg.sender, liquidity);
reserveA += amountA;
reserveB += amountB;
}Removing liquidity
function removeLiquidity(uint256 liquidity) external returns (uint256 amountA, uint256 amountB) {
uint256 totalSupply = lpToken.totalSupply();
// Proportional share of both reserves
amountA = (liquidity * reserveA) / totalSupply;
amountB = (liquidity * reserveB) / totalSupply;
require(amountA > 0 && amountB > 0, 'Insufficient liquidity burned');
lpToken.burnFrom(msg.sender, liquidity);
reserveA -= amountA;
reserveB -= amountB;
tokenA.transfer(msg.sender, amountA);
tokenB.transfer(msg.sender, amountB);
}Impermanent loss
When the price ratio between the two pooled tokens changes, LPs end up with a different ratio than they deposited. This "impermanent loss" means they'd have been better off just holding the tokens — unless fees earned compensate for it. The loss is impermanent because it disappears if the price ratio returns to its original state.
Understanding impermanent loss is critical for evaluating liquidity provision as a strategy. High-volume pools with thin price swings (like stablecoin pairs) tend to minimize it.
Fee accumulation
The standard Uniswap V2 fee is 0.3% per swap. This fee stays in the pool — it's not distributed separately. As fees accumulate, the reserves grow, making each LP token worth more tokens when it's eventually redeemed.
// Fee is built into the swap formula:
// amountInWithFee = amountIn * 997 (0.3% stays in pool)
// The reserves grow by the fee amount on every trade
// LPs capture this when they burn their LP tokens and withdraw reserves