Full Report
Poor rounding in DeFi has been the catalyst of many, many bugs in Web3, even on major projects. The consequences of truncations and rounding down can seem insignificant but can be horrible consequences. This post dives into how this happens and a systematic approach for discovering rounding issues. The EVM doesn't have floats; everything is an integer. So, 5/2 is not 2.5 but 2. To combat this, fixed-point arithmetic is used, which most folks know as decimal arithmetic. Now, 5 is no longer 5 but 5^18. Now, when you divide by 2 it's 2.5^18 which keeps most the precision. Some libraries also provide functionality for rounding up or down depending on the situation. They provide an example of the following formula: balanceOut * (1 - balanceIn / (balanceIn + tokenIn)) from Balancer. if balanceIn is 0, then this can become balanceOut * (1-0). balanceOut is the only value leftover. This can happen by combining a flash mint with a pool unbalanced. This truncation allows the attacker to steal all funds from the protocol. The fix is rounding up instead of down. It's commonly said to round in the favor of the protocol. In particular, if going to the users' round down and if going to the protocol round up. In reality, this doesn't work. First, there's a complexity problem. With HUGE formulas, the rounding depends on the runtime values, making this not a simple task. Second, code is commonly reused. Sometimes, it'll require rounding down and others up. Third, errors can be bad as well. For instance, making a liquidation unliquidatable would be a major problem. The author includes several tips for fixing this. First, every rounding issue is a bug. Instead of spending hours writing an exploit path, it just needs to be fixed on the spot. Some bugs are vulnerabilities, some are exploitable, but they are ALL bugs. The second consideration is around design. One thought is to redesign or simplify formulas, or to add protocol invariants. Next, precision loss can cancel each other out. By rewriting formulas with multiple steps, math errors can cancel each other out. All of these decisions must be explicitly documented. Overall, a good post on rounding vulnerabilities and how to think about them going forward.
Analysis Summary
# Vulnerability: Integer Truncation/Rounding Down in DeFi Arithmetic leading to Fund Theft
## CVE Details
- CVE ID: Not specified in the text (General vulnerability class, not a specific CVE)
- CVSS Score: Not specified (High severity implied by implication of fund theft)
- CWE: CWE-785 (Use of a Resource in a Way That Violates the Intended Resource Model) or related arithmetic errors.
## Affected Systems
- Products: DeFi Protocols utilizing fixed-point arithmetic based on EVM integer division (e.g., Balancer V2, mentioned in context of similar bugs in Bunny, Yield V2, Solana Program Library).
- Versions: Not specified; affects any implementation where division truncation (rounding down) occurs in critical financial formulas.
- Configurations: Any configuration where a calculation results in an intermediate ratio dividing to zero due to truncation, especially when combined with flash loans to unbalance reserves.
## Vulnerability Description
The core issue stems from the structure of the Ethereum Virtual Machine (EVM), which performs all arithmetic using integers, meaning division truncates results (e.g., $5/2 = 2$, not $2.5$). DeFi mitigates this with fixed-point arithmetic (scaling values, often by $10^{18}$).
When precision is lost during division, libraries allow rounding up or down. A specific vulnerability arises when a critical calculation, such as determining the amount of tokens received in a swap: `tokenOut = balanceOut * (1 - balanceIn / (balanceIn + tokenIn))`, uses truncation (rounding down). If the ratio $\frac{\text{balanceIn}}{\text{balanceIn} + \text{tokenIn}}$ rounds down to $0$, the formula simplifies to $\text{tokenOut} = \text{balanceOut} \times (1-0) = \text{balanceOut}$. This results in the attacker draining the entire balance of the output token from the protocol.
## Exploitation
- Status: The text describes a confirmed attack scenario (Balancer 2021 audit example) achievable via flash loans.
- Complexity: Medium (Requires understanding of flash loans and exploiting precise rounding edge cases).
- Attack Vector: Network
## Impact
- Confidentiality: None stated.
- Integrity: **Severe**. Allows unauthorized draining of protocol funds.
- Availability: Moderate. Can empty liquidity pools, impacting service availability.
## Remediation
### Patches
The fundamental fix involves changing the rounding direction at the point of vulnerability:
1. **Critical Fix:** For calculations where rounding down leads to fund loss (like the Balancer swap formula), the ratio calculation must be forced to **round up** instead of down. This ensures the calculated ratio is never exactly zero unless mathematically warranted, preventing the full balance drain.
2. **General Principle:** Decisions about rounding must be explicit: round down when calculating amounts paid *out* to users, and round up when calculating amounts paid *in* by users (though this rule is insufficient on its own).
### Workarounds
1. **Formula Simplification/Redesign:** Rethink and simplify complex formulas to avoid runtime dependency on rounding direction when possible.
2. **Precision Loss Cancellation:** Re-write formulas using algebraic rearrangement to encourage mathematical errors from multiple steps to offset each other, leading to a more accurate final result.
3. **Documentation:** Explicitly document the required rounding direction for **every** mathematical step in complex formulas.
4. **Trapping Path Handling:** For operations like liquidations where rounding up could lead to an invalid state (e.g., seizing more collateral than available), implement explicit caps or fallbacks.
## Detection
- **Audit Focus:** Auditors must treat *every* rounding discrepancy as a bug, even if it appears exploitable only in theory.
- **Testing:** Intensive unit testing of edge cases, especially near zero balances and high ratios.
- **Advanced Tools:** Utilize fuzzing (Foundry, Echidna, Medusa) and formal verification (Certora, Halmos, K framework) to stress-test arithmetic properties against all inputs.
- **Code Review:** Scrutinize reusable math components for ambiguous rounding specifications (use explicit naming like `mulDown` or specifying the rounding mode).
## References
- Vendor Advisories: Audit review referenced: hxxps://github.com/trailofbits/publications/blob/master/reviews/2021-04-balancer-balancerv2-securityreview.pdf
- Presentation supporting attack path: hxxps://github.com/montyly/publications/blob/main/industrial/presentations/2025/wondercon/2025-11-16\_rounding/pdf