$1,000,000 in security audit grants are live now, Apply here →

← Resource Hub

The Constant Product AMM: Swaps, LPs and Impermanent Loss

Updated 7 min read

Quick answer. A constant product AMM prices trades with x * y = k, where x and y are its two token balances. Swaps move along the curve and keep k fixed; adding liquidity raises k, which reduces price impact.

Automated market makers (AMMs) are perhaps the most common and important DeFi primitive. They enable permissionless onchain trading, 24/7, for anyone in the world, and they are the bedrock of DeFi.

As a smart contract auditor, you need a deep understanding of them. This guide covers what you need to know about the constant product AMM, with every number worked through by hand.

What Is a Constant Product AMM?

There are many kinds of automated market maker. Constant mean, constant sum, hybrid function and dynamic AMMs all exist.

The most famous and most widely adopted is the constant product AMM, implemented most famously by Uniswap.

It is essentially one equation, based on the supply of the two tokens in a market.

x * y = k

Here x is the amount of one token, y is the amount of the other, and k is simply a measure of the pool's liquidity.

A Swap, Step by Step

Start at one point on the x * y = k curve. The pool holds 5 ether (the x-axis token) and 25,000 DAI (the y-axis token).

That is 25,000 DAI for 5 ether, a price of 5,000 DAI per ether. Plugging the point into the formula gives the curve's k:

k = 5 * 25,000 = 125,000

Solving for the output

Now a trader swaps 5,000 DAI into the pool. That shifts the point on the curve to the left.

The change in y, dy, is the 5,000 DAI. The matching change in x, dx, is how far the pool's ether balance falls: the ether the trader gets out.

During a swap, k does not change. That is where the name constant product comes from: while people trade, the supply of each token changes, the product does not, and that is where price comes from.

So after the swap, y is 25,000 plus the trader's 5,000, x is 5 minus the unknown dx, and their product is still 125,000.

(5 - dx) * (25,000 + 5,000) = 125,000
5 - dx = 125,000 / 30,000 ≈ 4.1667
dx ≈ 0.833 ether

The trader put in 5,000 DAI and got about 0.833 ether out.

The price the trader got

Relate the 5,000 DAI to the 0.833 ether to get the rate the trader actually paid.

5,000 DAI / 0.833 ether ≈ 6,000 DAI per ether

The pool's price was 5,000 DAI per ether, but the trader experienced roughly 6,000 during the swap.

The Liquidity Provider's View

During a trade, k cannot change; only the amounts of x and y do. When someone provides liquidity, k increases.

That makes sense, because k is the product of the two token supplies. Increase both supplies, and k gets larger.

A larger k means swappers experience less price impact and get better execution. The numbers below prove it.

Depositing at the pool's ratio

Keep the same pool: 5 ether and 25,000 DAI, so ether trades at 5,000 DAI.

To add liquidity, you have to deposit at the same ratio as the pool's balances. For every ether you provide, you provide 5,000 DAI, so you do not change the ratio and therefore do not change the price.

Say you deposit 5 ether and 25,000 DAI, and the total supply of LP tokens in circulation is 5.

Minting LP tokens

The LP tokens you receive come from comparing what you deposit with what was already in the pool, multiplied by the total LP supply.

LP minted = amount deposited / amount in pool * total LP supply

Using ether: 5 / 5 * 5           = 5 LP tokens
Using DAI:   25,000 / 25,000 * 5 = 5 LP tokens

Both tokens give the same answer: 5 LP tokens minted to you. The total supply becomes 10, and you own 5 of the 10, or 50%.

The pool now holds 10 ether and 50,000 DAI. Burn your 50% of the LP tokens and you get 50% of the pool, which is exactly the 5 ether and 25,000 DAI you put in.

Deeper Pools, Better Prices

With the supply of each token doubled, the new k is:

k = 10 * 50,000 = 500,000

Doubling both tokens multiplied k by four. Now run the same 5,000 DAI swap against the deeper pool.

(10 - dx) * (50,000 + 5,000) = 500,000
10 - dx = 500,000 / 55,000 ≈ 9.09
dx ≈ 0.909 ether

Before, 5,000 DAI bought about 0.833 ether. Now it buys about 0.909, a little more than 0.9.

5,000 DAI / 0.909 ether ≈ 5,500 DAI per ether

The execution price is about 5,500 DAI per ether, much better than the 6,000 before the liquidity was added.

That is the service a liquidity provider offers. By increasing k, you make swappers far less exposed to negative price impact.

Providing liquidity is a passive way to add value to the DeFi ecosystem and earn fees and rewards in return.

It has risks, though. Besides exposure to the assets you provide, there is the classic risk of impermanent loss.

Impermanent Loss, Worked Through

Impermanent loss is the relative loss a liquidity provider experiences when the supplies of the pool's two tokens diverge.

You have probably heard that definition. Here is exactly where the loss comes from, using the running example.

The pool moves

The pool holds 10 ether and 50,000 DAI. You deposited 5 ether and 25,000 DAI and received 5 of the 10 LP tokens, so you own 50% of the pool's assets.

Now, over time, 5 ether are swapped into the pool for DAI. That could be one large trader, or many smaller traders and arbitrageurs.

After the swap math works out, the pool holds 15 ether and about 33,333 DAI. Check it yourself with the swap formula above.

The pool's price of ether is now 33,333 divided by 15, roughly 2,222 DAI.

Withdraw, or hold?

Burn your 5 LP tokens and you get 50% of each side: 7.5 ether, now worth about 2,222 DAI each, plus half of the 33,333 DAI.

LP position: 7.5 * 2,222 + 16,666 ≈ 33,333 DAI
Holding:     5 * 2,222 + 25,000   ≈ 36,110 DAI

The LP figure makes sense. Each side of the pool holds half its value, so withdrawing 50% of the pool gives you value equal to one side, and the DAI side is already in dollars.

If you had simply held your 5 ether and 25,000 DAI, you would have about 36,110.

StrategyEtherDAIValue at 2,222 DAI per ether
Provide liquidity, then withdraw7.5About 16,666About 33,333 DAI
Just hold525,000About 36,110 DAI

The difference is the impermanent loss: the loss you took by depositing into the pool while swappers and arbitrageurs traded against it.

33,333 - 36,110 ≈ -2,777 DAI

With all the rounding, you lost roughly 2,777 dollars by providing liquidity instead of just holding the two assets.

Why LPs end up with the losing token

As the liquidity provider, you ended up with more of the token that fell in value: 7.5 ether instead of 5. Holding less ether and more DAI would have been more profitable.

When people swap ether to DAI, the pool fills up with ether, and ether is the token trading down.

That holds in either direction. Whether ether goes up or down, liquidity providers always end up with the losing token, so some impermanent loss occurs whenever the token supplies diverge.

Practice the Numbers

Work through each example yourself until you get the same answers and understand every step.

That gives you a solid base for more complex DeFi primitives built on the constant product AMM, such as Uniswap V3 concentrated liquidity.

To see how attackers profit from the price impact you just calculated, read about sandwich attacks.

How Guardian Helps

Guardian has reviewed novel AMMs, including Poolshark's cover and limit AMMs and Abracadabra's MIMSwap.

A smart contract audit pairs invariant suites around accounting, rounding and math edge cases with senior researchers who attack protocol logic and integrations.

Frequently Asked Questions

What does k mean in x * y = k?

The value k is the product of the pool's two token balances and a measure of its liquidity. It stays constant during swaps and grows when liquidity is added.

How do you calculate a swap's output in a constant product AMM?

Keep k fixed. Add the input to its token's balance, divide k by that, and subtract the result from the other balance. With 5 ether, 25,000 DAI and 5,000 DAI in, you get about 0.833 ether.

Why does more liquidity give better prices?

Adding liquidity raises k, so the same trade moves the pool less. In the worked example, a 5,000 DAI swap paid about 6,000 DAI per ether in the shallow pool and about 5,500 after liquidity doubled.

What is impermanent loss?

It is the loss a liquidity provider takes, relative to just holding, when the pool's token supplies diverge. LPs end up with more of the token that fell. In the example: about 33,333 DAI versus 36,110.

Sources

Get your AMM math reviewed

Guardian builds invariant suites around your pool's accounting and rounding, then attacks what they leave standing.