Snowman Merkle Airdrop

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

Snow.buySnow double-charges users who send ETH — WETH is pulled AND the ETH is kept, with no refund

Root + Impact

buySnow falls through to the WETH transferFrom path when msg.value doesn't exactly match the fee, keeping any ETH sent and charging the full WETH fee on top, with no refund.

Description

buySnow checks if (msg.value == s_buyFee * amount) for the ETH path, but on mismatch it falls into the WETH transferFrom path while any ETH actually sent with the call stays in the contract. There is no refund branch.

Risk

Likelihood: Medium

Impact: A user who sends ETH with a slightly wrong value (or sends ETH expecting it to count toward the fee) is charged the full fee in WETH via transferFrom AND loses the ETH they sent. collectFee later sweeps both the WETH fees and the trapped ETH to the fee collector, so the user has no recovery path.

Proof of Concept

  1. User calls buySnow sending ETH with a value slightly different from s_buyFee * amount.

  2. The exact-match check fails, so the contract pulls the full fee in WETH via transferFrom.

  3. The ETH sent stays trapped in the contract — the user has paid twice.

  4. collectFee sweeps both the WETH and the trapped ETH to the fee collector; the user cannot recover the ETH.

Recommended Mitigation

If msg.value > 0, require it to equal the exact fee and skip the WETH pull; otherwise refund any ETH sent. Never accept value on the WETH path.

Updates

Lead Judging Commences

ai-first-flight-judge Lead Judge about 1 hour 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!