Solidity uses fixed-size integers like uint256 (0 to 2²⁵⁶-1).
Before Solidity 0.8.0:
- Adding past the maximum value wraps around to 0 (overflow).
- Subtracting below 0 wraps around to the maximum value (underflow).
It’s like a car odometer: after 999,999 km it jumps back to 0.
Hackers exploited this to create “free” tokens or drain balances — the most famous case being the BeautyChain (BEC) token hack in 2018, where attackers minted billions of tokens for almost nothing.
Solidity 0.8.0+ changed the game: now any overflow or underflow automatically reverts (transaction fails), making these attacks much harder — unless you explicitly use unchecked {}.
This repo lets you see both the old vulnerable behavior and the modern safe way.
This code is intentionally vulnerable in places.
Never deploy it on mainnet — it’s for learning only!
# Clone & jump in
git clone https://github.com/Dimeji-go/solidity-integer-overflow-demo.git
cd solidity-integer-overflow-demo
# Install (Foundry preferred)
forge install
# Run the tests
forge testYou’ll see something like this:
[⠊] Compiling...
[⠔] Compiling 8 files with 0.8.24
Compiler run successful
Running 3 tests for test/OverflowTest.t.sol:OverflowTest
[PASS] testOldVersionAllowsUnderflowAttack() (gas: ~142k)
[PASS] testSolidity08RevertsOnOverflow() (gas: ~95k)
[PASS] testSafeMathBlocksExploit() (gas: ~108k)
All good! 3 passed; 0 failed; ~1.5s
// Classic batch transfer bug (like BEC)
function batchTransfer(address[] memory receivers, uint256 amount) public {
uint256 total = amount * receivers.length; // overflows silently!
require(balances[msg.sender] >= total);
for (uint i = 0; i < receivers.length; i++) {
balances[receivers[i]] += amount;
}
balances[msg.sender] -= total; // underflow = free money
}// No extra code needed — overflow reverts automatically
balances[msg.sender] -= amount;
balances[to] += amount;using SafeMath for uint256;
balances[msg.sender] = balances[msg.sender].sub(amount);
balances[to] = balances[to].add(amount);unchecked {
counter++; // wraps around if maxed out
}Pro tip: Only use unchecked if you’re optimizing gas and you’re absolutely sure wrapping is safe.
- 2018: BeautyChain (BEC) token — attackers minted trillions of tokens via overflow
- 2017–2019: Dozens of ERC-20 tokens lost millions due to similar bugs
- Post-0.8: Much safer, but audits still find people using
uncheckedcarelessly
- Solidity 0.8.0: The Overflow Revolt
- BeautyChain Hack Deep Dive
- OpenZeppelin SafeMath (for old contracts)
Questions, ideas, or PRs welcome!