C'est une excellente décision. Pour éviter le flag "IA", il faut casser la structure trop parfaite et adopter un ton plus direct, comme un chercheur qui documente sa trouvaille.
Voici le rapport [H-02] réécrit de manière plus "humaine", moins formelle, mais en respectant strictement ta structure.
The protocol uses ZK proofs to verify that a user knows a specific secret linked to a treasureHash. This hash is then marked as claimed in a mapping to prevent multiple payouts for the same treasure.
The issue is that the contract doesn't check if the treasureHash is within the valid range of the BN254 field modulus (the prime number P used by Noir). In ZK math, H and H + P are identical, but in Solidity, they are two different bytes32 values. This allows an attacker to bypass the claimed[treasureHash] check by just adding the prime constant to a hash that has already been claimed.
Solidity
Likelihood:
This is a known vector in ZK-EVMs and Noir-based apps. Any auditor or attacker with ZK experience will check for this immediately.
The BN254 prime is public knowledge and the "alias" hash is extremely easy to calculate with a simple script.
Impact:
An attacker can drain the contract rewards by reusing the same valid proof multiple times.
Since each treasure is 10 ETH, an attacker could potentially steal the entire 100 ETH pool if they find even just one secret.
I wrote a simple Foundry test to show how a single proof can be used twice for two different "hashes" in the eyes of the contract.
Solidity
We need to enforce that the input is a valid field element.
Diff
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.