### Terms and Conditions
- [x] I agree to the [Grant Agreement](https://9ba4718…c-5c73-47c3-a024-4fc4e5278803.usrfiles.com/ugd/9ba471_f81ef4e4b5f040038350270590eb2e42.pdf) terms if funded
- [x] I agree to [Provide KYC information](https://9ba4718c-5c73-47c3-a024-4fc4e5278803.usrfiles.com/ugd/9ba471_7d9e73d16b584a61bae92282b208efc4.pdf) if funded above $50,000 USD
- [x] I agree to disclose conflicts of interest
- [x] I agree to adhere to the [Code of Conduct](https://forum.zcashcommunity.com/t/zcg-code-of-conduct/41787) and [Communication Guidelines](https://forum.zcashcommunity.com/t/zcg-communication-guidelines/44284)
- [x] I understand all milestone deliverables will be validated and accepted by their intended users or their representatives, who will confirm that the deliverables meet the required quality, functionality, and usability for each user story.
- [x] I agree that for any new open-source software, I will create a `CONTRIBUTING.md` file that reflects the high standards of Zcash development, using the [`librustzcash` style guides](https://github.com/zcash/librustzcash/blob/main/CONTRIBUTING.md#styleguides) as a primary reference.
- [x] I understand when contributing to existing Zcash code, I am required to adhere to the project specific contribution guidelines, paying close attention to any [merge](https://github.com/zcash/librustzcash/blob/main/CONTRIBUTING.md#merge-workflow), [branch](https://github.com/zcash/librustzcash/blob/main/CONTRIBUTING.md#branch-history), [pull request](https://github.com/zcash/librustzcash/blob/main/CONTRIBUTING.md#pull-request-review), and [commit](https://github.com/zcash/librustzcash/blob/main/CONTRIBUTING.md#commit-messages) guidelines as exemplified in the `librustzcash` repository.
- [x] I agree to post request details on the [Community Forum](https://forum.zcashcommunity.com/c/grants/33)
- [x] I understand it is my responsibility to post a link to this issue on the [Zcash Community Forums](https://forum.zcashcommunity.com/c/grants/33) after this application has been submitted so the community can give input. I understand this is required in order for ZCG to discuss and vote on this grant application.
### Application Owners (@Octocat, @Octocat1)
@deucali0n10
### Organization Name
Independent Developer
### How did you learn about Zcash Community Grants
Through the ZCG wishlist ("Audits for updated Zcash software") and the Zcash developer community.
### Requested Grant Amount (USD)
$18.000
### Category
Research & Development
### Project Lead
```project-lead.yaml
Name: Deucalion
Role: Project Lead
Background:Systems engineer working in Rust on consensus-node internals. Practical
experience with mempool transaction handling and admission logic, wire-format
serialization and deserialization, address encoding, chain/genesis state
initialization, and multi-signature schemes. Comfortable reasoning about async
service architecture (Tokio), task scheduling and timeout/cancellation paths —
the specific surface this project makes deterministically testable.
Familiar with the Zcash protocol stack and the Zebra node architecture,
including the mempool download pipeline and ZIP 401 size-limiting policy.
Responsibilities: - Technical direction and deterministic harness architecture
- Adversarial scenario and invariant design
- Finding triage, severity assessment, and coordinated disclosure with the ZF
- Milestone delivery, documentation, and forum reporting
```
### Additional Team Members
```team-members.yaml
None — solo applicant.
```
### Project Summary
An open-source, CI-enforced adversarial resilience harness for Zebra's mempool policy layer. Zebra carries per-fix regression tests for individually disclosed mempool vulnerabilities, but there is no systematic harness that makes timeout- and concurrency-dependent mempool paths deterministically reproducible, nor one that exercises mempool policy under composed, multi-peer, valid-but-malicious load. This project builds that layer, encodes ZIP 401's anti-DoS properties as executable adversarial conformance checks, and extends coverage to the new Ironwood mempool surface.
### Project Description
With zcashd reaching End-of-Support at block 3,417,100 on 18 July 2026, the network now runs on Zebra and Zakura, with Zallet replacing the zcashd wallet. Zebra is the reference implementation that this generation of nodes derives from, which means a mempool policy weakness is present across most of the network's nodes at once and is inherited by downstream forks.
The mempool is a node's most exposed stateful surface: it accepts unconfirmed, fee-competitive transactions from untrusted peers. Zcash addresses mempool denial-of-service at the protocol level in ZIP 401 (cost-based size limiting and weighted-random eviction designed not to be gameable by an adversary), and Zebra implements it (`mempool/storage/policy.rs`, `storage/eviction_list.rs`).
Zebra's security process around this surface is active and mature: mempool denial-of-service issues are found, responsibly disclosed, and patched — for example GHSA-4fc2-h7jh-287c (single-peer inbound queue saturation, patched 4.5.0), GHSA-65jj-fmw8-468q (unbounded memory retention on the mempool download timeout path, patched 4.5.0), GHSA-m9xx-8rcj-vmgp (per-peer admission accounting bypass, patched 6.0.0-rc.0), and GHSA-84j3-rw4c-gqmj (peer-advertised mempool transactions stalling Tokio workers, patched 6.0.0). Zebra also lands per-fix regression tests for these, in-repo — for instance the test explicitly labelled `Regression test for GHSA-m9xx-8rcj-vmgp` in `zebrad/src/components/mempool/downloads/tests.rs`.
Zebra also benefits from an active pipeline of external researchers filing PoC-backed mempool denial-of-service reports (GHSA-4fc2, -m9xx, -84j3, -65jj). This project does not replace that pipeline — it makes its output permanent. Ad-hoc proofs of concept are single-vector and effectively disappear once the fix lands: they are not composed with other attack patterns, they are not re-run as the subsystem evolves, and they do not make the underlying timeout and cancellation paths deterministically testable. We provide the reusable deterministic harness, composed multi-vector scenarios, and a ZIP 401 conformance oracle that turn one-off findings into standing CI coverage — which #10684, a regression on a subsystem that already carried a regression test for a neighbouring path, shows is needed.
The gap this project addresses is therefore not "no testing exists" — it is that per-fix tests and one-off PoCs cover specific reported scenarios, not the adjacent paths of the same subsystem, and there is no deterministic way to exercise timeout- and concurrency-dependent mempool behaviour under composed adversarial load.
Issue #10684 (open, unassigned) is the concrete evidence: the mempool verification-timeout path does not release the per-peer queue slot, so after MAX_INBOUND_CONCURRENCY_PER_PEER (5) timed-out transactions a source stays pinned at the cap and is rejected with `MempoolError::FullQueue`. It is a regression of the GHSA-65jj fix, on the same subsystem that already had a regression test for a neighbouring path.
This project delivers the missing systematic layer: a deterministic simulation harness for the async mempool, a composed adversarial scenario library, a ZIP 401 adversarial-conformance oracle, and coverage of the Ironwood mempool surface — all left behind as permanent, CI-enforced infrastructure.
### Proposed Problem
1. Timeout and concurrency paths are not deterministically testable. Zebra's mempool is an async (Tokio) service; bugs on timeout and cancellation paths — the exact class of GHSA-65jj and #10684 — are difficult to reproduce reliably without controlled time and task scheduling. No such harness exists.
2. Per-fix regression coverage leaves adjacent paths uncovered. #10684 is a regression on the same subsystem that already carried regression tests for a neighbouring path.
3. ZIP 401's anti-DoS properties are not adversarially verified. Zebra implements ZIP 401 and has correctness-oriented property tests for mempool storage, but the specific ZIP 401 guarantee that eviction must not be gameable by an adversary is not exercised under attack.
4. A new, untested surface is arriving. Ironwood (NU6.3) activates at block 3,428,143 around 28 July 2026, introducing new transaction types into the mempool admission path.
5. Honest scope of impact. A mempool denial-of-service cannot cause counterfeiting or a chain split; those are consensus/verification surfaces covered by other funded work. Its impact is node availability (resource exhaustion, degraded or halted transaction admission) and transaction-relay censorship. GHSA-4fc2 demonstrated a single peer denying mempool admission to honest peers. This is availability and censorship-resistance — core Zcash properties — and it is what we scope the project to.
6. ZCG priority alignment. The ZCG wishlist explicitly includes "Audits for updated Zcash software"; continuous adversarial testing is the sustained form of that assurance.
### Proposed Solution
1. Deterministic mempool simulation harness. A controlled environment around Zebra's mempool service using a paused/steerable clock and deterministic task scheduling, so timeout- and cancellation-dependent behaviour reproduces reliably rather than flakily. This is the enabling engineering work.
2. Composed adversarial scenario library. Multi-peer, valid-but-malicious traffic patterns: per-peer slot exhaustion (fake txids, expensive-verification parking), eviction/replacement gameability, fee-based pinning, orphan and dependency-chain abuse, sustained growth toward the cost limit.
3. ZIP 401 adversarial conformance oracle. ZIP 401's cost limit and non-gameable weighted-random eviction expressed as executable properties and checked under adversarial load.
4. Ironwood mempool surface coverage (conditional on upstream API maturity).
5. Permanent CI infrastructure and coordinated disclosure. Everything left in a public repository, runnable by the ZF, Zebra maintainers and future auditors.
### Solution Format
Open-source software (a Rust crate) plus documentation.
Deliverables:
- Rust crate `zebra-mempool-resilience` — standalone crate; deterministic simulation harness, adversarial scenario library, invariant assertions (`proptest` + `arbitrary`, following Zebra's existing property-test conventions).
- ZIP 401 adversarial conformance checks.
- Standing regression coverage for timeout/concurrency mempool classes, beginning with a deterministic reproduction of #10684.
- CI integration — GitHub Actions: per-PR smoke run, scheduled deep runs.
- Adversarial mempool threat model — public document mapping the DoS surfaces and the invariants that must hold (contributes to the open request #9302).
- Security reports — minimal reproduction, severity, reachability; disclosed via the ZF's security policy.
- Documentation — adding scenarios, running locally, interpreting results.
### Dependencies
No dependency on the Zebra core team. All work is based on the public Zebra repository and its existing public APIs. Upstream PRs will be submitted, but upstream merge is a bonus outcome, not a milestone blocker; the crate functions standalone.
Technical dependencies: the Zebra repository (pinned revision), Rust toolchain, `proptest` and `arbitrary` crates, GitHub Actions for CI.
Coordination: findings are disclosed to the Zcash Foundation through its published security policy. No prior commitment from any third party is required to complete the deliverables.
### Technical Approach
Determinism layer. Zebra's mempool download pipeline (`zebrad/src/components/mempool/downloads.rs`) is driven by async tasks with verification timeouts and cancellation. The harness supplies a paused, explicitly advanced clock and controlled task progression so that timeout paths execute in a defined order — turning a class of bugs that is otherwise flaky into deterministic, CI-runnable tests.
Synthetic peer model. Multiple distinct sources with per-source accounting, so per-peer admission limits (MAX_INBOUND_CONCURRENCY_PER_PEER) can be exercised under composed attack patterns rather than single-scenario unit tests.
Invariants asserted (examples):
- A verification timeout always releases the source's per-peer slot.
- Mempool cost stays within the ZIP 401 limit under every generated sequence.
- Eviction cannot be steered by an adversary to systematically remove a targeted fee-paying transaction.
- Mempool state remains internally consistent after eviction (no dangling dependencies).
- A source is never permanently locked out by its own timed-out transactions.
Prioritisation:
- P0: per-peer admission accounting under timeout/cancel; cost-limit growth.
- P1: eviction/replacement gameability; fee-pinning; orphan/dependency abuse.
- P2 (conditional): Ironwood/turnstile transaction load.
Explicit non-goals, to avoid duplicating funded or established work:
- Not input-parsing/crash fuzzing of transactions, blocks, P2P or RPC messages — that is ZCG #234's declared scope.
- Not external synthetic-node network-layer testing — that is Ziggurat's domain; our work is in-process at the mempool policy layer and complements it.
- Not batch-verification soundness — that is ZCG #332.
- Not consensus changes, new features, wallet or accounting functionality, and not a reimplementation of the mempool. We test policy; we do not change it.
### Upstream Merge Opportunities
Repository: ZcashFoundation/zebra.
Planned changes: this project does not fork or modify Zebra's production code. It is developed as a standalone crate (`zebra-mempool-resilience`) that exercises Zebra's existing public APIs.
Potential upstream benefit:
- The crate can be adopted as a Zebra workspace member if maintainers want it in-tree.
- CI workflows follow Zebra's existing GitHub Actions patterns.
- Deterministic reproductions of confirmed issues can be upstreamed as regression tests alongside fixes, in the same style as the existing `Regression test for GHSA-...` tests in `mempool/downloads/tests.rs`.
- The adversarial threat model can inform the open mempool-specification request (#9302).
Coordination: findings are reported through the ZF's coordinated disclosure process. Upstream merge requires maintainer review but is treated as a bonus outcome, not a milestone dependency.
Timeline: upstream PRs offered after each milestone; no milestone is blocked on merge.
### Hardware/Software Costs (USD)
$1500
### Hardware/Software Justification
CI runner time and compute for scheduled deep adversarial runs and long-running resource-growth scenarios, which exceed the limits of standard free-tier CI minutes.
### Service Costs (USD)
0
### Service Costs Justification
No external service providers are required. All research, development, testing, and reporting is performed by the applicant.
### Compensation Costs (USD)
$16500
### Compensation Costs Justification
Eight weeks of focused, full-time engineering by a single developer, covering: the deterministic simulation harness (the principal engineering effort), the adversarial scenario library and invariant framework, ZIP 401 conformance checks, standing regression coverage, CI integration, the threat model document, documentation, and coordinated disclosure.
The scope is deliberately narrow so that it can be delivered intensively rather than spread thin. For comparison on total project cost, ZCG #234 (Zebra coverage-guided fuzzing infrastructure) was funded at $30,000 for a broader input-parsing surface across transactions, blocks, P2P and RPC. This proposal covers a single, deeper, stateful surface and is priced at $18,000 — a lower total cost for a tightly scoped deliverable.
### Total Budget (USD)
$18000
### Previous Funding
No
### Previous Funding Details
No
### Other Funding Sources
No
### Other Funding Sources Details
N/A
### Implementation Risks
- Determinism is the hard part. Making an async mempool reproducible is the principal technical risk. It is scoped as Milestone 1 with an explicit acceptance criterion (deterministic reproduction of #10684) rather than assumed.
- Overlap with existing work. Addressed by explicit non-goals and by scoping to in-process stateful policy behaviour, which is not covered by ZCG #234, ZCG #332, or Ziggurat.
- Upstream churn. Mempool code is under active refactoring; the harness pins to a specific upstream revision and is updated across releases.
- Ironwood maturity. Ironwood mempool APIs are new; that deliverable is conditional on their stability (see milestones).
- Findings may be limited. The value proposition is the permanent harness and conformance oracle, not a guaranteed number of new bugs; milestones are defined by delivered infrastructure, not by findings count.
- Solo delivery risk. As a single-engineer project, scope is kept deliberately narrow and milestones are independently useful, so partial delivery still leaves usable infrastructure behind.
### Potential Side Effects
- Any confirmed denial-of-service finding is handled through the Zcash Foundation's coordinated disclosure process; no exploit detail is published before a fix is available.
- The threat model may document invariants the current implementation does not fully guarantee; these are reported constructively as engineering findings, not as criticism of the maintainers.
- Adversarial CI runs consume compute; runs are scheduled rather than continuous to limit cost and noise.
### Success Metrics
- Deterministic reproduction of #10684 in CI (Milestone 1 acceptance criterion).
- A scenario library covering the P0/P1 surfaces, runnable locally and in CI.
- ZIP 401 cost-limit and eviction-gameability properties asserted under adversarial load.
- Standing CI: per-PR smoke run plus scheduled deep runs, green on a pinned Zebra revision.
- A published adversarial mempool threat model.
- Coordinated disclosure reports for any confirmed findings.
### Startup Funding (USD)
$3000
### Startup Funding Justification
Covers the first two weeks: repository and crate scaffolding, the initial deterministic harness skeleton, and the community forum post. This front-loads the principal technical unknown — async determinism — so it is de-risked before the main milestones begin.
### Milestone Details
```milestones.yaml
- Milestone: 1
Amount (USD): 5000
Expected Completion Date: Week 4
Deliverables:
- Deterministic simulation harness (paused clock, controlled task progression)
- Synthetic multi-peer source model
- Invariant/property framework
- P0 scenarios: per-peer admission accounting under timeout/cancel; cost-limit growth
Acceptance Criteria:
- Issue #10684 reproduced deterministically and repeatably in CI
- Harness runs green on a pinned Zebra revision
- Milestone: 2
Amount (USD): 5000
Expected Completion Date: Week 6
Deliverables:
- P1 adversarial scenario library - eviction/replacement gameability, fee-based pinning, orphan/dependency-chain abuse
- Standing regression coverage for the timeout/concurrency classes
- Coordinated disclosure of any confirmed findings
Acceptance Criteria:
- Each P1 surface has at least one composed multi-peer scenario with asserted invariants
- Regression coverage runs in CI
- Milestone: 3
Amount (USD): 5000
Expected Completion Date: Week 8
Deliverables:
- ZIP 401 adversarial conformance checks (cost limit, eviction gameability)
- Permanent CI integration (per-PR smoke + scheduled deep runs)
- Adversarial mempool threat model document
- Documentation and final report
- Conditional - Ironwood/turnstile mempool-load scenarios
Acceptance Criteria:
- ZIP 401 properties asserted under adversarial load
- Threat model published
- CI green and documented
Notes: 3500 USD fixed for ZIP 401 conformance, CI, threat model and documentation. 1500 USD conditional on Ironwood upstream mempool APIs being stable enough to integrate within the milestone window.
```
### Supporting Documents
```files.yaml
Referenced Zebra issues: #10684 (open, unassigned), #8044 (open, unassigned), #9302 (open)
Referenced advisories: GHSA-4fc2-h7jh-287c, GHSA-65jj-fmw8-468q, GHSA-m9xx-8rcj-vmgp, GHSA-84j3-rw4c-gqmj
Forum post: (to be added after submission)
```