16 个版本 (1 个稳定版)
1.0.0 | 2024年8月1日 |
---|---|
0.13.0 | 2024年6月26日 |
0.12.0 | 2024年6月3日 |
0.8.0 | 2024年3月18日 |
0.3.2 | 2020年10月22日 |
#808 in 魔法豆
每月下载量 209
115KB
2.5K SLoC
奖励模块
此模块公开了质押奖励的功能。
单一资产算法
考虑一个只有一个奖励资产的单一池,一般情况下,它将表现得如下
from collections import defaultdict
pool = {}
pool["shares"] = 0
pool["rewards"] = 0
pool["withdrawn_rewards"] = 0
users = defaultdict(lambda: dict(shares = 0, withdrawn_rewards = 0))
def inflate(pool, user_share):
return 0 if pool["shares"] == 0 else pool["rewards"] * (user_share / pool["shares"])
def add_share(pool, users, user, user_share):
# virtually we add more rewards, but claim they were claimed by user
# so until `rewards` grows, user will not be able to claim more than zero
to_withdraw = inflate(pool, user_share)
pool["rewards"] = pool["rewards"] + to_withdraw
pool["withdrawn_rewards"] = pool["withdrawn_rewards"] + to_withdraw
pool["shares"] += user_share
user = users[user]
user["shares"] += user_share
user["withdrawn_rewards"] += to_withdraw
def accumulate_reward(pool, amount):
pool["rewards"] += amount
def claim_rewards(pool, users, user):
user = users[user]
inflation = inflate(pool, user["shares"])
to_withdraw = min(inflation - user["withdrawn_rewards"], pool["rewards"] - pool["withdrawn_rewards"])
pool["withdrawn_rewards"] += to_withdraw
user["withdrawn_rewards"] += to_withdraw
return to_withdraw
证明
我们想要证明当添加新的份额时,不会稀释之前的奖励。
在奖励积累之后添加份额的用户,将不会获得之前奖励的任何部分。
设 $R_n$ 为当前奖励资产的数量。
设 $s_i$ 为 $m$ 个总用户中的任意特定用户的质押。
用户当前奖励份额等于
$$ r_i = R_n * ({s_i} / {\sum_{i=1}^m s_i}) $$
用户 $m + 1$ 带来他的份额,因此
$$r_i' = R_n * ({s_i} / {\sum_{i=1}^{m+1} s_i}) $$
$r_i > r_i'$,因此原始份额被稀释,新用户可以领取现有用户的份额。
如果我们通过增加 $R_n$ 的 $\delta_R$ 来增加奖励池,以使原始用户获得相同的份额。
我们得到
$$ R_n * ({s_i} / {\sum_{i=1}^m s_i}) = ({R_n + \delta_R}) * ({s_i} / {\sum_{i=1}^{m+1} s_i})$$
经过简单的代数简化后,我们得到
$$ \delta_R = R_n * ({s_m}/{\sum_{i=1}^{m} s_i}) $$
因此,对于新的份额,我们增加了奖励池。为了补偿这一点,$\delta_R$ 金额被标记为新的用户从池中提走。
依赖项
~19-34MB
~576K SLoC