Articles Home

Common Vulnerabilities in Solidity: Arithmetic Overflow and Underflow

Mar 22, 2023

Due to the frequent occurrence of incidents targeting smart contracts, more and more criminals are stealing other people's digital assets through vulnerabilities in contracts. Therefore, we will introduce you to some common vulnerabilities in smart contracts , so that everyone can better understand the security and threats of Solidity smart contracts. This article will introduce a classic vulnerability in smart contracts —— arithmetic overflow.

What Is Arithmetic Overflow And Underflow ?

Overflow vulnerabilities are caused by improper handling of mathematical operations in Solidity. There are two types of overflow vulnerabilities: arithmetic overflow and arithmetic underflow.

When running a single numerical calculation, an overflow occurs when the result of the calculation is very large, greater than the capacity limit that a register or memory can store or represent. This is called an arithmetic overflow. For example, if a smart contract uses the uint8 type to run calculations, the maximum value it can store is 256-1, which means the range it can represent is from 0 to 255. Arithmetic overflow occurs when the operation result is greater than 256-1.

Similarly, arithmetic underflow means that when running a single numerical calculation, the result of the calculation is less than the capacity limit that a register or memory can store or represent. For example, when calculating 0-1 using the uint8 type in a smart contract, an arithmetic underflow will occur.

If there is an overflow vulnerability in a smart contract, there will be a significant difference between the actual calculation results and the expected calculation results. This will affect the normal logic of the contract, and more seriously, it will lead to the loss of funds in the contract.

However, the overflow vulnerability has version limitations. In earlier versions of Solidity (version < 0.8.0), the overflow will not report an error. When the Solidity version is>=0.8.0, the overflow will report an error (tips: note that no error will be reported when using uncheked). Therefore, if the smart contract uses Solidity versions below 0.8.0, attention should be paid to the issue of overflow vulnerabilities.

Vulnerability Example

After reading the above content, we have a certain understanding of the concept of overflow vulnerabilities. Next, we will conduct a deeper understanding of overflow vulnerabilities in combination with contract code:

        
            // SPDX-License-Identifier: MIT
            pragma solidity ^0.7.6;

            comtract TimeLock {
                mapping(address => uint) public balances;
                mapping(address => uint) public lockTie;

                function deposit() external payable {
                    balances[msg.sender] += msg.value;
                    lockTime[msg.sender] = block,timestamp + 1 weeks;
                }
                function increasrLockTime(uint _secondsToIncrease) public {
                    lockTime[msg.sender] += _secondsToIncrease;
                }

                function withdraw() public {
                    require(balances[msg.sender] > 0, "Insufficient funds");
                    require(block.tiestamp > lockTime[msg.sender], "lock time not expired");

                    uint amount = balances[msg.sender];
                    balances[] = 0;

                    (bool sent,) = msg.sender.call{value: amount}("");
                    require(sent, "Failed to send Ether");
                }
            }
        
    

This is a TimeLock contract where users can deposit tokens into the contract and lock them for at least a week. And users can increase the storage time through the increaseLockTime function. Users cannot withdraw the locked tokens in the contract within the set lockTime.

We have noticed that the version supported by this contract is 0.7.6 upwardly compatible, so there may be an overflow vulnerability. In the incrementLockTime function, an overflow vulnerability exists in the _secondsToIncrease parameter.

If the user calls the increaseLockTime function and passes in `type(uint256).max - lockTime` as `_secondsToIncrease`. The result of the calculation will overflow and reset to zero, allowing users to withdraw tokens from the contract in advance before the lockTime expires.

How to prevent overflow vulnerabilities?

You can prevent overflow vulnerabilities in Solidity through the following precautions: