The Noir circuit is designed to let a finder prove knowledge of any one of the 10 intended treasures without revealing which one it is. It does this by checking that the public treasure_hash is present in the hardcoded ALLOWED_TREASURE_HASHES array and that it equals pedersen_hash(treasure).
The last two entries in ALLOWED_TREASURE_HASHES are identical. The array therefore only contains 9 unique hashes instead of the documented 10. Treasure #9’s hash is missing, so no valid ZK proof can ever be generated for it.
Likelihood:
The array is statically defined in the circuit source and is baked into the deployed verifier contract.
The is_allowed helper and the main function both rely on this exact array; the duplicate is present in every build and every deployment.
Impact:
Treasure #9 becomes permanently unclaimable, even a finder who physically locates it and knows the correct secret cannot generate a valid proof.
The real-world treasure hunt is left with only 9 working treasures instead of the intended 10, breaking the game design and fairness guarantees.
Simply inspecting the array shows ALLOWED_TREASURE_HASHES[8] == ALLOWED_TREASURE_HASHES[9]. Any attempt to claim treasure #9 with its real secret will fail the assert(is_allowed(treasure_hash)) check in main.
Update the array size, loop bounds, all comments that say “10 allowed hashes / 10 treasures”, and the test suite accordingly.
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.