Token-0x

First Flight #54
Beginner FriendlyDeFi
100 EXP
Submission Details
Impact: high
Likelihood: high

Integer Underflow in `_burn`

Author Revealed upon completion

Integer Underflow in _burn

Root + Impact

Description

  • The burn function should decrease the user's balance and total supply, reverting if the user has insufficient balance.

  • The _burn function uses assembly to subtract the value from the balance and supply without checking if the result underflows (i.e., if balance < value).

// src/helpers/ERC20Internals.sol
function _burn(address account, uint256 value) internal {
assembly ("memory-safe") {
// ... (check zero address)
let supply := sload(supplySlot)
sstore(supplySlot, sub(supply, value)) // @> No check for underflow
// ...
let accountBalance := sload(accountBalanceSlot)
sstore(accountBalanceSlot, sub(accountBalance, value)) // @> No check for underflow
}
}

Risk

Likelihood:

  • High // Any user can call burn on their own address.

Impact:

  • High// A user with 0 tokens can burn tokens to underflow their balance to 2^256 - 1 (effectively infinite tokens).

  • High // totalSupply will also underflow, breaking token accounting.

Proof of Concept

function test_Underflow_Burn() public {
address userA = makeAddr("userA");
token.mint(userA, 100);
// Burn 101. Should underflow to MAX.
token.burn(userA, 101);
unchecked {
assertEq(token.balanceOf(userA), uint256(100) - uint256(101));
}
}

Recommended Mitigation

- sstore(supplySlot, sub(supply, value))
+ // Check for underflow: ensure supply >= value
+ if lt(supply, value) { revert(0, 0) }
+ sstore(supplySlot, sub(supply, value))
- sstore(accountBalanceSlot, sub(accountBalance, value))
+ // Check for underflow: ensure balance >= value
+ if lt(accountBalance, value) { revert(0, 0) }
+ sstore(accountBalanceSlot, sub(accountBalance, value))

For subtraction, we must ensure that the value being subtracted is not greater than the value it is being subtracted from. In Yul, sub(a, b) wraps on underflow if b > a. We add an explicit check lt(supply, value) (is supply < value?) to detect this condition and revert.

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!