Avoiding Arithmetic Vulnerabilities in Smart Contracts: Overflow and Underflow
Arithmetic overflow and underflow are vulnerabilities in smart contracts, self-executing programs that run on a blockchain. These vulnerabilities can occur when a contract performs arithmetic operations on variables that exceed the maximum or minimum value that can be stored in that variable.
Overflow occurs when the result of an arithmetic operation is greater than the maximum value that can be stored in the variable. This can cause the result to wrap around to the minimum value, leading to unexpected and potentially dangerous consequences.
Underflow occurs when the result of an arithmetic operation is less than the minimum value that can be stored in the variable. This can also cause the result to wrap around to the maximum value, leading to unexpected consequences.
Here is an example of code that is vulnerable to arithmetic overflow:
pragma solidity ^0.6.0;
contract Overflow {
uint public balance;
function deposit() public payable {
balance += msg.value;
}
}
In this example, the deposit()
function allows users to send ether to the contract and adds the amount to the balance
variable. However, if the balance
variable exceeds the maximum value that can be stored in a uint
(which is 2^256 - 1), an overflow will occur and the balance
will wrap around to a lower value.
To prevent arithmetic overflow and underflow, smart contract developers must ensure that their contracts perform proper bounds checking on variables. This can be done by using the SafeMath
library, which provides several functions for performing arithmetic operations safely and securely.
Here is an example of how to use the SafeMath
library to prevent arithmetic overflow:
pragma solidity ^0.6.0;
import "https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/math/SafeMath.sol";
contract Overflow {
using SafeMath for uint;
uint public balance;
function deposit() public payable {
balance = balance.add(msg.value);
}
}
In this example, the deposit()
function uses the add()
function from the SafeMath
library to add the amount of ether sent to the contract to the balance
variable. If an overflow had occurred, the add()
the function will instead throw an exception, and the transaction will be reverted.
Note: solidity version 0.8 has already fixed this issue, and there is no explicit need to use the SafeMath library, onwards from 0.8 version.