Title: feat(contracts): Multi-Sig Treasury and Financing Pool Security
Labels: contracts, security, priority-high
Description:
Large fund movements in the escrow contract currently require
only a single admin signature. For true decentralization and
security, this issue adds a multi-sig requirement for releases
above a configurable threshold, preventing single-point-of-failure
attacks.
What Needs to Be Done:
- Add to contracts/escrow/src/lib.rs:
MultiSigConfig { signers: Vec, min_signers: u32,
large_amount_threshold: i128 }
ReleaseProposal { invoice_id: u64, proposer: Address,
approvals: Vec, proposed_at: u64, expires_at: u64 }
- Functions:
initialize_multisig(admin, signers, min_signers, threshold)
propose_release(signer, invoice_id)
- Only for amounts above threshold
- Starts proposal with 48h expiry
approve_release(signer, invoice_id)
- Additional signers approve
- Cannot approve twice
execute_release(invoice_id)
- Callable after min_signers reached
- Transfers funds to lender
cancel_proposal(admin, invoice_id)
- Admin cancels pending proposal
get_proposal_status(invoice_id) — view
update_threshold(admin, new_threshold) — admin updates limit
- Amounts below threshold: single admin release (existing behavior)
- Amounts above threshold: multi-sig required
- Proposal expires after 48 hours — must re-propose if expired
- Events:
("multisig", "proposed") → { invoice_id, proposer, amount }
("multisig", "approved") → { invoice_id, approver, count }
("multisig", "executed") → { invoice_id, amount, signers }
("multisig", "canceled") → { invoice_id, canceled_by }
("multisig", "expired") → { invoice_id }
Key Files:
- contracts/escrow/src/lib.rs (update)
- contracts/escrow/src/test.rs (update)
Acceptance Criteria:
- Cannot execute with fewer than min_signers approvals
- Same signer cannot approve twice (duplicate check)
- Amounts below threshold still use single admin release
- Expired proposals cannot be executed
- All multi-sig functions protected by require_auth()
- cargo test passes with 95%+ coverage
- Tests cover: propose, approve, execute, duplicate approve,
execute before threshold, expired proposal, cancel,
below-threshold single-sig release
Security Notes:
- Signer list stored in persistent storage — immutable after init
- Admin rotation does not change signer list automatically
- Proposal stores exact expiry timestamp on-chain
Branch: feat/contract-multisig-treasury
Commit: feat(contracts): add multi-sig treasury with configurable threshold and proposal expiry
Title: feat(contracts): Multi-Sig Treasury and Financing Pool Security
Labels: contracts, security, priority-high
Description:
Large fund movements in the escrow contract currently require
only a single admin signature. For true decentralization and
security, this issue adds a multi-sig requirement for releases
above a configurable threshold, preventing single-point-of-failure
attacks.
What Needs to Be Done:
MultiSigConfig { signers: Vec, min_signers: u32,
large_amount_threshold: i128 }
ReleaseProposal { invoice_id: u64, proposer: Address,
approvals: Vec, proposed_at: u64, expires_at: u64 }
initialize_multisig(admin, signers, min_signers, threshold)
propose_release(signer, invoice_id)
approve_release(signer, invoice_id)
execute_release(invoice_id)
cancel_proposal(admin, invoice_id)
get_proposal_status(invoice_id) — view
update_threshold(admin, new_threshold) — admin updates limit
("multisig", "proposed") → { invoice_id, proposer, amount }
("multisig", "approved") → { invoice_id, approver, count }
("multisig", "executed") → { invoice_id, amount, signers }
("multisig", "canceled") → { invoice_id, canceled_by }
("multisig", "expired") → { invoice_id }
Key Files:
Acceptance Criteria:
execute before threshold, expired proposal, cancel,
below-threshold single-sig release
Security Notes:
Branch: feat/contract-multisig-treasury
Commit: feat(contracts): add multi-sig treasury with configurable threshold and proposal expiry