Division by Zero Remediation
Overview
Related Detector: Division by Zero
In Solidity, dividing by zero reverts. That turns any divisor an attacker or an edge case can drive to zero into a denial-of-service: a pool with zero total supply, a rate with zero denominator, a first-depositor share calculation. In inline assembly the same operation silently yields zero instead of reverting, which corrupts downstream math. The remediation is to check the divisor before every division that can reach zero.
Recommended Fix
Before (Vulnerable)
// If totalShares is 0 (e.g. before the first deposit), this reverts and
// blocks the function entirely.
function pricePerShare(uint256 totalAssets, uint256 totalShares)
external pure returns (uint256)
{
return totalAssets / totalShares;
}
After (Fixed — explicit guard and defined edge case)
error NoShares();
function pricePerShare(uint256 totalAssets, uint256 totalShares)
external pure returns (uint256)
{
if (totalShares == 0) return 0; // defined answer for the empty pool
return totalAssets / totalShares;
}
Choose the edge-case behaviour deliberately: return a sentinel (as above), revert with a clear error, or use a virtual-share offset so the denominator is never zero.
Common Mistakes
- Guarding a division in Solidity but performing an unguarded
divin anassemblyblock, where the result is0rather than a revert. - Assuming a denominator “can never be zero” without tracing every state transition that sets it (unpausing, full withdrawals, migrations).
- Reverting on the empty-pool case when the caller (e.g. a UI price read) would be better served by a defined zero.