SWC·SWC-101·high

Integer overflow and underflow

Arithmetic wraps silently instead of reverting.

What it is

Before Solidity 0.8, arithmetic wrapped: subtracting 1 from an unsigned 0 produced the largest representable number. From 0.8 the compiler inserts checks and reverts — unless the maths sits inside an unchecked block, which teams add for gas and then forget to revisit.

Why it matters

A balance check that should fail passes. An attacker withdraws more than they hold, or mints supply out of an underflow. On modern compilers the risk has moved entirely into unchecked blocks and unsafe casts.

The vulnerable pattern

Pre-0.8 without SafeMath: the subtraction wraps.

function withdraw(uint256 amount) public {
    balances[msg.sender] -= amount;   // wraps to a huge number
    payable(msg.sender).transfer(amount);
}

How to fix it

  • Use Solidity 0.8 or later and let the compiler insert the checks.
  • Justify every unchecked block in a comment that states why overflow is impossible there.
  • Watch downcasts: uint256 to uint128 truncates silently even on 0.8. Use a safe-cast library.
  • Multiply before dividing. Integer division truncates, and (a / b) * c loses precision that (a * c) / b keeps.

How it is detected

Every audit on EVM Smart Audit checks for SWC-101 and reports it as passed or flagged in the standards coverage grid — so the report tells you it was checked even when nothing was found. See the detector suite for what else runs alongside it, or the full database for the other 21 checks.

Related weaknesses

Check your contract for integer overflow and underflow

The engine runs this check and 21 others on every audit, and shows what passed as well as what failed.

Start your auditSee pricing