Normal behavior: collectFee() transfers all accumulated WETH fees from the Snow contract to the collector address.
The issue: i_weth.transfer(s_collector, collection) uses the raw IERC20.transfer() whose return value is not checked. Snow.sol already imports and uses SafeERC20 correctly in buySnow() via i_weth.safeTransferFrom(). The inconsistency in collectFee() means a failed WETH transfer goes undetected — the function continues to send native ETH to the collector while WETH remains permanently stuck in the contract.
Likelihood:
The collector calls this function to withdraw fees — a silent WETH failure means permanent revenue loss.
Snow.sol already uses SafeERC20 in buySnow() — the omission in collectFee() is a clear inconsistency that will eventually trigger.
Impact:
WETH fees are silently lost — collector receives ETH but not WETH with no error raised.
Protocol revenue is permanently locked in the contract with no recovery mechanism.
The following Foundry test demonstrates that collectFee() silently succeeds even when the WETH transfer fails. A mock WETH token that returns false on transfer is used to simulate the failure. The function completes without reverting, the collector receives ETH but not WETH, and WETH remains stuck in the contract with no error raised.
The fix replaces the raw IERC20.transfer() call with SafeERC20.safeTransfer() which is already imported and used correctly elsewhere in Snow.sol. SafeERC20 wraps the transfer and reverts if the return value is false or if the token does not return a value at all. This brings collectFee() into consistency with buySnow() which already uses i_weth.safeTransferFrom() correctly. No new imports are required.
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.