Follow me on Twitter âđ»
Before we will dive in the pretty complicated logic of the attack, i would like to give the brief overview what has happened. I am sure that you are familiar with the UniswapV3 Concentrated Liquidity and how the Ticks works. If no, take a look at it.
Part#1. Brief Overview
updateLiquidity
and grasp âextraâ liquidity from the other tick ranges in the pool.Part#2. Core functionality problem
Firstly, just understand that the swap functionality executed in the while
loop, until a set amount of liquidity is finished or a set slippage limit is reached. If the liquidity for the current tick range is finished the _updateLiquidityAndCrossTick
would be called to switch and retrieve the liquidity from the next tick.
However, we have the if
statement in the while
loop that could break the swap execution. If the break is called the while loop simply finish the execution, without calling _updateLiquidityAndCrossTick
.
In what scenario this if
statement could be triggered and break the execution?
Imagine that the price during the swap goes from destination A to destination B. If the swap doesnât reach the destination B, it evaluates as follow âOkay, swap price doesnât reach the destination B, it means that we have no need to update it and step into new liquidity, letâs just stop the execution in current range without updating everything.â
What attacker did? He simply force the check to think that price never reach the destination B while in reality it does , the goal was to break the execution! You can take a look on the photo and understand what happened.
Part#3 Reinvestment Curve Bug
Eventually, how the price managed to jump into the new tick without check being notified and still thinking that the price in the right range?
Quick intro: KyberSwap introduces a feature called "liquidity reinvestment" to address a drawback found in Uniswap V3. In Uniswap V3, pool fees are kept separate from liquidity, requiring Liquidity Providers to manually reinvest or reclaim them. The liquidity reinvestment feature in KyberSwap Elastic improves this problem by storing fees generated by the pool as a real liquidity, known as reinvestL. This enables LPs to benefit from compounding without the need for manual intervention. So! We can just use them!
Imagine the numbers, there were 100 Liquidity in the attacker ticks. When attacker executed the crucial swap he set 99.9 as an amount. Problem was: During the calculation the fee(reinvestL) was added to the price of the execution. Consequently, the execution price was not 99.9, but 99.9 + fee = 100.1. The tick is crossed without notification, protocol is brokenâŠ.
Overall
In the end, the swap has moved the price beyond the tick, into a new tick range, but because _updateLiquidityAndCrossTick
 hasnât been called, the pool doesnât modify the liquidity. Originally, when you enter a new tick range, _updateLiquidityAndCrossTick
 should have brought the liquidity for that tick with it, and since weâre out of the liquidity range here, the liquidity for that tick range should be recognized as zero. However, since _updateLiquidityAndCrossTick
 was not called, the liquidity for that tick range is recognised the same as the liquidity for the previous range, meaning we have tricked the pool into calculating double the liquidity.
In simpler terms, the Reinvestment Curve feature in KyberSwap Elastic causes the protocol to require more tokens than expected for a swap. This misjudgment halts the update process for liquidity in ticks crossed by the boundary.
Attacker managed to drain the funds from a couple of L2 via this vulnerability. After the hack, he has publicly stated that he wants to own the KyberSwap exchange. Funds was drained through the Tornado Cash. The hacker is still undetectedâŠâŠ
Resources used :