Overflow, Underflow, Division by Zero
Solidity has built-in overflow/underflow checks. An overflow occurs when an operation attempts to create a number with more digits than the data type can handle. Typically, the least significant bits get stored, which causes the stored number to start from 0.
Let’s try this with a variable of one byte. One byte consists of eight bits. It can store values from 0 to 255.
If we calculate 255 + 1, we would expect 256.
Now, let’s have a look at the binary representations. The least significant bit is in on the right side.
Index | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
0 | – | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
255 | – | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
256 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
0 and 255 fit into the storage size of eight bits. But 256 needs more space than is available. It requires the bit with index 8. Usually, this bit is dropped, and only the fitting least significant bits [00000000] are stored.
Solidity takes care of that since v0.8. If an overflow or underflow occurs, the transaction will revert.
Try out the following example. We declared a variable of type uint8, which can take values from 0 to 255. To speed things a bit up, we initialized it with a value of 254. In the function addOne(), we increment the number by one.
This should work once but fail if the result is bigger than 255.
pragma solidity 0.8.20;
contract overflowTest{
uint8 public number = 254;
function addOne() public{
number++;
}
}
In some cases, however, overflows and underflows are useful. That’s why Solidity allows us to switch off this behavior by adding an unchecked block. The unchecked block can comprise a single statement as well as other blocks.
The following code shows how it works. Try it out.
pragma solidity 0.8.20;
contract overflowUncheckedTest{
uint8 public number = 254;
function addOne() public{
unchecked{
number++;
}
}
}
Exceptions of Overflow and Underflow Checks
Keep in mind that overflow and underflow checks are not performed with bitwise operations like << and >>.
Division by Zero and Modulo by Zero
Division and modulo by zero are also caught and answered with a revert. They cannot be allowed with unchecked.