Through the first nine months of 2026, decentralized finance lost roughly $1.1–1.3 billion across more than 120 incidents — and while the headlines belong to billion-dollar infrastructure attacks, a quieter story runs underneath. The defi hacks 2026 tally includes a persistent drumbeat of arithmetic exploits: a $1.73 million drain of Notional Finance's legacy escrow and a $234,000 extraction from a Balancer V1 pool deployed in 2020. Both were caused by the same class of bug that has haunted DeFi since 2021 — rounding errors and integer boundary conditions — and both were preventable with techniques documented years ago. This YTD recap traces the 2026 landscape, dissects the two arithmetic attacks, and explains why precision loss keeps draining pools no matter how many audits a protocol passes.
The 2026 DeFi Hack Landscape: A Dual Narrative
Aggregate trackers disagree on the exact figure, but the shape of the year is consistent. CertiK and Forbes put total crypto losses at about $1.3 billion through the first eight months. Immunefi recorded $972 million across 207 incidents in H1 alone — the highest incident count it has ever logged. CryptoRank counted 121 DeFi-specific hacks totaling roughly $942 million, and shattered.io tracked $816.9 million in DeFi losses by early September. Q2 was the most active quarter (85–99 incidents, ~$746–775 million), and August set a single-month record with 50 hacks.
The dominant story is infrastructure compromise. For the first time on record, private-key and infrastructure attacks overtook smart-contract bugs as the leading vector. The two largest incidents of the year — Drift Protocol ($285 million, April 1) and KelpDAO ($292 million, April 18) — were both attributed to North Korea's Lazarus Group (TraderTraitor), together accounting for about 44% of total losses. Drift was taken via social engineering and admin-key compromise through durable nonces; KelpDAO via a 1-of-1 LayerZero DVN and RPC poisoning.
But underneath those headline grabs, rounding and precision errors kept striking. The Notional Finance hack and the Balancer V1 hack are small in dollars but large in significance: they show that the DeFi ecosystem still ships and still leaves running immutable code that violates the most basic arithmetic-safety rules.
| Date | Protocol | Loss | Vector |
|---|---|---|---|
| Apr 1 | Drift Protocol | $285M | Social engineering, admin key (durable nonces) |
| Apr 18 | KelpDAO | $292M | LayerZero 1-of-1 DVN, RPC poisoning (Lazarus) |
| Aug 20–25 | Cosmos EVM (MANTRA, TAC, KiiChain) | ~$14.8M | Integer underflow in balance sync |
| Aug 31 | Balancer V1 | $234K | Rounding error in join math |
| Sep 3–4 | Notional Finance V1 | $1.73M | Integer overflow in collateral check |
The Notional Finance Hack: When Integer Overflow Erases Debt
On September 3–4, 2026, an attacker drained Notional Finance's V1 Escrow contract for 1,658,524 USDC and 69,257 DAI — about $1.73 million — then converted the haul to roughly 689.2 ETH and routed it through Tornado Cash. The preparation transaction landed at 23:58 UTC on September 3 (block 25,900,220); the drain followed at 00:01 UTC on September 4 (block 25,900,234).
Notional V1 represents fixed-rate lending positions as fCash, ERC1155 tokens that encode a payer and a receiver leg. The mintfCashPair() function creates both legs in one call but only checks free collateral on the payer side. The attacker exploited that asymmetry with two calls sharing the same payer account: the first with notional = 1, the second with notional = uint128.max (2^128 − 1). Added together, the combined debt equaled exactly 2^128, which in signed integer representation is recorded as −2^128.
The uint128 Downcast Trap
The fatal step happened in Escrow.convertBalancesToETH(), which converts the absolute value of a signed balance to uint128 via a raw cast. In Solidity 0.6.x — the language version Notional V1 was written in — there are no built-in overflow checks. abs(−2^128) equals 2^128, and casting 2^128 to a uint128 silently truncates it to 0. The account now appeared to have zero debt. With the collateral check defeated, the attacker withdrew the real tokens held in escrow.
The cruel irony is that Notional used safe, checked conversion elsewhere in the same file. This one code path — the convertBalancesToETH downcast — was missed. The root cause was not a novel cryptographic breakthrough; it was an integer boundary condition of the kind that has been documented since the earliest EVM exploits. OWASP's 2026 Smart Contract Top 10 classifies it as SC07 — Arithmetic Errors: truncation, scaling, and unit conversion producing exploitable results.
The Balancer V1 Hack: Rounding Errors in Legacy Code
Eight days earlier, on August 31, 2026, an attacker extracted about $234,000 from a Balancer V1 BPool — the original Balancer code first deployed in 2020. Balancer Labs had already shut down V1, but the contracts are immutable: they cannot be patched, only abandoned. The pool held DPI, USDC, WETH, and WBTC.
The root cause was a rounding error in joinswapPoolAmountOut, the function that lets a caller specify a desired amount of BPT (pool tokens) and have the contract reverse-compute the required input. The internal calculation calcSingleInGivenPoolOut uses 18-decimal fixed-point math. WBTC, however, has only 8 decimals. That decimal mismatch becomes lethal when reserves are driven to near-zero.
Reserve Compression and Dust-State Amplification
The attacker used nested flash loans — drawing from Spark, Aave, Morpho, and Uniswap V3 — to compress the pool's WBTC reserves down to dust. With reserves at a handful of satoshis, the reverse-computed required input rounded down to a single satoshi of WBTC. The contract then minted 4,408.8 BPT in exchange for that 1 satoshi. The attacker exited the pool, redeeming those BPT for real token balances — far more value than the dust they put in.
Three safeguards were missing: no minimum effective input, no minimum pool balance enforcement during join operations (the _MIN_BALANCE check only ran during bind/rebind), and no relative-error validation. The same bug family reappeared in Balancer V2 in November 2025: both are down-rounding in fixed-point math that favors the caller over the pool.
This is the "dust state amplifier." Every rounding exploit shares a common precondition: driving the system to an extreme numerical state — near-zero reserves, maximum integer values, or boundary ticks. When reserves equal 10 wei, a 1-wei rounding error is a 10% shift. In a deep pool of 10^20 wei, the same 1-wei error is negligible. The defense is not only to fix the rounding direction but to prevent the system from ever reaching the dust state.
Why Rounding Errors Keep Draining DeFi Pools
Rounding and precision-loss exploits are not new. They have been documented since at least 2021, and they keep appearing for four structural reasons: legacy code is immutable and cannot be patched; forks inherit the bugs of their parents; auditors tend to test normal operating ranges rather than edge cases; and the attack surface grows every time a new protocol composes fixed-point math on top of existing primitives. The result is a "known bug, new victim" cycle that has now spanned three years.
KyberSwap, Cetus, Balancer V2 — The Same Bug Family
- KyberSwap Elastic (November 2023, ~$48M): A precision-loss bug in
computeSwapStep()at tick boundaries.calcReachAmount()computed a swap amount of 1,056,056,735,638,220,800,000; the actual swap quantity was 1,056,056,735,638,220,799,999 — off by a single unit. That 0.00000000001% discrepancy bypassed the_updateLiquidityAndCrossTickcheck, liquidity was not removed, and a second swap double-counted it until the pool drained.
- Cetus Protocol (May 2025, ~$200–223M): An integer overflow in the
checked_shlwfunction ofclmm_math.moveon Sui. The overflow-check constant was wrong by 2^64, so shift-left operations wrapped silently. The attacker deposited 1 unit of a token and received liquidity on the order of 10^37. Move is memory-safe, but shift-left is not automatically guarded — a reminder that "safe language" does not mean "safe arithmetic."
- Balancer V2 Composable Stable Pools (November 2025, ~$116–128M): A rounding-direction error in the
_upscalefunction. It rounded down (mulDown) when it should have rounded up for output amounts. The attacker drained a pool into a low-liquidity state, then ran 65+ micro-swaps; each introduced a tiny accounting mismatch, and batching compounded the precision loss until the BPT price was suppressed and the attacker withdrew more value than they deposited.
The 2026 Notional and Balancer V1 hacks extend this lineage. Notional is an integer overflow that collapsed a massive debt to zero; Balancer V1 is a down-rounding that let a caller pay dust for real tokens. Different mechanisms, same class: arithmetic at the boundary.
The Mathematics of Rounding Error Exploits
To understand why these attacks work, you have to understand how smart contracts do math. The EVM and most blockchain virtual machines support only integer arithmetic — there is no floating point. Division truncates toward zero by default, silently discarding the remainder. To represent fractional quantities, protocols use fixed-point math: multiply by a scaling factor (commonly 1e18), do the arithmetic in integer space, and divide back at the end. Every division step loses a little precision.
That loss is usually harmless. It becomes an attack surface when three conditions align: a precision mismatch (tokens with different decimal places, like WBTC's 8 decimals against 18-decimal internal math), a compressed state (reserves driven to near-zero so that a 1-wei error is a large relative error), and a directional bias (rounding that consistently favors the caller rather than the protocol). When all three hold, repeated operations — 65 micro-swaps, or a single join/exit cycle at the dust state — extract real value.
The Golden Rule of Rounding Direction
The defense at the arithmetic level is a single rule: rounding should always favor the protocol, never the caller. Amounts that flow IN from the user should round UP, so the caller pays slightly more. Amounts that flow OUT to the user should round DOWN, so the caller receives slightly less. Over many operations, this bias accumulates in the protocol's favor and the pool's invariant never decreases from a user action.
Both 2025 Balancer V2 and 2026 Balancer V1 violated this rule: V2 rounded output amounts DOWN (favoring the caller), and V1 rounded the required input DOWN (favoring the caller). Notional's bug is a related but distinct flavor — not a rounding-direction issue per se, but an integer overflow that collapsed a boundary value to zero. It belongs to the same OWASP SC07 family because the exploit mechanism is the same: arithmetic at the edge of the representable range produces a result the developer never intended.
Defending Against Precision Loss Exploits
The fixes are known, documented, and in most cases amount to a few lines of code. The asymmetry between exploit cost and fix cost is staggering: Notional lost $1.73 million from one unchecked cast; Balancer V1 lost $234,000 from missing minimum-balance checks. Both fixes are trivial. The hard part is finding the vulnerable path before the attacker does.
Code-level defenses:
- Pool-favorable rounding. Always round in the direction that protects the protocol. Use libraries that make the direction explicit — OpenZeppelin's
FixedPoint.mulDown/mulUpor PRBMath — so a developer cannot accidentally round the wrong way. - Checked arithmetic. Use Solidity 0.8+ (built-in overflow checks) or OpenZeppelin SafeMath for 0.6.x/0.7.x codebases. Notional V1 ran on 0.6.x, where the truncating cast was silent.
- Minimum balance thresholds. Enforce minimum pool balances during ALL operations, not only during
bind/rebind. Balancer V1's_MIN_BALANCEdid not protectjoin. - Relative-error validation. Check that computed amounts stay within an acceptable tolerance. A required input of 1 satoshi for 4,408 BPT should fail any sane sanity check.
- Invariant enforcement. Runtime checks that the pool's value invariant never decreases from a single user operation catch the compounded-drain case.
Testing defenses:
- Invariant testing. Define mathematical invariants — "pool value never decreases from one swap" — and fuzz-test them with tools like Foundry's invariant tests or Recon.
- Stateful fuzzing with edge cases. Test with
MAX_UINT256, zero, 1 wei, and dust amounts — not just normal ranges. The bugs live at the boundaries. - Adversarial token mocks. Use tokens with hooks, non-standard decimals, and rebasing behavior in the test harness to catch decimal-mismatch bugs.
- Formal verification. Certora and similar tools can mathematically prove rounding-direction properties, eliminating the entire class rather than patching one instance.
Operational defenses:
- Deprecate legacy code. Balancer V1 was deployed in 2020 and unmaintained. Immutable contracts cannot be patched — the only remedy is to migrate liquidity away and shut the pool down.
- Monitor for reserve compression. Alert when pool reserves drop below safety thresholds; the dust state is the precondition for every rounding exploit.
- Circuit breakers. Pause pools when anomalous swap patterns are detected. Cetus validators froze $162 million on Sui mid-attack; fast action limits the blast radius.
- Multi-verifier bridge configs. KelpDAO's 1-of-1 DVN was a single point of failure — a reminder that infrastructure design matters as much as contract math.
The Fork Time Bomb
One systemic risk deserves emphasis. Balancer V1's join/exit math has been forked across DeFi. Those contracts are immutable. Every fork that preserved the down-rounding behavior and the missing minimum-balance check is a ticking bomb, waiting for someone to compress reserves and trigger the same extraction. This is not a hypothetical: the 2025 Balancer V2 incident and the 2026 Balancer V1 incident are the same bug in two generations of the same codebase. The defense for forks is not to patch — it cannot be — but to deprecate, migrate liquidity, and warn any protocol still running the inherited math.
FAQ
What is a rounding error exploit in DeFi? A rounding error exploit abuses the fact that blockchain virtual machines use integer arithmetic and division truncates toward zero. When a protocol's fixed-point math rounds in a direction that favors the caller — and the system is driven to an extreme state like near-zero reserves — an attacker can extract real value by repeating the rounding-favorable operation. The 2026 Balancer V1 hack is a textbook example.
How did the Notional Finance hack work? The attacker called mintfCashPair() twice with the same payer — once with notional = 1 and once with notional = uint128.max. The combined debt of 2^128 was stored as −2^128 in signed form. When convertBalancesToETH() cast abs(−2^128) to uint128, the value truncated to zero in Solidity 0.6.x (which has no overflow checks). The account appeared debt-free and the attacker withdrew real tokens.
Why do rounding errors keep happening in DeFi? Four reasons: legacy immutable code cannot be patched; forks inherit their parents' bugs; audits test normal ranges rather than dust/MAX_UINT edge cases; and the attack surface grows as more protocols compose fixed-point math. The result is a recurring "known bug, new victim" cycle visible from KyberSwap (2023) through Cetus and Balancer V2 (2025) to Notional and Balancer V1 (2026).
What is the golden rule of rounding direction? Rounding should always favor the protocol, never the caller. Amounts flowing IN from the user round UP (caller pays more); amounts flowing OUT to the user round DOWN (caller receives less). Violations — like Balancer V2's _upscale rounding output down, or Balancer V1's join math rounding input down — let value leak from the pool to the caller.
How can protocols prevent precision loss exploits? Use pool-favorable rounding libraries, checked arithmetic (Solidity 0.8+ or SafeMath), minimum balance thresholds enforced during all operations, relative-error validation, and runtime invariant checks. Test with edge cases (zero, 1 wei, MAX_UINT) via invariant fuzzing, and use formal verification to prove rounding-direction properties. Operationally, deprecate legacy immutable code and monitor for reserve compression.
Were the 2026 Notional and Balancer V1 hacks related? They are distinct incidents — different protocols, different exact mechanisms — but they belong to the same OWASP SC07 (Arithmetic Errors) family. Both exploited arithmetic at the boundary of the representable range: Notional via an integer overflow that collapsed debt to zero, Balancer V1 via a down-rounding that let a caller pay dust for real tokens. Together they show that precision loss remains a persistent DeFi attack vector even as infrastructure attacks dominate the headlines.
Conclusion
The defi hacks 2026 YTD record tells two stories. The loud one is infrastructure compromise: $577 million stolen by Lazarus through key theft and bridge misconfiguration, a vector that for the first time outpaced smart-contract bugs. The quiet one is arithmetic. Notional's $1.73 million and Balancer V1's $234,000 are small next to Drift and KelpDAO, but they are entirely preventable with techniques documented years ago — pool-favorable rounding, checked arithmetic, minimum-balance enforcement, invariant testing at the boundaries. The cost asymmetry is brutal: a few lines of code versus millions of dollars. Until the ecosystem stops leaving immutable legacy math running and stops testing only the happy path, rounding errors will keep striking again.
