ruvaag

Uniswap v2 AMM Math

This article is a gentle mathematical introduction to Uniswap's x*y=k market maker. before we get into the working of the model, let's look into why it was needed in the first place.

The Problem

Tradfi exchanges use an order-book mechanism to settle trades. This system relies on institutional market makers to provide liquidity to the system where they make money on the bid-ask spread [1]. Unfortunately, the order book mechanism doesn't translate well to a decentralised system such as ethereum due to several reasons, most importantly –

The Solution

The solution to this problem came in the form of liquidity pools [3] which were widely popularised by uniswap. A liquidity pool is essentially a collection of locked funds used to facilitate certain operations using smart contracts— in this case trading. With liquidity pools, market makers are replaced by liquidity providers (LPs) and anyone can become an lp by adding funds to a pool. Uniswap provides LPs with tokens proportional to their share in the pool which can be burnt later to redeem their liquidity. LPs are incentivized to add funds by earning trading fees for providing liquidity.

These pools replace conventional order-books in DEXs (decentralized exchanges) by forming a collective source of liquidity. Uniswap v2 pools contain equal values of both tokens and LPs are incentivized to add tokens of equal values since they risk losing capital to arbitrageurs if this is not the case. from a trading perspective, Uniswap prices these assets in the liquidity pool using automated market makers (AMMs) [4] which can be described as protocols that price assets algorithmically without the need for any counterparty. These AMM algorithms can be complex and are implementation-specific. Uniswap v2 uses a constant product market maker model, with the invariant x*y=k where x and y are the quantities of two tokens in the liquidity pools and k is the invariant product that must remain constant.

To understand how this model prices an asset and facilitates a trade, let's run through a trade on uniswap.

Swapping Tokens with Uniswap

Consider a liquidity pool of token pair X and Y holding reserves x and y respectively at the moment. the invariant for this pool is the product of quantities of these tokens x*y which should remain constant over time. Simply put, you can exchange △x tokens of x using this pool for △y tokens of Y such that (x+△x)(y−△y)=x*y so that the invariant product of the quantities of two tokens in the pool remains constant. Solving the previous equation for △y it can be seen that we get △xx+△xy tokens of Y in exchange for △x tokens to ensure that the invariant holds true.

This hyperbolic graph for the constant product equation x*y=k also defines the pricing model thus implemented by the market maker. In this case, the marginal price is the derivative of the curve x*y=k→y/x. this mechanism is eponymously called the constant product market maker and is a major feature of Uniswap v1 and v2.

While the above equations represent the ideal case, uniswap charges users a 0.3% fee per trade which still needs to be factored into these calculations. This fee is added to the liquidity pool reserves and forms the incentives for LPs to provide liquidity. Let's see how this fits into the original equation. Once again, assume that you wish to swap △x tokens of X for △y tokens of Y to a uniswap pool which currently holds x tokens of X and y tokens of Y.

When you trigger this swap, Uniswap first collects its trading fee – assume that the fee rate (as part of total exchanged value) is ρ,0≤ρ<1 and γ=1−ρ. accordingly, after this fee collection, you're left with γ△x tokens of X which are to be swapped. The remaining ρ△x are out of the equation for now, but we'll get to them later. We now go back to our original product invariant, but the equations are slightly modified, we add γ△x of tokens instead of the original △x tokens. putting this in the original equation solving for △y —

(x+γ△x)(y−△y)=x*y(1+γα)(y−△y)=y,where α=△xx△y=γα1+γαy=γ△xx+γ△xy

So in this case we get a lesser bang for our buck, owing to the fees lost earlier. The fee component ρ△x is now added back to the pool and the total reserves now stand at (x+△x) tokens of X and (y−△y) tokens of Y, with the updated value of △y as computed above. This implies that product is not constant but actually increases gradually over time with every trade. The difference here forms the incentives given to LPs which can be claimed when they burn their liquidity tokens.

For a detailed formalization of this model and it's implementation you can refer to the Uniswap whitepaper [5] and the formal model specification [6].