Repository: rotki/rotki

Issue:
Aave APR is not showing
## Problem Definition

APR for aave deposits is not showing in the UI. The problem is that the data is not being properly categorized when reading from the zerion sdk contract.


### System Description

Operating system: All
Rotki version: 1.26.1



Discussion:

Resolving patch:
diff --git a/rotkehlchen/chain/ethereum/modules/aave/aave.py b/rotkehlchen/chain/ethereum/modules/aave/aave.py
--- a/rotkehlchen/chain/ethereum/modules/aave/aave.py
+++ b/rotkehlchen/chain/ethereum/modules/aave/aave.py
@@ -122,7 +122,7 @@ def _get_balances(
             for balance_entry in balance_entries:
                 # Aave also has "Aave • Staking" and "Aave • Uniswap Market" but
                 # here we are only querying the balances in the lending protocol
-                if balance_entry.protocol.name not in ('Aave', 'Aave V2'):
+                if balance_entry.protocol.name not in ('Aave', 'Aave V2', 'Aave V2 • Variable Debt', 'Aave V2 • Stable Debt'):  # noqa: E501
                     continue
 
                 # Depending on whether it's asset or debt we find what the reserve asset is


Test patch:
diff --git a/rotkehlchen/tests/api/test_aave.py b/rotkehlchen/tests/api/test_aave.py
--- a/rotkehlchen/tests/api/test_aave.py
+++ b/rotkehlchen/tests/api/test_aave.py
@@ -10,6 +10,11 @@
 
 from rotkehlchen.accounting.structures.balance import Balance
 from rotkehlchen.api.server import APIServer
+from rotkehlchen.chain.ethereum.defi.structures import (
+    DefiBalance,
+    DefiProtocol,
+    DefiProtocolBalances,
+)
 from rotkehlchen.chain.ethereum.modules.aave.structures import (
     AaveBorrowEvent,
     AaveDepositWithdrawalEvent,
@@ -17,6 +22,7 @@
     AaveLiquidationEvent,
     AaveRepayEvent,
 )
+from rotkehlchen.chain.ethereum.types import string_to_evm_address
 from rotkehlchen.constants.assets import A_BUSD, A_DAI, A_ETH, A_LINK, A_USDT, A_WBTC
 from rotkehlchen.constants.misc import ONE, ZERO
 from rotkehlchen.fval import FVal
@@ -880,3 +886,91 @@ def test_query_aave_history_non_premium(rotkehlchen_api_server, ethereum_account
         contained_in_msg='Currently logged in user testuser does not have a premium subscription',
         status_code=HTTPStatus.CONFLICT,
     )
+
+
+@pytest.mark.parametrize('ethereum_accounts', [['0x01471dB828Cfb96Dcf215c57a7a6493702031EC1']])
+@pytest.mark.parametrize('ethereum_modules', [['aave']])
+def test_query_aave_defi_borrowing(rotkehlchen_api_server, ethereum_accounts):
+    """Checks that the apr/apy values are correctyly returned from the API for a mocked status"""
+    rotki = rotkehlchen_api_server.rest_api.rotkehlchen
+    addrs = string_to_evm_address('0x01471dB828Cfb96Dcf215c57a7a6493702031EC1')
+    defi_balances = {
+        addrs: [
+            DefiProtocolBalances(
+                protocol=DefiProtocol(
+                    name='Aave V2 • Variable Debt',
+                    description='Decentralized lending & borrowing protocol',
+                    url='aave.com',
+                    version=4,
+                ),
+                balance_type='Debt',
+                base_balance=DefiBalance(
+                    token_address=string_to_evm_address('0xdAC17F958D2ee523a2206206994597C13D831ec7'),  # noqa: E501
+                    token_name='Tether USD',
+                    token_symbol='USDT',
+                    balance=Balance(
+                        amount=FVal(2697.800279),
+                        usd_value=FVal(4046.7004185),
+                    ),
+                ),
+                underlying_balances=[],
+            ),
+            DefiProtocolBalances(
+                protocol=DefiProtocol(
+                    name='Aave V2',
+                    description='Decentralized lending & borrowing protocol',
+                    url='aave.com',
+                    version=3,
+                ),
+                balance_type='Asset',
+                base_balance=DefiBalance(
+                    token_address=string_to_evm_address('0x9ff58f4fFB29fA2266Ab25e75e2A8b3503311656'),  # noqa: E501
+                    token_name='Aave interest bearing WBTC',
+                    token_symbol='aWBTC',
+                    balance=Balance(
+                        amount=FVal(0.59425326),
+                        usd_value=FVal(0.891379890),
+                    ),
+                ),
+                underlying_balances=[
+                    DefiBalance(
+                        token_address=string_to_evm_address('0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599'),  # noqa: E501
+                        token_name='Wrapped BTC',
+                        token_symbol='WBTC',
+                        balance=Balance(
+                            amount=FVal(0.59425326),
+                            usd_value=FVal(0.891379890),
+                        ),
+                    ),
+                ],
+            ),
+        ],
+    }
+
+    setup = setup_balances(
+        rotki,
+        ethereum_accounts=ethereum_accounts,
+        btc_accounts=None,
+        defi_balances=defi_balances,
+    )
+
+    response = None
+    with ExitStack() as stack:
+        setup.enter_ethereum_patches(stack)
+        response = requests.get(api_url_for(
+            rotkehlchen_api_server,
+            "aavebalancesresource",
+        ))
+
+    assert response is not None
+    result = assert_proper_response_with_result(response)
+    account_data = result[addrs]
+    assert len(account_data['lending']) == 1
+    assert len(account_data['borrowing']) == 1
+    variable_borrowing = account_data['borrowing']['eip155:1/erc20:0xdAC17F958D2ee523a2206206994597C13D831ec7']  # noqa: E501
+    assert variable_borrowing['variable_apr'] == '8.85%'
+    assert variable_borrowing['stable_apr'] == '16.85%'
+    assert variable_borrowing['balance']['amount'] == '2697.800279'
+    variable_borrowing = account_data['lending']['eip155:1/erc20:0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599']  # noqa: E501
+    assert variable_borrowing['apy'] == '0.12%'
+    assert variable_borrowing['balance']['amount'] == '0.59425326'
diff --git a/rotkehlchen/tests/utils/blockchain.py b/rotkehlchen/tests/utils/blockchain.py
--- a/rotkehlchen/tests/utils/blockchain.py
+++ b/rotkehlchen/tests/utils/blockchain.py
@@ -500,6 +500,26 @@ def mock_requests_get(url, *args, **kwargs):
 
                 result = '0x' + web3.codec.encode_abi(output_types, [args]).hex()
                 response = f'{{"jsonrpc":"2.0","id":1,"result":"{result}"}}'
+            elif 'https://api.etherscan.io/api?module=proxy&action=eth_call&to=0x7d2768dE32b0b80b7a3454c06BdAc94A69DDc7A9&data=0x35ea6a75000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7' in url:  # noqa: E501
+                # This is querying ethscan for the aave balances
+                if 'ethscan' in original_queries:
+                    return original_requests_get(url, *args, **kwargs)
+                response = '{"jsonrpc":"2.0","id":1,"result":"0x0000000000000000000000000000000000000000000000000000000000f370be0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000"}'  # noqa: E501
+            elif 'https://api.etherscan.io/api?module=proxy&action=eth_call&to=0x7d2768dE32b0b80b7a3454c06BdAc94A69DDc7A9&data=0x35ea6a750000000000000000000000002260fac5e5542a773aa44fbcfedf7c193bc2c599' in url:  # noqa: E501
+                # This is querying aave for the status of the pool
+                if 'ethscan' in original_queries:
+                    return original_requests_get(url, *args, **kwargs)
+                response = '{"jsonrpc":"2.0","id":1,"result":"0x0000000000000000000000000000000000000000000007d00d08290420081c200000000000000000000000000000000000000000033d6d8eaa28625ea2840ba4000000000000000000000000000000000000000003471d710caeed5ae821e50400000000000000000000000000000000000000000000f487b0cec3822e8c80a60000000000000000000000000000000000000000000aa1b430cd04910319afff000000000000000000000000000000000000000000261ae07f3c498e21e01bfe00000000000000000000000000000000000000000000000000000000636f9edb0000000000000000000000009ff58f4ffb29fa2266ab25e75e2a8b350331165600000000000000000000000051b039b9afe64b78758f8ef091211b5387ea717c0000000000000000000000009c39809dec7f95f5e0713634a4d0701329b3b4d2000000000000000000000000f41e8f817e6c399d1ade102059c454093b24f35b0000000000000000000000000000000000000000000000000000000000000001"}'  # noqa: E501
+            elif 'https://api.etherscan.io/api?module=proxy&action=eth_call&to=0x7d2768dE32b0b80b7a3454c06BdAc94A69DDc7A9&data=0x35ea6a75000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7' in url:  # noqa: E501
+                # This is querying aave for the status of the pool
+                if 'ethscan' in original_queries:
+                    return original_requests_get(url, *args, **kwargs)
+                response = '{"jsonrpc":"2.0","id":1,"result":"0x0000000000000000000000000000000000000000000003e80d060000000000000000000000000000000000000000000000000000038af6b55802f0e1cb76bbb2000000000000000000000000000000000000000003b458a890598cb1c935e9630000000000000000000000000000000000000000003f555421b1abbbff673b900000000000000000000000000000000000000000004949192d990ec458441edc0000000000000000000000000000000000000000008b75c1de391906a8441edc00000000000000000000000000000000000000000000000000000000636f9f470000000000000000000000003ed3b47dd13ec9a98b44e6204a523e766b225811000000000000000000000000e91d55ab2240594855abd11b3faae801fd4c4687000000000000000000000000531842cebbdd378f8ee36d171d6cc9c4fcf475ec000000000000000000000000515e87cb3fec986050f202a2bbfa362a2188bc3f0000000000000000000000000000000000000000000000000000000000000000"}'  # noqa: E501
+            elif 'https://api.etherscan.io/api?module=proxy&action=eth_call&to=0xeefBa1e63905eF1D7ACbA5a8513c70307C1cE441&data=0x252dba4200000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000086f25b64e1fe4c5162cdeed5245575d32ec549db00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000084e5da1b6800000000000000000000000001471db828cfb96dcf215c57a7a6493702031ec100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000255aa6df07540cb5d3d297f0d0d4d84cb52bc8e600000000000000000000000000000000000000000000000000000000' in url:  # noqa: E501
+                # This is querying ethscan for the aave balances
+                if 'ethscan' in original_queries:
+                    return original_requests_get(url, *args, **kwargs)
+                response = '{"jsonrpc":"2.0","id":1,"result":"0x0000000000000000000000000000000000000000000000000000000000f371750000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000"}'  # noqa: E501
             else:
                 raise AssertionError(f'Unexpected etherscan call during tests: {url}')