ethers-io / ethers.js

Complete Ethereum library and wallet implementation in JavaScript.
https://ethers.org/
MIT License
7.91k stars 1.84k forks source link

invalid arrayify value when providing the argument of type bytes / bytes[] for write transaction using ethers js #3805

Open kombos opened 1 year ago

kombos commented 1 year ago

Describe the Feature

I'm trying to create a write transaction with these value:

const univ3StakerABI = [
  {
    "inputs": [
      { "internalType": "bytes[]", "name": "data", "type": "bytes[]" }
    ],
    "name": "multicall",
    "outputs": [
      { "internalType": "bytes[]", "name": "results", "type": "bytes[]" }
    ],
    "stateMutability": "payable",
    "type": "function"
  },
];

 if (isConnected && address && tokenId) {
    unstakeTokenTxn = stakerContract?.interface?.encodeFunctionData?.(
      "unstakeToken((address,address,uint256,uint256,address),uint256)",
      [  [
            "0x2C4F1DF9c7DE0C59778936C9b145fF56813F3295",
            "0xf5b8304dc18579c4247caad705df01928248bc71",
            1676041245,
            1676214045,
            "0x0ad4de31fc1E1e01Eaaf815dA18690441190f7ed",
          ], 443323]
    );

    withdrawTokenTxn = stakerContract?.interface?.encodeFunctionData?.(
      "withdrawToken(uint256,address,bytes)",
      [443323, "0xae6094170ABC0601b4bbe933D04368cD407C186a", []]
    );
  }

  const multiCallDataBytesArray = [
    ethers.utils.arrayify(unstakeTokenTxn),
    ethers.utils.arrayify(withdrawTokenTxn),
  ];

const { config } = usePrepareContractWrite({
    address: "0xe34139463bA50bD61336E0c446Bd8C0867c6fE65",
    abi: univ3StakerABI,
    functionName: "multicall(bytes[])",
    args: [multiCallDataBytesArray],
    enabled: isConnected && address && tokenId,
    chainId: 1,
    onError(error) {
      console.error(error);
      toast.error(PREPARE_CONTRACT_ERROR, toastConfig);
    },
  });

  const { writeAsync } = useContractWrite({
    ...config,
    onError(error) {
      console.error(error);
      notify(null, toastId, "Transaction Aborted. Try again.");
      toastId = null;
    },
  });

its throwing this error in prepare phase, but if we ignore and finish the transaction, it is going through successfully:

 Error: invalid arrayify value (argument="value", value={"0":245,"1":73,"2":171,"3":66,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":44,"17":79,"18":29,"19":249,"20":199,"21":222,"22":12,"23":89,"24":119,"25":137,"26":54,"27":201,"28":177,"29":69,"30":255,"31":86,"32":129,"33":63,"34":50,"35":149,"36":0,"37":0,"38":0,"39":0,"40":0,"41":0,"42":0,"43":0,"44":0,"45":0,"46":0,"47":0,"48":245,"49":184,"50":48,"51":77,"52":193,"53":133,"54":121,"55":196,"56":36,"57":124,"58":170,"59":215,"60":5,"61":223,"62":1,"63":146,"64":130,"65":72,"66":188,"67":113,"68":0,"69":0,"70":0,"71":0,"72":0,"73":0,"74":0,"75":0,"76":0,"77":0,"78":0,"79":0,"80":0,"81":0,"82":0,"83":0,"84":0,"85":0,"86":0,"87":0,"88":0,"89":0,"90":0,"91":0,"92":0,"93":0,"94":0,"95":0,"96":99,"97":230,"98":92,"99":29,"100":0,"101":0,"102":0,"103":0,"104":0,"105":0,"106":0,"107":0,"108":0,"109":0,"110":0,"111":0,"112":0,"113":0,"114":0,"115":0,"116":0,"117":0,"118":0,"119":0,"120":0,"121":0,"122":0,"123":0,"124":0,"125":0,"126":0,"127":0,"128":99,"129":232,"130":255,"131":29,"132":0,"133":0,"134":0,"135":0,"136":0,"137":0,"138":0,"139":0,"140":0,"141":0,"142":0,"143":0,"144":10,"145":212,"146":222,"147":49,"148":252,"149":30,"150":30,"151":1,"152":234,"153":175,"154":129,"155":93,"156":161,"157":134,"158":144,"159":68,"160":17,"161":144,"162":247,"163":237,"164":0,"165":0,"166":0,"167":0,"168":0,"169":0,"170":0,"171":0,"172":0,"173":0,"174":0,"175":0,"176":0,"177":0,"178":0,"179":0,"180":0,"181":0,"182":0,"183":0,"184":0,"185":0,"186":0,"187":0,"188":0,"189":0,"190":0,"191":0,"192":0,"193":6,"194":170,"195":39}, code=INVALID_ARGUMENT, version=bytes/5.7.0)
    at Logger.makeError (index.js:231:23)
    at Logger.throwError (index.js:240:20)
    at Logger.throwArgumentError (index.js:243:21)
    at arrayify (index.js:111:19)
    at BytesCoder.encode (bytes.js:19:79)
    at eval (array.js:59:19)
    at Array.forEach (<anonymous>)
    at pack (array.js:53:12)
    at ArrayCoder.encode (array.js:194:16)
    at eval (array.js:59:19)
    at Array.forEach (<anonymous>)
    at pack (array.js:53:12)
    at TupleCoder.encode (tuple.js:57:60)
    at AbiCoder.encode (abi-coder.js:106:15)
    at Interface._encodeParams (interface.js:273:31)
    at Interface.encodeFunctionData (interface.js:315:18)
    at eval (index.js:141:41)
    at Generator.next (<anonymous>)
    at fulfilled (index.js:21:58)

Code Example

No response

zemse commented 1 year ago

Can you console log the unstakeTokenTxn just before doing multiCallDataBytesArray? Also, is unstakeTokenTxn assigned elsewhere? It seems like it is JSON stringified and parsed again.

kombos commented 1 year ago

Can you console log the unstakeTokenTxn just before doing multiCallDataBytesArray? Also, is unstakeTokenTxn assigned elsewhere? It seems like it is JSON stringified and parsed again.

Hi, please find the console logs below. also both these variables are not assigned or modfied elsewhere:

unstakeTokenTxn: 0xf549ab420000000000000000000000002c4f1df9c7de0c59778936c9b145ff56813f3295000000000000000000000000f5b8304dc18579c4247caad705df01928248bc710000000000000000000000000000000000000000000000000000000063e65c1d0000000000000000000000000000000000000000000000000000000063e8ff1d0000000000000000000000000ad4de31fc1e1e01eaaf815da18690441190f7ed000000000000000000000000000000000000000000000000000000000006a747

withdrawTokenTxn: 0x3c423f0b000000000000000000000000000000000000000000000000000000000006a7470000000000000000000000009709f170c885cc844d6b30691b63686502bbda3600000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000

zemse commented 1 year ago

These values should work. At what point are you getting the error? Is it around multiCallDataBytesArray or the next lines? Can you add logs for multiCallDataBytesArray, config, and writeAsync.

kombos commented 1 year ago

These values should work. At what point are you getting the error? Is it around multiCallDataBytesArray or the next lines? Can you add logs for multiCallDataBytesArray, config, and writeAsync.

I'm getting this error in usePrepareContractWrite, in which there is an 'onError' clause, which is getting triggered. But if we continue with sending the transaction, then the txn goes through and the 'onError' of useContractWrite doesnt get triggered. Also the multicall successfully executes. also here are the logs (lemme know if you need a more clearer log values) :

image
zemse commented 1 year ago

If usePrepareContractWrite is imported from a library, you may create an issue on that repo since the problem seems to be in there. Otherwise, feel free to share the source code here.

Interestingly, it successfully gave encoded data in config.request.data regardless of the encoding error. It should not call onError if it's successful and if it's really not successful then maybe null/undefined can be returned instead of an incomplete config object.

kombos commented 1 year ago

If usePrepareContractWrite is imported from a library, you may create an issue on that repo since the problem seems to be in there. Otherwise, feel free to share the source code here.

Interestingly, it successfully gave encoded data in config.request.data regardless of the encoding error. It should not call onError if it's successful and if it's really not successful then maybe null/undefined can be returned instead of an incomplete config object.

the usePrepareContractWrite is from a library called wagmi hooks (https://wagmi.sh/). but it internally uses ethers.js library for communicating with blockchain. Had approached the wagmi team but they had mentioned to create a github issue here since this pertains to ethers.