Skip to content

[Governance] Multi-Sig Proposal Expiry, Quorum, Vote Weighting, and Nonce Sync Safety (Issue #18) - #37

Open
Jokay1997 wants to merge 7 commits into
EquipChain:mainfrom
Jokay1997:governance/multisig-enhancements-18
Open

[Governance] Multi-Sig Proposal Expiry, Quorum, Vote Weighting, and Nonce Sync Safety (Issue #18)#37
Jokay1997 wants to merge 7 commits into
EquipChain:mainfrom
Jokay1997:governance/multisig-enhancements-18

Conversation

@Jokay1997

@Jokay1997 Jokay1997 commented Jul 29, 2026

Copy link
Copy Markdown

Summary

Closes #18.

Implements Multi-Sig Proposal Expiry, Quorum Enforcement, Vote Weighting, and Nonce Sync Safety for the EquipChain governance system. This PR hardens the multi-sig decision layer with time-bounded voting windows, participation minimums, flexible vote weighting, and a race-condition fix in the nonce sync module.


Files Changed

File Type Description
\contracts/utility_contracts/src/governance.rs\ ✨ New Full governance module (proposal lifecycle, voting, expiry, quorum, weighting, timelock)
\contracts/utility_contracts/src/nonce_sync.rs\ 🔧 Modified Added \pending_nonce_lock\ to prevent concurrent nonce updates
\contracts/utility_contracts/src/lib.rs\ 🔧 Modified Module declaration, new \DataKey\ variants, new \ContractError\ variants, clippy fix
\contracts/utility_contracts/src/nonce_sync_tests.rs\ 🔧 Modified Fixed missing \Vec/\String\ imports for CI
\contracts/utility_contracts/src/tariff_oracle_tests.rs\ 🔧 Modified Pre-existing CI fix
\contracts/utility_contracts/src/temporary_storage_tests.rs\ 🔧 Modified Pre-existing CI fix

Implementation Details

governance.rs — New Module

Proposal Lifecycle
Draft → Voting → Approved / Rejected → Executed / Expired

  • \create_proposal\ opens a voting window bounded by a configurable \TIMEFRAME\
  • \cast_vote\ records weighted votes and checks expiry atomically
  • \ inalize_proposal\ transitions to \Approved\ or \Rejected\ once voting closes
  • \execute_proposal\ runs after the optional timelock delay
  • \cancel_proposal\ allows the original proposer to retract with a reason string

Proposal Expiry

  • Every proposal has a hard deadline stored on-chain (\expiry_ledger)
  • Votes cast after the deadline are rejected with \ProposalExpired\
  • \ inalize_proposal\ can be called by anyone once the window closes

Quorum Mechanism

  • \min_voters\ must participate before the vote can be finalized regardless of the approval ratio
  • Returns \QuorumNotSatisfied (error 124)\ if the threshold is not met

Vote Weighting

  • \TokenBased: proportional to on-chain token balance
  • \ReputationBased: proportional to reputation score stored in contract state
  • \Equal\ (1-person-1-vote): each eligible signer counts as 1

Timelock

  • Configurable delay (in ledgers) between approval and execution
  • Emergency proposals can bypass the timelock with multi-sig authorization

Proposal Status Query

  • Rich status enum (\Draft | Voting | Approved | Rejected | Executed | Expired | Cancelled) queryable on-chain for governance transparency

once_sync.rs — Race Condition Fix

  • Added \PendingNonceLock(BytesN<32>)\ storage key
  • Lock is acquired at the start of a nonce update and released on success or desync
  • Concurrent update attempts from the same device return \NonceLockActive (error 126)\ immediately instead of silently corrupting nonce state

lib.rs — Registry Updates

New \DataKey\ variants:

  • \GovernanceConfig\
  • \GovernanceProposal(u64)\
  • \GovernanceProposalCounter\
  • \GovernanceVote(u64, Address)\
  • \PendingNonceLock(BytesN<32>)\

New \ContractError\ variants:

  • \QuorumNotSatisfied = 124\
  • \GovernanceDisabled = 125\
  • \NonceLockActive = 126\

CI fix: resolved pre-existing collapsible \if\ clippy warning in the SLA penalty section.


Testing

  • Existing nonce sync tests updated with correct \Vec/\String\ imports
  • All pre-existing CI compilation errors on this branch resolved
  • \cargo check --workspace\ and \cargo test --workspace\ pass

…d Nonce Sync Safety

Closes EquipChain#18 - Multi-Sig Proposal Expiry, Quorum, Vote Weighting, and Nonce Sync Safety

- Add governance.rs module with full proposal lifecycle (create, vote, execute)
- Implement proposal expiry with configurable duration
- Add absolute quorum (min_voters) requirement
- Add vote weighting support (token-based, reputation, 1-person-1-vote)
- Add configurable timelock after approval threshold is reached
- Add cancel_proposal with reason (proposer only)
- Add proposal status query returning detailed status enum
- Fix nonce_sync.rs race condition with pending_nonce lock
- Fix collapsible if in SLA penalty section (pre-existing clippy warning)
Resolve cargo fmt --check failures on both CI jobs (identical root cause
as governance/upgrade-framework-16):
- Collapse env.storage().instance().get(&DataKey::ApprovedTokens) onto one line
  in require_approved_token()
- Wrap env.storage().instance() chains in approve_token() and revoke_token()
  starting at env. per rustfmt chain-call break rules
- Wrap env.storage().instance().set() calls in approve_token() and revoke_token()
- Collapse get_token_info() single-expression body onto one line

All changes are pure formatting; no logic altered.
…edToken, TokenBalanceMismatch)

The require_approved_token() and approve_token() functions introduced in
the Issue EquipChain#23 token whitelist implementation referenced:
  ContractError::UnapprovedToken      = 117
  ContractError::TokenBalanceMismatch = 118

These variants were present in main but dropped from the ContractError
enum on this branch during rebasing. Restores them to fix
cargo clippy --lib failures introduced by this PR.
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.

[Governance] Add Proposal Expiry, Quorum, Vote Weighting, and Nonce Sync Safety to Multi-Sig

2 participants