Upgradeable vs Immutable Smart Contracts: How to Choose
Choose between fixed implementation, governed upgrades and migration from product requirements. Use a scenario matrix and permission register to record who can change the system and what remains unavailable.
Key takeaways 4
- Fixed implementation code can still expose mutable parameters and dependencies
- Proxy compatibility does not settle the acceptability of an economic change
- Governance needs available participants and a defined execution process
- Restoring older logic requires analysis of the current state
Choose an upgrade path when the product needs a defined way to change and can support the authority and operating process that change requires. A proxy creates a technical mechanism; it does not decide who may use it or which changes users should accept.
Start with the product matrix below, then record the decision and permissions. These are hypothetical scenarios for architecture planning, not descriptions of Pharos client systems. None establishes that one architecture is always safer or cheaper.
A product decision matrix
| Hypothetical product | Change requirement | Starting architecture to evaluate | Boundary that can change the answer |
|---|---|---|---|
| Short-lived escrow agreements with fixed payout rules | New product versions can use new addresses; active agreements retain their rules | Fixed implementation, with new deployments for future versions | If active agreements must change in place, define consent and authority before considering a proxy |
| Long-lived vault with evolving integrations | Preserve the user-facing address while adding reviewed logic over time | Governed proxy upgrades, with explicit dependency and withdrawal controls | If governance cannot operate the review and approval process, an upgrade mechanism remains an unmanaged privilege |
| Credentials whose verification rules are fixed at issuance | Future cohorts may use different rules; existing credentials retain their meaning | Versioned fixed implementations and a discoverable version register | If a mutable registry can redirect verification, disclose that control even though each implementation is fixed |
The matrix recommends what to investigate first. A vault with an upgrade path still needs a defined treatment of balances and withdrawal rights. A fixed escrow still needs review of its resolver and pause powers. The contract label cannot replace those product decisions.
Fixed code does not mean a fixed product
On Ethereum, deployed code at an address is not rewritten in place. Upgrade patterns change the logic a user reaches, including through a proxy or a new deployment. Ethereum's upgrading documentation explains those distinctions.
A contract with fixed implementation code can still allow an administrator to change fees, pause functions or replace a dependency. Its behavior may also depend on another contract that has its own upgrade authority. Record these controls before calling the product immutable.
For this guide, a fixed implementation means the contract has no mechanism to replace its own execution logic. It does not imply that every stored value is permanent or that every component around it is fixed. A proxy-based product can preserve the user-facing address and state while switching its implementation, subject to the design's actual rules.
Migration is another option: deploy a new version and establish how users, assets or records move to it. The work is product-specific. Do not assume every user can be moved automatically or that every integration will accept a new address.
A filled architecture decision for the escrow example
The cost guide starts with escrow on one EVM network and one approved settlement asset. Here is a decision record for that hypothetical scope.
| Decision field | Recorded answer |
|---|---|
| Product constraint | Payout rules for an existing agreement should remain fixed; future releases may use new addresses |
| Selected starting design | Fixed escrow implementation without a proxy upgrade path |
| Required authority | Defined dispute resolution and pause authority; no general logic-replacement role |
| Upgrade option declined | A proxy is not required to satisfy the stated versioning requirement |
| Recovery limitation | A code defect may require new agreements to use a replacement deployment; an existing obligation cannot be assumed movable |
| Dependency assumption | Only the reviewed settlement asset is supported; its own controls and failure behavior remain part of the risk review |
| Revisit trigger | A documented need to change active agreements or preserve one user-facing address across logic releases |
| Evidence still required | Approved state model, permission tests, dependency review and release acceptance |
This record does not claim that fixed code prevents a defect.
The trade-off is explicit: the project avoids a general upgrade authority and accepts stricter limits on changing active agreements. If the product owner rejects those limits, revisit the requirement and estimate both options.
Do not add a proxy solely because the team might want flexibility later. Describe the future change, who will approve it and how existing users are affected. That description is an input to implementation and independent review.
What a proxy adds to the delivery scope
Proxy-based development needs initialization rules, compatibility review and tests against existing state. OpenZeppelin's guidance on upgradeable contracts describes initialization protections and storage-layout restrictions. A compatible change must be assessed against the actual architecture and versions being used.
Include an upgrade rehearsal in the acceptance plan. Start from representative existing state, apply the proposed change and exercise the behaviors that must remain valid. Check both permitted and rejected callers. Preserve the source versions, compatibility evidence and transaction sequence used for the rehearsal.
A new implementation can preserve storage layout while changing an economic rule users depend on. Technical compatibility therefore does not settle product approval. Review fee changes, payout conditions, permissions and dependency changes as part of the proposal.
Keep the old implementation reference, but do not promise that it can be restored safely. If an upgrade changes how current state is interpreted, returning to old logic requires its own compatibility analysis. The deployment checklist carries the approved architecture and recovery limits into the release runbook.
Record powers, not just wallet names
For an upgradeable vault scenario, a permission register might contain the following proposed controls. The escrow scenario above has no upgrade row because it has no such function.
| Power | Proposed authority boundary | Evidence and question to resolve |
|---|---|---|
| Replace implementation | Governed approval process with reviewed execution inputs | Who can propose, approve, execute and cancel the change? |
| Pause an admitted operation | Separate emergency authority with a defined scope | Can withdrawals remain available, and who can resume the operation? |
| Change an external dependency | Approved controller subject to the product's change policy | Which dependency constraints are enforced and how are users informed? |
| Change governance participants | Documented process for membership and recovery | Can a lost or unavailable participant block required operations? |
Map each power to the deployed mechanism. A multi-signature approval can distribute signing responsibility, but its members still hold authority. A timelock can delay a change; it does not evaluate the change's correctness. OpenZeppelin's access-control documentation also describes availability risks when a self-administered timelock loses the participants required for its workflow.
An advertised delay should match the actual permission path, including any exceptions. Define emergency actions separately and disclose whether they can bypass ordinary controls. Do not assume a pause stops every function or that an upgrade delay guarantees users can exit a product whose withdrawal path has other constraints.
Compare ongoing work before selecting the mechanism
For a governed proxy, budget implementation proposals, compatibility review, acceptance tests, independent review where required and governance execution. Agree who monitors implementation changes and maintains the evidence archive. A reusable upgrade script does not pay for those responsibilities.
For fixed implementations with later migration, budget new deployment review, integration changes, address discovery and any permitted asset or state transition. Explain how old obligations remain accessible. Leaving an old contract deployed is different from maintaining a usable interface and support process for it.
Ask the product owner to approve the change authority and recovery limitation in writing. Use Pharos smart contract architecture and development to turn that decision into scope, tests and handoff requirements. The implementation proposal should identify the selected mechanism, every privileged action and the changes that remain unavailable after launch.
I work with startup founders who need a dedicated software development team but don’t want to gamble on hiring, random outsourcing, or opaque delivery.
Most founders face the same problem sooner or later.
Early technical and team decisions lock the product into tech debt, slow delivery, missed milestones and constant re-hiring. By the time this becomes visible, fixing it is already expensive.As a CTO and software architect, I help founders design, build and run dedicated development teams that work as a true extension of the startup. Not as a black-box vendor.
My focus is on complex products where mistakes are costly:
- Web3 and blockchain platforms
- FinTech and regulated products
- High-load startup systems
- MVP → scale transitions
We don’t do body-shopping.
We don’t sell generic outsourcing.Instead, we help founders:
- build the right team structure from day one
- keep technical ownership and transparency
- scale delivery without losing control
- avoid vendor lock-in and hidden risks
Teams are aligned with the product roadmap, business goals and long-term architecture. Not just short-term velocity.