Skip to content

Add timelocked, quorum-approved WASM upgrade governance - #211

Merged
Obiajulu-gif merged 3 commits into
Chainmove:mainfrom
BigDella:issue-164-governed-wasm-upgrades
Aug 20, 2026
Merged

Add timelocked, quorum-approved WASM upgrade governance#211
Obiajulu-gif merged 3 commits into
Chainmove:mainfrom
BigDella:issue-164-governed-wasm-upgrades

Conversation

@BigDella

Copy link
Copy Markdown
Contributor

What changed

  • add a governance module to the chainmove-pool Soroban contract with proposal, approval, timelock, execution, and cancellation states
  • init_governance bootstraps a static approver set, quorum, and timelock (once only)
  • propose_upgrade requires an approver and an explicit next schema version (current + 1), rejecting skipped/repeated versions before any WASM is touched
  • approve_upgrade collects distinct approvals; an approver cannot approve the same proposal twice
  • execute_upgrade requires quorum to be met, the timelock to have elapsed, and the persisted schema version to still match what the proposal was evaluated against (defense against a stale proposal executing after a different upgrade already moved the schema version on) - only then does it call update_current_contract_wasm and advance the persisted schema version
  • cancel_upgrade lets the proposer or any approver kill a pending proposal; terminal states (Executed/Canceled) reject further approval, execution, or cancellation (no replay)
  • every transition emits an auditable chainmove_gov_v1 event

Why

The design docs call for upgradeable, governed Mainnet contracts, but the Soroban contracts exposed no controlled upgrade path - any deployer key could otherwise redeploy state-incompatible code with no quorum or delay.

Acceptance criteria

  • No single signer can upgrade immediately - proposing only records the proposer's own approval; quorum needs additional distinct approvers.
  • Execution is impossible before quorum and timelock conditions are both met (QuorumNotMet / TimelockNotElapsed).
  • Incompatible or stale schema versions fail before changing the active WASM (IncompatibleSchemaVersion / StaleProposal).

Tests

Added contracts/chainmove-pool/src/governance_test.rs covering: re-init rejection, invalid quorum/duplicate-approver config, authorization (only approvers propose/approve/execute), sequential schema-version enforcement, double-approval rejection, quorum gating, timelock gating, stale-proposal rejection via a simulated concurrent upgrade, cancellation authorization, and replay rejection on terminal proposals.

Validation

  • rustfmt --edition 2021 --check reports no parse errors for the changed files (only pre-existing formatting drift outside this diff, left untouched to keep the diff scoped).
  • cargo test could not link on this machine (link.exe is not a working MSVC linker in this environment - the same limitation noted on the other Soroban-contract PRs in this batch), so the test suite above was validated by careful manual review against the existing test.rs fixture conventions rather than execution. The one gap this leaves: a fully-executed success path (real update_current_contract_wasm swap) needs a second compiled WASM artifact to upload via env.deployer().upload_contract_wasm, which isn't buildable here either - all guard conditions leading up to that call (auth, quorum, timelock, schema checks) are covered instead.

Closes #164

…nance

Adds a governance module to the chainmove-pool Soroban contract:
- init_governance bootstraps a static approver set, quorum, and timelock
- propose_upgrade requires an approver and an explicit next schema version
- approve_upgrade collects distinct approvals, rejecting duplicates
- execute_upgrade requires quorum + elapsed timelock + matching schema
  version at execution time, then calls update_current_contract_wasm and
  advances the persisted schema version
- cancel_upgrade lets the proposer or any approver kill a pending proposal
- every transition emits an auditable event

No single signer can upgrade immediately; execution is impossible before
quorum and timelock conditions are met; an incompatible/stale schema
version fails closed before any WASM is swapped.
@BigDella
BigDella marked this pull request as draft August 18, 2026 13:07
@Obiajulu-gif
Obiajulu-gif marked this pull request as ready for review August 18, 2026 13:15
@Obiajulu-gif

Copy link
Copy Markdown
Collaborator

Hi! This PR currently has a merge conflict with the base branch and can't be merged as-is. Could you please rebase/merge main into your branch and resolve the conflicts? Thanks!

@Obiajulu-gif

Copy link
Copy Markdown
Collaborator

Thanks for this PR! It currently has merge conflicts against main and can't be merged as-is. Could you rebase/merge main into your branch and resolve the conflicts? I'll take another look once it's conflict-free.

…t CI fixes

Resolves conflicts in contracts/chainmove-pool/src/lib.rs: keeps both the
xdr::ToXdr import (idempotency key hashing, from main) and the Vec import
(governance approver lists, from this branch), and renumbers the
ContractError enum so the new RefundTooSmall variant from main (14) and the
governance variants from this branch (previously also starting at 14) no
longer collide. governance.rs references error variants by name only, so
renumbering does not affect its logic.
@Obiajulu-gif

Copy link
Copy Markdown
Collaborator

Reopening to retrigger CI after pushing merge commit with main to pick up TypeScript fixes.

…e#209)

Resolves a second ContractError discriminant collision: main added
InvestmentTooSmall = 15 (from Chainmove#209, merged after our previous sync), which
collided with the governance module's error range that also started at 15.
Shifts the governance variants to start at 16 (GovernanceAlreadyInitialized
through StaleProposal = 26). governance.rs references variants by name only,
so no other changes are needed.
@Obiajulu-gif
Obiajulu-gif merged commit 7e67cd1 into Chainmove:main Aug 20, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[HARD][SOROBAN GOVERNANCE] Add timelocked, quorum-approved WASM upgrades with schema migration guards

2 participants