In simple words, overflow is a situation when uint (unsigned integer) reaches its byte size. Then the next element added will return the first variable element.
Let’s say we have a uint8, which can only have 8 bits. That means the largest number we can store is binary 11111111 (in decimal 2^8 - 1 = 255)
Look at the code below.
uint8 balance = 255;
balance++;
If you execute the code above the "balance" will be 0. This is a simple example of overflow. If you add 1 to binary 11111111, it resets back to 00000000.
In the case of underflow, if you subtract 1 from a uint8 that is 0, it will change the value to 255.
Now I show you a simple implementation of underflow in Solidity.
Let's create a simple smart contract called "ChangeBalance.sol". We're going to use Solidity 0.7 for this example because Solidity 0.8 was secured.
pragma solidity 0.7.0;
contract ChangeBalance {
uint8 public balance;
function decrease() public {
balance--;
}
function increase() public {
balance++;
}
}
Let's compile and deploy the smart contract. As you can see the initial balance is 0.
If you press the "decrease" button, then the "balance" is decremented by one. Let's see what happens next.
As you can see the updated balance is now 255.
The easiest way is to use at least a 0.8 version of the Solidity compiler. In Solidity 0.8, the compiler will automatically take care of checking for overflows and underflows.
Let me show you how it works in practice. To do that I will change the compiler version and deploy a new contract.
pragma solidity 0.8.0;
contract ChangeBalance {
uint8 public balance;
function decrease() public {
balance--;
}
function increase() public {
balance++;
}
}
The initial balance is the same, i.e. 0.
Let's see what happened when we hit "decrease". Now you will get an error in the Remix console.
Also Published Here