NFT balance not calculated correctly for Decentraland contract

Hello Everyone,

While writing some tests for my app, I noticed that the balance for some addresses is not calculated correctly.

Let’s take for example this wallet: 0x895Be97bDb9F8a244c472B18EA96DeE39ddf8fe5.

According to the Moralis Web3 API (/{address}/nft) and Etherscan the user has 1 token relative to the contract 0xf87e31492faf9a91b02ee0deaad50d51d56d5d4d (Decentraland land)

If we query BlockScout or the Decentraland API instead, the count is 6 tokens.

The Moralis API (/{address}) doesn’t allow us to really understand what is happening. If we painstakingly go through all the transactions on the blockchain directly, we see that some data is missing that would help us: In the transaction the to address is the contract, but in the data we can see what is actually happening is that the user is receiving a token. I think the aggregation pipeline is ignoring the attached data, hence it register only 1 token instead of 6.

I can reproduce this for a bunch of other tokens, not sure if they are all violating the ERC20 spec, but it seems like a common behavior.

1 Like

in etherscan I can also see only 1 token for that address:

https://etherscan.io/token/0xf87e31492faf9a91b02ee0deaad50d51d56d5d4d?a=0x895be97bdb9f8a244c472b18ea96dee39ddf8fe5#inventory

The etherscan API is incorrect too unfortunately. The user has the following tokens relative to that contract:

  • 115792089237316195423570985008687907840679537089565840891312723532937705816027
  • 115792089237316195423570985008687907841019819456486779354776098140369474027484
  • 115792089237316195423570985008687907847144902061063671697116841074141301833669

and 3 more, as you can see from the official API. The balance instead show only one.

etherscan is showing 6 Land balance but 1 token. Are those two different things?

unfortunately it’s only one token id, while the user has 6 tokens id.

My best theory:

  • Blockscout uses an erlang blockchain parser, which is more strict
  • My tests uses a custom javascript parser, which is more strict
  • Etherscan instead uses geth, which is more laxed

and hence the difference in the result.
The problem is that blockscout gets other things wrong, hence I was trying to use your API to get the truth.

Possible fixes:

  • rethink the aggregation pipelines you use
  • Add more data to the transaction endpoint (/{address})

the contract returns that owner for 115792089237316195423570985008687907840679537089565840891312723532937705816027
https://etherscan.io/address/0xf87e31492faf9a91b02ee0deaad50d51d56d5d4d#readProxyContract
but I don’t know what transaction is related to that token id, I can not find it in etherscan

If i read the contract for tokensOf function, it is giving me these 6 token ids for your wallet address, but out these only the last one marked in bold has a NFT transaction. The remaining 5 do not have any NFT transaction but you own these Id’s as per the contract.

[115792089237316195423570985008687907840679537089565840891312723532937705816027][115792089237316195423570985008687907847144902061063671697116841074141301833669][10208471007628153903901238222953046343592][115792089237316195423570985008687907841019819456486779354776098140369474027484][115792089237316195423570985008687907840679537089565840891312723532937705816028][115792089237316195423570985008687907834894736851909887012435355206597646221185]

I guess you need to add metadata with createEstateWithMetadata function so the token would appear under your NFT’s.

1 Like

It seems you are right @johnversus . I’m not sure I understand your answer:

I guess you need to add metadata with createEstateWithMetadata function so the token would appear under your NFT’s.

Estates are a different type of token, and they are counted correctly. Unfortunately I don’t own neither the address nor the contract, I’m just trying to build statistical aggregations.

How would you suggest to get the right balance? Unfortunately Decentraland is not the only contract showing similar issues, and I was wondering how BlockScout gets it right.

Maybe you can call the smart contract view function to get these data.
If these tokenId transactions are not erc standard transactions then you cant get this token data from Moralis api.

1 Like