def _check_vaults_values(vaults, owner): expected_vault = VAULT_8015.copy() expected_vault['owner'] = owner expected_vaults = [expected_vault] assert_serialized_lists_equal(expected_vaults, vaults, ignore_keys=VAULT_IGNORE_KEYS)
def _check_vault_details_values(details): expected_details = [VAULT_8015_DETAILS] assert_serialized_lists_equal( expected_details, details, # Checking only the first 7 events length_list_keymap={'events': 7}, )
def _query_borrowing_aave_history_test(setup: BalancesTestSetup, server: APIServer) -> None: with ExitStack() as stack: # patch ethereum/etherscan to not autodetect tokens setup.enter_ethereum_patches(stack) response = requests.get(api_url_for( server, "aavehistoryresource", )) result = assert_proper_response_with_result(response) assert len(result) == 1 assert len(result[AAVE_TEST_ACC_3]) == 4 events = result[AAVE_TEST_ACC_3]['events'] total_earned_interest = result[AAVE_TEST_ACC_3]['total_earned_interest'] total_lost = result[AAVE_TEST_ACC_3]['total_lost'] total_earned_liquidations = result[AAVE_TEST_ACC_3][ 'total_earned_liquidations'] assert len(total_earned_interest) >= 1 assert len(total_earned_interest[A_AWBTC_V1.identifier]) == 2 assert FVal(total_earned_interest[A_AWBTC_V1.identifier] ['amount']) >= FVal('0.00000833') assert FVal( total_earned_interest[A_AWBTC_V1.identifier]['usd_value']) >= ZERO assert len(total_earned_liquidations) == 1 assert len(total_earned_liquidations['ETH']) == 2 assert FVal(total_earned_liquidations['ETH']['amount']) >= FVal( '9.251070299427409111') assert FVal(total_earned_liquidations['ETH']['usd_value']) >= ZERO assert len(total_lost) == 3 eth_lost = total_lost['ETH'] assert len(eth_lost) == 2 assert FVal(eth_lost['amount']) >= FVal('0.004452186358507873') assert FVal(eth_lost['usd_value']) >= ZERO busd_lost = total_lost[A_BUSD.identifier] assert len(busd_lost) == 2 assert FVal(busd_lost['amount']) >= FVal('21.605824443625747553') assert FVal(busd_lost['usd_value']) >= ZERO wbtc_lost = total_lost[A_WBTC.identifier] assert len(wbtc_lost) == 2 assert FVal(wbtc_lost['amount']) >= FVal('0.41590034') # ouch assert FVal(wbtc_lost['usd_value']) >= ZERO expected_events = process_result_list( expected_aave_liquidation_test_events) assert_serialized_lists_equal( a=events[:len(expected_events)], b=expected_events, ignore_keys=None, )
def _check_vault_details_values(details, total_interest_owed_list: List[Optional[FVal]]): expected_details = [VAULT_8015_DETAILS] assert_serialized_lists_equal( expected_details, details, # Checking only the first 7 events length_list_keymap={'events': 7}, ignore_keys=['total_interest_owed'], ) for idx, entry in enumerate(total_interest_owed_list): if entry is not None: # We check if the total interest owed is bigger than the given one since # with a non-zero stability fee, interest always increases assert FVal(details[idx]['total_interest_owed']) >= entry
def _query_simple_aave_history_test( setup: BalancesTestSetup, server: APIServer, async_query: bool, use_graph: bool, ) -> None: with ExitStack() as stack: # patch ethereum/etherscan to not autodetect tokens setup.enter_ethereum_patches(stack) response = requests.get(api_url_for( server, "aavehistoryresource", ), json={'async_query': async_query}) if async_query: task_id = assert_ok_async_response(response) # Big timeout since this test can take a long time outcome = wait_for_async_task(server, task_id, timeout=600) assert outcome['message'] == '' result = outcome['result'] else: result = assert_proper_response_with_result(response) assert len(result) == 1 assert len(result[AAVE_TEST_ACC_2]) == 4 events = result[AAVE_TEST_ACC_2]['events'] total_earned_interest = result[AAVE_TEST_ACC_2]['total_earned_interest'] total_lost = result[AAVE_TEST_ACC_2]['total_lost'] total_earned_liquidations = result[AAVE_TEST_ACC_2][ 'total_earned_liquidations'] assert len(total_lost) == 0 assert len(total_earned_liquidations) == 0 assert len(total_earned_interest) == 1 assert len(total_earned_interest[A_ADAI_V1.identifier]) == 2 assert FVal(total_earned_interest[A_ADAI_V1.identifier]['amount']) >= FVal( '24.207179802347627414') # noqa: E501 assert FVal( total_earned_interest[A_ADAI_V1.identifier]['usd_value']) >= FVal( '24.580592532348742989192') # noqa: E501 expected_events = process_result_list(expected_aave_deposit_test_events) if use_graph: expected_events = expected_events[:7] + expected_events[8:] assert_serialized_lists_equal( a=events[:len(expected_events)], b=expected_events, ignore_keys=['log_index', 'block_number'] if use_graph else None, )
def _query_simple_aave_history_test_v2( setup: BalancesTestSetup, server: APIServer, async_query: bool, ) -> None: with ExitStack() as stack: # patch ethereum/etherscan to not autodetect tokens setup.enter_ethereum_patches(stack) response = requests.get(api_url_for( server, "aavehistoryresource", ), json={'async_query': async_query}) if async_query: task_id = assert_ok_async_response(response) # Big timeout since this test can take a long time outcome = wait_for_async_task(server, task_id, timeout=600) assert outcome['message'] == '' result = outcome['result'] else: result = assert_proper_response_with_result(response) assert len(result) == 1 assert len(result[AAVE_V2_TEST_ACC]) == 4 events = result[AAVE_V2_TEST_ACC]['events'] total_earned_interest = result[AAVE_V2_TEST_ACC]['total_earned_interest'] total_lost = result[AAVE_V2_TEST_ACC]['total_lost'] total_earned_liquidations = result[AAVE_V2_TEST_ACC][ 'total_earned_liquidations'] assert len(total_lost) == 1 assert len(total_earned_liquidations) == 0 assert len(total_earned_interest) == 1 assert len(total_earned_interest[ '_ceth_0xa06bC25B5805d5F8d82847D191Cb4Af5A3e873E0']) == 2 assert FVal(total_earned_interest[ '_ceth_0xa06bC25B5805d5F8d82847D191Cb4Af5A3e873E0']['amount']) >= FVal( '0.09') # noqa: E501 assert FVal(total_earned_interest[ '_ceth_0xa06bC25B5805d5F8d82847D191Cb4Af5A3e873E0'] ['usd_value']) >= FVal('0.09248') # noqa: E501 assert_serialized_lists_equal( a=events[:len(expected_aave_v2_events)], b=process_result_list(expected_aave_v2_events), ignore_keys=None, )
def test_query_historical_dsr_with_a_zero_withdrawal( rotkehlchen_api_server, ethereum_accounts, inquirer, # pylint: disable=unused-argument ): """Test DSR for an account that was opened while DSR is 0 and made a 0 DAI withdrawal Essentially reproduce DSR problem reported here: https://github.com/rotki/rotki/issues/1032 The account in question operates in a zero DSR environment but the reported problem seems to be just because he tried a zero DAI withdrawal """ rotki = rotkehlchen_api_server.rest_api.rotkehlchen original_get_logs = rotki.chain_manager.ethereum.get_logs proxies_mapping = { # proxy for 0x714696C5a872611F76655Bc163D0131cBAc60a70 ethereum_accounts[0]: '0xAe9996b76bdAa003ace6D66328A6942565f5768d', } mock_proxies(rotki, proxies_mapping, 'makerdao_dsr') # Query only until a block we know DSR is 0 and we know the number # of DSR events def mock_get_logs( contract_address, abi, event_name, argument_filters, from_block, to_block='latest', # pylint: disable=unused-argument ): return original_get_logs( contract_address, abi, event_name, argument_filters, from_block, to_block=10149816, # A block at which DSR is still zero ) patched_get_logs = patch.object( rotki.chain_manager.ethereum, 'get_logs', side_effect=mock_get_logs, ) with patched_get_logs: response = requests.get( api_url_for( rotkehlchen_api_server, "makerdaodsrhistoryresource", )) assert_proper_response(response) json_data = response.json() assert json_data['message'] == '' result = json_data['result'][ethereum_accounts[0]] assert result['gain_so_far'] == {'amount': '0', 'usd_value': '0'} movements = result['movements'] expected_movements = [{ 'movement_type': 'deposit', 'gain_so_far': { 'amount': ZERO, 'usd_value': ZERO, }, 'value': { 'amount': FVal('79'), 'usd_value': FVal('79'), }, 'block_number': 9953028, 'timestamp': 1587970286, 'tx_hash': '0x988aea85b54c5b2834b144e9f7628b524bf9faf3b87821aa520b7bcfb57ab289', }, { 'movement_type': 'withdrawal', 'gain_so_far': { 'amount': ZERO, 'usd_value': ZERO, }, 'value': { 'amount': FVal('79'), 'usd_value': FVal('79'), }, 'block_number': 9968906, 'timestamp': 1588182567, 'tx_hash': '0x2a1bee69b9bafe031026dbcc8f199881b568fd767482b5436dd1cd94f2642443', }, { 'movement_type': 'withdrawal', 'gain_so_far': { 'amount': ZERO, 'usd_value': ZERO, }, 'value': { 'amount': ZERO, 'usd_value': ZERO, }, 'block_number': 9968906, 'timestamp': 1588182567, 'tx_hash': '0x618fc9542890a2f58ab20a3c12d173b3638af11fda813e61788e242b4fc9a756', }] assert_serialized_lists_equal(movements, expected_movements, max_diff="1e-26") errors = rotki.msg_aggregator.consume_errors() assert len(errors) == 0
def test_query_vaults_usdc_strange(rotkehlchen_api_server, ethereum_accounts): """Strange case of a USDC vault that is not queried correctly https://oasis.app/borrow/7538?network=mainnet """ rotki = rotkehlchen_api_server.rest_api.rotkehlchen proxies_mapping = { ethereum_accounts[0]: '0x15fEaFd4358b8C03c889D6661b0CA1Be3389792F', # 7538 } mock_proxies(rotki, proxies_mapping, 'makerdao_vaults') response = requests.get( api_url_for( rotkehlchen_api_server, "makerdaovaultsresource", )) # That proxy has 3 vaults. We only want to test 7538, which is closed/repaid so just keep that vaults = [ x for x in assert_proper_response_with_result(response) if x['identifier'] == 7538 ] vault_7538 = MakerdaoVault( identifier=7538, owner=ethereum_accounts[0], collateral_type='USDC-A', urn='0x70E58566C7baB6faaFE03fbA69DF45Ef4f48223B', collateral_asset=A_USDC, collateral=Balance(ZERO, ZERO), debt=Balance(ZERO, ZERO), collateralization_ratio=None, liquidation_ratio=FVal(1.1), liquidation_price=None, ) expected_vaults = [vault_7538.serialize()] assert_serialized_lists_equal(expected_vaults, vaults) # And also make sure that the internal mapping will only query details of 7538 makerdao_vaults = rotki.chain_manager.get_module('makerdao_vaults') makerdao_vaults.vault_mappings = {ethereum_accounts[0]: [vault_7538]} response = requests.get( api_url_for( rotkehlchen_api_server, "makerdaovaultdetailsresource", )) vault_7538_details = { 'identifier': 7538, 'collateral_asset': 'USDC', 'creation_ts': 1585145754, 'total_interest_owed': '0.0005943266', 'total_liquidated': { 'amount': '0', 'usd_value': '0', }, 'events': [{ 'event_type': 'deposit', 'value': { 'amount': '250.12', 'usd_value': '250.12', }, 'timestamp': 1588664698, 'tx_hash': '0x9ba4a6187fa2c49ba327e7c923846a08a1e972017ec41d3f9f66ef524f7dde59', }, { 'event_type': 'generate', 'value': { 'amount': '25', 'usd_value': '25', }, 'timestamp': 1588664698, 'tx_hash': '0x9ba4a6187fa2c49ba327e7c923846a08a1e972017ec41d3f9f66ef524f7dde59', }, { 'event_type': 'payback', 'value': { 'amount': '25.000248996', 'usd_value': '25.000248996', }, 'timestamp': 1588696496, 'tx_hash': '0x8bd960e7eb8b9e2b81d2446d1844dd63f94636c7800ea5e3b4d926ea0244c66c', }, { 'event_type': 'deposit', 'value': { 'amount': '0.0113', 'usd_value': '0.0113', }, 'timestamp': 1588720248, 'tx_hash': '0x678c4da562173c102473f1904ff293a767ebac9ec6c7d728ef2fd41acf00a13a', }], } details = assert_proper_response_with_result(response) expected_details = [vault_7538_details] assert_serialized_lists_equal(expected_details, details)
def test_query_vaults_usdc(rotkehlchen_api_server, ethereum_accounts): """Check vault info and details for a vault with USDC as collateral""" rotki = rotkehlchen_api_server.rest_api.rotkehlchen proxies_mapping = { ethereum_accounts[0]: '0xBE79958661741079679aFf75DbEd713cE71a979d', # 7588 } mock_proxies(rotki, proxies_mapping, 'makerdao_vaults') response = requests.get( api_url_for( rotkehlchen_api_server, "makerdaovaultsresource", )) vaults = assert_proper_response_with_result(response) vault_7588 = MakerdaoVault( identifier=7588, owner=ethereum_accounts[0], collateral_type='USDC-A', urn='0x56D88244073B2fC17af5B1E6088936D5bAaDc37B', collateral_asset=A_USDC, collateral=Balance(ZERO, ZERO), debt=Balance(ZERO, ZERO), collateralization_ratio=None, liquidation_ratio=FVal('1.03'), liquidation_price=None, stability_fee=FVal('0.04'), ) expected_vaults = [vault_7588.serialize()] assert_serialized_lists_equal( expected_vaults, vaults, ignore_keys=['stability_fee', 'liquidation_ratio'], ) response = requests.get( api_url_for( rotkehlchen_api_server, "makerdaovaultdetailsresource", )) vault_7588_details = { 'identifier': 7588, 'collateral_asset': 'USDC', 'creation_ts': 1585286480, 'total_interest_owed': '0.00050636718', 'total_liquidated': { 'amount': '0', 'usd_value': '0', }, 'events': [{ 'event_type': 'deposit', 'value': { 'amount': '45', 'usd_value': '45', }, 'timestamp': 1585286480, 'tx_hash': '0x8b553dd0e8ee5385ec91105bf911143666d9df0ecd84c04f288278f7658aa7d6', }, { 'event_type': 'generate', 'value': { 'amount': '20', 'usd_value': '20.46', }, 'timestamp': 1585286480, 'tx_hash': '0x8b553dd0e8ee5385ec91105bf911143666d9df0ecd84c04f288278f7658aa7d6', }, { 'event_type': 'generate', 'value': { 'amount': '15.99', 'usd_value': '16.35777', }, 'timestamp': 1585286769, 'tx_hash': '0xdb861c893a51e4649ff3740cd3658cd4c9b1d048d3b8b4d117f4319bd60aee01', }, { 'event_type': 'payback', 'value': { 'amount': '35.990506367', 'usd_value': '36.818288', }, 'timestamp': 1585290263, 'tx_hash': '0xdd7825fe4a93c6f1ffa25a91b6da2396c229fe16b17242ad5c0bf7962928b2ec', }, { 'event_type': 'withdraw', 'value': { 'amount': '45', 'usd_value': '45', }, 'timestamp': 1585290300, 'tx_hash': '0x97462ebba7ce2467787bf6de25a25c24e538cf8a647919112c5f048b6a293408', }], } details = assert_proper_response_with_result(response) expected_details = [vault_7588_details] assert_serialized_lists_equal(expected_details, details, ignore_keys=['liquidation_ratio'])
def test_query_vaults_wbtc(rotkehlchen_api_server, ethereum_accounts): """Check vault info and details for a vault with WBTC as collateral""" rotki = rotkehlchen_api_server.rest_api.rotkehlchen proxies_mapping = { ethereum_accounts[0]: '0x9684e6C1c7B79868839b27F88bA6d5A176367075', # 8913 } mock_proxies(rotki, proxies_mapping, 'makerdao_vaults') response = requests.get( api_url_for( rotkehlchen_api_server, "makerdaovaultsresource", )) # That proxy has 3 vaults. We only want to test 8913, which is closed/repaid so just keep that vaults = [ x for x in assert_proper_response_with_result(response) if x['identifier'] == 8913 ] vault_8913 = MakerdaoVault( identifier=8913, owner=ethereum_accounts[0], collateral_type='WBTC-A', urn='0x37f7B3C82A9Edc13FdCcE66E7d500b3698A13294', collateral_asset=A_WBTC, collateral=Balance(ZERO, ZERO), debt=Balance(ZERO, ZERO), collateralization_ratio=None, liquidation_ratio=FVal(1.5), liquidation_price=None, stability_fee=FVal(0.02), ) expected_vaults = [vault_8913.serialize()] assert_serialized_lists_equal(expected_vaults, vaults, ignore_keys=['stability_fee']) # And also make sure that the internal mapping will only query details of 8913 makerdao_vaults = rotki.chain_manager.get_module('makerdao_vaults') makerdao_vaults.vault_mappings = {ethereum_accounts[0]: [vault_8913]} response = requests.get( api_url_for( rotkehlchen_api_server, "makerdaovaultdetailsresource", )) vault_8913_details = { 'identifier': 8913, 'collateral_asset': 'WBTC', 'creation_ts': 1588664698, 'total_interest_owed': '0.1903819198', 'total_liquidated': { 'amount': '0', 'usd_value': '0', }, 'events': [{ 'event_type': 'deposit', 'value': { 'amount': '0.011', 'usd_value': '87.06599', }, 'timestamp': 1588664698, 'tx_hash': '0x9ba4a6187fa2c49ba327e7c923846a08a1e972017ec41d3f9f66ef524f7dde59', }, { 'event_type': 'generate', 'value': { 'amount': '25', 'usd_value': '25.15', }, 'timestamp': 1588664698, 'tx_hash': '0x9ba4a6187fa2c49ba327e7c923846a08a1e972017ec41d3f9f66ef524f7dde59', }, { 'event_type': 'payback', 'value': { 'amount': '25.000248996', 'usd_value': '25.15025', }, 'timestamp': 1588696496, 'tx_hash': '0x8bd960e7eb8b9e2b81d2446d1844dd63f94636c7800ea5e3b4d926ea0244c66c', }, { 'event_type': 'deposit', 'value': { 'amount': '0.0113', 'usd_value': '89.440517', }, 'timestamp': 1588720248, 'tx_hash': '0x678c4da562173c102473f1904ff293a767ebac9ec6c7d728ef2fd41acf00a13a', }], # way too many events in the vault, so no need to check them all } details = assert_proper_response_with_result(response) assert len(details) == 1 assert_serialized_dicts_equal( details[0], vault_8913_details, # Checking only the first 4 events length_list_keymap={'events': 4}, )