Skip to content

[NF-06] [CONTRACT] On-Chain Guardian Multisig Contract #81

Closed

Description

@wumibals

Overview

Governance assumes a Guardian Multisig exists to veto Strategist proposals, but no multisig contract exists anywhere in this repository. This issue builds an actual on-chain N-of-M threshold signer contract to fill that role.

Problem

In contracts/governance/src/lib.rs, the Guardian is stored as a single plain Address:

env.storage().instance().set(&DataKey::Guardian, &guardian);
...
guardian.require_auth();

veto() just requires standard auth from whatever address was registered as Guardian at initialize time. The README describes a "4-of-7 multisig" but that threshold/signer-list logic does not exist in this codebase at all — it is assumed to live in some externally-deployed contract supplied as a single Address. There is no way to verify, from this repo alone, that the deployed Guardian address actually enforces a 4-of-7 threshold.

Proposed Solution

  • New contract contracts/guardian_multisig/: stores a fixed set of signers: Vec<Address> and a threshold: u32 (e.g. 4-of-7) at initialize.
  • propose_veto(proposal_id: u32) -> u32 (returns a multisig-internal action id), approve(action_id: u32) (any signer, require_auth), execute_veto(action_id: u32, governance: Address) — once approve count reaches threshold, calls Governance.veto(proposal_id) on behalf of the multisig contract's own address (which is what's registered as Guardian in Governance).
  • Add signers() -> Vec<Address>, threshold() -> u32, approvals(action_id) -> Vec<Address> read-only functions for the frontend signing console.
  • Governance itself needs no changes — it already just calls guardian.require_auth(), which will now correctly route through this new contract's own auth when it calls veto.

Acceptance Criteria

  • Multisig contract enforces that execute_veto only succeeds once approvals reach the configured threshold
  • A single signer cannot approve twice for the same action
  • execute_veto correctly calls Governance.veto(proposal_id) and the veto is reflected in the proposal's status
  • Signer set and threshold are fixed at deployment (no mutation function) unless a separate signer-rotation issue is scoped
  • Unit tests cover: reaching threshold executes the veto, below-threshold does not, duplicate approval from the same signer is rejected

Activity

  1. devwums commented on Jul 16, 2026

    @devwums
    Contributor

    Hello team, i would love to resolve this issue. i have so many free time so i will be dedicated to your project. I am a software engineer and web3 developer. I will surely deliver on this with a quality pr.

  2. grantfox-oss commented on Jul 16, 2026

    @grantfox-oss

    🦊 GrantFox — @devwums has been assigned to this issue as part of the Official Campaign | FWC26 campaign!

    Next steps:

    1. Open a Pull Request referencing this issue (e.g., Closes #81)
    2. Your PR will be reviewed by the LadderMine maintainers

    Good luck! Track your progress on GrantFox.

  3. grantfox-oss commented on Jul 21, 2026

    @grantfox-oss

    🎉 This issue has been marked as completed on GrantFox as part of the Official Campaign | FWC26 campaign!

    @devwums's PR #132 was approved and merged by @wumibals.

    🏆 @devwums: You earned 35 FoxPoints for this contribution! Your current tier: Explorer (834 total points). Track your full progress on GrantFox.

    👏 Great work, @devwums! Keep contributing to LadderMine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions