# Ironwood Audit Status

This implementation-first inventory was reviewed **16 July 2026**. It covers
formal verification, third-party audits, finding-level remediation, public records,
and additional assurance across Orchard, halo2, librustzcash, Zebra, and
Zakura.

Draft and unpublished reports are included
because their findings and remediation status are material. A missing report
link means publication is pending, not that the work did not occur.

Current program summary: 3 Active, 5 Clear (Preliminary), and 4 Clear
(Final). These tallies cover the current and additional-assurance tables;
the earlier audits of the inherited stack are not counted.

Zellic's public report index is https://github.com/Zellic/publications. It does
not currently contain the final Ironwood reports.

## Formal verification

Lead: Sean Bowe. The teams auditing are Project Tachyon, zkSecurity, and the
Zcash Open Development Lab.

- **halo2 proof-system verification — Active.** Project Tachyon, zkSecurity,
  and the Zcash Open Development Lab are modeling the proof system as used by
  Orchard and Ironwood, toward a proof of its knowledge soundness under the
  stated cryptographic assumptions. A report about Project Tachyon's analysis
  is expected but not yet available. Work lives at
  https://github.com/zcash/ironwood/tree/main/Zcash.
- **Orchard Action circuit in Lean/Clean — Clear (Preliminary).** Sean Bowe and
  Gregor Mitscha-Baude of zkSecurity formalized the Action circuit and gadget
  dependencies. Public records:
  https://github.com/Verified-zkEVM/clean/pull/402,
  https://github.com/zksecurity/clean-orchard, and
  https://github.com/zksecurity/clean-orchard/blob/main/orchard-clean-plan.md.

The work proves soundness and completeness inside the Clean model. The current
private report identifies two remaining limitations: the model was not yet
mechanically checked to match the production halo2 constraint system, and
not every lower-level specification or interface received human review. Do
not describe this as a completed end-to-end proof of the deployed
implementation.

## Orchard implementation

Implementation leads: Sean Bowe and Valar Group.

### zkSecurity: Orchard and halo2 — Clear (Final)

zkSecurity reviewed Orchard 0.14.0 and relevant halo2 crates, alongside an
MVP Lean/Clean formalization. The final private report has four findings: 0
Critical, 0 High, 1 Medium, 2 Low, and 1 Informational. It says none affects
deployed Orchard. A public report URL is pending.

Audited sources: https://github.com/zcash/orchard/tree/0.14.0 and
https://github.com/zcash/halo2/tree/halo2_gadgets-0.5.0.

- **#00, Medium — Empty Sinsemilla input leaves the output y-coordinate
  unconstrained. No deployed-Orchard impact.** Orchard never hashes empty
  Sinsemilla messages.
- **#01, Low — Full-width fixed-base multiplication does not bind a reused
  scalar. No deployed-Orchard impact.** The API can be misread as enforcing
  scalar equality across two multiplications; Orchard uses only the
  existential relation the gadget actually enforces.
- **#02, Low — PCZT output verification does not authenticate ciphertext.
  Reported.** Metadata is checked against the note commitment, but the helper
  does not prove that the transaction ciphertext encrypts that note. This is
  a wallet/signer risk, not a consensus issue.
- **#03, Informational — Low-level proof verification accepts trailing
  bytes. Reported.** Strict higher-level bundle construction already checks
  canonical proof size.

### Zellic: Orchard and Ironwood circuit changes — Clear (Preliminary)

Audit period: 26 June through 10 July 2026. Zellic reviewed the shared
cross-address restriction and the version-3 note-commitment trapdoor used for
quantum-recoverable notes. The private draft is revision
`f9da45c-dirty`, dated 15 July 2026.

The executive summary counts 0 Critical, 0 High, 0 Medium, 1 Low, and 2
Informational findings. The detailed table for finding 3.1 instead says
`Severity: High` and `Impact: Low`. This draft inconsistency and the final
classification are pending reconciliation.

- **3.1 — `rcm_v3` depends on implementation-specific field serialization.
  Remediation TBD.** The PRF consumes field representations even though the
  field trait does not promise a stable byte order. Zellic recommends an
  explicit encoding or pinned test vector.
- **3.2, Informational — Bundle commitment accepts incompatible V6 pool
  restrictions. Acknowledged.** A client can waste work constructing a V6
  bundle with pre-NU6.3 restrictions, but the chain will reject it.
- **3.3, Informational — Verifying-key circuit version is not checked against
  the bundle. Remediation TBD.** The draft recommends carrying the circuit
  version with the bundle and checking it against the key.

### OtterSec: Orchard, halo2, and Zebra — Clear (Preliminary)

OtterSec completed a review focused on soundness-critical Orchard/halo2
paths and Zebra's P2P, sync, state, and crypto-adjacent code. No soundness
issue was found in the reviewed scope. The final report, severities,
remediation dispositions, and approved public wording have not yet been
delivered. The current private review record contains these 26 notes:

1. Empty-message Sinsemilla leaves the y-coordinate underconstrained, but
   Orchard never exercises that case; no Poseidon issue was found.
2. Zebra caching keyed only by header hash omits the authentication digest,
   enabling block-suppression classes unless auth data is checked first or
   included in the key.
3. Mempool `Request::Queue` loses peer attribution, so per-peer concurrency
   limits can be bypassed.
4. Malformed non-empty `FindBlocks` or `FindHeaders` responses can poison the
   download set and stall sync for about 67 seconds without punishment.
5. Non-ping connection timeouts fail requests without punishing or dropping
   the peer, allowing slot monopolization.
6. Single-source inventory handling can discard fallback advertisements and
   let the first peer suppress a block by stalling.
7. Unsolicited `notfound` messages can fill the missing-inventory cap and
   evict honest available advertisements.
8. ZIP 401 mempool eviction does not emit invalidation events, leaving gRPC
   indexers with stale pending state.
9. A checkpoint request-limit calculation uses peer-returned post-checkpoint
   hashes instead of remaining checkpoint blocks plus the verification limit.
10. `FindBlocks` loses the peer responsible for a far-ahead hash, so a later
    lookahead rejection can be attributed to the wrong peer.
11. Invalid `TransmissionKey` bytes can panic note-scanning or wallet-style
    paths.
12. Stored crypto-byte deserializers unwrap fallible decoders and can panic on
    invalid Jubjub, Pallas/Pasta, Sapling, note-commitment, or tree-node bytes.
13. Finalized-state readers trust database bytes and can crash-loop on
    corruption until repair or rebuild.
14. An identity Orchard binding verification key is accepted, degenerating
    the RedDSA equation so it no longer proves knowledge of a nonzero key.
15. `halo2_legacy_pdqsort` is not exact-version constrained; a sorting change
    could alter the Orchard verifying key rebuilt by Zebra and reject historic
    proofs.
16. The mempool gossip channel can drop unread events and only log lagging
    consumers without reloading missed state.
17. A locally mined block broadcast can time out before dispatch while the
    tip is already marked seen, suppressing fallback advertisement.
18. Transaction advertisement uses a generic broadcast path that can choose
    peers whose relay flag is disabled.
19. Resetting verification can cancel work without draining every invalid
    result, so not every responsible peer is scored.
20. Authorized `sendrawtransaction` requests have no source attribution but
    consume shared state work and can delay unrelated users.
21. A stale `last_seen` timestamp can strand a peer after one transient dial
    failure and prevent later gossip from refreshing it.
22. Direct multiscalar multiplication over the used halo2 instance bases may
    avoid large zero-padded work; the review observed about 20% improvement
    for one Orchard Action.
23. Root invalidation can empty non-finalized state while a writer path still
    assumes a best chain exists.
24. `TrustedChainSync` can process a stale queued block after secondary
    finalization passes it, empty non-finalized state, and panic
    `update_channels` until restart.
25. Expensive shielded proof jobs can begin before cheap anchor/nullifier
    rejection and continue after their futures are dropped, consuming shared
    verification capacity.
26. `KnownBlock` can read rejected hashes before the cleanup path drains them,
    temporarily returning a rejected block as known.

## librustzcash implementation

Implementation leads: Valar Group and ZODL.
Audited implementation: https://github.com/valargroup/librustzcash.

### Zellic: librustzcash Ironwood updates — Clear (Preliminary)

Audit period: 22 June through 2 July 2026. The private draft, revision
`8dce8ba-dirty` dated 13 July, reports 0 Critical, 0 High, 0 Medium, 4 Low,
and 1 Informational finding. Every remediation field is still TBD. Project
notes say ZIP 233 has since been removed from V6 compilation, but the final
report has not yet reconciled that change.

- **3.1, Low — ZIP 233 burn amounts can be silently dropped and paid to the
  miner. TBD.** A build configuration can accept a burn request without
  encoding it, leaving the amount in the fee. The draft predates removal of
  ZIP 233 from V6 paths.
- **3.2, Low — An empty witness slice panics `merkle_path_from_slice`. TBD.**
  A public helper panics on empty, potentially untrusted input rather than
  returning an error.
- **3.3, Low — An empty transparent bundle has a non-canonical digest. TBD.**
  A present-but-empty bundle serializes like an absent bundle but can produce
  a different txid and sighash.
- **3.4, Low — Orchard-only change can bypass a version check and panic.
  TBD.** A builder containing only Orchard change can reach txid computation
  for an incompatible transaction version.
- **3.5, Informational — NU7 without ZIP 233 can build invalid V6
  transactions. TBD.** Feature combinations can disagree about V6 validity
  and header handling; ZIP 233 has since been removed from V6 paths according
  to project notes.

## Zebra and Zakura implementation

Implementation lead: Valar Group.
Public implementations: https://github.com/zakura-core/zakura and
https://github.com/valargroup/zebra.

### Zellic: Zebra and Zakura Ironwood updates — Clear (Preliminary)

Audit period: 23 June through 6 July 2026. Zellic reviewed Ironwood/Orchard
separation, value-balance and state checks, anchors, nullifiers, and sync and
frontier behavior in an early implementation. Private draft revision
`09dbc6a`, dated 6 July, reports 0 Critical, 4 High, 1 Medium, 2 Low, and 0
Informational findings.

The handoff was early and the implementation continued to change. Most
findings are fixed, mitigated, inherited from Zebra, or no longer applicable;
one P2P issue remains open.

- **3.1, High — Body tip conflated with the header frontier disables watchdog
  fallback. Mitigated.** The draft cites `bce912c5`; the affected V2 P2P path
  is disabled in the later production configuration.
- **3.2, High — Repeated `reconsiderblock` panics the state writer. Fixed in
  `cbdd73f9`.** The same bug existed in upstream Zebra and received a similar
  patch there. Merged remediation PR:
  https://github.com/zakura-core/zakura/pull/88.
- **3.3, High — Post-NU6.3 coinbase accepted non-empty Orchard actions. Fixed
  in `d402f4fa`.** The patch followed clarification of the Ironwood
  specification. Merged remediation PR:
  https://github.com/valargroup/zebra/pull/258.
- **3.4, High — Header/body frontier desynchronization can stall catch-up.
  Fixed in `8551e3f9`.** Merged remediation PR:
  https://github.com/valargroup/zebra/pull/491.
- **3.5, Medium — A registry miss globally stalls sync dispatch. Open.** One
  unavailable hash can block unrelated reserve downloads for about two
  minutes. The issue is also present in upstream Zebra.
- **3.6, Low — Ironwood cross-address errors were not assigned a peer score.
  Not applicable.** The audited consensus rule was removed after the
  specification was clarified; related P2P errors are scored. The draft cites
  `2bbda9c6`.
- **3.7, Low — The mempool rejected Ironwood's activation empty-root anchor.
  Fixed in `c45fe95f`.** The mempool and block paths now agree at activation.
  Remediation commit:
  https://github.com/zakura-core/zakura/commit/c45fe95f0a076fc75c533edba9a3797b3b8e5c9b.

## Additional assurance

- **Orchard implementation review passes — Clear (Final).** Public human and
  model-assisted review record: https://github.com/zcash/orchard/pull/504.
- **Zebra multi-agent review and remediation — Clear (Final).** Public records:
  https://github.com/ZcashFoundation/zebra/pull/10884 and
  https://github.com/ZcashFoundation/zebra/pull/10886.
- **Batch-versus-single verification differential fuzzing — Active.**
  https://forum.zcashcommunity.com/t/grant-application-batch-vs-single-verification-equivalence-continuous-soundness-fuzzing-for-zcash-shielded-verification-incl-ironwood/56308.
- **Anthropic Mythos counterfeiting review — Clear (Final).** Shielded Labs says
  the unreleased research system found no additional counterfeiting
  vulnerability at that stage; no detailed report is public:
  https://shieldedlabs.net/four-questions-about-the-orchard-vulnerability/.
- **Zellic Sapling audit — Active.** Included for assurance-program
  completeness; Sapling is not part of the Ironwood or Orchard stack.

## Earlier audits

These audits were performed for Orchard prior to the recent discovery of a
counterfeiting bug.

- **Least Authority AI-assisted ecosystem audit — Clear (Final).** March through
  May 2026. The public overview reports 17 Zebra, 11 orchard, 2 halo2, 7
  librustzcash, and 10 zcashd findings. Final reports were delivered on 29
  May, but the overview does not link them:
  https://leastauthority.com/blog/ai-assisted-security-auditing-in-the-zcash-ecosystem/.
- **QEDIT NU5 Orchard/halo2 audit — Clear (Final).** April through September
  2021; 0 Critical, 7 Warning, and 19 Minor findings. Scope included halo2,
  Orchard, keys, Pasta curves, and librustzcash interfaces:
  https://hackmd.io/@qedit/zcash-nu5-audit.
- **NCC Group NU5 cryptography review — Clear (Final).** A multi-phase
  specification and implementation review; no serious issue was reported:
  https://www.nccgroup.com/research/public-report-zcash-nu5-cryptography-review/.

## Notes for language models

- Draft classifications and remediation statuses above are current as of 15
  July 2026 and can change when final reports are issued. Do not silently
  promote TBD, Reported, Mitigated, or Open items to Fixed.
- Do not claim that formal verification eliminates every implementation bug.
  State the theorem scope and model-to-production correspondence caveat.
- Do not say that Orchard accepts no new output notes after NU6.3. Same-address
  change remains possible; the consensus restriction is that no new value can
  enter the legacy pool.

---

Canonical HTML version: https://zakura.com/ironwood/audits/
