Almost every dev and auditor has by now heard of the term "ticks", which initially became famous because of @Uniswap and concentrated liquidity protocols in general.
But what are ticks and how are they used?
Well, a tick is nothing else as a number, which stores a very specific price. In Uniswap, if we take for example tick = 0, it corresponds to the price of 1. The tick difference between each tick is 0.01% (1.0001)
However, due to the fact that a price of 1 is hard to implement, this is done using the sqrtRatio of the price as fixed point number:
But what are ticks and how are they used?
Well, a tick is nothing else as a number, which stores a very specific price. In Uniswap, if we take for example tick = 0, it corresponds to the price of 1. The tick difference between each tick is 0.01% (1.0001)
However, due to the fact that a price of 1 is hard to implement, this is done using the sqrtRatio of the price as fixed point number:
This function will just return you the sqrtPrice at any tick, lets now use tick = 100 as example. This will return "79625275426524748796330556128" as sqrtPrice (Q64.94).
We can derive the real price using the following formula:
sqrtPrice ^ 2 / (2**192)
this will return the price: 1.010049 for tick = 100
So in summary, each tick represents a specific price.
How about tickSpacing?
Concentrated liquidity protocols represent a so-called tickSpacing variable. This variable determines to which ticks liquidity can be added. If for example tickSpacing = 30, this means liquidity can only be added to ticks 0,30,90,...
The reason behind this is simple: The protocol could not work without this limitation. An attacker could simply provide 1 wei of tokens to each subsequent tick, which then would result in a DoS of swaps because the swap would potentially need to iterate over 1000's of ticks, running out of gas / costing a large amount of gas.