e TreasureHunt::withdraw function allows the owner to recover any remaining ETH once the hunt is finished. The completion criteria is defined
as claimsCount >= MAX_TREASURES (where MAX_TREASURES is 10)
The issue is a logical deadlock caused by the duplicate hash in the Noir circuit (Finding [H-01]). Since the circuit only allows 9 unique
treasures to be proved, and the contract (assuming the double-spend bug is fixed) only allows each hash to be claimed once, the claimsCount can
never exceed 9. Consequently, the require statement in withdraw will always fail
Likelihood:
This is a guaranteed outcome if the Noir circuit bug is not fixed, as the claimsCount state variable is strictly incremented per successful
claim
Impact:
Locked Funds: The owner will be unable to retrieve the remaining 10 ETH (allocated for the 10th treasure) or any excess funding. This results
in a permanent loss of funds for the organizer
This test simulates the end-state of the hunt.
We simulate 9 unique successful claims (the maximum possible unique claims).
We verify claimsCount is 9 and 10 ETH remains.
We call withdraw() as the owner and confirm it reverts with "HUNT_NOT_OVER", proving that the owner can never recover the final 10 ETH even
after all possible treasures are found.
The primary mitigation is to fix the Noir circuit bug (Finding [H-01]). Additionally, it is recommended to add a time-based recovery mechanism
(e.g., block.timestamp > huntEndTime) to the withdraw function so the owner can recover funds if some treasures are never found physically.
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.