KyberSwap 50 million$ exploit. SimplyÂ đŸ§‘đŸŸâ€đŸŽ€

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

  • Firstly. There were two tokens in the pool, WETH and frxETH. Attacker took the huge flashLoan of WETH to make the swap. The idea was to move the price to a tick with zero liquidity.
  • After that, attacker supplied equal amount of tokens to the tick range with zero liquidity. The idea was to adjust the token amounts in way, that attack could pass more smoothly in terms of calculation.
  • Consequently, the attacker executed the swap back and forth in this tick and gained the profit of additional 9 WETH due to miscalculation. In a few words, during the swap, when the tick was crossed, it didn’t 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 :

Subscribe to Arsen
Receive the latest updates directly to your inbox.
Mint this entry as an NFT to add it to your collection.
Verification
This entry has been permanently stored onchain and signed by its creator.