I'm testing transferring a minted NFT from a regular address to this smart contract's address (I'm creating a DEX), but whenever I test it with Truffle I get the error VM Exception while processing transaction: revert.

contract Exchange is ERC721Enumerable {
    function sellToExchange(uint256 _tokenId, uint256 _sellPrice) public {
       safeTransferFrom(msg.sender, payable(this), _tokenId);

I don't understand why I keep getting this error. If I call the exact same function with transferFrom() instead, it passes my test, but not with safeTransferFrom().

I'm using OpenZeppelin's ERC721 contract by the way.

Also, should I make the smart contract's address a type of address or address payable in order to receive the NFT?


The issue was that in order to receive NFT/ERC721 tokens to a smart contract address, that address needs to inherit ERC721Holder.sol which is found on OpenZeppelin's contract GitHub repo (link below).


  • Has msg.sender authorized the contract to access to _tokenId? See approve in their docs docs.openzeppelin.com/contracts/3.x/api/token/…
    – Ismael
    Jun 9, 2021 at 5:36
  • I figured out why. I needed to inherit ERC721Receiver to be able to let my contract accept NFT tokens.
    – Adrian D.
    Jun 9, 2021 at 22:23
  • It will be awesome if you could add the solution as an answer so it can help others.
    – Ismael
    Jun 10, 2021 at 0:39

1 Answer 1


Try this: safeTransferFrom(ownerOf(_tokenId), payable(this), _tokenId);

  • 1
    payable address is only for receiving ether, not tokens.
    – turboza
    Jun 16, 2022 at 16:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.