Snowman Merkle Airdrop

First Flight #42
Beginner FriendlyFoundrySolidityNFT
100 EXP
View results
Submission Details
Impact: medium
Likelihood: medium
Invalid

Ensure exclusive payment mode in buySnow() to prevent ambiguity and potential bypass

Root + Impact- The buySnow() function does not restrict payment to only one mode between ETH or WETH. Without enforcing exclusive modes, users may send both or neither, causing unintended minting behavior or loss of funds.

Description

  • buySnow() is designed to accept either ETH or WETH as payment and mint Snow tokens accordingly.

  • There is no explicit check that ensures users are only using one payment mode per call. This could allow edge cases like double payment attempts or misrouted logic.

function buySnow(uint256 amount) external payable canFarmSnow {
@> if (msg.value == (s_buyFee * amount)) {
_mint(msg.sender, amount);
} else {
i_weth.safeTransferFrom(msg.sender, address(this), (s_buyFee * amount));
_mint(msg.sender, amount);
}

Risk

Likelihood:

  • Users with ETH and approved WETH may accidentally trigger dual behavior or fallback to an unintended path.

  • Confusion or exploitation by custom smart wallets that abuse logic ambiguity.

Impact:

  • Incorrect minting without valid payment.

  • Funds stuck or lost due to ambiguous payment handling.

Proof of Concept- This PoC shows that a user can pass ETH and have a WETH allowance. Due to lack of a strict check, the ETH is ignored, and WETH is also taken. The ETH remains stuck in the contract, or the user overpays.

// Simulate a user with approved WETH and also sending ETH
payable(snowContract).call{value: s_buyFee * amount}(
abi.encodeWithSelector(snow.buySnow.selector, amount)
);
// The contract will enter the WETH branch, but ETH is also sent, leading to potential fund loss.

Recommended Mitigation- Enforce exclusive payment modes using strict conditional branches and reverts

+ error S__InvalidPaymentMode();
- if (msg.value == (s_buyFee * amount)) {
+ if (msg.value > 0 && msg.value == (s_buyFee * amount)) {
_mint(msg.sender, amount);
+ } else if (msg.value == 0) {
i_weth.safeTransferFrom(msg.sender, address(this), (s_buyFee * amount));
_mint(msg.sender, amount);
+ } else {
+ revert S__InvalidPaymentMode(); // Add this custom error
}
Updates

Lead Judging Commences

yeahchibyke Lead Judge
2 months ago
yeahchibyke Lead Judge 2 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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