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

Update S5 methodology #68

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
10 changes: 9 additions & 1 deletion backends/redoubt/tokens.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,13 @@ def _do_calculate(self, config: SeasonConfig, dry_run: bool = False):
and build_time < to_timestamp({config.start_time}) - interval '14 day' -- end of the S4 season
order by thd.address, build_time desc
), tvl_prior_start as (
select symbol, sum(tvl_ton) as start_tvl from tvl_prior_start_all
select symbol, sum(tvl_ton) as start_tvl,
(
select rate from ton_usd_rates
where build_time < to_timestamp({config.start_time}) - interval '14 day'
order by build_time desc limit 1
) * sum(tvl_ton) as start_tvl_usd
from tvl_prior_start_all
group by 1
), current_tvl as (
-- TVL during the season
Expand Down Expand Up @@ -116,6 +122,7 @@ def _do_calculate(self, config: SeasonConfig, dry_run: bool = False):
prizes,
url, boost_link,
coalesce(start_tvl, 0) as start_tvl,
coalesce(start_tvl_usd, 0) as start_tvl_usd,
coalesce(last_tvl.tvl, 0) as last_tvl,
coalesce(100 * coalesce(price_change, 0), 0) as price_delta,
coalesce(price_before, 0) as price_before,
Expand Down Expand Up @@ -148,6 +155,7 @@ def _do_calculate(self, config: SeasonConfig, dry_run: bool = False):
results[row['symbol']].metrics[ProjectStat.TOKEN_IS_MEME] = row['is_meme']
results[row['symbol']].metrics[ProjectStat.TOKEN_HAS_BOOST] = row['has_boost']
results[row['symbol']].metrics[ProjectStat.TOKEN_START_TVL] = int(row['start_tvl'])
results[row['symbol']].metrics[ProjectStat.TOKEN_START_TVL_USD] = int(row['start_tvl_usd'])
results[row['symbol']].metrics[ProjectStat.TOKEN_LAST_TVL] = int(row['last_tvl'])
results[row['symbol']].metrics[ProjectStat.TOKEN_PRICE_BEFORE] = float(row['price_before'])
results[row['symbol']].metrics[ProjectStat.TOKEN_PRICE_AFTER] = float(row['price_after'])
Expand Down
2 changes: 2 additions & 0 deletions models/results.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ class ProjectStat:
APP_ONCHAIN_UAW = 'onchain_uaw'
APP_ONCHAIN_MEDIAN_TX = 'onchain_median_tx'

TOKEN_TVL_CATEGORY = 'token_tvl_category'
TOKEN_TVL_CHANGE = 'token_tvl_change'
TOKEN_START_TVL = 'token_start_tvl'
TOKEN_START_TVL_USD = 'token_start_tvl_usd'
TOKEN_LAST_TVL = 'token_last_tvl'
TOKEN_PRICE_BEFORE = 'token_price_before'
TOKEN_PRICE_AFTER = 'token_price_after'
Expand Down
28 changes: 24 additions & 4 deletions seasons/tokens_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,38 @@ def calculate(self, metrics: List[ProjectStat]):


"""
Token leaderboard score model, launched since S5. The only metrics is price change
Token leaderboard score model, launched since S5
30% - base TVL Delta weight
40% - base New holders weight
30% - base Price change (normalised on sqrt(TVL)) weight
"""
class TokenLeaderboardModelV5(ScoreModel):
def __init__(self):
super().__init__()
self.params[ScoreModel.PARAM_TOKEN_MIN_VALUE_FOR_NEW_HOLDER] = 1.0 # 1 TON
self.tvl_category = {
"10M – 20M": {"low": 10_000_000, "high": None, "coefficient": 1},
"5M – 10M": {"low": 5_000_000, "high": 10_000_000, "coefficient": 0.8},
"2M – 5M": {"low": 2_000_000, "high": 5_000_000, "coefficient": 0.6},
"1M – 2M": {"low": 1_000_000, "high": 2_000_000, "coefficient": 0.5},
"500K – 1M": {"low": 500_000, "high": 1_000_000, "coefficient": 0.4},
"100K – 500K": {"low": None, "high": 500_000, "coefficient": 0.3},
}

def get_tvl_category(self, tvl_value) -> str:
for category_name, limits in self.tvl_category.items():
if (not limits["low"] or tvl_value > limits["low"]) and (not limits["high"] or tvl_value <= limits["high"]):
return category_name

def calculate(self, metrics: List[ProjectStat]):
MIN_TVL = 14106 # $100,000 nominated in TON
for project in metrics:
logger.info(f"Calculating score for {project}")
project.score = project.metrics[ProjectStat.TOKEN_LAST_TVL] - \
max(MIN_TVL, project.metrics[ProjectStat.TOKEN_START_TVL])
project.metrics[ProjectStat.TOKEN_TVL_CATEGORY] = self.get_tvl_category(project.metrics[ProjectStat.TOKEN_START_TVL_USD])
price_change_weight = 30 * self.tvl_category[project.metrics[ProjectStat.TOKEN_TVL_CATEGORY]]["coefficient"]
tvl_change_weight = 30 + (30 - price_change_weight) * 3 / 7
new_holders_weight = 40 + (30 - price_change_weight) * 4 / 7
project.score = new_holders_weight * self.normalized_max(project, ProjectStat.TOKEN_NEW_USERS_WITH_MIN_AMOUNT, metrics) + \
tvl_change_weight * self.normalized_min_max(project, ProjectStat.TOKEN_TVL_CHANGE, metrics) + \
price_change_weight * self.normalized_min_max(project, ProjectStat.TOKEN_PRICE_CHANGE_NORMED, metrics)

return sorted(metrics, key=lambda m: m.score, reverse=True)
Loading