Skip to main content

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