The contract should prevent each treasure from being claimed more than once, but claim() checks claimed[_treasureHash] instead of claimed[treasureHash].
Because _treasureHash is never initialized, repeat claims for the same submitted treasureHash are not blocked.
Likelihood:
A successful claimant already has all required values for a valid claim:
proof
treasureHash
recipient
Because the contract does not correctly check whether that specific treasureHash was already claimed, the same claim can be submitted again.
Impact:
The same treasure can be claimed multiple times, draining more rewards than intended. Since each claim pays REWARD, repeated claims can drain the contract balance until either:
claimsCount reaches MAX_TREASURES, or
the contract has less than REWARD ETH remaining.
This violates the core invariant that each treasure should only pay out once.
The PoC deploys the verifier and TreasureHunt contract with 100 ether, then loads a valid proof, treasureHash, and recipient from the generated fixtures. It calls claim() once successfully, then calls claim() again with the exact same proof and treasureHash; the second call incorrectly succeeds and pays another reward, proving the same treasure can be claimed multiple times.
Replace the incorrect _treasureHash lookup with the submitted treasureHash.
The unused immutable variable should also be removed to avoid future confusion:
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.