The claim() function checks claimed[_treasureHash] to prevent
double-claims, but _treasureHash is an immutable field that is
never initialized in the constructor, so it permanently defaults
to bytes32(0).
Meanwhile, when a treasure IS claimed, it marks claimed[treasureHash]
(the function parameter). These are two different mapping keys — the
check always reads claimed[0x0] which is always false, so the
protection never triggers.
Likelihood:
Any caller with a valid ZK proof can call claim() repeatedly
No special access or conditions needed — exploitable immediately
on deployment
Impact:
Same treasure can be claimed unlimited times with different
recipient addresses
Each claim pays 10 ETH from the contract
All 100 ETH can be fully drained in a single transaction sequence
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.