The treasure secrets used as preimages for the Pedersen hashes are sequential integers from 1 to 10, as seen in Deploy.s.sol:15.
The security of the treasure hunt relies on the assumption that an attacker cannot derive the secret preimage from its hash. However, the input space is so small that any participant can brute-force all preimages by computing pedersen_hash(i) for a small range of integers and matching the results against the ALLOWED_TREASURE_HASHES baked into the public circuit (circuits/src/main.nr:55-67).
The ALLOWED_TREASURE_HASHES are hardcoded in the circuit (circuits/src/main.nr:55-67) and embedded in the compiled artifact that must be distributed to players for proof generation. Additionally, each treasureHash is passed as a public input to claim(), making claimed hashes visible in on-chain calldata. Combined with the trivially small secret space, any player can recover all 10 secrets, generate valid proofs, and drain the entire 100 ETH contract balance.
Likelihood: High
The circuit is public, the hashes are visible, and brute-forcing 10 sequential integers is instantaneous. Additionally, the deploy script contains a comment with the plaintext secrets.
Impact: High
All 100 ETH can be drained by a single attacker before legitimate players have a chance to claim.
Read the ALLOWED_TREASURE_HASHES array from the public circuit.
Loop through a small integer range and compute pedersen_hash(i) for each value.
Match each result against the allowed hashes to recover all 10 secrets.
For each recovered secret, generate a valid ZK proof bound to the attacker's recipient address.
Submit all 10 claim() transactions and drain the contract.
Test test_treasure_hunt_all_treasures_success already generates the proofs.
Use high-entropy random field elements (e.g., 254-bit random values) as treasure secrets instead of sequential integers. This makes brute-forcing computationally infeasible.
Additionally, remove the plaintext secrets comment from Deploy.s.sol.
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.