Beispiel #1
0
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)
Beispiel #2
0
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},
    )
Beispiel #3
0
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,
    )
Beispiel #4
0
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
Beispiel #5
0
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,
    )
Beispiel #6
0
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,
    )
Beispiel #7
0
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
Beispiel #8
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)
Beispiel #9
0
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'])
Beispiel #10
0
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},
    )