Arbitrary ERC-20 Transfer
Detects ERC-20 transfer and transferFrom calls where the recipient or amount is user-controlled without access control, enabling token theft.
Arbitrary ERC-20 Transfer
Overview
The arbitrary ERC-20 transfer detector identifies functions that call transfer() or transferFrom() on token contracts where the recipient address or token amount is derived from user input, and the function lacks access control. This enables an attacker to call the function and redirect the contract’s token holdings to their own address.
The Yearn Finance exploit ($11.6M, February 2021) involved a vulnerability where token transfers could be manipulated without proper authorization.
Why This Is an Issue
Contracts that hold ERC-20 tokens and expose transfer functionality without access control are trivially exploitable. An attacker calls the vulnerable function with their own address as the recipient and the contract’s full balance as the amount.
How to Resolve
// Before: Vulnerable — anyone can transfer tokens out
function sendTokens(address token, address to, uint256 amount) external {
IERC20(token).transfer(to, amount);
}
// After: Fixed — only owner can transfer
function sendTokens(address token, address to, uint256 amount) external onlyOwner {
IERC20(token).transfer(to, amount);
}
Detection Methodology
- Transfer call identification: Locates external calls matching
transfer(address,uint256)andtransferFrom(address,address,uint256)selectors. - Parameter taint analysis: Traces the recipient and amount parameters to determine if they originate from calldata.
- Access control check: Searches for
CALLERcomparison before the transfer call. - Self-transfer exclusion: Calls where the destination is
address(this)are excluded (these are deposits, not withdrawals).
Limitations
False positives: Functions that are only callable through access-controlled parent functions may be flagged. False negatives: Transfers through intermediate helper contracts may not be traced.
Related Detectors
- Access Control — detects missing authorization
- Unprotected Ether Withdrawal — detects unprotected ETH transfers