Snow::buySnow lets a user mint amount Snow tokens by paying the price s_buyFee * amount, in either native ETH (via msg.value) or WETH. The intended behavior is that a buyer pays the price once, in exactly one of the two assets.
The ETH path is only taken when msg.value is exactly equal to s_buyFee * amount. For any other msg.value (including sending slightly too much for safety, or an approximate value), execution falls into the else branch, which pulls the full price again in WETH via safeTransferFrom while the ETH sent in msg.value stays in the contract. The excess/sent ETH is never refunded, and is later swept to the collector by collectFee. A buyer who sends non-exact ETH is therefore charged twice (ETH kept + WETH pulled), or — if they have no WETH allowance — the transaction reverts and their intended ETH purchase silently fails.
Likelihood: High
Hitting the exact-wei ETH price is impractical; users routinely overpay slightly or round, so msg.value != s_buyFee * amount is the common case for ETH buyers.
Any buyer who holds a WETH allowance (the standard setup, since the contract advertises WETH payment) and sends non-exact ETH is double-charged on every such purchase.
Impact: High
Buyers lose funds: they pay the price in WETH and forfeit the ETH they sent, receiving only a single amount of Snow for a double payment.
Even without a WETH allowance, any surplus ETH over the exact price is permanently retained by the contract with no refund, so ETH buyers cannot pay correctly without losing the overage.
A buyer intends to pay in ETH but sends 1 wei more than the exact price. They also hold a WETH allowance (as expected for a protocol that accepts WETH). They are charged in WETH and their ETH is kept:
Make the payment asset explicit and refund/repay correctly. Only pull WETH when no ETH was sent, require sufficient ETH (not exact) and refund any surplus:
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.