buySnow() logic incorrectly assumes a WETH payment when an incorrect amount of ETH is sent, causing a user to be charged in both assets and leading to the permanent loss of their initial ETH deposit.The buySnow() function allows users to purchase "Snow" tokens by paying a fee. It is designed to accept payment in either native ETH (via msg.value) or WETH (via safeTransferFrom).
The issue arises from the flawed if/else logic that determines the payment method. The code only accepts an ETH payment if msg.value is exactly equal to the required fee. If a user sends any other non-zero amount of ETH (e.g., one wei less or one wei more than required), the else block is executed. This block proceeds to charge the user the full fee in WETH, assuming that was the user's intent. The critical flaw is that the native ETH sent in msg.value is accepted by the payable function but is never refunded or accounted for, resulting in the user paying with both ETH and WETH for a single purchase.
Likelihood: Medium
This occurs any time a user attempts to pay with native ETH but provides an incorrect msg.value. This can easily happen due to user error, a front-end UI bug, or transaction misconfiguration.
The vulnerability requires the user to have also pre-approved the contract to spend their WETH, which is a common requirement in DeFi protocols.
Impact: High
Direct Loss of User Funds: Users who trigger this condition will lose the entire amount of ETH they sent in msg.value. The loss is permanent and irrecoverable.
The following test demonstrates that a user attempting to buy 2 "Snow" token by WETH, but accidentally sending ETH, will lose that ETH and also be charged the full WETH.
The payment logic should be strict and unambiguous. Do not allow a transaction to fall through from an ETH payment attempt to a WETH payment. Explicitly separate the two payment flows. If msg.value is greater than zero, the function should treat it as an ETH-only payment attempt and revert if the amount is incorrect. WETH payments should only be processed when msg.value is zero.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.