SC07:2026 - 算術エラー (Arithmetic Errors)
説明
Arithmetic errors (rounding and precision loss) describe any situation where a smart contract performs integer-based calculations that produce incorrect or exploitable results due to truncation, scaling, or unit conversion. Smart contracts are limited to integer arithmetic; any division, fixed-point scaling, or conversion between units can lose precision, introduce asymmetric rounding, or—when combined with unchecked blocks or non-EVM semantics—cause overflow/underflow (see SC09).
This affects all contract types that compute numeric values: DeFi (share minting/burning, LP tokens, interest accrual, swap outputs, AMM invariant updates), yield vaults and ERC-4626 (asset/share conversions), rebasing tokens, reward distribution, and NFT/token economics. On non-EVM chains (e.g., Move, Rust-based), integer semantics and available precision differ; similar risks apply wherever arithmetic drives economic outcomes.
Few areas to focus on:
Share and LP token calculations (deposit/withdraw formulas, rounding direction)
Interest and reward accrual (compounding, time-weighted averages)
Swap and AMM math (constant product, concentrated liquidity, output calculations)
Fixed-point and scaling (1e18, 1e8 conventions, cross-token conversions)
Rebasing and proportional distribution (per-user vs. global accounting)
Attackers exploit:
Rounding bias (e.g., rounding that favors depositor or protocol under adversarial sequences)
Repeated small gains via flash loans (SC04) or high-frequency interactions
Edge cases (zero total supply, first depositor, extreme ratios) where formulas break down
Precision loss in multi-step computations that accumulates across operations
When combined with flash loans (SC04) or business logic flaws (SC02), arithmetic errors can be amplified into protocol-draining exploits.
事例 (脆弱な株価計算)
Issues:
Rounding always truncates; under adversarial sequences of deposits/withdrawals, this can be gamed.
No invariant tests to ensure that total share value remains consistent across edge cases.
事例 (より堅牢な算術演算と不変条件設計)
Security Improvements:
Explicitly handles initial states and avoids division by zero.
Uses a clearly documented rounding strategy (
round upin this example).Adds overflow checks and custom errors for clarity.
Real-world protocols should pair such logic with formal reasoning and invariants (e.g., through formal verification or property-based tests).
2025 ケーススタディ
zkLend (February 2025, $9.5M loss) A rounding error in the
mint()function—integer division rounding down—caused a mismatch between recorded and actual values. A withdrawal that should have burned 1.5 tokens rounded down to 1.0, allowing attackers to artificially inflate the lending_accumulator via repeated deposits/withdrawals and drain ~$9.5M.Bunni (September 2025, $8.4M loss) Precision bugs in the withdrawal function's rounding logic. Developers assumed rounding down the idle balance would be "safe," but repeated operations created an exploitable loophole—the attacker decreased USDC balance by 85.7% while only burning 84.4% of liquidity, enabling disproportionate value extraction.
ベストプラクティスと緩和策
Use safe math patterns (Solidity 0.8+ has built-in checks, but logic around them still matters).
Clearly document and test your rounding strategy:
Decide whether rounding should favor the protocol or users.
Prove that repeated interactions cannot create “free value”.
Rely on well-reviewed math libraries for complex operations:
Fixed-point math (e.g., 1e18 scaling)
High-precision exponentiation or logarithms
Incorporate invariant checks:
E.g.,
totalAssetsvs. sum of user balances, or share/value consistency after operations.
Use fuzz testing and differential testing to discover edge cases around small/large values and repeated operations.
Last updated