Summary
On February 12, 2025 zkLend, a money-market protocol on Starknet, lost about $9.5 million (roughly 61 wstETH) through an integer-division rounding exploit in its lending accumulator on an empty market. The attacker deposited 1 wei into an empty wstETH market where reserve balance and zToken supply were zero, then used repeated flash-loan borrow-and-repay cycles to inflate the lending_accumulator, computed as (reserve_balance + total_debt - amount_to_treasury) * 1e27 / ztoken_supply, to an extreme value around 4.069e45. Because zToken amounts are derived via amount * 1e27 / lending_accumulator using direct division that rounds down, the attacker could deposit a few wstETH yet mint only 1 zToken, and on withdrawal burn 1 zToken while pulling out more wstETH than deposited. Repeating this rounding asymmetry grew the raw balance and let the attacker drain wstETH and other assets across the protocol.
How to avoid it in your code
- Never initialize accumulator-based markets from an empty state; require a protocol-seeded initial supply so the accumulator cannot be inflated.
- Round share/zToken issuance down and asset withdrawal in the protocol's favour so a withdrawal can never exceed the value deposited.
- Track reserves internally instead of reading raw balances, so donations and flash-loan repayments cannot manipulate the accumulator.
- Cap per-transaction or per-block growth of the lending accumulator and reject deposits that mint zero shares.
- Add scaled-precision or virtual-offset arithmetic so integer division truncation cannot be weaponized at low supply.
References
Related vulnerabilities
All Web3 →- CRITICALWEB3-BUNNI-2025
On September 2, 2025 Bunni, a liquidity manager built on Uniswap v4, was drained of roughly $8.4 million across Ethereum and Unichain (USDC, USDT, and weETH/ETH) through a rounding error in its withdrawal accounting amplified by flash loans. Bunni's Liquidity Distribution Function (LDF) tracks an 'idle balance' that is rebalanced on every swap, and the withdraw path rounded that balance in the wrong direction under specific conditions. The attacker flash-borrowed millions in USDT and executed a precisely sized sequence of swaps that pushed the pool's spot price back and forth across tick boundaries, triggering the faulty rounding repeatedly; each cycle let them withdraw more tokens than they burned in liquidity (in the USDC/USDT pool the idle balance fell 85.7% while liquidity fell only 84.4%, and that gap was the leak). The bug was application-specific accounting math, not an oracle or price-feed flaw. Unable to fund a secure relaunch, the Bunni team announced on October 23, 2025 that it was permanently shutting down, leaving withdrawals open and relicensing v2 from BUSL to MIT.
- CRITICALWEB3-SONNE-2024
On May 14, 2024 Sonne Finance, a Compound v2 lending fork on Optimism, lost about $20 million when an attacker exploited a freshly created, low-liquidity VELO (Velodrome) market. Because market creation and the protective collateral-factor setup were split across timelocked permissionless transactions two days apart, the attacker acted inside the window before the market was safely seeded. The attacker minted the minimum amount of soVELO cTokens (1 wei) and then donated a large quantity of VELO directly to the soVELO contract, inflating totalCash while totalSupply stayed near zero. Since exchangeRate equals (totalCash + totalBorrows - totalReserves) / totalSupply, this empty-market rounding manipulation drove the cToken exchange rate up so the tiny share position was valued as enormous collateral. The attacker then borrowed roughly 265 WETH plus available USDC.e against the over-valued collateral, draining about $20M within about 25 minutes.
- HIGHWEB3-ONYX-2023
On November 1, 2023 Onyx Protocol, a Compound v2 lending fork on Ethereum, lost about $2.1 million, and the same unfixed bug class was exploited again in September 2024 for about $3.8 million. A newly added, unfunded oPEPE market was left with zero supply because the protocol skipped the standard practice of minting and burning initial cTokens. The attacker used an Aave/Balancer flash loan to mint a tiny amount of oPEPE in the empty market, then donated PEPE directly into the contract to inflate the cToken exchange rate, exploiting the rounding in exchangeRate at low totalSupply. With the artificially over-valued oPEPE counted as collateral, the attacker borrowed other assets and, on redemption, the truncation let them withdraw more value than they supplied, draining the protocol. The September 2024 repeat applied the same empty-market exchange-rate manipulation to a fresh VUSD/oETH market plus an NFTLiquidation input-validation flaw.
- HIGHWEB3-ERC4626-INFLATION-2023
Disclosed publicly by OpenZeppelin on August 15, 2023 and leading the ERC-4626 audit checklists from Trail of Bits and Spearbit, this is the canonical tokenized-vault accounting bug, with real losses such as roughly $200K on early unprotected vaults. The attacker becomes the first depositor into an empty vault and mints 1 share for 1 wei of the underlying. The attacker then transfers (donates) a large amount of the underlying directly to the vault contract, bypassing the mint logic, so totalAssets rises while totalSupply stays at 1. A subsequent depositor's share count, computed as assets * totalSupply / totalAssets, rounds down to zero because their deposit is smaller than the inflated price-per-share. The attacker, still holding the only share, then redeems the entire balance including the victim's captured deposit. The root cause is integer division truncation in share pricing at low totalSupply combined with assets being increased by raw transfers.
- HIGHWEB3-FRONTEND-DNS-HIJACK-2022
A frontend hijack leaves the on-chain contracts untouched but replaces the Web2 surface serving the dApp UI with a wallet-drainer clone, so no Solidity audit can catch it. The recurring pattern: attackers take over the domain registrar or DNS provider account (or a CDN/tag-manager account), repoint the domain to a cloned site, and prompt visitors to sign malicious token approvals, EIP-2612 permit signatures, or transfers. Curve Finance was hit twice: on August 9-10, 2022 its curve.fi domain was DNS-hijacked via a compromised nameserver and drained ~$570K in USDC/DAI; and again around May 12, 2025 at the registrar level, after which Curve permanently migrated to curve.finance and announced an ENS move (Convex Finance and Resupply, which depend on Curve's data feeds, suffered dependency-driven outages but were not themselves compromised). In July 2024 a mass wave hit DeFi domains registered through Squarespace, whose forced migration off Google Domains stripped 2FA: Compound's frontend redirected to an Inferno Drainer clone and 100+ protocols were exposed (Celer blocked its takeover via domain monitoring). Ambient Finance's domain was hijacked through stolen registrar credentials on October 17, 2024. Most recently, on April 14, 2026 attackers used forged identity documents to social-engineer the registrar into handing over DNS control of CoW Swap's swap.cow.fi and cow.fi domains, redirecting users to a pixel-perfect drainer clone for about 90 minutes; over $1M was taken in roughly three hours, including 219 ETH (~$750K) from a single wallet, while CoW's contracts, backend APIs, and solver network were untouched. The same bucket includes CDN-account injections (KyberSwap's September 2022 Cloudflare/Google Tag Manager compromise, ~$265K) and BGP route hijacks that swap signed bundles for drainer code.
- CRITICALWEB3-CETUS-2025
On May 22, 2025 Cetus Protocol, the leading DEX on Sui, was drained of approximately $223M. The root cause was a flawed overflow check: the checked_shlw function in the integer-mate math library built its guard mask as 0xFFFFFFFFFFFFFFFF << 192 instead of 0x1 << 192, so values above 2^192 slipped past the check and the subsequent 64-bit left shift silently overflowed (left shifts do not abort in Move). The flaw lived in get_delta_a, which computes the tokens needed for a liquidity position; under the overflow the numerator wrapped to a tiny value, so the function demanded as little as 1 token unit for an enormous liquidity amount. Using flash swaps (borrowing ~10M haSUI), the attacker opened a tight-range position (ticks [300000, 300200]) and minted a massive amount of liquidity for a negligible deposit, then withdrew real pool reserves. Around $162M was frozen on-chain by Sui validators and eventually returned, while roughly $62M was bridged out to Ethereum. Cetus relaunched after recovering and replenishing affected pool liquidity.