Free 30-min Web3 Consultation
Book Now
Smart Contract Security Audits
Learn More
Custom DeFi Protocol Development
Explore
Full-Stack Web3 dApp Development
View Services
Free 30-min Web3 Consultation
Book Now
Smart Contract Security Audits
Learn More
Custom DeFi Protocol Development
Explore
Full-Stack Web3 dApp Development
View Services
Free 30-min Web3 Consultation
Book Now
Smart Contract Security Audits
Learn More
Custom DeFi Protocol Development
Explore
Full-Stack Web3 dApp Development
View Services
Free 30-min Web3 Consultation
Book Now
Smart Contract Security Audits
Learn More
Custom DeFi Protocol Development
Explore
Full-Stack Web3 dApp Development
View Services
LABS
Glossary

Delegatecall

Delegatecall is a low-level function call in the Ethereum Virtual Machine (EVM) that executes code from another contract while preserving the storage, msg.sender, and msg.value of the calling contract.
Chainscore © 2026
definition
SMART CONTRACT OPERATION

What is Delegatecall?

Delegatecall is a low-level function in the Ethereum Virtual Machine (EVM) that allows a smart contract to execute code from another contract while preserving its own storage, `msg.sender`, and `msg.value` context.

Delegatecall is a specialized opcode in the Ethereum Virtual Machine (EVM) that enables a contract to borrow the logic of another contract. Unlike a standard external call (call), which executes code in the context of the called contract, delegatecall executes the external code as if it were part of the calling contract. This means the executed code reads from and writes to the caller's storage, and the original msg.sender and msg.value are preserved. This behavior is fundamental for implementing upgradeable contract patterns and proxy architectures.

The primary use case for delegatecall is in proxy patterns and upgradeable smart contracts. In this design, a lightweight proxy contract stores all the application's state. When a user interacts with the proxy, it uses delegatecall to forward the request to a separate logic contract, which contains the executable code. This separation allows developers to deploy new logic contracts while the proxy (and thus the contract's address and stored data) remains unchanged, enabling seamless upgrades without migrating state.

A critical security consideration with delegatecall is storage layout compatibility. Because the logic contract's code manipulates the proxy's storage slots, the order and types of variables declared in both contracts must remain perfectly aligned across upgrades. A mismatch can lead to catastrophic state corruption, where variables are unintentionally overwritten. This risk makes thorough testing and the use of established libraries like OpenZeppelin's Upgradeable Contracts essential for safe implementation.

The delegatecall operation is also a common vector for reentrancy attacks and other exploits if not handled carefully. Since the called contract executes in the context of the caller, it has full access to the caller's state and balance. Malicious contracts can use this to manipulate execution flow. Developers must apply the same security checks—such as the checks-effects-interactions pattern and proper access controls—as they would for internal functions when using delegatecall.

In summary, delegatecall is a powerful but dangerous EVM feature that underpins modern smart contract upgradeability. Its correct use requires a deep understanding of EVM storage, context preservation, and strict adherence to security best practices to manage the significant risks associated with delegating control of a contract's execution environment.

how-it-works
EVM OPCODE

How Delegatecall Works

An in-depth look at the `delegatecall` opcode, a core mechanism for smart contract composability and upgradeable proxy patterns in Ethereum.

Delegatecall is an Ethereum Virtual Machine (EVM) opcode that allows a smart contract to execute code from another contract's logic while preserving its own storage, msg.sender, and msg.value. This means the calling contract's state is modified, not the state of the contract where the code is defined. It is the foundational mechanism behind proxy patterns and upgradeable contracts, enabling logic to be separated from data storage. Unlike a standard call, which runs in the context of the target contract, delegatecall runs in the context of the caller, making it a powerful but potentially dangerous tool for contract composition.

The primary technical distinction lies in the execution context. When Contract A performs a delegatecall to Contract B, it loads and executes the bytecode of Contract B. However, all storage reads and writes reference the storage slots of Contract A. Furthermore, the msg.sender and msg.value from the original transaction remain unchanged, meaning Contract B's logic can act on behalf of Contract A. This is critical for diamond proxies and modular designs, where a single proxy contract can delegate to multiple logic libraries, all sharing a unified state.

A canonical example is an upgradeable proxy. A simple proxy contract stores the implementation address in a known storage slot (e.g., slot 0). When a user calls the proxy, the proxy's fallback function uses delegatecall to forward the request to the implementation contract. The logic executes, but any state changes (like updating a user's balance) are written to the proxy's storage. To upgrade, the proxy's admin simply updates the implementation address in storage, instantly changing the contract's behavior without migrating data.

Using delegatecall introduces significant security considerations, most notably the risk of storage collisions. Since the logic contract writes to the proxy's storage, both contracts must have identically aligned storage layouts. If the logic contract's variables are declared in a different order, it will write to the wrong storage slots, corrupting the proxy's state. This risk necessitates careful use of inheritance or structured storage patterns. The infamous Parity Wallet hack was caused by a vulnerability where an uninitialized proxy contract could be claimed and self-destructed via a delegatecall.

Beyond upgradeability, delegatecall enables library contracts. Libraries are stateless contracts that deploy once, and other contracts use delegatecall to run their functions. This saves gas by avoiding code duplication. The delegatecall opcode is also integral to more complex architectures like EIP-2535 Diamonds, which allow a proxy to map function selectors to multiple logic contracts, creating a modular, facet-based system. Understanding its context-preserving behavior is essential for advanced Ethereum development and security auditing.

key-features
SOLIDITY LOW-LEVEL FUNCTION

Key Features of Delegatecall

delegatecall is a low-level Solidity function that allows a contract to execute code from another contract while preserving its own storage, msg.sender, and msg.value context.

01

Preserves the Calling Contract's Context

The most critical feature of delegatecall is that it executes the logic of the target contract within the context of the caller. This means:

  • Storage: Modifications are made to the storage of the calling contract, not the target.
  • msg.sender & msg.value: These values are preserved from the original transaction, allowing for accurate permission and payment checks.
  • this (address): Refers to the caller's address, not the target's. This enables upgradeable proxy patterns, where logic can be changed while user data and funds remain in a fixed storage contract.
02

Enables Upgradeable Smart Contract Patterns

Delegatecall is the foundational mechanism for proxy contracts and upgradeable systems like the Transparent Proxy or UUPS patterns.

  • Logic/Storage Separation: A permanent proxy contract holds all state (storage).
  • Delegate to Logic: The proxy uses delegatecall to execute code in a separate, changeable logic contract.
  • Non-Destructive Upgrades: Developers can deploy a new logic contract and point the proxy to it, upgrading functionality without migrating user assets or breaking existing integrations. This is a core design pattern in major DeFi protocols.
03

Requires Identical Storage Layouts

A major technical constraint of delegatecall is that the calling and target contracts must have compatible storage layouts. Because the target's code manipulates the caller's storage slots directly:

  • Slot Collision Risk: If variable declarations are reordered or changed between contract versions, delegatecall can corrupt storage, leading to catastrophic bugs or fund loss.
  • Inheritance & Packing: Developers must carefully manage inheritance chains and variable packing to maintain slot alignment.
  • Best Practice: Use established upgradeability frameworks (like OpenZeppelin) that enforce storage layout safety through inheritance or structured storage.
04

Gas Cost & Execution Flow

delegatecall is a low-level opcode with specific gas and execution characteristics:

  • Gas Forwarding: The caller must forward sufficient gas for the execution of the target's code. Running out of gas in the delegate-called context can cause the entire transaction to revert.
  • Return Data: It returns a boolean success flag and the return data (bytes memory) from the executed function, which must be decoded by the caller.
  • No Value Transfer: Unlike call, delegatecall ignores any msg.value sent with it for Ether transfer, as its primary purpose is code execution, not payment. Any Ether sent must be handled within the contract's logic.
05

Security Considerations & Attack Vectors

Misuse of delegatecall introduces severe security risks:

  • Selfdestruct in Context: If the target contract contains a selfdestruct opcode, calling it via delegatecall will destroy the caller contract, not the target, potentially locking all funds.
  • Unchecked Return Values: Failing to check the boolean success return can lead to silent failures.
  • Malicious Logic Contracts: A proxy must only delegatecall to trusted, audited logic contracts, as they have full write access to the proxy's storage.
  • Parity Wallet Hack: A famous exploit occurred due to an unprotected delegatecall in a library contract, allowing an attacker to become the owner and drain the multi-sig wallet.
06

Comparison with Call and Staticcall

delegatecall is one of three primary low-level call operations in Solidity, each with distinct contexts:

  • call: Executes code in another contract's context. Uses the target's storage, and msg.sender is the caller. Can transfer Ether.
  • staticcall: Identical to call but guarantees no state modifications (view/pure). Reverts if the called function tries to write to storage.
  • delegatecall: Executes code from another contract but in the caller's own context (storage, msg.sender). Cannot transfer Ether via the call itself. Understanding these differences is crucial for designing secure inter-contract interactions.
code-example
DELEGATECALL

Code Example

A practical demonstration of the delegatecall opcode in Solidity, showing how a contract can execute code from another contract while preserving its own storage context.

The following Solidity code defines two contracts: a Library containing logic and a Proxy that uses delegatecall to execute it. The key distinction is that when Proxy calls Library.delegateCallIncrement(), the code runs in the context of the Proxy's storage. This means the number variable in the Library contract is never written to; instead, the number variable in the Proxy contract is modified, as evidenced by the differing return values of getLibraryNumber() and getProxyNumber().

Understanding the Execution Context is critical. The delegatecall opcode preserves the msg.sender, msg.value, and, most importantly, the storage layout of the calling contract. This requires the storage variables in the calling contract (Proxy) to be declared in the exact same order and type as in the target contract (Library) to prevent catastrophic storage collisions. This pattern is the foundation for upgradeable proxy contracts, where logic can be changed by pointing the proxy to a new library address.

Security Considerations for delegatecall are paramount. Since the target contract's code executes with the proxy's privileges, a malicious or compromised library contract could perform arbitrary state changes, including self-destruct. The Proxy contract must therefore strictly control and verify the library address it delegates to. This example is a minimal, insecure illustration; production systems use established patterns like the Transparent Proxy or UUPS (EIP-1822) to manage upgradeability and access control securely.

ecosystem-usage
DELEGATECALL

Ecosystem Usage & Examples

delegatecall is a low-level EVM opcode enabling contract composition and upgradeability by executing code from another contract within the caller's storage context.

04

The Parity Wallet Hack (2017)

A historic example of delegatecall's security risks was the Parity Multisig Wallet Hack. A vulnerability in a library contract, which was called via delegatecall by hundreds of wallets, allowed an attacker to become the library's owner. The attacker then destructed the library via selfdestruct, bricking all dependent wallets by making their delegatecalls fail. This incident, which froze over $150M+ in ETH at the time, underscores the criticality of immutability and careful dependency management with delegatecall.

06

Cross-Chain Messaging & Bridges

In cross-chain architectures, delegatecall can be used by bridge relayers or omnichain protocols. A contract on the destination chain may receive a verified message and delegatecall to a specific handler contract to execute the intended action (e.g., minting tokens, updating state). This keeps the core messaging logic separate from application logic, though it requires extreme caution to prevent malicious callees from compromising the receiver's storage.

security-considerations
DELEGATECALL

Security Considerations & Risks

The delegatecall opcode is a powerful but dangerous feature of the EVM, enabling contract composability while creating unique security pitfalls. Its misuse is a root cause of major protocol hacks.

01

Storage Collision & Context Preservation

A delegatecall executes code from a target contract within the context of the calling contract. This means the target code reads and writes to the caller's storage slots, not its own. If storage layouts between the two contracts are misaligned, the target code can overwrite critical variables, leading to arbitrary state corruption.

  • Example: A proxy contract's owner variable at slot 0 could be overwritten if the implementation contract mistakenly writes to slot 0 for a different purpose.
02

The Parity Wallet Multisig Hack

A canonical example of delegatecall vulnerability. In 2017, an attacker exploited a publicly accessible initWallet function in the Parity multisig library contract. By calling it via delegatecall from a vulnerable wallet, the attacker became the owner of the library itself. This allowed them to destruct the library, permanently freezing ~514,000 ETH (over $150M at the time) in all wallets that depended on it, demonstrating the systemic risk of upgradeable patterns.

03

msg.sender and msg.value Persistence

Unlike a standard call, delegatecall preserves the original msg.sender and msg.value. This is essential for authentication but creates subtle risks:

  • Unexpected Privilege: A user may call a proxy function that delegatecalls to a logic contract, which then performs a sensitive operation that correctly authenticates the original msg.sender, potentially bypassing intermediary checks.
  • Value Mismanagement: msg.value is passed through, but the called contract's logic may not be designed to handle native ETH, as delegatecall does not transfer value. This can lead to accounting errors.
04

Selfdestruct in the Calling Context

If the target contract code contains a selfdestruct instruction, executing it via delegatecall will destroy the calling contract, not the target. This can be used in a malicious implementation to brick a proxy or wallet. Even non-maliciously, a buggy upgrade that introduces a selfdestruct path can lead to irreversible loss of the entire contract and its assets.

05

Mitigation: Stateless Libraries & Storage Safety

Best practices to mitigate delegatecall risks:

  • Use Stateless Libraries: Design libraries to be pure or view, or to operate only on data passed explicitly as arguments, avoiding storage writes.
  • Explicit Storage Management: In upgradeable proxies, use structured storage patterns (like Eternal Storage or unstructured storage proxies) or storage gaps to prevent layout collisions.
  • Access Control: Rigorously guard all functions that can make a delegatecall, especially in proxy fallback() functions.
06

Related Vulnerability: Unchecked Return Values

While delegatecall itself returns a boolean success flag, a critical but separate risk is failing to check it. A low-level delegatecall that fails (returns false) will not revert the outer transaction unless explicitly checked. This can lead to silent failures where state changes in the caller are applied, but the delegated logic was not executed, leaving the contract in an inconsistent state. Always use Solidity's address.delegatecall() or explicitly check the return value.

EVM LOW-LEVEL OPERATIONS

Comparison: Call vs. Delegatecall vs. Staticcall

A technical comparison of the three primary low-level message calls in the Ethereum Virtual Machine, detailing their execution context and state-modifying capabilities.

Feature / BehaviorCallDelegatecallStaticcall

Execution Context (msg.sender)

Original caller

Original caller

Original caller

Execution Context (this / address(this))

Target contract address

Calling contract address

Calling contract address

Can Modify Target Contract State?

Can Modify Calling Contract State?

Can Read Target Contract State?

Gas Forwarded to Target

Specified by caller

Specified by caller

Specified by caller

EVM Opcode

CALL (0xF1)

DELEGATECALL (0xF4)

STATICCALL (0xFA)

Primary Use Case

External interaction, value transfer

Upgradeable proxies, library patterns

View/pure function calls, security checks

DELEGATECALL

Common Misconceptions

The `delegatecall` opcode is a powerful but frequently misunderstood feature of the Ethereum Virtual Machine (EVM). It is the mechanism behind upgradeable contracts and proxy patterns, but its behavior often leads to critical security vulnerabilities when its implications are not fully grasped. This section clarifies the most persistent misconceptions.

No, a delegatecall is fundamentally different from a standard call. A regular call executes code in the context of the target contract, using the target's storage, balance, and msg.sender. In contrast, a delegatecall executes the target contract's code within the context of the calling contract. This means it uses the caller's storage, the caller's balance, and the original msg.sender and msg.value. The primary purpose is to allow a contract to delegate logic execution to another contract while preserving its own state.

solidity
// In a Proxy contract
(bool success, ) = logicContract.delegatecall(
    abi.encodeWithSignature("execute()")
);
// The `execute()` function from logicContract will read/write Proxy's storage.
DELEGATECALL

Technical Deep Dive

Delegatecall is a low-level EVM opcode that enables a smart contract to execute code from another contract while preserving its own storage, `msg.sender`, and `msg.value`. This section explores its mechanics, critical use cases, and inherent security risks.

Delegatecall is an Ethereum Virtual Machine (EVM) opcode that allows a smart contract (the caller) to execute code from another contract (the target) within the caller's own context. Unlike a standard call, delegatecall does not switch the execution context; the target's code runs as if it were part of the caller. This means the target code reads from and writes to the caller's storage, and the original msg.sender and msg.value are preserved. It is the foundational mechanism behind upgradeable proxy patterns and library contracts.

Key Mechanics:

  • Context Preservation: Storage, msg.sender, and msg.value remain those of the original caller contract.
  • No Ether Transfer: The value field in a delegatecall must be zero, as it cannot transfer native Ether.
  • Code Execution: Only the logic from the target contract is used; its state is ignored.
DELEGATECALL

Frequently Asked Questions

Delegatecall is a low-level EVM opcode that enables powerful but complex smart contract interactions. These questions address its core mechanics, use cases, and critical security implications.

Delegatecall is an Ethereum Virtual Machine (EVM) opcode that allows a smart contract to execute code from another contract's logic while preserving its own storage, msg.sender, and msg.value context. Unlike a standard call, which runs the target contract in its own context, delegatecall runs the target's code as if it were part of the calling contract. This enables proxy patterns and upgradeable contracts, where a proxy contract delegates its logic execution to a separate, updateable implementation contract, keeping user data and assets in the proxy's persistent storage.

ENQUIRY

Get In Touch
today.

Our experts will offer a free quote and a 30min call to discuss your project.

NDA Protected
24h Response
Directly to Engineering Team
10+
Protocols Shipped
$20M+
TVL Overall
NDA Protected direct pipeline