Repository: rotki/rotki

Issue:
Adding an EOA address that has no activity apart from withdrawals/blocks fails.
## Problem Definition

If you try to add an EOA address that has no other activity apart from eth2 withdrawals or non-mev block productions in rotki it fails. The reason is that no transactions/erc20 transfers etc. happened and we don't query for withdrawals or blocks and as such for rotki it seems as if the address has had no activity.

An example address is: https://etherscan.io/address/0x3c69bc9b9681683890ad82953fe67d13cd91d5ee

## Task

When adding/detecting activity for an address, if it's mainnet also check if it has any ETH balance.



Discussion:

Resolving patch:
diff --git a/rotkehlchen/externalapis/etherscan.py b/rotkehlchen/externalapis/etherscan.py
--- a/rotkehlchen/externalapis/etherscan.py
+++ b/rotkehlchen/externalapis/etherscan.py
@@ -55,10 +55,12 @@ class EtherscanHasChainActivity(Enum):
     """
     Classify the type of transaction first found in etherscan. TRANSACTIONS means that the endpoint
     for transactions/internal transactions had entries, TOKENS means that the tokens endpoint had
-    entries and NONE means that no entry has been found in the different endpoints.
+    entries, BALANCE means that the address has a non-zero native asset balance and
+    NONE means that no activity was found.
     """
     TRANSACTIONS = auto()
     TOKENS = auto()
+    BALANCE = auto()
     NONE = auto()
 
 
@@ -532,8 +534,8 @@ def get_token_transaction_hashes(
         yield _hashes_tuple_to_list(hashes)
 
     def has_activity(self, account: ChecksumEvmAddress) -> EtherscanHasChainActivity:
-        """Queries transactions, internal_txs and tokentx for an address with limit=1
-        just to quickly determine if the account has had any activity in the chain.
+        """Queries native asset balance, transactions, internal_txs and tokentx for an address
+        with limit=1 just to quickly determine if the account has had any activity in the chain.
         We make a distinction between transactions and ERC20 transfers since ERC20
         are often spammed. If there was no activity at all we return the enum value
         NONE.
@@ -548,6 +550,10 @@ def has_activity(self, account: ChecksumEvmAddress) -> EtherscanHasChainActivity
         result = self._query(module='account', action='tokentx', options=options)
         if len(result) != 0:
             return EtherscanHasChainActivity.TOKENS
+        if self.chain in {SupportedBlockchain.ETHEREUM, SupportedBlockchain.GNOSIS}:
+            balance = self._query(module='account', action='balance', options={'address': account})
+            if int(balance) != 0:
+                return EtherscanHasChainActivity.BALANCE
         return EtherscanHasChainActivity.NONE
 
     def get_latest_block_number(self) -> int:


Test patch:
diff --git a/rotkehlchen/tests/external_apis/test_etherscan.py b/rotkehlchen/tests/external_apis/test_etherscan.py
--- a/rotkehlchen/tests/external_apis/test_etherscan.py
+++ b/rotkehlchen/tests/external_apis/test_etherscan.py
@@ -12,6 +12,7 @@
 from rotkehlchen.db.dbhandler import DBHandler
 from rotkehlchen.db.evmtx import DBEvmTx
 from rotkehlchen.db.filtering import EvmTransactionsFilterQuery
+from rotkehlchen.externalapis.etherscan import EtherscanHasChainActivity
 from rotkehlchen.globaldb.migrations.migration1 import ILK_REGISTRY_ABI
 from rotkehlchen.serialization.deserialize import deserialize_evm_transaction
 from rotkehlchen.tests.utils.mock import MockResponse
@@ -192,3 +193,13 @@ def test_etherscan_get_contract_abi(temp_etherscan):
     abi = temp_etherscan.get_contract_abi('0x5a464C28D19848f44199D003BeF5ecc87d090F87')
     assert abi == json.loads(ILK_REGISTRY_ABI)
     assert temp_etherscan.get_contract_abi('0x9531C059098e3d194fF87FebB587aB07B30B1306') is None
+
+
+@pytest.mark.vcr(filter_query_parameters=['apikey'])
+def test_has_activity(temp_etherscan):
+    """Test to check if an address has any activity on ethereum mainnet"""
+    assert temp_etherscan.has_activity('0x95222290DD7278Aa3Ddd389Cc1E1d165CC4BAfe5') == EtherscanHasChainActivity.TRANSACTIONS  # noqa: E501
+    assert temp_etherscan.has_activity('0x725E35e01bbEDadd6ac13cE1c4a98bA4Cf00dF21') == EtherscanHasChainActivity.TRANSACTIONS  # noqa: E501
+    assert temp_etherscan.has_activity('0x3C69Bc9B9681683890ad82953Fe67d13Cd91D5EE') == EtherscanHasChainActivity.BALANCE  # noqa: E501
+    assert temp_etherscan.has_activity('0x014cd0535b2Ea668150a681524392B7633c8681c') == EtherscanHasChainActivity.TOKENS  # noqa: E501
+    assert temp_etherscan.has_activity('0x6c66149E65c517605e0a2e4F707550ca342f9c1B') == EtherscanHasChainActivity.NONE  # noqa: E501
diff --git a/rotkehlchen/tests/unit/test_trades.py b/rotkehlchen/tests/unit/test_trades.py
--- a/rotkehlchen/tests/unit/test_trades.py
+++ b/rotkehlchen/tests/unit/test_trades.py
@@ -158,7 +158,6 @@ def test_query_trade_history_with_exchange_instance_excluded(events_historian):
     Test that when an exchange is ignored and more instances of the same location exist
     we only ignore the correct instance and not all.
     """
-
     coinbase_instances = [create_test_coinbase(
         name=name,
         database=events_historian,