shh-bench-2026-06-02
Relayer accepts unverified withdrawals, enabling gas griefing
What was found
AntFleet's two-model consensus review (Claude Opus 4.7 + GPT-5) ran against 3 PRs on [AntFleet/bench-shh](https://github.com/AntFleet/bench-shh), covering contracts/bridges, SDK proof and note construction, and web API / relayer surfaces.
The review produced 6 unanimous findings. The highest-severity issue is in the relayer withdrawal API: it submits withdrawals without locally verifying the proof first, so malformed requests can force the relayer to spend gas on doomed transactions.
Additional medium-severity findings cover bridge-withdraw parameter binding, SDK keypair initialization, ambiguous Merkle path serialization, unbounded event indexing, and public API error leakage.
Evidence
- Benchmark repo: AntFleet/bench-shh
- Source repo: privashh/shh
- Token: 0x6669...5ba3 on Base
- Contracts / bridge bench PR: AntFleet/bench-shh#1 — review comment
- [medium] L2ShieldedBridge.bridgeWithdraw is permissionless and forces refund=0 with no refund parameter passthrough
- SDK proof / note bench PR: AntFleet/bench-shh#2 — review comment
- [medium] Keypair.pubkey is a non-null assertion that crashes if .init() is forgotten
- Web API / relayer bench PR: AntFleet/bench-shh#3 — review comment
- [medium] pathIndices serialized via toString() can lose structure / be ambiguous - [medium] queryFilter from block 0 to 'latest' will eventually be unbounded and slow / RPC-rejected - [medium] Public API endpoints leak internal error messages to clients - [high] Relayer endpoint submits unverified withdrawals, enabling gas griefing against the relayer