Uniswap Hook Incubator — Ticks and Q64.96 Numbers #2
In the Uniswap v2, the price curve follows the formuala xy = k
. where k is a constant does not change, it only increases or decreases in value when users add / remove the liquidity. As a result to this, v2 price curve it an infinite continuous curve that never touches either of its axis.
In case of v3, since it follows the principle of concentrated liquidity, allowing users to specify the range in which to provide liquidity. So, the curves must be finite now right?
Ticks
A tick can be defined as a specific point on the curve where a trade can happen and it represents a specific price of the token. The ticks basically breakup the continuous curve into evenly spaced points where each point represents a specific price for a trade to happen.
Tick spacing is the gap between two such ticks.
Ticks <> Prices
The price of an asset at a given tick is represented by the equation
p(i) = 1.0001 ^ i
Lets assume a pool has two tokens A and B and address(A) = 0x00… address(B) = 0x12… Since the address(A) is smaller than address(B), A becomes Token 0 and B becomes Token 1. So the token prices is always represented in the form of x Token0 = y Token1
Example of Tick Price Calculation
Price at Tick = 10
p(i) = 1.0001 ^ i
i = 10
=> p(i) = 1.0001 ^ 10
= 1.0010004501
1 unit of Token A = 1.0010004501 units of Token B
In conclusion, A positive tick value means that Token A is worth more than Token B per-unit and vice-versa.
The tick values are stored as int24
data type. Even though the range of int24
is very large, the enforced tick range is The actual enforced range is [-887,272, 887,272]
It must very clear from the above example that when perform this computation we need a way to maintain the integer numbers without losing precision. The way to solve this is Q Notation and Q64.96 Numbers.
Q Notation and Q64.96 Numbers
They are used to represent numbers with 64 bits for integer part and 96 bits for fractional part of the given number.
Q_n = D_n * (2^k) where k = 96
Lets understand with the help of an example. Lets D_n = 1.
Tick price at point x = 1.000234
Q_n = 1.000234 * 2^96 = 79246701904292675448540839620.378624
we can store 79246701904292675448540839620 safely and
we lose a very negligible amount of precision.
How is the Q Notation useful?
Slippages are common amoung AMMs and the sqrtPriceLimitX96
sets via the user defined frontend slippage tolerance helps calculate the value. The X96
at the end of the variable signifies that this is a value in Q64.96 representation. Basically, the new sqrtPrice
is compared with the sqrtPriceLimitX96
if the limit exceeds based on direction of the swap the tx reverts.
Thanks for Reading ! Stay Tuned for the next blog !