Since Solidity 0.8.0, arithmetic reverts on overflow and underflow by default, so most of the old SafeMath era bugs no longer happen in new code. Two exceptions remain: unchecked blocks restore wrapping on purpose, and contracts compiled with older versions still need explicit checks.
The old behavior
Before 0.8.0, a uint that went past its maximum wrapped around to zero, and one that went below zero wrapped to a huge number. The Solidity documentation notes that this led to widespread use of safe math libraries. If a developer forgot to use one on a single line, the bug was there.
The new default
The Solidity control structures page states that arithmetic operations revert on over and underflow by default. The Ethereum security guide agrees: version 0.8.0 and later reject overflowing and underflowing arithmetic, while older versions need checks or SafeMath.
The same guide shows a time lock example where an overflow is used to bypass the lock period. That kind of bug is what the default now prevents.
Where overflow can still happen
- Unchecked blocks. Wrapping a statement in an unchecked block turns checking off. The documentation says it applies only to statements written directly inside the block, not to functions the block calls.
- Bitwise shifts, which never perform overflow checks.
- Explicit type conversions, which truncate rather than fail, with the exception of integer to enum conversions.
- Any contract still compiled with a version before 0.8.0.
Reverts have a cost too
A revert on overflow is safer than silent wrapping, but it can leave a contract stuck if a state value can be pushed to the limit. The Solidity security page advises bounding inputs with require and mentions the SMT checker as a further aid.
A short checklist
- Check the compiler version in every contract, including dependencies.
- Search for unchecked blocks and ask why each one exists. Gas savings alone is a thin reason on a contract that holds funds.
- Review casts from larger to smaller integer types.
- Bound user supplied amounts with require.
- Add tests at the boundary values, zero and the maximum.
Quick check
Do I still need SafeMath on 0.8 and later?
Not for ordinary arithmetic, because checking is the default. You may still see it in older code or in code that targets older compilers.
Is a revert on overflow always a good outcome?
It is better than wrapping, but it can lock a function if inputs are not bounded. Design so that normal use cannot reach the limit.
Sources
- Control structures, Solidity documentation
- Smart contract security, ethereum.org
- Security considerations, Solidity documentation
Last reviewed: 19 October 2026.