From 7453a47c80aeed22d8bc1c7f544b303b6e95cbf0 Mon Sep 17 00:00:00 2001 From: Mayank Mittal Date: Wed, 7 Jun 2023 13:50:14 +0530 Subject: [PATCH] [FEAT] Add support for DEPOSIT and WITHDRAW token transfer event in older contracts --- CHANGELOG.md | 1 + .../lib/explorer/chain/token_transfer.ex | 6 ++ .../lib/indexer/transform/token_transfers.ex | 50 ++++++++++++++++- .../transform/token_transfers_test.exs | 56 ++++++++++++++++++- 4 files changed, 110 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c4edb695f..ff84e07795 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ ### Features +- [#7653](https://github.com/blockscout/blockscout/pull/7653) - Add support for DEPOSIT and WITHDRAW token transfer event in older contracts - [#7628](https://github.com/blockscout/blockscout/pull/7628) - Support partially verified property from verifier MS; Add property to track contracts automatically verified via eth-bytecode-db - [#7603](https://github.com/blockscout/blockscout/pull/7603) - Add Polygon Edge and optimism genesis files support - [#7513](https://github.com/blockscout/blockscout/pull/7513) - Add Polygon Edge support diff --git a/apps/explorer/lib/explorer/chain/token_transfer.ex b/apps/explorer/lib/explorer/chain/token_transfer.ex index b70f5623a9..d1abd9971e 100644 --- a/apps/explorer/lib/explorer/chain/token_transfer.ex +++ b/apps/explorer/lib/explorer/chain/token_transfer.ex @@ -74,6 +74,8 @@ defmodule Explorer.Chain.TokenTransfer do @typep api? :: {:api?, true | false} @constant "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef" + @weth_deposit_signature "0xe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c" + @weth_withdrawal_signature "0x7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65" @erc1155_single_transfer_signature "0xc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62" @erc1155_batch_transfer_signature "0x4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb" @@ -146,6 +148,10 @@ defmodule Explorer.Chain.TokenTransfer do """ def constant, do: @constant + def weth_deposit_signature, do: @weth_deposit_signature + + def weth_withdrawal_signature, do: @weth_withdrawal_signature + def erc1155_single_transfer_signature, do: @erc1155_single_transfer_signature def erc1155_batch_transfer_signature, do: @erc1155_batch_transfer_signature diff --git a/apps/indexer/lib/indexer/transform/token_transfers.ex b/apps/indexer/lib/indexer/transform/token_transfers.ex index 27e4291b06..6ea41b6500 100644 --- a/apps/indexer/lib/indexer/transform/token_transfers.ex +++ b/apps/indexer/lib/indexer/transform/token_transfers.ex @@ -23,6 +23,14 @@ defmodule Indexer.Transform.TokenTransfers do |> Enum.filter(&(&1.first_topic == unquote(TokenTransfer.constant()))) |> Enum.reduce(initial_acc, &do_parse/2) + weth_transfers = + logs + |> Enum.filter(fn log -> + log.first_topic == TokenTransfer.weth_deposit_signature() || + log.first_topic == TokenTransfer.weth_withdrawal_signature() + end) + |> Enum.reduce(initial_acc, &do_parse/2) + erc1155_token_transfers = logs |> Enum.filter(fn log -> @@ -31,8 +39,13 @@ defmodule Indexer.Transform.TokenTransfers do end) |> Enum.reduce(initial_acc, &do_parse(&1, &2, :erc1155)) - rough_tokens = erc1155_token_transfers.tokens ++ erc20_and_erc721_token_transfers.tokens - rough_token_transfers = erc1155_token_transfers.token_transfers ++ erc20_and_erc721_token_transfers.token_transfers + rough_tokens = + erc1155_token_transfers.tokens ++ + erc20_and_erc721_token_transfers.tokens ++ weth_transfers.tokens + + rough_token_transfers = + erc1155_token_transfers.token_transfers ++ + erc20_and_erc721_token_transfers.token_transfers ++ weth_transfers.token_transfers {tokens, token_transfers} = sanitize_token_types(rough_tokens, rough_token_transfers) @@ -157,6 +170,39 @@ defmodule Indexer.Transform.TokenTransfers do {token, token_transfer} end + # ERC-20 token transfer for WETH + defp parse_params(%{second_topic: second_topic, third_topic: nil, fourth_topic: nil} = log) + when not is_nil(second_topic) do + [amount] = decode_data(log.data, [{:uint, 256}]) + + {from_address_hash, to_address_hash} = + if log.first_topic == TokenTransfer.weth_deposit_signature() do + {@burn_address, truncate_address_hash(log.second_topic)} + else + {truncate_address_hash(log.second_topic), @burn_address} + end + + token_transfer = %{ + amount: Decimal.new(amount || 0), + block_number: log.block_number, + block_hash: log.block_hash, + log_index: log.index, + from_address_hash: from_address_hash, + to_address_hash: to_address_hash, + token_contract_address_hash: log.address_hash, + transaction_hash: log.transaction_hash, + token_ids: nil, + token_type: "ERC-20" + } + + token = %{ + contract_address_hash: log.address_hash, + type: "ERC-20" + } + + {token, token_transfer} + end + # ERC-721 token transfer with topics as addresses defp parse_params(%{second_topic: second_topic, third_topic: third_topic, fourth_topic: fourth_topic} = log) when not is_nil(second_topic) and not is_nil(third_topic) and not is_nil(fourth_topic) do diff --git a/apps/indexer/test/indexer/transform/token_transfers_test.exs b/apps/indexer/test/indexer/transform/token_transfers_test.exs index 731c277520..f416733ea1 100644 --- a/apps/indexer/test/indexer/transform/token_transfers_test.exs +++ b/apps/indexer/test/indexer/transform/token_transfers_test.exs @@ -7,7 +7,7 @@ defmodule Indexer.Transform.TokenTransfersTest do describe "parse/1" do test "parse/1 parses logs for tokens and token transfers" do - [log_1, _log_2, log_3] = + [log_1, _log_2, log_3, weth_deposit_log, weth_withdrawal_log] = logs = [ %{ address_hash: "0xf2eec76e45b328df99a34fa696320a262cb92154", @@ -47,6 +47,32 @@ defmodule Indexer.Transform.TokenTransfersTest do third_topic: "0x000000000000000000000000dccb72afee70e60b0c1226288fe86c01b953e8ac", transaction_hash: "0x4011d9a930a3da620321589a54dc0ca3b88216b4886c7a7c3aaad1fb17702d35", type: "mined" + }, + %{ + address_hash: "0x0BE9e53fd7EDaC9F859882AfdDa116645287C629", + block_number: 23_704_638, + block_hash: "0x8f61c99b0dd1196714ffda5bf979a282e6a62fdd3cff25c291284e6b57de2106", + data: "0x00000000000000000000000000000000000000000000002be19edfcf6b480000", + first_topic: "0xe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c", + second_topic: "0x000000000000000000000000fb76e9e7d88e308ab530330ed90e84a952570319", + third_topic: nil, + fourth_topic: nil, + index: 1, + transaction_hash: "0x185889bc91372106ecf114a4e23f4ee615e131ae3e698078bd5d2ed7e3f55a49", + type: "mined" + }, + %{ + address_hash: "0x0BE9e53fd7EDaC9F859882AfdDa116645287C629", + block_number: 23_704_608, + block_hash: "0x5a5e69984f78d65fc6d92e18058d21a9b114f1d56d06ca7aa017b3d87bf0491a", + data: "0x00000000000000000000000000000000000000000000000000e1315e1ebd28e8", + first_topic: "0x7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65", + second_topic: "0x000000000000000000000000e3f85aad0c8dd7337427b9df5d0fb741d65eeeb5", + third_topic: nil, + fourth_topic: nil, + index: 1, + transaction_hash: "0x07510dbfddbac9064f7d607c2d9a14aa26fa19cdfcd578c0b585ff2395df543f", + type: "mined" } ] @@ -59,6 +85,10 @@ defmodule Indexer.Transform.TokenTransfersTest do %{ contract_address_hash: log_1.address_hash, type: "ERC-20" + }, + %{ + contract_address_hash: weth_withdrawal_log.address_hash, + type: "ERC-20" } ], token_transfers: [ @@ -84,6 +114,30 @@ defmodule Indexer.Transform.TokenTransfersTest do transaction_hash: log_1.transaction_hash, token_type: "ERC-20", block_hash: log_1.block_hash + }, + %{ + amount: Decimal.new("63386150072297704"), + block_hash: weth_withdrawal_log.block_hash, + block_number: weth_withdrawal_log.block_number, + from_address_hash: truncated_hash(weth_withdrawal_log.second_topic), + log_index: 1, + to_address_hash: "0x0000000000000000000000000000000000000000", + token_contract_address_hash: weth_withdrawal_log.address_hash, + token_ids: nil, + token_type: "ERC-20", + transaction_hash: weth_withdrawal_log.transaction_hash + }, + %{ + amount: Decimal.new("809467672956315893760"), + block_hash: weth_deposit_log.block_hash, + block_number: weth_deposit_log.block_number, + from_address_hash: "0x0000000000000000000000000000000000000000", + log_index: 1, + to_address_hash: truncated_hash(weth_deposit_log.second_topic), + token_contract_address_hash: weth_deposit_log.address_hash, + token_ids: nil, + token_type: "ERC-20", + transaction_hash: weth_deposit_log.transaction_hash } ] }