Bit of Explanation
First you should familiarize yourself with the concept of "unchecked arithmetic", which is part of the v0.8 breaking changes list:
Arithmetic operations revert on underflow and overflow. You can use unchecked { ... } to use the previous wrapping behavior.
Importantly, overflows and underflows use the REVERT opcode instead of the INVALID opcode:
Failing assertions and other internal checks like division by zero or arithmetic overflow do not use the invalid opcode but instead the revert opcode.
If you're a user of Hardhat, you will get the following JavaScript/ TypeScript error in the terminal while testing your contract:
Error: VM Exception while processing transaction: reverted with panic code 0x11 (Arithmetic operation underflowed or overflowed outside of an unchecked block)
It looks like Solidity chose the hexadecimal number 0x11 to be the panic code associated with arithmetic overflows and underflows.
Code Updated
Unfortunately there is no way to achieve what you want without wrapping your code in an unchecked
block.
First you do that, and then you do what SafeMath does: check that the sum is greater than x
; if it isn't, the operation has overflown max uint8.
function nice(uint8 x) public returns(uint8 z){
uint8 z = 0;
z = z + 240;
unchecked {
z = z + x;
require(z >= x, "Your custom message here");
}
}
Suggestion
Why use revert reasons when you can now define custom errors?
error Overflow(uint8 z, uint8 x);
function nice(uint8 x) public returns(uint8 z){
uint8 z = 0;
z = z + 240;
unchecked {
z = z + x;
if (z < x) {
revert Overflow(x, z);
}
}
}
Imo this is a godsend for Solidity development. Compared to revert reason strings, custom errors are easier to work with, more gas efficient, and more elegant.