Skip to main content

ERC721EnumerableMod

Internal logic for enumerable ERC-721 tokens

Key Features
  • Exposes internal functions for mint, burn, and transfer operations.
  • Integrates with the diamond storage pattern via a predefined storage slot.
  • Utilizes custom errors for gas-efficient error reporting.
  • No external dependencies or using directives, promoting composability.
Module Usage

This module provides internal functions for use in your custom facets. Import it to access shared logic and storage.

Overview

This module provides internal functions for managing enumerable ERC-721 tokens using the diamond storage pattern. Facets can import this module to implement minting, burning, and transfer logic while maintaining token enumeration order. Changes made through this module are immediately visible to all facets accessing the shared storage.


Storage

ERC721EnumerableStorage

Definition
struct ERC721EnumerableStorage {
mapping(uint256 tokenId => address owner) ownerOf;
mapping(address owner => uint256[] ownerTokens) ownerTokens;
mapping(uint256 tokenId => uint256 ownerTokensIndex) ownerTokensIndex;
uint256[] allTokens;
mapping(uint256 tokenId => uint256 allTokensIndex) allTokensIndex;
mapping(address owner => mapping(address operator => bool approved)) isApprovedForAll;
mapping(uint256 tokenId => address approved) approved;
string name;
string symbol;
string baseURI;
}

State Variables

PropertyTypeDescription
STORAGE_POSITIONbytes32Diamond storage slot position for this module (Value: keccak256("compose.erc721.enumerable"))

Functions

burn

Burns (destroys) an existing ERC-721 token, removing it from enumeration lists. Reverts if the token does not exist or if the sender is not authorized.

function burn(uint256 _tokenId, address _sender) ;

Parameters:

PropertyTypeDescription
_tokenIduint256The ID of the token to burn.
_senderaddressThe address initiating the burn.

getStorage

Returns the ERC-721 enumerable storage struct from its predefined slot. Uses inline assembly to point to the correct diamond storage position.

function getStorage() pure returns (ERC721EnumerableStorage storage s);

Returns:

PropertyTypeDescription
sERC721EnumerableStorageThe storage reference for ERC-721 enumerable state variables.

mint

Mints a new ERC-721 token to the specified address, adding it to enumeration lists. Reverts if the receiver address is zero or if the token already exists.

function mint(address _to, uint256 _tokenId) ;

Parameters:

PropertyTypeDescription
_toaddressThe address that will own the newly minted token.
_tokenIduint256The ID of the token to mint.

transferFrom

Transfers a token ID from one address to another, updating enumeration data. Validates ownership, approval, and receiver address before state updates.

function transferFrom(address _from, address _to, uint256 _tokenId, address _sender) ;

Parameters:

PropertyTypeDescription
_fromaddressThe current owner of the token.
_toaddressThe address receiving the token.
_tokenIduint256The ID of the token being transferred.
_senderaddressThe initiator of the transfer (may be owner or approved operator).

Events

Errors

Best Practices

Best Practice
  • Ensure the ERC721EnumerableMod is correctly initialized with the diamond's storage pointer.
  • Verify ownership and approval checks are performed by the calling facet before invoking transferFrom or burn.
  • Handle potential errors like ERC721NonexistentToken or ERC721IncorrectOwner in facet logic.

Integration Notes

Shared Storage

This module reads and writes to diamond storage at the position identified by keccak256(\"compose.erc721.enumerable\"). The ERC721EnumerableStorage struct, containing state like token name, symbol, and base URI, is managed at this slot. All functions are internal and directly interact with this shared storage, making changes immediately visible to any facet accessing the same storage position.

Was this helpful?
Last updated: