contract IERC721Receiver {
  /**
   * @notice Handle the receipt of an NFT
   * @dev The ERC721 smart contract calls this function on the recipient
   * after a `safeTransfer`. This function MUST return the function selector,
   * otherwise the caller will revert the transaction. The selector to be
   * returned can be obtained as `this.onERC721Received.selector`. This
   * function MAY throw to revert and reject the transfer.
   * Note: the ERC721 contract address is always the message sender.
   * @param operator The address which called `safeTransferFrom` function
   * @param from The address which previously owned the token
   * @param tokenId The NFT identifier which is being transferred
   * @param data Additional data with no specified format
   * @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
   */
  function onERC721Received(
    address operator,
    address from,
    uint256 tokenId,
    bytes data
  )
    public
    returns(bytes4);
}
function onERC721Received(
  address operator,
  address from,
  uint256 tokenId,
  bytes data
)
  public
  returns(bytes4);

/**
 * @notice Handle the receipt of an NFT
 * @dev The ERC721 smart contract calls this function on the recipient
 * after a `safeTransfer`. This function MUST return the function selector,
 * otherwise the caller will revert the transaction. The selector to be
 * returned can be obtained as `this.onERC721Received.selector`. This
 * function MAY throw to revert and reject the transfer.
 * Note: the ERC721 contract address is always the message sender.
 * @param operator The address which called `safeTransferFrom` function
 * @param from The address which previously owned the token
 * @param tokenId The NFT identifier which is being transferred
 * @param data Additional data with no specified format
 * @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
 */