Skip to content

feat: lp pool, SEP-41 lp token, weighted multisig with governed rotation - #151

Merged
dami-005 merged 1 commit into
Zenith-options:mainfrom
Coredevjay:feature/64-65-69-70-lp-pool-token-multisig-rotation-weights
Sep 30, 2026
Merged

dami-005 merged 1 commit into
Zenith-options:mainfrom
Coredevjay:feature/64-65-69-70-lp-pool-token-multisig-rotation-weights

Conversation

@Coredevjay

Copy link
Copy Markdown
Contributor

Summary

  • [High] Weighted Signers in multisig #70 Weighted signers: signers are stored as Map<Address, u32> and threshold is a total weight. New initialize_weighted and get_approval_weight; is_approved compares weight against the threshold. The legacy initialize is kept, with every signer at weight 1. Validation: every weight > 0, overflow-safe sums, threshold ≤ total weight. A single key that can reach quorum alone is allowed but emits a single_key_quorum event (documented policy).
  • [High] Governed Signer Rotation for multisig with Safety Invariants #69 Governed signer rotation: propose_signer_change → queue_signer_change → execute_signer_change, plus veto_signer_change. A change needs rotation_threshold weight, which is always above threshold or equal to unanimity. After approval there is a mandatory rotation_delay, and any single signer can veto until execution. At most one signer is added and one removed per change, and weights can change. Invariants are checked both at proposal and at execution. Approvals are keyed by signer epoch, so a rotation invalidates every outstanding vote in O(1). Events: signer_change_proposed, signer_change_vetoed, signers_rotated. The README rationale section is rewritten.
  • [High] SEP-41 LP Share Token for the Liquidity Pool #65 lp_token: a full SEP-41 token::Interface whose mint is restricted to the pinned lp_pool. Standard events; balances live in persistent storage and allowances in temporary storage with a TTL up to expiration_ledger. The conformance checklist is in docs/lp_token.md.
  • [High] Liquidity Provider Pool That Writes Options on Behalf of Depositors #64 lp_pool: deposits and withdrawals are queued per epoch. A keeper runs write_option on options_market within per-series and utilization caps, and process_epoch only runs once every position has been reclaimed. Share price = (idle + locked − expected liabilities) / shares. First-depositor inflation is blocked by internal accounting, virtual shares and a minimum deposit. The strategy and risk doc is in docs/lp_pool.md.

⚠️ Repository state

main at f95d8d4 (#150) left multisig/src/{lib,types,test}.rs, all of vault/src/{lib,types,events,error,test}.rs, options_market/src/lib.rs and timelock/src/* empty. The multisig source from #149 was also internally inconsistent: it had duplicated fragments and mixed u64 and BytesN<32> ids. This PR restores the multisig from #149, repaired and consistent on BytesN<32> ids, and builds the new features on top. The other gutted crates are out of scope and still fail CI. #150's multisig timelock tiers (is_executable) and __check_auth were never in the committed source, so they are still missing. zenith-common::is_executable has nothing to call until they're rebuilt; the README now says so.

lp_pool calls options_market through invoke_contract against the write_option(writer, series_id, contracts, collateral_amount, min_premium) -> u64 / reclaim_collateral(writer, position_id) ABI from #147, so it doesn't need that crate's wasm to build. It's tested against a mock market that uses real SAC token transfers, with only the keeper's auth mocked.

Closes: #64
Closes: #65
Closes: #69
Closes: #70

Validation

  • multisig: cargo test passes all 78 tests, 26 of them new. cargo clippy --all-targets -D warnings and cargo fmt --check are clean, and the wasm release build succeeds.
  • lp_token: cargo test passes all 15 tests; clippy, fmt and the wasm build are clean.
  • lp_pool: cargo test passes all 14 tests; clippy, fmt and the wasm build are clean.

- multisig: restore source wiped in Zenith-options#150 (from Zenith-options#149, de-duplicated and
  made consistent on BytesN<32> action ids)
- multisig: per-signer weights, initialize_weighted, get_approval_weight;
  legacy initialize keeps equal weights (Zenith-options#70)
- multisig: propose/queue/veto/execute_signer_change with a higher
  rotation threshold, mandatory delay, single-signer veto, invariant
  re-validation and epoch-keyed approvals (Zenith-options#69)
- lp_token: SEP-41 share token, mint restricted to the pinned lp_pool (Zenith-options#65)
- lp_pool: epoch-queued deposits/withdrawals, keeper option writing
  within series and utilization caps, virtual-share inflation defence (Zenith-options#64)
- CI matrices, README and docs updated

Closes: Zenith-options#64
Closes: Zenith-options#65
Closes: Zenith-options#69
Closes: Zenith-options#70
@drips-wave

drips-wave Bot commented Sep 29, 2026

Copy link
Copy Markdown

@Coredevjay 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

@dami-005
dami-005 merged commit 58a0fae into Zenith-options:main Sep 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants