
Integer Overflow in Solidity: What It Is, Real Examples, and How to Prevent It (2026)
An integer overflow vulnerability occurs when arithmetic operations exceed the maximum value a data type can hold — causing the value to wrap around to zero or a small number. Before Solidity 0.8.0, this was a critical security flaw that allowed attackers to manipulate balances and bypass checks. The BEC Token hack in 2018 exploited integer overflow to generate $900 million worth of tokens from nothing. Use the free Blockhertz AI Smart Contract Auditor to check your contracts for overflow vulnerabilities in under 60 seconds.
https://www.youtube.com/embed/vIDQ7nMppDIWhat is Integer Overflow in Solidity?
Every integer type in Solidity has a fixed range. A uint256 can hold values from 0 to 2²⁵⁶-1. When an arithmetic operation exceeds this maximum, the value wraps around — like an odometer rolling over from 99999 to 00000. Before Solidity 0.8.0, this wrapping happened silently with no error. Attackers exploited this behavior to manipulate token balances, bypass transfer checks, and drain contracts.
Overflow Example
// In Solidity < 0.8.0: uint256 max = type(uint256).max; uint256 result = max + 1; // result = 0 (wraps around!)
Underflow Example
// In Solidity < 0.8.0: uint256 zero = 0; uint256 result = zero - 1; // result = 115792089237316195... // (wraps to maximum value!)
How Did the $900 Million BEC Token Hack Happen?
In April 2018, an attacker exploited an integer overflow vulnerability in the BeautyChain (BEC) token contract. The vulnerable batch transfer function allowed users to send tokens to multiple addresses. The attacker passed a carefully crafted value that caused an integer overflow in the amount calculation — generating an astronomically large token balance from nothing. The attacker then dumped these tokens on exchanges, causing the BEC token price to crash to near zero and wiping out an estimated $900 million in market value.
The Vulnerable Code
// VULNERABLE — BEC Token style
// Solidity ^0.4.16
function batchTransfer(
address[] receivers,
uint256 value
) public returns (bool) {
uint cnt = receivers.length;
// ❌ OVERFLOW HERE:
uint256 amount = uint256(cnt) * value;
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;
}
How Do You Prevent Integer Overflow in Solidity?
Prevent integer overflow by upgrading to Solidity 0.8.0 or higher which has built-in protection, using OpenZeppelin SafeMath for legacy contracts, and being careful with unchecked blocks and type casting.
Does Solidity 0.8 Automatically Prevent Integer Overflow?
Yes — Solidity 0.8.0 introduced automatic overflow and underflow protection. Every arithmetic operation now reverts automatically if it would overflow or underflow — no additional code required. Simply upgrading to Solidity 0.8.0+ eliminates integer overflow vulnerabilities entirely for standard arithmetic.
// SECURE — Solidity ^0.8.0
pragma solidity ^0.8.20;
contract SecureToken {
mapping(address => uint256) public balances;
function transfer(address to, uint256 amount) external {
// ✅ Automatically reverts if underflow
balances[msg.sender] -= amount;
balances[to] += amount;
}
}
What is SafeMath and When Should You Use It?
SafeMath is an OpenZeppelin library for Solidity versions below 0.8.0 that prevents integer overflow and underflow by reverting on unsafe arithmetic operations. It is no longer needed in Solidity 0.8.0 and above. Only use SafeMath when maintaining legacy contracts that cannot be upgraded to Solidity 0.8+.
// SECURE — Legacy Solidity with SafeMath
pragma solidity ^0.6.0;
import "@openzeppelin/contracts/math/SafeMath.sol";
contract SecureToken {
using SafeMath for uint256;
mapping(address => uint256) public balances;
function batchTransfer(
address[] memory receivers,
uint256 value
) public returns (bool) {
uint256 cnt = receivers.length;
// ✅ SafeMath reverts on overflow
uint256 amount = cnt.mul(value);
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);
}
return true;
}
}
When is it Safe to Use unchecked Blocks in Solidity?
Use unchecked blocks only when overflow is mathematically impossible — such as loop counters already bounded by array length checks. Never use unchecked for token balances, amounts, or any value that could be influenced by user input.
// ✅ SAFE use of unchecked
function processArray(uint256[] memory data) external {
for (uint256 i = 0; i < data.length;) {
// process data[i]
unchecked {
++i; // safe: i < data.length guarantees no overflow
}
}
}
// ❌ UNSAFE use of unchecked
function dangerousAdd(uint256 a, uint256 b) external pure returns (uint256) {
unchecked {
return a + b; // can overflow!
}
}
Integer Overflow Checklist
Check Status
Using Solidity 0.8.0 or higher
✅ Required
SafeMath used for legacy Solidity
✅ Required if < 0.8.0
unchecked blocks only where safe
✅ Required
Multiplication before division
✅ Recommended
Array length × value checked
✅ Required
No casting from large to small types
✅ Required
Can Type Casting Cause Overflow in Solidity?
Yes — casting from a larger integer type to a smaller one can cause overflow even in Solidity 0.8.0+. Use OpenZeppelin's SafeCast library to safely downcast between integer types with automatic revert on overflow.
// ❌ RISKY — explicit cast truncates value uint256 large = 257; uint8 small = uint8(large); // small = 1 (256 truncated!) // ✅ SAFE — use OpenZeppelin SafeCast import "@openzeppelin/contracts/utils/math/SafeCast.sol"; uint256 large = 257; uint8 small = SafeCast.toUint8(large); // Reverts if value doesn't fit in uint8
Why Does Multiplication Order Matter in Solidity?
Always multiply before dividing to avoid precision loss. Dividing first truncates the result to an integer before multiplication amplifies it — this can create exploitable rounding behavior in financial calculations.
// ❌ WRONG order — precision loss uint256 result = (a / b) * c; // ✅ CORRECT order — multiply first uint256 result = (a * c) / b;
How Do You Detect Integer Overflow in Smart Contracts?
The Blockhertz AI Smart Contract Auditor automatically detects integer overflow vulnerabilities in your Solidity, Rust, Move, or Vyper contracts in under 60 seconds.
- Go to blockhertz.com/tools/ai-auditor
- Paste your smart contract
- Click Audit Contract
- Get a full security report with risk score and fix recommendations
Free to start — no signup required: blockhertz.com/tools/ai-auditor
Summary
- Integer overflow = arithmetic wraps around when exceeding max value
- BEC Token hack = $900M exploited via overflow in 2018
- Solidity 0.8.0+ = automatic overflow protection built in
- Legacy contracts = use OpenZeppelin SafeMath
- unchecked blocks = only when overflow is mathematically impossible
- Type casting = use SafeCast for safe downcasting
References
- BatchOverflow Bug in BEC Token — PeckShield (2018)
- Checked/Unchecked Arithmetic — Solidity Documentation
- SafeCast — OpenZeppelin Documentation
- SWC-101: Integer Overflow — Smart Contract Weakness Registry
- Insecure Arithmetic — Consensys Best Practices
Related Blockhertz Tools
Most common vulnerability explained
Automatically detect integer overflow and 10+ other vulnerabilities in your smart contracts at blockhertz.com/tools/ai-auditor — free, no signup required.
Explore Blockhertz
Views
19
Read Time
6 min read
Likes
2
Published
Aug 12, 2026
SIGNAL THREAD
NO SIGNALS YET — BE FIRST TO TRANSMIT
Technical Writer Team Blockhertz
Blockchain & Web3 Innovator
Blockhertz is a collective of blockchain developers, architects, and innovators dedicated to building next-gen Web3 solutions. Our team specialises in DeFi, tokenomics, smart contracts, and distributed systems.