SNARKeling Treasure Hunt

First Flight #59
Beginner FriendlyGameFiFoundry
100 EXP
Submission Details
Impact: low
Likelihood: high

[L-01] `Claimed` event logs caller instead of actual recipient

Author Revealed upon completion

Root + Impact

Description

The normal behavior is that Claimed(treasureHash, recipient) reflects the address that receives payout.

The issue is that event emission uses msg.sender instead of the recipient parameter. Off-chain consumers indexing rewards from logs get systematically incorrect attribution.

// contracts/src/TreasureHunt.sol
event Claimed(bytes32 indexed treasureHash, address indexed recipient);
function claim(bytes calldata proof, bytes32 treasureHash, address payable recipient) external nonReentrant() {
// ...
emit Claimed(treasureHash, msg.sender); // @> wrong field emitted
}

Risk

Likelihood:

  • Every successful claim emits the wrong second indexed parameter.

  • Existing test demonstrates this behavior deterministically.

Impact:

  • Analytics, scoreboards, and monitoring systems receive corrupted claim attribution.

  • Operational and dispute-resolution workflows relying on event logs can fail.

Proof of Concept

Standalone reproduction:

  1. Pick msg.sender = participant and recipient = anotherAddress.

  2. Submit a valid claim(proof, treasureHash, recipient).

  3. Inspect emitted log.

  4. Observe second indexed argument equals participant instead of recipient.

function test_C1_ClaimedEventEmitsWrongRecipient() public {
address payable recipient = payable(address(0xABCD));
vm.expectEmit(true, true, false, false, address(hunt));
emit TreasureHunt.Claimed(HASH_1, PARTICIPANT); // actual buggy emission
vm.prank(PARTICIPANT);
hunt.claim(DUMMY_PROOF, HASH_1, recipient);
}

Written explanation: the reward can be sent to recipient, but indexers reading the event will record PARTICIPANT as recipient because the contract emits the caller.

Recommended Mitigation

Use the function claim(bytes calldata proof, bytes32 treasureHash, address payable recipient).

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

Support

FAQs

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

Give us feedback!