DEV Community

Cover image for Burning Liquidity: Exit, Profit, and How DeFi Began losing its mind
Adi
Adi

Posted on

Burning Liquidity: Exit, Profit, and How DeFi Began losing its mind

Six posts in. The end is in sight. We've covered the AMM fundamentals, the architecture, mint, swap, and flash loans. Burn is the last of the four core flows, and honestly it's the most straightforward of the lot. The mechanics are clean, the math follows directly from everything we've already covered, and by the end of this post you'll have a complete picture of the liquidity lifecycle on Uniswap V2.

But burn also opens a door to a story that's hard not to tell once you start. Because LP tokens aren't just receipts. They're assets. And what people did with that realisation in 2020 was, depending on your perspective, either the most creative financial engineering in the history of decentralised systems or a spectacular collective hallucination that somehow worked. Possibly both.

We'll get to the mechanics first.


The flow: removeLiquidity()

When a liquidity provider wants their tokens back, they call removeLiquidity() on the Router. The signature:

removeLiquidity(address tokenA, address tokenB, uint liquidity, uint amountAMin, uint amountBMin, address to, uint deadline)
Enter fullscreen mode Exit fullscreen mode

tokenA and tokenB identify the pool. liquidity is how many LP tokens they're handing back. amountAMin and amountBMin are the slippage floors. to is where the tokens go. deadline is the same deadline we've seen on every other Router function.

The first thing the Router does is transfer the LP tokens from the user directly to the pair contract using safeTransferFrom(). Not to the Router. To the pair itself. If you remember from the mint post, this is the same pattern as when tokens were sent to the pair before mint() was called: the pair figures out what arrived by comparing its actual balance against its last recorded state. Here, the pair looks at how many of its own LP tokens it's currently holding, and that number is what gets burned.

Then the Router calls burn(to) on the pair contract.


Inside the Pair: burn()

burn() starts the same way mint() did, by calling _mintFee(). Same logic as before: if the protocol fee is enabled, the accumulated fee since the last liquidity event gets minted to feeTo before anything else changes. This ensures the protocol takes its cut before the LP's share is calculated, which matters because minting fee tokens after would dilute the LP's redemption.

Then the pair reads its current token balances (balance0 and balance1) and checks how many LP tokens it's holding. The redemption amounts are calculated as:

amount0=liquidity×balance0totalSupplyamount0 = liquidity \times \frac{balance0}{totalSupply}
amount1=liquidity×balance1totalSupplyamount1 = liquidity \times \frac{balance1}{totalSupply}

This is the LP token math from the other direction. When you minted, the pair gave you LP tokens proportional to your share of the pool. Now it's giving you back that proportional share of whatever the pool currently holds. The ratio liquidity / totalSupply is your ownership fraction: if you hold 5% of LP supply, you get 5% of balance0 and 5% of balance1.

Notice it uses balance0 and balance1 rather than the stored reserves. Fees accumulate as actual token balances above what the reserves track. By using the real balances, your redemption automatically includes your share of every fee the pool collected while you were in it. You don't need to claim fees separately. They're baked into what your LP tokens are worth.

After calculating the amounts, the pair calls _burn() on its own LP token supply (the ERC-20 inherited from UniswapV2ERC20), reducing totalSupply by liquidity. Then it transfers amount0 and amount1 to the to address using _safeTransfer(). Then _update() syncs the reserves, kLast gets updated if the protocol fee is on, and the Burn event is emitted.

Back in the Router, the raw amount0 and amount1 get mapped back to amountA and amountB in the user's original token ordering (the pair stores tokens sorted by address, which may differ from the order the user passed in). Then the slippage check: amountA >= amountAMin and amountB >= amountBMin. If the pool moved between submission and execution and the output dropped below the floors, it reverts here.

That's the full burn flow. Clean, proportional, and symmetrical with mint in almost every detail.


But who said the person burning had to be the person who minted?

Here's something worth stating clearly: LP tokens are just ERC-20 tokens. Standard, transferable, tradeable ERC-20 tokens. The pair contract doesn't know or care whether the address calling burn() is the same address that called mint() originally. It just checks how many LP tokens you're handing back and gives you the proportional pool share in return.

This means LP tokens have a market. You can sell them. You can buy them. You can hold them as a long-term position in a pool without ever having interacted with the pool directly. If you buy LP tokens for the ETH/USDC pool on the secondary market, you now own a share of that pool: you earn fees from every swap that goes through it for as long as you hold those tokens, and you can burn them whenever you want to get the underlying back.

LP tokens are, in a real sense, an investable asset. Their value appreciates as the pool collects fees. A large, high-volume pool accumulates fees continuously, and the LP tokens for that pool quietly become worth more over time even if the underlying token prices stay flat. Holding ETH/USDC LP tokens in a bull market when ETH is appreciating and the pool is doing heavy volume is a compounding position: exposure to ETH price appreciation and fee income simultaneously.

Naturally, the DeFi space looked at this and immediately figured out seventeen ways to make it more complicated.


LP tokens, yield farming, and the part where things got weird

Composability (quite popular these days since the Drift Protocol exploit), is one of those words that gets used in crypto to sound sophisticated, but the concept is straightforward. Because everything on-chain is open and permissionless, any protocol can accept the output of any other protocol as an input. LP tokens are a clean output: they represent value, they're ERC-20 compatible, and any protocol that accepts ERC-20 tokens can accept LP tokens. Which means you can take your LP tokens and deposit them somewhere else.

Some protocols noticed this and started accepting LP tokens as staked assets, paying out their own governance tokens as rewards. So now you could provide liquidity on Uniswap, receive LP tokens, stake those LP tokens on another protocol, and earn that protocol's token on top of the fees you were already earning from Uniswap. Two yield streams from one capital deployment.

Then someone noticed you could take those governance token rewards, sell them for more of the underlying tokens, add more liquidity to Uniswap, get more LP tokens, stake those too, and now your position is compounding. Then some protocols started accepting the governance tokens from the first protocol as staking collateral for a third protocol. Then yield optimisers appeared that automated all of this, moving capital between pools to chase the highest APY, compounding rewards every few hours.

By mid-2020, there were protocols offering four-digit APYs. Tokens named after food. A protocol called YAM that launched, attracted hundreds of millions of dollars in liquidity, discovered a critical bug in its rebase mechanism within 36 hours, and asked users to vote on an emergency fix before the next rebase. People were refreshing Etherscan at 2am to time their transactions. Gas prices hit levels that made simple token transfers cost $50 and complex DeFi interactions cost several hundred dollars. Everyone was a liquidity provider. Everyone was a yield farmer. Everyone was going to be rich.

Most of it eventually unwound the way these things do. Yields compressed as more capital chased them, reward token prices collapsed, and the protocols that had nothing underneath them besides circular incentives quietly died. Some protocols from that period are still running today with genuine utility. Most are not. The food tokens are largely gone. YAM still exists, somehow.

What's interesting in retrospect is that this entire structure was built on LP tokens being transferable ERC-20s. That single design property of Uniswap V2 unlocked an entire layer of financial infrastructure on top of it. Whether that infrastructure was mostly useful or mostly speculative is a debate worth having properly, and the composability story of 2020 DeFi deserves its own deep dive. We'll get there eventually.


Next up: TWAP oracles, and then we're done.

Top comments (0)