buySnow() decides the payment path using strict equality:
If msg.value matches the fee exactly, payment is taken in ETH. Any other value — including overpaying by even 1 wei — routes to the else branch, which pulls payment in WETH via safeTransferFrom instead. Whatever ETH was sent alongside that call is never checked, never used, and never refunded — it simply accumulates in the contract's ETH balance.
Likelihood: Medium. This repo ships no frontend, so callers interact either directly (e.g. via a block explorer's "Write Contract" tab, where the value field is filled in manually with no validation) or through third-party scripts computing msg.value themselves. A mismatch doesn't require any special exploit setup — it's the natural result of a fat-fingered value field or a rounding bug in a caller's script — but it does require the user to have both ETH and approved WETH available at once, which narrows how often it occurs in practice.
Impact: Medium. Funds are directly lost, but the loss is bounded per-transaction to whatever excess ETH was sent — this isn't a protocol-wide drain, and there's no way for an attacker to force another user into this state (it requires the victim's own transaction to misconfigure msg.value). Still, a well-designed payable function should never silently retain unaccounted-for funds with no recovery path, regardless of how the mismatch occurs.
Result: PASS. Buyer sends fee + 1 wei of ETH, still gets their Snow token (paid for via WETH), and the extra 1 wei of ETH remains permanently in the contract with no way to retrieve it.
Either reject any mismatched msg.value outright:
or explicitly refund the excess ETH before or after the WETH transfer path executes.
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.