Users are restricted to collect NFT only 1 time as stated in the docs but due to weak duplicacy check inside the SantasList::collectPresent function, one can mint NFT as many times they want by transferring their NFT to their alternate address and bypassing the weak duplicacy check as it will fail because the user now has 0 balance of NFT after transferring, thus again minting a NFT by calling collectPresent function.
This will lead to minting of the NFT as many times a user want, thus going against the protocol rules set by Santa.
Also, one can collect NFT and transfer it to other NICE
or EXTRA_NICE
person and tease them to not be able to mint NFT even though they have not collected it by calling the collectPresent
function but they can collect it by transferring the NFT to address(0).
The vulnerability is due to the weak duplicacy check present inside the function SantasList::collectPresent function at line 151. The check is not strong enough to check for duplicate minting of NFT by a user.
As the check just validate the user's nft balance if it is zero or not, the nft minted by collectPresent
function can be transferred to another address by calling transferFrom
function on the SantasList contract leaving the NFT balance to 0, thus collectPresent
function can be again called as the check will fail as the user's NFT balance is 0 due transferring it to another address, thus collectPresent can be called again and again, and NFT can be minted as many times.
Refactor the import in file test/unit/SantasListTest.t.sol
: (Vm is used to get array to get the Log array to store recorded event logs)
to
Add the test in the file test/unit/SantasListTest.t.sol
Run the test:
The Santa allows a NICE
or EXTRA_NICE
person to mint NFT a single time by calling the collectPresent function but due to the weak check the protocol can be tricked and NFT can be minted as many times, thus it violates the protocol rules and hence it creates high impact on the protocol as well as on Santa.
Also, malicious users can tease NICE
or EXTRA_NICE
to not be able to mint NFT by transferring their NFT to their address and as their NFT balance becomes > 0, thus they can't collect their present as collectPresent function call will revert.
Manual Review, Foundry Test
Instead of checking the user's NFT balance, add a mapping to check whether a user has collected the present or not. (Remember to follow the CEI pattern)
Now, it doesn't depend on the user's NFT balance and one can't collect NFT the other time as it only allows the eligible users to call it once.
Relying on balanceOf > 0 in collectPresent() allows the msg.sender to send their present to another address and then collect again.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.