The getNFTTransfers endpoint is broken: missing entries and wrong prices

The getNFTTransfers endpoint (v2/nft/{{contract_address}}/transfers) does not correctly handle complex bundled sales.

For example this transaction: https://etherscan.io/tx/0xf5700abfd1a36801b10c2d04afd75719bce470e7d009361b34ff314c00fb36ae

It’s the sale of 7 separate NFTs for a given collection, but bundled as one via the tool GenieSwap. Note that this is not a bundle like on OpenSea, here with GenieSwap, each individual item has a separate price and therefore it’s really the sale of 7 individual NFTs with their respective prices (again, see the Etherscan link and you’ll see the individual prices).

Now the problem here is that the getNFTTransfers endpoint reports one single sale for only 1 item out of the 7, and for a price of 1.75 ETH (which is the total price for the 7-in-1 operation done by GenieSwap, and not the price that this one reported item was really bought for). In addition, only 1 item shows up in the getNFTTransfers endpoint data, and the other 6 sales are missing. This is a very serious data discrepancy.

If you go to OpenSea and check this collection, you will see 7 distinct sales at the same time: 27 February 2022 at 10:18pm UTC. OpenSea is showing the correct data: https://opensea.io/collection/mojoheads?tab=activity

Please fix the endpoint to handle complex sales such as the one I mentioned, and also make sure that you always differentiate transfers from sales by setting the value of transfers always to null or 0 (sales have an ‘OrdersMatched’ in them, and transfers do not).

Finally, once you are doing fixing the getNFTTransfers endpoint you will have to reprocess all transactions since the beginning of times for all ERC721/ERC1155 contract addresses in order to retro-actively fix all data returned by this endpoint.

1 Like

I see multiple NFT transfers registered for that transaction:
https://deep-index.moralis.io/api/v2/0x97a99da15fc89d96b3fbe673ffd8f69f6ce7c9b1/nft/transfers?chain=eth&format=decimal&direction=to

=>

{
      "block_number": "14290890",
      "block_timestamp": "2022-02-27T22:18:57.000Z",
      "block_hash": "0xda6ba67206aaaa0d5f4d56640bcb81cd86eddd964cd7efb11dbf6e5af8a5fb60",
      "transaction_hash": "0xf5700abfd1a36801b10c2d04afd75719bce470e7d009361b34ff314c00fb36ae",
      "transaction_index": 197,
      "log_index": 349,
      "value": "1750000000000000000",
      "contract_type": "ERC721",
      "transaction_type": "Single",
      "token_address": "0x83ff0d70bf7ea1955920c136d8a2915bca5a53b6",
      "token_id": "559",
      "from_address": "0xbb44705c3912d1981e9a84b385f2309198505180",
      "to_address": "0x97a99da15fc89d96b3fbe673ffd8f69f6ce7c9b1",
      "amount": "1",
      "verified": 1,
      "operator": null
    },
    {
      "block_number": "14290890",
      "block_timestamp": "2022-02-27T22:18:57.000Z",
      "block_hash": "0xda6ba67206aaaa0d5f4d56640bcb81cd86eddd964cd7efb11dbf6e5af8a5fb60",
      "transaction_hash": "0xf5700abfd1a36801b10c2d04afd75719bce470e7d009361b34ff314c00fb36ae",
      "transaction_index": 197,
      "log_index": 346,
      "value": "1750000000000000000",
      "contract_type": "ERC721",
      "transaction_type": "Single",
      "token_address": "0x83ff0d70bf7ea1955920c136d8a2915bca5a53b6",
      "token_id": "1016",
      "from_address": "0x30762e50c0307dbf709b79e5d3dc043e1fa7bdff",
      "to_address": "0x97a99da15fc89d96b3fbe673ffd8f69f6ce7c9b1",
      "amount": "1",
      "verified": 1,
      "operator": null
    },
    {
      "block_number": "14290890",
      "block_timestamp": "2022-02-27T22:18:57.000Z",
      "block_hash": "0xda6ba67206aaaa0d5f4d56640bcb81cd86eddd964cd7efb11dbf6e5af8a5fb60",
      "transaction_hash": "0xf5700abfd1a36801b10c2d04afd75719bce470e7d009361b34ff314c00fb36ae",
      "transaction_index": 197,
      "log_index": 343,
      "value": "1750000000000000000",
      "contract_type": "ERC721",
      "transaction_type": "Single",
      "token_address": "0x83ff0d70bf7ea1955920c136d8a2915bca5a53b6",
      "token_id": "1013",
      "from_address": "0xbb44705c3912d1981e9a84b385f2309198505180",
      "to_address": "0x97a99da15fc89d96b3fbe673ffd8f69f6ce7c9b1",
      "amount": "1",
      "verified": 1,
      "operator": null
    },
    {
      "block_number": "14290890",
      "block_timestamp": "2022-02-27T22:18:57.000Z",
      "block_hash": "0xda6ba67206aaaa0d5f4d56640bcb81cd86eddd964cd7efb11dbf6e5af8a5fb60",
      "transaction_hash": "0xf5700abfd1a36801b10c2d04afd75719bce470e7d009361b34ff314c00fb36ae",
      "transaction_index": 197,
      "log_index": 340,
      "value": "1750000000000000000",
      "contract_type": "ERC721",
      "transaction_type": "Single",
      "token_address": "0x83ff0d70bf7ea1955920c136d8a2915bca5a53b6",
      "token_id": "1317",
      "from_address": "0x4276d883b78d0914c8006aa83eaab56e9f0204ee",
      "to_address": "0x97a99da15fc89d96b3fbe673ffd8f69f6ce7c9b1",
      "amount": "1",
      "verified": 1,
      "operator": null
    },
    {
      "block_number": "14290890",
      "block_timestamp": "2022-02-27T22:18:57.000Z",
      "block_hash": "0xda6ba67206aaaa0d5f4d56640bcb81cd86eddd964cd7efb11dbf6e5af8a5fb60",
      "transaction_hash": "0xf5700abfd1a36801b10c2d04afd75719bce470e7d009361b34ff314c00fb36ae",
      "transaction_index": 197,
      "log_index": 337,
      "value": "1750000000000000000",
      "contract_type": "ERC721",
      "transaction_type": "Single",
      "token_address": "0x83ff0d70bf7ea1955920c136d8a2915bca5a53b6",
      "token_id": "1175",
      "from_address": "0x30762e50c0307dbf709b79e5d3dc043e1fa7bdff",
      "to_address": "0x97a99da15fc89d96b3fbe673ffd8f69f6ce7c9b1",
      "amount": "1",
      "verified": 1,
      "operator": null
    },
    {
      "block_number": "14290890",
      "block_timestamp": "2022-02-27T22:18:57.000Z",
      "block_hash": "0xda6ba67206aaaa0d5f4d56640bcb81cd86eddd964cd7efb11dbf6e5af8a5fb60",
      "transaction_hash": "0xf5700abfd1a36801b10c2d04afd75719bce470e7d009361b34ff314c00fb36ae",
      "transaction_index": 197,
      "log_index": 334,
      "value": "1750000000000000000",
      "contract_type": "ERC721",
      "transaction_type": "Single",
      "token_address": "0x83ff0d70bf7ea1955920c136d8a2915bca5a53b6",
      "token_id": "1023",
      "from_address": "0xa6bc44a89510ceabface881a74b5b57df879da05",
      "to_address": "0x97a99da15fc89d96b3fbe673ffd8f69f6ce7c9b1",
      "amount": "1",
      "verified": 1,
      "operator": null
    },
    {
      "block_number": "14290890",
      "block_timestamp": "2022-02-27T22:18:57.000Z",
      "block_hash": "0xda6ba67206aaaa0d5f4d56640bcb81cd86eddd964cd7efb11dbf6e5af8a5fb60",
      "transaction_hash": "0xf5700abfd1a36801b10c2d04afd75719bce470e7d009361b34ff314c00fb36ae",
      "transaction_index": 197,
      "log_index": 331,
      "value": "1750000000000000000",
      "contract_type": "ERC721",
      "transaction_type": "Single",
      "token_address": "0x83ff0d70bf7ea1955920c136d8a2915bca5a53b6",
      "token_id": "999",
      "from_address": "0x9a0417e8833f3ce38fdd2c2c1492f4cc5b7947f0",
      "to_address": "0x97a99da15fc89d96b3fbe673ffd8f69f6ce7c9b1",
      "amount": "1",
      "verified": 1,
      "operator": null
    },

Hello,

You are right. I was looking at blockchain data incorrectly, and was under the incorrect assumption that any transaction with a unique transaction_hash would only contain a single token. My script was indexing on transaction hashes only and therefore I was storing only a single token every time there was a transaction even if it related to multiple distinct token ids. Totally my mistake.

However, and unless I’m still misunderstanding something, my second remark about the value field is still correct: here all transfers in the snippet that you shared are showing a value of 1.75 ETH, when in reality this is the total value for all 7 transfers combined. If you look at the same data reported by OpenSea [1], you’ll find that their data show the correct value for each transfer, which is 0.25 ETH, and is also correctly reported in the section “Interacted With” of Etherscan [2].

It would be great if the value field in the Moralis endpoint could reflect the value of each individual transfer/sale, and not the total value for the combined sale. That would seem more appropriate and more logical. In addition, sometimes there are transfers with a value that is non-zero and non-null and therefore could be considered as sales, when in reality they are not sales; for more details, please take a look at the ticket I wrote here [3].

Thank you for your work on the Moralis API, I think it’s a great product and it goes a long way in helping the NFT community!

[1] https://etherscan.io/tx/0xf5700abfd1a36801b10c2d04afd75719bce470e7d009361b34ff314c00fb36ae
[2] https://opensea.io/collection/mojoheads?tab=activity
[3] Critical information is missing from the nftTransfer schema, making the data unusable

there is also this thread that describes a similar problem:

1 Like

@cryptokid by any chance, have you had some time to look into this problem? Any idea if this will ever get fixed? Thank you!

The part with having the value of the traded tokenId instead of the total value of the transaction, I don’t know if it will be implemented. You can propose it on roadmap.moralis.io. It doesn’t seem easy to do it in the general case.