#06 SC06:2026 High Held #6

Unchecked External Calls

Unchecked external calls describe any situation where a smart contract invokes another contract or address without fully accounting for the callee's behavior, return value, or reentrancy potential.

Official OWASP description, from scs.owasp.org (CC BY-NC-SA 4.0).

Why this rank in 2026

Held at #6. The category overlaps significantly with SC08 (reentrancy) - most 2025 reentrancy losses also fit here - but OWASP keeps them separate because the prevention pattern is different: SC06 is about *what the callee does*; SC08 is about *when control returns to the original contract*.

What this category covers

Every external call in Solidity hands control to code the original contract does not own. The category covers five common failure patterns:

  • Reentrancy via callbacks (ERC-777, ERC-721/1155 receivers, ERC-4626, flash-loan callbacks).

  • Silent failures from ignored return values.

  • Arbitrary code execution via user-supplied addresses.

  • State-after-call ordering - the classic reentrancy window.

  • Unsafe delegatecall to untrusted code.

2025 incidents

  • GMX V1 (Jul 2025) lost $42M because executeDecreaseOrder transferred control to an attacker-supplied address during refund, and state updates happened after the external calls. OWASP cross-references this with SC03 and SC08.

  • Arcadia Finance (Jul 2025) lost $3.5M because SwapLogic._swapRouter() and RebalancerSpot allowed arbitrary external calls to user-supplied router addresses without callee validation.

How AI auditors handle this category

AI tools handle the canonical patterns well - missing return-value checks, low-level call to user-supplied address, missing reentrancy guard. The remaining gap is callbacks: callee identity validation in routers, hooks, and flash-loan recipients. SCH's /attacks/reentrancy walks through the canonical examples that often appear in this category.

2025 incidents tied to this category

Pulled live from the SCH hack database, ordered by amount lost. Click any incident for the full post-mortem.

View the full SCH hack dashboard →

Vulnerable vs secure code

✗ Vulnerable solidity
// Vulnerable: state updated AFTER the external call; return value ignored
function withdraw(uint256 amount) external {
    require(balances[msg.sender] >= amount, "insufficient");
    (bool ok, ) = msg.sender.call{value: amount}("");   // attacker can reenter
    // even if ok is false, we proceed:
    balances[msg.sender] -= amount;
}
✓ Secure solidity
// Secure: CEI + return value checked + ReentrancyGuard
function withdraw(uint256 amount) external nonReentrant {
    uint256 bal = balances[msg.sender];
    require(bal >= amount, "insufficient");
    balances[msg.sender] = bal - amount;                // effect first
    (bool ok, ) = msg.sender.call{value: amount}("");   // interaction
    require(ok, "transfer failed");
}

AI vs human auditor on this category

Each bar is a detection rate: out of 100 known external calls bugs, how many that auditor type finds. Higher means more reliable. The gap below is the percentage-point difference - the work senior humans still do that AI does not.

AI auditor (frontier LLM)
78%
Human auditor (senior)
91%

% of SC06 bugs caught - higher is better.

Human advantage on SC06
+13 percentage points
Senior auditors catch 13 more external calls bugs per 100 than frontier AI today. That gap is the skill the SCH course teaches.

AI handles the canonical "unchecked .call{value:}()" patterns well. The remaining gap is callbacks: ERC-777 transfer hooks, ERC-4626 receive hooks, flash-loan callbacks, and router callees where the *identity* of the callee should be validated, not just the return value.

Methodology: EVMbench, Cecuro purpose-built agent benchmarks, and senior-auditor self-reported catch rates. SCH editorial, not OWASP-authored.

Prevention checklist

  • Treat every external call as untrusted, including calls to standard tokens.
  • Apply Checks-Effects-Interactions: validate → update state → call.
  • Prefer pull-based payments over push for arbitrary recipients.
  • Always check return values; use SafeERC20 for token interactions.
  • Be extremely cautious with low-level calls, callbacks, and delegatecall.
  • Validate callee identity and permissions on hook and callback entry points.

Detection tools

Industry-standard tools that detect this category. Tool mappings are SCH editorial - OWASP's per-category pages do not list specific tools.

Slither
static

unchecked-transfer, unchecked-send, low-level-calls, arbitrary-send-eth, controlled-delegatecall

Mythril
symbolic

symbolic check for unchecked low-level calls

Aderyn
static

unchecked-low-level-call, unsafe-erc20-call

FAQ

What is OWASP SC06 Unchecked External Calls?
SC06 covers any situation where a smart contract invokes another contract or address without fully accounting for the callee behavior, return value, or reentrancy potential. It is #6 in the OWASP Smart Contract Top 10 2026 and covers callbacks, silent failures from ignored return values, arbitrary code execution via user-supplied addresses, and unsafe delegatecall to untrusted code.
How is SC06 Unchecked External Calls different from SC08 Reentrancy?
SC06 is about what the callee does - the value returned, the code executed, whether tokens are actually transferred. SC08 is about when control returns to the original contract before its state has been updated. They overlap in most reentrancy cases but the prevention patterns are different: SC06 fixes are about validating returns and identities, SC08 fixes are about CEI ordering and ReentrancyGuard.
What was the GMX V1 unchecked external call exploit?
In July 2025, GMX V1 lost $42M when executeDecreaseOrder transferred control to an attacker-supplied address during a refund, and state updates happened after the external calls. The exploit chained SC03 oracle manipulation, SC06 unchecked external calls, and SC08-style state-after-call ordering into a single transaction. OWASP cross-references the incident under all three categories.
How do you fix unchecked external calls in Solidity?
Apply Checks-Effects-Interactions ordering rigorously, check all return values (do not assume success), use SafeERC20 for token interactions, prefer pull-based payments over push for arbitrary recipients, be extremely cautious with low-level calls and delegatecall, and validate callee identity on every hook and callback entry point (router callees, ERC-777 hooks, ERC-4626 receive hooks, flash-loan callbacks).
Can AI auditors catch unchecked external call bugs?
AI handles canonical patterns well - around 78% catch rate on missing return-value checks, low-level call to user-supplied address, missing reentrancy guard. Senior humans detect around 91%. The remaining gap is callbacks: callee identity validation in routers, hooks, and flash-loan recipients where the right callee should be a specific protocol-managed address.

Master the techniques that make this category exploitable

The SCH Smart Contract Hacking Course teaches the exploit primitives, audit techniques, and tool workflows for unchecked external calls and every other OWASP 2026 category.