KyberSwap Elastic (2023)
A $48M exploit against KyberSwap Elastic — KyberSwap's concentrated-liquidity AMM — in November 2023. The bug was a tick-math edge case: by manipulating the price into a very specific range near a tick boundary, the attacker caused the pool to compute liquidity incorrectly, double-spending the same liquidity across positions.
Timeline
- November 22, 2023: Attacker drained ~$48M across multiple KyberSwap Elastic pools on Arbitrum, Optimism, Polygon, Ethereum, and Base.
- Same day: KyberSwap paused affected pools.
- November 30, 2023: KyberSwap published a postmortem.
- December 2023: Attacker engaged in extensive on-chain communications, demanding governance concessions in exchange for funds return. Most funds not returned.
Root Cause
KyberSwap Elastic's tick math, like Uniswap V3's, tracked liquidity by ticks (discrete price points). Each position spans a range of ticks; pool liquidity is the sum of active positions' liquidity at the current price.
The bug: at certain tick boundary conditions, the pool's invariant — that currentLiquidity equals the sum of active position liquidity — could be violated. Specifically:
- When the price moved exactly to a tick boundary from a direction where multiple positions ended at that tick, the liquidity-update arithmetic could double-count.
- The attacker could exploit this to make the pool believe its liquidity was larger than it actually was, then swap against this phantom liquidity at favorable rates.
The math involved was Uniswap V3-derived but had KyberSwap-specific extensions for re-investment and dynamic fees, which interacted with tick boundaries in ways that pure V3 didn't.
Exploit Path
The attacker's transactions were carefully orchestrated. Approximately:
- Add a tightly-targeted concentrated liquidity position at a specific tick range.
- Use a flash loan to make a series of large swaps that drove the price to exactly the right tick boundary.
- At the tick boundary, the pool's liquidity bookkeeping went wrong: the pool over-counted the attacker's position's contribution to the pool's active liquidity.
- Subsequent swaps drained value from the pool at rates that the inflated liquidity made appear acceptable.
- The attacker's position was effectively "double-counted" — they extracted value matching their actual position twice over, once per double-count.
The on-chain transaction sequence was complex; reproducing it required deep understanding of the tick math.
What an Audit Should Have Caught
KyberSwap Elastic had been audited multiple times. The bug was in subtle tick-boundary arithmetic that was hard to verify by inspection.
Findings that, in retrospect, should have been pursued:
-
Tick-boundary edge cases need rigorous formal verification. Uniswap V3's tick math was famously challenging; KyberSwap's extensions added more complexity. For this category of math, fuzzing and formal verification (Certora, Halmos) are essential. Manual review can find some bugs but not the kind of edge case that requires exhaustive search.
-
The invariant
sum(active liquidity) == currentLiquidityshould be checked at every state-changing operation. If this invariant can ever fail by even one wei, the pool can be exploited. Property-based testing should target this invariant directly. -
Liquidity bookkeeping across position transitions. When the price crosses a tick where positions end, the bookkeeping must remove their liquidity contribution. Edge cases (positions ending exactly at the current tick, multiple positions ending at the same tick) need explicit tests.
-
The deviation from Uniswap V3 deserves extra scrutiny. Code that "is similar to Uniswap V3 but with extensions" is risky. The base contract was well-vetted; the extensions may not be. Audit reports should explicitly enumerate every deviation from a reference implementation and audit each one independently.
Lessons
-
Complex math is bug-rich. Concentrated-liquidity AMMs (Uniswap V3, KyberSwap Elastic, Algebra) involve substantially more math than constant-product AMMs. Bug density correlates with code complexity. Formal verification is increasingly necessary.
-
Fork-derived code inherits known bug status but is exposed to new bugs in modifications. "Based on Uniswap V3, audited by X, Y, Z" is partial reassurance — only the parts identical to Uniswap V3 benefit; the modifications need their own audit.
-
Tick-boundary cases are notorious. Other concentrated-liquidity exploits and near-misses (some Uniswap V3 forks, various Algebra implementations) involve similar issues. The combinatorial space of tick-boundary scenarios is large.
-
Formal verification is becoming table stakes for AMMs. Uniswap V3's formal verification by Certora has been a model. Concentrated-liquidity AMMs deployed without formal verification of core invariants are accepting substantial risk.
-
Audit reports should make verification methods explicit. A reader of an audit report should be able to tell: was this fuzzed? Formally verified? Manually reviewed? For each invariant, with what coverage? Vague "we reviewed the code" reports are insufficient for code this complex.
-
Multi-chain deployments multiply exposure. KyberSwap Elastic was deployed on five chains. The same bug exploited all five. A protocol going multi-chain should consider whether each deployment increases risk linearly (no — same code, same bug) or whether per-chain risk is more independent. KyberSwap's case shows multi-chain deployment multiplies impact, not safety.
-
On-chain extortion is a real outcome. The attacker's demands for governance concessions in exchange for fund return is a pattern that's appeared in other incidents (Euler had similar dynamics). The negotiation outcomes vary; protocols should not assume cooperative resolution.
KyberSwap Elastic is the canonical 2023 case for "concentrated-liquidity AMMs are math-heavy and audit-resistant." The industry response has been more formal verification, more conservative deployment patterns, and a degree of skepticism about complex AMM designs from less-resourced teams.