buySnow() allows users to purchase Snow tokens by paying either exact ETH or by pulling WETH from their balance.
The ETH payment logic uses strict equality (==). If a user sends more ETH than the exact required fee, the condition is false, the else branch executes pulling WETH from the user AND keeping the sent ETH — the user is double-charged and their ETH is permanently locked. If the user underpays, the condition is also false — ETH stays in the contract while WETH is pulled instead. s_buyFee is stored as fee * PRECISION (a large number), making exact ETH computation error-prone and triggering this path frequently without tooling.
Likelihood:
Users who slightly overpay when calling buySnow() with ETH — a common occurrence when computing exact amounts manually or with imprecise tooling — permanently lose the difference.
Frontend implementations that pad ETH amounts for gas estimation or use slightly stale fee values trigger this path automatically.
Impact:
Any user who sends more ETH than the exact required fee permanently loses the excess to the contract — collectFee() sends ETH to the collector, not back to the user, providing no recovery path.
Users who accidentally underpay lose their ETH silently while being charged again via WETH.
Place this test in test/ and run forge test --match-test testOverpaymentIsLost. The test demonstrates that buySnow() uses a strict equality check for msg.value — overpayment does NOT revert; instead it silently falls through to the WETH else-branch, double-charging the user (ETH is kept by the contract AND WETH is pulled from the user).
Change the fee check from msg.value == totalFee to msg.value >= totalFee and refund any excess msg.value - totalFee back to the caller to prevent accidental ETH loss.
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.