SNARKeling Treasure Hunt

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

(MEDIUM) `recipient == msg.sender` is rejected, forcing legitimate finders to use a second wallet or relayer with no added security.

Location: contracts/src/TreasureHunt.sol:86

Description

The claim function explicitly rejects recipient == msg.sender:

if (recipient == address(0) || recipient == address(this) || recipient == owner || recipient == msg.sender) revert InvalidRecipient();

The protocol already binds the proof to the recipient as a public input, which prevents front-running. Blocking recipient == msg.sender does not add any security property: a finder who wants to pay themselves can simply create a second EOA, use that as the submitter, and sidestep the check. The net effect is worse UX.

Risk (M)

Likelihood: High. Every legitimate single-wallet user hits this restriction on their first attempt.

Impact: Low. No fund loss; the friction pushes users toward relayers or second wallets.

Proof of Concept

function test_SelfClaimReverts() public {
(bytes memory proof, bytes32 treasureHash, address payable recipient) = _loadFixture();
// Pretend msg.sender == recipient (the natural way to self-claim).
vm.expectRevert(TreasureHunt.InvalidRecipient.selector);
vm.prank(recipient);
hunt.claim(proof, treasureHash, recipient);
}

Run:

forge test --match-test test_SelfClaimReverts -vv

The test passes, confirming the revert.

Recommended Mitigation

Remove the recipient == msg.sender

- if (recipient == address(0) || recipient == address(this) || recipient == owner || recipient == msg.sender) revert InvalidRecipient();
+ if (recipient == address(0) || recipient == address(this) || recipient == owner) revert InvalidRecipient();
Updates

Lead Judging Commences

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

incorrect self-transfer rejection

The issue is that `claim()` rejects any case where `recipient == msg.sender`, even though the proof system already binds the claim to the recipient address and the contract ultimately transfers the reward to that same recipient, so prohibiting self-receipt does not protect any obvious security property of the payout flow. It is a low-severity logic or UX restriction, which unnecessarily forces honest claimants to control and provide a second wallet address in order to receive funds.

Support

FAQs

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

Give us feedback!