Explicit Balance Checks
What it detects
This detector identifies functions that perform ether or token transfers without explicitly verifying that the sender has a sufficient balance. In smart contract logic, especially where custom accounting is used (e.g., internal mapping(address => uint256)
), failure to check balances can allow users to transfer more than they own, leading to inconsistencies, negative balances (off-chain), or potential exploits.
It also catches missing or incorrect assertions like:
require(balances[msg.sender] >= amount)
- Improper or inverted comparison logic
- Lack of reversion when balance is insufficient
These issues often arise in poorly designed transfer functions, reward systems, or manual accounting implementations.
Typical symptoms
- Transfer succeeds even when sender has no funds
- User balances drop below zero in off-chain accounting or frontend displays
- Total supply mismatches actual user holdings
- Users can exploit the flaw to "mint" or receive more tokens than they should
Solidity snippet (v0.8.25)
pragma solidity ^0.8.25;
contract SendWithoutCheck {
mapping(address => uint256) public balances;
function send(address to, uint256 amount) external {
// Missing check: does msg.sender have enough balance?
// Attacker can send any amount without constraint
balances[to] += amount;
balances[msg.sender] -= amount;
}
}
Fixed Version
function send(address to, uint256 amount) external {
require(balances[msg.sender] >= amount, "Insufficient balance");
balances[msg.sender] -= amount;
balances[to] += amount;
}
Why it matters on EVM
Smart contracts do not prevent negative balances by default—this responsibility falls on developers. Without explicit checks, contracts can perform invalid state transitions that are exploitable or cause long-term inconsistencies.
These vulnerabilities can:
- Enable fund theft or unauthorized balance increases
- Undermine protocol trust by violating expected accounting logic
- Result in failed withdrawals, inaccurate reward distributions, or insolvency
- Be used in larger attack chains involving flash loans or reentrancy