Wrong variable referenced in AlreadyClaimed check + total reward pool drain
The claim() function is designed to prevent the same treasure from being claimed twice by checking the claimed mapping against a treasure hash. Once a treasure is claimed, subsequent claims for that hash should revert with AlreadyClaimed.
The AlreadyClaimed check queries the immutable state variable _treasureHash (which is never assigned in the constructor and defaults to bytes32(0)) instead of the function parameter treasureHash. Meanwhile, _markClaimed() correctly marks the function parameter treasureHash as claimed. This mismatch means the double-spend check always queries a different key than the one that was set, so it never detects a previously claimed treasure.
Likelihood:
A participant with a single valid ZK proof for any treasure calls claim() repeatedly up to 10 times (until claimsCount >= MAX_TREASURES), since the AlreadyClaimed guard never triggers
The ZK proof remains valid for the same treasureHash + recipient combination on every call, so no new proof generation is needed
Impact:
A single participant drains the entire 100 ETH reward pool by repeatedly claiming the same treasure
9 other legitimate treasure finders receive no reward
The integrity of the treasure hunt is completely broken
Note: The existing test testClaimDoubleSpendReverts at line 134 has vm.expectRevert() commented out, confirming this behavior was observed but not fixed.
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.
The contest is complete and the rewards are being distributed.