Smart contracts are immutable once deployed, so teams use one of a few patterns to change them: migrate to a new contract, separate data from logic, use a proxy, a strategy pattern, or a diamond. Each trades simplicity for flexibility, and each moves risk onto whoever controls the upgrade.
The approaches
Contract migration. Deploy a new contract, move storage and balances over, update references, and get users and exchanges to switch. ethereum.org calls it straightforward and safe, but slow and gas intensive.
Data separation. A logic contract holds code and points to a separate storage contract. You upgrade by pointing to new logic. It is simpler than migration, but you manage several contracts and more complex authorization.
Proxy pattern. A proxy holds state and uses delegatecall to forward calls to a swappable logic contract. Upgrading changes the logic address. It is popular but more complex, and misuse can cause flaws such as function selector clashes. See upgradeable contract rules.
Strategy pattern. A main contract with core logic calls swappable satellite contracts. Good for minor changes, but it cannot help if the main contract is itself compromised.
Diamond pattern. A proxy maps function selectors to several logic contracts called facets. It allows partial upgrades, helps with the 24KB size limit, and permits permissions scoped to specific functions.
Choosing
| Need | Likely fit |
|---|---|
| Rare change, users can move | Migration |
| Frequent logic fixes, one state | Proxy |
| Large system, partial updates | Diamond |
| Small tweaks to behaviour | Strategy |
If trust matters more than flexibility, consider not upgrading at all and accepting immutability.
The cost of upgradeability
The guide lists real trade-offs. Upgrades weaken the immutability that underpins trustlessness. Users must trust developers not to change contracts arbitrarily. Upgrade logic adds complexity and room for critical flaws. It can also encourage launching before due diligence is done.
Controls to pair with any upgrade path
- Strong access control on the upgrade function.
- Decentralized control, such as a multisig or DAO vote.
- A timelock so users can exit, accepting that it slows emergency patches.
- Monitoring and alerts on upgrade events.
- A tested rollback or pause plan.
Questions to ask about any upgradeable contract
- Who can upgrade, and how many keys are involved?
- Is there a delay, and how long?
- Is the implementation locked against direct initialization?
- Can users see and verify each new implementation?
Safeguard can scan the packages used to build and test contracts and keep an inventory of them. Free scan: gold.safeguard.sh/scan.
Quick check
Is an upgradeable contract less secure than an immutable one?
It adds a trusted party and more complexity. That can be acceptable with strong controls, but it is a different trust model.
Sources
Last reviewed: 19 October 2026.