OAK — OnChain Attack Knowledge

Worked example · 2026-06

Zcash Orchard counterfeiting vulnerability — under-constrained halo2 scalar-mul gadget (AI-discovered responsible disclosure) — 2026-05-29 / 2026-06-02

Loss
**no proven realised loss; a latent undetectable, unbounded counterfeiting capability in the Orchard shielded pool, AI-discovered and patched before any known exploitation. Security researcher Taylor Hornby found a missing-constraint (soundness) bug in the Orchard circuit that enabled "undetectable and unbounded (aside from the turnstiles) inflation of ZEC within the Orchard pool" — concretely, the ability to double-spend a shielded note repeatedly, doubling its value each time. A full proof-of-concept (developed with Anthropic Opus 4.8) inflated a regtest wallet's Orchard balance past 10,000,000 ZEC locally, proving exploitability under the exact rules and proof-validation mainnet uses. Because Orchard is privacy-shielded, there is no way to cryptographically prove whether the bug was exploited in the ~4 years it was live; the Zcash Foundation reports no evidence of exploitation and no unauthorised value created, but the property is unprovable by construction. The market priced the uncertainty: ZEC fell ~31% in the first 24h (to ≈$409) and roughly halved peak-to-trough over the episode (≈$600 → ≈$312), and Arthur Hayes publicly announced he exited his entire ZEC position, citing that non-exploitation "cannot be formally cryptographically proved impossible." The realised extraction is bounded only by Zcash's pool turnstiles** (the value-balance limit on what can leave a shielded pool), not by the size of the counterfeit.
OAK Techniques observed
OAK-T9.014 (Protocol-Client Consensus Bug — the canonical anchor. The flaw is in the reference-client consensus code (the halo2 proving-circuit gadget shipped in zcashd / zebra), not in a smart contract; it permits transactions that create value from nothing in violation of the protocol's supply rules; and the fix mechanism was a network-wide emergency soft fork then hard fork (NU6.2), not a contract patch — the exact T9.014 structural signature established by the Bitcoin value-overflow bug and CVE-2018-17144. This case extends T9.014 with a zk-circuit-soundness sub-shape: the inflation surface is an under-constrained zero-knowledge proving circuit, not an integer overflow in a C++ arithmetic check. See techniques/T9.014-protocol-client-consensus-bug.md). OAK-T9.004 (Access-Control Misconfiguration — cross-referenced in the "missing-validation" reading: an under-constrained circuit is a verification predicate that fails to constrain an input it should have constrained, so an arbitrary/false witness is accepted. Same "missing constraint = missing validation" logic OAK applies to proof-verifier cases such as Veil Cash's Groth16 verifier and FOOM Cash. See techniques/T9.004-access-control-misconfiguration.md). OAK-T9 (Smart-Contract / Protocol Exploit parent).
Attribution
unattributed — this is a responsible disclosure with no attacker, not an exploited incident. Discovered 2026-05-29 by Taylor Hornby using his zcash-full-stack-auditor agent framework running Opus 4.8 at max effort; reported the same night over Signal to Daira Emma Hopwood and Kris Nuttycombe, and remediated by the Zcash Open Development Lab (ZODL). The advisory ("The Orchard Counterfeiting Vulnerability — and next steps") was authored by Zooko Wilcox, Jason McGee, and Taylor Hornby (Shielded Labs). Structurally adjacent to OAK's other unexploited-vulnerability anchors (CVE-2018-17144 duplicate-input inflation; ERC-4337 EntryPoint griefing disclosure; Coinbase Smart Wallet pre-launch H-01) — and to Zcash's own 2018/2019 counterfeiting vulnerability (CVE-2019-7167), see Discussion.
Key teaching point
Zcash Orchard is the first AI-discovered consensus-critical zk-circuit-soundness bug in OAK, and the cleanest case of "privacy makes non-exploitation unprovable." Three lessons compound. (1) Circuit soundness is consensus-critical. The supply integrity of a shielded pool rests entirely on the soundness of its proving circuit; a single missing constraint — here, a base point fed into a scalar-multiplication gadget via assign_advice() with no constraint binding it to the real base — silently removes the backing requirement for a crafted witness, and is a supply-inflation bug of the same severity class as a consensus-code integer overflow, fixed by the same hard-fork machinery. (2) Privacy inverts the forensics. On a transparent ledger you can prove after the fact that no inflation occurred (Bitcoin's value-overflow block was identified and reorged); in a shielded pool you cannot — counterfeit-note nullifiers are indistinguishable from real ones, so the residual is permanent uncertainty, which is itself market-moving even with zero proven exploitation. (3) AI changes the discovery economics on both sides. A bug that survived "pretty in-depth audits prior to activation" and four years of expert scrutiny was found by an automated audit agent within ~4 days of the Opus 4.8 model's public release — Hornby's framework running the prior model (Opus 4.7) had not found it without highly specific direction. The defender takeaway is the report's own recommendation: "Balance integrity violation audits should be performed immediately upon the public release of any new AI model" — because attackers will run exactly that audit too.

Summary

Zcash is a privacy coin whose Orchard shielded pool (activated in the NU5 upgrade, 2022-05-31) uses the halo2 (Halo 2 / PLONKish) proving system. Supply integrity inside Orchard depends on the soundness of the Orchard Action circuit: a valid proof must exist only for transactions that conserve value and spend each note exactly once.

On 2026-05-29, Taylor Hornby ran his zcash-full-stack-auditor agent framework — an automated soundness/zero-knowledge audit suite — over the halo2 implementation, including the Orchard circuit, using the just-released Opus 4.8 model at max effort. An audit agent flagged a critical under-constraint in the variable-base scalar-multiplication gadget that could be used to double-spend Orchard notes. Hornby (with Claude) built a proof-of-concept against the real Orchard circuit, then an RPC test that doubled an Orchard note's value repeatedly until a local regtest balance exceeded 10M ZEC — confirming a practically exploitable, unbounded inflation attack (bounded only by Zcash's pool turnstiles). The PoC ran only in local regtest; nothing was broadcast to testnet or mainnet.

He disclosed the same night (2026-05-29, 11:53pm MDT) over Signal to Daira Emma Hopwood and Kris Nuttycombe, delivered a second PoC at 2:06am, and after escalating by phone got ZODL engaged on 2026-05-30. ZODL prepared an emergency soft fork to disable Orchard; the first soft fork failed (a missed p2p DoS-banning rule prematurely banned non-upgraded nodes), and a retry 60 blocks later activated on 2026-06-01 (~9:30pm MDT). Orchard was re-enabled with corrected circuit code at block 3,364,600 (the NU6.2 upgrade, 2026-06-02 ~10pm MDT / 2026-06-03 UTC).

The total window of exposure was 4 years, 1 day, 10 hours (NU5 activation → fix). The window from Opus 4.8's public release to discovery was 4 days, ~10 hours. Because Orchard transactions are shielded, whether the bug was exploited during the four-year window cannot be determined cryptographically; the Zcash Foundation states there is no evidence of exploitation and that user privacy was not affected. The public disclosure (2026-06-05) coincided with a sharp ZEC sell-off and high-profile capitulation.

Vulnerability detail (precise root cause)

The Orchard Action statement enforces diversified-address integrity:

(1) pk_d_old = [ivk] · g_d_old

i.e. the incoming viewing key ivk the prover supplies must be the correct one for the note's address (pk_d, g_d). This is what binds the prover to the note's real ivk — and therefore its real nullifier key nk — so that the nullifier the Action reveals is the spent note's true nullifier, preventing double-spends.

The check [ivk]·g_d is computed by halo2's variable-base scalar-multiplication gadget (halo2_gadgets/src/ecc/chip/mul/incomplete.rs, lines 309–310). For performance, the gadget uses an incomplete point-addition inner loop. The root cause: the base point is handed to the incomplete-addition stage with assign_advice() — which assigns a private witness value without introducing any constraint that the value equals the actual base. A separate constraint (q_mul_2) forces the loop's base values equal to each other, but nothing binds them to the real base g_d.

Consequently a malicious prover has complete freedom to choose the base used in the loop. Given any target (pk_d, g_d, ivk), the prover can solve for the unconstrained base that makes [ivk]·g_d evaluate to pk_d, circumventing check (1) entirely. (Per the writeup, Opus 4.8 derived the required algebra on its own.) With (1) defeated, the attacker can spend a note using a wrong nk, and since nk feeds the nullifier computation, each wrong nk yields a distinct nullifier for the same note — letting them spend it repeatedly, doubling its value each time.

The fix is one-line-shaped: change the first-iteration assign_advice() to copy_advice(), producing a constraint that binds the first base value to the correct base; the existing q_mul_2 then propagates that equality across the loop.

AI-assisted discovery (why this case is a landmark)

  • Found by an automated audit agent within ~4 days of the model's release. Hornby's zcash-full-stack-auditor framework, running Opus 4.8 at max effort, surfaced the under-constraint during a routine soundness sweep that included Orchard in scope.
  • The prior model missed it. Earlier runs of the same framework with Opus 4.7 (xhigh) did not find the bug; 4.7 found it only when narrowly directed ("audit the variable-base scalar-mul gadget for missing constraints that could lead to an inflation/double-spend bug"). On a generic prompt, even Opus 4.8 found it in only ~1 of 4 runs — a small, explicitly non-scientific sample, but a sharp illustration that discovery was probabilistic and prompt-sensitive.
  • The model doubted itself. Opus 4.8 was "extremely skeptical that it had found a real bug," assuming audited upstream code must be correct (or that it was looking at a planted backdoor), and needed prodding to take the finding seriously — a notable failure-mode for AI-assisted audit.
  • Humans had not found it. "Orchard had pretty in-depth audits prior to activation, suggesting the bug was difficult for humans to discover," and it survived four years of public scrutiny.
  • A possible differentiator: the successful run fed the halo2 book into the initialization stage (vs only the protocol spec / ZIPs in prior audits).

Detection / exploitation forensics (the load-bearing asymmetry)

  • The attack leaves no observable on-chain signature: exploitation only sets private circuit inputs, and nullifiers from double-spends are indistinguishable from legitimate nullifiers.
  • The only statistical handle is Orchard transaction arity (actions per transaction) — an attacker might duplicate-then-consolidate notes. Hornby had Claude analyse arity since the Opus 4.8 release; results were inconclusive (an arity-4 anomaly in the window matched a similar month-boundary anomaly a month prior). And because the bug doubles note value, very few actions are needed to accrue a large balance, so even this handle is weak.
  • Eli Ben-Sasson's heuristic (StarkWare; a relevant zk authority) on how to read the uncertainty: if the bug was exploited, the market will likely learn within days, because an attacker rushes the turnstile to surface and cash out shielded value; each day that passes without such a move makes prior exploitation less likely. It is a behavioural bound, not a cryptographic proof — which is precisely the point of the case.

Timeline (MDT unless noted)

When Event OAK ref
2022-05-31 11:50am Vulnerable NU5 upgrade activates; Orchard goes live with the under-constrained scalar-mul gadget (latent T9.014 surface — 4y)
2026-05-28 ~12:00pm Opus 4.8 publicly released (capability shift)
2026-05-29 ~6:00pm Hornby's zcash-full-stack-auditor (Opus 4.8, max effort) audit agent flags a critical Orchard double-spend under-constraint T9.014 discovered
2026-05-29 11:53pm Reported with PoC over Signal to Daira Emma Hopwood & Kris Nuttycombe (responsible disclosure)
2026-05-30 2:06am Second PoC against the real Orchard circuit (multi-nullifier double-spend); recommends emergency disable
2026-05-30 ~6:30am Issue acknowledged by ZODL; RPC PoC inflates regtest balance past 10M ZEC
2026-06-01 ~9:30pm Soft fork disabling Orchard activates (first attempt failed on a p2p DoS-ban rule; retry 60 blocks later succeeds) (containment)
2026-06-02 ~10:00pm Orchard re-enabled at block 3,364,600 with corrected circuit (NU6.2); 2026-06-03 UTC (fix via network upgrade)
2026-06-05 Public advisory; ZEC sells off (~31% in 24h; ≈$600 → ≈$312 peak-to-trough); Arthur Hayes exits his ZEC position (disclosure / market)

Total exposure: 4 years, 1 day, 10 hours. Opus-4.8-release-to-discovery: 4 days, ~10 hours.

What defenders observed / should take away

  • Audit the missing constraints, adversarially. The defect was an assign_advice() that should have been a copy_advice() — a witness assigned with no binding constraint. The report's own long-term recommendation is to enumerate every assign_advice() (and similar) and ask a SAT solver or AI: "can this value be changed to anything other than the honest prover's assignment without violating any constraint?" Under-constraint bugs are invisible to functional testing (valid inputs still produce valid proofs); they surface only under adversarial witness construction.
  • Pre-build a fast "disable the pool" lever. The two-phase soft-fork-to-disable, then hard-fork-to-fix is the model T9.014 response, but the soft fork was a multi-day coordination effort (and the first attempt failed on an unrelated p2p rule). The report recommends a multisig to turn off shielded pools, which "would have reduced the exposure window by days." Protocols with consensus-critical circuits should hold a pre-planned kill-switch.
  • Treat new-AI-model release as a security event. "Balance-integrity-violation audits should be performed immediately upon the public release of any new AI model." A latent bug that humans missed for years became discoverable within days of a model release — which means it became discoverable to adversaries on the same clock. (Mitigating note from the report: the full PoC took ~6 hours to build even after the bug was known, so it is unlikely the miners who privately received the soft-fork patch — which did not include bug details — could have weaponised it before activation.)
  • Shrink the turnstile-bounded blast radius over time. Because realised theft is capped by pool turnstiles, the report recommends spinning up a fresh Orchard-equivalent pool and auto-migrating funds so the turnstile-enforced upper bound on potentially-stolen value decreases over time.

What this example tells contributors writing future Technique pages

  • T9.014 needs a documented zk-circuit-soundness sub-shape. It is mechanically distinct from the integer-overflow (Bitcoin 2010) and duplicate-input (CVE-2018-17144) sub-shapes: the inflation surface is an under-constrained proving circuit, and the audit discipline is constraint-coverage / adversarial-witness review, not integer-bounds checking. Record which sub-shape a new T9.014 case belongs to.
  • Circuit soundness is a consensus bug, not a "smart-contract bug." When a validity/shielded system's supply invariant is enforced by a circuit, a missing constraint is a network-wide unbounded-mint vulnerability fixed by hard fork, not contract upgrade. Map under T9.014 (cross-ref T9.004 for the "missing-validation" reading).
  • Record forensic asymmetry for privacy systems. Note explicitly that exploitation may be cryptographically unprovable and that "no evidence of exploitation" is a weaker assurance than on a transparent chain. Capture behavioural heuristics (Ben-Sasson's turnstile-rush argument) as the only available read on exploitation.
  • Record AI provenance and the model-release clock. This is the first OAK anchor where the discovery capability itself is dated to a model release. Contributors should record the tool/model, whether prior models found it, and that adversaries operate on the same release clock — neutrally, as a fact about how discovery now works (consistent with OAK's Moonwell cbETH AI-co-authored-commit note).

Public references

Discussion

Zcash Orchard joins OAK's protocol-client consensus-bug lineage (examples/2010-08-bitcoin-value-overflow-bug.md and the CVE-2018-17144 pipeline anchor) as its first zero-knowledge sub-shape, its first privacy-coin case, and its first AI-discovered anchor. Where Bitcoin's 2010 bug is the canonical transparent-ledger arithmetic inflation — exploited on mainnet, identified, reorged — Orchard is the canonical shielded-circuit soundness inflation — demonstrated in a regtest PoC, disclosed responsibly, patched by hard fork, but with the defining twist that exploitation can never be proven or disproven. Same structural failure (reference-client validation lets value be created from nothing; fixed by network upgrade), opposite forensic posture (provable vs unprovable).

The sharpest context is that Zcash has been here before. In 2018, cryptographer Ariel Gabizon found a subtle flaw in the BCTV14 zk-SNARK construction underpinning the original (Sprout) shielded pool that also allowed undetectable infinite counterfeiting — a bug "so subtle it evaded years of analysis by expert cryptographers." It was quietly fixed in the Sapling upgrade (2018-10-28) and disclosed only in February 2019 (CVE-2019-7167), again with no evidence of exploitation and no privacy impact. Orchard 2026 is the second occurrence of the same class at the same project: a years-latent soundness flaw in Zcash's shielded-pool proof system enabling infinite counterfeit, fixed-then-disclosed, exploitation unprovable. The recurrence is the lesson — the soundness of a shielded pool's circuit is a perennial, consensus-critical attack surface, and the 2026 instance adds that the discovery side has been transformed: what took an in-house cryptographer's insight in 2018 was surfaced by an automated audit agent within days of a new model's release in 2026. As the report puts it, the unsettling question is not this bug but how many comparable under-constraints still sit in other protocols' circuits — now that the tooling to find them ships to attackers and defenders simultaneously.

Techniques demonstrated (3)