SNARKeling Treasure Hunt

First Flight #59
Beginner FriendlyGameFiFoundry
100 EXP
View results
Submission Details
Severity: low
Valid

`Claimed` event logs `msg.sender` instead of the declared `recipient` field, misleading off-chain indexers

Scope: contracts/src/TreasureHunt.sol

Root + Impact

Description

The Claimed event is declared with an indexed recipient parameter:

event Claimed(bytes32 indexed treasureHash, address indexed recipient);

…but inside claim() it is emitted with msg.sender in the
recipient slot:

emit Claimed(treasureHash, msg.sender); // @> should be `recipient`

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.

Risk

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.

Proof of Concept

  1. Call hunt.claim(proof, treasureHash, rcpt) from msg.sender == alice
    with rcpt = bob.

  2. ETH transfers to bob as expected.

  3. The emitted Claimed event has treasureHash as expected and
    recipient = alice (wrong — should be bob).

  4. Any subgraph or explorer that wires {treasureHash -> recipient}
    from the event will show Alice as the payout target.

Recommended Mitigation

- emit Claimed(treasureHash, msg.sender);
+ emit Claimed(treasureHash, recipient);

If both the submitter and the recipient are considered useful
off-chain, add a separate indexed submitter field:

- event Claimed(bytes32 indexed treasureHash, address indexed recipient);
+ event Claimed(bytes32 indexed treasureHash, address indexed recipient, address indexed submitter);
...
- emit Claimed(treasureHash, msg.sender);
+ emit Claimed(treasureHash, recipient, msg.sender);

Disclosure

This finding was identified and written up with the assistance of an
autonomous AI auditor (Anthropic Claude).

Updates

Lead Judging Commences

s3mvl4d Lead Judge 18 days ago
Submission Judgement Published
Validated
Assigned finding tags:

incorrect event parameter

The event is declared as event `Claimed(bytes32 indexed treasureHash, address indexed recipient);`, which clearly indicates that the second indexed field is meant to represent the reward recipient, but `claim()` emits `Claimed(treasureHash, msg.sender)` instead of `Claimed(treasureHash, recipient)`, even though the ETH transfer is sent to recipient and the proof itself is constructed around the public inputs (treasureHash, recipient). As a standalone finding, this is appropriately low severity because it is fundamentally an event/accounting inconsistency rather than a direct loss-of-funds issue: the core state transition and payout still follow the intended recipient, but off-chain consumers reading the event log will observe incorrect metadata about who was associated with the claim.

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!