# Smart contract security: 4. Integer overflow

By [skka3134](https://paragraph.com/@skka3134) · 2023-07-26

---

1.Vulnerabilities

For example, the `uint8` type has a total of 8 bits, which can represent the value of `00000000~11111111`, converted into decimal, which is the value range of `0~255`. At this time, once the result is `256`, since there are only 8 digits in total, the 9th digit 1 cannot be displayed, leaving only `00000000`, which is the desired 256, but actually 0 is obtained.

For example, the following TimeLock contract:

    pragma solidity ^0.4.18;
    
    contract TimeLock {
        mapping(address => uint) public balances;
        mapping(address => uint) public lockTime;
    
        function deposit() public payable {
            balances[msg.sender] += msg.value;
            lockTime[msg.sender] = now + 1 weeks;
        }
    
        function increaseLockTime(uint _secondsToIncrease) public {
            lockTime[msg.sender] += _secondsToIncrease;
        }
    
        function withdraw() public {
            require(balances[msg.sender] > 0);
            require(now > lockTime[msg.sender]);
            uint transferValue = balances[msg.sender];
            balances[msg.sender] = 0;
            msg.sender.transfer(transferValue);
        }
    }
    

In the `increaseLockTime` function, since a free timestamp increment can be input by itself, there is a risk of integer overflow. Just imagine, if the input `_secondsToIncrease` is added to the original `lockTime[msg.sender]` ，due to overflow, the value of `lockTime[msg.sender]` will finally become a very small value, so that in the `withdraw` function, you can smoothly pass

    require(now > lockTime[msg.sender]);
    

这一行，使得deposit进去的ETH可以提前被取出。

2.Preventive measures

First of all, in version `0.8.0`, this problem has been solved at the language level: once an integer overflow occurs, the transaction will be directly reverted. Before version `0.8.0`, a `SafeMath` library of openzeppelin was required.

3.Real cases

On April 22, 2018, hackers launched an attack on the BEC smart contract and took out out of thin air:

`57,896,044,618,658,100,000,000,000,000,000,000,000,000,000,000,000,000,000,000.792003956564819968` BEC tokens were sold in the market. If it is 0, the market collapses instantly.

The contract version is `^0.4.16`, which is less than version 0.8, and the SafeMath library is not used, so there is an integer overflow problem.

    function batchTransfer(address[] _receivers, uint256 _value) public whenNotPaused returns (bool) {
        uint cnt = _receivers.length;
        uint256 amount = uint256(cnt) * _value; //溢出点，这里存在整数溢出
        require(cnt > 0 && cnt <= 20);
        require(_value > 0 && balances[msg.sender] >= amount);
     
        balances[msg.sender] = balances[msg.sender].sub(amount);
        for (uint i = 0; i < cnt; i++) {
            balances[_receivers[i]] = balances[_receivers[i]].add(_value);
            Transfer(msg.sender, _receivers[i], _value);
        }
        return true;
      }
    

The hacker passed in a very large value (here it is 2\*\*255), and overflowed through multiplication, so that the amount (the total number of coins to be transferred) overflowed and became a small number or 0 (here became 0) , so as to bypass the check code of balances\[msg.sender\] >= amount, so that the malicious transfer of a huge amount of \_value can be successful.

Malicious transfer records of actual attacks:

![](https://storage.googleapis.com/papyrus_images/0f2122a8a21331f75262a8a812f16b1b0d0d00db22ae5ac64ac374feac25c121.png)

---

*Originally published on [skka3134](https://paragraph.com/@skka3134/smart-contract-security-4-integer-overflow)*
