function nice(uint8 x) public returns(uint8 z) {
uint8 z = 0;
z = z + 240;
require(z = z + x, "overflow");
}
I have been using this code with Solidity prior to the 0.8 update. If there was an overflow, the transaction would get reverted with the message overflow
.
Now, I am moving to 0.8. If I use the same code, my test cases fail, because they don't get overfow
revert message anymore. If I remove require
and just leave z = z + x
as the compiler suggests, I have no idea with what message it will get reverted with. What I want to achieve is to use 0.8 and still get overflow
revert message.
NOTE I don't want to use unchecked
.
Best Answer
Bit of Explanation
First you should familiarize yourself with the concept of "unchecked arithmetic", which is part of the v0.8 breaking changes list:
Importantly, overflows and underflows use the REVERT opcode instead of the INVALID opcode:
If you're a user of Hardhat, you will get the following JavaScript/ TypeScript error in the terminal while testing your contract:
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.Suggestion
Why use revert reasons when you can now define custom errors?
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.