Overflow and Underflow are arithmetic errors that occur when a calculation results in a number that is outside the fixed range of the variable's data type.
1. Explanation
| Term | What happens | Example (uint8: range 0–255) |
|---|---|---|
| Overflow | You exceed the maximum value and the number "wraps" to the bottom. | 255 + 1 --> 0 |
| Underflow | You go below the minimum value and the number "jumps" to the top. | 0 - 1 --> 255 |
2. Solidity 0.8.0
Before version 0.8.0, Solidity did not check for these errors. You had to use a library called SafeMath to prevent them.
Since 0.8.0: The compiler includes built-in checks. If an overflow or underflow occurs, the transaction reverts (fails) automatically with a "Panic" error.
The unchecked Block: Sometimes, you know a calculation is safe and you want to save gas by skipping the check. You can wrap that code in an unchecked block:
// This will NOT revert; it will wrap around to 0
unchecked {
uint8 x = 255;
x++;
}
3. Prevention
Use Solidity >= 0.8.0: This is the easiest and most important step.
Typecasting Caution: Even in 0.8.0, casting a large type to a small type (e.g., uint256 to uint8) can still cause "silent" wrapping without a revert. Always check the range before casting.
Use uint256: Unless you have a specific reason (like fitting data into a single storage slot/32 bytes), stick to uint256. It has such a massive range (2^256 - 1) that it is practically impossible to overflow in most financial applications.
Top comments (3)
which case we use unchecked block ?
can you give an example case ?
Maybe the given example is not very relevant.
Imagine calculating the sum of the elements in an array with a for loop where i starts at 0 and increments by 1 each iteration. A loop condition i < data.length makes sure i will never overflow. So i won't reach type(uint256).max.
This will save gas every iteration.