graph-tooling icon indicating copy to clipboard operation
graph-tooling copied to clipboard

Can't handle two dimensional array rightly in codegen from solidity

Open Aliceonly opened this issue 1 year ago • 2 comments

Which packages are impacted by your issue?

@graphprotocol/graph-cli

Describe the issue

codegen from solidity func like : function getPositionsByTokenIds(uint256[] memory) public view returns (Position.PositionInfo[][] memory)

The Solidity function return type:Position.PositionInfo[][] is a two-dimensional array. PositionInfo[][] is a two-dimensional array. Each element itself is also a Position.PositionInfo[] array.

TypeScript mapping type: Reader__getPositionsByTokenIdsResultValue0Struct[] is a one-dimensional array. This means that the return type expected by TypeScript is an array of Reader__getPositionsByTokenIdsResultValue0Struct objects, not an array of arrays (a two-dimensional array).

Reproduction

graph codegen

Steps to Reproduce the Bug or Issue

gen code: getPositionsByTokenIds( tokenIds: Array<BigInt> ): Array<Array<Reader__getPositionsByTokenIdsResultValue0Struct>> { let result = super.call( "getPositionsByTokenIds", "getPositionsByTokenIds(uint256[]):((((uint256,address,address,bool,uint256),uint256,uint256,uint256,uint256,uint256,uint256,uint256,int256,uint256,bool,(uint256,(uint256,uint256,uint256,uint256),(uint256,uint256,uint256,uint256)),(uint256,(uint256,uint256,uint256,uint256),(uint256,uint256,uint256,uint256))),address)[][])", [ethereum.Value.fromUnsignedBigIntArray(tokenIds)] ); return result[0].toTupleMatrix<>(); } try_getPositionsByTokenIds(tokenIds: Array<BigInt>): ethereum.CallResult<Array<Reader__getPositionsByTokenIdsResultValue0Struct>> { let result = super.tryCall( "getPositionsByTokenIds", "getPositionsByTokenIds(uint256[]):((((uint256,address,address,bool,uint256),uint256,uint256,uint256,uint256,uint256,uint256,uint256,int256,uint256,bool,(uint256,(uint256,uint256,uint256,uint256),(uint256,uint256,uint256,uint256)),(uint256,(uint256,uint256,uint256,uint256),(uint256,uint256,uint256,uint256))),address)[][])", [ethereum.Value.fromUnsignedBigIntArray(tokenIds)] ); if (result.reverted) { return new ethereum.CallResult(); } let value = result.value; return ethereum.CallResult.fromValue(value[0].toTupleMatrix<>()); }

Expected behavior

Screenshots or Videos

No response

Platform

  • OS: [e.g. macOS, Windows, Linux]
  • NodeJS: [e.g. 18.5.0]
  • @graphprotocol/* version(s): [e.g. 2.6.2]

Subgraph Manifest

No response

Subgraph GraphQL Schema

No response

Additional context

No response

Aliceonly avatar Jan 25 '24 08:01 Aliceonly

can you share the ABI or the contract address?

saihaj avatar Jan 25 '24 13:01 saihaj

Thx for reply. Here's the function abi gened by solc 0.8.20:

  {
    "inputs": [
      {
        "internalType": "uint256[]",
        "name": "tokenIds",
        "type": "uint256[]"
      }
    ],
    "name": "getPositionsByTokenIds",
    "outputs": [
      {
        "components": [
          {
            "components": [
              {
                "components": [
                  {
                    "internalType": "uint256",
                    "name": "tokenId",
                    "type": "uint256"
                  },
                  {
                    "internalType": "contract IVault",
                    "name": "collateralTokenVault",
                    "type": "address"
                  },
                  {
                    "internalType": "address",
                    "name": "indexToken",
                    "type": "address"
                  },
                  {
                    "internalType": "bool",
                    "name": "isLong",
                    "type": "bool"
                  },
                  {
                    "internalType": "uint256",
                    "name": "giantTokenId",
                    "type": "uint256"
                  }
                ],
                "internalType": "struct Keys.PositionKeyInfo",
                "name": "keyInfo",
                "type": "tuple"
              },
              {
                "internalType": "uint256",
                "name": "giantTokenId",
                "type": "uint256"
              },
              {
                "internalType": "uint256",
                "name": "size",
                "type": "uint256"
              },
              {
                "internalType": "uint256",
                "name": "collateral",
                "type": "uint256"
              },
              {
                "internalType": "uint256",
                "name": "averagePrice",
                "type": "uint256"
              },
              {
                "internalType": "uint256",
                "name": "fundingPerSize",
                "type": "uint256"
              },
              {
                "internalType": "uint256",
                "name": "claimableFundingPerSize",
                "type": "uint256"
              },
              {
                "internalType": "uint256",
                "name": "accBorrowingRate",
                "type": "uint256"
              },
              {
                "internalType": "int256",
                "name": "realisedPnL",
                "type": "int256"
              },
              {
                "internalType": "uint256",
                "name": "shares",
                "type": "uint256"
              },
              {
                "internalType": "bool",
                "name": "isLong",
                "type": "bool"
              },
              {
                "components": [
                  {
                    "internalType": "uint256",
                    "name": "timestamp",
                    "type": "uint256"
                  },
                  {
                    "components": [
                      {
                        "internalType": "uint256",
                        "name": "min",
                        "type": "uint256"
                      },
                      {
                        "internalType": "uint256",
                        "name": "max",
                        "type": "uint256"
                      },
                      {
                        "internalType": "uint256",
                        "name": "blockNumber",
                        "type": "uint256"
                      },
                      {
                        "internalType": "uint256",
                        "name": "timestamp",
                        "type": "uint256"
                      }
                    ],
                    "internalType": "struct Market.Price",
                    "name": "collateralTokenPrice",
                    "type": "tuple"
                  },
                  {
                    "components": [
                      {
                        "internalType": "uint256",
                        "name": "min",
                        "type": "uint256"
                      },
                      {
                        "internalType": "uint256",
                        "name": "max",
                        "type": "uint256"
                      },
                      {
                        "internalType": "uint256",
                        "name": "blockNumber",
                        "type": "uint256"
                      },
                      {
                        "internalType": "uint256",
                        "name": "timestamp",
                        "type": "uint256"
                      }
                    ],
                    "internalType": "struct Market.Price",
                    "name": "indexTokenPrice",
                    "type": "tuple"
                  }
                ],
                "internalType": "struct Position.UpdateInfo",
                "name": "increasedInfo",
                "type": "tuple"
              },
              {
                "components": [
                  {
                    "internalType": "uint256",
                    "name": "timestamp",
                    "type": "uint256"
                  },
                  {
                    "components": [
                      {
                        "internalType": "uint256",
                        "name": "min",
                        "type": "uint256"
                      },
                      {
                        "internalType": "uint256",
                        "name": "max",
                        "type": "uint256"
                      },
                      {
                        "internalType": "uint256",
                        "name": "blockNumber",
                        "type": "uint256"
                      },
                      {
                        "internalType": "uint256",
                        "name": "timestamp",
                        "type": "uint256"
                      }
                    ],
                    "internalType": "struct Market.Price",
                    "name": "collateralTokenPrice",
                    "type": "tuple"
                  },
                  {
                    "components": [
                      {
                        "internalType": "uint256",
                        "name": "min",
                        "type": "uint256"
                      },
                      {
                        "internalType": "uint256",
                        "name": "max",
                        "type": "uint256"
                      },
                      {
                        "internalType": "uint256",
                        "name": "blockNumber",
                        "type": "uint256"
                      },
                      {
                        "internalType": "uint256",
                        "name": "timestamp",
                        "type": "uint256"
                      }
                    ],
                    "internalType": "struct Market.Price",
                    "name": "indexTokenPrice",
                    "type": "tuple"
                  }
                ],
                "internalType": "struct Position.UpdateInfo",
                "name": "decreasedInfo",
                "type": "tuple"
              }
            ],
            "internalType": "struct Position.Props",
            "name": "position",
            "type": "tuple"
          },
          {
            "internalType": "address",
            "name": "collateralToken",
            "type": "address"
          }
        ],
        "internalType": "struct Position.PositionInfo[][]",
        "name": "",
        "type": "tuple[][]"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },


It gens ts code:

getPositionsByTokenIds(
    tokenIds: Array<BigInt>
  ): Array<Reader__getPositionsByTokenIdsResultValue0Struct> {
    let result = super.call(
      "getPositionsByTokenIds",
      "getPositionsByTokenIds(uint256[]):((((uint256,address,address,bool,uint256),uint256,uint256,uint256,uint256,uint256,uint256,uint256,int256,uint256,bool,(uint256,(uint256,uint256,uint256,uint256),(uint256,uint256,uint256,uint256)),(uint256,(uint256,uint256,uint256,uint256),(uint256,uint256,uint256,uint256))),address)[][])",
      [ethereum.Value.fromUnsignedBigIntArray(tokenIds)]
    );

    return result[0].toTupleMatrix<>();
  }

  try_getPositionsByTokenIds(
    tokenIds: Array<BigInt>
  ): ethereum.CallResult<
    Array<Reader__getPositionsByTokenIdsResultValue0Struct>
  > {
    let result = super.tryCall(
      "getPositionsByTokenIds",
      "getPositionsByTokenIds(uint256[]):((((uint256,address,address,bool,uint256),uint256,uint256,uint256,uint256,uint256,uint256,uint256,int256,uint256,bool,(uint256,(uint256,uint256,uint256,uint256),(uint256,uint256,uint256,uint256)),(uint256,(uint256,uint256,uint256,uint256),(uint256,uint256,uint256,uint256))),address)[][])",
      [ethereum.Value.fromUnsignedBigIntArray(tokenIds)]
    );
    if (result.reverted) {
      return new ethereum.CallResult();
    }
    let value = result.value;
    return ethereum.CallResult.fromValue(value[0].toTupleMatrix<>());
  }

static error in return:

It is not possible to assign type "CallResult<Tuple[][]>" to type "CallResult<Reader__getPositionsByTokenIdsResultValue0Struct[]>". ]>".
  Type "Tuple[][]" cannot be assigned to type "Reader__getPositionsByTokenIdsResultValue0Struct[]". ts(2322)

Aliceonly avatar Jan 27 '24 04:01 Aliceonly