SNARKeling Treasure Hunt

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

Claimed Event Emits msg.sender Instead of recipient Off-chain Tracking Broken

Root + Impact

Description

  • The Claimed event signature is event Claimed(bytes32 indexed treasureHash, address indexed recipient) clearly intended to record the ETH recipient.

The emission inside claim() passes msg.sender (the proof submitter) as the second argument instead of the recipient (the payee), producing permanently incorrect on-chain logs.

event Claimed(bytes32 indexed treasureHash, address indexed recipient);
function claim(bytes calldata proof, bytes32 treasureHash, address payable recipient) external ... {
...
(bool sent, ) = recipient.call{value: REWARD}(""); // @> ETH goes to recipient
require(sent, "ETH_TRANSFER_FAILED");
// @> Bug: emits msg.sender, not recipient
emit Claimed(treasureHash, msg.sender);
}

Risk

Likelihood:

  • This bug fires on every successful claim.

  • The discrepancy is only visible when msg.sender != recipient, which is always the case (the guard if (recipient == msg.sender) revert InvalidRecipient() ensures they differ).

Impact:

  • Block explorers, analytics dashboards, and subgraphs that index the Claimed event will display wrong recipient addresses.

  • The event is immutable on-chain — the incorrect data cannot be corrected after deployment.

  • Any off-chain system awarding secondary prizes or reputation based on event logs will attribute rewards to the wrong party.

Proof of Concept

Alice submits proof, designating Bob as recipient. ETH is correctly sent to Bob.

But the event logs Alice as recipient:

emit Claimed(treasureHash, alice); // Should be bob

Recommended Mitigation

Make changes in code as shown below

// Before (buggy):
emit Claimed(treasureHash, msg.sender);
// After (fixed):
emit Claimed(treasureHash, recipient);
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!