When a user overpays using ETH and has already approved WETH, the buySnow()
logic enters the else
branch and pulls WETH, while still accepting the full ETH payment. The function lacks a refund mechanism for overpayment, leading to unnecessary token loss
Likelihood:
This issue will occur when a user sends more ETH than required, either due to UI miscalculation, gas estimation overbuffering, or manual error — all of which are common real-world behaviors. In these cases, the exact msg.value == totalCost
check will fail, and the function will default to the WETH path, triggering an unexpected transferFrom()
call.
It will also occur any time the user has an active WETH allowance set for the contract, which is typical for protocols accepting ERC-20 payments. The combination of overpayment + allowance is highly probable, especially among power users or those interacting via aggregators and custom scripts.
Impact:
It punishes normal user behavior — users often overpay ETH unintentionally (e.g. due to UIs rounding up).
It can silently drain user balances without triggering any reverts or warnings.
It undermines user trust and protocol reliability.
This test demonstrates a realistic scenario where a user mistakenly overpays using ETH (e.g., they miscalculate gas or front-end overestimates the fee), and has also approved WETH. The current buySnow()
logic does not stop after receiving ETH. Instead, if the ETH amount doesn't match the exact expected value, it silently falls through to the WETH path — causing both tokens to be pulled, resulting in double payment.
Upadate the buySnow()
function to gracefully handle overpayment, my solution was to include a refund mechanism.
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.