Scope: contracts/src/TreasureHunt.sol, circuits/src/main.nr
TreasureHunt.claim(bytes proof, bytes32 treasureHash, address payable recipient) verifies the proof against public inputs (treasureHash, recipient) only. msg.sender is NOT part of the proof's public inputs, nor is it otherwise bound into the statement the ZK circuit proves.
Consequence: once Alice broadcasts a valid (proof, hash, Bob) transaction to the mempool, any third party Eve who observes it can copy the exact calldata verbatim and submit the same proof with a higher gas price from her own EOA. Eve's tx lands first; the contract:
Verifies the proof successfully (public inputs unchanged).
Distributes REWARD to Bob (the bound recipient — NOT to Eve).
In the post-fix world (i.e., after Finding 1's double-claim bug is patched), this marks the treasure as claimed, so Alice's subsequent tx reverts with AlreadyClaimed.
Note: under the CURRENT code, Finding 1 masks this — both tx's succeed because the duplicate-claim check reads claimed[_treasureHash] (always 0). So the front-run finding becomes materially relevant after Finding 1 is fixed, which any reviewer would presumably do.
Likelihood: MEDIUM (in the post-fix world)
Mempool sniping is a routine pattern; it only requires a public-chain mempool observer with non-trivial gas-budget tolerance.
Alice has no cryptographic or economic defense on this contract — she can't choose a msg.sender-bound proof because the circuit doesn't accept one.
Impact: LOW
Eve cannot steal ETH: the payout still goes to Bob (the recipient bound into the proof). Bob is typically under Alice's control, so her ECONOMIC position is unharmed.
Eve burns gas for herself to grief Alice, consuming the claim slot. This is a denial-of-service griefing vector: Alice wasted gas on a reverting tx, and Bob still gets paid, but Alice experiences a failed UX. Cumulative griefing across 10 claims increases the attacker's gas cost but does nothing beneficial for them.
In pathological cases (e.g., a finder who needs to claim quickly before the contract drains due to some other issue, or before the hunt's time window expires), griefing can cause the finder to lose their chance entirely.
Bind msg.sender to the proof's public inputs. This requires updating both the circuit and the contract, and regenerating the verifier fixtures:
This pins the proof to a specific claim-submitting address. Mempool sniping is no longer profitable because a sniped copy would fail verification (the submitter public input doesn't match Eve's msg.sender).
Alternatively, EIP-2930 / EIP-7702 account abstraction flows could be used so claims don't hit the public mempool at all.
This finding was identified and written up with the assistance of an autonomous AI auditor (Anthropic Claude) — surfaced during the Claude + GPT brainstorm review of the initial 6-finding batch. The finding is filed separately from Finding 1 because Finding 1's fix is prerequisite for this one to be materially exploitable on-chain.
The claim that the proof system is broken because the recipient is not explicitly constrained in the Noir circuit reflects a misunderstanding of how zero-knowledge proofs bind public inputs. Although the circuit does not impose algebraic constraints on recipient, the value is still included in the public input vector, which is cryptographically committed to during proof generation. As a result, the proof is only valid for the exact tuple of public inputs it was created with. Any attempt by an attacker to front-run and substitute a different recipient would alter this tuple, causing the verifier’s check to fail because the proof no longer matches the provided public inputs. Therefore, while unconstrained public inputs do not enforce logical relationships within the circuit, they remain inseparably bound to the proof itself, and this binding is sufficient to prevent tampering or replay with modified values. Run the unit tests 'testClaimInvalidProofFails', 'testFrontRunningClaimFails'.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.