[Feat]: Decide contract upgrade authority: governance (Root) or a wallet
Nobody has claimed this yet.
- Dominant language
- Solidity
- Stars
- 4
- Forks
- 2
- Avg merge
- 1d 18h
- Merged PRs (30d)
- 24
Description
Component
Other
Priority
P1
Summary
Contract upgrades are authorised by _authorizeUpgrade, gated onlyOwner on every UUPS proxy, so a single owner key can replace any implementation and bypass every other control. Before mainnet we need to decide who holds upgrade authority. Two options below; the aim is to pick one and wire it consistently across all upgradeable contracts.
Proposal
Option 1: governance (Root), via originIsRoot().
Gate _authorizeUpgrade on ISystem(SYSTEM_ADDR).originIsRoot(). Only a Root-origin dispatch can upgrade, which on Polkadot Asset Hub means a passed OpenGov referendum. originIsRoot() (the pallet-revive System precompile) reads the transaction-level origin and holds through the UUPS delegatecall frame, unlike callerIsRoot(), which returns false from behind the proxy.
- Decentralised: token holders decide, and there is no admin key.
- Secure: nothing to steal or phish, and upgrades ride the Root referendum track with its confirmation period.
- Cost: no unilateral hotfix. An urgent upgrade runs through a governance track, so we also want a short or emergency track for the worst case (see #205).
- Robust to the Asset Hub Migration: whether OpenGov dispatches locally on Asset Hub or reaches us from the Relay as Root over XCM, the contract sees Root and the gate holds.
Option 2: wallet (keep onlyOwner).
Owner is an account, either an EOA or a multisig. This is today's model; the only change worth making is moving owner to a shared multisig.
- Fast: an upgrade is a single transaction, no referendum.
- Simple: no new precompile dependency, and no track to stand up.
- Weaker: the owner keys are a standing target. A compromised key, or a coerced signer set, can replace any implementation and bypass every other control. A multisig raises the bar but is still a fixed keyholder set, not the token holders.
Recommendation. Option 1 for mainnet, since upgrade is the most dangerous power and it should have no single key behind it. Option 2 with a multisig is a reasonable interim on testnets, or until the Asset Hub Migration lands OpenGov on Polkadot Asset Hub.
Acceptance criteria
- Upgrade authority decided and recorded.
-
_authorizeUpgradeupdated to the chosen authority across every UUPS proxy. - If governance: gated on
originIsRoot(), with a paired fork test proving a Root dispatch can upgrade and a non-root caller cannot. - If wallet: owner set to the agreed account or multisig and documented in DEPLOYMENTS.md.
- Emergency-upgrade path decided and linked (#205).
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by searching all upgradeable contracts for _authorizeUpgrade and reviewing the UUPS proxy setup; also read DEPLOYMENTS.md if the wallet option is chosen. The work is done when one authority is decided and applied consistently, the corresponding Root or wallet fork test passes, and the emergency-upgrade decision is linked to #205.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- solidity
- Domain
- authorization, blockchain
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100