The protocol allows users to buy Snow tokens by sending exactly s_buyFee * amount in ETH or by having WETH pulled from their wallet. The function is designed so that ETH payment is used when provided and WETH is used as fallback.
The condition msg.value == (s_buyFee * amount) uses strict equality. Any msg.value that is non-zero but does not match the fee exactly (e.g., off by 1 wei due to gas estimation, rounding, or front-end bugs) causes the ETH to be silently trapped in the contract while the else branch also charges the full fee in WETH — the user pays twice and recovers nothing.
Likelihood:
Occurs whenever a user sends any ETH amount that is off by even 1 wei — a common outcome of gas estimation, front-end rounding, or direct contract interaction.
Users with active WETH approvals (set during a prior purchase attempt) unknowingly trigger both ETH retention and WETH transfer when they retry with a wrong amount
Impact:
User ETH is permanently locked in the Snow contract, recoverable only by the s_collector address via collectFee() — the user has no self-recovery path
Users with WETH approval active are charged up to double the required fee for a single Snow token purchase
The test gives Alice exactly correctFee - 1 wei in ETH — one wei short of the required amount, a realistic outcome of front-end rounding or gas estimation truncation. Alice also has a full WETH approval active from a prior interaction with the contract. After calling buySnow with the short ETH value, the test checks three state transitions: Alice's ETH is now held inside the Snow contract with no refund path, Alice's WETH balance has been reduced by the full correctFee, and Alice received her Snow token. The net result is that Alice paid approximately double the required fee — both her ETH and WETH — for a single Snow token, with the ETH permanently locked in the contract and recoverable only by the s_collector address through collectFee.
To run: forge test --match-test test_WrongEthLocksUserFundsAndPullsWeth -vvvv
Add explicit reverts for non-zero, incorrect ETH values, and add a refund for any overpayment:
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.