#奖励 #分享 # #模块 #存储 #管理 #领取

无需 std orml-rewards

存储和管理份额及奖励

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 魔法豆

Download history 137/week @ 2024-04-15 5/week @ 2024-05-20 155/week @ 2024-06-03 9/week @ 2024-06-10 167/week @ 2024-06-24 2/week @ 2024-07-01 207/week @ 2024-07-29

每月下载量 209

Apache-2.0GPL-3.0-only

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