Description:
The internal _mint implementation in ERC20Internals performs unchecked arithmetic operations on both totalSupply and the account balance, without proper overflow validation:
There are no checks to ensure that totalSupply + value and balanceOf(account) + value do not overflow. It can lead to:
Wrap totalSupply back to zero or a small number.
Wrap a holder’s balance back to zero or a smaller number, essentially “burning” their tokens without any revert.
All of this happens silently, which is very dangerous for a library that aims to be “secure and cheap” and is intended as a base for DeFi protocols.
Impact:
If the contract mints very large amounts or is used in a context where totalSupply can approach type(uint256).max, it will overflow and wrap to a small number without reverting.
This breaks core invariants expected by other contracts (e.g., sum(balances) == totalSupply).
In extreme scenarios, user balances can wrap to zero after minting (a permanent loss of effective tokens from the holder’s perspective).
This is a high‑risk correctness bug. While it may seem unlikely to hit 2^256 in practice, protocols often reason symbolically about totalSupply, so the lack of any safety guard is not acceptable in a reusable base contract.
Proof of Concept:
Token using Token-0x ERC20:
Token2 using OpenZeppelin ERC20:
OpenZeppelin’s implementation reverts when totalSupply + amount overflows, while Token-0x silently wraps, proving the issue.
Mitigation:
Add overflow checks in _mint for both totalSupply and the recipient’s balance:
Implement mint logic in Solidity with default overflow checks and only optimize storage access with assembly.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.
The contest is complete and the rewards are being distributed.