An automated market maker (AMM) is an algorithmic method for price discovery in a given market. This contrasts with the order book model used by traditional market makers.
Central to the story of AMMs on public blockchains is Uniswap, which is the most successful AMM by TVL/volume and has inspired many other AMM protocols.
The rest of this post summarizes the history of Uniswap and the math that makes it possible.
Timeline of Events
October 2016: Vitalik Buterin publishes a Reddit post introducing the general concept of an “on-chain automated market maker (AMM)”.
May 2017: Bancor publishes a whitepaper that describes the first AMM. Bancor’s approach was subjected to a lot of criticism that likely stifled the project’s growth.
June 2017: Vitalik publishes a blog post that introduces the constant product AMM. This would become the basis for Uniswap v1. (Vitalik credits Martin Köppelmann from Gnosis as the originator of this specific AMM formulation, but Hayden says it was actually Alan Lu at Gnosis that conceived of the idea.)
October 2017: Hayden Adams builds a proof-of-concept (“POC”) of Uniswap. The POC was never launched on the Ethereum Mainnet and consists of a single liquidity pool i.e., it allowed swapping of ETH for “UNI” (a generic testnet ERC20 token). Moreover, the liquidity pool only supports a single liquidity provider i.e., 2 or more wallets can’t contribute to the liquidity pool.
November 2017: Karl Floersch discusses AMMs at Devcon 3 and briefly presents Hayden’s proof-of-concept website. Pascal Van Hecke, who attended Karl’s presentation, becomes Hayden’s advisor.
March 2018: Hayden Adams and a few friends (“Uniswap”) build the first fully-featured demo of Uniswap v1. v1 features a factory contract that enables third parties to create an arbitrary number of liquidity pools. Moreover, each liquidity pool can be funded by an arbitrary number of wallets.
April 2018: Karl Floersch introduces Hayden Adams to Vitalik at Deconomy 2018 in Seoul, Korea. Vitalik encourages Hayden to apply for an Ethereum Foundation grant.
July 2018: Uniswap receives an Ethereum Foundation grant of $100,000.
October 2018: Hayden Adams finalizes the Uniswap v1 whitepaper and receives audit results from Runtime Verification. (Runtime Verification also produces a formal specification of the protocol.) Meanwhile, Jacky Chan at Kyokan builds a completely new version of the Uniswap v1 UI.
November 2018: Hayden Adams launches Uniswap v1 at Devcon 4.
April 2019: Uniswap raises a seed round led by Paradigm.
March 2020: Uniswap v2 is launched. Uniswap v2 makes marginal improvements to v1. For example, it supports direct ERC20-to-ERC20 transfers; v1 required ETH as an intermediary for all such trades.
May 2021: Uniswap v3 is launched, a new design that features concentrated liquidity.
The Constant Product AMM
Note: the following assumes a basic knowledge of differential calculus.
Uniswap v1 and v2 implement an ordinary constant product AMM. This is an algorithm for trading two fungible tokens, α and β. Let x be the liquidity pool reserves of α and y and the reserves of β. The market has reserves x > 0 and x > 0, constant product xy = L².
Consider the case where one desires to sell Δx units of α in exchange for Δy units of β. When the fee is 0,
The name constant product market comes from the fact that any trade Δx to Δy must change the reserves in such a way that the product of x and y remains equal to the constant L².
After each transaction, the reserves are updated in the following way: y ↦ y − Δy, x ↦ x + Δx, and L² ↦ L².
From an implementation perspective, there are two cases to consider:
- A trader wants to sell Δx units of α and the smart contract needs to compute Δy
- A trader wants to buy Δy units of β and the smart contract needs to compute Δx
For the first case, we have
For the second case, we have
These formulae are implemented here and here in Uniswap v1 and here and here in Uniswap v2. (Note that fees are ignored in this article.)
The price that a user realizes is simply
Moreover, we can define a marginal price, or the current price (P), as the swap price realized for small changes in x or y i.e.,
This formula suggests another approach to do the swap math. Note that
which implies that
These formulae represent an alternative way of computing Δx given Δy (and vice versa). In fact, this is the approach taken by Uniswap v3 to “avoid having to take any square roots when computing swaps”. (The whitepaper doesn’t go into the details motivating this approach, but all math in v3 is done on the square root of the price; the front-end application converts from √P to P and vice versa.)
Uniswap v3’s primary innovation is concentrated liquidity. As stated in the whitepaper, Uniswap v1 and v2 “were designed to provide liquidity across the entire price range (0, ∞). This… means that much of the assets held in a pool are never touched. Having considered this, it seems reasonable to allow LPs to concentrate their liquidity to smaller price ranges than (0, ∞).”
In other words, Uniswap v3 allows all of a user’s liquidity to be utilized within a specified price range i.e., all reserves are depleted at the boundaries of that price range.
This involves a transformation of the constant product AMM formula into 3 ranges as follows:
To understand why this formula makes sense, we can consider the boundaries i.e., we require P = pₐ when y = 0 and P = pᵦ when x = 0.
So when x = 0,
and when y = 0,
By substitution, we can also see that
In other words, x is a linear function of 1/√P and y is a linear function of √P.
So just as Uniswap v1 and v2,
As stated in the Uniswap v3 whitepaper, “when swapping one token for the other, the pool contract can first compute the new √P… and then can compute the amount of (x) or (y) to send out…”. (As stated earlier, in Uniswap v3, all calculations use √P as an intermediary variable; the front-end has the responsibility of squaring √P before it’s displayed to a user.)
That’s all there is to it! What makes v3’s code complicated (compared to v1 and v2) is the nuanced position accounting. There is not just a single liquidity pool anymore for each pair. Rather, there are a potentially unlimited number of positions that each have their own values of pₐ and pᵦ.
Hayden Adams’ Summary of the Early History of Uniswap
An Early Post from Vitalik on Improving Front Running Resistance
An Analysis of Uniswap Markets