Skip to content

[Feature] Implement multi-sig admin approval for high-risk pool actions (emergency_withdraw, pause, remove_member) #181

Description

@Sendi0011

Getting Started

  1. Fork the repository: https://github.com/JointSave-org/Joint_Save
  2. Clone your fork:
git clone https://github.com/<your-username>/Joint_Save.git
cd Joint_Save
  1. Create a new branch:
git checkout -b feat/multisig-admin-controls

Overview

All three pool contracts (Rotational, Target, Flexible) currently require only a single admin signature to execute high-risk actions: emergency_withdraw, pause/unpause, and remove_member. If an admin key is compromised or an admin acts maliciously, there is no check against draining or disrupting a pool holding real funds. The emergency pause infrastructure was added in #168, but it still relies on single-signer trust.

This issue adds a threshold-based multi-sig approval mechanism to these critical actions across all pool contracts, and builds the corresponding frontend UI for managing multi-sig admins and approving pending actions.

Requirements

Smart Contract Changes (all three pool contracts)

  • Add a new storage key admin_quorum storing the set of designated multi-sig admins as a Vec<Address>
  • Add a new storage key pending_approvals mapping a proposed action hash (Bytes) to the list of admins who have approved it
  • Add new functions:
    • set_admin_quorum(admin, new_admins: Vec<Address>) — only callable by the current admin; sets the list of N admins
    • approve_action(admin, action_hash: Bytes) — records an admin's approval for a specific pending action
    • revoke_approval(admin, action_hash: Bytes) — removes an admin's approval before execution
    • execute_approved(action_hash: Bytes, action_data: Vec<u8>) — only succeeds if approvals count >= ceil(N/2) (simple majority), executes the action, then clears the pending record
  • Modify emergency_withdraw, pause/unpause, and remove_member to be callable only via execute_approved when a quorum is configured (i.e., when admin_quorum length > 0); keep single-signer fallback when no quorum is set (for backward compatibility with existing single-admin pools)
  • Add view functions: get_admin_quorum(), get_pending_action(action_hash), get_approval_count(action_hash)

Frontend Changes

  • New component: AdminQuorumManager on the group detail page (admin-only section)
    • Display current quorum members with their Stellar addresses
    • Form to add/remove quorum members (subject to the contract's set_admin_quorum)
    • Show pending actions awaiting approval with an "Approve" button
    • Display approval progress (e.g., "2 of 3 approvals received")
  • New component: PendingActionCard showing each pending multi-sig action with:
    • Action type and parameters (decoded from action_data)
    • List of admins who have approved/revoked
    • Expiry mechanism (pending actions older than 48 hours are automatically expired)
  • Update existing admin action buttons (emergency_withdraw, pause, remove_member) to submit through the multi-sig flow when quorum is configured

Testing

  • Unit tests for the new contract functions (approval counting, quorum threshold, backward compatibility)
  • Integration test: create a pool with 3 admins, set quorum to 2, verify that single admin cannot execute; verify that 2-of-3 approval succeeds
  • Frontend tests for AdminQuorumManager component rendering and interaction

Acceptance Criteria

  • Setting a quorum disables single-signer execution for emergency_withdraw, pause/unpause, and remove_member
  • Without a quorum configured, all actions work exactly as before (backward compatible)
  • execute_approved only succeeds when the threshold is met
  • Pending actions expire after 48 hours and cannot be executed
  • Frontend AdminQuorumManager renders correctly for pools with and without a quorum
  • Frontend correctly shows approval progress and prevents execution below threshold
  • No existing functionality breaks — test the full deposit/withdraw/pause flow after applying changes

Metadata

Metadata

Assignees

Labels

GrantFox OSSIssue tracked in GrantFox OSSMaybe RewardedIssue may be eligible for a GrantFox rewardOfficial CampaignCampaign: Official CampaignOfficial Campaign | FWC26Campaign: Official Campaign | FWC26featureNew functionality to addhigh-complexityLarge scope, multiple systems/files. Needs planning

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions