Skip to content

Upgradeability Model

CenturionUpgradeGovernor is the governance contract. It is not the same thing as roleAdmin.

The governor enforces role gates, target registration, implementation metadata checks, operation hashing, timelock readiness, execution, cancellation, and optional final freeze. roleAdmin is an address stored inside the governor authority model. That address can propose/execute role grants, revoke roles, and transfer role-admin authority.

Two different compromise classes

Compromising governor code means the rules themselves are wrong or bypassed. Compromising the keys that hold roles means valid governor functions can be used maliciously. A correct governor contract does not save the system from weak role custody.

Roles In Current Source

Role Function authority Recommended holder
PROPOSER_ROLE proposeUpgrade Upgrade Operations Safe
QUEUER_ROLE queueUpgrade Upgrade Operations Safe or separate queue Safe
EXECUTOR_ROLE executeUpgrade Upgrade Operations Safe with final pre-execution checklist
CANCELLER_ROLE cancelUpgrade Independent Guardian/Canceller Safe
REGISTRAR_ROLE registerTransparentProxy, registerBeacon, recordGenesisImplementation, sealGenesisApprovals Release/Registrar Safe
FREEZER_ROLE finalFreeze Guardian/Canceller Safe or separate emergency Safe
roleAdmin proposeRoleGrant, executeRoleGrant, cancelRoleGrant, revokeRole, transferRoleAdmin, cancelRoleAdminTransfer Cold high-threshold RoleAdmin Safe

Constructor seeding grants all roles to the initial roleAdmin. Production hardening should then separate roles through the timelocked grant flow and revoke excess authority from broad holders.

Implementation Approval Registry

The governor stores ImplementationApproval records with:

  • contractKind;
  • version;
  • policyHash;
  • codeHash;
  • approved.

recordGenesisImplementation can approve genesis implementations until sealGenesisApprovals. Later executeUpgrade validates implementation metadata and writes the approval record for the executed implementation. assertTransparentProxyPolicy and assertBeaconPolicy prove live target implementations remain registered, kind-matched, policy-matched, and code-hash matched.

Exact Upgrade Lifecycle

  1. Implementation build: produce bytecode, metadata, storage-layout notes, and source commit.
  2. Metadata/policy review: verify contractKind, implementationVersion, and economicPolicyHash match the release plan.
  3. Target registration review: confirm proxy admin or beacon authority is the governor and target kind is correct.
  4. Proposal: PROPOSER_ROLE calls proposeUpgrade with full payload and expected initialized version.
  5. Independent hash reproduction: reviewers recompute hashOperation.
  6. Queue: QUEUER_ROLE calls queueUpgrade; readyAt = block.timestamp + minDelay.
  7. Timelock monitoring: monitors decode operation, inspect implementation code hash, watch role events, and keep guardian cancellation ready.
  8. Execution: EXECUTOR_ROLE calls executeUpgrade only after readyAt and final review.
  9. Post-execution assertions: read live proxy/beacon implementation, policy assertion output, initialized version, and smoke-test behavior.
  10. Evidence archival: store build artifacts, signatures, tx ids, event logs, assertion outputs, and reviewer approvals.

Final Freeze Status

finalFreeze and finalFrozen remain relevant in CenturionUpgradeGovernor. The current source uses them to freeze registered beacons and block paths protected by notFinalFrozen. They are not deposit prerequisites and should not be described as part of a deposit baseline freeze. finalFreeze is an irreversible emergency/end-state action, not routine launch choreography.

Why Not EOAs

EOAs do not provide quorum, signer accountability, recovery policy, or durable organizational custody. A single stolen EOA with EXECUTOR_ROLE, REGISTRAR_ROLE, or roleAdmin authority can cause damage while still using valid governor functions.

Why One Multisig Is Weaker

One multisig controlling all roles can:

  • propose malicious code;
  • queue it;
  • execute it after the delay;
  • register misleading targets or implementations;
  • revoke defenders;
  • cancel only the operations it wants canceled.

Separate roles create independent veto, monitoring, and evidence paths. They do not remove governance risk, but they reduce the blast radius of one signer-set failure.