美文网首页
Matic 项目质押奖励分析

Matic 项目质押奖励分析

作者: 雪落无留痕 | 来源:发表于2021-09-21 15:07 被阅读0次

本文主要介绍Matic(现为Polygon) 验证者质押、质押代理、奖励分配以及惩罚处理流程。

验证者质押

直接质押

直接质押要求目前验证者人数小于 validatorThreshold, validatorThreshold 初始值为7, 可通过治理更新,目前值为:100。

质押数量需要大于minDeposit, minDeposit 初始值为1 matic, 可通过治理更新, 目前为1 Matic。

质押需要支付手续费用 hemidallFee, 需要大于minHeimdallFee, 其初始值为1matic, 可通过治理更新, 目前为1 matic。

function stake(
    uint256 amount,
    uint256 heimdallFee,
    bool acceptDelegation,
    bytes calldata signerPubkey
) external {
    stakeFor(msg.sender, amount, heimdallFee, acceptDelegation, signerPubkey);
}

质押过程通过NFTContract为验证者铸造validatorId, 验证者从当前周期epoch生效。

若接受代理,则为验证者部署ValidateShare 合约。

竞拍成为验证者

竞拍合约函数:

function startAuction(
    uint256 validatorId,
    uint256 amount,
    bool _acceptDelegation,
    bytes calldata _signerPubkey
) external onlyWhenUnlocked
  • validiatorId 为要挑战的验证者,必须要求其是有效的;
require(
    validators[validatorId].deactivationEpoch == 0 && currentValidatorAmount != 0,
    "Invalid validator for an auction"
);
  • 验证者不能挑战另外一个验证者。

  • 要求过了冷却期:replacementCoolDown; 每次更新dynasty时冷静期才会更新, 目前值为:2018083。 目前currentEpoch 值为 18106, 所有还不能参与竞拍。 replacementCoolDown 可以用来控制不是开启竞拍功能。

  • 要求在竞拍期, autionPeriod 目前值为20。

  // (auctionPeriod--dynasty)--(auctionPeriod--dynasty)--(auctionPeriod--dynasty)
  currentEpoch.sub(validators[validatorId].activationEpoch) % dynasty.add(auctionPeriod)) < auctionPeriod
  • Dynasty 为两次竞拍的周期间隔,初始值为886, 可通过治理更新, 目前值为:80
function updateDynastyValue(uint256 newDynasty) public onlyGovernance {
    require(newDynasty > 0);
    logger.logDynastyValueChange(newDynasty, dynasty);
    dynasty = newDynasty;
    WITHDRAWAL_DELAY = newDynasty;
    auctionPeriod = newDynasty.div(4);
    // set cooldown period
    replacementCoolDown = currentEpoch.add(auctionPeriod);
}
  • 保证竞标质押金额同时大于 被挑战的验证者的总质押(加上代理给验证者的质押)和上一个竞标者的质押金额;

增加质押

验证者可以调用restake 增加质押量,或者将奖励转为质押。

function restake(
    uint256 validatorId,
    uint256 amount,
    bool stakeRewards
) public onlyWhenUnlocked onlyStaker(validatorId) 

竞拍确认函数:

function confirmAuctionBid(
    uint256 validatorId,
    uint256 heimdallFee /** for new validator */
) external onlyWhenUnlocked 
  • 要求竞标者或当前验证者触发该函数;

  • 要求必须过了竞拍期:

    _currentEpoch.sub(auction.startEpoch) % auctionPeriod.add(dynasty) >= auctionPeriod
    
  • 若验证者最终质押总量大于竞标者的质押量,则退还竞标者的质押金额;

  • 若竞标者最终胜出,竞标者需要支付手费用:heimdalFee, 从当前周期成为新的验证者。原先验证者开始解除质押。

Heimdall fee

无论验证者经过质押或竞拍成为验证者,都需要支付一定的手续费用Heimdall fee

function _transferAndTopUp(
    address user,
    uint256 fee,
    uint256 additionalAmount
) private {
    require(fee >= minHeimdallFee, "Not enough heimdall fee");
    require(token.transferFrom(msg.sender, address(this), fee.add(additionalAmount)), "Fee transfer failed");
    totalHeimdallFee = totalHeimdallFee.add(fee);
    logger.logTopUpFee(user, fee);
}

minHeimdallFee 初始值为1 Matic, 可通过治理更新, 目前值为1Matic, 推荐大于10。

Heimdall Fee 可以由验证者自己赎回,需要提供Merkle 路径证明,其中accountStateRoot 由每次提交checkpoint时更新。

function claimFee(
    uint256 accumFeeAmount,
    uint256 index,
    bytes memory proof
) public {}

质押退出

function unstake(uint256 validatorId) external onlyStaker(validatorId)
  • 必须在非竞拍期才能调用;

  • 标记开始退出的周期:

    validators[validatorId].deactivationEpoch = exitEpoch;
    
  • 立即返还验证者的奖励;

  • 若存在代理合约的,锁定代理合约,代理者无法再质押。

质押赎回

function unstakeClaim(uint256 validatorId) public onlyStaker(validatorId) 
  • 要求必须经过WITHDRAW_DELAY个周期,其初始值为2^13(8192), 随后可通过dynasty 值设定, 目前值为80。
require(
    deactivationEpoch > 0 &&
        deactivationEpoch.add(WITHDRAWAL_DELAY) <= currentEpoch &&
        validators[validatorId].status != Status.Unstaked
);
  • 销毁验证者的NFT: NFTContract.burn(validatorId);

  • signerToValidator[validators[validatorId].signer] = INCORRECT_VALIDATOR_ID;
    
      通过了设置`INCORRECT_VALIDATOR_ID` 确保该验证者不能再参与竞拍成为验证者,但可以通过直接参与质押成为验证者。
    
  • 设置验证者的状态为:validators[validatorId].status = Status.Unstaked;

  • 立即退还验证者的质押。

代理者质押

验证者给代理者奖励分配采用类似AMM模型的机制,由验证者部署ValidatorShare合约,可以看作发行一定数量的代币,总量为10^10个:

function totalSupply() public view returns (uint256) {
    return 10000000000 * 10**uint256(DECIMALS);
}

然后由代理者根据当前的汇率认购:

ExchangeRate = (totalDelegatedPower + delegatorRewardPool) / totalDelegatorShares

汇率是不断变化的,当验证者不断获取奖励的时候,汇率上升;反之若受到惩罚,奖励汇率下降。

质押

当代理者代理质押matic时候,将matic通过汇率转换为可申购的份额:

function _buyShares(uint256 _amount, uint256 _minSharesToMint) private onlyWhenUnlocked returns(uint256) {}

代理者也可以通过调用restake()将所得到的奖励进行再质押。

退出质押

当代理者退出质押的时候,根据当前汇率售出所拥有的份额:

function sellVoucher(uint256 _minClaimAmount) public {}

注:每次提交checkpoint是一个周期。

质押赎回

质押的退出需要等待 WITHDRAWL_DELAY个周期,即目前为80。

function unstakeClaimTokens() public {
   ...
   require(delegator.withdrawEpoch.add(stakeManager.withdrawalDelay()) <= stakeManager.epoch() && shares > 0, "Incomplete withdrawal period");
   ...
}

奖励

Checkpoint 奖励

CHECKPOINT_REWARD checkpoint奖励的上限,初始为20188个matic, 可以通过治理更新, 目前值为:107163。

checkPointBlockInterval 初始值设为1024,可通过治理更新, 目前值为:5120。

proposerBouns 初始值为10,可通过治理进行更新,值小于等于100,目前值为10:

maxRewardsCheckpoints: 可通过治理更新, 目前值为:3

checkpointRewardDelta : 可通过治理更新,目前值为:10

rewardDecreasePerCheckpoint: 可通过治理更新,目前值为:30

CHK_REWARD_PRECISION: 值为100

计算过程:

计算 fullIntervals:
fullIntervals = Math.min(\frac{blockInterval}{targetBlockInterval}, maxRewardedCheckpoints);
其中 blockInterval为当前是checkpoint的包括的块数, targetBlockInterval = checkpointBlockInterval

chkReward初始值:
ckpReward = CHECKPOINT\_REWARD;
然后计算 delta:
delta = ckpReward * \frac {checkpointRewardDelta}{CHK\_REWARD\_PRECISION};
更新 ckpReward:

// 
if (prevBlockInterval > fullIntervals) {  // 若checkpoint比上次提交的更快
    // checkpoint is faster
    ckpReward += delta;
} else {
    ckpReward -= delta;
}

blockInterval > targetBlockInterval, ckpReward 执行下面的更新:
reward = ckpReward*fullIntervals - ckpReward * \frac{(fullIntervals - 1) * fullIntervals}{2 * CHK\_REWARD\_PRECISION}* rewardDecreasePerCheckpoint \\ \\ blockInterval = blockInterval - fullIntervals * targetBlockInterval \\ \\ ckpReward = ckpReward - \frac{ckpReward * fullIntervals * rewardDecreasePerCheckpoint}{CHK\_REWARD\_PRECISION }
最终该checkPoint 得到 reward 为:
reward = reward + \frac{blockInterval}{targetBlockInterval} * ckpReward \\ reward = reward * \frac{signedStakePower}{currentTotalStake}

提交checkPoint的Bonus分配

proposerBonus = reward * \frac{proposerBonus}{MAX\_PROPOSER\_BONUS}

其中 proposerBonus 为通过治理更新的参数,目前值为10. MAX_PROPOSER_BOUNS 值为100

        proposer.reward = proposer.reward.add(proposerBonus);

proposerBonus奖励全部给予 proposer

剩余奖励分配

主要分为以下三个步骤:

(1) 计算每份质押的奖励
newRewardPerStake = rewardPerStake + (reward - proposerBouns) * \frac{REWARD\_PRECISION}{signedStakePower}
其中 rewardPerStake 为上一个checkpoint执行后得到每份质押的奖励,signedStakePower为此次checkpoint所有签名者的质押。REWARD\_PRECIISION 为固定值, 值为10^{25}, 即 10^{7} matic.

(2) 分发非签名验证者的奖励,并更新initialRewardPerStake

// evaluate rewards for validator who did't sign and set latest reward per stake to new value to avoid them from getting new rewards.
_updateValidatorsRewards(unsignedValidators, totalUnsignedValidators, newRewardPerStake);

(3) 分发签名验证者的奖励

// distribute rewards between signed validators
rewardPerStake = newRewardPerStake;

(4) 分发已经在退出质押的签名验证者的奖励

// evaluate rewards for unstaked validators to avoid getting new rewards until they claim their stake
_updateValidatorsRewards(deactivatedValidators, totalDeactivatedValidators, newRewardPerStake);

代理者奖励

分给完Bonus后,剩余奖励根据质押比例,分别对每个签名验证者根据质押总量比例进行奖励分配;然后每个验证者然后根据其代理者质押比例再进行分配。

    function checkSignature(
        uint256 checkpointStakePower,
        uint256 reward,
        bytes32 voteHash,
        bytes memory sigs
    ) internal returns (uint256)

在手续费commisionRate大于0的情况下,给委托者的奖励需要先扣除手续费,然后再根据质押比较比例分配给代理者。

惩罚机制

惩罚包括两个过程: (1)惩罚作恶验证者;(2)奖励提出者

function updateSlashedAmounts(bytes memory data, bytes memory sigs) public {}

slash

  • 通过slashNonce 防止重复提交。
  • 惩罚需要经过2/3 + 1 质押验证者签名验证;
  • 提交的数据中包括: (1)待惩罚的验证者; (2)惩罚金额;(3)确定是否要关禁闭:jail
  • 惩罚金额直接从验证者的质押金额中扣除, 若存在代理者,则根据质押比例分担惩罚金额,即使有代理正在赎回期,仍要进行处罚。
  • 禁闭时间目前为1个周期,期间无法对checkpoint验证,然后由验证者主动解除禁闭。
     function unjail(uint256 validatorId) public onlyStaker(validatorId)

Bounty

奖励的金额为总的惩罚金额的乘以 reportRate 比例,reportRate 初始值为5, 可由管理员更新,其余到的转到合约中。合约的金额可以由管理员取款。

uint256 bounty = (slashedAmount.mul(reportRate)).div(100);

若调用合约者 和 proposer为不同的地址,则两者均分,否则都转给合约调用者。

参考

https://github.com/maticnetwork/contracts

https://docs.matic.network/docs/validate/orientation/

https://docs.matic.network/docs/develop/network-details/genesis-contracts/

https://etherscan.io/address/0x5e3Ef299fDDf15eAa0432E6e66473ace8c13D908#readProxyContract

https://github.com/itinance/openzeppelin-solidity/blob/master/contracts/token/ERC721/ERC721Enumerable.sol

相关文章

  • Matic 项目质押奖励分析

    本文主要介绍Matic(现为Polygon) 验证者质押、质押代理、奖励分配以及惩罚处理流程。 验证者质押 直接质...

  • Matic 数据流分析

    本文主要分析Matic数据流在 Ethereum <---> Heimdall <---> Bor 中的数据流动过...

  • livepeer提取奖励与解质押流程

    直接拿我的账号举例吧,这个账号质押了10lpt,经过很多天后,得到了1.49的奖励。 解质押在这个页面https:...

  • Matic Network:改进版的Plasma侧链 | BiQ

    [1 ] Rating Profile 评级概要 主要优势 Matic Network(Matic)致力于利用侧链...

  • 以太坊的好基友-Matic,你认识吗?

    币安审核项目严格,这在币圈已经是有口皆碑的事情。其中,币安的第6个Launchpad项目是Matic,上线4个月,...

  • Everipedia(IQ)奖励模型

    Everipedia 对内容管理(投票)和编辑文章给予奖励。用户在系统中投票的权重由“脑力”决定。质押 IQ To...

  • Matic币价暴涨60%,这是为何?

    据最新报道,加密货币交易所Coinbase正在评估上线Matic。此消息一出,Matic币价暴涨60%,并且吸引了...

  • 2019-05-04

    币安LaunchPad第四个代币MATIC:改进版的Plasma侧链 币安LaunchPad第四个代币Matic ...

  • Staking economy质押经济的利与弊

    有的人不太理解质押经济,简单来说,它就象支付宝里的余额宝,Staking就是你把币质押给节点,项目方给予节点一定奖...

  • 7月第2周币圈感悟

    本周感悟分为币圈大势分析、币圈注意事项、板块&项目、操作看法、感悟5个板块。 一、币圈大势分析 1.区块奖励减半,...

网友评论

      本文标题:Matic 项目质押奖励分析

      本文链接:https://www.haomeiwen.com/subject/pgnbgltx.html