Snowman Merkle Airdrop

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

Missing Access Control on mint function

Missing Access Control in Snowman.sol::mintSnowman() Causes any one can Mint arbitrary amount of NFT's

Description

Normal Behaviour: The Snowman.sol::mintSnowman() function should restrict NFT minting to onlyOwner, to enforce fair distribution

Issue : The function lacks access control, allowing any external address to mint unlimited NFTs for free, violating the contract’s intended economic model.

<@ 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:

  • Public Exploitability: The function is external and callable by anyone, making abuse inevitable.

  • Economic Incentive: Attackers will exploit this to hoard/sell NFTs or disrupt the project’s tokenomics.

Impact:

  • Unlimited NFT supply

  • Spam attacks that bloat the contract state

Proof of Concept

The provided PoC demonstrates how any arbitrary user can mint NFTs without restrictions, exploiting the missing access control and supply cap in Snowman.sol.

function testInfiniteMintingAttack() public {
address attacker = makeAddr("attacker");
vm.startPrank(attacker);
// Attempt to mint the maximum possible NFTs (2^256 - 1)
nft.mintSnowman(attacker, type(uint256).max);
// Verify the attack succeeded (balance would overflow, but the counter keeps increasing)
assertEq(nft.balanceOf(attacker), type(uint256).max, "Attacker minted infinite NFTs!");
}

Recommended Mitigation

The current mintSnowman() function lacks below** critical security measure**:

  1. Access Control (who can mint?)

This allows anyone to mint an unlimited number of NFTs.


1. Add Access Control (Restrict Minting to Owner)

Why?

  • Prevents unauthorized users from minting NFTs.

  • Ensures only the contract owner (or a privileged role) can control supply.

- 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++;
- }
- }
+ 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++;
+ }
+ }
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.