Token-0x

First Flight #54
Beginner FriendlyDeFi
100 EXP
View results
Submission Details
Severity: high
Valid

Mint Overflow-_mint() has no overflow check causing balance and totalSupply to wrap to zero

Root + Impact

Description

  • In Solidity 0.8+, arithmetic operations revert on overflow.

  • In Yul assembly, add() does NOT check for overflow — it silently wraps around.

  • _mint() uses unchecked add() for both totalSupply and balance.

// src/helpers/ERC20Internals.sol#L134-L156
function _mint(address account, uint256 value) internal {
assembly ("memory-safe") {
// ...
let supply := sload(supplySlot)
@> sstore(supplySlot, add(supply, value)) // Overflow wraps to 0!
let accountBalance := sload(accountBalanceSlot)
@> sstore(accountBalanceSlot, add(accountBalance, value)) // Overflow wraps to 0!
}
}

Risk

Likelihood:

  • Requires minting near type(uint256).max tokens first

  • Unlikely in normal usage but possible in edge cases or malicious setups

Impact:

  • totalSupply can wrap to 0 while tokens exist

  • User balance can wrap to 0, losing all tokens

  • Breaks invariant: totalSupply == sum(balances)

Proof of Concept

function test_BUG_MintOverflowTotalSupply() public {
token.mint(alice, type(uint256).max);
uint256 supplyBefore = token.totalSupply();
console.log("Supply after first mint:", supplyBefore); // type(uint256).max
token.mint(bob, 1);
uint256 supplyAfter = token.totalSupply();
console.log("Supply after second mint:", supplyAfter); // 0 !!!
}

Recommended Mitigation

function _mint(address account, uint256 value) internal {
assembly ("memory-safe") {
// ...
let supply := sload(supplySlot)
+ let newSupply := add(supply, value)
+ if lt(newSupply, supply) { revert(0, 0) } // Overflow check
- sstore(supplySlot, add(supply, value))
+ sstore(supplySlot, newSupply)
let accountBalance := sload(accountBalanceSlot)
+ let newBalance := add(accountBalance, value)
+ if lt(newBalance, accountBalance) { revert(0, 0) } // Overflow check
- sstore(accountBalanceSlot, add(accountBalance, value))
+ sstore(accountBalanceSlot, newBalance)
}
}
---
## Finding #4 — Mint Missing Event
**Titre :**

_mint() does not emit Transfer event violating ERC20 standard

Updates

Lead Judging Commences

gaurangbrdv Lead Judge 18 days ago
Submission Judgement Published
Validated
Assigned finding tags:

overflow & underflow

missing checks for overflow and underflow.

Support

FAQs

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

Give us feedback!