EVM

Low-Level Call

A low-level call is a Solidity call such as call, delegatecall, staticcall, or send that returns success and data instead of using typed function checks.

A low-level call gives more control, but it also removes many safety rails.

Low-Level Call Explained in Detail

Low-level calls interact with addresses without normal Solidity interface checks. They usually return (bool success, bytes memory data) and leave error handling to the caller.

They are powerful, but easy to misuse.

Smart contract example

(bool ok, bytes memory data) = target.call(payload);
require(ok, "call failed");

Ignoring ok can make the contract continue after a failed call.

Low-Level Call in Auditing

Low-level calls often appear in proxies, routers, plugins, callbacks, ETH transfers, and generic execution systems. They can introduce reentrancy, unchecked failures, arbitrary target execution, and confusing return data.

Auditors check the target, payload, success handling, and state-update order.

Red flags in code

  • success is ignored.

  • Target or calldata is user-controlled without restrictions.

  • ETH is sent before state updates.

  • Return data length and type are not checked.

  • delegatecall is used where call was intended.

How to test or review it

  • Test target success, revert, false return, and malformed return data.

  • Use malicious receivers to test reentrancy.

  • Review call ordering against checks-effects-interactions.

  • Confirm allowed targets and selectors are constrained.

  • Decode and validate return data where it affects state.

Sources