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

Use `ERC721::_safe_mint()` instead of `ERC721::_mint()`

Summary

The Snek-Raffle project is using the snekmate library from pcaversaccio for implementing the ERC721 standard. This library has two internal functions for creating and sending new non-fungible tokens: _safe_mint() and _mint(). As indicated by its name, _safe_mint() is considered safer as it checks whether the receiver supports ERC721 tokens.

Vulnerability Details

The code snippet below shows the fulfillRandomWords() function calling the insecure _mint() function, contrary to the recommendations from the library:

@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
self.tokenIdToRarity[ERC721._total_supply()] = rarity
log WinnerPicked(recent_winner)
@> ERC721._mint(recent_winner, ERC721._total_supply())
send(recent_winner, self.balance)

See the comment from the ERC721 library:

@internal
def _mint(owner: address, token_id: uint256):
"""
@dev Mints `token_id` and transfers it to `owner`.
@notice Note that `token_id` must not exist and
`owner` cannot be the zero address.
@> WARNING: Usage of this method is discouraged,
@> use `_safe_mint` whenever possible.
@param owner The 20-byte owner address.
@param token_id The 32-byte identifier of the token.
"""

Impact

Raffle winners could lose access to their Snek NFTs if they use smart contracts that do not have support for the ERC721 standard.

Tools Used

Manual analysis.

Recommendations

It is recommended to use _safe_mint() over _mint() as shown in the example below:

log WinnerPicked(recent_winner)
- ERC721._mint(recent_winner, ERC721._total_supply())
+ ERC721._safe_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
Invalidated
Reason: Incorrect statement
EloiManuel Submitter
over 1 year ago
inallhonesty Lead Judge
over 1 year ago
EloiManuel Submitter
over 1 year ago
inallhonesty Lead Judge
over 1 year ago
EloiManuel Submitter
over 1 year ago
inallhonesty Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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