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, logging wrong beneficiary address

Root + Impact

Description

  • The Claimed event is intended to log which address received the reward. However, it emits msg.sender (the proof submitter) instead of recipient (the address that actually receives the ETH). These two addresses are always different — the claim() function explicitly enforces recipient != msg.sender. Any off-chain indexer, explorer, or frontend tracking the Claimed event will display the wrong beneficiary.

function claim(..., address payable recipient) external {
// @> ETH is sent to recipient
(bool sent, ) = recipient.call{value: REWARD}("");
require(sent, "ETH_TRANSFER_FAILED");
// @> but event logs msg.sender — always a different address
emit Claimed(treasureHash, msg.sender);
}

Risk

Likelihood:

  • Triggers on every single successful claim() call, 100% of events are wrong.

  • The contract explicitly enforces recipient != msg.sender, guaranteeing the logged address never matches the paid address.

Impact:

  • Off-chain indexers, explorers, and frontends tracking Claimed events display the wrong winner

  • Participants monitoring events to confirm their reward was received will see an incorrect address

  • Any protocol building on top of this contract that uses the event to track payouts will have corrupted data

Proof of Concept

function testClaimedEventEmitsWrongAddress() public {
bytes memory proof = hex"deadbeef";
bytes32 treasureHash = bytes32(uint256(1));
vm.prank(attacker);
vm.expectEmit(true, true, false, false);
// @> event will fire with msg.sender (attacker), not recipient
emit TreasureHunt.Claimed(treasureHash, attacker);
hunt.claim(proof, treasureHash, payable(recipient));
// recipient received the ETH, but event logged attacker
assertEq(recipient.balance, 10 ether);
}

Recommended Mitigation

- emit Claimed(treasureHash, msg.sender);
+ 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!