IERC721Receiver should not be a public function

I'm currently creating a smart contract that users can send their NFTs to.

Upon receiving the NFT, I emit an event and process that event later on on another machine.

The issue is quite simple as raised in Implementation of an IERC721Receiver Contract - Preventing bad actor scenarios? as well.

There will definitely be bad actors tricking the contract by called on onERC721Received on my contract.

Now before processing the emitted event on the other machine, I'll have to add additional checks to see if indeed an NFT was transferred to my contract with correct details.

What's the point of this extra work? Why is onERC721Received public?

Because ERC721 requires the implementation of that function. It makes sense to already provide it in the OZ implementation.

What do you mean extra work? if the your function requires the user sent you a NFT you need to check if you got it. Not sure what onERC721Received has to do with that, except that you make sure you have no re-entrancy vulnerability.

1 Like

It must be public for the token to invoke it. There is no other option.

However, you may be able to restrict who can successfully invoke the function. If your contract only works with a specific NFT you can add a require check in onERC721Received so that msg.sender must be that specific NFT.

If your contract has to work with any possible NFT, your backend may need to have some logic to handle transfers that don't correspond to legitimate tokens, as you described. I don't see a way around this.

1 Like