← Back to blog

Smart Contract Upgrade Patterns: Proxies, UUPS and Beyond

November 9, 2026
Smart Contract Upgrade Patterns: Proxies, UUPS and Beyond

Smart contracts are immutable, so "upgrading" one means changing which code runs behind a stable address, or moving users to a new deployment. The main upgrade patterns are the transparent proxy, UUPS, beacon proxies, diamonds and plain migration. For most business products on Ethereum-compatible chains, a proxy with a multisig and a timelock is the default starting point. Below we explain how each pattern works, where upgrades go wrong, and how to decide what your project needs.

Proud Lion Studios
Plan Your Smart Contract Architecture
Proud Lion Studios develops blockchain solutions, including smart contracts, for startups and enterprises building custom digital products.
Explore Proud Lion Studios

TL;DR

  • Deployed bytecode cannot be edited. Upgradeability works by routing calls through a proxy that keeps the address and state while the logic behind it changes.
  • Transparent proxies keep upgrade logic in the proxy. UUPS keeps it in the implementation, which makes the proxy lighter but adds a lock-out risk if you ship a broken upgrade function.
  • Most upgrade failures come from storage layout mistakes, unprotected initializers and a single powerful admin key, not from the pattern itself.
  • Upgrade authority is a trust decision. Use a multisig, a timelock and published runbooks, and consider immutability for small, single-purpose contracts.
  • If you are commissioning a build in the UAE or GCC, decide the upgrade model before the first line of code, because it shapes architecture, audit scope and cost.

Table of Contents

Why smart contracts need upgrade patterns at all

On Ethereum, deployed contract bytecode at an address cannot be edited. That is a strength when users want guarantees, and a problem when you find a bug, add a feature or need to respond to a changed requirement.

Upgradeability does not mutate that bytecode. Instead, it changes which logic gets executed, usually by sending calls through a stable proxy, while preserving the address and the state. The trade-off is real: you introduce a privileged upgrade authority and a new category of security risk. Every pattern below is a different way of managing that trade-off.

For a founder, the practical question is not "which pattern is coolest" but three simpler ones:

  1. What might need to change after launch, and how often?
  2. Who is allowed to change it, and how will users know?
  3. What does it cost to build, test and audit that flexibility?

The main upgrade patterns at a glance

Ethereum's developer documentation groups the approaches into migration, separating logic and storage, proxies, satellite contracts and diamonds. In practice, teams building production products mostly choose among the following.

PatternWhere upgrade logic livesAddress and state preservedBest fitMain watch-out
Transparent proxyIn the proxy, usually managed by a ProxyAdminYesProducts that want a clear separation between admin and user callsSlightly higher overhead per call
UUPSIn the implementationYesLean deployments, many instances, gas-sensitive productsA broken upgrade function can lock the proxy
Beacon proxyIn a shared beacon pointing to one implementationYes, per proxyMany identical contracts upgraded togetherShared failure domain
Diamond (multi-facet)In a router with several logic modulesYesVery large systems that exceed contract size limitsComplexity in storage and tooling
MigrationNot applicable, new deploymentNo, state is movedCases where trust and simplicity outweigh convenienceUser coordination and gas costs

The sections below explain each one in plain terms.

How the proxy pattern works

The proxy pattern is the most common upgrade approach on Ethereum. Users call the proxy. The proxy's fallback function delegates the call to an implementation contract. Because delegatecall runs the implementation's code in the proxy's own context, the proxy is the contract that holds the storage and the balance.

An upgrade then has three moving parts:

  1. Deploy a new implementation contract.
  2. Change the implementation address stored in the proxy.
  3. Keep using the same proxy address, with the same state, from the user's side.

This is why integrations, wallets and front ends do not need to change addresses after an upgrade. It is also why the question "who can change that implementation address?" becomes the most important security question in the system.

Transparent proxy vs UUPS

These two are the pair most teams compare, so it is worth being precise.

Transparent proxy

In a transparent proxy, upgrade handling lives in the proxy itself, commonly through a ProxyAdmin contract. The design separates administrator calls from user calls, which helps prevent function-selector clashes between the proxy's admin functions and the implementation's functions.

What that means for you: the implementation contract can stay focused on business logic, and a mistake in a new implementation is less likely to remove your ability to upgrade again. The cost is a bigger proxy and a little more overhead on each call.

UUPS

UUPS, defined in ERC-1822, places the upgrade logic in the implementation rather than the proxy. It uses a compatibility check (the proxiableUUID function) and stores the implementation address in a designated slot. The proxy is smaller and cheaper to deploy, which matters when you create many instances.

Transparent proxy and UUPS upgrade comparison

The catch is that the upgrade function is now part of every implementation. As OpenZeppelin's overview of upgrade approaches notes, an implementation that omits the upgrade functions can lock the proxy, and ERC-1822 itself warns that missing upgrade functions can make a proxy unusable. The safeguard is procedural: every new version must be tested specifically to confirm it can still be upgraded, and upgrade permission must be tightly restricted.

Which should you choose?

Both need compatible storage layouts between versions. A reasonable rule of thumb:

  • Choose a transparent proxy when you want the most forgiving operational model, you have a small number of contracts, and your team values a clear admin boundary.
  • Choose UUPS when per-instance deployment cost matters, your team has a disciplined release and testing process, and you will verify upgradeability on every version.

Neither is "safer" in the abstract. The safer one is the one your team can operate without mistakes, and that is a process question as much as a code question.

Beacon proxies and diamonds

A beacon proxy setup centralizes the implementation address in a beacon, so many proxies can be upgraded in a single transaction. That suits products that deploy a contract per user, vault or listing and want them all to move to the same logic together. It also means one bad upgrade affects every instance at once, so the testing and governance bar goes up with the number of proxies.

A diamond splits logic across several modules behind one entry address. It can help when a system outgrows contract size limits or needs to upgrade parts independently. The price is complexity: storage organization, tooling support and audit effort all become heavier. For most startups building a first product, a diamond is more architecture than the problem demands.

Migration and data separation

Not every upgrade needs a proxy. With migration, you deploy a new version, move state and balances across, update integrations and ask users to switch. Ethereum.org lists user coordination and gas costs as its main drawbacks, which is why it suits cases where users are few, well known and reachable, or where the trust model matters more than convenience.

With data separation, logic and storage live in different contracts, so you replace the logic while keeping the storage contract. It avoids delegatecall, but it makes every storage access an external call and adds its own design overhead.

If you maintain data across versions in any system, the discipline is similar to the one in this implementation checklist for data sync: define what the source of truth is, decide how state moves, and verify that nothing is lost in the transition.

Migration and data separation

Storage layout: where most upgrades break

Because the proxy holds the state, the new implementation must read that state exactly as the old one wrote it. Mistakes here corrupt data silently, often with no error at all.

OpenZeppelin explains that naive proxy variables can collide with implementation variables because both use the same storage slots. The fix is unstructured storage: ERC-1967 defines a standardized slot for the implementation address, chosen to avoid collisions with application state.

The upgrade-safety rules from OpenZeppelin's upgrade guidance are short enough to pin on a wall:

  • Never remove, reorder or change the type of an existing state variable.
  • Never insert new variables before existing ones. Append them.
  • Keep the inheritance order compatible between versions.
  • Validate the layout with tooling before every upgrade, not by eye.

Initializers, not constructors

A constructor runs when the implementation is deployed, not when the proxy is set up, so the proxy's state never sees it. Use an initializer function for proxy state, protect it against being called twice, and disable initialization on the implementation contract itself so nobody can take it over directly. OWASP's guidance on proxy and upgradeability vulnerabilities lists initialization, storage collisions, delegatecall context, admin roles and governance among the key risk areas.

Governance: who holds the upgrade key?

An upgradeable contract is only as trustworthy as the party that can upgrade it. A single externally owned account holding that power is a single point of failure, for hacks and for trust.

The common safeguards are:

  • Multisig control. A multisig requires a predefined threshold of owners to approve an action, which reduces dependence on one key.
  • Timelock. A timelock delays approved changes, giving users time to review or exit. Emergency fixes may need a separate, narrowly scoped pause mechanism, because a timelock alone cannot respond instantly.
  • Runbooks. A written upgrade procedure that names who does what, in which order, with which checks.
  • Separated preparation. OpenZeppelin's tooling supports a prepare step that validates and deploys the new implementation separately, so governance only has to approve the final switch.

OWASP's recommendations point the same direction: established proxy libraries, multisig governance, initializer guards, locked implementations, timelocks, upgrade runbooks, storage-layout verification, migration testing and on-chain simulation.

How to test and ship an upgrade safely

A release process that treats upgrades as first-class work looks like this:

  1. Validate storage layout, initializer patterns and unsafe operations with upgrade tooling.
  2. Test V1 to V2 on a fork or testnet: state must survive, behavior must match expectations, and the contract must remain upgradeable afterward.
  3. Rehearse rollback. The TRON developer guide recommends end-to-end testnet upgrades, rollback testing and a separate audit for each implementation.
  4. Prepare the implementation separately from the switch, so reviewers can inspect the exact deployed code.
  5. Execute through the multisig and timelock, then verify state and permissions on-chain.
  6. Monitor after the switch and keep the runbook updated.

These steps overlap with a normal deployment workflow. Our smart contract deployment process guide covers the wider pipeline, and our notes on OWASP-aligned smart contract audits explain what an auditor will look for before you go live.

When you should not make a contract upgradeable

Upgradeability is a design choice, not a default. The TRON guide recommends immutable deployment for small, single-purpose, low-value contracts, for systems that promise censorship resistance, and for projects without trustworthy governance. The Smart Contract Security Field Guide takes a similar view: immutability is often the cleanest security outcome, and upgradeability should be justified by a real need and backed by transparent governance.

A practical way to apply this is to split your system. Keep the core of value custody and fixed rules small and immutable where you can, and put the fast-changing parts, such as fee logic, integrations or reward rules, behind an upgrade mechanism with proper governance. Users then get strong guarantees where they matter and flexibility where you need it.

What this means for UAE and GCC projects

If you are a founder or CTO in the UAE or wider GCC, upgrade design touches several business conversations at once.

  • Regulatory conversations. If your product involves virtual assets in Dubai, VARA (Virtual Assets Regulatory Authority) is the body to engage on whether and how your activity is regulated. Whoever holds upgrade keys, how changes are approved and how users are notified are facts a regulator, a bank or an institutional partner may ask you to explain, so document them from day one. Confirm requirements for your specific activity with VARA and your legal counsel.
  • Investor and partner diligence. Admin keys and upgrade rights are standard questions in technical due diligence. A multisig with a timelock and a published runbook answers them cleanly.
  • Budget. Upgradeable architecture adds design, testing and audit work compared with a fixed contract. It is also cheaper than redeploying and migrating a live product later, so budget for it early.
  • Timeline. Plan separate time for the upgrade rehearsal and review, not just the first deployment.

Our perspective

Most upgrade incidents we hear about in the industry are not exotic. They are an initializer left open, a storage variable inserted in the wrong place, or one key that could do everything. That is why we treat the upgrade model as an architecture decision made at the start, not a patch added before launch.

Our fully UAE-based team designs contracts together with the frontend, the deployment pipeline and the governance setup, because founders do not experience those as separate things. We recommend proxies when a product has a roadmap that will change, immutable cores where users need hard guarantees, and a multisig with a timelock whenever real value is at stake. We also write the upgrade runbook with you, so your team can operate the system after handover.

Our work has been recognized through grants from the Aptos Foundation, and we bring the same tailored approach to Ethereum-compatible chains and beyond: custom designs built around your business outcome, never a template.

Amal

Get a smart contract suite designed for upgrades

Our blockchain development service covers smart contract engineering, frontend integration and delivery, with a smart contract suite with frontend integration available from $20,000 (one-off). Upgrade strategy, storage layout rules and governance setup are part of how we plan a contract suite, tailored to your product rather than copied from a template. You can read more about our smart contract development approach, and our blockchain security essentials guide shows how we think about protecting live systems.

Proud Lion Studios

If you want a second pair of eyes on your architecture before you commit, message us on WhatsApp at +971 54 757 8282.

A short decision checklist

Use this before you brief a development partner:

  • List what must never change (token supply rules, custody logic) and what is likely to change (fees, integrations, reward formulas).
  • Decide who can upgrade, with what threshold, and with what delay.
  • Pick the pattern: transparent proxy for a forgiving admin boundary, UUPS for leaner instances with disciplined testing, beacon for many identical contracts, migration where simplicity and trust win.
  • Require layout validation, V1 to V2 tests and a rollback rehearsal in the scope.
  • Ask for a separate audit for each implementation that goes live.
  • Write down how you will tell users about an upgrade before it happens.

For the wider build, our Web3 smart contract guide and blockchain development guide give the surrounding context.

FAQ

What is the difference between UUPS and a transparent proxy?

A transparent proxy keeps upgrade logic in the proxy and separates admin calls from user calls. UUPS puts the upgrade logic in the implementation, so the proxy is smaller and cheaper. The trade-off is that a UUPS implementation missing its upgrade function can lock the proxy, so every release must be tested for upgradeability.

Can I upgrade a smart contract without changing its address?

Yes, with a proxy pattern. Users and integrations keep calling the same proxy address, and the proxy points to a new implementation. The state stays in the proxy, so the new logic must respect the existing storage layout.

Are upgradeable contracts less secure than immutable ones?

They carry an extra risk: someone holds the power to change the code. That risk is managed with a multisig, a timelock, protected initializers and storage-layout validation. For small, single-purpose contracts where trust guarantees matter most, an immutable deployment can be the better design choice.

What does an upgradeable contract change about cost and timeline?

Expect extra design, testing and audit effort compared with a fixed contract, because each implementation version needs validation. Our smart contract suite with frontend integration starts from $20,000 (one-off), and the final scope depends on your product. A free discovery call is the fastest way to scope it.

Do UAE projects need to disclose who controls upgrades?

Requirements depend on your activity and licensing, so confirm them with VARA (Virtual Assets Regulatory Authority) and your legal counsel. Regardless of regulation, documenting who holds upgrade rights, the approval threshold and the delay is good practice for partners, banks and investors.

Sources

Ready to plan your upgrade strategy with an experienced team? Book a free discovery call or reach us on WhatsApp at +971 54 757 8282.