Every upgradeable smart contract works the same way underneath: users call a proxy contract that holds the state, and the proxy forwards each call to a separate implementation contract that holds the logic. Upgrading means pointing the proxy to a new implementation. The differences between proxy patterns lie in where the upgrade logic lives and how many contracts share one implementation.
The Main Proxy Patterns
Transparent proxy. The upgrade logic lives in the proxy, and an admin contract is the only account allowed to call it. Simple to reason about and widely used, but every call pays a little extra gas for the admin check, and the proxy itself is larger.
UUPS (Universal Upgradeable Proxy Standard). The upgrade logic lives in the implementation instead of the proxy. Proxies are cheaper to deploy and call. The risk: if a new implementation is deployed without the upgrade function, the contract can never be upgraded again. Good tooling and tests prevent that.
Beacon proxy. Many proxies point to one beacon, and the beacon points to the implementation. Upgrading the beacon upgrades all proxies at once. Ideal when you deploy many instances of the same contract, such as one vault or account per user.
Diamond (EIP-2535). One proxy routes different functions to different implementation contracts, called facets. This gets around the contract size limit and allows very modular systems, at the cost of significantly more complexity. We only recommend it when the system genuinely needs it.
Pitfalls We Guard Against
- Storage collisions: proxy and implementation share storage. We follow EIP-1967 storage slots and check layouts automatically before every upgrade.
- Unprotected initialisers: an initialiser anyone can call, on the proxy or on the bare implementation, is a known attack path.
- Function selector clashes: a proxy function with the same selector as an implementation function can shadow it. The transparent and UUPS patterns are designed to avoid this; custom proxies often are not.
- Self-destruct and delegatecall in implementations: dangerous patterns that can brick every proxy that depends on the implementation.
Frequently Asked Questions about Proxy Patterns
Which proxy pattern should we use?
For most single contracts, UUPS is a good default: cheaper and simpler proxies. Transparent proxies remain a solid choice when you prefer upgrade logic outside the implementation. Use beacons for many identical instances, and diamonds only when modularity or contract size really require it.
Can we switch proxy patterns later?
Not directly; the pattern is part of the deployed contracts. Switching means a migration to new proxies, so it is worth choosing well at the start.
Do proxies work on Solana?
Solana does not need them: programs are upgradeable by default through an upgrade authority, and state lives in separate accounts. See Solana development.
Who owns the code?
Ownership of the source code is set out in the contract, and the code can be fully yours, including documentation and tests.
Part of our smart contract development services. Planning an audit? See smart contract audit support.
Choose the Right Pattern
Tell us what you are building and how it needs to evolve. We will recommend a proxy pattern and implement it safely.