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

Users can collect many presents

Summary

Based on this requirement, "An address is only allowed to collect 1 NFT per address, there is a check in the codebase to prevent someone from minting duplicate NFTs" . Lets look at the check to prevent this

inside the collectPresent function there is this function that prevents users from collecting more NFTs

if (balanceOf(msg.sender) > 0) {
revert SantasList__AlreadyCollected();
}

this prevents users from collecting presents if they already have collected since there balance will be more than 0 in this case

Vulnerability Details

The contract currently lacks a robust mechanism to prevent multiple NFT collections by the same address. lets look at this POC

Impact

Bob is a nice user and is eligible for presents from santa.

Bob has a best friend Alice who is not nice, and is not eligible for rewards.

Bob tries to collect his present. this will succeed since he is nice and can get the present from santa.

the check to ensure that Bobs balance is not greater than 0 passes and Bob gets his present.

When Bob tries to collect the present again it will revert now that his balance is more than 0.

Bob now buys a present for his friend Alice who is not eligible for presents and the Token is burned using the burn function.

now the balance of Bob is back to 0 and when he tries to collect another NFT the check will still pass since his balance will be back to 0.

He can continue doing this process multiple times till he gets unlimited number of tokens

Tools Used

manual review

Recommendations

Introduce a mapping or mechanism within the contract to track addresses that have already collected their presents. as follows

mapping(address => bool) private s_hasCollectedPresent;

then as you check to ensure the balance is not greater than 0 also include one to see that the user is yet to collect the present as below

if (balanceOf(msg.sender) > 0 || s_hasCollectedPresent[msg.sender]) {
revert SantasList__AlreadyCollected();
}

this way only users that are yet to collect there presents will be eligible

Updates

Lead Judging Commences

equious Auditor
over 1 year ago
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.