From 26ff15d6e972a8acb577c02f41eea911a4342718 Mon Sep 17 00:00:00 2001 From: Mitja T Date: Tue, 28 Nov 2023 15:02:23 -0800 Subject: [PATCH 1/4] analyzer/runtime: Support WROSE events Deposit, Withdrawal --- analyzer/evmabi/contracts/WROSE.sol | 90 +++++ .../evmabi/contracts/artifacts/WROSE.json | 347 ++++++++++++++++++ analyzer/evmabi/evmabi.go | 4 + analyzer/runtime/extract.go | 82 +++++ analyzer/runtime/visitors.go | 44 ++- 5 files changed, 562 insertions(+), 5 deletions(-) create mode 100644 analyzer/evmabi/contracts/WROSE.sol create mode 100644 analyzer/evmabi/contracts/artifacts/WROSE.json diff --git a/analyzer/evmabi/contracts/WROSE.sol b/analyzer/evmabi/contracts/WROSE.sol new file mode 100644 index 000000000..61cf0a1ff --- /dev/null +++ b/analyzer/evmabi/contracts/WROSE.sol @@ -0,0 +1,90 @@ +// NOTE: The exact WROSE source code is lost as of 2023-11-28. +// The code below is a "partial match", meaning it compiles to the exact bytecode that is +// deployed on Oasis (Sapphire+Emerald, testnet+mainnet, as of this writing) but it +// there are differences in comments, whitespace, variable names, and/or filenames. +// +// The contract is identical to the WETH contract except for the name and symbol: +// https://etherscan.io/token/0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2#code + +// SPDX-License-Identifier: MIT + +// Copyright (C) 2015, 2016, 2017 Dapphub + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +pragma solidity ^0.4.18; + +contract WROSE { + string public name = "Wrapped ROSE"; + string public symbol = "wROSE"; + uint8 public decimals = 18; + + event Approval(address indexed src, address indexed guy, uint wad); + event Transfer(address indexed src, address indexed dst, uint wad); + event Deposit(address indexed dst, uint wad); + event Withdrawal(address indexed src, uint wad); + + mapping(address => uint) public balanceOf; + mapping(address => mapping(address => uint)) public allowance; + + function() public payable { + deposit(); + } + + function deposit() public payable { + balanceOf[msg.sender] += msg.value; + Deposit(msg.sender, msg.value); + } + + function withdraw(uint wad) public { + require(balanceOf[msg.sender] >= wad); + balanceOf[msg.sender] -= wad; + msg.sender.transfer(wad); + Withdrawal(msg.sender, wad); + } + + function totalSupply() public view returns (uint) { + return this.balance; + } + + function approve(address guy, uint wad) public returns (bool) { + allowance[msg.sender][guy] = wad; + Approval(msg.sender, guy, wad); + return true; + } + + function transfer(address dst, uint wad) public returns (bool) { + return transferFrom(msg.sender, dst, wad); + } + + function transferFrom( + address src, + address dst, + uint wad + ) public returns (bool) { + require(balanceOf[src] >= wad); + + if (src != msg.sender && allowance[src][msg.sender] != uint(-1)) { + require(allowance[src][msg.sender] >= wad); + allowance[src][msg.sender] -= wad; + } + + balanceOf[src] -= wad; + balanceOf[dst] += wad; + + Transfer(src, dst, wad); + + return true; + } +} diff --git a/analyzer/evmabi/contracts/artifacts/WROSE.json b/analyzer/evmabi/contracts/artifacts/WROSE.json new file mode 100644 index 000000000..20e13eb8b --- /dev/null +++ b/analyzer/evmabi/contracts/artifacts/WROSE.json @@ -0,0 +1,347 @@ +{ + "deploy": { + "VM:-": { + "linkReferences": {}, + "autoDeployLib": true + }, + "main:1": { + "linkReferences": {}, + "autoDeployLib": true + }, + "ropsten:3": { + "linkReferences": {}, + "autoDeployLib": true + }, + "rinkeby:4": { + "linkReferences": {}, + "autoDeployLib": true + }, + "kovan:42": { + "linkReferences": {}, + "autoDeployLib": true + }, + "goerli:5": { + "linkReferences": {}, + "autoDeployLib": true + }, + "Custom": { + "linkReferences": {}, + "autoDeployLib": true + } + }, + "data": { + "gasEstimates": { + "creation": { + "codeDepositCost": "640800", + "executionCost": "infinite", + "totalCost": "infinite" + }, + "external": { + "": "22099", + "allowance(address,address)": "850", + "approve(address,uint256)": "22353", + "balanceOf(address)": "664", + "decimals()": "552", + "deposit()": "22077", + "name()": "infinite", + "symbol()": "infinite", + "totalSupply()": "651", + "transfer(address,uint256)": "43395", + "transferFrom(address,address,uint256)": "64484", + "withdraw(uint256)": "infinite" + } + }, + "methodIdentifiers": { + "allowance(address,address)": "dd62ed3e", + "approve(address,uint256)": "095ea7b3", + "balanceOf(address)": "70a08231", + "decimals()": "313ce567", + "deposit()": "d0e30db0", + "name()": "06fdde03", + "symbol()": "95d89b41", + "totalSupply()": "18160ddd", + "transfer(address,uint256)": "a9059cbb", + "transferFrom(address,address,uint256)": "23b872dd", + "withdraw(uint256)": "2e1a7d4d" + } + }, + "abi": [ + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "guy", + "type": "address" + }, + { + "name": "wad", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "src", + "type": "address" + }, + { + "name": "dst", + "type": "address" + }, + { + "name": "wad", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "wad", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "decimals", + "outputs": [ + { + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "dst", + "type": "address" + }, + { + "name": "wad", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "deposit", + "outputs": [], + "payable": true, + "stateMutability": "payable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "address" + }, + { + "name": "", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "payable": true, + "stateMutability": "payable", + "type": "fallback" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "src", + "type": "address" + }, + { + "indexed": true, + "name": "guy", + "type": "address" + }, + { + "indexed": false, + "name": "wad", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "src", + "type": "address" + }, + { + "indexed": true, + "name": "dst", + "type": "address" + }, + { + "indexed": false, + "name": "wad", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "dst", + "type": "address" + }, + { + "indexed": false, + "name": "wad", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "src", + "type": "address" + }, + { + "indexed": false, + "name": "wad", + "type": "uint256" + } + ], + "name": "Withdrawal", + "type": "event" + } + ] +} diff --git a/analyzer/evmabi/evmabi.go b/analyzer/evmabi/evmabi.go index 0ec715fad..e9b0e787d 100644 --- a/analyzer/evmabi/evmabi.go +++ b/analyzer/evmabi/evmabi.go @@ -40,3 +40,7 @@ var ERC721Metadata = MustUnmarshalABI(artifactERC721MetadataJSON) //go:embed contracts/artifacts/ERC721Enumerable.json var artifactERC721EnumerableJSON []byte var ERC721Enumerable = MustUnmarshalABI(artifactERC721EnumerableJSON) + +//go:embed contracts/artifacts/WROSE.json +var artifactWROSEJSON []byte +var WROSE = MustUnmarshalABI(artifactWROSEJSON) diff --git a/analyzer/runtime/extract.go b/analyzer/runtime/extract.go index aa49e8808..813c97ff1 100644 --- a/analyzer/runtime/extract.go +++ b/analyzer/runtime/extract.go @@ -829,6 +829,7 @@ func extractEvents(blockData *BlockData, relatedAccountAddresses map[apiTypes.Ad Body: event.UndelegateStart, WithScope: ScopedSdkEvent{ConsensusAccounts: event}, RelatedAddresses: map[apiTypes.Address]bool{fromAddr: true, toAddr: true}, + // We cannot set EvmLogSignature here because topics[0] is not the log signature for anonymous events. } extractedEvents = append(extractedEvents, &eventData) } @@ -1106,6 +1107,87 @@ func extractEvents(blockData *BlockData, relatedAccountAddresses map[apiTypes.Ad } return nil }, + WROSEDeposit: func(ownerECAddr ethCommon.Address, amount *big.Int) error { + wrapperAddr := eventAddr // the WROSE wrapper contract is implicitly the address that emitted the contract + + ownerAddr, err2 := registerRelatedEthAddress(blockData.AddressPreimages, relatedAccountAddresses, ownerECAddr.Bytes()) + if err2 != nil { + return fmt.Errorf("owner: %w", err2) + } + eventData.RelatedAddresses[ownerAddr] = true + registerTokenIncrease(blockData.TokenBalanceChanges, wrapperAddr, ownerAddr, amount) + registerTokenIncrease(blockData.TokenBalanceChanges, evm.NativeRuntimeTokenAddress, wrapperAddr, amount) + registerTokenDecrease(blockData.TokenBalanceChanges, evm.NativeRuntimeTokenAddress, ownerAddr, amount) + + // ^ The above includes dead-reckoning for the native token because no events are emitted for native token transfers. + // + // Example: in mainnet Emerald block 7847845, account A withdrew 1 WROSE from the WROSE contract, + // i.e. unwrapped 1 WROSE into ROSE. The effect is that A's WROSE balance decreases by 1, + // and the WROSE contract transfers 1 ROSE to A. + // However, that block shows a single event: evm.log Withdrawal(from=A, value=1000000000000000000) + // Similarly, in block 7847770, A deposited 1 ROSE into the WROSE contract. + // No ROSE events were emitted, only evm.log Deposit(to=A, value=1000000000000000000) + // + // Details for the above example: + // A = 0x2435ff763095d7c8ABfc1F05d1C4031B44013914 + // WROSE = 0x21C718C22D52d0F3a789b752D4c2fD5908a8A733 + + if _, ok := blockData.PossibleTokens[eventAddr]; !ok { + blockData.PossibleTokens[eventAddr] = &evm.EVMPossibleToken{} + } + + eventData.EvmLogName = evmabi.WROSE.Events["Deposit"].Name + eventData.EvmLogSignature = ethCommon.BytesToHash(event.Topics[0]) + eventData.EvmLogParams = []*apiTypes.EvmEventParam{ + { + Name: "dst", + EvmType: "address", + Value: ownerECAddr, + }, + { + Name: "wad", + EvmType: "uint256", + // JSON supports encoding big integers, but many clients (javascript, jq, etc.) + // will incorrectly parse them as floats. So we encode uint256 as a string instead. + Value: amount.String(), + }, + } + return nil + }, + WROSEWithdrawal: func(ownerECAddr ethCommon.Address, amount *big.Int) error { + wrapperAddr := eventAddr // the WROSE wrapper contract is implicitly the address that emitted the contract + + ownerAddr, err2 := registerRelatedEthAddress(blockData.AddressPreimages, relatedAccountAddresses, ownerECAddr.Bytes()) + if err2 != nil { + return fmt.Errorf("owner: %w", err2) + } + eventData.RelatedAddresses[ownerAddr] = true + registerTokenDecrease(blockData.TokenBalanceChanges, wrapperAddr, ownerAddr, amount) + registerTokenIncrease(blockData.TokenBalanceChanges, evm.NativeRuntimeTokenAddress, ownerAddr, amount) + registerTokenDecrease(blockData.TokenBalanceChanges, evm.NativeRuntimeTokenAddress, wrapperAddr, amount) + + if _, ok := blockData.PossibleTokens[eventAddr]; !ok { + blockData.PossibleTokens[eventAddr] = &evm.EVMPossibleToken{} + } + + eventData.EvmLogName = evmabi.WROSE.Events["Withdrawal"].Name + eventData.EvmLogSignature = ethCommon.BytesToHash(event.Topics[0]) + eventData.EvmLogParams = []*apiTypes.EvmEventParam{ + { + Name: "src", + EvmType: "address", + Value: ownerECAddr, + }, + { + Name: "wad", + EvmType: "uint256", + // JSON supports encoding big integers, but many clients (javascript, jq, etc.) + // will incorrectly parse them as floats. So we encode uint256 as a string instead. + Value: amount.String(), + }, + } + return nil + }, }); err1 != nil { return err1 } diff --git a/analyzer/runtime/visitors.go b/analyzer/runtime/visitors.go index 9ed6e5bbd..bbc774a66 100644 --- a/analyzer/runtime/visitors.go +++ b/analyzer/runtime/visitors.go @@ -199,6 +199,12 @@ type EVMEventHandler struct { ERC721Transfer func(from ethCommon.Address, to ethCommon.Address, tokenID *big.Int) error ERC721Approval func(owner ethCommon.Address, approved ethCommon.Address, tokenID *big.Int) error ERC721ApprovalForAll func(owner ethCommon.Address, operator ethCommon.Address, approved bool) error + // `owner` wrapped/deposited runtime's native token (ROSE) into the wrapper contract (creating WROSE). + // `value` ROSE is transferred from `owner` to the wrapper (= event-emitting contract). Caller's WROSE balance increases by `value`. + WROSEDeposit func(owner ethCommon.Address, value *big.Int) error + // `owner` unwrapped/withdrew runtime's native token (ROSE) into the wrapper contract (burning WROSE). + // Caller's WROSE balance decreases by `value`. `value` ROSE is transferred from the wrapper (= event-emitting contract) to `owner`. + WROSEWithdrawal func(owner ethCommon.Address, value *big.Int) error } func eventMatches(evmEvent *evm.Event, ethEvent abi.Event) bool { @@ -232,7 +238,7 @@ func VisitEVMEvent(event *evm.Event, handler *EVMEventHandler) error { args[1].(ethCommon.Address), args[2].(*big.Int), ); err != nil { - return fmt.Errorf("erc20 transfer: %w", err) + return fmt.Errorf("handle erc20 transfer: %w", err) } } case eventMatches(event, evmabi.ERC20.Events["Approval"]): @@ -246,7 +252,7 @@ func VisitEVMEvent(event *evm.Event, handler *EVMEventHandler) error { args[1].(ethCommon.Address), args[2].(*big.Int), ); err != nil { - return fmt.Errorf("erc20 approval: %w", err) + return fmt.Errorf("handle erc20 approval: %w", err) } } case eventMatches(event, evmabi.ERC721.Events["Transfer"]): @@ -260,7 +266,7 @@ func VisitEVMEvent(event *evm.Event, handler *EVMEventHandler) error { args[1].(ethCommon.Address), args[2].(*big.Int), ); err != nil { - return fmt.Errorf("erc721 transfer: %w", err) + return fmt.Errorf("handle erc721 transfer: %w", err) } } case eventMatches(event, evmabi.ERC721.Events["Approval"]): @@ -274,7 +280,7 @@ func VisitEVMEvent(event *evm.Event, handler *EVMEventHandler) error { args[1].(ethCommon.Address), args[2].(*big.Int), ); err != nil { - return fmt.Errorf("erc721 approval: %w", err) + return fmt.Errorf("handle erc721 approval: %w", err) } } case eventMatches(event, evmabi.ERC721.Events["ApprovalForAll"]): @@ -288,7 +294,35 @@ func VisitEVMEvent(event *evm.Event, handler *EVMEventHandler) error { args[1].(ethCommon.Address), args[2].(bool), ); err != nil { - return fmt.Errorf("erc721 approval for all: %w", err) + return fmt.Errorf("handle erc721 approval for all: %w", err) + } + } + // Signature: 0xe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c (hex) or 4f/8xJI9BLVZ9NKai/xs2gTrWw08RgdRwkAsXFzJEJw= (base64) + case eventMatches(event, evmabi.WROSE.Events["Deposit"]): + if handler.WROSEDeposit != nil { + _, args, err := abiparse.ParseEvent(event.Topics, event.Data, evmabi.WROSE) + if err != nil { + return fmt.Errorf("parse wrose deposit: %w", err) + } + if err = handler.WROSEDeposit( + args[0].(ethCommon.Address), + args[1].(*big.Int), + ); err != nil { + return fmt.Errorf("handle wrose deposit: %w", err) + } + } + // Signature: 0x7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65 (hex) or f89TLBXwptsL1tDgOL6nHTDYCMfZjLO/cmipW/UIG2U= (base64) + case eventMatches(event, evmabi.WROSE.Events["Withdrawal"]): + if handler.WROSEWithdrawal != nil { + _, args, err := abiparse.ParseEvent(event.Topics, event.Data, evmabi.WROSE) + if err != nil { + return fmt.Errorf("parse wrose withdrawal: %w", err) + } + if err = handler.WROSEWithdrawal( + args[0].(ethCommon.Address), + args[1].(*big.Int), + ); err != nil { + return fmt.Errorf("handle wrose withdrawal: %w", err) } } } From f3a6c0495432f36e0430e7cccbd77675216a82f6 Mon Sep 17 00:00:00 2001 From: Mitja T Date: Tue, 28 Nov 2023 23:38:07 -0800 Subject: [PATCH 2/4] Update e2e results --- .../expected/db__evm_balances.csv | 5 ++ .../expected/emerald_events.body | 14 ++++- .../expected/emerald_token.body | 2 +- .../expected/emerald_token_holders.body | 52 +++++++++--------- .../expected/emerald_tokens.body | 24 ++++---- .../rpc-cache/emerald/00000-1.psg | Bin 18714370 -> 18717104 bytes .../rpc-cache/emerald/00000-1.psg.pmt | Bin 621 -> 621 bytes .../rpc-cache/emerald/index.pmt | Bin 657 -> 657 bytes .../e2e_regression/rpc-cache/emerald/main.pix | Bin 168448 -> 168448 bytes .../rpc-cache/emerald/overflow.pix | Bin 23040 -> 23040 bytes 10 files changed, 57 insertions(+), 40 deletions(-) diff --git a/tests/e2e_regression/expected/db__evm_balances.csv b/tests/e2e_regression/expected/db__evm_balances.csv index 70d3da597..8f94eb8ba 100644 --- a/tests/e2e_regression/expected/db__evm_balances.csv +++ b/tests/e2e_regression/expected/db__evm_balances.csv @@ -141,6 +141,7 @@ emerald,oasis1qpgcp5jzlgk4hcenaj2x82rqk8rrve2keyuc8aaf,oasis1qp4ea625vm8a8h953m9 emerald,oasis1qpgcp5jzlgk4hcenaj2x82rqk8rrve2keyuc8aaf,oasis1qp4kmt69u7kts4tak44fkmucp8wf5n8mrykv8ljv,10688918093504000157 emerald,oasis1qpgcp5jzlgk4hcenaj2x82rqk8rrve2keyuc8aaf,oasis1qp4wveera0cwde5jsxxnr6ld0v6stlskxuglkghg,156539866342556565450177 emerald,oasis1qpgcp5jzlgk4hcenaj2x82rqk8rrve2keyuc8aaf,oasis1qp6z6cu688mshx0j7q22evutye4ue27xtymrj7fm,26264688946382165974369 +emerald,oasis1qpgcp5jzlgk4hcenaj2x82rqk8rrve2keyuc8aaf,oasis1qp9et6mexa0nyyx3q95n5zfs0p4w0ltg3scaaws5,137143306750924749264 emerald,oasis1qpgcp5jzlgk4hcenaj2x82rqk8rrve2keyuc8aaf,oasis1qpfvjgcjj4gzjcyv3u87uhuutu87065g5uup32ux,1396355662401688145 emerald,oasis1qpgcp5jzlgk4hcenaj2x82rqk8rrve2keyuc8aaf,oasis1qpg68lh7jk3zgvnmedfyqrgtd679kk8pzyu9j62k,447710308244836 emerald,oasis1qpgcp5jzlgk4hcenaj2x82rqk8rrve2keyuc8aaf,oasis1qpjaapzc7e3exckszq0n53f0k690wyzy9vz4hmtw,134690857157501250482017 @@ -168,6 +169,7 @@ emerald,oasis1qpgcp5jzlgk4hcenaj2x82rqk8rrve2keyuc8aaf,oasis1qq2styhx4yknqxss3xw emerald,oasis1qpgcp5jzlgk4hcenaj2x82rqk8rrve2keyuc8aaf,oasis1qq2yx2slnma9gxgzfq3ft9pedqgxzd8klyfslqn6,40745883638033914690526 emerald,oasis1qpgcp5jzlgk4hcenaj2x82rqk8rrve2keyuc8aaf,oasis1qq3mavddm7aj6v2r6ax4ad6u7lym336mc58n7h5t,963947261612550888749 emerald,oasis1qpgcp5jzlgk4hcenaj2x82rqk8rrve2keyuc8aaf,oasis1qq3q3awrrcl64rzvhxyc6ykjveny7zczkqrm28yp,1782689760270071616619888 +emerald,oasis1qpgcp5jzlgk4hcenaj2x82rqk8rrve2keyuc8aaf,oasis1qq4hp3mfsp2vvfqlt35tn59h4cx08wyd2vlrpxx7,37790213374165533333299 emerald,oasis1qpgcp5jzlgk4hcenaj2x82rqk8rrve2keyuc8aaf,oasis1qq5cxq28sr5360a3dsqe5pl0p8axlur8agpm0x4u,181215216348578320 emerald,oasis1qpgcp5jzlgk4hcenaj2x82rqk8rrve2keyuc8aaf,oasis1qq6w27n94lf45hshtyxuwd9a4sq56t8cxyke8zd2,8014310264760728716 emerald,oasis1qpgcp5jzlgk4hcenaj2x82rqk8rrve2keyuc8aaf,oasis1qq8g6w3pa4lm57468qtsz0tvnlsdpcu535ss7wpn,20593294086374608732 @@ -184,6 +186,7 @@ emerald,oasis1qpgcp5jzlgk4hcenaj2x82rqk8rrve2keyuc8aaf,oasis1qqgmdg5wr2zh350780g emerald,oasis1qpgcp5jzlgk4hcenaj2x82rqk8rrve2keyuc8aaf,oasis1qqgqw6fs93w0j9mrpxjg4uavqlz6y8fj9s9vv0lk,201082918271679735 emerald,oasis1qpgcp5jzlgk4hcenaj2x82rqk8rrve2keyuc8aaf,oasis1qqh3qy6uy49kw2l75pw5nkxygsun06k6lueskguy,32411397180437988928434 emerald,oasis1qpgcp5jzlgk4hcenaj2x82rqk8rrve2keyuc8aaf,oasis1qqh7mvlge57vsllqu5dnuerscwa22jj9eqwvpmxs,25209997445468732109288 +emerald,oasis1qpgcp5jzlgk4hcenaj2x82rqk8rrve2keyuc8aaf,oasis1qqlguxv5dvk4hu74jjk9acutmmm5a38j0c0x90sf,452858779323991141874 emerald,oasis1qpgcp5jzlgk4hcenaj2x82rqk8rrve2keyuc8aaf,oasis1qqrme0kxj6trd3edjhzpzqnr7lcjvpwr5usumkze,30507466736691235206660 emerald,oasis1qpgcp5jzlgk4hcenaj2x82rqk8rrve2keyuc8aaf,oasis1qqt6kmyzv620rmx4mjzqlugy4n0y4nhyzsattr7x,1867992270111567391412646 emerald,oasis1qpgcp5jzlgk4hcenaj2x82rqk8rrve2keyuc8aaf,oasis1qqv02n0w2eerustj2m0p3tl69rscvn3x8uwzvxyx,186694709994367722963634 @@ -215,6 +218,7 @@ emerald,oasis1qpgcp5jzlgk4hcenaj2x82rqk8rrve2keyuc8aaf,oasis1qrf7cth4azs3u5g9v6v emerald,oasis1qpgcp5jzlgk4hcenaj2x82rqk8rrve2keyuc8aaf,oasis1qrfqjn9pkyadvuusxzruj6jdq0ykd7dsf5ltdzrc,39484003235544295217 emerald,oasis1qpgcp5jzlgk4hcenaj2x82rqk8rrve2keyuc8aaf,oasis1qrgpjt6uvnqayjycrmsrcyse9cult7uze5jc7jth,15285086395047442816485 emerald,oasis1qpgcp5jzlgk4hcenaj2x82rqk8rrve2keyuc8aaf,oasis1qrk9appc6lhxnx5xhk0ga2w8http5h6fsylxyau7,1146586449943194918267914 +emerald,oasis1qpgcp5jzlgk4hcenaj2x82rqk8rrve2keyuc8aaf,oasis1qrlxuqztjaequ8up3qu8xpfe9fsmg22d2gc4x7fr,68489772985955832475 emerald,oasis1qpgcp5jzlgk4hcenaj2x82rqk8rrve2keyuc8aaf,oasis1qrpt07y9y968rgvckhz8ykj8d2gk2agelvx65l6g,45574747939268354290 emerald,oasis1qpgcp5jzlgk4hcenaj2x82rqk8rrve2keyuc8aaf,oasis1qrqewnqd5cflrq2732c5u5dt43ar8g9gsy0t7hpd,314262025227635605 emerald,oasis1qpgcp5jzlgk4hcenaj2x82rqk8rrve2keyuc8aaf,oasis1qrqtawexs396hp2txznnjqfgd7a95fkwgudysqgy,600000000006821 @@ -225,6 +229,7 @@ emerald,oasis1qpgcp5jzlgk4hcenaj2x82rqk8rrve2keyuc8aaf,oasis1qrsd857j0rjn60sx79z emerald,oasis1qpgcp5jzlgk4hcenaj2x82rqk8rrve2keyuc8aaf,oasis1qrufx0224ghm3wy9x3t98j5makhwg2cfc568xj89,76086479250941843109 emerald,oasis1qpgcp5jzlgk4hcenaj2x82rqk8rrve2keyuc8aaf,oasis1qrv6kvaj6z9srp6urk0jezyqupq5qm5njvs52m36,235591290865892702 emerald,oasis1qpgcp5jzlgk4hcenaj2x82rqk8rrve2keyuc8aaf,oasis1qrvyg5qv4rknre58gm9jk8zml6sc4q6e2q77n9dr,2881845240453607957 +emerald,oasis1qpgcp5jzlgk4hcenaj2x82rqk8rrve2keyuc8aaf,oasis1qrwcw4a893jp0jf5zg92ugz96rp2vj2mcvrsqmpl,251243281025540000000000 emerald,oasis1qpgcp5jzlgk4hcenaj2x82rqk8rrve2keyuc8aaf,oasis1qrxkfykuptq48cjwjymn68e8a3wsvd3hxvufqqr0,417282953432831567555 emerald,oasis1qpgcp5jzlgk4hcenaj2x82rqk8rrve2keyuc8aaf,oasis1qz0mmlh27zkrk062e7daz3wyrk5jftuj6gk8rlya,253975562210353750630 emerald,oasis1qpgcp5jzlgk4hcenaj2x82rqk8rrve2keyuc8aaf,oasis1qz0szf4f4lcn3qr4aree5una2gyz0snq6sgafy5m,60649220217623625938265 diff --git a/tests/e2e_regression/expected/emerald_events.body b/tests/e2e_regression/expected/emerald_events.body index 8b4bc07a8..2ac0f238a 100644 --- a/tests/e2e_regression/expected/emerald_events.body +++ b/tests/e2e_regression/expected/emerald_events.body @@ -965,7 +965,19 @@ ] }, "eth_tx_hash": "e8a911990ef643cb4472855b5810c18e1414d09fb7471ee1ae4c0a270fbafbe2", - "evm_log_name": "", + "evm_log_name": "Deposit", + "evm_log_params": [ + { + "evm_type": "address", + "name": "dst", + "value": "0x250d48c5e78f1e85f7ab07fec61e93ba703ae668" + }, + { + "evm_type": "uint256", + "name": "wad", + "value": "2000000000000000000" + } + ], "evm_token": { "decimals": 18, "symbol": "wROSE", diff --git a/tests/e2e_regression/expected/emerald_token.body b/tests/e2e_regression/expected/emerald_token.body index 9699f0ac2..37f8ae2e1 100644 --- a/tests/e2e_regression/expected/emerald_token.body +++ b/tests/e2e_regression/expected/emerald_token.body @@ -4,7 +4,7 @@ "eth_contract_addr": "0x21C718C22D52d0F3a789b752D4c2fD5908a8A733", "is_verified": false, "name": "Wrapped ROSE", - "num_holders": 126, + "num_holders": 131, "num_transfers": 2113, "symbol": "wROSE", "total_supply": "134273688211406143160770252", diff --git a/tests/e2e_regression/expected/emerald_token_holders.body b/tests/e2e_regression/expected/emerald_token_holders.body index 54a9fd430..c0d8383ec 100644 --- a/tests/e2e_regression/expected/emerald_token_holders.body +++ b/tests/e2e_regression/expected/emerald_token_holders.body @@ -95,6 +95,11 @@ "eth_holder_address": "0x1Ba37943f2346F8D1b7264a65A404D416B3e9eea", "holder_address": "oasis1qzur4dfk9eqenuwyzcpp0p6x4nydfl0nlqt28jsc" }, + { + "balance": "251243281025540000000000", + "eth_holder_address": "0x5848C791e09901b40A9Ef749f2a6735b418d7564", + "holder_address": "oasis1qrwcw4a893jp0jf5zg92ugz96rp2vj2mcvrsqmpl" + }, { "balance": "196022554099460246173161", "eth_holder_address": "0xAdB8E60B7BF0841680e3034590beB15d797A1B7A", @@ -165,6 +170,11 @@ "eth_holder_address": "0xcDB4198Fd739B768aa816A3068662abE958Fa6c4", "holder_address": "oasis1qr3g9759ew429lytjq3a7pe2zpnmqtdueqdszy32" }, + { + "balance": "37790213374165533333299", + "eth_holder_address": "0x7bc8b1B5AbA4dF3Be9f9A32daE501214dC0E4f3f", + "holder_address": "oasis1qq4hp3mfsp2vvfqlt35tn59h4cx08wyd2vlrpxx7" + }, { "balance": "37223313022281370382404", "eth_holder_address": "0x3992B313c956d058Fae8147EF7Fe20e0cF3f13eB", @@ -330,6 +340,11 @@ "eth_holder_address": "0x5b98A37Eb30F3130e4fF61EcFc7b70602CbAE67B", "holder_address": "oasis1qqatz6uj08mvs4nh4y8cnlzlkfsrgpg98uza0fm3" }, + { + "balance": "452858779323991141874", + "eth_holder_address": "0xA50E975E7dc7418756cA1B2A54415f286dCD0626", + "holder_address": "oasis1qqlguxv5dvk4hu74jjk9acutmmm5a38j0c0x90sf" + }, { "balance": "417282953432831567555", "eth_holder_address": "0x3a82B2d4fee1BffD7a18FE6932e4d18DBfe58947", @@ -380,6 +395,11 @@ "eth_holder_address": "0x8199c4F756985E03B0746f2229A722914099E237", "holder_address": "oasis1qr3nja5g8e7e2j6hsnwpsdyz8zuv7v53a554d2m6" }, + { + "balance": "137143306750924749264", + "eth_holder_address": "0x18eC663BE52baC93a6687D8c95C692174BaBA803", + "holder_address": "oasis1qp9et6mexa0nyyx3q95n5zfs0p4w0ltg3scaaws5" + }, { "balance": "118097578603115375935", "eth_holder_address": "0xBA5Aa78B8254201D3A88626006E5d9dC2143C034", @@ -420,6 +440,11 @@ "eth_holder_address": "0xE39009aD4562dEf56BC9d13984671DEFB25505dF", "holder_address": "oasis1qpx9hpwca2shu9d09ldt9ylh7vymdxa085saj6yg" }, + { + "balance": "68489772985955832475", + "eth_holder_address": "0x83D76c3F8138071E61A1f3b22c0613393D5CA731", + "holder_address": "oasis1qrlxuqztjaequ8up3qu8xpfe9fsmg22d2gc4x7fr" + }, { "balance": "68297073222180707162", "eth_holder_address": "0x7eEECf5f3D2eb5b7C2F565C669675Bb690c00Da0", @@ -474,33 +499,8 @@ "balance": "10146044617261364206", "eth_holder_address": "0xF04A65B4f1F53FF56Db57feE8E3e395B3cB1D699", "holder_address": "oasis1qpn4ayjxasuz03y6w2wm45w9en4hg5mf0uz8dgd6" - }, - { - "balance": "8014310264760728716", - "eth_holder_address": "0xEec92107c67C9b6F0875329D7c6E177d864B49a4", - "holder_address": "oasis1qq6w27n94lf45hshtyxuwd9a4sq56t8cxyke8zd2" - }, - { - "balance": "6024280045801688191", - "eth_holder_address": "0x1EbB73f5F47Bcc3D7dC1dabf7284875E3AE40E07", - "holder_address": "oasis1qz87hgw4rgge8kjfugyp6edfa703gnjmjqnmr9up" - }, - { - "balance": "5049575763814672029", - "eth_holder_address": "0x55978F18a1D01C92c72DE87e4eF53018E4B709Eb", - "holder_address": "oasis1qzv2qc7ta3d7lpdfrnlxfvwtyvdsdklz2y9c0q6c" - }, - { - "balance": "3688786471673099892", - "eth_holder_address": "0x3B6dFA69c26912CdC6b0B969ca500F29A7a0bc99", - "holder_address": "oasis1qreah5vvpf2hrulrdaj7pqfjjsz24mwujsntk222" - }, - { - "balance": "3356263870845886955", - "eth_holder_address": "0x7AFAbd4A099cD401462218759bcAF50268215Ccc", - "holder_address": "oasis1qrdkufnzhcw42rplx4rx66v6cct5tjewt5tsdeuk" } ], "is_total_count_clipped": false, - "total_count": 126 + "total_count": 131 } diff --git a/tests/e2e_regression/expected/emerald_tokens.body b/tests/e2e_regression/expected/emerald_tokens.body index 2431a93e2..d473dcb68 100644 --- a/tests/e2e_regression/expected/emerald_tokens.body +++ b/tests/e2e_regression/expected/emerald_tokens.body @@ -1,5 +1,17 @@ { "evm_tokens": [ + { + "contract_addr": "oasis1qpgcp5jzlgk4hcenaj2x82rqk8rrve2keyuc8aaf", + "decimals": 18, + "eth_contract_addr": "0x21C718C22D52d0F3a789b752D4c2fD5908a8A733", + "is_verified": false, + "name": "Wrapped ROSE", + "num_holders": 131, + "num_transfers": 2113, + "symbol": "wROSE", + "total_supply": "134273688211406143160770252", + "type": "ERC20" + }, { "contract_addr": "oasis1qrg90d4qlelg5zg4q4sd4y0z8j2lpjpvuspzjlyl", "decimals": 6, @@ -12,18 +24,6 @@ "total_supply": "96164907280233", "type": "ERC20" }, - { - "contract_addr": "oasis1qpgcp5jzlgk4hcenaj2x82rqk8rrve2keyuc8aaf", - "decimals": 18, - "eth_contract_addr": "0x21C718C22D52d0F3a789b752D4c2fD5908a8A733", - "is_verified": false, - "name": "Wrapped ROSE", - "num_holders": 126, - "num_transfers": 2113, - "symbol": "wROSE", - "total_supply": "134273688211406143160770252", - "type": "ERC20" - }, { "contract_addr": "oasis1qqz8706pmf38wmptl6dkcaec8yykw0rvfv7ql6fc", "decimals": 18, diff --git a/tests/e2e_regression/rpc-cache/emerald/00000-1.psg b/tests/e2e_regression/rpc-cache/emerald/00000-1.psg index 3f01844951186f0a2eeb97f17428cef512cf4c14..28b017d571adb61ee1bf2b0a21dccfbdf04ca7b4 100644 GIT binary patch delta 1086 zcmZXQX;{>C6otDp1Iz%UECVyZ5U5eKSP-I?MX9)yxU^7a(q@=oI)YScs5rhU$xjeN zrV{vLTAFB@C|ZF*rEN+eZB|5CS(Yu6EJ3AC57Q?<-gD2n&wG!vs@u4`w%b^MphJ%V zAAIq{hzWlJ2*k_)1`jh#-_l@hF~l;6!3^ON;<%K{i05*y;7YDy zC|7e02_$kYNem;I;f!D;*Ks|gxPco<;U;coG-DV`D&rW>1SWC|w=#(|CNqVpOyf3g z=ML^9ox8Z3>DI9Naqxhy1)$9SA4 zSj1wM@Fe*xWf{vUUoa*v|o8<8|Jko(2x`CXF=l7H{(o zhd9i;yvO@|z=s^+D9wCC3#}ZZjgR?+Px*|`InEb+$yc=VH647zx18WRzUK!{@*_WS zil6y~)BMVB{LUY^`I9qr(nU8t{6#N){LMf7%URA9iV{&eQF>7ZQ9h!4Mfr&`iZY4v z7Zo5XP?TBJ08s-)1&In46(TBBltomSsBlqMQ8rN#q9R2_iLy(5wCGB-#C)q{yXty% z7Ol0%BGEB^j+B!fo6~w*7Nln8W#-PynxC~WFKgDg+}!Rt<+g_Yfab`GlH}4@A8no9 zEFt>vjzwC6=h9qlX=J3N=?gZk(1O!Fvn!*r(4y@svdKt8RbAW~Z#-jVgrpgkK;rPU_UuARsGOq%n6RYDAn`^SfP4dyt5MT?sDAJ~}5d)vM0(ZE!Xx-8P8_RVfu zgypYwqd*2{mL4 z9kIRNr8&AhE$Cu8HMiL=sos}jYr{O%B(((=YdL3pB|f4m$JRD|RLgKzYOZ7E5oh&` mNn6van;Yr!?wy%M!3hpE(Wge0oj7%9P;+Z`P4(GOoAW%wIM0&+ delta 610 zcmV~$2b>pT007Y6ch}whZ{Kx$Q3;umipr{ll7u7)p&^u2MxyJy>hKXov`JP}mlKsk zQE1z;vMDo-OIE#CSKpYZncbME79>g5M2b{t64GVJlqFk^TzT>}RiIFjVkJtIDOaIV zl>;28ndVwJNJ|Gh#GzU_%;Ao3q@x_IwPPHsjpMY{PJ72YK?fama-x%*>=dW!tc$Kr z)6MD5aHj5hI7?4w>*XB1o$Ea3>*E4_U8tXn^mnlVE^(>L40O3GTxpQOh8XH9!(8ne z*BWkw>s;>!H@eA4qulHkx4O+}w;SUQcN(kOI5qCVcoR%i>u&eBS9G8IP4a*TO*X|t z9yZk@9yQH$Gt4y0Y;!#3adSOko+mx!Y0r4pe9w8_0t+otXR#O5d(jdvdD&9SEcc2A zuX@evR#@o`Z(3!wx4i8gYpk`-dK+xC$-Cb3z7KrpBOm+3W}o`Z=f3czExz)#Z+z=J z-}}LjezMgzKl{b6e)GFOZ1<-fcG_jPMtl5aufP4{U;p{vzS#(#_+j2;XCE))dH delta 16 XcmbQpI+1llClkj`#(#_+j2;XCEtCYh diff --git a/tests/e2e_regression/rpc-cache/emerald/main.pix b/tests/e2e_regression/rpc-cache/emerald/main.pix index 0f8b4613397aed7e1803dfa03522c1e803d6dc79..43565c847f5f9affac825deef5567c98003b8ae0 100644 GIT binary patch delta 356 zcmZoz!qu>ZYlDKNfV3Iodj^II1`7rT28k)Mj1vVfY_huGCSWgM!2=V2HBpvvqo4xg zrlx}F0^O6&O2H&bW`Hy_Y?ET#AS^KT-rS2Y2?L;xiGmK>^cWvV3oM><%mpUVGgX#x z`v*_P25y0s527D4Fqkng0&UKp2{9;)vA|H^kfB`xOg+PNh(rhD1Z9CM23f~p5={Ld ziG*!y7&nLuJa}{74ki&d8DjMj#sYJJKU{U6VRq<2?fAnufmz_+1+N;Ij!R%~Cv0Jw z;3l9{Sr!QsUor{g?F7bc9!v{(1T-hIUxCT&0b0IMFo1De7?XpkfJ4oqej*u5K; I^)Rsk0BS*DbN~PV delta 120 zcmZoz!qu>ZYlDL2M8OA}tS-216f|Jm)KoBiqTqyWQj8mfCkh5^(_?%fJyB3$n-^mN zH%L5;vA_^ScQ8&+o+wzbZ4KiFage$rj0NT(@jr|cn1SM3m?i*?D`4E_!L)#9qhJE# RwlF3K(}{uymh~{P0RYvfEO`I` diff --git a/tests/e2e_regression/rpc-cache/emerald/overflow.pix b/tests/e2e_regression/rpc-cache/emerald/overflow.pix index c5d42d8a4b6cd3fa497961f9c4594176124b4d23..0f0b793d09e1c22b3e1fa4ed36f6ffb220e4d04c 100644 GIT binary patch delta 58 zcmZqJ!q~8daf5@NK%w`7CI*HI1`7rT2DfRlj2i_vFm5sskP}ETT5=mEQ8oc2@qlqr G02cuBtPnf^ delta 26 icmZqJ!q~8daf5^2M!^G&n+ycxHVVFH-2C64kqZEdm Date: Fri, 1 Dec 2023 12:45:05 -0800 Subject: [PATCH 3/4] EXPERIMENT: Re-query ERC-20 balance of user for every interaction with contract --- analyzer/queries/queries.go | 11 +++++++++-- analyzer/runtime/extract.go | 2 ++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/analyzer/queries/queries.go b/analyzer/queries/queries.go index 23963aa64..7b6d41f94 100644 --- a/analyzer/queries/queries.go +++ b/analyzer/queries/queries.go @@ -557,8 +557,13 @@ var ( RuntimeEVMTokenBalanceAnalysisMutateRoundUpsert = ` INSERT INTO analysis.evm_token_balances (runtime, token_address, account_address, last_mutate_round) - VALUES - ($1, $2, $3, $4) + ( + SELECT $1, $2, $3, $4 + -- Insert the row only if $2 is a valid token. The runtime analyzer enqueues for balance re-querying + -- every (contract, account) pair that interacts, regardless of whether the contract is a token, + -- because the analyzer doesn't have access to that info. + WHERE EXISTS (SELECT 1 FROM chain.evm_tokens WHERE runtime = $1::runtime AND token_address = $2::oasis_addr) + ) ON CONFLICT (runtime, token_address, account_address) DO UPDATE SET last_mutate_round = excluded.last_mutate_round` @@ -578,6 +583,8 @@ var ( SELECT runtime, token_address, account_address, MAX(last_mutate_round) FROM todo_updates.evm_token_balances WHERE runtime = $1 + -- TODO: Filter out rows where "token_address" is not a token? + -- But we don't know yet which contracts are tokens since fast-sync just concluded. GROUP BY runtime, token_address, account_address ) ON CONFLICT (runtime, token_address, account_address) DO UPDATE diff --git a/analyzer/runtime/extract.go b/analyzer/runtime/extract.go index 813c97ff1..ad4785af4 100644 --- a/analyzer/runtime/extract.go +++ b/analyzer/runtime/extract.go @@ -544,6 +544,8 @@ func ExtractRound(blockHeader nodeapi.RuntimeBlockHeader, txrs []nodeapi.Runtime registerTokenIncrease(blockData.TokenBalanceChanges, evm.NativeRuntimeTokenAddress, to, reckonedAmount) for _, signer := range blockTransactionData.SignerData { registerTokenDecrease(blockData.TokenBalanceChanges, evm.NativeRuntimeTokenAddress, signer.Address, reckonedAmount) + // In case the contract is an ERC-20, the sender's ERC-20 balance might change as a result of the call. Schedule for re-querying. + registerTokenDecrease(blockData.TokenBalanceChanges, to, signer.Address, big.NewInt(0)) } } From 62df8031ad988437f916fb12a8158cca06ea732f Mon Sep 17 00:00:00 2001 From: Mitja T Date: Fri, 1 Dec 2023 12:46:51 -0800 Subject: [PATCH 4/4] Revert "EXPERIMENT: Re-query ERC-20 balance of user for every interaction with contract" This reverts commit 3ead7da2d7741ffa4582ac831bf0739ec09fc517. --- analyzer/queries/queries.go | 11 ++--------- analyzer/runtime/extract.go | 2 -- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/analyzer/queries/queries.go b/analyzer/queries/queries.go index 7b6d41f94..23963aa64 100644 --- a/analyzer/queries/queries.go +++ b/analyzer/queries/queries.go @@ -557,13 +557,8 @@ var ( RuntimeEVMTokenBalanceAnalysisMutateRoundUpsert = ` INSERT INTO analysis.evm_token_balances (runtime, token_address, account_address, last_mutate_round) - ( - SELECT $1, $2, $3, $4 - -- Insert the row only if $2 is a valid token. The runtime analyzer enqueues for balance re-querying - -- every (contract, account) pair that interacts, regardless of whether the contract is a token, - -- because the analyzer doesn't have access to that info. - WHERE EXISTS (SELECT 1 FROM chain.evm_tokens WHERE runtime = $1::runtime AND token_address = $2::oasis_addr) - ) + VALUES + ($1, $2, $3, $4) ON CONFLICT (runtime, token_address, account_address) DO UPDATE SET last_mutate_round = excluded.last_mutate_round` @@ -583,8 +578,6 @@ var ( SELECT runtime, token_address, account_address, MAX(last_mutate_round) FROM todo_updates.evm_token_balances WHERE runtime = $1 - -- TODO: Filter out rows where "token_address" is not a token? - -- But we don't know yet which contracts are tokens since fast-sync just concluded. GROUP BY runtime, token_address, account_address ) ON CONFLICT (runtime, token_address, account_address) DO UPDATE diff --git a/analyzer/runtime/extract.go b/analyzer/runtime/extract.go index ad4785af4..813c97ff1 100644 --- a/analyzer/runtime/extract.go +++ b/analyzer/runtime/extract.go @@ -544,8 +544,6 @@ func ExtractRound(blockHeader nodeapi.RuntimeBlockHeader, txrs []nodeapi.Runtime registerTokenIncrease(blockData.TokenBalanceChanges, evm.NativeRuntimeTokenAddress, to, reckonedAmount) for _, signer := range blockTransactionData.SignerData { registerTokenDecrease(blockData.TokenBalanceChanges, evm.NativeRuntimeTokenAddress, signer.Address, reckonedAmount) - // In case the contract is an ERC-20, the sender's ERC-20 balance might change as a result of the call. Schedule for re-querying. - registerTokenDecrease(blockData.TokenBalanceChanges, to, signer.Address, big.NewInt(0)) } }