Payable Fallback
Detects contracts with payable fallback or receive functions that accept ETH without proper handling or access control.
Payable Fallback
Overview
The payable fallback detector identifies contracts where the fallback or receive function accepts ETH without proper handling. A payable fallback that accepts ETH without emitting events, updating accounting state, or restricting access can lead to permanently locked funds — ETH sent to the contract accumulates with no mechanism for withdrawal.
Why This Is an Issue
If a contract accepts ETH through a payable fallback but has no withdrawal mechanism, those funds are permanently locked. Even if a withdrawal function exists, the lack of accounting in the fallback means the contract’s internal balance tracking diverges from its actual ETH balance, which can break invariants relied on by other functions. Additionally, unrestricted ETH acceptance enables attackers to manipulate balance-based logic via selfdestruct or coinbase transfers.
How to Resolve
// Before: Vulnerable — accepts ETH with no handling
fallback() external payable {}
receive() external payable {}
// After: Option 1 — reject unexpected ETH
fallback() external { revert("No fallback"); }
receive() external payable {
emit Received(msg.sender, msg.value);
// Or revert if ETH is not expected
}
// After: Option 2 — track deposits
receive() external payable {
deposits[msg.sender] += msg.value;
emit Deposited(msg.sender, msg.value);
}
Detection Methodology
- Fallback identification: Locates the fallback dispatcher in bytecode (code path reached when no function selector matches).
- Payable check: Determines if the fallback path lacks a CALLVALUE-zero check (i.e., accepts non-zero ETH).
- Handling analysis: Checks whether the payable path performs any state updates (SSTORE) or event emission (LOG).
- Withdrawal check: Scans for any function that can extract ETH from the contract (CALL with value, SELFDESTRUCT).
Limitations
False positives: Contracts designed as ETH vaults (e.g., WETH) intentionally accept ETH in their receive function. False negatives: Contracts that accept ETH through a named deposit function but have a non-payable fallback are not in scope.
Related Detectors
- Unprotected Ether Withdrawal — detects missing access control on ETH transfers
- Access Control — detects missing authorization broadly