Skip to main content

ERC-721 Enumerable Transfer Facet

ERC-721 token transfers within a diamond

Key Features
  • Exposes external functions for diamond routing of ERC-721 transfers.
  • Accesses shared ERC-721 state via diamond storage.
  • Supports standard ERC-721 transfer and safe transfer operations.
  • Includes a mechanism (exportSelectors) for diamond selector discovery.

Overview

This facet implements ERC-721 token transfers as external functions in a diamond. It routes calls through the diamond proxy and accesses shared storage via ERC721Storage. Developers add this facet to expose token transfer functionality while maintaining upgradeability.

Storage

ERC721EnumerableStorage

Definition
struct ERC721EnumerableStorage {
mapping(address owner => mapping(uint256 index => uint256 tokenId)) ownerTokens;
mapping(uint256 tokenId => uint256 ownerTokensIndex) ownerTokensIndex;
uint256[] allTokens;
mapping(uint256 tokenId => uint256 allTokensIndex) allTokensIndex;
}

ERC721Storage

Definition
struct ERC721Storage {
mapping(uint256 tokenId => address owner) ownerOf;
mapping(address owner => uint256 balance) balanceOf;
mapping(address owner => mapping(address operator => bool approved)) isApprovedForAll;
mapping(uint256 tokenId => address approved) approved;
}

State Variables

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

Functions

transferFrom

Transfers a token from one address to another.

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

Parameters:

PropertyTypeDescription
_fromaddressThe current owner of the token.
_toaddressThe recipient address.
_tokenIduint256The token ID to transfer.

safeTransferFrom

Safely transfers a token, checking for receiver contract compatibility.

function safeTransferFrom(address _from, address _to, uint256 _tokenId) external;

Parameters:

PropertyTypeDescription
_fromaddressThe current owner of the token.
_toaddressThe recipient address.
_tokenIduint256The token ID to transfer.

safeTransferFrom

Safely transfers a token with additional data.

function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes calldata _data) external;

Parameters:

PropertyTypeDescription
_fromaddressThe current owner of the token.
_toaddressThe recipient address.
_tokenIduint256The token ID to transfer.
_databytesAdditional data to send to the receiver contract.

exportSelectors

Exports the function selectors of the ERC721EnumerableTransferFacet This function is use as a selector discovery mechanism for diamonds

function exportSelectors() external pure returns (bytes memory);

Returns:

PropertyTypeDescription
-bytesselectors The exported function selectors of the ERC721EnumerableTransferFacet

Events

Errors

Best Practices

Best Practice
  • Ensure the ERC721Storage struct is properly initialized and accessible by this facet.
  • Verify that other facets do not interfere with the token ownership state managed by this facet.
  • Call transferFrom, safeTransferFrom functions through the diamond proxy address.

Security Considerations

Security

The transferFrom and safeTransferFrom functions handle token ownership transfers. Reentrancy is mitigated by the checks-effects-interactions pattern. Input validation is crucial; ensure token IDs are valid and ownership rules are respected. Errors ERC721NonexistentToken, ERC721IncorrectOwner, ERC721InvalidReceiver, and ERC721InsufficientApproval are used to revert on invalid operations. The safeTransferFrom variations include checks for receiver contract compatibility.

Was this helpful?
Last updated:

Newsletter

Get notified about releases, feature announcements, and technical deep-dives on building smart contracts with Compose.

No spam. Unsubscribe anytime.