Root Cause: The buySnow function does not refund excess ETH when msg.value does not match the required fee, and instead keeps it in the contract.
Normal behavior: When a user wants to buy Snow tokens, they should send exactly s_buyFee * amount in ETH. If they send the correct amount, they receive the tokens. If they don't send ETH, the contract tries to pull the equivalent value in WETH from their wallet.
the problem: If a user sends ETH but the amount is not exactly the required fee (for example, they send 2 ETH when only 1 ETH is needed), the contract still enters the WETH branch and pulls the required WETH from them. However, the ETH they sent is not returned – it stays stuck in the contract. Later, the collector can call collectFee and withdraw all ETH accumulated in the contract, effectively stealing the user’s funds.
Likelihood: Medium
This will happen every time a user mistakenly sends an incorrect ETH amount (higher or lower) while calling buySnow.
It can also be triggered if the frontend miscalculates the required fee or if the user manually sends a wrong value.
Impact: High
Users lose the exact ETH they sent (which can be any amount).
Additionally, they also lose WETH equivalent to the required fee because the contract pulls WETH from them.
The collector can drain all trapped ETH at any time, making the loss irreversible.
The following Foundry test demonstrates the vulnerability:
Refund any excess ETH sent by the user. If the user sends ETH but the amount is not exactly the required fee, return the ETH and then proceed with the WETH transfer (or revert entirely to avoid confusion).
Alternatively, you could revert the transaction entirely if the user sends ETH when they should use WETH, to avoid confusion. But the simplest fix is to return the ETH.
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.