# Smart contract security: 4. Integer overflow **Published by:** [skka3134](https://paragraph.com/@skka3134/) **Published on:** 2023-07-26 **URL:** https://paragraph.com/@skka3134/smart-contract-security-4-integer-overflow ## Content 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: ## Publication Information - [skka3134](https://paragraph.com/@skka3134/): Publication homepage - [All Posts](https://paragraph.com/@skka3134/): More posts from this publication - [RSS Feed](https://api.paragraph.com/blogs/rss/@skka3134): Subscribe to updates - [Twitter](https://twitter.com/skka3134): Follow on Twitter