buySnow uses an exact equality check (msg.value == s_buyFee * amount) to determine whether the caller is paying in raw ETH. If the check fails, the function silently falls through to the WETH path without reverting or refunding the sent ETH.
The specific issue is that any non-zero msg.value that doesn't exactly match s_buyFee * amount is accepted, the WETH pull executes on top of it, and the stray ETH has no refund mechanism — it is permanently locked in the contract.
Likelihood:
Any buyer who miscalculates the fee (e.g., sends 3 ETH when 5 is required) will trigger the else branch while their ETH sits in the contract.
Frontends or scripts that round or truncate values before computing msg.value will produce mismatches.
Impact:
User's ETH is permanently trapped in the contract.
User pays the full WETH fee on top of the already-sent ETH, effectively overpaying by the amount of msg.value.
The equality check msg.value == (s_buyFee * amount) evaluates to 3 ether == 5 ether → false. Execution falls into the else branch, where safeTransferFrom pulls 5 WETH from the buyer's wallet. The transaction succeeds, 5 Snow tokens are minted, but the 3 ETH sent with the call has no refund path — it is permanently locked in the contract. The buyer has now paid 8 ETH equivalent (3 ETH + 5 WETH) for tokens worth 5 ETH.
This guard ensures that if the caller sends any ETH that doesn't exactly match the expected fee, the transaction reverts immediately and the ETH is returned to the sender. The two legitimate paths remain intact:
msg.value == 0 → WETH path (no ETH was sent, so nothing to validate)
msg.value == s_buyFee * amount → raw ETH path (exact match, proceeds normally)
Any other value is rejected before the WETH pull can execute, eliminating the stuck-ETH scenario entirely.
The contest is live. Earn rewards by submitting a finding.
Submissions are being reviewed by our AI judge. Results will be available in a few minutes.
View all submissionsThe contest is complete and the rewards are being distributed.