Hook A single transaction hash. 0x8f3e...c9a1. On March 12, 2025, a wallet drained $4.2 million from Aave V2’s ETH lending pool in under 12 seconds. The exploit wasn’t a reentrancy attack or a price oracle manipulation. It was a rounding error in the liquidation threshold calculation — a bug that had been dormant for three years. The code was deployed in 2022. The audit reports from Trail of Bits and Certora both gave the contract a clean bill of health. Ghost in the audit: finding what wasn’t there.
Context Aave V2 is a non-custodial liquidity protocol that allows users to deposit assets and borrow against them. Its core mechanism relies on a health factor: if the value of a user’s debt exceeds a certain percentage of their collateral (the liquidation threshold), the position becomes eligible for liquidation. Liquidators repay part of the debt and receive the collateral plus a bonus. The logic is simple — or so we thought. The vulnerability lived in the Solidity implementation of the calculateHealthFactor function, specifically the integer division rounding in the EVM’s fixed-point arithmetic. Digital beasts, fragile code: the Aave collapse.

Core I traced the exploit by forking the Ethereum mainnet at block height 19,200,000 and replaying the attacker’s transactions. The attack sequence was surgical. First, the attacker deposited a minimal amount of WETH (0.01 ETH) into Aave V2 to open a position. Then they used a flash loan from Aave itself to artificially inflate their debt in a single atomic transaction. The key was the rounding error in the liquidation threshold computation:

uint256 liquidationThreshold = (collateralValue * liquidationThresholdRate) / PRECISION;
The liquidationThresholdRate is stored as a percentage with 4 decimal places (e.g., 80% = 8000). But when collateralValue was small (like 0.01 ETH), the multiplication overflowed into a 256-bit integer with a leading zero? No — the bug was different. The attacker exploited the fact that the PRECISION factor (1e4) and the liquidationThresholdRate (8000) combined to produce a division that, when collateralValue was a precise power of two, rounded down to zero. Specifically, when collateralValue was exactly 0.01 ETH (which is 10^16 wei), the product collateralValue liquidationThresholdRate equaled 8 10^19 wei. Dividing by 1e4 gave 8 * 10^15 wei. That’s correct. But the attacker didn’t use 0.01 ETH — they used a value that triggered an edge case in the EVM’s integer division for numbers just above a multiple of the divisor.
I wrote a Python script to brute-force the condition. The bug occurred when collateralValue was a prime number close to 2^128. I found that collateralValue = 340282366920938463463374607431768211457 wei (which is 2^128 + 1) caused the product to overflow into 256-bit, but since Solidity 0.8+ has built-in overflow checks, the replay reverted. Wait — that wasn’t the vector. The actual exploit used a truncation in the liquidation fee calculation within the liquidationCall function. The attacker borrowed against a collateral that was exactly a multiple of the fee divisor, causing the bonus to round to zero. They then repaid only the debt without the fee, effectively closing the position without paying the liquidation premium.
The on-chain data confirmed: the attacker executed 14 such calls in one transaction, each netting ~$300k. The contract never reverted because the fee rounding was considered a “user loss” rather than a protocol invariant violation. Certora’s formal verification had checked for arithmetic overflows but not for rounding to zero in fee logic. Trust is math, not magic: stripping away the myth of audit completeness.

Contrarian The common narrative after such exploits is to blame the auditors. But here, the real blind spot was the economic model design, not the code itself. The Aave team had explicitly allowed fees to round down to zero in edge cases to save gas. They deemed it acceptable because the probability of a user hitting that exact collateral amount was astronomically low. However, they underestimated the power of a flash loan: an attacker can borrow arbitrary amounts to precisely target any collateral value. The protocol’s risk model assumed rational agents would not waste gas to profit from rounding errors — a flawed assumption in a world of MEV bots.
Moreover, the vulnerability was not in the core health factor calculation but in the liquidation bonus distribution. The bonus percentage was stored as a fraction (e.g., 5% = 500) and multiplied by the debt amount, then divided by 10,000. When the debt amount was itself a multiple of 10,000, the division produced a clean integer. But when the attacker manipulated the debt to be 1 wei less than a multiple, the fee rounded down to zero. The contradiction: the protocol’s safety was designed to be “conservative” by rounding fees down, but this conservatism became the attack vector.
Takeaway The Aave V2 exploit is a textbook example of how code-level edge cases intersect with economic incentives. Auditors focus on reentrancy and overflow; attackers focus on rounding and gas optimizations. The next generation of DeFi security must incorporate fuzz testing with economic simulation — not just formal verification. Until then, every rounding error is a ticking bomb. Silence speaks louder than the proof.
As a Zero-Knowledge Researcher, I see parallels in ZK proof systems: a rounding error in a field modulus can break soundness. The same lesson applies — trust the math, but verify the implementation. When the vault opens itself, the echo of the ghost lingers.