forked from ton-society/the-open-league
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdefi_models.py
107 lines (88 loc) · 4.08 KB
/
defi_models.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
from typing import Callable, List, Tuple
from models.results import ProjectStat
from models.scores import ScoreModel
from loguru import logger
"""
DeFi Leaderboard rewards calculator. Has two params - total_prize_pool and max_prize per project.
Each project gets reward in accordance with it TVL impact, projects with negative TVL impact
have no rewards
"""
class DeFiWeightedRewards(ScoreModel):
def __init__(self, total_prize_pool, max_prize):
super().__init__()
self.total_prize_pool = total_prize_pool
self.max_prize = max_prize
def calculate(self, metrics: List[ProjectStat]):
total_tvl_delta = 0
for project in metrics:
delta = project.metrics[ProjectStat.DEFI_TVL_DELTA_COUNTED]
if delta > 0 and project.metrics[ProjectStat.PRIZES]:
total_tvl_delta += delta
logger.info(f"Total positive TVL delta is {total_tvl_delta:0.2f}$")
prize_pool = self.total_prize_pool
counted_tvl = 0
for project in sorted(metrics, key=lambda m: m.metrics[ProjectStat.DEFI_TVL_DELTA_COUNTED], reverse=True):
delta = project.metrics[ProjectStat.DEFI_TVL_DELTA_COUNTED]
if total_tvl_delta <=0 or delta < 0 or not project.metrics[ProjectStat.PRIZES]:
reward = 0
else:
reward = min(prize_pool * delta / (total_tvl_delta - counted_tvl), self.max_prize)
counted_tvl += delta
prize_pool -= reward
logger.info(f"Reward for {project.name} is {reward}, counted tvl is {counted_tvl}, "
f"prize pool is {prize_pool}")
logger.info(f"Calculating score for {project}")
project.score = reward
project.metrics[ProjectStat.REWARD] = reward
return sorted(metrics, key=lambda m: m.score, reverse=True)
"""
Returns contributin of positive TVL into overall TVL growth
"""
class DeFiTVLContribution(ScoreModel):
"""
Accepts list of squads ranges, each squad is a tuple with min limit predicate and string
"""
def __init__(self, squads: List[Tuple[Callable[[int], bool], str]]):
super().__init__()
self.squads = squads
def calculate(self, metrics: List[ProjectStat]):
total_tvl_delta = 0
for project in metrics:
delta = project.metrics[ProjectStat.DEFI_TVL_DELTA_COUNTED]
if delta > 0:
total_tvl_delta += delta
logger.info(f"Total positive TVL delta is {total_tvl_delta:0.2f}$")
for project in metrics:
delta = project.metrics[ProjectStat.DEFI_TVL_DELTA_COUNTED]
tvl = project.metrics[ProjectStat.DEFI_TVL_AFTER_COUNTED]
project.metrics[ProjectStat.DEFI_SQUAD] = next(filter(lambda s: s[0](tvl), self.squads))[1]
if delta > 0 and total_tvl_delta > 0:
project.score = 100.0 * delta / total_tvl_delta
else:
project.score = 0
return sorted(metrics, key=lambda m: m.score, reverse=True)
"""
Returns contributin of trading volume into overall trading volume
"""
class DeFiVolumeContribution(ScoreModel):
"""
Accepts list of squads ranges, each squad is a tuple with min limit predicate and string
"""
def __init__(self, squads: List[Tuple[Callable[[int], bool], str]]):
super().__init__()
self.squads = squads
def calculate(self, metrics: List[ProjectStat]):
total_volme = 0
for project in metrics:
volume = project.metrics[ProjectStat.DEFI_VOLUME_USD]
# assert volume > 0
total_volme += volume
logger.info(f"Total trading volume is {total_volme:0.2f}$")
for project in metrics:
volume = project.metrics[ProjectStat.DEFI_VOLUME_USD]
project.metrics[ProjectStat.DEFI_SQUAD] = next(filter(lambda s: s[0](volume), self.squads))[1]
if total_volme > 0:
project.score = 100. * volume / total_volme
else:
project.score = 0
return sorted(metrics, key=lambda m: m.score, reverse=True)