Snowman Merkle Airdrop

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

Snowman NFT can be minted for free

Root + Impact

Description

  • The Snowman NFT is supposed to be minted only when the receiver has enough Snow tokens and calls into the SnowmanAirdrop contract

  • The function mintSnowmanhas no access control modifier or any checks that prevents anybody from minting Snowman NFTs

    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 anybody can call the function and the cost is just that of an NFT minting

Impact:

  • HIGH as it completely breaks the whole business model of the contracts

Proof of Concept

The actual test of the Snowman contract already showcases the problem, as there is no vm.prankused here. However a quick modification to test that not only the owner can call the function would be:

function testAnybodyCanMintSnowman() public {
assert(nft.balanceOf(alice) == 0);
assert(nft.balanceOf(bob) == 0);
vm.prank(alice);
nft.mintSnowman(bob, 1);
vm.prank(bob);
nft.mintSnowman(alice, 1);
assert(nft.ownerOf(0) == bob);
assert(nft.ownerOf(1) == alice);
assert(nft.balanceOf(alice) == 1);
assert(nft.balanceOf(bob) == 1);
assert(nft.getTokenCounter() == 2);
}

Recommended Mitigation

Add a modifier that allows only the right account to call the minting function

address private immutable s_airdrop;
constructor(string memory _SnowmanSvgUri, address airdrop) {
s_airdrop = airdrop;
}
modifier onlySnowmanAirdrop() {
if (msg.sender != s_airdrop) {
revert SM_NotAllowed();
}
}
function mintSnowman(address receiver, uint256 amount) external onlySnowmanAirdrop {
...
}
Updates

Lead Judging Commences

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