3
function _checkOnERC721Received(
    address from,
    address to,
    uint256 tokenId,
    bytes memory _data
) private returns (bool) {
    if (to.isContract()) {
        try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {
            return retval == IERC721Receiver.onERC721Received.selector;
        } catch (bytes memory reason) {
            if (reason.length == 0) {
                revert("ERC721: transfer to non ERC721Receiver implementer");
            } else {
                assembly {
                    revert(add(32, reason), mload(reason))
                }
            }
        }
    } else {
        return true;
    }
}

1 Answer 1

7

If is usually called after a token has been transferred (in same tx).

If the receiver of the token is a contract, it checks if the contract implements the onERC721Received interface.

If no, it reverts the transaction.

If yes, the receiver contract has a onERC721Received method. The ERC721 calls this method, and now execution goes to the receiver contract to do whatever he wants. For example - staking the received token. [or more dangerously - reenter the ERC721 contarct.]

After the receiver token's onERC721Received finishes, the execution resumes in the ERC721 contract.

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.