Unchecked ERC-20
Detects ERC-20 token operations whose boolean return values are not checked, allowing silent transfer failures.
Unchecked ERC-20
Overview
The unchecked ERC-20 detector identifies calls to ERC-20 token functions (transfer, transferFrom, approve) whose boolean return values are not checked. Some tokens (notably USDT) do not revert on failure — they return false instead. If the calling contract ignores this return value, it proceeds as if the transfer succeeded, leading to accounting mismatches and potential fund loss.
Why This Is an Issue
The ERC-20 standard specifies that transfer and transferFrom return a boolean indicating success. However, the standard does not mandate reverting on failure. Tokens like USDT, BNB, and some other widely-used tokens return false on failure without reverting. A contract that calls token.transfer(to, amount) without checking the return value will update its internal state (marking the transfer as complete) even when no tokens actually moved.
How to Resolve
// Before: Vulnerable — return value ignored
function pay(address token, address to, uint256 amount) internal {
IERC20(token).transfer(to, amount); // May silently fail
paid[to] = true;
}
// After: Fixed — use SafeERC20
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
using SafeERC20 for IERC20;
function pay(address token, address to, uint256 amount) internal {
IERC20(token).safeTransfer(to, amount); // Reverts on failure
paid[to] = true;
}
Detection Methodology
- ERC-20 call identification: Identifies calls to
transfer(address,uint256)(0xa9059cbb),transferFrom(address,address,uint256)(0x23b872dd), andapprove(address,uint256)(0x095ea7b3). - Return value usage: Checks whether the CALL return value and the decoded boolean are consumed by a conditional (ISZERO + JUMPI) or stored.
- SafeERC20 pattern: Detects use of OpenZeppelin’s SafeERC20 wrapper, which handles non-standard tokens.
- Revert-on-failure check: Distinguishes between tokens that revert and those that return false.
Limitations
False positives: Contracts that only interact with known reverting tokens (e.g., DAI, USDC) do not need return value checks, but this detector cannot determine the token at analysis time. False negatives: Custom wrapper functions that check the return value internally may not be recognized.
Related Detectors
- Unchecked Call — detects unchecked return values on general external calls
- Fee-on-Transfer — detects fee-token accounting issues