Documentation Index
Fetch the complete documentation index at: https://docs.webacy.com/llms.txt
Use this file to discover all available pages before exploring further.
Overview
Malicious external calls are contract interactions that can be exploited to steal funds, manipulate state, or enable other attacks.
Types of Malicious External Calls
Arbitrary External Call
Allows calling any contract with any data, enabling theft.
// DANGEROUS: Arbitrary external call
function execute(address target, bytes memory data) public onlyOwner {
target.call(data); // Can call anything!
}
Attack: Owner calls token.transfer(attacker, balance) on any token.
Unprotected Delegatecall
Delegatecall executes external code in the context of the calling contract.
// DANGEROUS: Unprotected delegatecall
function upgrade(address impl) public {
impl.delegatecall(abi.encodeWithSignature("initialize()"));
}
Attack: Attacker provides malicious implementation that modifies storage.
Callback to Untrusted Contract
Calling user-provided addresses without validation.
// DANGEROUS: Callback to user address
function processPayment(address callback) public {
// ... payment logic ...
ICallback(callback).onPayment(); // User controls callback
}
Attack: Callback contract re-enters or manipulates state.
Approve and Call Patterns
Combining approvals with external calls.
// DANGEROUS: Approve then external call
function swapTokens(address router, uint256 amount) public {
token.approve(router, type(uint256).max); // Unlimited approval
IRouter(router).swap(amount); // Router is user input
}
Attack: Malicious router drains all approved tokens.
Safe Patterns
Whitelist External Calls
// SAFE: Only whitelisted targets
mapping(address => bool) public approvedTargets;
function execute(address target, bytes memory data) public onlyOwner {
require(approvedTargets[target], "Target not approved");
target.call(data);
}
Validate Callback Addresses
// SAFE: Validate callback contract
function processPayment(address callback) public {
require(callback.code.length > 0, "Not a contract");
require(trustedCallbacks[callback], "Untrusted callback");
ICallback(callback).onPayment();
}
Limited Approvals
// SAFE: Exact approval amount
function swapTokens(address router, uint256 amount) public {
require(trustedRouters[router], "Untrusted router");
token.approve(router, amount); // Exact amount only
IRouter(router).swap(amount);
token.approve(router, 0); // Reset approval
}
| Tag | Severity | Description |
|---|
external_call | Medium | Arbitrary external call detected |
dangerous_delegatecall | High | Unprotected delegatecall |
untrusted_callback | Medium | Callback to user-provided address |
unlimited_approval | Medium | Infinite token approval |
API Response Example
{
"issues": [
{
"tag": "external_call",
"severity": "medium",
"description": "Arbitrary external call with user-controlled target",
"location": "execute(address,bytes)"
},
{
"tag": "dangerous_delegatecall",
"severity": "high",
"description": "Delegatecall to unvalidated address",
"location": "upgrade(address)"
}
]
}
Prevention Checklist