示例#1
0
def test_query_all_balances_async(
    rotkehlchen_api_server_with_exchanges,
    ethereum_accounts,
    btc_accounts,
):
    """Test that using the query all balances endpoint works with async call"""
    # Disable caching of query results
    rotki = rotkehlchen_api_server_with_exchanges.rest_api.rotkehlchen
    rotki.chain_manager.cache_ttl_secs = 0
    setup = setup_balances(rotki, ethereum_accounts, btc_accounts)

    # Test all balances request by requesting to not save the data
    with ExitStack() as stack:
        setup.enter_all_patches(stack)
        response = requests.get(
            api_url_for(
                rotkehlchen_api_server_with_exchanges,
                "allbalancesresource",
            ),
            json={'async_query': True},
        )
        task_id = assert_ok_async_response(response)
        outcome = wait_for_async_task(rotkehlchen_api_server_with_exchanges,
                                      task_id)

    assert_all_balances(
        data=outcome,
        db=rotki.data.db,
        expected_data_in_db=True,
        setup=setup,
    )
示例#2
0
def test_query_all_balances_with_manually_tracked_balances(
    rotkehlchen_api_server_with_exchanges,
    ethereum_accounts,
    btc_accounts,
    manually_tracked_balances,
):
    """Test that using the query all balances endpoint also includes manually tracked balances"""
    # Disable caching of query results
    rotki = rotkehlchen_api_server_with_exchanges.rest_api.rotkehlchen
    rotki.chain_manager.cache_ttl_secs = 0
    setup = setup_balances(
        rotki=rotki,
        ethereum_accounts=ethereum_accounts,
        btc_accounts=btc_accounts,
        manually_tracked_balances=manually_tracked_balances,
    )
    # now do the same but save the data in the DB and test it works
    # `save_data` is False by default but data will save since this is a fresh account
    with ExitStack() as stack:
        setup.enter_all_patches(stack)
        response = requests.get(
            api_url_for(
                rotkehlchen_api_server_with_exchanges,
                "allbalancesresource",
            ), )
    assert_proper_response(response)
    json_data = response.json()
    assert_all_balances(
        data=json_data,
        db=rotki.data.db,
        expected_data_in_db=True,
        setup=setup,
    )
示例#3
0
def test_query_owned_assets(
        rotkehlchen_api_server_with_exchanges,
        ethereum_accounts,
        btc_accounts,
        number_of_eth_accounts,
):
    """Test that using the query all owned assets endpoint works"""
    # Disable caching of query results
    rotki = rotkehlchen_api_server_with_exchanges.rest_api.rotkehlchen
    rotki.chain_manager.cache_ttl_secs = 0
    setup = setup_balances(rotki, ethereum_accounts, btc_accounts)

    # Get all our mocked balances and save them in the DB
    with setup.poloniex_patch, setup.binance_patch, setup.etherscan_patch, setup.bitcoin_patch:
        response = requests.get(
            api_url_for(
                rotkehlchen_api_server_with_exchanges,
                "allbalancesresource",
            ), json={'save_data': True},
        )
    assert_proper_response(response)

    # And now check that the query owned assets endpoint works
    with setup.poloniex_patch, setup.binance_patch, setup.etherscan_patch, setup.bitcoin_patch:
        response = requests.get(
            api_url_for(
                rotkehlchen_api_server_with_exchanges,
                "ownedassetsresource",
            ),
        )
    assert_proper_response(response)
    data = response.json()
    assert data['message'] == ''
    assert set(data['result']) == {'ETH', 'BTC', 'EUR', 'RDN'}
示例#4
0
def test_removing_ethereum_tokens_async(
        rotkehlchen_api_server,
        ethereum_accounts,
        number_of_eth_accounts,
):
    """Test that the rest api endpoint to add new ethereum tokens works properly"""
    rotki = rotkehlchen_api_server.rest_api.rotkehlchen
    setup = setup_balances(
        rotki,
        ethereum_accounts=ethereum_accounts,
        token_balances={
            'RDN': ['0', '0'],
            'DAI': ['50000000', '0'],
            'GNO': ['0', '0'],
        },
        btc_accounts=[],
    )

    # Remove GNO and RDN as tracked tokens and make sure that the dai balance checks out
    with setup.etherscan_patch, setup.alethio_patch:
        response = requests.delete(api_url_for(
            rotkehlchen_api_server,
            "ethereumtokensresource",
        ), json={'eth_tokens': ['GNO', 'RDN'], 'async_query': True})
        task_id = assert_ok_async_response(response)
        outcome = wait_for_async_task(rotkehlchen_api_server, task_id)
    assert_modifying_ethereum_tokens(
        rotkehlchen_api_server,
        outcome,
        ethereum_accounts,
        setup,
        ['DAI'],
    )
示例#5
0
def test_query_statistics_netvalue(
    rotkehlchen_api_server_with_exchanges,
    ethereum_accounts,
    btc_accounts,
):
    """Test that using the statistics netvalue over time endpoint works"""
    # Disable caching of query results
    rotki = rotkehlchen_api_server_with_exchanges.rest_api.rotkehlchen
    rotki.chain_manager.cache_ttl_secs = 0
    setup = setup_balances(rotki, ethereum_accounts, btc_accounts)

    # query balances and save data in DB to have data to test the statistics endpoint
    with ExitStack() as stack:
        setup.enter_all_patches(stack)
        response = requests.get(
            api_url_for(
                rotkehlchen_api_server_with_exchanges,
                "allbalancesresource",
            ),
            json={'save_data': True},
        )
    assert_proper_response(response)

    # and now test that statistics work fine
    response = requests.get(
        api_url_for(
            rotkehlchen_api_server_with_exchanges,
            "statisticsnetvalueresource",
        ), )

    result = assert_proper_response_with_result(response)
    assert len(result) == 2
    assert len(result['times']) == 1
    assert len(result['data']) == 1
示例#6
0
def test_get_sushiswap_trades_history(
        rotkehlchen_api_server,
        ethereum_accounts,  # pylint: disable=unused-argument
):
    """Test that the last 11/23 sushiswap trades of the account since 1605437542
    are parsed and returned correctly

    Also test that data are written in the DB and properly retrieved afterwards
    """
    async_query = random.choice([False, True])
    rotki = rotkehlchen_api_server.rest_api.rotkehlchen
    setup = setup_balances(
        rotki,
        ethereum_accounts=ethereum_accounts,
        eth_balances=['33000030003'],
        token_balances={},
        btc_accounts=None,
        original_queries=['zerion', 'logs', 'blocknobytime'],
    )
    _query_and_assert_simple_sushiswap_trades(setup, rotkehlchen_api_server, async_query)
    # make sure data are written in the DB
    db_trades = rotki.data.db.get_amm_swaps()
    assert len(db_trades) == 11
    # Query a 2nd time to make sure that when retrieving from the database everything works fine
    _query_and_assert_simple_sushiswap_trades(setup, rotkehlchen_api_server, async_query)
示例#7
0
def test_query_aave_history_with_borrowing(rotkehlchen_api_server,
                                           ethereum_accounts, aave_use_graph):  # pylint: disable=unused-argument  # noqa: E501
    """Check querying the aave histoy endpoint works. Uses real data."""
    rotki = rotkehlchen_api_server.rest_api.rotkehlchen
    setup = setup_balances(
        rotki,
        ethereum_accounts=ethereum_accounts,
        btc_accounts=None,
        original_queries=['zerion', 'logs', 'blocknobytime'],
    )
    _query_borrowing_aave_history_test(setup, rotkehlchen_api_server)
    # Run it 2 times to make sure that data can be queried properly from the DB
    _query_borrowing_aave_history_test(setup, rotkehlchen_api_server)

    # Make sure events end up in the DB
    assert len(rotki.data.db.get_aave_events(AAVE_TEST_ACC_3)) != 0
    # test aave data purging from the db works
    response = requests.delete(
        api_url_for(
            rotkehlchen_api_server,
            'namedethereummoduledataresource',
            module_name='aave',
        ))
    assert_simple_ok_response(response)
    assert len(rotki.data.db.get_aave_events(AAVE_TEST_ACC_3)) == 0
示例#8
0
def test_query_yearn_vault_history(rotkehlchen_api_server, ethereum_accounts):
    """Check querying the yearn vaults history endpoint works. Uses real data."""
    async_query = random.choice([True, False])
    rotki = rotkehlchen_api_server.rest_api.rotkehlchen
    setup = setup_balances(
        rotki,
        ethereum_accounts=ethereum_accounts,
        btc_accounts=None,
        original_queries=['zerion', 'logs', 'blocknobytime'],
    )

    for _ in range(2):
        # Run 2 times to make sure that loading data from DB the 2nd time works fine
        with ExitStack() as stack:
            # patch ethereum/etherscan to not autodetect tokens (not needed with infura)
            setup.enter_ethereum_patches(stack)
            response = requests.get(api_url_for(
                rotkehlchen_api_server,
                "yearnvaultshistoryresource",
            ),
                                    json={'async_query': async_query})
            if async_query:
                task_id = assert_ok_async_response(response)
                outcome = wait_for_async_task(rotkehlchen_api_server,
                                              task_id,
                                              timeout=600)
                assert outcome['message'] == ''
                result = outcome['result']
            else:
                result = assert_proper_response_with_result(response)

        # Make sure some data was saved in the DB after first call
        events = rotki.data.db.get_yearn_vaults_events(
            TEST_ACC1,
            YEARN_VAULTS['yyDAI+yUSDC+yUSDT+yTUSD'],
        )
        assert len(events) >= 11

        result = result[TEST_ACC1]
        check_vault_history('YALINK Vault', EXPECTED_HISTORY, result)
        check_vault_history('YCRV Vault', EXPECTED_HISTORY, result)
        check_vault_history('YSRENCURVE Vault', EXPECTED_HISTORY, result)
        check_vault_history('YUSDC Vault', EXPECTED_HISTORY, result)
        check_vault_history('YUSDT Vault', EXPECTED_HISTORY, result)
        check_vault_history('YYFI Vault', EXPECTED_HISTORY, result)

    # Make sure events end up in the DB
    # test yearn vault data purging from the db works
    response = requests.delete(
        api_url_for(
            rotkehlchen_api_server,
            'ethereummoduledataresource',
            module_name='yearn_vaults',
        ))
    assert_simple_ok_response(response)
    events = rotki.data.db.get_yearn_vaults_events(
        TEST_ACC1,
        YEARN_VAULTS['yyDAI+yUSDC+yUSDT+yTUSD'],
    )
    assert len(events) == 0
示例#9
0
def test_query_aave_balances_module_not_activated(
    rotkehlchen_api_server,
    ethereum_accounts,
):
    async_query = random.choice([False, True])
    rotki = rotkehlchen_api_server.rest_api.rotkehlchen
    setup = setup_balances(rotki,
                           ethereum_accounts=ethereum_accounts,
                           btc_accounts=None)

    with ExitStack() as stack:
        # patch ethereum/etherscan to not autodetect tokens
        setup.enter_ethereum_patches(stack)
        response = requests.get(api_url_for(
            rotkehlchen_api_server,
            "aavebalancesresource",
        ),
                                json={'async_query': async_query})

        if async_query:
            task_id = assert_ok_async_response(response)
            outcome = wait_for_async_task(rotkehlchen_api_server, task_id)
            assert outcome['result'] is None
            assert outcome['message'] == 'aave module is not activated'
        else:
            assert_error_response(
                response=response,
                contained_in_msg='aave module is not activated',
                status_code=HTTPStatus.CONFLICT,
            )
示例#10
0
def test_query_periodic(rotkehlchen_api_server_with_exchanges):
    rotki = rotkehlchen_api_server_with_exchanges.rest_api.rotkehlchen
    rotki.chain_manager.cache_ttl_secs = 0
    setup = setup_balances(rotki, ethereum_accounts=[], btc_accounts=[])
    start_ts = ts_now()

    # Query trades of an exchange to get them saved in the DB
    with setup.binance_patch, setup.poloniex_patch:
        response = requests.get(
            api_url_for(
                rotkehlchen_api_server_with_exchanges,
                "allbalancesresource",
            ),
            json={'save_data': True},
        )
    assert_proper_response(response)

    response = requests.get(
        api_url_for(rotkehlchen_api_server_with_exchanges,
                    "periodicdataresource"), )
    assert_proper_response(response)
    data = response.json()
    assert data['message'] == ''
    assert len(data['result']) == 3
    assert data['result']['last_balance_save'] >= start_ts
    assert data['result']['eth_node_connection'] is False
    # Non -1 value tests for these exist in test_history.py::test_query_history_timerange
    assert data['result']['last_data_upload_ts'] == 0
示例#11
0
def test_query_yearn_vault_balances(rotkehlchen_api_server, ethereum_accounts):
    async_query = random.choice([True, False])
    rotki = rotkehlchen_api_server.rest_api.rotkehlchen
    setup = setup_balances(
        rotki,
        ethereum_accounts=ethereum_accounts,
        btc_accounts=None,
        original_queries=['zerion'],
    )
    with ExitStack() as stack:
        # patch ethereum/etherscan to not autodetect tokens
        setup.enter_ethereum_patches(stack)
        response = requests.get(api_url_for(
            rotkehlchen_api_server,
            'yearnvaultsbalancesresource',
        ),
                                json={'async_query': async_query})
        if async_query:
            task_id = assert_ok_async_response(response)
            outcome = wait_for_async_task(rotkehlchen_api_server, task_id)
            assert outcome['message'] == ''
            result = outcome['result']
        else:
            result = assert_proper_response_with_result(response)

    for _, vault in result[TEST_ACC1].items():
        assert '%' in vault['roi']
        assert FVal(vault['vault_value']['amount']) > ZERO
        assert FVal(vault['vault_value']['usd_value']) > ZERO
        assert FVal(vault['underlying_value']['amount']) > ZERO
        assert FVal(vault['underlying_value']['usd_value']) > ZERO
示例#12
0
def test_get_trades_history(
        rotkehlchen_api_server,
        ethereum_accounts,  # pylint: disable=unused-argument
        rotki_premium_credentials,  # pylint: disable=unused-argument
        start_with_valid_premium,  # pylint: disable=unused-argument
):
    """Test get the trades history for premium users works as expected.

    This test will fetch the first 75 swaps, from 1606921757 to 1607015339.
    Then it will check the resulting trades from 1607008178 (swap 68) to
    1607015339 (swap 75). This particular time range has swaps with the timestamp.

    Swaps 68 to 75 (the endpoint returns them in desc order):
        1607008178 - Trade 1
        1607008178 - Trade 2
        1607008218 - Trade 3
        1607009877 - Trade 4
        1607010888 - Trade 5
        1607015059 - Trade 6
        1607015339 - Trade 7
        1607015339 - Trade 8
    """
    async_query = random.choice([False, True])
    rotki = rotkehlchen_api_server.rest_api.rotkehlchen
    setup = setup_balances(
        rotki,
        ethereum_accounts=ethereum_accounts,
        btc_accounts=None,
        original_queries=['zerion', 'logs', 'blocknobytime'],
    )
    with ExitStack() as stack:
        # patch ethereum/etherscan to not autodetect tokens
        setup.enter_ethereum_patches(stack)
        response = requests.get(
            api_url_for(rotkehlchen_api_server,
                        'balancertradeshistoryresource'),
            json={
                'async_query': async_query,
                'from_timestamp': 0,
                'to_timestamp': 1607015339,
            },
        )
        if async_query:
            task_id = assert_ok_async_response(response)
            outcome = wait_for_async_task(rotkehlchen_api_server, task_id)
            assert outcome['message'] == ''
            result = outcome['result']
        else:
            result = assert_proper_response_with_result(response)

    db_trades = rotki.data.db.get_amm_swaps()
    assert len(db_trades) == 75

    address_trades = result[BALANCER_TEST_ADDR2]
    assert len(address_trades) == 75

    expected_trades = get_balancer_test_addr2_expected_trades()[::-1]
    filtered_trades = address_trades[:len(expected_trades)]
    for trade, expected_trade in zip(filtered_trades, expected_trades):
        assert trade == expected_trade.serialize()
示例#13
0
def test_removing_ethereum_tokens(
    rotkehlchen_api_server,
    ethereum_accounts,
):
    """Test that the rest api endpoint to add new ethereum tokens works properly"""
    rotki = rotkehlchen_api_server.rest_api.rotkehlchen
    setup = setup_balances(
        rotki,
        ethereum_accounts=ethereum_accounts,
        token_balances={
            A_RDN: ['0', '0'],
            A_DAI: ['50000000', '0'],
            A_GNO: ['0', '0'],
        },
        btc_accounts=[],
    )

    # Remove GNO and RDN as tracked tokens and make sure that the dai balance checks out
    with setup.etherscan_patch, setup.alethio_patch:
        response = requests.delete(api_url_for(
            rotkehlchen_api_server,
            "ethereumtokensresource",
        ),
                                   json={'eth_tokens': ['GNO', 'RDN']})

    assert_proper_response(response)
    json_data = response.json()
    assert json_data['message'] == ''
    assert_modifying_ethereum_tokens(
        rotkehlchen_api_server,
        json_data,
        ethereum_accounts,
        setup,
        ['DAI'],
    )
示例#14
0
def test_query_eth2_info(rotkehlchen_api_server, ethereum_accounts):
    """This test uses real data and queries the eth2 deposit contract logs"""
    async_query = random.choice([False, True])
    rotki = rotkehlchen_api_server.rest_api.rotkehlchen
    setup = setup_balances(
        rotki,
        ethereum_accounts=ethereum_accounts,
        btc_accounts=[],
        original_queries=['logs', 'transactions', 'blocknobytime'],
    )
    with ExitStack() as stack:
        setup.enter_blockchain_patches(stack)
        response = requests.get(
            api_url_for(
                rotkehlchen_api_server,
                'eth2stakeresource',
            ),
            json={'async_query': async_query},
        )
        if async_query:
            task_id = assert_ok_async_response(response)
            outcome = wait_for_async_task(
                rotkehlchen_api_server,
                task_id,
                timeout=ASYNC_TASK_WAIT_TIMEOUT * 5,
            )
            assert outcome['message'] == ''
            result = outcome['result']
        else:
            result = assert_proper_response_with_result(response)

    assert result['deposits'][0] == {
        'from_address':
        '0xfeF0E7635281eF8E3B705e9C5B86e1d3B0eAb397',
        'log_index':
        22,
        'pubkey':
        '0xb016e31f633a21fbe42a015152399361184f1e2c0803d89823c224994af74a561c4ad8cfc94b18781d589d03e952cd5b',  # noqa: E501
        'timestamp':
        1604506685,
        'tx_hash':
        '0xd9eca1c2a0c5ff2f25071713432b21cc4d0ff2e8963edc63a48478e395e08db1',
        'validator_index':
        9,
        'value': {
            'amount': '32',
            'usd_value': '0'
        },
        'withdrawal_credentials':
        '0x004c7691c2085648f394ffaef851f3b1d51b95f7263114bc923fc5338f5fc499',  # noqa: E501
    }
    assert FVal(result['details'][0]['balance']['amount']) >= ZERO
    assert FVal(result['details'][0]['balance']['usd_value']) >= ZERO
    assert result['details'][0][
        'eth1_depositor'] == '0xfeF0E7635281eF8E3B705e9C5B86e1d3B0eAb397'  # noqa: E501
    assert result['details'][0]['index'] == 9
    for duration in ('1d', '1w', '1m', '1y'):
        performance = result['details'][0][f'performance_{duration}']
        assert FVal(performance['amount']) >= ZERO
        assert FVal(performance['usd_value']) >= ZERO
示例#15
0
def test_eth2_add_eth1_account(rotkehlchen_api_server):
    """This test uses real data and tests that adding an ETH1 address with
    ETH2 deposits properly detects validators"""
    new_account = '0xa966B0eabCD717fa28Bd165F1cE160E7057FA369'
    async_query = random.choice([False, True])
    rotki = rotkehlchen_api_server.rest_api.rotkehlchen
    setup = setup_balances(
        rotki,
        ethereum_accounts=[new_account],
        btc_accounts=[],
        original_queries=['logs', 'transactions', 'blocknobytime', 'beaconchain'],
    )
    with ExitStack() as stack:
        setup.enter_blockchain_patches(stack)
        data = {'accounts': [{'address': new_account}], 'async_query': async_query}
        response = requests.put(api_url_for(
            rotkehlchen_api_server,
            'blockchainsaccountsresource',
            blockchain='ETH',
        ), json=data)

        if async_query:
            task_id = assert_ok_async_response(response)
            result = wait_for_async_task_with_result(
                rotkehlchen_api_server,
                task_id,
                timeout=ASYNC_TASK_WAIT_TIMEOUT * 4,
            )
        else:
            result = assert_proper_response_with_result(response)

        # now get all detected validators
        response = requests.get(
            api_url_for(
                rotkehlchen_api_server,
                'eth2validatorsresource',
            ),
        )
        result = assert_proper_response_with_result(response)
        # That address has only 1 validator. If that changes in the future this
        # test will fail and we will need to adjust the test
        validator_pubkey = '0x800199f8f3af15a22c42ccd7185948870eceeba2d06199ea30e7e28eb976a69284e393ba2f401e8983d011534b303a57'  # noqa: E501
        assert len(result['entries']) == 1
        assert result['entries'][0] == {
            'validator_index': 227858,
            'public_key': validator_pubkey,
            'ownership_percentage': '100.00',
        }
        response = requests.get(api_url_for(
            rotkehlchen_api_server,
            'blockchainbalancesresource',
        ), json={'blockchain': 'eth2'})
        result = assert_proper_response_with_result(response)
        per_acc = result['per_account']
        assert FVal(per_acc['ETH'][new_account]['assets']['ETH']['amount']) > ZERO
        assert FVal(per_acc['ETH2'][validator_pubkey]['assets']['ETH2']['amount']) > FVal('32.54')
        totals = result['totals']['assets']
        assert FVal(totals['ETH']['amount']) > ZERO
        assert FVal(totals['ETH2']['amount']) > FVal('32.54')
示例#16
0
def test_get_trade_with_1_token_pool(
        rotkehlchen_api_server,
        ethereum_accounts,  # pylint: disable=unused-argument
        rotki_premium_credentials,  # pylint: disable=unused-argument
        start_with_valid_premium,  # pylint: disable=unused-argument
):
    """
    Test the special case of a swap within an 1 token pool.
    This can probably happen if the controller has since removed tokens from the pool.
    """
    rotki = rotkehlchen_api_server.rest_api.rotkehlchen
    setup = setup_balances(
        rotki,
        ethereum_accounts=ethereum_accounts,
        btc_accounts=None,
        original_queries=['zerion', 'logs', 'blocknobytime'],
    )
    with ExitStack() as stack:
        # patch ethereum/etherscan to not autodetect tokens
        setup.enter_ethereum_patches(stack)
        response = requests.get(
            api_url_for(rotkehlchen_api_server, 'balancertradeshistoryresource'),
            json={
                'from_timestamp': 1621358338,
                'to_timestamp': 1621358340,
            },
        )
        result = assert_proper_response_with_result(response)

    db_trades = rotki.data.db.get_amm_swaps()
    assert len(db_trades) == 29

    address_trades = result[BALANCER_TEST_ADDR4]
    assert len(address_trades) == 1
    assert address_trades[0] == AMMTrade(
        trade_type=TradeType.BUY,
        base_asset=A_WETH,
        quote_asset=A_WBTC,
        amount=AssetAmount(FVal('0.205421420618533148')),
        rate=Price(FVal('0.07606382992071615428519015532')),
        trade_index=0,
        swaps=[
            AMMSwap(
                tx_hash='0x4f9e0d8aa660a5d3db276a1ade038f7027f29838dd22d5276571d2e4ea7131ae',  # noqa: E501
                log_index=84,
                address=string_to_ethereum_address(BALANCER_TEST_ADDR4),  # noqa: E501
                from_address=string_to_ethereum_address('0xFD3dFB524B2dA40c8a6D703c62BE36b5D8540626'),  # noqa: E501
                to_address=string_to_ethereum_address('0x582818356331877553F3E9Cf9557b48e5DdbD54a'),  # noqa: E501
                timestamp=Timestamp(1621358339),
                location=Location.BALANCER,
                token0=A_WBTC,
                token1=A_WETH,
                amount0_in=AssetAmount(FVal('0.01562514')),
                amount1_in=AssetAmount(ZERO),
                amount0_out=AssetAmount(ZERO),
                amount1_out=AssetAmount(FVal('0.205421420618533148')),
            ),
        ],
    ).serialize()
示例#17
0
def test_query_yearn_vault_v2_history(rotkehlchen_api_server,
                                      ethereum_accounts):
    """Check querying the yearn vaults v2 history endpoint works. Uses real data."""

    async_query = random.choice([True, False])
    rotki = rotkehlchen_api_server.rest_api.rotkehlchen
    setup = setup_balances(
        rotki,
        ethereum_accounts=ethereum_accounts,
        btc_accounts=None,
        token_balances={
            '0x5f18C75AbDAe578b483E5F43f12a39cF75b973a9': ['70000000'],
            '0xB8C3B7A2A618C552C23B1E4701109a9E756Bab67':
            ['2550000000000000000000'],
        },
        original_queries=['blocknobytime'],
    )

    with ExitStack() as stack:
        # patch ethereum/etherscan to not autodetect tokens
        setup.enter_ethereum_patches(stack)
        response = requests.get(api_url_for(
            rotkehlchen_api_server,
            "yearnvaultsv2historyresource",
        ),
                                json={'async_query': async_query})
        if async_query:
            task_id = assert_ok_async_response(response)
            outcome = wait_for_async_task(rotkehlchen_api_server, task_id)
            assert outcome['message'] == ''
            result = outcome['result']
        else:
            result = assert_proper_response_with_result(response)

    # Make sure some data was saved in the DB after first call
    events = rotki.data.db.get_yearn_vaults_v2_events(TEST_V2_ACC2, 0,
                                                      12770065)
    assert len(events) >= 11

    result = result[TEST_V2_ACC2]
    check_vault_history(
        '_ceth_0x1C6a9783F812b3Af3aBbf7de64c3cD7CC7D1af44',
        EXPECTED_V2_HISTORY,
        result,
    )

    # Make sure events end up in the DB
    # test yearn vault data purging from the db works
    response = requests.delete(
        api_url_for(
            rotkehlchen_api_server,
            'ethereummoduledataresource',
            module_name='yearn_vaults_v2',
        ))
    assert_simple_ok_response(response)
    events = rotki.data.db.get_yearn_vaults_v2_events(TEST_V2_ACC2, 0,
                                                      12770065)
    assert len(events) == 0
示例#18
0
def test_balances_caching_mixup(
    rotkehlchen_api_server,
    ethereum_accounts,
):
    """Test that querying the balances in a specific order does not mix up the caches.

    This tests for the problem seen where the bitcoin balances being empty and
    queried first returned an empty result for the ethereum balances.
    """
    rotki = rotkehlchen_api_server.rest_api.rotkehlchen
    setup = setup_balances(
        rotki,
        ethereum_accounts=ethereum_accounts,
        btc_accounts=None,
        eth_balances=['1000000000000000000'],
        token_balances={A_RDN: ['2000000000000000000']},
        original_queries=['zerion'],
    )

    # Test all balances request by requesting to not save the data
    with ExitStack() as stack:
        setup.enter_blockchain_patches(stack)
        response_btc = requests.get(api_url_for(
            rotkehlchen_api_server,
            "named_blockchain_balances_resource",
            blockchain='BTC',
        ),
                                    json={'async_query': True})
        response_eth = requests.get(api_url_for(
            rotkehlchen_api_server,
            "named_blockchain_balances_resource",
            blockchain='ETH',
        ),
                                    json={'async_query': True})
        task_id_btc = assert_ok_async_response(response_btc)
        task_id_eth = assert_ok_async_response(response_eth)
        result_btc = wait_for_async_task_with_result(
            rotkehlchen_api_server,
            task_id_btc,
        )
        result_eth = wait_for_async_task_with_result(
            server=rotkehlchen_api_server,
            task_id=task_id_eth,
            timeout=ASYNC_TASK_WAIT_TIMEOUT * 2,
        )
        assert result_eth['per_account']['ETH'][ethereum_accounts[0]][
            'assets']['ETH']['amount'] == '1'  # noqa: E501
        assert result_eth['per_account']['ETH'][ethereum_accounts[0]][
            'assets'][A_RDN.identifier]['amount'] == '2'  # noqa: E501
        assert result_eth['totals']['assets']['ETH']['amount'] == '1'
        assert result_eth['totals']['assets'][
            A_RDN.identifier]['amount'] == '2'
        assert result_eth['per_account']['ETH'][ethereum_accounts[0]][
            'assets'][A_RDN.identifier]['amount'] == '2'  # noqa: E501
        assert result_btc['per_account'] == {}
        assert result_btc['totals']['assets'] == {}
        assert result_btc['totals']['liabilities'] == {}
示例#19
0
def test_query_aave_history_with_borrowing_v2(rotkehlchen_api_server, ethereum_accounts):  # pylint: disable=unused-argument  # noqa: E501
    """Check querying the aave histoy endpoint works. Uses real data."""
    rotki = rotkehlchen_api_server.rest_api.rotkehlchen
    setup = setup_balances(
        rotki,
        ethereum_accounts=ethereum_accounts,
        btc_accounts=None,
        original_queries=['zerion', 'logs', 'blocknobytime'],
    )
    _query_simple_aave_history_test_v2(setup, rotkehlchen_api_server, False)
示例#20
0
def test_query_compound_balances(rotkehlchen_api_server, ethereum_accounts):
    """Check querying the compound balances endpoint works. Uses real data.

    TODO: Here we should use a test account for which we will know what balances
    it has and we never modify
    """
    async_query = random.choice([False, True])
    rotki = rotkehlchen_api_server.rest_api.rotkehlchen
    setup = setup_balances(
        rotki,
        ethereum_accounts=ethereum_accounts,
        btc_accounts=None,
        original_queries=['zerion'],
    )
    with ExitStack() as stack:
        # patch ethereum/etherscan to not autodetect tokens
        setup.enter_ethereum_patches(stack)
        response = requests.get(api_url_for(
            rotkehlchen_api_server,
            "compoundbalancesresource",
        ),
                                json={'async_query': async_query})
        if async_query:
            task_id = assert_ok_async_response(response)
            outcome = wait_for_async_task(rotkehlchen_api_server,
                                          task_id,
                                          timeout=60)
            assert outcome['message'] == ''
            result = outcome['result']
        else:
            result = assert_proper_response_with_result(response)

    if len(result) != 1:
        test_warnings.warn(
            UserWarning(f'Test account {TEST_ACC1} has no compound balances'))
        return

    lending = result[TEST_ACC1]['lending']
    for _, entry in lending.items():
        assert len(entry) == 2
        assert len(entry['balance']) == 2
        assert 'amount' in entry['balance']
        assert 'usd_value' in entry['balance']
        assert '%' in entry['apy']
    borrowing = result[TEST_ACC1]['borrowing']
    for _, entry in borrowing.items():
        assert len(entry) == 2
        assert len(entry['balance']) == 2
        assert 'amount' in entry['balance']
        assert 'usd_value' in entry['balance']
        assert '%' in entry['apy']
    rewards = result[TEST_ACC1]['rewards']
    if len(rewards) != 0:
        assert len(rewards) == 1
        assert A_COMP.identifier in rewards
示例#21
0
def test_get_balances(
        rotkehlchen_api_server,
        ethereum_accounts,  # pylint: disable=unused-argument
        rotki_premium_credentials,  # pylint: disable=unused-argument
        start_with_valid_premium,  # pylint: disable=unused-argument
):
    """Test get the balances for premium users works as expected"""
    async_query = random.choice([False, True])
    rotki = rotkehlchen_api_server.rest_api.rotkehlchen
    setup = setup_balances(
        rotki,
        ethereum_accounts=ethereum_accounts,
        btc_accounts=None,
        original_queries=['zerion', 'logs', 'blocknobytime'],
    )
    with ExitStack() as stack:
        # patch ethereum/etherscan to not autodetect tokens
        setup.enter_ethereum_patches(stack)
        response = requests.get(
            api_url_for(rotkehlchen_api_server, 'balancerbalancesresource'),
            json={'async_query': async_query},
        )
        if async_query:
            task_id = assert_ok_async_response(response)
            outcome = wait_for_async_task(rotkehlchen_api_server, task_id)
            assert outcome['message'] == ''
            result = outcome['result']
        else:
            result = assert_proper_response_with_result(response)

    if len(result) != 1:
        test_warnings.warn(
            UserWarning(f'Test account {BALANCER_TEST_ADDR1} has no balances'),
        )
        return

    for pool_share in result[BALANCER_TEST_ADDR1]:
        assert pool_share['address'] is not None
        assert FVal(pool_share['total_amount']) >= ZERO
        assert FVal(pool_share['user_balance']['amount']) >= ZERO
        assert FVal(pool_share['user_balance']['usd_value']) >= ZERO

        for pool_token in pool_share['tokens']:
            assert pool_token['token'] is not None
            # UnknownEthereumToken
            if isinstance(pool_token['token'], dict):
                assert pool_token['token']['ethereum_address'] is not None
                assert pool_token['token']['name'] is not None
                assert pool_token['token']['symbol'] is not None

            assert pool_token['total_amount'] is not None
            assert FVal(pool_token['user_balance']['amount']) >= ZERO
            assert FVal(pool_token['user_balance']['usd_value']) >= ZERO
            assert FVal(pool_token['usd_price']) >= ZERO
            assert FVal(pool_token['weight']) >= ZERO
示例#22
0
def test_get_events_history_get_all_events(
        rotkehlchen_api_server,
        ethereum_accounts,  # pylint: disable=unused-argument
        rotki_premium_credentials,  # pylint: disable=unused-argument
        start_with_valid_premium,  # pylint: disable=unused-argument
):
    """Test get all the events balances

    LPs involved by the address: minimum 6

    By calling the endpoint without a specific time range:
      - All the events are queried.
      - The events balances factorise in the current balances in the
      protocol (do not assert amounts).

    As the structures are already tested in the tests above, only the response
    length is tested.
    """
    async_query = random.choice([False, True])
    rotki = rotkehlchen_api_server.rest_api.rotkehlchen

    # Set module premium is required for calling `get_balances()`
    premium = None
    if start_with_valid_premium:
        premium = Premium(rotki_premium_credentials)

    rotki.chain_manager.uniswap.premium = premium

    setup = setup_balances(
        rotki,
        ethereum_accounts=ethereum_accounts,
        eth_balances=['33000030003'],
        token_balances={},
        btc_accounts=None,
        original_queries=['zerion', 'logs', 'blocknobytime'],
    )
    with ExitStack() as stack:
        # patch ethereum/etherscan to not autodetect tokens
        setup.enter_ethereum_patches(stack)
        response = requests.get(api_url_for(
            rotkehlchen_api_server, 'uniswapeventshistoryresource'),
            json={'async_query': async_query},
        )
        if async_query:
            task_id = assert_ok_async_response(response)
            outcome = wait_for_async_task(rotkehlchen_api_server, task_id, timeout=120)
            assert outcome['message'] == ''
            result = outcome['result']
        else:
            result = assert_proper_response_with_result(response)

    events_balances = result[AAVE_TEST_ACC_1]

    assert len(events_balances) >= 6
示例#23
0
def test_get_balances_premium(
        rotkehlchen_api_server,
        ethereum_accounts,  # pylint: disable=unused-argument
        rotki_premium_credentials,  # pylint: disable=unused-argument
        start_with_valid_premium,  # pylint: disable=unused-argument
):
    """Test get balances for premium users works as expected
    """
    async_query = random.choice([False, True])
    rotki = rotkehlchen_api_server.rest_api.rotkehlchen

    # Set module premium is required for calling `get_balances()`
    premium = None
    if start_with_valid_premium:
        premium = Premium(rotki_premium_credentials)

    rotki.chain_manager.adex.premium = premium

    setup = setup_balances(
        rotki,
        ethereum_accounts=ethereum_accounts,
        btc_accounts=None,
        original_queries=['zerion', 'logs', 'blocknobytime'],
    )
    with ExitStack() as stack:
        # patch ethereum/etherscan to not autodetect tokens
        setup.enter_ethereum_patches(stack)
        response = requests.get(api_url_for(
            rotkehlchen_api_server, 'adexbalancesresource'),
            json={'async_query': async_query},
        )
        if async_query:
            task_id = assert_ok_async_response(response)
            outcome = wait_for_async_task(rotkehlchen_api_server, task_id)
            assert outcome['message'] == ''
            result = outcome['result']
        else:
            result = assert_proper_response_with_result(response)

    if len(result) != 1:
        test_warnings.warn(
            UserWarning(f'Test account {ADEX_TEST_ADDR} has no balances'),
        )
        return

    for staking_balance in result[ADEX_TEST_ADDR]:
        assert staking_balance['pool_id'] is not None
        assert 'pool_name' in staking_balance
        assert staking_balance['contract_address'] is not None
        assert staking_balance['adx_balance']['amount']
        assert staking_balance['adx_balance']['usd_value']
        assert staking_balance['dai_unclaimed_balance']['amount']
        assert staking_balance['dai_unclaimed_balance']['usd_value']
示例#24
0
def test_query_aave_history_no_duplicates(rotkehlchen_api_server, ethereum_accounts):  # pylint: disable=unused-argument  # noqa: E501
    """Check querying the aave histoy avoids duplicate event data and keeps totals positive"""
    rotki = rotkehlchen_api_server.rest_api.rotkehlchen
    setup = setup_balances(
        rotki,
        ethereum_accounts=ethereum_accounts,
        btc_accounts=None,
        original_queries=['zerion', 'logs', 'blocknobytime'],
    )

    _test_for_duplicates_and_negatives(setup, rotkehlchen_api_server)
    # Test that we still don't get duplicates at the 2nd query which hits the DB
    _test_for_duplicates_and_negatives(setup, rotkehlchen_api_server)
示例#25
0
def test_query_aave_history_with_borrowing(rotkehlchen_api_server,
                                           ethereum_accounts, aave_use_graph):  # pylint: disable=unused-argument  # noqa: E501
    """Check querying the aave histoy endpoint works. Uses real data."""
    rotki = rotkehlchen_api_server.rest_api.rotkehlchen
    setup = setup_balances(
        rotki,
        ethereum_accounts=ethereum_accounts,
        btc_accounts=None,
        original_queries=['zerion', 'logs', 'blocknobytime'],
    )
    _query_borrowing_aave_history_test(setup, rotkehlchen_api_server)
    # Run it 2 times to make sure that data can be queried properly from the DB
    _query_borrowing_aave_history_test(setup, rotkehlchen_api_server)
示例#26
0
def test_query_all_balances(
        rotkehlchen_api_server_with_exchanges,
        ethereum_accounts,
        btc_accounts,
        number_of_eth_accounts,
):
    """Test that using the query all balances endpoint works

    Test that balances from various sources are returned. Such as exchanges,
    blockchain and FIAT"""
    # Disable caching of query results
    rotki = rotkehlchen_api_server_with_exchanges.rest_api.rotkehlchen
    rotki.chain_manager.cache_ttl_secs = 0
    setup = setup_balances(rotki, ethereum_accounts, btc_accounts)
    # Test all balances request by requesting to not save the data
    with ExitStack() as stack:
        setup.enter_all_patches(stack)
        response = requests.get(
            api_url_for(
                rotkehlchen_api_server_with_exchanges,
                "allbalancesresource",
            ), json={'save_data': False},
        )

    assert_proper_response(response)
    json_data = response.json()
    assert_all_balances(
        data=json_data,
        db=rotki.data.db,
        expected_data_in_db=False,
        setup=setup,
    )

    # now do the same but save the data in the DB and test it works
    # Omit the argument to test that default value of save_data is True
    with ExitStack() as stack:
        setup.enter_all_patches(stack)
        response = requests.get(
            api_url_for(
                rotkehlchen_api_server_with_exchanges,
                "allbalancesresource",
            ),
        )
    assert_proper_response(response)
    json_data = response.json()
    assert_all_balances(
        data=json_data,
        db=rotki.data.db,
        expected_data_in_db=True,
        setup=setup,
    )
示例#27
0
def test_query_aave_balances(rotkehlchen_api_server, ethereum_accounts,
                             async_query):
    """Check querying the aave balances endpoint works. Uses real data.

    TODO: Here we should use a test account for which we will know what balances
    it has and we never modify
    """
    rotki = rotkehlchen_api_server.rest_api.rotkehlchen
    setup = setup_balances(
        rotki,
        ethereum_accounts=ethereum_accounts,
        btc_accounts=None,
        original_queries=['zerion'],
    )
    with ExitStack() as stack:
        # patch ethereum/etherscan to not autodetect tokens
        setup.enter_ethereum_patches(stack)
        response = requests.get(api_url_for(
            rotkehlchen_api_server,
            "aavebalancesresource",
        ),
                                json={'async_query': async_query})
        if async_query:
            task_id = assert_ok_async_response(response)
            outcome = wait_for_async_task(rotkehlchen_api_server, task_id)
            assert outcome['message'] == ''
            result = outcome['result']
        else:
            result = assert_proper_response_with_result(response)

    if len(result) != 1:
        test_warnings.warn(
            UserWarning(
                f'Test account {AAVE_TEST_ACC_1} has no aave balances'))
        return

    lending = result[AAVE_TEST_ACC_1]['lending']
    for _, entry in lending.items():
        assert len(entry) == 2
        assert len(entry['balance']) == 2
        assert 'amount' in entry['balance']
        assert 'usd_value' in entry['balance']
        assert '%' in entry['apy']
    borrowing = result[AAVE_TEST_ACC_1]['borrowing']
    for _, entry in borrowing.items():
        assert len(entry) == 3
        assert len(entry['balance']) == 2
        assert 'amount' in entry['balance']
        assert 'usd_value' in entry['balance']
        assert '%' in entry['variable_apr']
        assert '%' in entry['stable_apr']
示例#28
0
def test_get_events_history_2(
        rotkehlchen_api_server,
        ethereum_accounts,  # pylint: disable=unused-argument
        rotki_premium_credentials,  # pylint: disable=unused-argument
        start_with_valid_premium,  # pylint: disable=unused-argument
):
    """Test POOL2 (BAT-LINK-LEND-MKR-SNX-WETH-KNC) events balance for ADDR3"""
    async_query = random.choice([False, True])
    rotki = rotkehlchen_api_server.rest_api.rotkehlchen
    setup = setup_balances(
        rotki,
        ethereum_accounts=ethereum_accounts,
        btc_accounts=None,
        original_queries=['zerion', 'logs', 'blocknobytime'],
    )
    with ExitStack() as stack:
        # patch ethereum/etherscan to not autodetect tokens
        setup.enter_ethereum_patches(stack)
        response = requests.get(
            api_url_for(rotkehlchen_api_server,
                        'balancereventshistoryresource'),
            json={
                'async_query': async_query,
                'from_timestamp': 1598376244,
                'to_timestamp': 1598377474,
            },
        )
        if async_query:
            task_id = assert_ok_async_response(response)
            outcome = wait_for_async_task(rotkehlchen_api_server, task_id)
            assert outcome['message'] == ''
            result = outcome['result']
        else:
            result = assert_proper_response_with_result(response)

    address_pool_events_balances = result[BALANCER_TEST_ADDR3]

    assert len(address_pool_events_balances) == 2
    pool_event_balances = [
        pool_events_balance
        for pool_events_balance in address_pool_events_balances
        if pool_events_balance['pool_address'] ==
        BALANCER_TEST_ADDR3_POOL2.ethereum_address
    ]

    assert len(pool_event_balances) == 1
    pool_events_balance = pool_event_balances[0]

    assert pool_events_balance == BALANCER_TEST_ADDR3_EXPECTED_HISTORY_POOL2.serialize(
    )
示例#29
0
def test_query_avax_balances(rotkehlchen_api_server):
    """Test query the AVAX balances when multiple accounts are set up works as
    expected.
    """
    async_query = random.choice([False, True])
    setup = setup_balances(
        rotki=rotkehlchen_api_server.rest_api.rotkehlchen,
        ethereum_accounts=None,
        btc_accounts=None,
        eth_balances=None,
        token_balances=None,
        btc_balances=None,
    )
    with ExitStack() as stack:
        setup.enter_blockchain_patches(stack)
        response = requests.get(
            api_url_for(
                rotkehlchen_api_server,
                'named_blockchain_balances_resource',
                blockchain=SupportedBlockchain.AVALANCHE.value,
            ),
            json={'async_query': async_query},
        )
        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)

    # Check per account
    account_1_balances = result['per_account']['AVAX'][
        AVALANCHE_ACC1_AVAX_ADDR]
    assert 'liabilities' in account_1_balances
    asset_avax = account_1_balances['assets']['AVAX']
    assert FVal(asset_avax['amount']) >= ZERO
    assert FVal(asset_avax['usd_value']) >= ZERO

    account_2_balances = result['per_account']['AVAX'][
        AVALANCHE_ACC2_AVAX_ADDR]
    assert 'liabilities' in account_2_balances
    asset_avax = account_2_balances['assets']['AVAX']
    assert FVal(asset_avax['amount']) >= ZERO
    assert FVal(asset_avax['usd_value']) >= ZERO

    # Check totals
    assert 'liabilities' in result['totals']
    total_avax = result['totals']['assets']['AVAX']
    assert FVal(total_avax['amount']) >= ZERO
    assert FVal(total_avax['usd_value']) >= ZERO
示例#30
0
def test_get_balances_premium(
        rotkehlchen_api_server,
        ethereum_accounts,  # pylint: disable=unused-argument
        rotki_premium_credentials,  # pylint: disable=unused-argument
        start_with_valid_premium,  # pylint: disable=unused-argument
):
    """Test get balances for premium users works as expected
    """
    async_query = random.choice([False, True])
    rotki = rotkehlchen_api_server.rest_api.rotkehlchen

    # Set module premium is required for calling `get_balances()`
    premium = None
    if start_with_valid_premium:
        premium = Premium(rotki_premium_credentials)

    adex = rotki.chain_manager.get_module('adex')
    adex.premium = premium

    setup = setup_balances(
        rotki,
        ethereum_accounts=ethereum_accounts,
        btc_accounts=None,
        # original_queries=['adex_staking'],
        extra_flags=['mocked_adex_staking_balance'],
    )
    with ExitStack() as stack:
        # patch ethereum/etherscan to not autodetect tokens
        setup.enter_ethereum_patches(stack)
        response = requests.get(
            api_url_for(rotkehlchen_api_server, 'adexbalancesresource'),
            json={'async_query': async_query},
        )
        if async_query:
            task_id = assert_ok_async_response(response)
            outcome = wait_for_async_task(rotkehlchen_api_server, task_id)
            assert outcome['message'] == ''
            result = outcome['result']
        else:
            result = assert_proper_response_with_result(response)

    if len(result) != 1:
        test_warnings.warn(
            UserWarning(f'Test account {ADEX_TEST_ADDR} has no balances'), )
        return

    assert FVal(result[ADEX_TEST_ADDR][0]['adx_balance']['amount']) == FVal(
        '113547.9817118382760270384899')  # noqa: E501
    assert result[ADEX_TEST_ADDR][0]['adx_balance']['usd_value'] is not None