In buySnow, if msg.value is greater than 0 but does not exactly equal s_buyFee * amount, the else branch executes which charges the user WETH via safeTransferFrom.
The ETH sent with the transaction is not refunded. The user ends up paying both ETH (stuck in contract) and WETH for the same purchase.
While the ETH can eventually be recovered by the collector via collectFee, the user who sent it loses their ETH.
Likelihood:
A user who miscalculates the exact ETH fee, or a frontend that sends slightly wrong amounts, triggers this.
Less likely for sophisticated users, but very possible for newcomers.
Impact:
User loses the ETH sent (it goes to the collector, not back to user).
User also pays the full WETH fee - double payment for one purchase.
The buySnow function uses an if/else structure where the if branch checks for an exact ETH amount match. If the ETH sent does not exactly equal s_buyFee * amount, the else branch executes, which pulls WETH from the user via safeTransferFrom. The problem is that the ETH sent in msg.value is never refunded in the else branch. The user ends up paying twice — their ETH stays in the contract and they also pay the full WETH amount.
Step-by-step scenario:
The buy fee is set to 5 (i.e. s_buyFee = 5 * 10^18). To buy 1 Snow token with ETH, a user must send exactly 5 * 10^18 wei.
A user mistakenly sends 4.9 * 10^18 wei (slightly less than required) when calling buySnow(1).
The if condition msg.value == (s_buyFee * amount) evaluates to false because 4.9e18 != 5e18.
The else branch executes: i_weth.safeTransferFrom(user, contract, 5e18) pulls 5 WETH from the user.
The user receives 1 Snow token, but they paid 4.9 ETH + 5 WETH for it.
The 4.9 ETH remains in the Snow contract and will be collected by the fee collector via collectFee(). The user has no way to recover it.
Restructure the if/else logic to explicitly check whether the user intends to pay with ETH or WETH. If msg.value > 0, verify it matches the exact fee and reject mismatched amounts with a revert. If msg.value == 0, proceed with the WETH payment path. This prevents users from accidentally sending ETH that doesn't match the fee, eliminating the double-payment 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.