Repository: rotki/rotki

Issue:
Added Bitfinex support
- [X] Pending to extend `_api_query_paginated()` for supporting rate limits. Unit tested.
- [X] Pending check whether we need to add a special case in `converters.py` for Bitfinex (~~I don't think so~~, hell yes).
- [X] Added test for discovering exchange assets not supported yet by Rotki (`test_bitfinex_exchange_assets_are_known`).

Closes #438 


Discussion:
> Pending check whether we need to add a special case in converters.py for Bitfinex (I don't think so).

Hey @vnavascues what do you mean by that? Didn't you say they got some special naming?
# [Codecov](https://codecov.io/gh/rotki/rotki/pull/1968?src=pr&el=h1) Report
> Merging [#1968](https://codecov.io/gh/rotki/rotki/pull/1968?src=pr&el=desc) (a310c16) into [develop](https://codecov.io/gh/rotki/rotki/commit/4fdd6e624ee47a78032dfde245cdaedaad130892?el=desc) (4fdd6e6) will **increase** coverage by `19.31%`.
> The diff coverage is `69.62%`.

[![Impacted file tree graph](https://codecov.io/gh/rotki/rotki/pull/1968/graphs/tree.svg?width=650&height=150&src=pr&token=unMzgWld3q)](https://codecov.io/gh/rotki/rotki/pull/1968?src=pr&el=tree)

```diff
@@             Coverage Diff              @@
##           develop    #1968       +/-   ##
============================================
+ Coverage    50.77%   70.08%   +19.31%     
============================================
  Files          236      431      +195     
  Lines         5148    25387    +20239     
  Branches       760     3642     +2882     
============================================
+ Hits          2614    17793    +15179     
- Misses        2335     6674     +4339     
- Partials       199      920      +721     
```

| Flag | Coverage Δ | |
|---|---|---|
| backend | `79.44% <69.55%> (?)` | |
| frontend_integration | `50.76% <100.00%> (-0.01%)` | :arrow_down: |
| frontend_unit | `22.62% <100.00%> (?)` | |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags#carryforward-flags-in-the-pull-request-comment) to find out more.

| [Impacted Files](https://codecov.io/gh/rotki/rotki/pull/1968?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [frontend/app/src/components/history/consts.ts](https://codecov.io/gh/rotki/rotki/pull/1968/diff?src=pr&el=tree#diff-ZnJvbnRlbmQvYXBwL3NyYy9jb21wb25lbnRzL2hpc3RvcnkvY29uc3RzLnRz) | `100.00% <ø> (ø)` | |
| [rotkehlchen/data/importer.py](https://codecov.io/gh/rotki/rotki/pull/1968/diff?src=pr&el=tree#diff-cm90a2VobGNoZW4vZGF0YS9pbXBvcnRlci5weQ==) | `73.30% <0.00%> (ø)` | |
| [rotkehlchen/db/schema.py](https://codecov.io/gh/rotki/rotki/pull/1968/diff?src=pr&el=tree#diff-cm90a2VobGNoZW4vZGIvc2NoZW1hLnB5) | `100.00% <ø> (ø)` | |
| [rotkehlchen/exchanges/manager.py](https://codecov.io/gh/rotki/rotki/pull/1968/diff?src=pr&el=tree#diff-cm90a2VobGNoZW4vZXhjaGFuZ2VzL21hbmFnZXIucHk=) | `90.78% <ø> (ø)` | |
| [rotkehlchen/typing.py](https://codecov.io/gh/rotki/rotki/pull/1968/diff?src=pr&el=tree#diff-cm90a2VobGNoZW4vdHlwaW5nLnB5) | `92.07% <60.00%> (ø)` | |
| [rotkehlchen/assets/asset.py](https://codecov.io/gh/rotki/rotki/pull/1968/diff?src=pr&el=tree#diff-cm90a2VobGNoZW4vYXNzZXRzL2Fzc2V0LnB5) | `88.39% <66.66%> (ø)` | |
| [rotkehlchen/assets/converters.py](https://codecov.io/gh/rotki/rotki/pull/1968/diff?src=pr&el=tree#diff-cm90a2VobGNoZW4vYXNzZXRzL2NvbnZlcnRlcnMucHk=) | `79.48% <69.23%> (ø)` | |
| [rotkehlchen/exchanges/bitfinex.py](https://codecov.io/gh/rotki/rotki/pull/1968/diff?src=pr&el=tree#diff-cm90a2VobGNoZW4vZXhjaGFuZ2VzL2JpdGZpbmV4LnB5) | `69.90% <69.90%> (ø)` | |
| [rotkehlchen/serialization/deserialize.py](https://codecov.io/gh/rotki/rotki/pull/1968/diff?src=pr&el=tree#diff-cm90a2VobGNoZW4vc2VyaWFsaXphdGlvbi9kZXNlcmlhbGl6ZS5weQ==) | `84.33% <75.00%> (ø)` | |
| [frontend/app/src/data/defaults.ts](https://codecov.io/gh/rotki/rotki/pull/1968/diff?src=pr&el=tree#diff-ZnJvbnRlbmQvYXBwL3NyYy9kYXRhL2RlZmF1bHRzLnRz) | `100.00% <100.00%> (ø)` | |
| ... and [396 more](https://codecov.io/gh/rotki/rotki/pull/1968/diff?src=pr&el=tree-more) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/rotki/rotki/pull/1968?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/rotki/rotki/pull/1968?src=pr&el=footer). Last update [e323cca...320855f](https://codecov.io/gh/rotki/rotki/pull/1968?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

Some research done
```
Bitfinex supported assets' symbols
['AAA', 'ABS', 'ADA', 'ADD', 'AGI', 'AIO', 'ALG', 'AMP', 'AMPF0', 'ANT', 'AST', 'ATD', 'ATO', 'AUC', 'AVAX', 'AVT', 'B21X', 'BAL', 'BAND', 'BAT', 'BBB', 'BCH', 'BCHABC', 'BCHN', 'BFT', 'BFX', 'BG1', 'BG2', 'BNT', 'BOX', 'BSV', 'BTC', 'BTCDOMF0', 'BTCF0', 'BTG', 'BTSE', 'BTT', 'CAD', 'CBT', 'CHF', 'CHZ', 'CLO', 'CND', 'CNH', 'CNHT', 'CNN', 'COMP', 'CSTBCHABC', 'CSTBCHN', 'CSX', 'CTX', 'DAI', 'DAPP', 'DAT', 'DGB', 'DGX', 'DOG', 'DOT', 'DOTF0', 'DRK', 'DRN', 'DSH', 'DTA', 'DTX', 'DUSK', 'EDO', 'EGLD', 'ELF', 'ENJ', 'EOS', 'EOSDT', 'EOSF0', 'EOX', 'ESS', 'ETC', 'ETH', 'ETH2P', 'ETHF0', 'ETP', 'EUR', 'EURF0', 'EUROPE50IXF0', 'EUS', 'EUT', 'FET', 'FIL', 'FTT', 'FUN', 'GBP', 'GBPF0', 'GEN', 'GERMANY30IXF0', 'GNO', 'GNT', 'GOT', 'GSD', 'GTX', 'HEZ', 'HKD', 'HOT', 'IMP', 'IOS', 'IOT', 'IOTF0', 'IQX', 'JPY', 'JPYF0', 'JST', 'KAN', 'KNC', 'KSM', 'LBT', 'LEO', 'LES', 'LET', 'LINK', 'LINKF0', 'LNX', 'LRC', 'LTC', 'LTCF0', 'LYM', 'MAN', 'MGO', 'MKR', 'MLN', 'MNA', 'MTN', 'MTO', 'NCA', 'NEC', 'NEO', 'NUT', 'ODE', 'OKB', 'OMG', 'OMN', 'ONL', 'ORS', 'PAI', 'PANTEOS', 'PAS', 'PAX', 'PBALEOS', 'PBANDEOS', 'PBATEOS', 'PBTCEOS', 'PBTCETH', 'PCOMPEOS', 'PDAIEOS', 'PEOSETH', 'PETHEOS', 'PLINKEOS', 'PLRCEOS', 'PLTCEOS', 'PLTCETH', 'PLU', 'PMKREOS', 'PNK', 'POA', 'POMGEOS', 'PPNKEOS', 'PPNTEOS', 'PREPEOS', 'PSNXEOS', 'PUNIEOS', 'PUOSEOS', 'PYFIEOS', 'PZRXEOS', 'QSH', 'QTM', 'RBT', 'RCN', 'RDN', 'REP', 'REQ', 'RIF', 'RINGX', 'RLC', 'RRB', 'RRT', 'RTE', 'SAN', 'SCR', 'SEE', 'SGD', 'SNG', 'SNT', 'SNX', 'STJ', 'SUN', 'SWM', 'TESTBTC', 'TESTBTCF0', 'TESTUSD', 'TESTUSDT', 'TESTUSDTF0', 'THB', 'TKN', 'TNB', 'TRI', 'TRX', 'TSD', 'TWD', 'UDC', 'UNI', 'UNIF0', 'UOP', 'UOS', 'USD', 'USK', 'UST', 'USTF0', 'UTK', 'UTN', 'VEE', 'VET', 'VLD', 'VSY', 'WAX', 'WBT', 'WPR', 'WTC', 'XAGF0', 'XAUT', 'XAUTF0', 'XCH', 'XDC', 'XLM', 'XMR', 'XRA', 'XRP', 'XTZ', 'XVG', 'YFI', 'YGG', 'YYW', 'ZBT', 'ZCN', 'ZEC', 'ZIL', 'ZRX']

Bitfinex exchange pairs
['AAABBB', 'ADABTC', 'ADAUSD', 'ADAUST', 'AIOUSD', 'ALGBTC', 'ALGUSD', 'ALGUST', 'AMPBTC', 'AMPUSD', 'AMPUST', 'ANTBTC', 'ANTETH', 'ANTUSD', 'ASTUSD', 'ATOBTC', 'ATOETH', 'ATOUSD', 'AUCUSD', 'AVAX:USD', 'AVAX:UST', 'AVTUSD', 'B21X:USD', 'B21X:UST', 'BALUSD', 'BALUST', 'BAND:USD', 'BAND:UST', 'BATBTC', 'BATETH', 'BATUSD', 'BCHABC:USD', 'BCHN:USD', 'BFTUSD', 'BNTUSD', 'BOXUSD', 'BSVBTC', 'BSVUSD', 'BTC:CNHT', 'BTCEUR', 'BTCGBP', 'BTCJPY', 'BTCUSD', 'BTCUST', 'BTCXCH', 'BTGBTC', 'BTGUSD', 'BTSE:USD', 'BTTUSD', 'CBTUSD', 'CHZUSD', 'CHZUST', 'CLOUSD', 'CNDUSD', 'CNH:CNHT', 'COMP:USD', 'COMP:UST', 'CTXUSD', 'DAIBTC', 'DAIETH', 'DAIUSD', 'DAPP:USD', 'DAPP:UST', 'DATBTC', 'DATUSD', 'DGBUSD', 'DGXUSD', 'DOGBTC', 'DOGUSD', 'DOGUST', 'DOTUSD', 'DOTUST', 'DRNUSD', 'DSHBTC', 'DSHUSD', 'DTAUSD', 'DTXUSD', 'DUSK:BTC', 'DUSK:USD', 'EDOBTC', 'EDOETH', 'EDOUSD', 'EGLD:USD', 'EGLD:UST', 'ENJUSD', 'EOSBTC', 'EOSDT:USD', 'EOSDT:UST', 'EOSETH', 'EOSEUR', 'EOSGBP', 'EOSJPY', 'EOSUSD', 'EOSUST', 'ESSUSD', 'ETCBTC', 'ETCUSD', 'ETHBTC', 'ETHEUR', 'ETHGBP', 'ETHJPY', 'ETHUSD', 'ETHUST', 'ETPBTC', 'ETPETH', 'ETPUSD', 'EUSUSD', 'EUTEUR', 'EUTUSD', 'EUTUST', 'FETUSD', 'FETUST', 'FILUSD', 'FILUST', 'FTTUSD', 'FTTUST', 'FUNUSD', 'GENUSD', 'GNOUSD', 'GNTBTC', 'GNTETH', 'GNTUSD', 'GOTEUR', 'GOTUSD', 'GSDUSD', 'GTXUSD', 'GTXUST', 'HEZUSD', 'HEZUST', 'HOTUSD', 'IMPUSD', 'IOSUSD', 'IOTBTC', 'IOTETH', 'IOTEUR', 'IOTGBP', 'IOTJPY', 'IOTUSD', 'IQXUSD', 'IQXUST', 'JSTBTC', 'JSTUSD', 'JSTUST', 'KANUSD', 'KANUST', 'KNCBTC', 'KNCUSD', 'KSMUSD', 'KSMUST', 'LEOBTC', 'LEOEOS', 'LEOETH', 'LEOUSD', 'LEOUST', 'LINK:USD', 'LINK:UST', 'LRCBTC', 'LRCUSD', 'LTCBTC', 'LTCUSD', 'LTCUST', 'LYMUSD', 'MANUSD', 'MGOUSD', 'MKRBTC', 'MKRETH', 'MKRUSD', 'MLNUSD', 'MNABTC', 'MNAUSD', 'MTNUSD', 'NCAUSD', 'NECETH', 'NECUSD', 'NEOBTC', 'NEOETH', 'NEOEUR', 'NEOGBP', 'NEOJPY', 'NEOUSD', 'NUTUSD', 'NUTUST', 'ODEUSD', 'OKBUSD', 'OKBUST', 'OMGBTC', 'OMGETH', 'OMGUSD', 'OMNBTC', 'OMNUSD', 'ONLUSD', 'ORSUSD', 'PAIUSD', 'PASUSD', 'PAXUSD', 'PAXUST', 'PLUUSD', 'PNKETH', 'PNKUSD', 'POAUSD', 'QSHUSD', 'QTMBTC', 'QTMUSD', 'RBTBTC', 'RBTUSD', 'RCNUSD', 'REPBTC', 'REPUSD', 'REQUSD', 'RIFUSD', 'RINGX:USD', 'RLCBTC', 'RLCUSD', 'RRBUSD', 'RRBUST', 'RRTUSD', 'SANBTC', 'SANETH', 'SANUSD', 'SCRUSD', 'SNGUSD', 'SNTUSD', 'SNXUSD', 'SNXUST', 'STJUSD', 'SUNUSD', 'SUNUST', 'SWMUSD', 'TESTBTC:TESTUSD', 'TESTBTC:TESTUSDT', 'TKNUSD', 'TNBUSD', 'TRIUSD', 'TRXBTC', 'TRXETH', 'TRXEUR', 'TRXUSD', 'TSDUSD', 'TSDUST', 'UDCUSD', 'UDCUST', 'UNIUSD', 'UNIUST', 'UOPUSD', 'UOPUST', 'UOSBTC', 'UOSUSD', 'USKUSD', 'UST:CNHT', 'USTUSD', 'UTKUSD', 'VEEUSD', 'VETBTC', 'VETUSD', 'VSYBTC', 'VSYUSD', 'WAXUSD', 'WBTETH', 'WBTUSD', 'WPRUSD', 'WTCUSD', 'XAUT:BTC', 'XAUT:USD', 'XAUT:UST', 'XCHETH', 'XCHUSD', 'XDCUSD', 'XDCUST', 'XLMBTC', 'XLMETH', 'XLMUSD', 'XMRBTC', 'XMRUSD', 'XMRUST', 'XRAUSD', 'XRPBTC', 'XRPUSD', 'XRPUST', 'XTZBTC', 'XTZUSD', 'XVGUSD', 'YFIUSD', 'YFIUST', 'YGGUSD', 'YYWUSD', 'ZBTUSD', 'ZCNUSD', 'ZECBTC', 'ZECUSD', 'ZILUSD', 'ZRXBTC', 'ZRXETH', 'ZRXUSD']

Bitfinex assets'symbol map (extended with our BITFINEX_TO_WORLD, e.g. ZBT: ZB)
{'AAA': 'TESTAAA', 'ABS': 'ABYSS', 'AIO': 'AION', 'ALG': 'ALGO', 'AMP': 'AMPL', 'AMPF0': 'AMPLF0', 'ATO': 'ATOM', 'BBB': 'TESTBBB', 'BTCF0': 'BTC', 'CNHT': 'CNHt', 'CSX': 'CS', 'CTX': 'CTXC', 'DAT': 'DATA', 'DOG': 'MDOGE', 'DRN': 'DRGN', 'DSH': 'DASH', 'DTX': 'DT', 'EDO': 'PNT', 'EUS': 'EURS', 'EUT': 'EURt', 'GNT': 'GLM', 'GSD': 'GUSD', 'IOS': 'IOST', 'IOT': 'IOTA', 'LBT': 'LBTC', 'LES': 'LEO-EOS', 'LET': 'LEO-ERC20', 'MNA': 'MANA', 'NCA': 'NCASH', 'OMN': 'OMNI', 'PAS': 'PASS', 'PBTCEOS': 'pBTC-EOS', 'PBTCETH': 'PBTC-ETH', 'PETHEOS': 'pETH-EOS', 'PLTCEOS': 'PLTC-EOS', 'PLTCETH': 'PLTC-ETH', 'QSH': 'QASH', 'QTM': 'QTUM', 'RBT': 'RBTC', 'REP': 'REP2', 'SCR': 'XD', 'SNG': 'SNGLS', 'STJ': 'STORJ', 'TSD': 'TUSD', 'UDC': 'USDC', 'USK': 'USDK', 'UST': 'USDt', 'USTF0': 'USDt', 'UTN': 'UTNP', 'VSY': 'VSYS', 'WBT': 'WBTC', 'XAUT': 'XAUt', 'XCH': 'XCHF', 'YGG': 'YEED', 'YYW': 'YOYOW', 'ZBT': 'ZB'}
```

Known test assets: AAA, BBB, TESTBTC, TESTUSD, TESTUSDT

Added the assets that appeared in:
```
UserWarning: Found unknown asset CLO in bitfinex. Support for it has to be added
UserWarning: Found unknown asset UOS in bitfinex. Support for it has to be added
UserWarning: Found unknown asset ETP in bitfinex. Support for it has to be added
UserWarning: Found unknown asset EOSDT in bitfinex. Support for it has to be added
UserWarning: Found unknown asset USDK in bitfinex. Support for it has to be added
UserWarning: Found unknown asset RRT in bitfinex. Support for it has to be added
UserWarning: Found unknown asset EURt in bitfinex. Support for it has to be added
UserWarning: Found unknown asset TRI in bitfinex. Support for it has to be added
UserWarning: Found unknown asset DAPP in bitfinex. Support for it has to be added
UserWarning: Found unknown asset VSYS in bitfinex. Support for it has to be added
UserWarning: Found unknown asset DT in bitfinex. Support for it has to be added
UserWarning: Found unknown asset OKB in bitfinex. Support for it has to be added
UserWarning: Found unknown asset XCHF in bitfinex. Support for it has to be added
UserWarning: Found unknown asset XAUt in bitfinex. Support for it has to be added
UserWarning: Found unknown asset XDC in bitfinex. Support for it has to be added
UserWarning: Found unknown asset RIF in bitfinex. Support for it has to be added
UserWarning: Found unknown asset ZB in bitfinex. Support for it has to be added
UserWarning: Found unknown asset RINGX in bitfinex. Support for it has to be added
UserWarning: Found unknown asset HEZ in bitfinex. Support for it has to be added
UserWarning: Found unknown asset ESS in bitfinex. Support for it has to be added
UserWarning: Found unknown asset NUT in bitfinex. Support for it has to be added
UserWarning: Found unknown asset LEO in bitfinex. Support for it has to be added
UserWarning: Found unknown asset UOP in bitfinex. Support for it has to be added
UserWarning: Found unknown asset RBTC in bitfinex. Support for it has to be added
UserWarning: Found unknown asset GTX in bitfinex. Support for it has to be added
UserWarning: Found unknown asset XD in bitfinex. Support for it has to be added
UserWarning: Found unknown asset IMP in bitfinex. Support for it has to be added
UserWarning: Found unknown asset RRB in bitfinex. Support for it has to be added
UserWarning: Found unknown asset CNHt in bitfinex. Support for it has to be added
UserWarning: Found unknown asset XRA in bitfinex. Support for it has to be added
UserWarning: Found unknown asset BTSE in bitfinex. Support for it has to be added
```
Unsupported the following assets:
```
BCHN
B21X
GTX
IQX
```
The test that fails is unrelated with this PR: `test_add_xpub_with_conversion_works`.
Frontend is missing and I receive the following warning:
`WARNING rotkehlchen.user_messages: Found unknown bitfinex asset RRT due to: Unknown asset RRT provided.. Ignoring its balance query.`
@philhug This is not ready for testing by others yet :smile: 

I have not reviewed it, it's not completely finalized and yes frontend is indeed missing!

But it's really cool you can test from source! I will ping you once we are ready for your to do it.
@LefterisJP I'm fully aware that it's not reviewed/tested yet.
Hi @philhug, thanks for your interest in this PR, testing it and spotting things to be improved.

1. Balances from margin and funding will be added.
2. ~~The warnings from unsupported assets by Rotki will be hidden.~~ (this is the expected behaviour).
3. Frontend will be added in due time.

I understand that despite we haven't provided yet the frontend, you managed to set it up via the back-end API, did you?
If so, it would be very helpful if you could give us your feedback regarding both trades and asset movements endpoints. Did they work as you expected?

Many thanks
> 1. Balances from margin and funding will be added.
Seems to work.

> 2. ~The warnings from unsupported assets by Rotki will be hidden.~ (this is the expected behaviour).
ok

> 3. Frontend will be added in due time. 
> I understand that despite we haven't provided yet the frontend, you managed to set it up via the back-end API, did you?
np, I just added the frontend

> If so, it would be very helpful if you could give us your feedback regarding both trades and asset movements endpoints. Did they work as you expected?

unfortunately no. trades are fetched, but no further log output than:
DEBUG rotkehlchen.exchanges.bitfinex: bitfinex API request request_url=https://api.bitfinex.com/v2/conf/pub:map:currency:sym
DEBUG rotkehlchen.exchanges.bitfinex: bitfinex API request request_url=https://api.bitfinex.com/v2/auth/r/movements/hist?start=1609167431000&end=1609167714000&limit
=1000&sort=1

There's no obvious error/exception or further logs that show success regarding movement history.
I haven't looked into detail into the code though.
@philhug 

> np, I just added the frontend

![tenor](https://user-images.githubusercontent.com/1658405/103223749-20eeb880-4927-11eb-9b98-ced3f66adbbd.gif)

> unfortunately no. trades are fetched, but no further log output than:

So wait, trades are fetched, but asset movements no? That's not clear to me yet.


> > unfortunately no. trades are fetched, but no further log output than:
> 
> So wait, trades are fetched, but asset movements no? That's not clear to me yet.

Both trades and asset movements are fetched. I can see data in the database.
I did create a new database to test and then I had the errors in the log:
```ERROR rotkehlchen.exchanges.bitfinex: Error processing a bitfinex trades result. raw_result=[MASKED, 'BTC', None], error=Could not deserialize bitfinex trade pair tBTCUSD using fee_currency symbol BTC. Raw trade: ...```

also I see the following debug message, but this might be ok:
```DEBUG rotkehlchen.exchanges.bitfinex: Skipped bitfinex asset_movements result. Already processed raw_result=[MASKED, 'BTC', 'BITCOIN', None, None, MASKED, MASKED, None, None, 'COMPLETED', None, None, -MASKED, 0, None, None, None, None, None, None, None, None]```

The frontend throws an exception, but this might be due to my patched frontend:
```
vue.runtime.esm.js:619 [Vue warn]: Error in mounted hook (Promise/async): "Error: AssertionError"

found in

---> <DepositsWithdrawals> at src/views/history/DepositsWithdrawals.vue
       <VTabItem>
         <VTabsItems>
           <VTabs>
             <TabNavigation> at src/components/helper/TabNavigation.vue
               <History> at src/views/history/History.vue
                 <VMain>
                   <VApp>
                     <App> at src/App.vue
                       <Root>
```

> > > unfortunately no. trades are fetched, but no further log output than:
> > 
> > 
> > So wait, trades are fetched, but asset movements no? That's not clear to me yet.
> 
> Both trades and asset movements are fetched. I can see data in the database.
> I did create a new database to test and then I had the errors in the log:
> `ERROR rotkehlchen.exchanges.bitfinex: Error processing a bitfinex trades result. raw_result=[MASKED, 'BTC', None], error=Could not deserialize bitfinex trade pair tBTCUSD using fee_currency symbol BTC. Raw trade: ...`
> 
> also I see the following debug message, but this might be ok:
> `DEBUG rotkehlchen.exchanges.bitfinex: Skipped bitfinex asset_movements result. Already processed raw_result=[MASKED, 'BTC', 'BITCOIN', None, None, MASKED, MASKED, None, None, 'COMPLETED', None, None, -MASKED, 0, None, None, None, None, None, None, None, None]`
> 
> The frontend throws an exception, but this might be due to my patched frontend:
> 
> ```
> vue.runtime.esm.js:619 [Vue warn]: Error in mounted hook (Promise/async): "Error: AssertionError"
> 
> found in
> 
> ---> <DepositsWithdrawals> at src/views/history/DepositsWithdrawals.vue
>        <VTabItem>
>          <VTabsItems>
>            <VTabs>
>              <TabNavigation> at src/components/helper/TabNavigation.vue
>                <History> at src/views/history/History.vue
>                  <VMain>
>                    <VApp>
>                      <App> at src/App.vue
>                        <Root>
> ```

Hi again!

Could you join us on our discord at https://discord.gg/ZjQ3QUKG? It will really help us to speeding up this!

Resolving patch:
diff --git a/rotkehlchen/assets/converters.py b/rotkehlchen/assets/converters.py
--- a/rotkehlchen/assets/converters.py
+++ b/rotkehlchen/assets/converters.py
@@ -464,8 +464,10 @@
     'AAA',
     'BBB',
     'TESTBTC',
+    'TESTBTCF0',
     'TESTUSD',
     'TESTUSDT',
+    'TESTUSDTF0',
 )
 
 
diff --git a/rotkehlchen/exchanges/bitfinex.py b/rotkehlchen/exchanges/bitfinex.py
--- a/rotkehlchen/exchanges/bitfinex.py
+++ b/rotkehlchen/exchanges/bitfinex.py
@@ -31,7 +31,11 @@
 
 from rotkehlchen.accounting.structures import Balance
 from rotkehlchen.assets.asset import Asset
-from rotkehlchen.assets.converters import BITFINEX_TO_WORLD, asset_from_bitfinex
+from rotkehlchen.assets.converters import (
+    BITFINEX_EXCHANGE_TEST_ASSETS,
+    BITFINEX_TO_WORLD,
+    asset_from_bitfinex,
+)
 from rotkehlchen.constants.misc import ZERO
 from rotkehlchen.errors import (
     DeserializationError,
@@ -217,7 +221,6 @@ def _api_query_paginated(  # pylint: disable=no-self-use
             self,
             options: Dict[str, Any],
             case: Literal['trades'],
-            currency_map: Dict[str, str],
     ) -> List[Trade]:
         ...
 
@@ -226,7 +229,6 @@ def _api_query_paginated(  # pylint: disable=no-self-use
             self,
             options: Dict[str, Any],
             case: Literal['asset_movements'],
-            currency_map: Dict[str, str],
     ) -> List[AssetMovement]:
         ...
 
@@ -234,7 +236,6 @@ def _api_query_paginated(
             self,
             options: Dict[str, Any],
             case: Literal['trades', 'asset_movements'],
-            currency_map: Dict[str, str],
     ) -> Union[List[Trade], List[AssetMovement]]:
         """Request a Bitfinex API v2 endpoint paginating via an options
         attribute.
@@ -330,7 +331,6 @@ def _api_query_paginated(
             results_ = self._deserialize_api_query_paginated_results(
                 case=case_,
                 options=call_options,
-                currency_map=currency_map,
                 raw_results=response_list,
                 processed_result_ids=processed_result_ids,
             )
@@ -365,7 +365,6 @@ def _deserialize_api_query_paginated_results(  # pylint: disable=no-self-use
             self,
             case: Literal['trades'],
             options: Dict[str, Any],
-            currency_map: Dict[str, str],
             raw_results: List[List[Any]],
             processed_result_ids: Set[int],
     ) -> List[Trade]:
@@ -376,7 +375,6 @@ def _deserialize_api_query_paginated_results(  # pylint: disable=no-self-use
             self,
             case: Literal['asset_movements'],
             options: Dict[str, Any],
-            currency_map: Dict[str, str],
             raw_results: List[List[Any]],
             processed_result_ids: Set[int],
     ) -> List[AssetMovement]:
@@ -386,7 +384,6 @@ def _deserialize_api_query_paginated_results(
             self,
             case: Literal['trades', 'asset_movements'],
             options: Dict[str, Any],
-            currency_map: Dict[str, str],
             raw_results: List[List[Any]],
             processed_result_ids: Set[int],
     ) -> Union[List[Trade], List[AssetMovement]]:
@@ -448,10 +445,7 @@ def _deserialize_api_query_paginated_results(
                 continue
 
             try:
-                result = deserialization_method(
-                    raw_result=raw_result,
-                    currency_map=currency_map,
-                )
+                result = deserialization_method(raw_result=raw_result)
             except DeserializationError as e:
                 msg = str(e)
                 log.error(
@@ -469,11 +463,7 @@ def _deserialize_api_query_paginated_results(
 
         return results
 
-    @staticmethod
-    def _deserialize_asset_movement(
-            raw_result: List[Any],
-            currency_map: Dict[str, str],
-    ) -> AssetMovement:
+    def _deserialize_asset_movement(self, raw_result: List[Any]) -> AssetMovement:
         """Process an asset movement (i.e. deposit or withdrawal) from Bitfinex
         and deserialize it.
 
@@ -498,7 +488,7 @@ def _deserialize_asset_movement(
         try:
             fee_asset = asset_from_bitfinex(
                 bitfinex_name=raw_result[1],
-                currency_map=currency_map,
+                currency_map=self.currency_map,
             )
         except (UnknownAsset, UnsupportedAsset) as e:
             asset_tag = 'Unknown' if isinstance(e, UnknownAsset) else 'Unsupported'
@@ -533,11 +523,7 @@ def _deserialize_asset_movement(
         )
         return asset_movement
 
-    @staticmethod
-    def _deserialize_trade(
-            raw_result: List[Any],
-            currency_map: Dict[str, str],
-    ) -> Trade:
+    def _deserialize_trade(self, raw_result: List[Any]) -> Trade:
         """Process a trade result from Bitfinex and deserialize it.
 
         The base and quote assets are instantiated using the `fee_currency_symbol`
@@ -552,34 +538,26 @@ def _deserialize_trade(
         """
         amount = deserialize_asset_amount(raw_result[4])
         trade_type = TradeType.BUY if amount >= ZERO else TradeType.SELL
-        bfx_pair = raw_result[1].replace(':', '')
-        if bfx_pair.startswith('t'):
-            bfx_pair = bfx_pair[1:]
-        bfx_fee_currency_symbol = raw_result[10]
-        if bfx_pair.startswith(bfx_fee_currency_symbol):
-            bfx_base_asset_symbol = bfx_fee_currency_symbol
-            bfx_quote_asset_symbol = bfx_pair[len(bfx_fee_currency_symbol):]
-        elif bfx_pair.endswith(bfx_fee_currency_symbol):
-            bfx_base_asset_symbol = bfx_pair[:-len(bfx_fee_currency_symbol)]
-            bfx_quote_asset_symbol = bfx_fee_currency_symbol
-        else:
+        bfx_pair = self._process_bfx_pair(raw_result[1])
+        if bfx_pair not in self.pair_bfx_symbols_map:
             raise DeserializationError(
-                f'Could not deserialize bitfinex trade pair {raw_result[1]} '
-                f'using fee_currency symbol {bfx_fee_currency_symbol}. '
+                f'Could not deserialize bitfinex trade pair {raw_result[1]}. '
                 f'Raw trade: {raw_result}',
             )
+
+        bfx_base_asset_symbol, bfx_quote_asset_symbol = self.pair_bfx_symbols_map[bfx_pair]
         try:
             base_asset = asset_from_bitfinex(
                 bitfinex_name=bfx_base_asset_symbol,
-                currency_map=currency_map,
+                currency_map=self.currency_map,
             )
             quote_asset = asset_from_bitfinex(
                 bitfinex_name=bfx_quote_asset_symbol,
-                currency_map=currency_map,
+                currency_map=self.currency_map,
             )
             fee_asset = asset_from_bitfinex(
-                bitfinex_name=bfx_fee_currency_symbol,
-                currency_map=currency_map,
+                bitfinex_name=raw_result[10],
+                currency_map=self.currency_map,
             )
         except (UnknownAsset, UnsupportedAsset) as e:
             asset_tag = 'Unknown' if isinstance(e, UnknownAsset) else 'Unsupported'
@@ -617,6 +595,14 @@ def _get_error_response_data(response_list: List[Any]) -> ErrorResponseData:
             reason=reason,
         )
 
+    @staticmethod
+    def _process_bfx_pair(raw_pair: str) -> str:
+        bfx_pair = raw_pair.replace(':', '')
+        if bfx_pair.startswith('t'):
+            bfx_pair = bfx_pair[1:]
+
+        return bfx_pair
+
     def _query_currencies(self) -> CurrenciesResponse:
         """Query and return the list of all the currencies supported in
         `<CurrenciesResponse>.currencies`.
@@ -640,7 +626,10 @@ def _query_currencies(self) -> CurrenciesResponse:
                     f'Check further logs',
                 )
             else:
-                currencies = response_list[0]
+                currencies = [
+                    currency for currency in response_list[0]
+                    if currency not in set(BITFINEX_EXCHANGE_TEST_ASSETS)
+                ]
 
         return CurrenciesResponse(
             success=was_successful,
@@ -675,7 +664,10 @@ def _query_currency_map(self) -> CurrencyMapResponse:
                     f'{self.name} currency map returned invalid JSON response. Check further logs',
                 )
             else:
-                currency_map = dict(response_list[0])
+                currency_map = {
+                    bfx_symbol: symbol for bfx_symbol, symbol in response_list[0]
+                    if bfx_symbol not in set(BITFINEX_EXCHANGE_TEST_ASSETS)
+                }
                 currency_map.update(BITFINEX_TO_WORLD)
 
         return CurrencyMapResponse(
@@ -707,7 +699,11 @@ def _query_exchange_pairs(self) -> ExchangePairsResponse:
                     f'Check further logs',
                 )
             else:
-                pairs = response_list[0]
+                pairs = [
+                    pair for pair in response_list[0]
+                    if not pair.startswith(BITFINEX_EXCHANGE_TEST_ASSETS) and
+                    not pair.endswith(BITFINEX_EXCHANGE_TEST_ASSETS)
+                ]
 
         return ExchangePairsResponse(
             success=was_successful,
@@ -802,6 +798,60 @@ def _process_unsuccessful_response(
         raise AssertionError(f'Unexpected {self.name} response_case: {case}')
 
     def first_connection(self) -> None:
+        """Request:
+        - currencies list: tickers of the supported assets.
+        - pairs list: pairs available for trading.
+        - currency map: a map between the ticker used by Bitfinex and the
+        standard one (outside Bitfinex).
+
+        These data are stored in properties along with `pair_bfx_symbols_map`,
+        a dict that maps a pair between the tickers of the base and quote assets.
+        """
+        if self.first_connection_made:
+            return
+
+        currencies_response = self._query_currencies()
+        if currencies_response.success is False:
+            raise RemoteError(
+                f'bitfinex failed to request currencies list. '
+                f'Response status code: {currencies_response.response.status_code}. '
+                f'Response text: {currencies_response.response.text}.',
+            )
+
+        exchange_pairs_response = self._query_exchange_pairs()
+        if exchange_pairs_response.success is False:
+            raise RemoteError(
+                f'bitfinex failed to request exchange pairs list. '
+                f'Response status code: {exchange_pairs_response.response.status_code}. '
+                f'Response text: {exchange_pairs_response.response.text}.',
+            )
+
+        currency_map_response = self._query_currency_map()
+        if currency_map_response.success is False:
+            raise RemoteError(
+                f'bitfinex failed to request exchange currency map. '
+                f'Response status code: {currency_map_response.response.status_code}. '
+                f'Response text: {currency_map_response.response.text}.',
+            )
+        # Generate a pair - tickers map. Bitfinex test assets have already been
+        # removed from both 'pairs' and 'currencies' lists.
+        pair_bfx_symbols_map: Dict[str, Tuple[str, str]] = {}
+        for pair in exchange_pairs_response.pairs:
+            bfx_pair = self._process_bfx_pair(pair)
+            for bfx_symbol in currencies_response.currencies:
+                if bfx_pair.startswith(bfx_symbol):
+                    bfx_base_asset_symbol = bfx_symbol
+                    bfx_quote_asset_symbol = bfx_pair[len(bfx_symbol):]
+                elif bfx_pair.endswith(bfx_symbol):
+                    bfx_base_asset_symbol = bfx_pair[:-len(bfx_symbol)]
+                    bfx_quote_asset_symbol = bfx_symbol
+                else:
+                    continue
+
+                pair_bfx_symbols_map[bfx_pair] = (bfx_base_asset_symbol, bfx_quote_asset_symbol)
+
+        self.currency_map = currency_map_response.currency_map
+        self.pair_bfx_symbols_map = pair_bfx_symbols_map
         self.first_connection_made = True
 
     @protect_with_lock()
@@ -817,19 +867,7 @@ def query_balances(self) -> Tuple[Optional[Dict[Asset, Dict[str, FVal]]], str]:
         Endpoint documentation:
         https://docs.bitfinex.com/reference#rest-auth-wallets
         """
-        try:
-            currency_map_response = self._query_currency_map()
-        except IndexError:
-            msg = f'Error processing {self.name} currency map. Response is empty'
-            log.error(msg)
-            return None, msg
-
-        if currency_map_response.success is False:
-            result, msg = self._process_unsuccessful_response(
-                response=currency_map_response.response,
-                case='balances',
-            )
-            return result, msg
+        self.first_connection()
 
         response = self._api_query('wallets')
         if response.status_code != HTTPStatus.OK:
@@ -865,7 +903,7 @@ def query_balances(self) -> Tuple[Optional[Dict[Asset, Dict[str, FVal]]], str]:
             try:
                 asset = asset_from_bitfinex(
                     bitfinex_name=wallet[currency_index],
-                    currency_map=currency_map_response.currency_map,
+                    currency_map=self.currency_map,
                 )
             except (UnknownAsset, UnsupportedAsset) as e:
                 asset_tag = 'unknown' if isinstance(e, UnknownAsset) else 'unsupported'
@@ -902,19 +940,7 @@ def query_online_deposits_withdrawals(
         Endpoint documentation:
         https://docs.bitfinex.com/reference#rest-auth-movements
         """
-        try:
-            currency_map_response = self._query_currency_map()
-        except IndexError:
-            self.msg_aggregator.add_error(
-                f'Error processing {self.name} currency map. Response is empty',
-            )
-            return []
-
-        if currency_map_response.success is False:
-            return self._process_unsuccessful_response(
-                response=currency_map_response.response,
-                case='asset_movements',
-            )
+        self.first_connection()
 
         options = {
             'start': start_ts * 1000,
@@ -924,7 +950,6 @@ def query_online_deposits_withdrawals(
         asset_movements: List[AssetMovement] = self._api_query_paginated(
             options=options,
             case='asset_movements',
-            currency_map=currency_map_response.currency_map,
         )
         return asset_movements
 
@@ -938,19 +963,7 @@ def query_online_trade_history(
         Endpoint documentation:
         https://docs.bitfinex.com/reference#rest-auth-trades
         """
-        try:
-            currency_map_response = self._query_currency_map()
-        except IndexError:
-            self.msg_aggregator.add_error(
-                f'Error processing {self.name} currency map. Response is empty',
-            )
-            return []
-
-        if currency_map_response.success is False:
-            return self._process_unsuccessful_response(
-                response=currency_map_response.response,
-                case='trades',
-            )
+        self.first_connection()
 
         options = {
             'start': start_ts * 1000,
@@ -961,7 +974,6 @@ def query_online_trade_history(
         trades: List[Trade] = self._api_query_paginated(
             options=options,
             case='trades',
-            currency_map=currency_map_response.currency_map,
         )
         return trades
 


Test patch:
diff --git a/rotkehlchen/tests/exchanges/test_bitfinex.py b/rotkehlchen/tests/exchanges/test_bitfinex.py
--- a/rotkehlchen/tests/exchanges/test_bitfinex.py
+++ b/rotkehlchen/tests/exchanges/test_bitfinex.py
@@ -2,10 +2,9 @@
 from contextlib import ExitStack
 from datetime import datetime
 from http import HTTPStatus
-from unittest.mock import call, patch
+from unittest.mock import MagicMock, call, patch
 
 import pytest
-from requests import Response
 
 from rotkehlchen.accounting.structures import Balance
 from rotkehlchen.assets.asset import Asset
@@ -21,7 +20,6 @@
     API_RATE_LIMITS_ERROR_MESSAGE,
     API_SYSTEM_CLOCK_NOT_SYNCED_ERROR_CODE,
     Bitfinex,
-    CurrencyMapResponse,
 )
 from rotkehlchen.exchanges.data_structures import AssetMovement, Trade, TradeType
 from rotkehlchen.fval import FVal
@@ -102,6 +100,22 @@ def test_bitfinex_exchange_assets_are_known(mock_bitfinex):
             ))
 
 
+def test_first_connection(mock_bitfinex):
+    """Test 'currency_map' and 'pair_bfx_symbols_map' contain the expected data.
+    """
+    assert mock_bitfinex.first_connection_made is False
+    assert hasattr(mock_bitfinex, 'currency_map') is False
+    assert hasattr(mock_bitfinex, 'pair_bfx_symbols_map') is False
+
+    mock_bitfinex.first_connection()
+
+    assert mock_bitfinex.currency_map['UST'] == 'USDt'
+    assert mock_bitfinex.currency_map['WBT'] == 'WBTC'
+    assert mock_bitfinex.pair_bfx_symbols_map['BTCUST'] == ('BTC', 'UST')
+    assert mock_bitfinex.pair_bfx_symbols_map['UDCUSD'] == ('UDC', 'USD')
+    assert mock_bitfinex.first_connection_made is True
+
+
 def test_validate_api_key_system_clock_not_synced_error_code(mock_bitfinex):
     """Test the error code related with the local system clock not being synced
     raises SystemClockNotSyncedError.
@@ -144,17 +158,12 @@ def test_query_balances_asset_balance(mock_bitfinex, inquirer):  # pylint: disab
       - The balance of an asset in UNSUPPORTED_BITFINEX_ASSETS is skipped.
       - The asset ticker is standardized (e.g. WBT to WBTC, UST to USDT).
     """
-    response = Response()
-    response.status_code = HTTPStatus.OK
-    currency_map_response = CurrencyMapResponse(
-        success=True,
-        response=response,
-        currency_map={
-            'UST': 'USDt',
-            'GNT': 'GLM',
-            'WBT': 'WBTC',
-        },
-    )
+    mock_bitfinex.first_connection = MagicMock()
+    mock_bitfinex.currency_map = {
+        'UST': 'USDt',
+        'GNT': 'GLM',
+        'WBT': 'WBTC',
+    }
     balances_data = (
         """
         [
@@ -179,19 +188,11 @@ def test_query_balances_asset_balance(mock_bitfinex, inquirer):  # pylint: disab
     def mock_api_query_response(endpoint):  # pylint: disable=unused-argument
         return MockResponse(HTTPStatus.OK, balances_data)
 
-    currency_map_patch = patch.object(
-        target=mock_bitfinex,
-        attribute='_query_currency_map',
-        return_value=currency_map_response,
-    )
-    balances_query_patch = patch.object(
+    with patch.object(
         target=mock_bitfinex,
         attribute='_api_query',
         side_effect=mock_api_query_response,
-    )
-    with ExitStack() as stack:
-        stack.enter_context(currency_map_patch)
-        stack.enter_context(balances_query_patch)
+    ):
         asset_balance, msg = mock_bitfinex.query_balances()
 
         assert asset_balance == {
@@ -226,6 +227,7 @@ def mock_api_query_response(endpoint):  # pylint: disable=unused-argument
 def test_api_query_paginated_stops_requesting(mock_bitfinex):
     """Test requests are stopped after retry limit is reached.
     """
+    mock_bitfinex.currency_map = {}
 
     def mock_api_query_response(endpoint, options):  # pylint: disable=unused-argument
         return MockResponse(
@@ -254,7 +256,6 @@ def mock_api_query_response(endpoint, options):  # pylint: disable=unused-argume
         result = mock_bitfinex._api_query_paginated(
             options={'limit': 2},
             case='trades',
-            currency_map={},
         )
         assert result == []
 
@@ -266,6 +267,7 @@ def test_api_query_paginated_retries_request(mock_bitfinex):
     JSON as a dict and later as a list (via `_process_unsuccessful_response()`)
     works as expected.
     """
+    mock_bitfinex.currency_map = {}
 
     def get_paginated_response():
         results = [
@@ -299,16 +301,16 @@ def mock_api_query_response(endpoint, options):  # pylint: disable=unused-argume
         result = mock_bitfinex._api_query_paginated(
             options={'limit': 2},
             case='trades',
-            currency_map={},
         )
         assert result == []
 
 
 def test_deserialize_trade_buy(mock_bitfinex):
-    currency_map = {
+    mock_bitfinex.currency_map = {
         'WBT': 'WBTC',
         'UST': 'USDt',
     }
+    mock_bitfinex.pair_bfx_symbols_map = {'WBTUST': ('WBT', 'UST')}
     raw_result = [
         399251013,
         'tWBT:UST',
@@ -320,7 +322,7 @@ def test_deserialize_trade_buy(mock_bitfinex):
         None,
         -1,
         -0.09868591,
-        'UST',
+        'USD',
     ]
     expected_trade = Trade(
         timestamp=Timestamp(1573485493),
@@ -330,19 +332,17 @@ def test_deserialize_trade_buy(mock_bitfinex):
         amount=AssetAmount(FVal('0.26334268')),
         rate=Price(FVal('187.37')),
         fee=Fee(FVal('0.09868591')),
-        fee_currency=Asset('USDT'),
+        fee_currency=Asset('USD'),
         link='399251013',
         notes='',
     )
-    trade = mock_bitfinex._deserialize_trade(
-        raw_result=raw_result,
-        currency_map=currency_map,
-    )
+    trade = mock_bitfinex._deserialize_trade(raw_result=raw_result)
     assert trade == expected_trade
 
 
 def test_deserialize_trade_sell(mock_bitfinex):
-    currency_map = {'UST': 'USDt'}
+    mock_bitfinex.currency_map = {'UST': 'USDt'}
+    mock_bitfinex.pair_bfx_symbols_map = {'ETHUST': ('ETH', 'UST')}
     raw_result = [
         399251013,
         'tETHUST',
@@ -354,7 +354,7 @@ def test_deserialize_trade_sell(mock_bitfinex):
         None,
         -1,
         -0.09868591,
-        'UST',
+        'USD',
     ]
     expected_trade = Trade(
         timestamp=Timestamp(1573485493),
@@ -364,14 +364,11 @@ def test_deserialize_trade_sell(mock_bitfinex):
         amount=AssetAmount(FVal('0.26334268')),
         rate=Price(FVal('187.37')),
         fee=Fee(FVal('0.09868591')),
-        fee_currency=Asset('USDT'),
+        fee_currency=Asset('USD'),
         link='399251013',
         notes='',
     )
-    trade = mock_bitfinex._deserialize_trade(
-        raw_result=raw_result,
-        currency_map=currency_map,
-    )
+    trade = mock_bitfinex._deserialize_trade(raw_result=raw_result)
     assert trade == expected_trade
 
 
@@ -392,16 +389,16 @@ def test_query_online_trade_history_case_1(mock_bitfinex):
     Trades with id 1 to 4 are expected to be returned.
     """
     api_limit = 2
-    response = Response()
-    response.status_code = HTTPStatus.OK
-    currency_map_response = CurrencyMapResponse(
-        success=True,
-        response=response,
-        currency_map={
-            'UST': 'USDt',
-            'WBT': 'WBTC',
-        },
-    )
+    mock_bitfinex.first_connection = MagicMock()
+    mock_bitfinex.currency_map = {
+        'UST': 'USDt',
+        'WBT': 'WBTC',
+    }
+    mock_bitfinex.pair_bfx_symbols_map = {
+        'ETHUST': ('ETH', 'UST'),
+        'WBTUSD': ('WBT', 'USD'),
+        'ETHEUR': ('ETH', 'EUR'),
+    }
     # Buy ETH with USDT
     trade_1 = """
     [
@@ -415,7 +412,7 @@ def test_query_online_trade_history_case_1(mock_bitfinex):
         null,
         -1,
         -0.09868591,
-        "UST"
+        "USD"
     ]
     """
     # Sell ETH for USDT
@@ -463,7 +460,7 @@ def test_query_online_trade_history_case_1(mock_bitfinex):
         null,
         -1,
         -20.00000000,
-        "WBT"
+        "BTC"
     ]
     """
     # Sell ETH for EUR, outside time range (gt 'end_ts')
@@ -525,11 +522,6 @@ def mock_api_query_response(endpoint, options):  # pylint: disable=unused-argume
         return MockResponse(HTTPStatus.OK, next(get_response))
 
     get_response = get_paginated_response()
-    currency_map_patch = patch.object(
-        target=mock_bitfinex,
-        attribute='_query_currency_map',
-        return_value=currency_map_response,
-    )
     api_limit_patch = patch(
         target='rotkehlchen.exchanges.bitfinex.API_TRADES_MAX_LIMIT',
         new=api_limit,
@@ -541,7 +533,6 @@ def mock_api_query_response(endpoint, options):  # pylint: disable=unused-argume
     )
     with ExitStack() as stack:
         stack.enter_context(api_limit_patch)
-        stack.enter_context(currency_map_patch)
         api_query_mock = stack.enter_context(api_query_patch)
         trades = mock_bitfinex.query_online_trade_history(
             start_ts=Timestamp(0),
@@ -557,7 +548,7 @@ def mock_api_query_response(endpoint, options):  # pylint: disable=unused-argume
                 amount=AssetAmount(FVal('0.26334268')),
                 rate=Price(FVal('187.37')),
                 fee=Fee(FVal('0.09868591')),
-                fee_currency=Asset('USDT'),
+                fee_currency=Asset('USD'),
                 link='1',
                 notes='',
             ),
@@ -593,7 +584,7 @@ def mock_api_query_response(endpoint, options):  # pylint: disable=unused-argume
                 amount=AssetAmount(FVal('10000.0')),
                 rate=Price(FVal('0.00005')),
                 fee=Fee(FVal('20.0')),
-                fee_currency=Asset('WBTC'),
+                fee_currency=Asset('BTC'),
                 link='4',
                 notes='',
             ),
@@ -617,16 +608,16 @@ def test_query_online_trade_history_case_2(mock_bitfinex):
     Trades with id 1 to 4 are expected to be returned.
     """
     api_limit = 2
-    response = Response()
-    response.status_code = HTTPStatus.OK
-    currency_map_response = CurrencyMapResponse(
-        success=True,
-        response=response,
-        currency_map={
-            'UST': 'USDt',
-            'WBT': 'WBTC',
-        },
-    )
+    mock_bitfinex.first_connection = MagicMock()
+    mock_bitfinex.currency_map = {
+        'UST': 'USDt',
+        'WBT': 'WBTC',
+    }
+    mock_bitfinex.pair_bfx_symbols_map = {
+        'ETHUST': ('ETH', 'UST'),
+        'WBTUSD': ('WBT', 'USD'),
+        'ETHEUR': ('ETH', 'EUR'),
+    }
     # Buy ETH with USDT
     trade_1 = """
     [
@@ -706,11 +697,6 @@ def mock_api_query_response(endpoint, options):  # pylint: disable=unused-argume
         return MockResponse(HTTPStatus.OK, next(get_response))
 
     get_response = get_paginated_response()
-    currency_map_patch = patch.object(
-        target=mock_bitfinex,
-        attribute='_query_currency_map',
-        return_value=currency_map_response,
-    )
     api_limit_patch = patch(
         target='rotkehlchen.exchanges.bitfinex.API_TRADES_MAX_LIMIT',
         new=api_limit,
@@ -722,7 +708,6 @@ def mock_api_query_response(endpoint, options):  # pylint: disable=unused-argume
     )
     with ExitStack() as stack:
         stack.enter_context(api_limit_patch)
-        stack.enter_context(currency_map_patch)
         stack.enter_context(api_query_patch)
         trades = mock_bitfinex.query_online_trade_history(
             start_ts=Timestamp(0),
@@ -782,7 +767,7 @@ def mock_api_query_response(endpoint, options):  # pylint: disable=unused-argume
 
 
 def test_deserialize_asset_movement_deposit(mock_bitfinex):
-    currency_map = {'WBT': 'WBTC'}
+    mock_bitfinex.currency_map = {'WBT': 'WBTC'}
     raw_result = [
         13105603,
         'WBT',
@@ -820,10 +805,7 @@ def test_deserialize_asset_movement_deposit(mock_bitfinex):
         fee=Fee(FVal('0.00135')),
         link=str(13105603),
     )
-    asset_movement = mock_bitfinex._deserialize_asset_movement(
-        raw_result=raw_result,
-        currency_map=currency_map,
-    )
+    asset_movement = mock_bitfinex._deserialize_asset_movement(raw_result=raw_result)
     assert asset_movement == expected_asset_movement
 
 
@@ -831,7 +813,7 @@ def test_deserialize_asset_movement_withdrawal(mock_bitfinex):
     """Test also both 'address' and 'transaction_id' are None for fiat
     movements.
     """
-    currency_map = {}
+    mock_bitfinex.currency_map = {}
     raw_result = [
         13105603,
         'EUR',
@@ -869,10 +851,7 @@ def test_deserialize_asset_movement_withdrawal(mock_bitfinex):
         fee=Fee(FVal('0.00135')),
         link=str(13105603),
     )
-    asset_movement = mock_bitfinex._deserialize_asset_movement(
-        raw_result=raw_result,
-        currency_map=currency_map,
-    )
+    asset_movement = mock_bitfinex._deserialize_asset_movement(raw_result=raw_result)
     assert asset_movement == expected_asset_movement
 
 
@@ -895,13 +874,8 @@ def test_query_online_deposits_withdrawals_case_1(mock_bitfinex):
     Movements with id 1, 2 and 4 are expected to be returned.
     """
     api_limit = 2
-    response = Response()
-    response.status_code = HTTPStatus.OK
-    currency_map_response = CurrencyMapResponse(
-        success=True,
-        response=response,
-        currency_map={'WBT': 'WBTC'},
-    )
+    mock_bitfinex.first_connection = MagicMock()
+    mock_bitfinex.currency_map = {'WBT': 'WBTC'}
     # Deposit WBTC
     movement_1 = """
     [
@@ -1077,11 +1051,6 @@ def mock_api_query_response(endpoint, options):  # pylint: disable=unused-argume
         return MockResponse(HTTPStatus.OK, next(get_response))
 
     get_response = get_paginated_response()
-    currency_map_patch = patch.object(
-        target=mock_bitfinex,
-        attribute='_query_currency_map',
-        return_value=currency_map_response,
-    )
     api_limit_patch = patch(
         target='rotkehlchen.exchanges.bitfinex.API_MOVEMENTS_MAX_LIMIT',
         new=api_limit,
@@ -1093,7 +1062,6 @@ def mock_api_query_response(endpoint, options):  # pylint: disable=unused-argume
     )
     with ExitStack() as stack:
         stack.enter_context(api_limit_patch)
-        stack.enter_context(currency_map_patch)
         api_query_mock = stack.enter_context(api_query_patch)
         asset_movements = mock_bitfinex.query_online_deposits_withdrawals(
             start_ts=Timestamp(0),
@@ -1160,13 +1128,8 @@ def test_query_online_deposits_withdrawals_case_2(mock_bitfinex):
     Trades with id 1 to 4 are expected to be returned.
     """
     api_limit = 2
-    response = Response()
-    response.status_code = HTTPStatus.OK
-    currency_map_response = CurrencyMapResponse(
-        success=True,
-        response=response,
-        currency_map={'WBT': 'WBTC'},
-    )
+    mock_bitfinex.first_connection = MagicMock()
+    mock_bitfinex.currency_map = {'WBT': 'WBTC'}
     # Deposit WBTC
     movement_1 = """
     [
@@ -1290,11 +1253,6 @@ def mock_api_query_response(endpoint, options):  # pylint: disable=unused-argume
         return MockResponse(HTTPStatus.OK, next(get_response))
 
     get_response = get_paginated_response()
-    currency_map_patch = patch.object(
-        target=mock_bitfinex,
-        attribute='_query_currency_map',
-        return_value=currency_map_response,
-    )
     api_limit_patch = patch(
         target='rotkehlchen.exchanges.bitfinex.API_MOVEMENTS_MAX_LIMIT',
         new=api_limit,
@@ -1306,7 +1264,6 @@ def mock_api_query_response(endpoint, options):  # pylint: disable=unused-argume
     )
     with ExitStack() as stack:
         stack.enter_context(api_limit_patch)
-        stack.enter_context(currency_map_patch)
         stack.enter_context(api_query_patch)
         asset_movements = mock_bitfinex.query_online_deposits_withdrawals(
             start_ts=Timestamp(0),