Solidity Overflow Safety
Solidity overflow safety is the built-in checking that stops a number from growing past the largest value its type can hold. Solidity has checked arithmetic by default since version 0.8.
A uint8 at 255 refuses one more
The counter starts at 255, the largest uint8 value. Adding 1 reverts, and the stored value stays 255.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
contract TinyCounter {
uint8 public count = 255;
function addOne() public {
count = count + 1;
}
}Division by zero reverts too
Checked arithmetic also covers division. A normal division works, and dividing by zero reverts.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
contract Divider {
function divide(uint256 total, uint256 parts) public pure returns (uint256) {
return total / parts;
}
}unchecked wraps to 0 on purpose
An unchecked block turns the checks off for the code inside it. The same counter now wraps from 255 to 0 instead of reverting.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
contract WrappingCounter {
uint8 public count = 255;
function addOneUnchecked() public {
unchecked {
count = count + 1;
}
}
}Example
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
contract SafeCounter {
uint8 public count = 255;
function addOne() public {
count = count + 1;
}
function addOneUnchecked() public {
unchecked {
count = count + 1;
}
}
function share(uint256 total, uint256 people) public pure returns (uint256) {
return total / people;
}
}Key points
- Checked arithmetic: Solidity stops a result that does not fit in its type.
- Panic: a failed safety check stops the call, and nothing changes.
- uint8 limit: a uint8 holds whole numbers from 0 to 255 only.
- Division by zero: dividing by zero fails the check and reverts.
- unchecked block: code inside unchecked { } skips the overflow and underflow checks.
- Wrapping: without a check, a uint8 at 255 plus 1 wraps around to 0.
In this example, the counter starts at 255, the largest uint8 value. The addOne function uses normal checked arithmetic, so adding 1 reverts and the count stays 255. The addOneUnchecked function puts the same addition inside unchecked { }, so the count wraps to 0. The share function divides one number by another, and dividing by zero reverts.
Note
use unchecked only in code that has already proven the result stays in range.
Try it Yourself
Edit the code, then press Run.
Running is simulated · Remix IDE
Exercise
A uint8 variable holds 255. What happens when normal Solidity 0.8 code adds 1 to it?