The protocol is documented and funded as a 10-treasure hunt: `README.md` states the circuit contains 10 valid treasure hashes, `Deploy.s.sol` documents 10 published hashes, and `TreasureHunt.sol` hardcodes `MAX_TREASURES = 10` with `REWARD = 10 ether`.
The Noir circuit does not actually contain 10 unique treasure hashes. `circuits/src/main.nr` repeats the same baked hash in the last two slots, while `Deploy.s.sol` still documents a different 9th hash (`-441772...`) that is absent from the circuit. This desynchronizes the circuit, deployment script, and operator-facing assumptions, and leaves one documented treasure outside the actual proof-valid set.
Likelihood: HIGH
The mismatch is already baked into the committed circuit source and mirrored by the scoped deployment script comments, so a deployment from this repository inherits the inconsistent treasure inventory by default.
Any operator or participant relying on the published hash list in `Deploy.s.sol` can be pointed to a treasure identifier that the circuit will never accept.
Impact: HIGH
One documented treasure becomes unclaimable through the intended ZK proof flow because its published hash is not present in the circuit's `is_allowed` set.
Protocol lifecycle assumptions drift out of sync: the system is funded and documented as a 10-treasure hunt even though the circuit only exposes 9 unique claimable treasure identifiers.
Add this test case to test file with any other stuff variable that depends, and run with forge test
Update any mirrored treasure-hash documentation in `Deploy.s.sol` and related operational materials from the same source of truth used to generate the circuit.
The issue stems from a mismatch between the circuit and the contract’s economic assumptions: the Solidity contract is configured for `MAX_TREASURES = 10` and only allows the owner to call `withdraw()` once `claimsCount >= MAX_TREASURES`, while the Noir circuit’s baked-in `ALLOWED_TREASURE_HASHES` array does not actually contain ten distinct treasures because one hash is duplicated and another expected hash is missing. As a result, under the intended one-claim-per-treasure design described in the README, there are only nine uniquely claimable treasures even though the system is funded and accounted as if ten rewards can be legitimately redeemed. That creates two linked consequences from the same root cause: first, one treasure is effectively unclaimable because no valid proof can ever be generated for the missing allowed hash, and second, the normal “hunt over” withdrawal path becomes bricked because honest participants can never reach ten legitimate unique claims, leaving the post-hunt fund recovery logic via `withdraw` function permanently unreachable. The owner can still intervene through the emergency path.
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.