Beginner FriendlyFoundryNFT
100 EXP
View results
Submission Details
Severity: high
Invalid

OneShot.mintRapper(): Users can mint as many rapper NFTs as they wish for free

Summary

Users can mint as many rapper NFTs as they wish without any cost, making the NFT worthless.

Vulnerability Details

OneShot.mintRapper() has no access control and it does not check if msg.sender already minted a NFT:

function mintRapper() public {
uint256 tokenId = _nextTokenId++;
_safeMint(msg.sender, tokenId);
// Initialize metadata for the minted token
rapperStats[tokenId] =
RapperStats({weakKnees: true, heavyArms: true, spaghettiSweater: true, calmAndReady: false, battlesWon: 0});
}

User can mint as many rapper NFTs as wish since there is no upper bound on the totalSupply of this NFT.

Impact

Each rapper NFT becomes worthless since anyone can mint as many as wish and it is free to mint.

PoC

For example, a random user can mint 100 NFTs for free. Add the following test case to OneShotTest.t.sol:

function testPoCMintRapperManyTimes() public {
vm.startPrank(user);
for (uint i = 0; i < 100; i++) {
oneShot.mintRapper();
}
vm.stopPrank();
assertEq(oneShot.balanceOf(user), 100);
}

Run test:

forge test --match-test testPoCMintRapperManyTimes -vv

Tools Used

Manual review

Recommendations

Consider adding a mapping to record if msg.sender already minted an NFT:

mapping(address => bool) public alreadyMinted;
...
function mintRapper() public {
require(!alreadyMinted[msg.sender], "already minted");
uint256 tokenId = _nextTokenId++;
_safeMint(msg.sender, tokenId);
// Initialize metadata for the minted token
rapperStats[tokenId] =
RapperStats({weakKnees: true, heavyArms: true, spaghettiSweater: true, calmAndReady: false, battlesWon: 0});
}
Updates

Lead Judging Commences

inallhonesty Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Design choice

Support

FAQs

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