Scope: contracts/src/TreasureHunt.sol
The Claimed event is declared with an indexed recipient parameter:
…but inside claim() it is emitted with msg.sender in the
recipient slot:
Because the same function explicitly rejects recipient == msg.sender
(line 86, revert InvalidRecipient()), the emitted address is
guaranteed to differ from the actual ETH payout recipient for every
successful claim.
Likelihood: HIGH — every successful claim produces an incorrectly
labeled event.
Impact: LOW — the on-chain ETH transfer is unaffected; only
off-chain consumers (subgraphs, block explorers, payout dashboards,
user-facing UIs) attribute the treasure reward to the submitter
instead of the recipient.
Call hunt.claim(proof, treasureHash, rcpt) from msg.sender == alice
with rcpt = bob.
ETH transfers to bob as expected.
The emitted Claimed event has treasureHash as expected and
recipient = alice (wrong — should be bob).
Any subgraph or explorer that wires {treasureHash -> recipient}
from the event will show Alice as the payout target.
If both the submitter and the recipient are considered useful
off-chain, add a separate indexed submitter field:
This finding was identified and written up with the assistance of an
autonomous AI auditor (Anthropic Claude).
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.