Skip to content

Solution: LP-0002 — Private M-of-N Multisig (resubmission of #133) - #143

Open
jeefxM wants to merge 4 commits into
logos-co:masterfrom
jeefxM:lp-0002-resubmission-4
Open

Solution: LP-0002 — Private M-of-N Multisig (resubmission of #133)#143
jeefxM wants to merge 4 commits into
logos-co:masterfrom
jeefxM:lp-0002-resubmission-4

Conversation

@jeefxM

@jeefxM jeefxM commented Sep 8, 2026

Copy link
Copy Markdown

Resubmission of #133 (closed on review by @weboko on 2026-09-07) — opened as a new PR only because GitHub refuses to reopen #133 (HTTP 422 on both the web and REST paths); the fork branch behind #133 is left untouched as the record of what was reviewed.

What the review found, and what changed. #133's execute() took the threshold from the caller, never bound the supplied recipient to the proposal, transferred the whole treasury, had no test, and the checklist claimed enforcement anyway. In this revision:

  • CreateProposal freezes threshold, recipient and amount into the ProposalState header (msig_core::ProposalHeader, 124 bytes); Execute { seed } reads them back and releases exactly the frozen amount to the frozen recipient, once (executed flag).
  • The treasury a proposal may spend is derived from the member set it was frozen on (treasury_seed(member_root) = SHA256(TREASURY_DOMAIN || member_root)) and Execute asserts the supplied seed equals it. This closes a second gap found while re-auditing: CreateProposal is permissionless and takes member_root from the caller, so with a program-wide treasury an outsider could have frozen a member set they control and drained the group. Disclosed in Security assumptions and Known limitations.
  • Ten msig_execute_* state tests pin every gate (below threshold, wrong recipient, wrong treasury seed, PDA mismatch, foreign-owned proposal, foreign member set in three shapes, insufficient treasury, second execution, exact-amount release) plus a header-layout test; 24 msig tests green.
  • Both end-to-end scripts submit four deliberately wrong Execute transactions against a funded treasury and fail unless the chain drops each one.
  • Fresh chain-verified 2-of-3 run on the current testnet generation (the testnet was reset on 2026-09-08; the run starts at block 169) with raw JSON-RPC captures under evidence/; three of the four rejected executes return getTransaction → null, the fourth is evidenced by a timestamped state snapshot because it shares its hash with the later release (an Execute has no nonce).
  • ./demo.sh re-verified green at RISC0_DEV_MODE=0 from a fresh checkout of this revision (trace committed).
  • Our contribution is dual-licensed MIT + Apache-2.0 (LICENSE-APACHE, NOTICE), as the terms require.

Repo: https://github.com/jeefxM/lp-0002-private-multisig @ da98a17d5 · CI green on main: https://github.com/jeefxM/lp-0002-private-multisig/actions/runs/34274880779 · Program id 3fNuZskqxs6NZUY4YoenCagQspckdsnjLQi1PUmh2nKa.

Previous rounds: #91 (2026-06), #97 (2026-06, v0.2.0-rc5), #133 (2026-08, v0.2.4). This is the same submission continued, not a new entry.

jeefxM and others added 4 commits August 28, 2026 16:26
Addresses the review of logos-co#97: the demo entrypoint now really runs at
RISC0_DEV_MODE=0 (verified green from a fresh clone with real STARKs), CI is
green on the default branch, and the whole solution is ported to LEZ v0.2.4 with
a fresh chain-verified ledger plus committed raw JSON-RPC captures so the
evidence survives the next testnet wipe.
…ble repo URL, licence

The bot reported 'Checking repo: logos-co/lambda-prize', i.e. it never extracted
our repository link, so every 'missing in linked repo' error cascaded from that:
the Repo line was inline code rather than a URL. Also renamed two headings to the
template's exact wording (## Repository, ## Success Criteria Checklist) and added
the licence (MIT, inherited from the upstream LEZ fork) plus explicit pointers to
demo.sh, the SPEL IDL and basecamp/module.json.
The validator pipes the solution file into grep -qF per required section. grep -q
exits at the first match and closes the pipe, so on a large file the feeding echo
dies with SIGPIPE and the check misreads as 'section missing' -- visible in the
job log as 'line 158: echo: write error: Broken pipe', and it hit exactly the
three earliest sections (Summary/Repository/Approach at lines 37/80/141) while
the later ones passed.

The 50 KB file was also simply too long for a submission entry; passing
submissions are 18-27 KB. This keeps Summary, Repository, a condensed Approach
(with why-Logos and the alternatives//what-failed narrative), the success-criteria
checklist, the FURPS assessment and Terms, and points at
docs/LP-0002-solution.md in the linked repo for the full technical write-up.
Verified against the validator's exact checks locally before pushing.
… its member set

Execute takes nothing from the caller: threshold, recipient and amount are
frozen at CreateProposal and the treasury is derived from the frozen member
root. Ten release-gate tests, four rejected executes on-chain, fresh
chain-verified 2-of-3 ledger on the current testnet generation, real-STARK
demo re-verified, contribution dual-licensed MIT + Apache-2.0.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown

✅ Validation passed

A reviewer will assess against the prize criteria.
ℹ️ Solution submission for LP-0002.
ℹ️ Checking repo: https://github.com/jeefxM/lp-0002-private-multisig


Automated check. See solution template and TERMS.

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.

2 participants