Skip to free scan
high

UNCHECKED RETURN VALUES: FAILURE WITHOUT A REVERT

April 1, 2026Updated September 15, 2026
Chainsethereumarbitrumbaseoptimismpolygonbnb-chain
Review toolsslithermythrilechidnahound-ai

Severity depends on reachable impact and deployment context. Listed tools are review aids; their applicability depends on language, version and configuration.

An unchecked return value lets execution continue after an operation reports failure without reverting. The contract may then record a payment, credit a deposit, consume a claim, or advance a workflow even though the expected external effect did not occur.

CALL SEMANTICS THAT MATTER

Solidity's low-level call, delegatecall, and staticcall return (bool success, bytes returndata) rather than automatically bubbling every failure. Ignoring success is dangerous when later state assumes the call completed. A true success flag proves only that EVM execution did not fail; it does not prove that the target implemented the intended function or produced a valid business result.

Typed external Solidity calls normally propagate a revert, but their application return values can still be ignored. ERC-20 transfer, transferFrom, and approve are specified to return a boolean. Some deployed tokens return false on failure, some revert, and some historical implementations return no value. Direct calls that assume one behavior can create false-success accounting or fail against otherwise supported assets.

REVIEW AND TESTING

Inventory low-level calls, Ether sends, token operations, oracle reads, bridge calls, and custom interfaces. For each returned value, ask what state changes if it indicates failure, contains malformed data, or carries a valid but unfavorable result. Search for discarded tuple components and bare expressions such as target.call(data);.

State does not need to be updated after the external call merely to check success. Checks-Effects-Interactions often updates state before calling out to reduce reentrancy risk. If a later require(success) reverts, the EVM rolls those earlier writes back. The important properties are that failure cannot commit false state and that call ordering preserves reentrancy invariants.

Tests should use callees that revert, return false, return no data, return malformed data, and return true without performing the expected effect. For asset transfers, compare balance deltas when fee-on-transfer or rebasing tokens are in scope rather than equating a successful call with receipt of the nominal amount.

Firepan can inspect discarded call results and state that depends on assumed success in a submitted repository and commit. Tool output remains scoped evidence and cannot establish every external token's runtime behavior.

MITIGATION AND LIMITS

  • Check low-level success and validate return data before relying on it. Bubble or translate revert data only according to the protocol's error policy.
  • Use a reviewed compatibility wrapper such as OpenZeppelin SafeERC20 for supported ERC-20 interactions. Its safe operations handle tokens that return false and tokens that return no value while still failing on a reverted call.
  • Define whether failure should revert the whole action, record a retryable obligation, or isolate one recipient. Silent continuation should be an explicit design, not an accident.
  • Verify code existence and interface behavior when arbitrary target addresses are accepted; low-level success alone is not interface authentication.

Checking a boolean is necessary but sometimes insufficient. The postcondition may require a balance change, a decoded value within bounds, or an authenticated callback.

SOURCES

Firepan

Scan Your Contracts Now

Run a free scan — results in minutes, no credit card required.

Run Free Scan →