Overview
Opcode:0xf1
Introduced: Frontier (EVM genesis)
CALL executes code from another account with specified gas, value, and calldata. The callee runs in its own context with msg.sender set to the caller and msg.value to the transferred amount. This is the primary mechanism for inter-contract communication.
Specification
Stack Input:Behavior
CALL performs a nested execution in the target account’s context:- Pop 7 stack arguments in order: gas, address, value, inOffset, inLength, outOffset, outLength
- Validate static context: Cannot transfer value in static call (EIP-214)
- Calculate gas cost:
- Base: 700 gas (Tangerine Whistle+)
- Value transfer: +9,000 gas if value > 0
- New account: +25,000 gas if recipient doesn’t exist and value > 0
- Cold access: +2,600 gas for first access (Berlin+)
- Memory expansion for both input and output regions
- Read calldata from memory at inOffset:inLength
- Forward gas: Up to 63/64 of remaining gas after charging (EIP-150)
- Execute in callee context:
- msg.sender = caller address
- msg.value = transferred value
- Storage = callee’s storage
- Code = callee’s code
- Transfer value: Move ETH from caller to callee (if value > 0)
- Copy returndata to memory at outOffset (up to min(outLength, returndata.length))
- Set return_data buffer to full returndata
- Push success flag (1 if succeeded, 0 if reverted/failed)
- Refund unused gas from child execution
- Callee stipend: +2,300 gas (free) if value > 0 for receive/fallback execution
- Cannot be called with value in static context (EIP-214)
- Success flag pushed even if call reverts (caller continues execution)
- Returndata accessible via RETURNDATASIZE/RETURNDATACOPY
- Call depth limited to 1,024 (pre-Tangerine Whistle enforcement)
Examples
Basic External Call
Value Transfer Call
Safe External Call Pattern
Token Transfer Example
Gas Cost
Total cost: 700 + value_transfer + new_account + cold_access + memory_expansion + forwarded_gasBase Cost: 700 gas (Tangerine Whistle+)
Pre-Tangerine Whistle: 40 gasValue Transfer: +9,000 gas
Charged whenvalue > 0:
New Account: +25,000 gas
Charged when sending value to non-existent account:Cold Access: +2,600 gas (Berlin+)
EIP-2929 (Berlin+): First access to address in transaction:Memory Expansion
Dynamic cost for both input and output regions:Gas Forwarding (EIP-150)
Tangerine Whistle+: Caller retains 1/64th, forwards up to 63/64:Example Calculation
Common Usage
Reentrancy Guard
Multicall Pattern
Router Pattern
Security
Reentrancy Attacks
CALL’s primary security risk - external code can re-enter caller:Return Value Check
Must check success flag - call can fail silently:Gas Griefing
Callee controls gas consumption:Returndata Bomb
Large returndata can cause OOG when copying:Value Transfer Validation
Ensure sufficient balance before value transfer:Implementation
- TypeScript
References
- Yellow Paper - Section 9.4.4 (Message Call)
- EIP-150 - Gas cost changes (63/64 rule)
- EIP-214 - STATICCALL and static context
- EIP-2929 - Access list gas costs
- evm.codes - CALL - Interactive reference
- Consensys Best Practices - Reentrancy patterns

