Normal behavior: users should buy Snow either with exact ETH or with WETH. ETH sent to the WETH purchase path should be rejected or refunded.
The issue is that buySnow() selects the ETH path only when msg.value == s_buyFee * amount. Any other msg.value, including a nonzero underpayment or overpayment, falls through to the WETH path. When the caller has WETH allowance, the contract keeps the ETH and also transfers the full WETH fee.
Likelihood:
Users or integrations can accidentally send slightly too much or too little ETH with a WETH-approved purchase transaction.
Wallet and frontend mistakes around exact native value are common when a function supports both native ETH and ERC20 payments in the same entry point.
Impact:
Buyers lose the accidental ETH value and still pay the full WETH price.
The collector can later withdraw both the WETH fee and the accidental ETH via collectFee().
The test gives the buyer both WETH allowance and a small amount of native ETH, then calls buySnow{value: 1}(1). Since the native value is not exactly equal to the required ETH price, the function falls through to the WETH branch while keeping the sent ETH.
Separate ETH and WETH purchase functions, or explicitly require msg.value == 0 for WETH purchases and exact ETH for native purchases.
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.