Repository: rotki/rotki

Issue:
Exchange Binance US imported but dispalyed as Binance on Deposits & Withdwawals page
Imported `Binnace US` exchange but it displays as `Binance`. App version 1.16.1
<img width="317" alt="Screen Shot 2021-05-04 at 5 26 34 PM" src="https://user-images.githubusercontent.com/15807643/117085295-e5cb1e80-ad38-11eb-870a-b5f708b05f5a.png">


<img width="452" alt="Screen Shot 2021-05-04 at 5 26 22 PM" src="https://user-images.githubusercontent.com/15807643/117085331-f8ddee80-ad38-11eb-8700-8589b67e1805.png">



Discussion:
Hey @CruiseMan thank you for opening the issue. I think I can see why this is happening.

We will fix this!

Resolving patch:
diff --git a/rotkehlchen/exchanges/binance.py b/rotkehlchen/exchanges/binance.py
--- a/rotkehlchen/exchanges/binance.py
+++ b/rotkehlchen/exchanges/binance.py
@@ -168,9 +168,10 @@ def trade_from_binance(
         fee=fee,
     )
 
+    location = Location.BINANCE if name == str(Location.BINANCE) else Location.BINANCE_US  # noqa: E501
     return Trade(
         timestamp=timestamp,
-        location=Location.BINANCE,
+        location=location,
         base_asset=base_asset,
         quote_asset=quote_asset,
         trade_type=order_type,
@@ -920,8 +921,9 @@ def _deserialize_asset_movement(self, raw_data: Dict[str, Any]) -> Optional[Asse
 
             timestamp = deserialize_timestamp_from_binance(raw_data[time_key])
             asset = asset_from_binance(raw_data['asset'])
+            location = Location.BINANCE if self.name == str(Location.BINANCE) else Location.BINANCE_US  # noqa: E501
             return AssetMovement(
-                location=Location.BINANCE,
+                location=location,
                 category=category,
                 address=deserialize_asset_movement_address(raw_data, 'address', asset),
                 transaction_id=get_key_if_has_val(raw_data, 'txId'),


Test patch:
diff --git a/rotkehlchen/tests/exchanges/test_binance.py b/rotkehlchen/tests/exchanges/test_binance.py
--- a/rotkehlchen/tests/exchanges/test_binance.py
+++ b/rotkehlchen/tests/exchanges/test_binance.py
@@ -11,7 +11,6 @@
 from rotkehlchen.assets.asset import Asset
 from rotkehlchen.assets.converters import UNSUPPORTED_BINANCE_ASSETS, asset_from_binance
 from rotkehlchen.constants.assets import A_BNB, A_BTC, A_ETH, A_USDT, A_WBTC
-from rotkehlchen.constants.misc import ZERO
 from rotkehlchen.errors import RemoteError, UnknownAsset, UnsupportedAsset
 from rotkehlchen.exchanges.binance import (
     API_TIME_INTERVAL_CONSTRAINT_TS,
@@ -22,14 +21,17 @@
 )
 from rotkehlchen.exchanges.data_structures import Location, Trade, TradeType
 from rotkehlchen.fval import FVal
-from rotkehlchen.tests.utils.constants import A_ADA, A_BUSD, A_DOT, A_RDN, A_XMR
+from rotkehlchen.tests.utils.constants import A_ADA, A_BUSD, A_DOT, A_RDN
 from rotkehlchen.tests.utils.exchanges import (
+    BINANCE_DEPOSITS_HISTORY_RESPONSE,
     BINANCE_MYTRADES_RESPONSE,
+    BINANCE_WITHDRAWALS_HISTORY_RESPONSE,
+    assert_binance_asset_movements_result,
     mock_binance_balance_response,
 )
 from rotkehlchen.tests.utils.factories import make_api_key, make_api_secret
 from rotkehlchen.tests.utils.mock import MockResponse
-from rotkehlchen.typing import AssetMovementCategory, Timestamp
+from rotkehlchen.typing import Timestamp
 from rotkehlchen.user_messages import MessagesAggregator
 from rotkehlchen.utils.misc import ts_now_in_ms
 
@@ -355,55 +357,6 @@ def query_binance_and_test(
     )
 
 
-BINANCE_DEPOSITS_HISTORY_RESPONSE = """{
-    "depositList": [
-        {
-            "insertTime": 1508198532000,
-            "amount": 0.04670582,
-            "asset": "ETH",
-            "address": "0x6915f16f8791d0a1cc2bf47c13a6b2a92000504b",
-            "txId": "0xef33b22bdb2b28b1f75ccd201a4a4m6e7g83jy5fc5d5a9d1340961598cfcb0a1",
-            "status": 1
-        },
-        {
-            "insertTime": 1508398632000,
-            "amount": 1000,
-            "asset": "XMR",
-            "address": "463tWEBn5XZJSxLU34r6g7h8jtxuNcDbjLSjkn3XAXHCbLrTTErJrBWYgHJQyrCwkNgYvV38",
-            "addressTag": "342341222",
-            "txId": "c3c6219639c8ae3f9cf010cdc24fw7f7yt8j1e063f9b4bd1a05cb44c4b6e2509",
-            "status": 1
-        }
-    ],
-    "success": true
-}"""
-
-BINANCE_WITHDRAWALS_HISTORY_RESPONSE = """{
-    "withdrawList": [
-        {
-            "id":"7213fea8e94b4a5593d507237e5a555b",
-            "amount": 1,
-            "address": "0x6915f16f8791d0a1cc2bf47c13a6b2a92000504b",
-            "asset": "ETH",
-            "txId": "0xdf33b22bdb2b28b1f75ccd201a4a4m6e7g83jy5fc5d5a9d1340961598cfcb0a1",
-            "applyTime": 1508488245000,
-            "status": 4
-        },
-        {
-            "id":"7213fea8e94b4a5534ggsd237e5a555b",
-            "amount": 850.1,
-            "address": "463tWEBn5XZJSxLU34r6g7h8jtxuNcDbjLSjkn3XAXHCbLrTTErJrBWYgHJQyrCwkNgYvyVz8",
-            "addressTag": "342341222",
-            "txId": "b3c6219639c8ae3f9cf010cdc24fw7f7yt8j1e063f9b4bd1a05cb44c4b6e2509",
-            "asset": "XMR",
-            "applyTime": 1508512521000,
-            "status": 4
-        }
-    ],
-    "success": true
-}"""
-
-
 def test_binance_query_deposits_withdrawals(function_scope_binance):
     """Test the happy case of binance deposit withdrawal query
 
@@ -432,40 +385,7 @@ def mock_get_deposit_withdrawal(url):  # pylint: disable=unused-argument
     warnings = binance.msg_aggregator.consume_warnings()
     assert len(errors) == 0
     assert len(warnings) == 0
-
-    assert len(movements) == 4
-
-    assert movements[0].location == Location.BINANCE
-    assert movements[0].category == AssetMovementCategory.DEPOSIT
-    assert movements[0].timestamp == 1508198532
-    assert isinstance(movements[0].asset, Asset)
-    assert movements[0].asset == A_ETH
-    assert movements[0].amount == FVal('0.04670582')
-    assert movements[0].fee == ZERO
-
-    assert movements[1].location == Location.BINANCE
-    assert movements[1].category == AssetMovementCategory.DEPOSIT
-    assert movements[1].timestamp == 1508398632
-    assert isinstance(movements[1].asset, Asset)
-    assert movements[1].asset == A_XMR
-    assert movements[1].amount == FVal('1000')
-    assert movements[1].fee == ZERO
-
-    assert movements[2].location == Location.BINANCE
-    assert movements[2].category == AssetMovementCategory.WITHDRAWAL
-    assert movements[2].timestamp == 1508488245
-    assert isinstance(movements[2].asset, Asset)
-    assert movements[2].asset == A_ETH
-    assert movements[2].amount == FVal('1')
-    assert movements[2].fee == ZERO
-
-    assert movements[3].location == Location.BINANCE
-    assert movements[3].category == AssetMovementCategory.WITHDRAWAL
-    assert movements[3].timestamp == 1508512521
-    assert isinstance(movements[3].asset, Asset)
-    assert movements[3].asset == A_XMR
-    assert movements[3].amount == FVal('850.1')
-    assert movements[3].fee == ZERO
+    assert_binance_asset_movements_result(movements=movements, location=Location.BINANCE)
 
 
 def test_binance_query_deposits_withdrawals_unexpected_data(function_scope_binance):
diff --git a/rotkehlchen/tests/exchanges/test_binance_us.py b/rotkehlchen/tests/exchanges/test_binance_us.py
--- a/rotkehlchen/tests/exchanges/test_binance_us.py
+++ b/rotkehlchen/tests/exchanges/test_binance_us.py
@@ -1,10 +1,24 @@
 import warnings as test_warnings
+from unittest.mock import patch
+
+import pytest
 
 from rotkehlchen.assets.converters import UNSUPPORTED_BINANCE_ASSETS, asset_from_binance
+from rotkehlchen.constants.assets import A_BNB, A_BTC
 from rotkehlchen.constants.misc import BINANCE_US_BASE_URL
 from rotkehlchen.errors import UnknownAsset, UnsupportedAsset
 from rotkehlchen.exchanges.binance import Binance
+from rotkehlchen.exchanges.data_structures import Location, Trade, TradeType
+from rotkehlchen.fval import FVal
+from rotkehlchen.tests.utils.exchanges import (
+    BINANCE_DEPOSITS_HISTORY_RESPONSE,
+    BINANCE_MYTRADES_RESPONSE,
+    BINANCE_WITHDRAWALS_HISTORY_RESPONSE,
+    assert_binance_asset_movements_result,
+)
 from rotkehlchen.tests.utils.factories import make_api_key, make_api_secret
+from rotkehlchen.tests.utils.mock import MockResponse
+from rotkehlchen.typing import Timestamp
 from rotkehlchen.user_messages import MessagesAggregator
 
 
@@ -43,3 +57,72 @@ def test_binance_assets_are_known(
                 f'Found unknown asset {e.asset_name} in binance_us. '
                 f'Support for it has to be added',
             ))
+
+
+@pytest.mark.parametrize('binance_location', [Location.BINANCE_US])
+def test_binanceus_trades_location(function_scope_binance):
+    """Test that trades from binance US have the right location.
+
+    Regression test for https://github.com/rotki/rotki/issues/2837
+    """
+    binance = function_scope_binance
+
+    def mock_my_trades(url):  # pylint: disable=unused-argument
+        if 'symbol=BNBBTC' in url:
+            text = BINANCE_MYTRADES_RESPONSE
+        else:
+            text = '[]'
+
+        return MockResponse(200, text)
+
+    with patch.object(binance.session, 'get', side_effect=mock_my_trades):
+        trades = binance.query_trade_history(start_ts=0, end_ts=1564301134, only_cache=False)
+
+    expected_trade = Trade(
+        timestamp=1499865549,
+        location=Location.BINANCE_US,
+        base_asset=A_BNB,
+        quote_asset=A_BTC,
+        trade_type=TradeType.BUY,
+        amount=FVal('12'),
+        rate=FVal('4.00000100'),
+        fee=FVal('10.10000000'),
+        fee_currency=A_BNB,
+        link='28457',
+    )
+
+    assert len(trades) == 1
+    assert trades[0] == expected_trade
+
+
+@pytest.mark.parametrize('binance_location', [Location.BINANCE_US])
+def test_binanceus_deposits_withdrawals_location(function_scope_binance):
+    """Test deposits/withdrawls of binance US have the right location.
+
+    Regression test for https://github.com/rotki/rotki/issues/2837
+    """
+    start_ts = 1508022000  # 2017-10-15
+    end_ts = 1508540400  # 2017-10-21 (less than 90 days since `start_ts`)
+    binance = function_scope_binance
+
+    def mock_get_deposit_withdrawal(url):  # pylint: disable=unused-argument
+        if 'deposit' in url:
+            response_str = BINANCE_DEPOSITS_HISTORY_RESPONSE
+        else:
+            response_str = BINANCE_WITHDRAWALS_HISTORY_RESPONSE
+
+        return MockResponse(200, response_str)
+
+    with patch.object(binance.session, 'get', side_effect=mock_get_deposit_withdrawal):
+        movements = binance.query_online_deposits_withdrawals(
+            start_ts=Timestamp(start_ts),
+            end_ts=Timestamp(end_ts),
+        )
+
+    errors = binance.msg_aggregator.consume_errors()
+    warnings = binance.msg_aggregator.consume_warnings()
+    assert len(errors) == 0
+    assert len(warnings) == 0
+
+    assert len(movements) == 4
+    assert_binance_asset_movements_result(movements=movements, location=Location.BINANCE_US)
diff --git a/rotkehlchen/tests/fixtures/exchanges/binance.py b/rotkehlchen/tests/fixtures/exchanges/binance.py
--- a/rotkehlchen/tests/fixtures/exchanges/binance.py
+++ b/rotkehlchen/tests/fixtures/exchanges/binance.py
@@ -1,6 +1,12 @@
 import pytest
 
 from rotkehlchen.tests.utils.exchanges import create_test_binance
+from rotkehlchen.typing import Location
+
+
+@pytest.fixture(name='binance_location')
+def fixture_binance_location() -> Location:
+    return Location.BINANCE
 
 
 @pytest.fixture
@@ -8,9 +14,11 @@ def function_scope_binance(
         database,
         inquirer,  # pylint: disable=unused-argument
         function_scope_messages_aggregator,
+        binance_location,
 ):
     binance = create_test_binance(
         database=database,
         msg_aggregator=function_scope_messages_aggregator,
+        location=binance_location,
     )
     return binance
diff --git a/rotkehlchen/tests/utils/exchanges.py b/rotkehlchen/tests/utils/exchanges.py
--- a/rotkehlchen/tests/utils/exchanges.py
+++ b/rotkehlchen/tests/utils/exchanges.py
@@ -1,9 +1,12 @@
 import json
 import os
 from pathlib import Path
-from typing import Any, Dict, Optional
+from typing import Any, Dict, List, Optional
 from unittest.mock import patch
 
+from rotkehlchen.assets.asset import Asset
+from rotkehlchen.constants.assets import A_ETH
+from rotkehlchen.constants.misc import BINANCE_BASE_URL, BINANCE_US_BASE_URL, ZERO
 from rotkehlchen.db.dbhandler import DBHandler
 from rotkehlchen.exchanges.binance import Binance, create_binance_symbols_to_pair
 from rotkehlchen.exchanges.bitcoinde import Bitcoinde
@@ -13,11 +16,14 @@
 from rotkehlchen.exchanges.bittrex import Bittrex
 from rotkehlchen.exchanges.coinbase import Coinbase
 from rotkehlchen.exchanges.coinbasepro import Coinbasepro
+from rotkehlchen.exchanges.data_structures import AssetMovement
 from rotkehlchen.exchanges.ftx import Ftx
 from rotkehlchen.exchanges.gemini import Gemini
 from rotkehlchen.exchanges.iconomi import Iconomi
 from rotkehlchen.exchanges.kucoin import Kucoin
 from rotkehlchen.exchanges.poloniex import Poloniex
+from rotkehlchen.fval import FVal
+from rotkehlchen.tests.utils.constants import A_XMR
 from rotkehlchen.tests.utils.factories import (
     make_api_key,
     make_api_secret,
@@ -25,7 +31,7 @@
 )
 from rotkehlchen.tests.utils.kraken import MockKraken
 from rotkehlchen.tests.utils.mock import MockResponse
-from rotkehlchen.typing import ApiKey, ApiSecret
+from rotkehlchen.typing import ApiKey, ApiSecret, AssetMovementCategory, Location
 from rotkehlchen.user_messages import MessagesAggregator
 
 POLONIEX_MOCK_DEPOSIT_WITHDRAWALS_RESPONSE = """{
@@ -278,6 +284,54 @@
     "isBestMatch": true
     }]"""
 
+BINANCE_DEPOSITS_HISTORY_RESPONSE = """{
+    "depositList": [
+        {
+            "insertTime": 1508198532000,
+            "amount": 0.04670582,
+            "asset": "ETH",
+            "address": "0x6915f16f8791d0a1cc2bf47c13a6b2a92000504b",
+            "txId": "0xef33b22bdb2b28b1f75ccd201a4a4m6e7g83jy5fc5d5a9d1340961598cfcb0a1",
+            "status": 1
+        },
+        {
+            "insertTime": 1508398632000,
+            "amount": 1000,
+            "asset": "XMR",
+            "address": "463tWEBn5XZJSxLU34r6g7h8jtxuNcDbjLSjkn3XAXHCbLrTTErJrBWYgHJQyrCwkNgYvV38",
+            "addressTag": "342341222",
+            "txId": "c3c6219639c8ae3f9cf010cdc24fw7f7yt8j1e063f9b4bd1a05cb44c4b6e2509",
+            "status": 1
+        }
+    ],
+    "success": true
+}"""
+
+BINANCE_WITHDRAWALS_HISTORY_RESPONSE = """{
+    "withdrawList": [
+        {
+            "id":"7213fea8e94b4a5593d507237e5a555b",
+            "amount": 1,
+            "address": "0x6915f16f8791d0a1cc2bf47c13a6b2a92000504b",
+            "asset": "ETH",
+            "txId": "0xdf33b22bdb2b28b1f75ccd201a4a4m6e7g83jy5fc5d5a9d1340961598cfcb0a1",
+            "applyTime": 1508488245000,
+            "status": 4
+        },
+        {
+            "id":"7213fea8e94b4a5534ggsd237e5a555b",
+            "amount": 850.1,
+            "address": "463tWEBn5XZJSxLU34r6g7h8jtxuNcDbjLSjkn3XAXHCbLrTTErJrBWYgHJQyrCwkNgYvyVz8",
+            "addressTag": "342341222",
+            "txId": "b3c6219639c8ae3f9cf010cdc24fw7f7yt8j1e063f9b4bd1a05cb44c4b6e2509",
+            "asset": "XMR",
+            "applyTime": 1508512521000,
+            "status": 4
+        }
+    ],
+    "success": true
+}"""
+
 
 def assert_binance_balances_result(balances: Dict[str, Any]) -> None:
     assert balances['BTC']['amount'] == '4723846.89208129'
@@ -286,6 +340,41 @@ def assert_binance_balances_result(balances: Dict[str, Any]) -> None:
     assert balances['ETH']['usd_value'] is not None
 
 
+def assert_binance_asset_movements_result(movements: List[AssetMovement], location: Location) -> None:  # noqa: E501
+    assert len(movements) == 4
+    assert movements[0].location == location
+    assert movements[0].category == AssetMovementCategory.DEPOSIT
+    assert movements[0].timestamp == 1508198532
+    assert isinstance(movements[0].asset, Asset)
+    assert movements[0].asset == A_ETH
+    assert movements[0].amount == FVal('0.04670582')
+    assert movements[0].fee == ZERO
+
+    assert movements[1].location == location
+    assert movements[1].category == AssetMovementCategory.DEPOSIT
+    assert movements[1].timestamp == 1508398632
+    assert isinstance(movements[1].asset, Asset)
+    assert movements[1].asset == A_XMR
+    assert movements[1].amount == FVal('1000')
+    assert movements[1].fee == ZERO
+
+    assert movements[2].location == location
+    assert movements[2].category == AssetMovementCategory.WITHDRAWAL
+    assert movements[2].timestamp == 1508488245
+    assert isinstance(movements[2].asset, Asset)
+    assert movements[2].asset == A_ETH
+    assert movements[2].amount == FVal('1')
+    assert movements[2].fee == ZERO
+
+    assert movements[3].location == location
+    assert movements[3].category == AssetMovementCategory.WITHDRAWAL
+    assert movements[3].timestamp == 1508512521
+    assert isinstance(movements[3].asset, Asset)
+    assert movements[3].asset == A_XMR
+    assert movements[3].amount == FVal('850.1')
+    assert movements[3].fee == ZERO
+
+
 def assert_poloniex_balances_result(balances: Dict[str, Any]) -> None:
     assert balances['BTC']['amount'] == '5.5'
     assert balances['BTC']['usd_value'] is not None
@@ -355,12 +444,18 @@ def create_test_coinbase(
 def create_test_binance(
         database: DBHandler,
         msg_aggregator: MessagesAggregator,
+        location: Location = Location.BINANCE,
 ) -> Binance:
+    if location == Location.BINANCE:
+        uri = BINANCE_BASE_URL
+    elif location == Location.BINANCE_US:
+        uri = BINANCE_US_BASE_URL
     binance = Binance(
         api_key=make_api_key(),
         secret=make_api_secret(),
         database=database,
         msg_aggregator=msg_aggregator,
+        uri=uri,
     )
     this_dir = os.path.dirname(os.path.abspath(__file__))
     json_path = Path(this_dir) / 'data' / 'binance_exchange_info.json'