Are the subgraphs broken?

I have a subgraph running here: https://thegraph.com/hosted-service/subgraph/cinjon/research-v0?selected=logs. I have made minor additions to it in order to accommodate a string identifier on some tokens, but the core erc20, erc1155, and account subgraphs are unchanged from the code in the OpenZeppelin repo (i'd link to it but new users can only post two urls :confused: ).

It was running for a while with no problem and then it failed on this transaction: https://goerli.etherscan.io/tx/0xb99e9700fae51a9dfeae2f1b144e4a1626e98686c445cd3d7bc6c3da9855a0c3 with the error below. It seems like there is some i32 issue converting a big number. The only place I could see where that is possible is in decimals (because it's the only i32 in the OpenZeppelin subgraph code).

However, their decimals value is 0, so that cant be right.

Have you seen this before? It seems like this transaction should break any other deployed subgraphs using the same code. Is there one currently serving Goerli that I can check?

Thanks!

{
  "data": {
    "indexingStatuses": [
      {
        "subgraph": "QmcGJAwTYH9KRQRqXBe7bj3D3NmVFhaXatYweTEff7Ungd",
        "synced": true,
        "health": "failed",
        "entityCount": "73302027",
        "fatalError": {
          "handler": null,
          "message": "transaction b99e9700fae51a9dfeae2f1b144e4a1626e98686c445cd3d7bc6c3da9855a0c3: Mapping aborted at ~lib/@graphprotocol/graph-ts/common/collections.ts, line 150, column 9, with message: overflow converting 0x000064a7b3b6e00d to i32\twasm backtrace:\t    0: 0x3730 - <unknown>!../src/fetch/erc20/fetchERC20\t    1: 0x3ced - <unknown>!../src/datasources/erc20/handleTransfer\t in handler `handleTransfer` at block #9338179 (09b257e0355e17839f5444cb78c2101bbf4ace833e6925926a00ac6710f176ab)",
          "deterministic": true,
          "block": {
            "hash": "0x09b257e0355e17839f5444cb78c2101bbf4ace833e6925926a00ac6710f176ab",
            "number": "9338179"
          }
        },
        "chains": [
          {
            "chainHeadBlock": {
              "number": "9339362"
            },
            "earliestBlock": {
              "number": "9284541"
            },
            "latestBlock": {
              "number": "9338179"
            }
          }
        ]
      }
    ]
  }
}
1 Like

I just tried pushing past this transaction (by setting the startBlock after it) and I hit another error on the same token. It's at this transaction: https://goerli.etherscan.io/tx/0x2e779e06601bf5b405552024cf8087929ee4046273c4c5ac374594489926d9f7.

Anyone have an idea of what's going on?

I think this is a consequence of decimals being Int and not BigInt. I am very surprised this hasn't come up before.

Another failed transaction: https://goerli.etherscan.io/token/0xc08f78d200621fede63aaf453913ec07628041c8. This one has a really high transfer amount.

Hey @cinjon,

I've taken a look at both contracts and seems that the decimals are not just 0 but instead completely broken. This is the decimal amounts for both:

$ cast call --rpc-url https://rpc.ankr.com/eth_goerli 0xc08f78d200621fede63aaf453913ec07628041c8 "decimals()"
> 0x0000000000000000000000000000000000000000000000000de0b6b3a7640000
$ cast call --rpc-url https://rpc.ankr.com/eth_goerli 0x954d391E04b52A74E36eb92C7d7E744F912ffa3E "decimals()"
> 0x0000000000000000000000000000000000000000000000000de0b6b3a7640000

Because the standard ERC20 uses a value up to type(uint8).max, these are not ERC20 compliant tokens, the return value should be capped to 255.

Both tokens are deployed by the same address with wrong decimal values, so there should be something broken in the way we handle these in the ERC20 datasource. It should be either the fetchERC20 function (includes a endpoint.try_decimals() function) or any of the toDecimals() functions.

This is currently not a priority because there will be some other changes for 5.0 and we may want to take care of the subgraphs updating more generally. If we have the clear root of the issue, should be an easy PR.

It's the first time I personally see this, and no, there's no deployed version for ERC20, just the ones seen here . Thanks for reporting the finding.

I've run across another version of this here: https://goerli.etherscan.io/tx/0x5026bfcf12dc57f0cbfdd03e80da286cc517bf24971ca11b93f2ae48ef7653d3.
Error:

7/27/2023, 11:13:09 AM

ERROR

Subgraph instance failed to run: transaction 5026bfcf12dc57f0cbfdd03e80da286cc517bf24971ca11b93f2ae48ef7653d3: out of range integral type conversion attempted wasm backtrace: 0: 0x46c6 - <unknown>!../src/datasources/erc20/handleTransfer in handler `handleTransfer` at block #9410761 (c10cf5653a3889cc6a3b85bbeca9b8c4bbf91c9b3503901f9b54c8f5b0ab656c), code: SubgraphSyncingFailure

Hello @cinjon, here are some elements to complete @ernestognw's answer.

First: there is no generic ERC20 subgraph that indexed all the ERC20 activity. The amount of data to index would be so large that a subgraph can't properly handle that. Even a single high-activity ERC20 token such as USDT or USDC might be to much to handle.

The issue might indeed come from the decimals. The subgraph fetches the decimals in the fetchERC20 function. We use a try catch to support tokens that don't have a decimal function. In that case we use 18 as a default value.

As @ernestognw pointed out. The contracts you are trying to index return a very big value for the decimals part. My understanding is that the subgraph does the call, get that value without a revert, and then try to cast it to an Int. This last part fails because the decimals is to large.

In order to fix that, we would have to change the interface we use for ERC20. Instead of using the standard definition, we would have to change the return type of the decimals() function That doesn't feel like something I'd be confortable with.

I'd argue that the issue here is in the token returning an invalid value, that honestly makes no sens. IMO the value you want to return is 18 and not 1000000000000000000.