ERC721 – Troubleshooting Transaction Failures in 0x Protocol on Rinkeby

0xerc-721rinkeby

I'm trying to interact with a signed order created using the ERC721Order from @0x/protocol-utils. Order created and signed using the following docs: https://docs.0x.org/nft-support/guides/signing-orders#signing-with-ethers

Example of the order:

const order = new ERC721Order({
  chainId: 4, // rinkeby
  verifyingContract: '0xdef1c0ded9bec7f1a1670819833240f027b25eff', // https://github.com/0xProject/protocol/blob/development/packages/contract-addresses/addresses.json
  direction: NFTOrder.TradeDirection.SellNFT,
  erc20Token: ETH_TOKEN_ADDRESS, // This address means eth, which we want.
  erc20TokenAmount: new BigNumber(optionMinPriceWei), // token amount in wei (i.e. the buy it now price)
  erc721Token: '0x0', // The actual erc721 contract address   
  erc721TokenId: new BigNumber('17'), // token id
  maker, // address of user selling the erc721 token
  taker: '0x0000000000000000000000000000000000000000', // Who can fill this order. May be NULL (0x000...) to allow anyone.
  nonce: new BigNumber(getRandomInt(10, 5000)), // random number 10-5000. TODO later https://docs.0x.org/nft-support/guides/creating-orders#choosing-a-nonce
  expiry: new BigNumber(Math.floor(Date.now() / 1000 + 86400)), // 1 day from now
  fees: [],
  erc721TokenProperties: [],
});

After signing it in the client and storing the "rawSignature" + the order data in my own DB. I'm trying to interact with the order using another wallet but the transaction fails.

I'm attempting to do this in TWO different ways with no success so far:

1) Using the @0x/contract-wrappers library following similar examples in GitHub (https://github.com/0xProject/0x-starter-project/blob/master/src/scenarios/fill_erc20_rfq_order_with_maker_order_signer.ts) but getting "execution reverted" message from different interactions with the contract like: getERC721OrderStatus, validateERC721OrderProperties and buyERC721 (not even getting the MetaMask to pop-up for the later).

Example of code:

  const { signature: rawSignature, erc721TokenID, erc20TokenAmount, expiry, nonce } = sellOrder; // stored in db
  const contractWrappers = new ContractWrappers(provider, { chainId: CHAIN_ID });

  const order = {
    taker: '0x0000000000000000000000000000000000000000', // Tried using the taker address
    direction: NFTOrder.TradeDirection.SellNFT, // Tried changing this
    maker: sellOrder.maker,
    erc20Token: sellOrder.erc20Token,
    erc721Token: sellOrder.erc721Token,
    nonce: new BigNumber(nonce), // Tried using string
    expiry: new BigNumber(expiry), // Tried using string
    erc721TokenId: new BigNumber(erc721TokenID), // Tried using string
    erc20TokenAmount: new BigNumber(erc20TokenAmount), // Tried using string
    fees: sellOrder.fees,
    erc721TokenProperties: [], // ??
  };

  const { v, r, s } = ethers.utils.splitSignature(rawSignature);
  const signature: Signature = {
    signatureType: SignatureType.EIP712,
    v,
    r,
    s,
  };

  const orderStatus = await contractWrappers.exchangeProxy
    .getERC721OrderStatus(order)
    .callAsync()
    .catch((error) => {
      console.error('getERC721OrderStatus', error); // catch to continue
    });
  console.log(orderStatus);

  const isValidOrder = await contractWrappers.exchangeProxy
    .validateERC721OrderProperties(order, new BigNumber(erc721TokenID))
    .callAsync()
    .catch((error) => {
      console.error('validateERC721OrderProperties', error); // catch to continue
    });
  console.log(isValidOrder);

  await contractWrappers.exchangeProxy
    .buyERC721(order, signature, '0x')
    // Also tried estimating gas
    .awaitTransactionSuccessAsync({
      from: taker,
      value: order.erc20TokenAmount,
      // from https://github.com/0xProject/0x-starter-project/blob/master/src/configs.ts
      gasPrice: 20e9,
      gas: 800000,
    });

2) Creating an instance of the Contract with ethers library using the abi (https://github.com/0xProject/protocol/blob/c1177416f50c2465ee030dacc14ff996eebd4e74/packages/contract-artifacts/artifacts/IZeroEx.json) and the contract address ("0xdef1c0ded9bec7f1a1670819833240f027b25eff") which I'm doing with other contracts like ERC721 successfully. For this one the execution of the method buyERC721 does open my MetaMask to sign and send the tx but it fails with the following: error: transaction failed [ See: https://links.ethers.org/v5-errors-CALL_EXCEPTION ]. Getting the same error for the view functions: getERC721OrderStatus and validateERC721OrderProperties .

Example code:

const { signature: rawSignature, erc721TokenID, erc20TokenAmount, expiry, nonce } = sellOrder;
  const order: any = {
    taker: '0x0000000000000000000000000000000000000000',
    direction: NFTOrder.TradeDirection.SellNFT,
    maker: sellOrder.maker,
    erc20Token: sellOrder.erc20Token,
    erc721Token: sellOrder.erc721Token,
    nonce: String(nonce) as any,
    expiry: String(expiry) as any,
    erc721TokenId: String(erc721TokenID) as any,
    erc20TokenAmount: String(erc20TokenAmount) as any,
    fees: sellOrder.fees,
    erc721TokenProperties: [], // ??
  };
  const { v, r, s } = ethers.utils.splitSignature(rawSignature);
  const signature: Signature = {
    signatureType: SignatureType.EIP712,
    v,
    r,
    s,
  };

  await getERC721OrderStatus(order).catch((error: any) => {
    console.error('getERC721OrderStatus', error);
  });

  await validateERC721OrderProperties(order, order.erc721TokenId).catch((error: any) => {
    console.error('validateERC721OrderProperties', error);
  });

  const overrides: PayableOverrides = {
    value: order.erc20TokenAmount as any,
    gasLimit: '800000',
  };

  // genTransactionFn - returns a wrapper fn that calls the callback (buyERC721) with any args sent
  // and waits for it to have at least 1 confirmation
  // this helper is being used for other contract interactions (not 0x) successfully.
  const buyERC721Fn = genTransactionFn(buyERC721);
  const response = await buyERC721Fn(order, signature, '0x', overrides);

  return response;

Best Answer

0x v4 is not deployed on Rinkeby; currently the only testnet that it is deployed on is Ropsten. You can see the list of chains 0x v4 is deployed to in this cheat sheet.

Related Topic