Integer Overflows and Underflows in <0.8 Solidity Smart Contracts
Integer overflows and underflows are a common source of vulnerabilities in <0.8 Solidity smart contracts. In this post, we’ll explore what integer overflows and underflows are and how vulnerabilities can be remedied.
What are Integer Overflows and Underflows?
In Solidity, integers are represented using a fixed number of bits. For example, uint8 uses 8 bits and can store values from 0 to 255. When an integer is incremented beyond its maximum value or decremented below its minimum value, an overflow or underflow occurs, respectively.
An integer overflow occurs when the result of an arithmetic operation exceeds the maximum value that can be stored in the integer’s bit representation. For example, if we add 1 to the maximum value of uint8, which is 255, the result is 0, causing an integer overflow.
On the other hand, an integer underflow occurs when the result of an arithmetic operation is less than the minimum value that can be stored in the integer’s bit representation. For example, if we subtract 1 from the minimum value of int8, which is -128, the result is 127, causing an integer underflow.
Why are Integer Overflows and Underflows Dangerous?
Integer overflows and underflows can have unintended consequences in smart contracts. An attacker can exploit integer overflows and underflows to steal funds, bypass access controls, or execute arbitrary code on the blockchain. For example, consider the following code:
uint256 myBalance = 10;
uint256 withdrawalAmount = 15;
require(myBalance >= withdrawalAmount, "Insufficient balance");
myBalance -= withdrawalAmount;
In the above code, the require statement checks if the user’s balance is sufficient before allowing them to withdraw funds. However, if an attacker sets the withdrawalAmount to a value greater than the maximum value of uint256 (2²⁵⁶ — 1), an integer overflow occurs, and the required condition gets satisfied. The attacker can then withdraw an arbitrary amount of funds from the contract.
How to Prevent Integer Overflows and Underflows?
To prevent integer overflows and underflows in Solidity, developers should use safe arithmetic functions such as SafeMath or Math. These libraries provide safe arithmetic operations that check for integer overflows and underflows before executing the operation. For example, consider the following code using the SafeMath library:
uint256 myBalance = 100;
uint256 withdrawalAmount = 200;
require(balance >= withdrawalAmount, "Insufficient balance");
myBalance = myBalance.sub(withdrawalAmount);
In the above code, the SafeMath library’s sub function checks if an integer underflow occurs before subtracting the withdrawalAmount from the balance variable. If an integer underflow occurs, the function will revert the transaction and prevent the attacker from withdrawing funds.
Solidity version 0.8
Starting from Solidity version 0.8, the compiler will throw an error when an integer overflow or underflow occurs during arithmetic operations. This new feature is designed to prevent developers from accidentally introducing vulnerabilities into their smart contracts by detecting and flagging potential risks at compile-time. This means that developers who upgrade to Solidity 0.8 or later versions can benefit from enhanced security by default, as the compiler will automatically prevent integer overflows and underflows. However, it’s still recommended to use safe arithmetic functions such as SafeMath or Math as an additional layer of protection against potential vulnerabilities. By combining both the new compiler error feature and safe arithmetic functions, developers can ensure their smart contracts are secure against integer overflows and underflows.
Solidity announcement:
https://blog.soliditylang.org/2020/12/16/solidity-v0.8.0-release-announcement/