Repository: rotki/rotki

Issue:
urlencode and non-string values
## Problem Definition

In various places in the code we are using urlencode. urlencode only encodes string or bytes values. This is something counter-intuitive for developer who would expect it to properly encode things like:

```python
True -> 'true'
False -> 'false'
None -> 'null'
```

In reality it just stringifies the above. So it does:


```python
True -> 'True'
False -> 'False'
None -> 'None'
```

## Task

Check all usages of urlencode() and make sure that it's used properly and only encodes string arguments. At least 1 place in coingecko uses booleans:

https://github.com/rotki/rotki/blob/13caf168311355f23eadb381197ef89db2a9f4f4/rotkehlchen/externalapis/coingecko.py#L432

This results in the value being ignored and for example all of our coingecko queries return all data that we do not require (social, internationalization etc).

Compare:
https://api.coingecko.com/api/v3/coins/ethereum?localization=False&tickers=False&market_data=False&community_data=False&developer_data=False&sparkline=False
https://api.coingecko.com/api/v3/coins/ethereum?localization=false&tickers=false&market_data=false&community_data=false&developer_data=false&sparkline=false


Discussion:

Resolving patch:
diff --git a/rotkehlchen/exchanges/iconomi.py b/rotkehlchen/exchanges/iconomi.py
--- a/rotkehlchen/exchanges/iconomi.py
+++ b/rotkehlchen/exchanges/iconomi.py
@@ -322,7 +322,7 @@ def query_online_trade_history(
         all_transactions = []
 
         while True:
-            resp = self._api_query('get', 'user/activity', {"pageNumber": str(page)})
+            resp = self._api_query('get', 'user/activity', {'pageNumber': str(page)})
 
             if len(resp['transactions']) == 0:
                 break
diff --git a/rotkehlchen/exchanges/poloniex.py b/rotkehlchen/exchanges/poloniex.py
--- a/rotkehlchen/exchanges/poloniex.py
+++ b/rotkehlchen/exchanges/poloniex.py
@@ -485,7 +485,7 @@ def return_deposits_withdrawals(
     @cache_response_timewise()
     def query_balances(self) -> ExchangeQueryBalances:
         try:
-            resp = self.api_query_dict('returnCompleteBalances', {"account": "all"})
+            resp = self.api_query_dict('returnCompleteBalances', {'account': 'all'})
         except RemoteError as e:
             msg = (
                 'Poloniex API request failed. Could not reach poloniex due '
diff --git a/rotkehlchen/externalapis/coingecko.py b/rotkehlchen/externalapis/coingecko.py
--- a/rotkehlchen/externalapis/coingecko.py
+++ b/rotkehlchen/externalapis/coingecko.py
@@ -343,7 +343,7 @@ def _query(
             self,
             module: Literal['coins/list'],
             subpath: Optional[str] = None,
-            options: Optional[Dict[str, Any]] = None,
+            options: Optional[Dict[str, str]] = None,
     ) -> List[Dict[str, Any]]:
         ...
 
@@ -352,7 +352,7 @@ def _query(
             self,
             module: Literal['coins', 'simple/price'],
             subpath: Optional[str] = None,
-            options: Optional[Dict[str, Any]] = None,
+            options: Optional[Dict[str, str]] = None,
     ) -> Dict[str, Any]:
         ...
 
@@ -360,7 +360,7 @@ def _query(
             self,
             module: str,
             subpath: Optional[str] = None,
-            options: Optional[Dict[str, Any]] = None,
+            options: Optional[Dict[str, str]] = None,
     ) -> Union[Dict[str, Any], List[Dict[str, Any]]]:
         """Performs a coingecko query
 
@@ -431,17 +431,17 @@ def asset_data(self, asset: Asset) -> CoingeckoAssetData:
         """
         options = {
             # Include all localized languages in response (true/false) [default: true]
-            'localization': False,
+            'localization': 'false',
             # Include tickers data (true/false) [default: true]
-            'tickers': False,
+            'tickers': 'false',
             # Include market_data (true/false) [default: true]
-            'market_data': False,
+            'market_data': 'false',
             # Include communitydata (true/false) [default: true]
-            'community_data': False,
+            'community_data': 'false',
             # Include developer data (true/false) [default: true]
-            'developer_data': False,
+            'developer_data': 'false',
             # Include sparkline 7 days data (eg. true, false) [default: false]
-            'sparkline': False,
+            'sparkline': 'false',
         }
         gecko_id = asset.to_coingecko()
         data = self._query(
@@ -604,7 +604,7 @@ def query_historical_price(
             subpath=f'{from_coingecko_id}/history',
             options={
                 'date': date,
-                'localization': False,
+                'localizatioen': 'false',
             },
         )
 


Test patch: