Skip to main content

ERC-721 Transfer Facet

ERC-721 token transfers within a diamond

Key Features
  • Exposes external ERC-721 transfer functions for diamond routing.
  • Internally uses internalTransferFrom for core transfer logic and validation.
  • Accesses shared diamond storage for ERC-721 state.
  • Supports safeTransferFrom with and without additional data.

Overview

This facet provides external functions for ERC-721 token transfers, routed through the diamond proxy. It interacts with shared diamond storage via the getStorage internal function. Developers integrate this facet to enable token transfer functionality while preserving diamond's upgradeability.

Storage

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"))

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 address to receive the token.
_tokenIduint256The token ID to transfer.

safeTransferFrom

Safely transfers a token, checking if the receiver can handle ERC-721 tokens.

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

Parameters:

PropertyTypeDescription
_fromaddressThe current owner of the token.
_toaddressThe address to receive the token.
_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 address to receive the token.
_tokenIduint256The token ID to transfer.
_databytesAdditional data with no specified format.

exportSelectors

Exports the function selectors of the ERC721TransferFacet 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 ERC721TransferFacet

Events

Errors

Best Practices

Best Practice
  • Initialize ERC721 storage correctly before adding this facet.
  • Ensure the caller has the necessary ownership or approval before invoking transfer functions.
  • Verify that receiver contracts implement the ERC721TokenReceiver interface when using safeTransferFrom.

Security Considerations

Security

All state-changing functions (transferFrom, safeTransferFrom) perform checks before state modifications, adhering to the checks-effects-interactions pattern. Reentrancy is mitigated by the diamond's proxy nature and the internal checks. Input validation is performed to prevent transfers of non-existent tokens, incorrect ownership, or to invalid receivers. Errors ERC721NonexistentToken, ERC721IncorrectOwner, ERC721InvalidReceiver, and ERC721InsufficientApproval are used to signal failures.

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.