Snowman Merkle Airdrop

AI First Flight #10
Beginner FriendlyFoundrySolidityNFT
EXP
View results
Submission Details
Impact: medium
Likelihood: low
Invalid

Unchecked WETH Transfer in collectFee May Fail Silently

Root + Impact

Description

  • Normal behavior: Fee collection should safely transfer all accumulated WETH and ETH to the collector, reverting if any transfer fails.

  • Specific issue: The collectFee function uses transfer() instead of safeTransfer() for WETH. If WETH transfer fails (non-standard token behavior), the failure is not caught.

// Root cause in src/Snow.sol:101-107
function collectFee() external onlyCollector {
uint256 collection = i_weth.balanceOf(address(this));
@> i_weth.transfer(s_collector, collection); // Not using safeTransfer!
(bool collected,) = payable(s_collector).call{value: address(this).balance}("");
require(collected, "Fee collection failed!!!");
}

Risk

Likelihood:

  • Standard WETH returns a bool, but non-standard implementations may not

  • If the transfer returns false instead of reverting, failure goes unnoticed

Impact:

  • WETH fees could be lost if the transfer fails silently

  • Inconsistent with the rest of the codebase, which uses safeTransfer

Proof of Concept

The contract imports and uses SafeERC20 from OpenZeppelin for safe token transfers. However, in the collectFee function, it uses the unsafe transfer method instead of safeTransfer. This inconsistency means that if the WETH transfer fails silently (returns false instead of reverting), the failure will not be caught and fees could be lost.

The code shows this inconsistency:

// Line 83 uses safeTransferFrom
i_weth.safeTransferFrom(msg.sender, address(this), (s_buyFee * amount));
// Line 103 uses unsafe transfer
i_weth.transfer(s_collector, collection);

Recommended Mitigation

Replace the unsafe transfer call with safeTransfer to ensure consistent handling of token transfers throughout the contract. This guarantees that any transfer failure will cause a revert rather than failing silently.

function collectFee() external onlyCollector {
uint256 collection = i_weth.balanceOf(address(this));
- i_weth.transfer(s_collector, collection);
+ i_weth.safeTransfer(s_collector, collection);
(bool collected,) = payable(s_collector).call{value: address(this).balance}("");
require(collected, "Fee collection failed!!!");
}
Updates

Lead Judging Commences

ai-first-flight-judge Lead Judge 1 day ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!