Skip to content

What is an upgradeable proxy contract?

An upgradeable proxy contract is a fixed address that forwards calls to replaceable logic. EIP-1967 defines the storage slots that hold the logic address.

evmquery team6 min readEthereum, explained, part 12 of 13

What is a proxy contract?

An upgradeable ProxyA proxy is a contract at a fixed address that forwards calls to another contract, which lets the logic be upgraded.See it in the glossaryRead the explainer contract is a front door with a fixed address that forwards every call to replaceable logic. It exists because the code of a Smart contractA smart contract is a program stored at an address on the blockchain that anyone can call and that runs exactly as written.See it in the glossaryRead the explainer cannot be edited after deployment. What is a smart contract covers the basics.

Immutability lets users rely on code that cannot change underneath them, but software has bugs and products need new features. A team can deploy a new contract and ask everyone to move, which is slow. Or it can put a proxy in front and swap the logic behind the same address.

Think of the proxy as a shopfront with a fixed address and a replaceable back office. The shopfront holds the money and the records but cannot do anything itself. For every request it passes the work to the back office, called the ImplementationIn an upgradeable contract, the implementation is the contract holding the actual logic that the proxy forwards calls to.See it in the glossaryRead the explainer.

The mechanism is an Ethereum Virtual Machine (EVMThe EVM, or Ethereum Virtual Machine, is the shared engine that runs smart contract code on Ethereum and many other chains.See it in the glossaryRead the explainer) feature called delegatecall, which runs another contract’s code on the caller’s own storage. The logic lives in the implementation, while balances and records stay in the proxy. An upgrade points the shopfront at a new back office, and the address and balances do not change.

Users always visit the same address, the proxy, which holds the balances and acts as the shopfront. It forwards to the current logic, the implementation. An upgrade replaces back office version 1 with version 2 while the shopfront address and balances stay the same.
Users keep visiting the same address. The upgrade only changes which back office the shopfront forwards to.

What is EIP-1967?

EIP-1967 is a standard that says where a proxy keeps its important addresses. Before it, every project stored the implementation address in a slot of its own choosing. Explorers and WalletA wallet is the app or device that holds your keys and lets you sign transactions and view your assets.See it in the glossary could not reliably find the real code. The standard fixes three storage slots, each derived from a name:

What it holds How the slot is derived Slot
Implementation address keccak256("eip1967.proxy.implementation") - 1 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc
Beacon address keccak256("eip1967.proxy.beacon") - 1 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50
Admin address keccak256("eip1967.proxy.admin") - 1 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103

Hashing a name and subtracting one gives a position no compiler would pick by accident. That avoids a clash between the proxy’s bookkeeping and the implementation’s own variables. Because the slots are identical in every EIP-1967 proxy, a tool can read them without knowing anything else about the contract.

The standard also says a proxy should emit an Upgraded event on every change, so upgrades can be monitored. Not every proxy uses these slots. USDC predates the standard and uses an older OpenZeppelin layout, so its EIP-1967 slot reads as zeros.

Transparent vs UUPS: where does the upgrade function live?

A transparent proxy keeps the upgrade function in the shopfront, and a UUPS proxy keeps it in the back office.

  • Transparent proxy. The shopfront checks who is calling. If the caller is the admin, it handles the call itself, for example an upgrade. Everyone else is forwarded to the implementation. The design is simple to reason about, but every call pays for the extra check.
  • UUPS proxy. The shopfront is as thin as possible. The upgrade function sits in the implementation, so each version of the logic must include it. Calls are cheaper. A new version shipped without an upgrade function cannot be upgraded again.

UUPS comes from ERC-1822, and both patterns store the implementation address in the same EIP-1967 slot. The choice trades a little cost per call against a little risk when upgrading.

Beacon and diamond proxies

A beacon proxy follows a shared pointer, so one change updates every shopfront at once. Each proxy stores the address of a beacon contract instead of the implementation. The beacon holds the current implementation, and the proxy asks it where to forward calls.

This suits products that create many identical contracts, such as one vault per user. Upgrading the beacon upgrades all of them in one transaction. EIP-1967 defines the beacon slot, and a client reads the beacon address first, then calls implementation() on the beacon.

A diamond (EIP-2535) routes each call to one of many modules called facets. The shopfront keeps a directory that maps each function to the room that handles it. A large system can then grow past the size limit of a single contract, and one facet can be replaced without touching the rest. There is no single implementation address to read, so you ask the diamond to list its facets.

Four panels. Transparent proxy: the upgrade switch is kept in the shopfront. UUPS: the upgrade switch is kept in the back office. Beacon proxy: many shopfronts follow one pointer to a single back office. Diamond: one shopfront routes to many back-office rooms.
Same idea, four layouts: the difference is where the upgrade switch sits and how many back offices there are.

What does an upgradeable contract mean for your trust?

If a contract is upgradeable, you trust whoever can upgrade it as well as the code you can read today. The upgrade key can replace the logic, so a safe contract can change tomorrow. Three questions matter:

  • Who holds the key? A single person is a different risk from a group. A multisig wallet requires several people to agree before an upgrade goes through.
  • Is there a timelock? A timelock forces a delay between announcing an upgrade and applying it, which gives users time to leave.
  • Is it announced? Upgrades emit events, so they can be watched, but nothing tells you unless you look.

Upgradeable is not the same as unsafe. Many serious products keep the option so they can patch a live system.

Proxies are common among contracts that hold other people’s money. When we resolved 44 widely used contracts on Ethereum and Base, 11 were proxies, including both USDC deployments, Aave V3 and stETH. USDT, DAI and WETH were not. The full list is in which major contracts are upgradeable proxies.

See it on a real contract

The card asks the Aave V3 Pool proxy for its revision number, which the implementation behind it answers. Resolve the proxy chain of this pool, or of USDC, in the Proxy Contract Detector.

Upgrade number of the code behind Aave's Pool

Reading live from Ethereum

Resolve the Aave Pool proxy in the Proxy Contract Detector

Show the queryformatUnits(pool.POOL_REVISION(), 0)

Common mix-ups

  • “A proxy contract is a warning sign.” It is not. Many serious products use one to patch a live system. What matters is who holds the upgrade key.

  • “An upgrade moves my funds or changes the address.” It does not. The balances stay in the proxy, and only the logic behind it changes.

  • “Verified code cannot change.” For an upgradeable contract it can. Whoever holds the upgrade key can replace the code you read today.

  • “Every proxy keeps its implementation in the same place.” Newer ones follow EIP-1967, but older ones such as USDC use their own layout.

Summary

  • An upgradeable proxy contract keeps one address and its balances while the logic behind it is replaced. Teams can then fix bugs without asking users to move.
  • EIP-1967 fixes where a proxy stores its implementation, admin and beacon addresses. Transparent, UUPS, beacon and diamond proxies differ in where the upgrade function lives and how many logic contracts they use.
  • An upgradeable contract is only as trustworthy as whoever holds its upgrade key. Check who holds it, whether a timelock applies and whether upgrades are announced.

For developers

A call through the proxy address reaches the implementation, so you can read live logic without knowing its address. To get the implementation address itself, see How to get the ABI of an unverified or proxy contract.

Share

See what any contract really runs

Free tier, no credit card. One API call resolves the proxy chain and reads the contract behind it.