# KyberSwap Elastic: precision loss enables double liquidity counting drain

Incorrect rounding in KyberSwap Elastic's reinvestment liquidity caused tick miscalculation and double liquidity counting, letting an attacker drain ~$48M from pools via flash-loan-funded swaps.

- Payout: Real-world hack
- Severity: critical
- Program: KyberSwap
- Analysis by: DeFiHackLabs
- Disclosed: 2023-11-22
- Write-up quality: 8/10
- Original: https://github.com/SunWeb3Sec/DeFiHackLabs/blob/main/src/test/2023-11/KyberSwap_exp.eth.1.sol
- Library page: https://bugbountylibrary.com/r/dhl%3A20231122-kyberswap-exp-eth-1
- Tags: area:web3 domain:web3 impact:funds-loss kind:incident platform:defihacklabs sev:critical tech:evm tech:solidity technique:chained vuln:accounting-error vuln:flash-loan vuln:oracle-manipulation vuln:precision-loss

**Target:** KyberSwap Elastic concentrated-liquidity pool (frxETH/WETH) and position manager
**Root cause:** Incorrect rounding direction during the reinvestment-liquidity computation in computeSwapStep produces a slightly wrong nextSqrtP, which maps to an incorrect tick; crossing that tick double-counts liquidity.
**Steps:**
1. Flash-borrow 2000 WETH from Aave V3 via `flashLoanSimple`.
2. Swap to move the pool into a tick range with zero liquidity: `IKyberswapPool(victim).swap(attacker, amount, false, 0x100000000000000000000000000, "")`.
3. Read pool state `getPoolState()` to get currentTick/nearestCurrentTick, then `mint` a tiny position at [nearestCurrentTick, nearestCurrentTick] with liquidity 6948087773336076.
4. `removeLiquidity` the position to trigger the rounding/tick miscalculation.
5. Perform back-and-forth swaps (`swap` with large amountSpecified then `-balanceOf(victim)`) to cross the miscomputed tick and double-count liquidity, extracting token0/token1.
6. Repay Aave flash loan with premium.
**How found:** BlockSec traced the anomaly to tick manipulation and double liquidity counting, then confirmed via the attacker's own message that the root cause was precision loss from incorrect rounding direction in the reinvestment computation.
**Exploitation:** Attacker flash-loaned 2000 WETH from Aave V3, manipulated the pool into a zero-liquidity tick range, minted and removed a minimal position to exploit the rounding error in reinvestment liquidity, then executed paired swaps that crossed the incorrectly computed tick, double-counting liquidity and draining ~$48M across multiple pools.
**Escalation:** Same technique applied across multiple KyberSwap Elastic pools, total losses exceeding $48M.
**Insight:** When auditing Uniswap-V3 forks with auto-compounded 'reinvestment' liquidity, check rounding direction of nextSqrtP and whether tick derivation from sqrtP can land on a boundary tick that double-counts liquidity; tiny mint/remove positions at the nearest tick are a cheap probe.
