Snowman Merkle Airdrop

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

Global s_earnTimer prevents parallel earnings

Description: The Snow::earnSnow() uses a single global variable 's_earnTimer' to track when users can earn free tokens, instead of using a per-user mapping. This creates a race condition where only one user can successfully earn a free token per week across the entire protocol. After one user earns a token, the timer is reset for everyone.

Impact: If any user earns tokens, it prevents all users from earning free tokens for a week. This is likely unintended behavior and significantly impacts the token distribution mechanics. While this doesn't lead to direct fund loss, it severely limits functionality and creates an unfair advantage for whoever manages to call these functions first.

Proof of Concept: Include the following test in the TestSnow.t.sol file:

function testEarnSnowBlock() public {
vm.prank(ashley);
snow.earnSnow();
vm.prank(victory);
vm.expectRevert();
snow.earnSnow();
}

Recommended Mitigation: Make the earn timer per user, not global:

mapping(address => uint256) private lastEarnedAt;
function earnSnowFix() external canFarmSnow {
if (lastEarnedAt[msg.sender] != 0 && block.timestamp < lastEarnedAt[msg.sender] + 1 weeks) {
revert S__Timer();
}
_mint(msg.sender, 1);
lastEarnedAt[msg.sender] = block.timestamp;
}
Updates

Lead Judging Commences

yeahchibyke Lead Judge
3 months ago
yeahchibyke Lead Judge 3 months ago
Submission Judgement Published
Invalidated
Reason: Design choice

Support

FAQs

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