Snowman Merkle Airdrop

AI First Flight #10
Beginner FriendlyFoundrySolidityNFT
EXP
View results
Submission Details
Impact: low
Likelihood: low
Invalid

Snow pulled into SnowmanAirdrop has no withdraw or burn path and is permanently locked in the contract

Claimed Snow is transferred into a contract with no withdraw path, permanently locking the tokens

Description

On a successful claim, claimSnowman pulls the receiver's Snow into the airdrop contract ("akin to burning"), but SnowmanAirdrop has no withdraw, rescue, or burn function and is not Ownable, so the accumulated Snow is permanently stuck.

i_snow.safeTransferFrom(receiver, address(this), amount); // @> sent to contract with no way out
s_hasClaimedSnowman[receiver] = true;
emit SnowmanClaimedSuccessfully(receiver, amount);

Every claim adds to a growing, irrecoverable balance; any Snow accidentally sent to the contract is also lost.

Risk

Likelihood:

This happens on every single successful claim by design; it is not conditional.

Impact:

All claimed Snow is locked forever. If the intent was to burn, the supply accounting is still wrong because the tokens remain in circulation held by a dead contract; if the intent was to retain them, they are unrecoverable. Low severity because no claimer is directly harmed, but value is permanently destroyed.

Proof of Concept

Snow accumulates in the airdrop contract with no method to retrieve it.

function test_snowLockedInContract() public {
uint256 before = snow.balanceOf(address(airdrop));
airdrop.claimSnowman(receiver, proof, v, r, s);
assertGt(snow.balanceOf(address(airdrop)), before); // and no withdraw exists
}

Recommended Mitigation

Burn the tokens to a real burn address, or make the contract Ownable and add a guarded rescue.

- i_snow.safeTransferFrom(receiver, address(this), amount); // akin to burning
+ i_snow.safeTransferFrom(receiver, address(0xdead), amount); // actually burn
// or add: function emergencyWithdraw() external onlyOwner { i_snow.safeTransfer(owner(), i_snow.balanceOf(address(this))); }
Updates

Lead Judging Commences

ai-first-flight-judge Lead Judge about 5 hours ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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

Give us feedback!