Smart Contract Security · Term

What is a delegatecall bug?

delegatecall runs another contract’s code inside your contract’s storage and context. Point it at the wrong code and an attacker can rewrite your contract’s state or seize control. Here is how it goes wrong.

Smart Contract Security · TermSmart Contract Audit
TL;DR

delegatecall is a low-level Solidity operation that executes another contract’s code in the calling contract’s own storage, balance, and `msg.sender` context. It powers upgradeable proxies, but it is dangerous: if the target is attacker-controlled, or the called code modifies storage slots that mean something different in the caller, an attacker can overwrite critical state (like the owner) or take over the contract. The fix is to delegatecall only trusted, immutable targets and align storage layouts. It maps to SWC-112.

By SecureLayer7 Audit Team, Smart Contract Audit, SecureLayer7Updated

What it is

A normal call runs the other contract’s code in its own context. `delegatecall` is different: it runs the other contract’s code but with the caller’s storage, balance, and `msg.sender`. In effect, "borrow that code and run it as if it were mine."

This is how upgradeable proxy patterns work (a proxy delegatecalls to an implementation). The danger is that the borrowed code can write the caller’s storage, so if it is malicious or mismatched, it can corrupt or hijack the calling contract.

How it works and example

Two classic failures:

  • Untrusted target: a contract delegatecalls to an address the attacker controls (for example, set via an unprotected function). The attacker’s code runs in the contract’s context and overwrites the owner slot, then drains it. The Parity multisig incidents stemmed from delegatecall/selfdestruct on shared library code.
  • Storage collision: the implementation’s variable layout does not match the proxy’s, so writing one variable corrupts another (for example the admin slot). See proxy storage collision.

Documented for defensive context.

How to defend

  • Only delegatecall trusted, immutable targets, never an address an attacker can set or influence.
  • Use battle-tested proxy patterns (standard upgradeable proxy libraries) rather than hand-rolling delegatecall.
  • Align storage layouts between proxy and implementation (use unstructured/EIP-1967 storage slots) to avoid collisions.
  • Protect upgrade and target-setting functions with strong access control.
  • Audit every delegatecall path and the proxy/implementation pairing.

References

  1. [1]SWC Registry: Smart Contract Weakness Classification(SWC Registry)
  2. [2]Solidity docs: Security considerations(Solidity)
  3. [3]MITRE CWE-829: Inclusion of Functionality from Untrusted Control Sphere(MITRE CWE)
Related terms

Common questions

Smart contract security, asked often

Shipping a contract on-chain soon?

Scope an audit

Get your smart contracts audited before they go on-chain.

Our auditors review your Solidity line by line and model the economic attacks a real adversary would run, then deliver a report your team can act on with every finding reproduced and a fix. Re-test of fixes included.

See smart contract audit30-min scoping call, fixed-price proposal in 48 hours.