Solidity 0.8.0 added built-in, by default, reverts when there is an overflow or underflow in an operation on integers.
I prefer the explicitness of SafeMath, or my own require statements. Over/underflow reverts by default are not a solve-all for the problem. In some cases revert on over/underflow is the wrong action, for example when it locks funds in a contract forever.
I don't want to use unchecked. I want to use SafeMath (or equivalent or better library) or my own require statements. This helps ensure that I look and think about each possible over/underflow case and not shotgun use the default functionality and assume it is the right thing to do in every case.
In addition, @wjmelements pointed out it is nice to be able to emit a user-friendly message via require specifying what exactly was under/overflowing.
gas
The majority of Solidity for loops increment a uint256 variable that starts at 0. These increment operations never need to be checked for over/underflow because the variable will never reach the max number of uint256 (will run out of gas long before that happens). The default over/underflow check wastes gas in every iteration of virtually every for loop I would ever write. It can be done unchecked in this awkward way:
for(uint256 i; i < 10;) {
// loop logic
unchecked { i++; }
}
Or possibly an inlined function can be used:
function inc(i) internal pure returns (uint256) {
unchecked { return i + 1; }
}
for(uint256 i; i < 10; i = inc(i)) {
// loop logic
}
But I would prefer to write my unchecked for loops (which are all of them) in the usual way like this:
for(uint256 i; i < 10; i++;) {
// loop logic
}
Things possibly could be done to improve the syntax of unchecked for loops. That's great. But I would just prefer to do without default over/underflow reverts, so I handle each possible over/underflow individually, explicitly and correctly.
Solidity 0.8.0 added built-in, by default, reverts when there is an overflow or underflow in an operation on integers.
I prefer the explicitness of SafeMath, or my own require statements. Over/underflow reverts by default are not a solve-all for the problem. In some cases revert on over/underflow is the wrong action, for example when it locks funds in a contract forever.
I don't want to use
unchecked. I want to use SafeMath (or equivalent or better library) or my own require statements. This helps ensure that I look and think about each possible over/underflow case and not shotgun use the default functionality and assume it is the right thing to do in every case.In addition, @wjmelements pointed out it is nice to be able to emit a user-friendly message via require specifying what exactly was under/overflowing.
gas
The majority of Solidity for loops increment a uint256 variable that starts at 0. These increment operations never need to be checked for over/underflow because the variable will never reach the max number of uint256 (will run out of gas long before that happens). The default over/underflow check wastes gas in every iteration of virtually every for loop I would ever write. It can be done unchecked in this awkward way:
Or possibly an inlined function can be used:
But I would prefer to write my unchecked for loops (which are all of them) in the usual way like this:
Things possibly could be done to improve the syntax of unchecked for loops. That's great. But I would just prefer to do without default over/underflow reverts, so I handle each possible over/underflow individually, explicitly and correctly.