Skip to content

feat: shared multisig N-of-M approval trait with stake_vault migration#774

Merged
Mathews-25 merged 1 commit into
AgesEmpire:mainfrom
GazzyLee:feat/multisig-approval-trait
Jul 1, 2026
Merged

feat: shared multisig N-of-M approval trait with stake_vault migration#774
Mathews-25 merged 1 commit into
AgesEmpire:mainfrom
GazzyLee:feat/multisig-approval-trait

Conversation

@GazzyLee

Copy link
Copy Markdown
Contributor

Summary

Adds a shared multi-sig N-of-M approval trait (shared/src/multisig.rs) and migrates the stake_vault contract's privileged admin functions to use it. When a MultisigConfig is set, single-admin gated functions (pause, unpause, set_minimum_stake, etc.) return RequiresMultisig and must go through a propose → approve → execute flow with N-of-M signer approvals.

Changes

New file

  • contracts/shared/src/multisig.rs — Shared multisig module with:
    • MultisigConfig (signers, threshold, proposal timeout), Proposal, ProposalStatus types
    • MultisigStorageKey + MultisigError (Soroban #[contracttype])
    • Functions: set_config, validate_config, is_signer, propose, approve, get_proposal, has_approved, require_can_execute, mark_executed
    • Unit tests covering all core paths (threshold execution, expiry, duplicate/unauthorized rejection, idempotent execution)

Modified files

  • contracts/shared/src/lib.rs — Added pub mod multisig + re-exports

  • contracts/stake_vault/src/lib.rs

    • Added mod action with discriminator constants for 6 privileged actions
    • Added encode_action, encode_i128_bytes, decode_i128_from_bytes helpers
    • Added entrypoints: set_multisig_config, propose_action, approve_action, execute_action
    • Migrated pause, unpause, set_minimum_stake, set_minimum_stake_duration, configure_slash_tiers, set_appeal_window — each checks for multisig config and returns RequiresMultisig when configured
    • Added missing StorageKey and StakeVaultError variants referenced by pre-existing code (unblocks compilation)
  • contracts/stake_vault/src/tests.rs — 9 new multisig integration tests (propose→approve→execute flow, error cases)

  • contracts/stake_vault/src/tests_emergency.rs — Fixed .unwrap() on auto-unwrapped Soroban client methods

  • contracts/integration_tests/Cargo.toml — Fixed duplicate [dev-dependencies] section

Test results

  • stake_vault: 92/94 pass (2 pre-existing event assertion failures, unrelated)
  • shared: cargo check passes (test compilation blocked by pre-existing asset_registry.rs issues)

Design

  • Module-based approach (not a trait), consistent with existing pausable.rs pattern
  • Optional<MultisigConfig> storage — None = single-admin fallback, Some = multisig required
  • Actions encoded as Bytes payloads with discriminator byte + data; dispatch by first byte
  • Proposals use Soroban Expirable-style exclusive upper-bound timeout
  • Dedicated MultisigStorageKey enum avoids collision with contract-local StorageKey

Closes #749

@drips-wave

drips-wave Bot commented Jun 30, 2026

Copy link
Copy Markdown

@GazzyLee Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@Mathews-25 Mathews-25 merged commit 0c9cdbb into AgesEmpire:main Jul 1, 2026
1 of 4 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.

common: Implement a shared multi-sig N-of-M admin approval trait

2 participants