Skip to content
Finance Lessons

Automated Market Makers (AMMs)

The Constant-Product Formula: x · y = k

The one equation that prices every AMM trade. How x·y=k turns two token reserves into a price, why a swap walks the pool along a curve, the 0.3% fee, and a fully worked swap.

9 min Updated Jun 4, 2026

Last lesson left you with a promise: an AMM prices trades against a pool using a formula, and that formula is the whole magic trick. Here it is, in all its anticlimactic glory:

xy=kx \cdot y = k

Two reserves. Multiply them. Keep the answer constant. That single line decides the price of every swap, why big trades cost more, why the pool can never run dry, and how liquidity providers get paid. It’s the most consequential multiplication in decentralized finance — and once it clicks, the rest of AMMs is just footnotes. Let’s make it click.

Before you read — take a guess

A pool holds 100 ETH and 200,000 USDC. Someone buys ETH by adding USDC. Right after that swap, what must be true of the product (ETH reserve) × (USDC reserve)?

The invariant: keep the product constant

Call the two reserves xx and yy — say xx is the ETH in the pool and yy is the USDC. The pool lives by one rule:

xy=kx \cdot y = k

where kk is a fixed number, the invariant. A swap is allowed to change xx and to change yy as much as it likes — but it must leave their product kk unchanged. You put one token in (that reserve goes up), you take the other token out (that reserve goes down), and the contract picks exactly how much comes out so that the product still equals kk.

Think of it as a seesaw with a very specific rule: the two seats can move freely, but the area of the rectangle they trace out is bolted to a constant. Push one side down and the other side must rise — and not by an equal amount, by whatever keeps the product fixed.

Plug in our numbers. A pool of 100 ETH and 200,000 USDC has:

k=100×200000=20,000,000k = 100 \times 200000 = 20{,}000{,}000

That 20 million is the pool’s identity card. Every legal state of this pool — every combination of ETH and USDC it can be in after any sequence of swaps — sits on the curve where xy=20,000,000x \cdot y = 20{,}000{,}000.

Info:

k is not a price

A tempting mistake: thinking kk is the price. It isn’t. kk just measures how much liquidity the pool holds — it barely changes. The price comes from the ratio of the reserves, which we’ll do next. Two pools can share the same price but have wildly different kk (one deep, one shallow). Keep “product = depth, ratio = price” separate in your head.

Spot price = the ratio of the reserves

So where’s the price? It’s the ratio of the two reserves. The spot price of ETH in terms of USDC is:

price=yx=USDC reserveETH reserve\text{price} = \frac{y}{x} = \frac{\text{USDC reserve}}{\text{ETH reserve}}

For our pool:

price=200000100=2000\text{price} = \frac{200000}{100} = 2000

One ETH is quoted at $2000. Intuitively: there are 2000 USDC sitting in the pool for every 1 ETH, so the pool values them at 2000-to-1. This is the spot price — the price for an infinitesimally small trade, the slope of the curve at the pool’s current point. The instant you trade a real, finite amount, the ratio shifts and the price you actually pay drifts away from it. That gap is the whole story of the next section.

Fill in the mechanics of a constant-product pool.

Pick the right option for each blank, then check.

A constant-product pool keeps the of its two reserves equal to a constant . The spot price of token X is the reserve of . When you sell token X into the pool, the X reserve goes and the Y reserve goes , so the price of X — measured as y over x — goes .

A swap walks the pool along the curve

Here’s the geometric picture that makes everything intuitive. Rearrange the invariant:

y=kxy = \frac{k}{x}

That’s a hyperbola — a curve that swoops down steeply on the left, flattens in the middle, and hugs the axes at the extremes. Every possible state of the pool is a single point sliding along this curve. A swap doesn’t jump the point somewhere new; it walks it along the hyperbola from the old reserves to the new ones.

To swap, you sell an amount Δx\Delta x of token X into the pool. The new reserves are:

  • New X reserve: x=x+Δxx' = x + \Delta x (you added X)
  • New Y reserve: y=kxy' = \dfrac{k}{x'} (forced by the invariant)
  • Y you receive: Δy=yy\Delta y = y - y' (the drop in the Y reserve)

Let’s grind a real example. You want to buy ETH by adding 2,000 USDC. Here ETH is the token leaving (X) and USDC is the token entering (Y), so it’s cleanest to track the USDC reserve as the one we add to:

  • Old reserves: 100 ETH, 200,000 USDC, with k=20,000,000k = 20{,}000{,}000.
  • Add 2,000 USDC → new USDC reserve y=200000+2000=202000y' = 200000 + 2000 = 202000.
  • Invariant forces the new ETH reserve: x=ky=2000000020200099.0099x' = \dfrac{k}{y'} = \dfrac{20000000}{202000} \approx 99.0099.
  • ETH you receive: 10099.00990.990100 - 99.0099 \approx 0.990 ETH.

So 2,000 USDC bought you about 0.990 ETH. What price did you actually pay?

average price=20000.9902020\text{average price} = \frac{2000}{0.990} \approx 2020

You paid about $2020 per ETH — already worse than the $2000 spot price you saw before you traded, even though you only nudged the pool by a couple thousand dollars. And the pool’s new spot price has moved too:

new price=20200099.00992040\text{new price} = \frac{202000}{99.0099} \approx 2040

The next person buying ETH starts from $2040, not $2000. Your trade pushed the price up, and it stays up until someone trades the other way. Drag the slider below and watch the pool point crawl along the curve — the readouts show your average price diverging from spot as the trade grows.

Constant product: x · y = kx · y = 20,000,000
ETH reserve (x)USDC reserve (y)
X sold in
0
Y received out
0
Old spot price
2,000
New spot price
2,000
Constant product k100 × 200,000 = 20,000,000100 × 200,000 = 20,000,000

Start at 100 ETH / 200,000 USDC, spot price 2000. As you sell more ETH into the pool, the point slides down the hyperbola: the ETH reserve climbs, the USDC reserve falls, and each extra ETH you sell fetches less USDC than the last. The product k stays pinned. That widening gap between spot and what you actually get is slippage — lesson 4.

Because the hyperbola never touches the axes. Look at y=k/xy = k/x: as you buy more and more ETH, the ETH reserve xx shrinks toward 0 — and k/xk/x blows up toward infinity. To buy ETH when only a sliver is left, you’d have to pour in a near-infinite amount of USDC, because the price (y/xy/x) rockets to infinity as x0x \to 0. The same holds the other way: as y0y \to 0, the price collapses to zero. So the reserves asymptote to the axes but can never reach them. You can buy 99.9% of the ETH if you’re rich and reckless enough, but the last unit is mathematically unbuyable. That asymptote is the genius of using a hyperbola: the pool is self-protecting and can never be emptied by a single trade.

Why bigger trades pay worse prices

Notice the pattern in the worked example: a tiny trade pays ≈ spot, but the price you actually get degrades as the trade grows. That’s not a bug — it falls straight out of the curve’s shape. The hyperbola is convex: the deeper you push a reserve, the steeper the trade-off gets, so each additional unit you buy costs more than the one before it.

A quick feel for the scale, all from the same 100 ETH / 200,000 USDC pool:

USDC you addETH you getAverage price paidNew spot price
2,000≈ 0.990≈ $2,020≈ $2,040
20,000≈ 9.091≈ $2,200≈ $2,420
100,000≈ 33.33≈ $3,000≈ $4,500

Spend 1% of the pool and you barely notice ($2020 vs $2000). Spend half the pool and you pay 50% over spot. The lesson: small trades ≈ spot price; big trades pay much more, and the penalty accelerates. This worsening is the seed of price impact / slippage, which gets its own full lesson (lesson 4) — for now, just internalize that the curve, not a fee, is what makes size expensive.

Sort each statement by whether it describes a SMALL trade or a LARGE trade against a constant-product pool.

Place each item in the right group.

  • Pushes the pool's point a long way down the hyperbola
  • Average price ends up far above spot
  • New spot price is almost unchanged afterward
  • Leaves the next trader facing a noticeably different price
  • Barely moves the pool's point along the curve
  • Average price is very close to the spot price

The fee: how LPs actually get paid

So far the math has been frictionless, and a frictionless pool would pay its liquidity providers nothing. Real AMMs add a swap fee. The classic Uniswap v2 fee is 0.3%, and the mechanism is delightfully simple: the fee is skimmed off your input and left inside the pool rather than traded against the curve.

Concretely, when you add 2,000 USDC with a 0.3% fee:

  • The fee is 0.003×2000=60.003 \times 2000 = 6 USDC.
  • Only 99.7% of your input — 1,994 USDC — actually trades against the curve and determines your ETH out.
  • The 6 USDC of fee is deposited into the pool anyway.

Because the fee tokens stay in the pool without buying any ETH out, the pool ends each swap holding slightly more than the invariant strictly required — so kk doesn’t stay perfectly constant, it ticks up a hair every single swap. That slow, relentless growth of kk is exactly the LPs’ income: their share of the pool now represents a bigger pile of reserves than they put in. Every trade fattens the pool a little, and LPs own a slice of the fattening. (This is why lesson 1’s ”xy=kx \cdot y = k stays constant” came with a quiet almost — fees nudge it upward.)

Info:

Constant-product is one invariant, not the only one

We’ve been studying the constant-product formula specifically — the Uniswap v2 design, where xy=kx \cdot y = k. It’s the canonical AMM, but not the only one: pools for assets that should trade near each other (two dollar-stablecoins, say) use a different stableswap invariant that stays nearly flat through the middle to cut slippage, and other designs concentrate liquidity in price ranges. Same big idea — a formula on reserves — different curve. This lesson is the foundation they all riff on.

Match each term to its precise meaning in a constant-product pool.

Pick a term, then click its definition.

Key Takeaways

Success:

What to remember

  • A constant-product pool obeys one rule: xy=kx \cdot y = k. A swap can change each reserve but must leave their product (the invariant kk) essentially unchanged.
  • The spot price of token X is the reserve ratio y/xy/x — depth is the product, price is the ratio. A 100 ETH / 200,000 USDC pool has k=20,000,000k = 20{,}000{,}000 and a spot price of $2000.
  • A swap walks the pool along the hyperbola y=k/xy = k/x: add Δx\Delta x, the invariant forces y=k/(x+Δx)y' = k/(x+\Delta x), and you receive yyy - y'. Adding 2,000 USDC buys ≈0.990 ETH at an average of ≈$2020 — already above spot.
  • The curve is convex, so big trades pay much worse than spot while tiny trades ≈ spot. That’s the seed of slippage (lesson 4).
  • You can never drain the pool: as a reserve → 0 the price → ∞, so the curve only asymptotes to the axes.
  • The 0.3% fee is skimmed from your input and left in the pool, so kk creeps upward every swap — which is how liquidity providers get paid.

Big picture

The constant-product formula at a glance

  • x · y = k
    • The invariant
      • Product of reserves is fixed
      • k = depth, not price
      • Swaps preserve k (almost)
    • Price
      • Spot price = y / x
      • Ratio, not product
      • 100 ETH / 200k USDC → $2000
    • A swap
      • Walks along y = k/x
      • Convex → big trades cost more
      • Can never drain the pool
    • The fee
      • 0.3% skimmed from input
      • Left in the pool, nudges k up
      • Pays the LPs
One screen for x·y=k — the foundation every later AMM lesson builds on.

Lesson 2 check

Question 1 of 50 correct

A pool holds 50 ETH and 100,000 USDC. What is its invariant k and its spot price for ETH?

Check your answer to continue.

Next up: liquidity providers and LP tokens — who actually fills the pool, what they receive for it, and how that creeping kk turns into their paycheck.

Mark lesson as complete