Beginner FriendlyFoundryNFT
100 EXP
View results
Submission Details
Severity: medium
Valid

The fulfillRandomWords function not compare the random number with the rarity value, resulting in all NFTs having the same rarity

Summary

The fulfillRandomWords function does not compare the rarity value, resulting in equal rarity for all NFTs, which contradicts the documented rarity distribution.

Vulnerability Details

Within the fulfillRandomWords function, rarity is solely determined by the result of a random number modulo 3 operation. Consequently, the chances of obtaining common, rare, and legendary NFTs are identical. This deviates from the documented rarity distribution, which specifies:

Common: 70%
Rare: 25%
Legendary: 5%

Impact

This oversight allows anyone to obtain a legendary NFT with a 33% chance instead of the intended 5% probability. Similarly, users have a 33% chance of receiving a rare NFT instead of the intended 25% probability.

Tools Used

Manual Review

Recommendations

Before assigning rarity, ensure that the calculated rarity is compared to 100.

@internal
def fulfillRandomWords(request_id: uint256, random_words: uint256[MAX_ARRAY_SIZE]):
index_of_winner: uint256 = random_words[0] % len(self.players)
recent_winner: address = self.players[index_of_winner]
self.recent_winner = recent_winner
self.players = []
self.raffle_state = RaffleState.OPEN
self.last_timestamp = block.timestamp
- rarity: uint256 = random_words[0] % 3 # @audit-issue
+ result: uint256 = random_words[0] % 100
+ rarity: uint256 = COMMON
+ if(result>70) rarity = RARE
+ if(result>95) rarity = LEGEND
self.tokenIdToRarity[ERC721._total_supply()] = rarity
log WinnerPicked(recent_winner)
ERC721._mint(recent_winner, ERC721._total_supply())
send(recent_winner, self.balance)
Updates

Lead Judging Commences

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

Rarity is 1/3 instead of what the docs say

Support

FAQs

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