Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Token address processing fixes #358

Merged
merged 2 commits into from
Dec 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions apps/dashboard_app/helpers/load_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
get_supply_stats,
get_utilization_stats,
)
from dashboard_app.helpers.tools import get_prices
from dashboard_app.helpers.tools import add_leading_zeros, get_prices

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -54,7 +54,9 @@ def _init_zklend_state(self) -> ZkLendState:
logger.info("Initializing ZkLend state.")
zklend_state = ZkLendState()
start = monotonic()
zklend_data = self.data_connector.fetch_data(self.data_connector.ZKLEND_SQL_QUERY)
zklend_data = self.data_connector.fetch_data(
self.data_connector.ZKLEND_SQL_QUERY
)
zklend_interest_rate_data = self.data_connector.fetch_data(
self.data_connector.ZKLEND_INTEREST_RATE_SQL_QUERY
)
Expand Down Expand Up @@ -114,7 +116,7 @@ def _set_underlying_addresses_to_decimals(self):
)
self.underlying_addresses_to_decimals.update(
{
x.address: int(math.log10(x.decimal_factor))
add_leading_zeros(x.address): int(math.log10(x.decimal_factor))
for x in TOKEN_SETTINGS.values()
}
)
Expand Down
78 changes: 50 additions & 28 deletions apps/dashboard_app/helpers/protocol_stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from collections import defaultdict
from decimal import Decimal

import numpy as np
import pandas as pd
from data_handler.handlers import blockchain_call
from shared.constants import TOKEN_SETTINGS
Expand All @@ -16,7 +17,11 @@
get_protocol,
get_supply_function_call_parameters,
)
from dashboard_app.helpers.tools import get_addresses, get_underlying_address
from dashboard_app.helpers.tools import (
add_leading_zeros,
get_addresses,
get_underlying_address,
)


def get_general_stats(
Expand Down Expand Up @@ -116,7 +121,11 @@ def get_supply_stats(
df = pd.DataFrame(data)
df["Total supply (USD)"] = sum(
df[column]
* Decimal(prices[TOKEN_SETTINGS[column.replace(" supply", "")].address])
* Decimal(
prices[
add_leading_zeros(TOKEN_SETTINGS[column.replace(" supply", "")].address)
djeck1432 marked this conversation as resolved.
Show resolved Hide resolved
]
)
for column in df.columns
if "supply" in column
).apply(lambda x: round(x, 4))
Expand Down Expand Up @@ -248,35 +257,48 @@ def get_utilization_stats(
) -> pd.DataFrame:
"""
Get utilization stats for the dashboard.
:param stats: DataFrame containing
general_stats, supply_stats, debt_stat.
:param general_stats: DataFrame containing general stats.
:param supply_stats: DataFrame containing supply stats.
:param debt_stats: DataFrame containing debt stats.
:return: DataFrame with utilization stats
"""

general_stats.columns = general_stats.columns.str.lower()
supply_stats.columns = supply_stats.columns.str.lower()
debt_stats.columns = debt_stats.columns.str.lower()

required_columns_general = {"protocol", "total debt (usd)"}
required_columns_supply = {"total supply (usd)"}
if not required_columns_general.issubset(
general_stats.columns
) or not required_columns_supply.issubset(supply_stats.columns):
return pd.DataFrame()

data = pd.DataFrame(
{
"Protocol": general_stats["Protocol"],
"Total utilization": general_stats["Total debt (USD)"]
/ (general_stats["Total debt (USD)"] + supply_stats["Total supply (USD)"]),
"ETH utilization": debt_stats["ETH debt"]
/ (supply_stats["ETH supply"] + debt_stats["ETH debt"]),
"WBTC utilization": debt_stats["WBTC debt"]
/ (supply_stats.get("WBTC supply") + debt_stats.get("WBTC debt")),
"USDC utilization": debt_stats["USDC debt"]
/ (supply_stats["USDC supply"] + debt_stats["USDC debt"]),
"DAI utilization": debt_stats["DAI debt"]
/ (supply_stats["DAI supply"] + debt_stats["DAI debt"]),
"USDT utilization": debt_stats["USDT debt"]
/ (supply_stats["USDT supply"] + debt_stats["USDT debt"]),
"wstETH utilization": debt_stats["wstETH debt"]
/ (supply_stats["wstETH supply"] + debt_stats["wstETH debt"]),
"LORDS utilization": debt_stats["LORDS debt"]
/ (supply_stats["LORDS supply"] + debt_stats["LORDS debt"]),
"STRK utilization": debt_stats["STRK debt"]
/ (supply_stats["STRK supply"] + debt_stats["STRK debt"]),
},
"Protocol": general_stats["protocol"],
}
)
utilization_columns = [x for x in data.columns if "utilization" in x]
# NOTE: .map doesn't work for some reason. apply works
data[utilization_columns] = data[utilization_columns].apply(lambda x: x.round(4))
# data[utilization_columns] = data[utilization_columns].map(lambda x: round(x, 4))

total_debt = general_stats["total debt (usd)"].astype(float)
total_supply = supply_stats["total supply (usd)"].astype(float)
total_utilization = total_debt / (total_debt + total_supply)
total_utilization = total_utilization.replace([np.inf, -np.inf], 0).fillna(0)
data["Total utilization"] = total_utilization.round(4)

tokens = ["eth", "wbtc", "usdc", "dai", "usdt", "wsteth", "lords", "strk"]
djeck1432 marked this conversation as resolved.
Show resolved Hide resolved

for token in tokens:
debt_col = f"{token} debt"
supply_col = f"{token} supply"

if debt_col in debt_stats.columns and supply_col in supply_stats.columns:
debt = debt_stats[debt_col].astype(float)
supply = supply_stats[supply_col].astype(float)
utilization = debt / (debt + supply)
utilization = utilization.replace([np.inf, -np.inf], 0).fillna(0)
data[f"{token.upper()} utilization"] = utilization.round(4)
else:
data[f"{token.upper()} utilization"] = 0.0

return data
23 changes: 8 additions & 15 deletions apps/dashboard_app/helpers/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def get_collateral_token_range(
collateral_token_price: float,
) -> list[float]:
"""
Generates a range of prices for a collateral token and
Generates a range of prices for a collateral token and
Returns: A list of float values representing the range of prices for the collateral token.
"""
target_number_of_values = 50
Expand All @@ -54,7 +54,7 @@ def get_collateral_token_range(
difference = [
abs(50 - stop_price / (k * magnitude)) for k in step_factors
] # Stores the difference between the target value and
#number of values generated from each step factor.
# number of values generated from each step factor.
readable_step = (
step_factors[difference.index(min(difference))] * magnitude
) # Gets readable step from step factor with values closest to the target value.
Expand Down Expand Up @@ -98,19 +98,9 @@ def get_prices(token_decimals: dict[str, int]) -> dict[str, float]:

tokens_info = response.json()

# Define the addresses for which you do not want to apply add_leading_zeros
skip_leading_zeros_addresses = {
TOKEN_SETTINGS["STRK"].address,
}

# Create a map of token addresses to token information, applying add_leading_zeros conditionally
token_info_map = {
(
token["address"]
if token["address"] in skip_leading_zeros_addresses
else add_leading_zeros(token["address"])
): token
for token in tokens_info
add_leading_zeros(token["address"]): token for token in tokens_info
}

prices = {}
Expand All @@ -123,8 +113,11 @@ def get_prices(token_decimals: dict[str, int]) -> dict[str, float]:

if decimals != token_info.get("decimals"):
logging.error(
"Decimal mismatch for token %s: expected %d, got %d"
,token, decimals, token_info.get('decimals'))
"Decimal mismatch for token %s: expected %d, got %d",
token,
decimals,
token_info.get("decimals"),
)
continue

prices[token] = token_info.get("currentPrice")
Expand Down