The Uniswap v3 whitepaper includes a formula (Eq. 2.2) for computing the concentrated liquidity value from the real reserves of the tokens in a position:
I was asked on how to derive this formula, as I wrote a Uniswap v3 math explainer, but did not discuss this topic. Once you understand the idea, the derivation is quite simple.
The different coordinate systems
Depending on the goal, it’s convenient to think about a liquidity position with in an Automated Market Maker such as Uniswap v3 in one of these two ways:
- First option: y axis is the liquidity, x axis the price (or, because of technical reasons, logarithm of the price).
- Second option: y axis is the amounts of “Y” tokens in the position, x axis is the amounts of “X” tokens in the position.
These different coordinate systems are useful for different purposes:
- To calculate the slippage and the amount of fees a position is going to earn in proportion to other positions in the pool, the liquidity/price coordinate system is more useful.
- To see the amounts of tokens in the position — for example, to open or to close the position — the “amount of tokens” coordinate system is more useful.
In a classical Automated Market Maker such as Uniswap v2, liquidity is uniform across all price ranges, and in the liquidity/price it shows up as just a constant function (a horizontal line). Due to the concentrated liquidity feature, in Uniswap v3 the liquidity graph looks like a histogram: a piecewise constant function.
In the “amount of tokens” coordinate system, the liquidity shows up as a hyperbola in Uniswap v2. In Uniswap v3, it is a series of curved line segments.
In this graph, all positions at a constant price k form a line: y=kx. The steeper this line, the higher the price. (By convention, the price is expressed of X in terms of Y.) The liquidity determines the distance of a point on this line from the center of the coordinate system.
Liquidity positions in the different coordinate systems
Given virtual reserves x and y, the liquidity L is simply this (Eq. 2.1):
In the price/liquidity coordinate system, a Uniswap v3 concentrated liquidity position is a single bar. In the “amount of tokens” coordinate system, it is a segment of the hyperbola between points A and B. The shape of the hyperbola function is invariant to liquidity: it’s the same for all positions in the same price range. This means that the position is fully determined by the coordinates of its endpoints A and B.
Deriving the real reserves formula
In the concentrated liquidity approach, a liquidity position has only single token (X or Y) if the price range of the position does not include the current price. This means that when translating to real reserves of X and Y, the goal is to move the curve segment between points A = (ax, ay) and B = (bx, by) to points A’ and B’. Let’s rename ay to “y_offset” and bx to “x_offset” for clarity. to At the point A’=(ax — x_offset, 0) the Y token reserves is zero, and so that at the point B’=(0, by — y_offset) the X token reserves is zero.
This formula describes how to shift the function algebraically, leftwards by x_offset and downwards by y_offset:
The coordinates of the points A and B are very simple to express in the price/liquidity coordinate system, where Pa is the minimal price and Pb is the maximal price of the position:
Our goal is to translate these coordinates to the “amounts of tokens” coordinate system. A unique combination of price and liquidity corresponds to unique x and y coordinates:
- The price P of y in terms of x corresponds to the slope of the line y=P·x on which the point sits.
- The liquidity L of the position determines the distance from the coordinate center on that price line.
Let’s say we have a point (P, L) in the price/liquidity coordinate system. We can find its coordinates in the “amount of tokens” coordinate system by looking at the intersection of the price line and the liquidity curve. Algebraically, it’s a system of two equations:
Replace y with P·x and solve for x:
In the same way solve for y:
The x coordinate of the point B (i.e. x_offset) is bx=L/sqrt(P_b), and the y coordinate of the point A (i.e. y_offset) is ay=L·sqrt(P_a). These values are the amounts the liquidity curve needs to be shifted, so if we plug them in the equation 2.1 we get the equation 2.2:
Further reading: you may also want to check this excellent article and formula derivations (in the end) by Paradigm’s Dan Robinson, one of the authors of the v3 whitepaper: https://www.paradigm.xyz/2021/06/uniswap-v3-the-universal-amm
Acknowledgements: the author thanks to Anatoly Ressin for the idea to consider the two different coordinate systems.