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

Upgradeable Proxy

An upgradeable proxy is a smart contract design pattern that separates logic from storage, allowing a contract's code to be updated without changing its address or state.
Chainscore © 2026
definition
BLOCKCHAIN ARCHITECTURE

What is an Upgradeable Proxy?

An upgradeable proxy is a foundational smart contract design pattern that separates a contract's logic from its storage, enabling the deployed code to be updated without migrating state or changing its on-chain address.

An upgradeable proxy is a smart contract architecture where a proxy contract holds all storage (user balances, state variables) and delegates function calls to a separate implementation contract (or logic contract) that contains the executable code. This separation is governed by a delegatecall opcode, which executes the logic contract's code in the context of the proxy's storage. The proxy's address is the permanent, user-facing address of the application, while the address of the implementation contract it points to can be changed by an authorized party, facilitating an upgrade.

The primary mechanism enabling upgrades is a proxy admin or an upgrade function that updates the proxy's stored reference to a new implementation contract. Common patterns include the Transparent Proxy Pattern, which uses an admin to manage upgrades and prevent clashes, and the UUPS (Universal Upgradeable Proxy Standard), where the upgrade logic is built into the implementation contract itself. This design is critical for long-term project maintenance, allowing developers to patch bugs, add features, or optimize gas efficiency after deployment without disrupting the user experience or requiring complex migrations.

While powerful, upgradeability introduces significant considerations. It requires robust access control to secure the upgrade mechanism, often managed by a multi-signature wallet or a decentralized autonomous organization (DAO). Developers must also ensure storage layout compatibility between old and new implementations to prevent catastrophic data corruption. The pattern represents a trade-off between flexibility and decentralization, as it inherently centralizes upgrade authority, which can be a point of contention in trust-minimized environments.

how-it-works
ARCHITECTURE

How an Upgradeable Proxy Works

An upgradeable proxy is a smart contract design pattern that separates a contract's storage and logic, enabling the deployed code to be updated without losing state or changing its on-chain address.

An upgradeable proxy is a smart contract architecture where user interactions are directed to a proxy contract that holds all storage (data), while execution logic is delegated to a separate, mutable implementation contract (also called the logic contract). This is achieved through a low-level delegatecall, which allows the proxy to execute code from the implementation contract's address while using the proxy's own storage context. The proxy's storage contains a critical pointer, often named _implementation, that specifies the current logic contract address. To upgrade, a project's administrator simply updates this pointer to a new, audited implementation contract, instantly changing the contract's behavior for all future calls.

The most common standard for this pattern is the Transparent Proxy, which uses a ProxyAdmin contract to manage upgrades and differentiate between admin and regular user calls, preventing selector clash vulnerabilities. An alternative is the UUPS (Universal Upgradeable Proxy Standard), where the upgrade logic is embedded within the implementation contract itself, making it more gas-efficient. Regardless of the standard, all proxy patterns rely on the same core delegatecall mechanism. This separation ensures that user funds, token balances, and configuration settings stored in the proxy remain intact and permanently associated with the original contract address, even after multiple upgrades.

A critical component for safety is the use of initializer functions instead of constructors. Because a proxy's constructor code runs only once during the logic contract's deployment and not during the proxy's linking, state initialization must be handled by a separate function protected by an initializer modifier to prevent re-initialization attacks. Developers must also carefully manage storage layout; adding, removing, or reordering state variables in a new implementation can corrupt the proxy's existing storage, leading to catastrophic failures. Tools like OpenZeppelin's Upgrades Plugins enforce storage compatibility checks to mitigate this risk.

The primary advantage of this pattern is upgradability, allowing developers to patch bugs, add features, or respond to evolving standards post-deployment. However, it introduces significant trust assumptions and centralization risks, as a malicious or compromised administrator could upgrade the contract to malicious code. To decentralize control, upgrade authority can be transferred to a timelock contract or a decentralized autonomous organization (DAO), introducing a mandatory delay between proposing and executing an upgrade for community review. This pattern is fundamental to many major DeFi protocols and dApps that require long-term evolution while maintaining a consistent interface for users and integrators.

key-components
UPGRADEABLE PROXY

Key Components

An upgradeable proxy is a smart contract design pattern that separates a contract's logic from its storage, enabling the logic to be updated while preserving the contract's address and state.

01

Proxy Contract

The Proxy Contract is the user-facing address that holds the contract's state and storage. It delegates all function calls to a separate Logic Contract using a low-level delegatecall. This design ensures the proxy's address and stored data remain permanent, even when the underlying logic is changed.

02

Logic/Implementation Contract

The Logic Contract (or Implementation) contains the executable code and business logic. It is a standard contract but is never called directly by users. When the proxy delegates a call, it runs the logic contract's code within the proxy's own storage context, allowing for seamless upgrades by pointing the proxy to a new logic contract address.

03

Proxy Admin

The Proxy Admin is a contract (or externally owned account) with exclusive permissions to upgrade the proxy. It controls the critical upgradeTo(address newImplementation) function. This separation of upgrade authority enhances security by isolating the upgrade mechanism from the core logic, often managed via a multisig wallet or DAO governance.

04

Initialization Function

Because constructors don't work with proxies, an initialization function (e.g., initialize()) is used to set up the proxy's initial state. This function acts as a replacement constructor and must include access controls to prevent re-initialization. A common vulnerability is leaving this function unprotected, allowing attackers to hijack the contract.

05

Storage Collisions

A critical consideration in proxy patterns is avoiding storage collisions. Since the proxy and logic contract share the same storage layout, their declared variables must be compatible. Adding, removing, or reordering state variables in a new logic contract can corrupt the proxy's stored data. Using EIP-1967 storage slots is the standard solution to mitigate this risk.

06

Transparent Proxy Pattern

The Transparent Proxy Pattern is a common upgradeability standard (e.g., OpenZeppelin) that routes function calls based on the caller's address. If the caller is the admin, the proxy does not delegate the call, allowing admin functions like upgradeTo to execute. For all other users, calls are delegated to the logic contract. This prevents a potential clash between admin and logic contract functions.

UPGRADEABILITY PATTERNS

Proxy Standard Comparison

A comparison of the primary proxy patterns used for smart contract upgradeability, detailing their architectural approaches, security trade-offs, and implementation complexity.

Feature / MechanismTransparent Proxy (EIP-1967)UUPS (EIP-1822)Beacon Proxy

Upgrade Logic Location

Proxy Admin Contract

Implementation Contract

Beacon Contract

Proxy Bytecode Size

~2.5KB

~1KB

~1.2KB

Gas Overhead per Call

~2.4k gas

~700 gas

~2.2k gas

Implementation Storage Slot

EIP-1967 (specific)

EIP-1967 (specific)

Custom (beacon address)

Admin Privilege Centralization

Single Admin

Implementation Owner

Beacon Owner

Implementation Self-Destruct Risk

Low (Proxy unaffected)

High (Proxy brickable)

High (All proxies brickable)

Common Implementation

@openzeppelin/contracts

@openzeppelin/contracts-upgradeable

Custom / OpenZeppelin

Typical Use Case

General upgradeability

Gas-optimized upgrades

Mass, simultaneous upgrades

key-features
UPGRADEABLE PROXY

Key Features & Benefits

Upgradeable proxies separate a contract's storage and logic, enabling smart contracts to be updated post-deployment while preserving state and address.

01

Transparent Proxy Pattern

A common implementation where a proxy contract delegates all function calls to a separate logic contract using delegatecall. The proxy holds the storage, while the logic contract holds the executable code. An admin can upgrade the proxy to point to a new logic contract address, enabling seamless upgrades.

  • Key Mechanism: Uses delegatecall to execute code in the logic contract's context but store data in the proxy.
  • Admin Role: A designated address controls the upgrade function, a central point of trust and potential failure.
02

UUPS (Universal Upgradeable Proxy Standard)

An upgrade pattern where the upgrade logic is embedded within the logic contract itself, not the proxy. This makes the proxy contract simpler and cheaper to deploy.

  • Efficiency: Reduces gas costs for proxy deployment.
  • Self-Upgrading: The logic contract contains the upgradeTo function, allowing it to authorize its own replacement.
  • ERC-1967 Compliance: Uses a standardized storage slot for the logic contract address, defined by EIP-1967.
03

Preservation of State & Address

The core benefit: user balances, permissions, and all stored data remain intact during an upgrade because storage lives in the immutable proxy. The contract's on-chain address also stays the same.

  • User Experience: Users and integrated applications (wallets, DEXs) continue to interact with the same address.
  • Data Integrity: Critical for protocols with complex state like lending pools or DAOs, where resetting state is impossible.
04

Controlled Governance & Security

Upgrades are typically governed by a timelock and/or a multisig wallet to prevent malicious or erroneous updates. This introduces a critical security model.

  • Timelock: A delay between an upgrade proposal and its execution, allowing users to review code or exit.
  • Multisig: Requires multiple trusted parties to sign off on an upgrade, reducing single-point failure risks.
  • Centralization Trade-off: The upgrade authority represents a trusted element in an otherwise trust-minimized system.
05

Initialization & Constructor Caveat

Constructors in the logic contract are not run on the proxy's storage. Therefore, initialization functions are used, which can be a security risk if not protected.

  • Initializer Pattern: A special function (e.g., initialize()) replaces the constructor to set up initial state.
  • Reentrancy Guard: Must be protected to prevent re-initialization attacks that could reset protocol state or grant admin privileges.
06

Proxy Storage Collisions

A critical risk where the logic contract's variable layout conflicts with the proxy's own reserved storage slots, leading to corrupted state.

  • EIP-1967: Defines specific, pseudo-random storage slots for the logic address and admin address to avoid collisions.
  • Best Practice: Logic contracts should inherit from storage-safe base contracts (like OpenZeppelin's) that use these standardized slots.
security-considerations
UPGRADEABLE PROXY

Security Considerations & Risks

While enabling on-chain upgrades, proxy patterns introduce unique attack vectors and trust assumptions that developers and auditors must rigorously assess.

01

Storage Collision & Initialization

A critical vulnerability where the storage layout of the implementation contract and the proxy contract are mismatched, leading to state corruption. This can be exploited if the proxy's storage variables (like the implementation address) overlap with the logic contract's variables.

  • Mitigation: Use established patterns like EIP-1967 for standardized storage slots.
  • Risk: Malicious upgrades can overwrite critical proxy state, such as the admin address.
02

The `selfdestruct` Vulnerability

If a malicious upgrade sets the implementation contract's code to selfdestruct, the proxy's logic is permanently destroyed, freezing all funds. This is a denial-of-service attack that bricks the contract.

  • Example: The 2017 Parity multi-sig wallet hack, where a vulnerable initialization function allowed an attacker to become the library owner and trigger selfdestruct.
  • Mitigation: Use transparent proxies or UUPS patterns that separate upgrade logic from implementation.
03

Function Clashing in Transparent Proxies

In the Transparent Proxy Pattern, the proxy uses the msg.sender to decide whether to delegate a call to the implementation or handle it locally (e.g., for upgradeTo). If the implementation contract has a function with the same selector as a proxy admin function, it can be called unintentionally.

  • Risk: An admin may accidentally invoke a user-facing function instead of an admin action.
  • Mitigation: Ensure a clear separation of function selectors between proxy admin functions and the implementation's interface.
04

Unchecked Upgrade Authority

The entity controlling the proxy admin (a multi-sig, DAO, or EOA) holds unilateral power to change contract logic. This creates a central point of failure and significant trust assumptions for users.

  • Governance Risk: Compromised admin keys lead to a total breach.
  • Timelock Solution: Implementing a timelock contract between the admin and the proxy forces a delay on upgrades, allowing users to exit.
  • Transparency: All pending upgrades should be publicly verifiable.
05

Implementation Contract Verification

The bytecode at the implementation address must be verified and immutable. If the implementation is itself a proxy or is upgradeable, it creates a complex dependency chain that is difficult to audit and introduces additional attack surfaces.

  • Best Practice: The implementation contract should be deployed, fully verified on block explorers, and then have all ownership/renounce functions disabled to make it immutable.
  • Audit Focus: Ensure no backdoors exist in the implementation's constructor or initialization functions.
06

Frontrunning & Race Conditions

During an upgrade, a malicious actor can monitor the mempool for the upgradeTo transaction and frontrun it with a call that exploits a known vulnerability in the old implementation before the fix is in place.

  • Mitigation: Use a proxy admin contract that atomically upgrades and calls a migration function in a single transaction.
  • Pause Mechanism: Some protocols implement an emergency pause in the proxy to freeze activity during the upgrade window.
ecosystem-usage
UPGRADEABLE PROXY

Ecosystem Usage

An upgradeable proxy is a smart contract architecture that separates a contract's logic from its storage, allowing the logic to be updated while preserving the contract's address and state. This pattern is fundamental for maintaining and evolving decentralized applications.

03

Beacon Proxy Pattern

A pattern for upgrading many identical contracts simultaneously. A single beacon contract holds the current logic address. Many proxy contracts point to this beacon, reading the logic address from it for each call.

  • Key Use Case: Upgrading all instances in a deployed system (e.g., all NFT clones in a factory) with a single beacon update.
  • Efficiency: Saves gas on mass upgrades compared to updating each proxy individually.
  • Example: Used in systems with multiple contract instances like diamond-like facets or ERC-1167 minimal proxies.
05

Governance & Timelocks

Critical security practices for managing proxy upgrades in decentralized protocols. Upgrades are typically controlled by a DAO or multi-signature wallet, not a single admin.

  • Timelock: A delay (e.g., 48 hours) is enforced between proposing and executing an upgrade, allowing users to review code or exit.
  • Process: A governance proposal passes → upgrade is queued in a timelock contract → executed after the delay.
  • Purpose: Mitigates the risk of a malicious or buggy upgrade by introducing a mandatory review period.
06

Storage Layout & Initialization

A major technical challenge in upgradeable contracts. The storage layout (variable positions and types) must remain compatible between old and new logic versions.

  • Golden Rule: Never change the order, type, or remove existing state variables. New variables must be appended.
  • Initializers: Replace constructors with initialize functions to set up initial state, as constructors in logic contracts are not called by proxies.
  • Tooling: Libraries like OpenZeppelin's StorageSlot help manage storage collisions.
storage-layout
CONTRACT ARCHITECTURE

Upgradeable Proxy

A design pattern that separates a smart contract's logic from its persistent data storage, enabling the deployed logic to be updated while preserving the contract's state and address.

An upgradeable proxy is a smart contract architecture that uses the delegatecall opcode to separate a contract's logic from its storage. The system consists of two core components: a Proxy Contract that holds the state (storage) and a Logic Contract (or Implementation) that contains the executable code. When a user interacts with the proxy's address, the proxy delegates the call to the current logic contract, executing its code within the proxy's own storage context. This separation is the fundamental mechanism that allows for upgrades without migrating assets or changing the contract's on-chain identity.

The primary benefit of this pattern is upgradability, allowing developers to fix bugs, patch security vulnerabilities, or introduce new features after deployment. However, it introduces critical considerations for storage layout compatibility. Because the logic contract's code executes in the proxy's storage context, any new version of the logic must maintain the exact same order, types, and positions of state variables. An incompatible storage layout can lead to catastrophic state corruption, where new logic incorrectly reads or overwrites existing data. Tools like storage layout diffing are essential for safe upgrades.

Several standardized implementations exist to manage upgrade permissions and safety. The most common is the Transparent Proxy Pattern, which uses a ProxyAdmin contract to manage upgrades and prevent function selector clashes between the proxy and logic contract. The UUPS (Universal Upgradeable Proxy Standard) pattern moves the upgrade logic into the logic contract itself, making it more gas-efficient. A critical security measure in all patterns is the use of an initializer function instead of a constructor, as constructors do not run in the proxy's context, leaving the storage uninitialized and vulnerable.

UPGRADEABLE PROXY

Frequently Asked Questions (FAQ)

Common questions about smart contract upgradeability, a critical pattern for maintaining and evolving decentralized applications.

An upgradeable proxy is a smart contract design pattern that separates a contract's storage and logic, allowing the code to be updated while preserving the contract's address and state. It works by using a Proxy Contract that delegates all function calls via delegatecall to a separate Implementation Contract (or Logic Contract) which contains the executable code. The proxy holds the state, and a reference to the current implementation address is stored in a designated storage slot. When an upgrade is needed, an Admin (which could be a multisig or DAO) updates the proxy's pointer to a new, audited implementation contract, instantly changing the logic for all future calls without migrating assets or data.

Key Mechanism: delegatecall executes code from the implementation contract in the context of the proxy's storage, ensuring state persistence across upgrades.

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
What is an Upgradeable Proxy? | Blockchain Glossary | ChainScore Glossary