In the claim() function, the duplicate claim check uses _treasureHash (an immutable private variable that is NEVER initialized in the constructor, making it permanently bytes32(0)) instead of the caller-supplied treasureHash parameter. The check if (claimed[_treasureHash]) revert AlreadyClaimed(treasureHash); will always readclaimed[bytes32(0)], which is false. Meanwhile, _markClaimed(treasureHash) correctly marks the caller-supplied hash, but the guard never checks it. This means any valid ZK proof for a given treasure can be replayed up to MAX_TREASURES (10) times, limited only by the claimsCount cap, allowing a single treasure finder to drain the entire 100 ETH contract balance.
Impact:
A single treasure finder can replay their valid ZK proof up to 10 times (limited by MAX_TREASURES), draining the entire 100 ETH contract balance. Each replay uses a different recipient address (since recipient != msg.sender is enforced), but the attacker controls all recipient addresses. This completely breaks the core game mechanic and results in total loss of funds.
no need
In `claim()`, the guard uses `claimed[_treasureHash]`, where `_treasureHash` is an immutable state variable that is never initialized to the caller-supplied treasure identifier, while the contract later marks `claimed[treasureHash] = true` using the function argument instead. As a result, the duplicate-claim check and the state update are performed against different keys, which means a previously claimed treasure is not actually blocked from being claimed again with the same valid proof and `treasureHash`. This breaks a core invariant of the protocol described in the README, namely, that each treasure can only be redeemed once, and allows one valid treasure/proof pair to be reused to drain rewards repeatedly until either the `MAX_TREASURES` cap or the contract balance is exhausted.
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.