Repository: rotki/rotki

Issue:
Liquity: Missing movements for DSProxy Troves
## Liquity: Missing movements for DSProxy Troves

Trove operations show up fine for regular troves, but not for troves owned through a DSProxy (e.g. created on DeFiSaver)

![Screenshot_20220118_172422](https://user-images.githubusercontent.com/701095/149978896-e1b77634-121a-4f76-95cb-cc3b4e6cfcd2.png)

## Motivation

It feels incomplete and inconsistent.



Discussion:
This is probably a special case, requiring same approach we followed for makerdao vaults owned by a DSProxy: https://github.com/rotki/rotki/pull/2205

Resolving patch:
diff --git a/rotkehlchen/chain/ethereum/modules/liquity/graph.py b/rotkehlchen/chain/ethereum/modules/liquity/graph.py
--- a/rotkehlchen/chain/ethereum/modules/liquity/graph.py
+++ b/rotkehlchen/chain/ethereum/modules/liquity/graph.py
@@ -25,6 +25,7 @@
             collateralAfter
             collateralBefore
             collateralChange
+            sequenceNumber
             borrowingFee
             transaction{
                 id
diff --git a/rotkehlchen/chain/ethereum/modules/liquity/trove.py b/rotkehlchen/chain/ethereum/modules/liquity/trove.py
--- a/rotkehlchen/chain/ethereum/modules/liquity/trove.py
+++ b/rotkehlchen/chain/ethereum/modules/liquity/trove.py
@@ -477,8 +477,13 @@ def get_trove_history(
         from_timestamp: Timestamp,
         to_timestamp: Timestamp,
     ) -> Dict[ChecksumEthAddress, List[LiquityEvent]]:
+        addresses_to_query = list(addresses)
+        proxied_addresses = self._get_accounts_having_proxy()
+        proxies_to_address = {v: k for k, v in proxied_addresses.items()}
+        addresses_to_query += proxied_addresses.values()
+
         try:
-            query = self._get_raw_history(addresses, 'trove')
+            query = self._get_raw_history(addresses_to_query, 'trove')
         except RemoteError as e:
             log.error(f'Failed to query trove graph events for liquity. {str(e)}')
             query = {}
@@ -486,6 +491,8 @@ def get_trove_history(
         result: Dict[ChecksumEthAddress, List[LiquityEvent]] = defaultdict(list)
         for trove in query.get('troves', []):
             owner = to_checksum_address(trove['owner']['id'])
+            if owner in proxies_to_address:
+                owner = proxies_to_address[owner]
             for change in trove['changes']:
                 try:
                     timestamp = change['transaction']['timestamp']
@@ -558,7 +565,7 @@ def get_trove_history(
                             ),
                         ),
                         trove_operation=operation,
-                        sequence_number=str(change['transaction']['sequenceNumber']),
+                        sequence_number=str(change['sequenceNumber']),
                     )
                     result[owner].append(event)
                 except (DeserializationError, KeyError) as e:


Test patch:
diff --git a/rotkehlchen/tests/api/test_liquity.py b/rotkehlchen/tests/api/test_liquity.py
--- a/rotkehlchen/tests/api/test_liquity.py
+++ b/rotkehlchen/tests/api/test_liquity.py
@@ -24,6 +24,7 @@
             1627818194: FVal('3000'),
             1627818617: FVal('3000'),
             1627827057: FVal('3500'),
+            1641529258: FVal('3395'),
         },
     },
     A_LQTY: {
@@ -36,6 +37,7 @@
             1627818194: FVal('1.02'),
             1627818617: FVal('1.019'),
             1627827057: FVal('1.02'),
+            1641529258: FVal('1.0010'),
         },
     },
 }
@@ -88,7 +90,7 @@ def test_trove_staking(rotkehlchen_api_server, inquirer):  # pylint: disable=unu
     assert 'amount' in stake_data and float(stake_data['amount']) > 0
 
 
-@pytest.mark.parametrize('ethereum_accounts', [[LQTY_ADDR]])
+@pytest.mark.parametrize('ethereum_accounts', [[LQTY_ADDR, LQTY_PROXY]])
 @pytest.mark.parametrize('ethereum_modules', [['liquity']])
 @pytest.mark.parametrize('should_mock_current_price_queries', [False])
 @pytest.mark.parametrize('should_mock_price_queries', [True])
@@ -126,7 +128,37 @@ def test_trove_events(rotkehlchen_api_server):
     assert trove_action['trove_operation'] == 'Open Trove'
     assert trove_action['collateral_after']['amount'] == trove_action['collateral_delta']['amount']
     assert trove_action['collateral_delta']['amount'] == '3.5'
-    assert trove_action['sequence_number'] == '51647'
+    assert trove_action['sequence_number'] == '74148'
+
+    # Check for account with dsproxy
+    response = requests.get(
+        api_url_for(
+            rotkehlchen_api_server,
+            'liquitytroveshistoryresource',
+        ), json={
+            'async_query': async_query,
+            'from_timestamp': 1641529258,
+            'to_timestamp': 1641529258,
+            'reset_db_data': False,
+        },
+    )
+    if async_query:
+        task_id = assert_ok_async_response(response)
+        result = wait_for_async_task_with_result(rotkehlchen_api_server, task_id)
+    else:
+        result = assert_proper_response_with_result(response)
+    assert len(result[LQTY_PROXY]) == 1
+    trove_action = result[LQTY_PROXY][0]
+    tx_id = '0xef24b51a09151cce6728de1f9c3a0e69ca40db1dcc82f287a1743e41c90ce95b'
+    assert trove_action['tx'] == tx_id
+    assert trove_action['timestamp'] == 1641529258
+    assert trove_action['kind'] == 'trove'
+    assert trove_action['debt_after']['amount'] == '0'
+    assert trove_action['debt_delta']['amount'] == '-27436.074977906493051'
+    assert trove_action['trove_operation'] == 'Liquidation In Normal Mode'
+    assert trove_action['collateral_after']['amount'] == '0'
+    assert trove_action['collateral_delta']['amount'] == '-9.420492116554037728'
+    assert trove_action['sequence_number'] == '105764'
 
 
 @pytest.mark.parametrize('ethereum_accounts', [[LQTY_ADDR]])