Automated market makers (CFMMs)
A constant-function market maker replaces the order book with a formula. It holds reserves of two or more assets and will accept any trade that leaves a chosen trading function of those reserves unchanged. Price is therefore not quoted by anyone; it is read off the reserves. The same convex object that prices a prediction market (a cost-function maker), priced from the reserves side, becomes the AMM that underpins decentralised exchanges.
The constant-product rule
The canonical instance (Uniswap) holds reserves $x, y$ of two assets and keeps their product fixed:
The marginal (spot) price of $X$ in units of $Y$ is the slope of the reserve curve, $p = y / x$. A swap of $\Delta x$ into the pool (after a fee $\gamma$, e.g. $0.3\%$, is skimmed from the input) returns
obtained by solving $\big(x + (1-\gamma)\Delta x\big)\,(y - \Delta y) = k$. Because the curve is convex, every finite trade executes at an average price strictly worse than the spot price, the slippage, or price impact, which grows with trade size relative to the reserves. Deep pools (large $k$) absorb trades with little impact; thin pools move sharply.
In code: ConstantProductAMM in
mechanisms/amm.py
exposes spot_price(), amount_out(),
swap(), and price_impact().
Constant mean, and StableSwap
Balancer generalises the product to a weighted geometric mean over $n$ assets, a self-rebalancing index fund:
Constant product is the two-asset, equal-weight case $w_i = \tfrac12$. The spot price of asset $i$ in units of $j$ is the weighted reserve ratio $(R_j/w_j)\,/\,(R_i/w_i)$. Curve's StableSwap instead interpolates between a constant-sum curve (zero slippage, for assets meant to trade near par) and constant product (which guarantees the pool can never be fully drained), tuned by an amplification coefficient $A$, the right shape for stablecoin pairs.
In code: ConstantMeanAMM in
mechanisms/amm.py.
Impermanent loss and LVR
An LP is effectively short volatility. Arbitrageurs always trade the pool back to the external market price, so it ends up holding more of whichever asset fell; the LP underperforms simply holding the initial basket. If the price ratio moves by a factor $r$, the constant-product pool's value relative to holding is
zero only at $r = 1$ and negative for any move in either direction. It follows from the pool rebalancing along $xy=k$: at price $p = r p_0$ the reserves become $x = \sqrt{k/p},\ y = \sqrt{kp}$, so the pool is worth $2\sqrt{kp}$ against a held basket worth $\sqrt{k}\,(p_0+p)/\sqrt{p_0}$, and the ratio is exactly the expression above. Fees are the LP's compensation; LPing beats holding only when accumulated fees exceed this divergence.
Loss-versus-rebalancing (Milionis–Moallemi–Roughgarden–Zhang, 2022) is the sharper modern metric: it benchmarks the LP not against a static HODL but against a continuously rebalancing portfolio, isolating the value that leaks to arbitrageurs and making the LP's running cost a clean function of volatility.
In code: impermanent_loss() in
mechanisms/amm.py;
raced against fees in the demo
examples/sim_amm.py.
Concentrated liquidity
Uniswap v3 lets an LP confine capital to a price range $[p_a, p_b]$, where it behaves like a constant-product position on shifted "virtual" reserves. Inside the range capital efficiency is far higher; once price exits, the position goes one-sided and inactive. Concentrated liquidity turns the LP's impermanent-loss / fee trade-off into a deliberate range-selection decision.
Why it is the dual of a cost-function maker
A prediction-market maker is a convex potential $C(q)$ with prices $\nabla C(q)$; a CFMM is a concave trading function $\varphi(R)$ with spot prices read from the ratio of its partials. Up to sign and a change of variables these are the same object viewed through convex duality: convexity is exactly no-arbitrage, and a bounded conjugate domain is exactly bounded loss. So LMSR, the general cost-function maker, and Uniswap/Balancer/Curve are all instances of convex-potential market making, the prediction-market side emphasising bounded-loss information elicitation, the DeFi side emphasising fees, impermanent loss, and capital efficiency.
Watch impermanent loss accrue
The external market price random-walks; an arbitrageur continuously trades against the $x\cdot y=k$ pool to keep its spot price in line. The LP's value (reserves marked at the live price) drifts below simply holding the starting basket; that gap, measured against holding, is impermanent loss, and it grows with realised volatility.
Try it: swap into the pool
Sell asset X into an $x\cdot y=k$ pool: see the output, the new spot price, and the impermanent loss an LP suffers for the resulting price move.
Code: mechanisms/amm.py ·
Demo: examples/sim_amm.py ·
Related: cost-function makers,
pm-AMM ·
Research: market-scoring-rules-and-amms.md