这个玩法有意思的地方在于越早参与获得的奖励越多,相当于普通的挖头矿,但是同时也取决于总体的参与人数,如果后面没有人参与,那么也没啥意义。必须是参与的早且后面还有更多人参与的情况下,奖励才会更多。
原文作者:xyyme.eth
原文来源:mirror
这两天 XEN 特别火,看了看代码,相对比较简单。这篇文章就来结合文档来解读一下合约代码,仅做学习交流用。对于玩法还不熟悉的朋友可以先看看我昨天发的推文。
整个玩法分成两部分,我这里将其区别为:
先来看第一部分,时间挖矿。用户通过调用 claimRank(uint256 term) 来参与,term 代表用户想要挖矿的天数,在这个时间到期之后才能领取 XEN 奖励。
其中全局变量 globalRank 代表的是全局参与的总人数,只增不减。activeMinters 代表正在参与挖矿的人数,当用户参与时间挖矿时增加 1,到期领取奖励后减少 1。userMints 代表用户的挖矿参数。我们看到,这里最短需要参与一天,最多参与的天数是通过 _calculateMaxTerm() 实时计算出来的。
首先如果全部参与人数没有超过 5000,那么最多只能挖 100 天。如果达到了 5000,通过对参与人数进行对数运算,计算出对应的最大天数。对应于文档中的:
最大参与时间计算公式
代码中的 fromUInt() 和 log_2() 都来自于 ABDKMath64x64 库(代码)。其中 fromUInt() 的代码:
入参 x 有限制,这个最大值转换为 10 进制是 9223372036854775807,全部参与人数不可能超过这个数,所有可以安全使用。
在构造的挖矿系数 mintInfo 中,_calculateRewardAmplifier() 和 _calculateEAARate() 也是实时计算的。
可以看到,越早参与,可以获得到的 AMP 就越多,最开始一天是 3000,每过一天会减少 1,最终超过 3000 天就会恒定为 1。
对应于文档中 AMP 的计算方式:
AMP 计算公式
从 100 开始,每当有 十万人 参与时,下降 1,最终若达到 一千万人 参与,则恒定为 0。同样也是越早参与越好。对应于文档:
EAA 计算公式
由于 Solidity 中没有小数,因此在代码中将其放大了 1000 倍,后面在 getGrossReward 方法中会再缩小 1000 倍。
到这里,我们可以看到,在用户参与时间挖矿时,已经确定的数据有
接下来我们来看用户领取奖励时的方法 claimMintReward():
校验限制后,计算可得奖励数量,然后 _mint 给用户,计算奖励数量的主要计算逻辑在 _calculateMintReward() 中:
这里我们先忽略 penalty 这一块,其他部分的计算正好对应于文档中的:
时间挖矿奖励数量计算公式
在计算最终奖励数量的时候,自己参与的位置越靠前,后面的人越多,那么
cRG - cRu
就会越大,同样说明越早参与越好。
我们再来看 penalty 这部分,这块其实就是系统限制用户必须在到期后一定时间内领取走,如果没有领取则会随着时间越来越少,最终归零。
对应于文档中的扣除比例:
扣除比例时间关系
文档中显示超过七天就全部不能领取,但是代码中显示最多只会扣除 99%。
到这里,我们就介绍完了时间挖矿的代码部分,接下来我们来看看 stake 挖矿的部分。
这里的 stake 其实比常见的挖矿计算逻辑要简单。常见的挖矿 APY 是根据用户质押数量占比以及参与时间来计算的,属于随挖随走类型的。而这里的 stake 挖矿的 APY 在参与时就已经固定了,且需要在参与时就指定参与时间,在时间到期后才能领取奖励,如果没有到期就领取,只能取回本金,没有任何的奖励。
用户可以在前面时间挖矿到期时调用 claimMintRewardAndStake 同时领取奖励并进行 stake,或者单独调用 stake(uint256 amount, uint256 term) 进行 stake 挖矿:
整体的逻辑也比较简单,参与的时候需要指定时间 term。有一个小细节是在 stake 的时候直接 burn 掉了用户的 token,而不是通过转账的方法,这样可以少一步授权操作。由于合约本身既包含了挖矿操作,同时也是 ERC20,因此可以实现这个逻辑。
接下来我们看看计算 APY 的方法 _calculateAPY():
基本逻辑也是类似于上面计算 EAA 的方法,一次函数递减,参与的时间越早,相对应的 APY 就越大。初始值为 20,每过 90 天,减少 1。最终在 1620 天后,恒定为 2。对应于文档:
APY 时间关系
最终在 stake 到期后,可以调用 withdraw() 取出本金和奖励:
其中计算奖励数量的方法 _calculateStakeReward():
对应于文档中的:
stake 奖励计算公式
对于 stake 挖矿而言,没有领取的限制,奖励数量不会变化。
到这里我们就看完了主要的逻辑代码。这个玩法有意思的地方在于越早参与获得的奖励越多,相当于普通的挖头矿,但是同时也取决于总体的参与人数,如果后面没有人参与,那么也没啥意义。必须是参与的早且后面还有更多人参与的情况下,奖励才会更多。目前时刻总参与人数已经快达到 50 万了,热度确实很高。
同时,前面的时间挖矿和后面的 stake 挖矿也存在博弈关系,如果前面选择的时间越长,获得的奖励就越多,但是来到后面的 stake 挖矿的 APY 就会降低,需要大家自行抉择。
合约本身代码没啥难度,但是整体机制比较有趣,值得花点时间了解。
责任编辑:MK