Halborn Logo

// Blog

Explained: Hacks

Explained: The KyberSwap Hack (November 2023)


profile

Rob Behnke

December 11th, 2023


In November 2023, KyberSwap Elastic, the decentralized exchange’s concentrated liquidity protocol, experienced a hack. By exploiting a vulnerability in the protocol, the attacker stole an estimated $48 million.

Inside the Attack

The KyberSwap hack was made possible by a very small precision error in KyberSwap’s calculations of liquidity. These errors were so small that the attacker needed to perform a series of precise calculations that bypassed a check by less than 0.00000000001%.

Manipulating Pool Liquidity

The KyberSwap attack began with a flash loan; however, unlike most flash loan exploits, the goal wasn’t price oracle manipulation. Instead, the attacker was taking advantage of KyberSwap’s concentrated liquidity model.

In a concentrated liquidity model, liquidity providers offer liquidity that is accessible for a certain range of prices (between two ticks). The KyberSwap attacker used their flash loan to push the pool price of the targeted liquidity pools to a range where no liquidity existed. The goal was to have complete control over liquidity calculations since no one else had liquidity in that range. 

Once the pool price was in that range, the attacker minted liquidity in the range. 

Then, they carried out two precise swaps:

  1. A swap selling a token (such as wstETH) designed to push the price to just below the target range.

  2. A buy of the same token that pushed the price above their target liquidity range.

Exploiting Arithmetic Errors

After these two swaps, the attacker has successfully drained the pool. The reason for this is that they were able to control when the updateLiquidityAndCrossTick function was called. This function is designed to execute whenever the pool value crosses a tick value and updates the amount of liquidity available to a user.

The problem is that, in the first swap, a small difference exists in how the code calculates two values:

  1. The maximum amount that can be swapped before hitting the next tick boundary

  2. Whether the result of a swap is a price at the next tick boundary.

Step 1 executes first and is intended to determine whether a swap will cross tick boundaries. If the swap is less than the maximum it shouldn’t cross the tick boundary. Then, step 2 is executed while assuming that the final price will either be inside the bound or equal to it. Due to this assumption, this calculation uses a strict equality test.

The problem is that these two functions used slightly different arithmetic, so, in one case, the boundary calculated in Step 1 was 1056056735638220800000, while the swap quantity was 1056056735638220799999. The swap amount was less than the value in Step 1, but not equal to the boundary value of 1056056735638220800000. As a result, it passed Step 1 while breaking the assumption that Step 2 relied upon.

Double-Counting Liquidity

The result of this careful swap is that updateLiquidityAndCrossTick was not called in the first swap (the sell) but was called in the second. The first call should have removed the liquidity associated with a given range as the pool price moved outside that range. Since it didn’t that liquidity was still available despite being out of range.

The second call to the updateLiquidityAndCrossTick function (during the buy) is designed to add liquidity when the pool price moved into the range where liquidity was available. This call executed, so the liquidity was added despite the fact that it was never removed during the first swap.

By double-counting liquidity, the attacker manipulated the exchange rate of a token pair. In the second swap, they received much more of the token than they paid in the first. By draining multiple liquidity pools, they were able to steal about $48 million.

Lessons Learned from the Attack

The KyberSwap hacker exploited a vulnerability in the protocol’s concentrated liquidity calculations. By performing similar arithmetic two different ways and assuming that they would have the same result, the protocol introduced a vulnerability where a carefully crafted swap could drain the protocol’s liquidity pools.

Liquidity calculations and other mission-critical arithmetic should undergo careful audits to help ensure that they don’t have these types of errors. To schedule an audit for your protocol, get in touch with Halborn..