
On November 3, 2025, at 7:46 AM UTC, the Balancer V2 protocol suffered one of the most sophisticated exploits in DeFi history. A subtle rounding inconsistency in Composable Stable Pools enabled attackers to drain approximately $121.1M across Ethereum, Arbitrum, Base, Optimism, and Polygon.
This wasn't a brute force attack. It was precision engineering, exploiting the mathematical underbelly of DeFi through carefully calibrated micro-swaps that eroded pool invariants without triggering alarms. Thanks to rapid response from security partners, whitehat rescuers, and emergency interventions, approximately $45.7M was protected or recovered. The losses could have been prevented with proactive security measures that detect precision vulnerabilities before deployment.
The exploit weaponized a two-stage attack pattern. First, manipulate the pool state. Second, withdraw clean. All executed via batchSwap for atomicity, bypassing single-swap guards.
The attacker didn't just attack blindly. They gathered comprehensive pool state data: token scaling factors, amplification parameters, fees, BPT rates, and current balances. Then they deployed a simulation contract and repeatedly called a helper function 0x524c9e20, passing arrays of balances, scaling factors, token indices, desired output amounts, amplification, and fees.
Using large iteration counts (approximately 100 billion iterations across 25 refinement loops), the attacker identified specific swap amounts that would land tokens on wei-level rounding cliffs. These are the precise edges where rounding errors compound.
Once calibrated, the attacker executed the sequence on-chain through atomic batchSwap transactions:
The attacker repeated this technique across multiple pools and chains: Arbitrum, Polygon, Base, Sonic, and Optimism, compounding the drain wherever pauses or protections were absent.
After accumulating underpriced BPT in their internal balance, the attacker later redeemed through managerUserBalance to EOA 0xaa760d53541d8390074c61defeaba314675b8e3f.
At the heart of the exploit was a rounding direction mismatch in Composable Stable Pools' scaling logic. The protocol used mulDown for upscaling but divUp/divDown for downscaling. This asymmetry meant the EXACT_OUT path (_swapGivenOut) could understate the required amountIn.
In the _swapGivenOut function, the amountOut was adjusted for token decimals and rate, then rounded down by _upscale before being passed into the calculation. While outputs are typically rounded down, StableMath's mechanics caused the amountIn to also be rounded down, producing an amountIn that was too low and allowing the caller to underpay for the given amountOut.
Repeating carefully tuned micro-swaps inside a single batchSwap() compounded tiny wei-level truncations, quietly reducing the invariant D and thus the BPT price (≈ D / totalSupply) without triggering reverts or sanity checks.
The exploit required three preconditions: the underlying rounding error in exact out swaps, rate providers to introduce imprecision in the math, and a low liquidity state required to magnify the imprecision enough to be exploitable. Only Composable Stable Pools satisfied all three conditions, and only if they actually incorporated BPT and rate providers.
Despite the severity, the response demonstrated the value of layered security:
07:46 UTC — First malicious transactions detected simultaneously across five chains
07:46 UTC — Bitfinding successfully front-ran the attacker on Ethereum Mainnet, recovering approximately $964k
07:52 UTC — Hypernative's monitoring systems flagged suspicious activity and established emergency communication
08:07 UTC — V6 Composable Stable Pool implementations paused across affected networks, protecting $19.3M in liquidity
08:14 UTC — SEAL 911 proactively contacted Balancer, having independently flagged attacker wallets
09:50 UTC — First public disclosure made via official channels
11:01 UTC — Recovery Mode activated on affected pools, enabling users to safely withdraw remaining funds
Through coordinated response efforts, approximately $45.7M in user funds were protected or recovered:
Following the exploit, Olympix ran a comprehensive analysis of the Balancer Composable Stable Pool contracts using BugPoCer, our automated vulnerability detection system. The results identified the exact vulnerability pattern that enabled the $121M exploit.
Unit Name: BaseGeneralPool / BasePool
Locations: ScalingHelpers.sol: _upscale(), BaseGeneralPool.sol: _swapGivenIn()
Description: The pool normalizes token amounts via _upscale(amount, scalingFactor), which uses FixedPoint.mulDown and therefore always rounds down. This is normally safe when the scaling factor represents only decimal normalization (10^(18−decimals)), because the truncation is economically negligible.
However, in this implementation, _scalingFactors() is overridden to include non-unitary, potentially dynamic token rates. Embedding token exchange rates inside the scaling factor amplifies rounding effects and creates a systematically biased truncation during _upscale().
The calculation works as follows:
_upscale(amount, scalingFactor) = floor(amount * scalingFactor / 1e18)
When scalingFactor includes a non-integer rate (e.g., a yield-accruing or rebasable token), small amount values or low-liquidity balance conditions can cause the floor operation to produce material percentage differences, not just ≤1 wei dust.
Exploitation Mechanism: This becomes exploitable when combined with multi-step swap paths (GIVEN_IN + GIVEN_OUT), repeated scaling and descaling, and the attacker's ability to position the pool into extremely skewed balance configurations.
The attacker leveraged exactly this vulnerability by:
This is the precise mechanism that enabled the invariant degradation attack. The systematic downward bias in _upscale() when combined with rate-augmented scaling factors created the rounding cliff that the attacker exploited.
The Olympix finding demonstrates that automated precision analysis could have identified the vulnerability pattern before deployment.
BugPoCer's precision analysis specifically flagged the biased rounding in rate-augmented scaling factors. This type of vulnerability is extremely difficult to catch in traditional audits because:
Automated analysis can systematically detect these patterns by analyzing:
With this finding, developers could have:
The core issue was embedding dynamic, non-unitary rates inside the scaling factor while maintaining a consistent downward rounding bias. The fix would have been straightforward:
// Instead of: _upscale(amount, scalingFactor_with_rate)
// Which always rounds down via mulDown
// Use: Apply rate separately with compensating bias
scaled = _upscaleDecimals(amount, decimalScalingFactor); // normalize decimals
rateAdjusted = _applyRate(scaled, rate, ROUND_UP); // apply rate, round up to favor pool
This separates concerns and ensures that rate application doesn't inherit the downward bias appropriate only for decimal normalization.
This exploit reveals the limits of traditional security approaches.
Audits Are Snapshots: The vulnerable code had been audited by multiple top-tier firms. But audits are point-in-time reviews. As new attack vectors emerge and complexity increases, code that was "secure enough" can become exploitable.
Rounding Appears Safe in Isolation: In manual review, seeing mulDown for upscaling appears correct. Downward rounding is typically the safe direction for calculating amounts owed by users. The vulnerability only emerges when you understand that rate-augmented scaling factors change this assumption.
Requires Cross-Component Analysis: The vulnerability required understanding how _upscale(), _scalingFactors(), rate providers, and swap paths interact across multiple transactions. Manual reviewers would need to trace through:
This level of cross-component, stateful analysis is precisely what automated tools excel at.
Testing Can't Catch Everything: Even comprehensive test suites struggle with precision bugs because they require adversarial calibration. The attacker performed exactly this kind of simulation with 100 billion iterations to find the rounding cliff. Standard test suites don't include this level of adversarial edge-case exploration.
The Balancer exploit proves that security in DeFi now means defending against economic engineering, not just coding bugs. A single wei-level rounding inconsistency cascaded into a $121M loss because:
Balancer V3 was completely unaffected by this attack. While V3 was designed before this specific vulnerability was discovered, its architectural principles proved effective:
The incident validates the value of building protocols with security-first architectural principles, even when specific attack vectors aren't yet known.
The Balancer exploit demonstrates a harsh reality: you can't audit your way to safety in DeFi. The industry needs to move from reactive security (audit and pray) to proactive security (continuous verification).
Protocols need to:
Our approach combines:
The Balancer V2 exploit shows how far DeFi security has to go. A tiny rounding bias, the kind that appears safe in isolation and passes multiple audits, cascaded into a $121M loss when combined with rate providers and low-liquidity conditions.
Olympix's post-incident analysis identified the exact vulnerability: biased rounding in rate-augmented scaling factors that enabled systematic precision loss exploitation. This finding demonstrates that automated security analysis can detect the subtle, multi-component vulnerability patterns that lead to real-world exploits.
Traditional audits focus on obvious bugs and known attack patterns. But the next major exploit won't look like the last one. It will be a novel combination of seemingly safe operations that interact in unexpected ways. Automated analysis can find these patterns by systematically exploring how components interact under adversarial conditions.
Mathematical vulnerabilities exist in production code right now. The only question is whether protocols will find them before attackers do.
Don't let mathematical vulnerabilities drain your TVL. Olympix's automated security analysis catches precision bugs, biased rounding, and rate amplification vulnerabilities before deployment.
[Request a Security Analysis]
Attacker Addresses for Reference:
Relevant Transaction Hashes: