Snowman Merkle Airdrop

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

Breaking invariant - Missing Access Control for NFT Minting

Root + Impact

Description

The mintSnowman function in Snowman.sol is accessible to any external contract without proper access control.

This violates the project's invariant that "Stakers of the Snow token receive this NFT" as anyone can mint NFTs without being a Snow token staker.

function mintSnowman(address receiver, uint256 amount) external {
for (uint256 i = 0; i < amount; i++) {
_safeMint(receiver, s_TokenCounter);
emit SnowmanMinted(receiver, s_TokenCounter);
s_TokenCounter++;
}
}

Risk

Likelihood:

  • High as anyone can call the mintSnowman function without any staking required check

Impact:

High as it breaks the invariant - Stakers of the Snow token receive this NFT.

Proof of Concept

  1. Any external contract can call mintSnowman

  2. No checks for Snow token staking status

  3. NFTs can be minted to any address

  4. This allows non-stakers to receive NFTs, violating the project's core invariant

Recommended Mitigation

Add proper access control and staking verification:

contract Snowman is ERC721, Ownable {
ISnow public immutable i_snowToken;
modifier onlyStaker() {
require(i_snowToken.balanceOf(msg.sender) > 0, "Not a Snow token staker");
_;
}
constructor(
string memory _SnowmanSvgUri,
address _snowToken
) ERC721("Snowman Airdrop", "SNOWMAN") Ownable(msg.sender) {
s_TokenCounter = 0;
s_SnowmanSvgUri = _SnowmanSvgUri;
i_snowToken = ISnow(_snowToken);
}
function mintSnowman(address receiver, uint256 amount) external onlyStaker {
require(i_snowToken.balanceOf(receiver) > 0, "Receiver must be a staker");
for (uint256 i = 0; i < amount; i++) {
_safeMint(receiver, s_TokenCounter);
emit SnowmanMinted(receiver, s_TokenCounter);
s_TokenCounter++;
}
}
}
Updates

Lead Judging Commences

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

Unrestricted NFT mint function

The mint function of the Snowman contract is unprotected. Hence, anyone can call it and mint NFTs without necessarily partaking in the airdrop.

Support

FAQs

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