Snowman Merkle Airdrop

First Flight #42
Beginner FriendlyFoundrySolidityNFT
100 EXP
View results
Submission Details
Severity: low
Valid

H-1 s_earnTimer can be reset in Snow.sol leading to DOS

Root + Impact


Description

  • s_earnTimer can lead in DOS in Snow.so.l. If a new users keeps calling Snow.sol::buySnow() it updates the Snow.sol::s_earnTimer.

  • making the old user can't earn after one week



  • s_earnTimer
// Root cause in the codebase with @> marks to highlight the relevant section
//>@audit anyone can rest their state variable s_earnTimer
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);
}
s_earnTimer = block.timestamp;
emit SnowBought(msg.sender, amount);
}

Risk

Likelihood:

  • Reason 1 // Describe WHEN this will occur (avoid using "if" statements)

  • Reason 2 very high likely.

Impact:

  • Impact 1 DOS

  • Impact 2 old user can't earn after one week

Proof of Concept

function testGlobalTimerExploit() public {
console2.log("Start time:", block.timestamp);
// Ashley earns snow
vm.prank(ashley);
snow.earnSnow();
uint256 firstEarn = snow.getEarnTimer();
console2.log("Ashley earned at:", firstEarn);
// Warp 8 days
vm.warp(block.timestamp + 8 days);
console2.log("After 8 days:", block.timestamp);
// Victory buys snow and resets s_earnTimer
vm.prank(victory);
snow.buySnow{value: FEE}(1);
uint256 afterBuy = snow.getEarnTimer();
console2.log("Victory bought at (timer):", afterBuy);
// Ashley tries to earn again (should revert — global timer was reset)
vm.prank(ashley);
vm.expectRevert(Snow.S__Timer.selector);
snow.earnSnow();
}

Recommended Mitigation

//Use a per-user mapping for s_earnTimer:
mapping(address => uint256) private s_earnTimer;
// Update all logic in earnSnow() and buySnow() to reference s_earnTimer[msg.sender], not a global value.
Updates

Lead Judging Commences

yeahchibyke Lead Judge 3 months ago
Submission Judgement Published
Validated
Assigned finding tags:

buying of snow resets global timer thus affecting earning of free snow

When buySnow is successfully called, the global timer is reset. This inadvertently affects the earning of snow as that particular action also depends on the global timer.

Support

FAQs

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