Normal behavior:
The buySnow()
function allows users to purchase Snow tokens by paying either in native ETH or by transferring WETH. The expected cost is calculated as s_buyFee * amount
.
The problem:
The function checks for an exact ETH payment match using msg.value == (s_buyFee * amount)
. If this check fails, it assumes the user wants to use WETH and proceeds to transfer WETH using safeTransferFrom
. However, it does not ensure that msg.value
is zero in that path, nor does it validate that the WETH transfer will succeed ahead of time. This causes silent ETH loss when the user sends non-zero msg.value
that does not exactly match the cost.
Likelihood: High
This issue occurs when a user sends an incorrect msg.value
amount — such as slightly too much or too little ETH — when calling buySnow()
. The function does not validate that the ETH sent is exactly equal to the expected fee, and proceeds assuming the user wants to pay with WETH instead.
The lack of validation allows ETH to be accidentally sent to the contract without being refunded or used, which is highly likely in frontend miscalculations, manual transactions, or poor UX prompting
Impact: High
Users can irreversibly lose ETH if they mistakenly overpay or underpay the exact required msg.value
for minting Snow tokens. This represents a direct financial loss.
The protocol silently mints tokens under the assumption that WETH is being used without ensuring WETH was actually transferred. This makes the contract behavior ambiguous, misleading, and potentially harmful to end users interacting via ETH.
This contract sends slightly more ETH than expected for buySnow
.
Since the contract only checks for an exact match (msg.value == s_buyFee * amount
), any mismatch defaults to WETH payment logic, even though WETH was not transferred.
This means:
ETH is silently accepted and trapped in the contract.
The user may or may not get Snow tokens depending on how the fallback logic interprets state, leading to undefined and harmful behavior.
Ensure that ETH payments in buySnow()
strictly match the required fee (s_buyFee * amount
). If msg.value
is greater or less than expected, revert the transaction with a clear error. This prevents users from unintentionally losing ETH due to overpayment and enforces safe and predictable payment logic.
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.
The contest is complete and the rewards are being distributed.