Notes / Audits and snapshots

Zcash POOL targets: trusted-setup risk, disclosed as facts, deliberately not scored

Audits and snapshots2026-09-17Chain: Zcash

Source: chains/zcash/data/pool_trusted_setup_disclosure_2026-09-17.md in the repository, rendered here without changes. Source file

METHODOLOGY.md 4.1's own framing for POOL targets (shielded value pools): "No key. Replaced by setup risk: no SRS (Halo 2) scores higher than an MPC SRS (Groth16)." No formula existed for this framing -- this file is the resolution: the facts, cross-checked against the primary source, and an explicit, reasoned decision NOT to turn them into a 0-100 score, rather than leaving the question silently open.

The facts (re-verified against ZIP 224 directly, not just cited from#

METHODOLOGY.md's own summary)

PoolProving systemTrusted setup?Source
SproutGroth16Yes -- a Structured Reference String (SRS) generated by a 6-participant MPC ceremonyZIP 224
SaplingGroth16Yes -- a separate SRS, "around 90 participants per round"ZIP 224
OrchardHalo 2No -- Halo 2 was chosen specifically because it "does not require an SRS"ZIP 224
Ironwood (NU6.3)Halo 2 variantNo -- same no-SRS property, per METHODOLOGY.md 3.3 ("Orchard protocol, new pool")ZIP 258

ZIP 224's own stated security model for the Groth16 ceremonies: "as long as at least one participant was honest and not compromised, the hidden structure is unrecoverable." If the hidden structure (the "toxic waste") were recovered by a colluding or compromised participant, it "could be used to create fake proofs and thus counterfeit funds" in that specific pool.

Why this is NOT turned into a numeric score, unlike every other target#

in this project

Every other score in this project (all 8 ecosystems, all target types scored so far) is derived from a LIVE, RE-CHECKABLE READ: an eth_call, a getAccountInfo, a GetLightdInfo, a NEAR view_access_key_list -- something a reader can re-run today and get the same answer, or an answer that has genuinely changed. The Groth16 ceremonies' security assumption is categorically different: "was at least one of the 6 Sprout participants (or roughly 90 per round of Sapling's) honest and did they actually destroy their share of the toxic waste" is not something any on-chain read, any API call, or any external verification can answer, today or ever. It is an assumption about historical human conduct during a ceremony that already happened, unfalsifiable by construction (a successful attack using recovered toxic waste would look like ordinary counterfeit spends, and the absence of an attack so far is not proof none occurred, only that a sufficiently sophisticated one hasn't been detected or attempted).

Assigning a 0-100 number here -- even a well-reasoned one -- would present a judgment call about unfalsifiable historical trust with the exact same apparent precision and re-checkability as this project's live RPC-derived scores, which would be misleading about what kind of claim it actually is. This is the same discipline already applied elsewhere in this project to similarly unquantifiable-but-real risks: Uniswap's governance-capture facts (chains/ethereum-l1/scorers.py's score_uniswap_v3_factory() docstring) and the LayerZero DVN configuration nuance on the Ethereum L1 OFTAdapters were both disclosed as facts in notes, not folded into a score, for the same underlying reason -- no defensible calibration basis exists, and a plausible-looking fabricated number is worse than an honest gap.

What CAN be said with confidence, and why it still doesn't produce a number#

Recommendation for a future pass, not done here#

If this project ever wants a POOL-type score, the honest path is a BINARY/categorical flag (hasTrustedSetup: true/false) published alongside the existing five dimensions as a sixth, clearly-labeled fact -- not folded into adminKeyScore or any existing dimension, and not expressed as a continuous 0-100 number that implies a precision the underlying question does not have. That is a real design decision (a new field, a contract change) outside the scope of what this pass should decide unilaterally.

Open item not resolved by this file#

Shielded pool VALUE (how much ZEC currently sits in Sprout vs. Sapling vs. Orchard, which determines how much is actually at stake if either ceremony were ever compromised) was not read this pass -- METHODOLOGY.md section 2 already notes "shielded state is not readable without viewing keys" via the lightwalletd interface this project's scripts use; a node-level getblockchaininfo-style valuePools read (a different RPC surface, tracked in consensus per ZIP 209 even though individual shielded transactions stay private) was not attempted this pass.

Not an audit, not investment advice. All notes ยท Back to the dashboard.