Division by Zero
Detects division and modulo operations where the divisor may be zero, causing transaction reverts that lock funds or enable denial of service.
Division by Zero
Overview
The division by zero detector identifies DIV, SDIV, MOD, and SMOD operations where the divisor operand may be zero at runtime. In the EVM, division by zero returns zero (it does not revert), but Solidity wraps division in a check that reverts on zero divisors. A revert in a critical function (such as a withdrawal or liquidation) can lock funds permanently or enable denial-of-service attacks.
Sigvex traces the divisor operand backward through the data-flow graph to determine whether it could be zero — from user input, from a storage variable that starts at zero, or from an external call return that might be zero.
Why This Is an Issue
Division by zero in price calculations, share-to-asset conversions, or fee computations causes the transaction to revert. If the divisor is a pool’s total supply (which is zero when the pool is empty), a withdrawal function that divides by total supply will revert, locking the first depositor’s funds. If the divisor comes from an oracle that returns zero during downtime, all dependent operations halt.
How to Resolve
// Before: Vulnerable — totalSupply may be zero
function sharePrice() public view returns (uint256) {
return totalAssets() / totalSupply(); // Reverts if totalSupply == 0
}
// After: Fixed — handle zero case
function sharePrice() public view returns (uint256) {
uint256 supply = totalSupply();
if (supply == 0) return 1e18; // Default 1:1 price when pool is empty
return (totalAssets() * 1e18) / supply;
}
Detection Methodology
- Division instruction identification: Locates
DIV,SDIV,MOD,SMODopcodes. - Divisor origin analysis: Traces the divisor operand to determine if it can be zero — from
CALLDATALOAD, uninitialized storage, external call return, or subtraction result. - Guard check detection: Looks for zero-comparison checks (
ISZERO+JUMPIfor revert) on the divisor before the division. - Confidence scoring: Divisors from external calls or user input without guards receive highest confidence; divisors from storage with known initialization receive lower confidence.
Limitations
False positives: Divisors that are guaranteed non-zero through business logic (e.g., a total supply that can only increase) may be flagged. False negatives: Complex guard patterns (e.g., require(x > 0) where x is used indirectly as a divisor) may not be connected.
Related Detectors
- Precision Errors — detects rounding and precision issues in arithmetic
- Integer Overflow — detects overflow in arithmetic operations
- DOS — detects denial of service vectors