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

The collectPresent function allows an address with right status to collect infinite tokens

Summary

The collectPresent function in the smart contract is designed to reward users based on their status (NICE or EXTRA NICE) with NFTs and SantaTokens. However, a critical vulnerability exists in this function, allowing users to collect an unlimited number of tokens.

Vulnerability Details

The vulnerability in the collectPresent function stems from the lack of checks to prevent users from collecting more than once. Although the function attempts to restrict users from collecting multiple times by checking their balance (balanceOf(msg.sender) > 0), this method is flawed. A user can bypass this restriction by simply transferring their existing token to another address, thereby resetting their balance to zero. This allows them to collect additional NFTs and SantaTokens indefinitely, as long as they continue transferring each newly acquired token to another address.

Impact

This vulnerability poses a severe threat as it allows for the unlimited minting of NFTs and SantaTokens. Since there is no supply control for either, a user with the EXTRA NICE status can potentially mint infinite amounts of both, leading to hyperinflation of the tokens and devaluation. The integrity of the token distribution system is compromised, undermining the credibility of the entire system.

Tools Used

Manual Code Review

Recommendations

  • Implement a more robust mechanism to track whether a user has already collected their present. This could involve maintaining a mapping of addresses to boolean values, marking whether they have already collected their reward.

mapping(address => bool) private hasCollected;
function collectPresent() external {
if (block.timestamp < CHRISTMAS_2023_BLOCK_TIME) {
revert SantasList__NotChristmasYet();
}
if (hasCollected[msg.sender]) {
revert SantasList__AlreadyCollected();
}
hasCollected[msg.sender] = true;
if (s_theListCheckedOnce[msg.sender] == Status.NICE && s_theListCheckedTwice[msg.sender] == Status.NICE) {
_mintAndIncrement();
return;
} else if (
s_theListCheckedOnce[msg.sender] == Status.EXTRA_NICE
&& s_theListCheckedTwice[msg.sender] == Status.EXTRA_NICE
) {
_mintAndIncrement();
i_santaToken.mint(msg.sender);
return;
}
revert SantasList__NotNice();
};
  • Adittional note: Consider adding a supply cap for both NFTs and SantaTokens to prevent hyperinflation and maintain their value.

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.