IERC721 Token Receiver…How?

A Blueberry Dog
2 min readAug 1, 2021

If you are new to the IERC721 token standard, AKA the NFT token standard, you might be wondering what safeTransferFrom is and how it differs from transferFrom. We will offer a quick explanation and give some examples of safe transfers in action.

Contract vs Account Addresses

Both contract and account addresses are represented as hexadecimal numbers. If you send a token to a user-controlled account, it is possible for them to send it back or send it to someone else, but if you send a token to a wrong contract address, it may be impossible to get it back. In other words, the token gets stuck forever. This is where safeTransferFrom comes to the rescue.

IERC721Receiver() and onERC721Received()

The safeTransferFrom function has the same behavior as transferFrom if the destination address is an account address, and if the destination is a contract address, it transfers the token and immediately calls the contract’s onERC721Received function. If the contract does not implement this function, the transfer fails. This eliminates accidental transfers to contracts that are not meant to receive NFTs. Hence, safeTransferFrom is a failsafe for unintended transfers to contract addresses.

An NFT Staking Example

For example, one can transfer an ERC721 token to a staking contract to gradually accumulate an ERC20 as yield. The staking contract implements the IERC721 interface.

In this code snippet, we can see exactly what the onERC721Received function does with the incoming NFT.

  1. It checks that the sender is our whitelisted NFT contract.
  2. It calls _stakeNFT() and stakes the NFT. (stores the staker address in a data structure and emits an event)
  3. It calls _onStake, which checks that certain conditions are met (the owner must have sufficient staking slots, otherwise the NFT is refused). It updates some counters, for example total number of NFTs staked.

Conclusion

The safeTransferFrom has the same behavior as the transferFrom function when the destination address is a user account. When the destination is a contract, safeTransferFrom tries to call the onERC721Received function defined in the contract. If this function is not implemented by the contract, it most likely should not be receiving NFTs in the firs place, and the transfer fails.

--

--

A Blueberry Dog

Technical guides and tutorials for the emerging web3 developer community ❤