質押挖礦系統開發(流程解析) | 質押挖礦系統開發(原始碼演示)

v_ch3nguang發表於2023-04-10

質押挖礦是將質押的代幣存入礦池中,礦池每分鐘或每個新區塊產生一些獎勵代幣,這些獎勵代幣按照流動性提供者質押的代幣份額分發給LP 。通俗來說,就是質押代幣,獲得其他代幣的獎勵。

 

質押挖礦原理(計算使用者得到多少收益)

1. 計算礦池中每秒產生的獎勵代幣數量(相當於速率)

rewardRate = 獎勵代幣總數 / 質押時長

2. 計算每單位質押代幣所得到的獎勵代幣

rewardPerToken = rewardRate / 此時礦池中質押代幣的總數

3. 計算某個使用者得到的收益 —— 遍歷所有質押的使用者,得到每個使用者質押代幣的份額

rewards = rewardPerToken * 某個使用者質押代幣的份額

 

可以根據 最後一次獎勵時間和開始質押時間來計算A 使用者的挖礦獎勵

假設 a   表示每秒產生的獎勵代幣數量(是3.1 當中的 rewardRate

P 表示此時礦池質押代幣的總數

a/P 表示每單位質押代幣所獲得的獎勵代幣

Tn 表示第n 分鐘開始的時候,累計的每質押代幣可以分配的獎勵之和,即 :Tn = a / P1 + a / P2 + a / P3 + … + a / Pn

 

原始碼分析

一共有四個合約,分別如下:

LPToken.sol : 表示質押代幣

rewardToken.sol : 表示獎勵代幣

stakeFactory.sol : 表示工廠合約,主要是部署質押合約

staking.sol : 表示質押合約,主要是一些相關函式

LPToken.sol rewardToken.sol   就是主要是繼承ERC20 合約,用於建立質押代幣和獎勵代幣,接下來就不介紹這兩個合約,主要介紹 stakeFactory.sol staking.sol

4.1 staking.sol

該合約主要是實現質押挖礦過程中所用到的功能。

 

匯入的依賴

 

import   "./rewardTokens.sol" ; import   "./LPToken.sol" ; import   "@openzeppelin/contracts/utils/math/Math.sol" ; import   "@openzeppelin/contracts/utils/math/SafeMath.sol" ; 複製程式碼

 

定義變數和常量

 

rewardUNITokens   建立獎勵代幣物件,一般是UNI 平臺幣

stakingLPTokens   :建立質押代幣物件,一般是LPtoken

stakingFinishTime = block.timestamp + stakingTime  : 質押挖礦結束時間

stakingTime  : 質押時長

_totalSupply : 礦池中質押代幣總量

rewardPerTokenStored : 儲存每單位質押代幣獲取的收益

lastUpdateTime  : 上一次更新時間

    rewardTokens public  rewardUNITokens;

    LPToken public  stakingLPTokens;

     uint   public  stakingFinishTime = block.timestamp + stakingTime;

     uint   public  stakingTime;

     uint   public  rewardRate = 100 ;

     uint   private  _totalSupply;

     uint   public  rewardPerTokenStored;

     uint   public  lastUpdateTime; 複製程式碼

 

對映

 

rewards : 使用者地址 => 使用者獲得的收益

balances : 使用者地址 => 使用者質押代幣數量

userRewardsPerToken : 使用者地址 => 每單位質押代幣獲取的收益數

    mapping( address  => uint) public rewards ;

    mapping( address  => uint) public balances ;

    mapping( address  => uint) public userRewardsPerToken ; 複製程式碼

 

事件

 

Stake : 儲存質押者地址和質押了多少代幣

Withdraw : 儲存此時取回收益的使用者地址和取出獎勵代幣數目

Rewards : 儲存使用者地址和對應的獎勵總數

     event Stake(address sender,uint amounts) ;

     event Withdraw(address recipient,uint amounts) ;

     event Rewards(address recipient,uint amounts) ; 複製程式碼

 

建構函式和修飾器

 

1. 建構函式初始化傳入的引數分別為  _rewardUNITokens`` _stakingLPTokens  _stakingTime ,對應的含義是 獎勵代幣地址,質押代幣地址,質押時長

2. modifier 用於修飾後面的 stake() withdraw() getRewards() 三個函式(這三個函式改變了礦池的狀態),用於更新一些變數包括 上一次狀態改變的時間,使用者操作之前得到每token 獎勵代幣數量,兩個對映函式

    constructor(address _rewardUNITokens,address _stakingLPTokens,uint _stakingTime){

         rewardUNITokens  = rewardTokens(_rewardUNITokens) ;

         stakingLPTokens  = LPToken(_stakingLPTokens) ;

         stakingTime  = _stakingTime ;

    }

    modifier update(address owner) {

         lastUpdateTime  = getLastTime() ;

         rewardPerTokenStored  = rewardUNIPerToken() ;

        if(owner != address(0)){

            userRewardsPerToken [owner]  = rewardPerTokenStored ;

            rewards [owner]  = allRewardsOfUser(owner) ;

        }

         ;

    }

 

 


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70028290/viewspace-2944744/,如需轉載,請註明出處,否則將追究法律責任。

相關文章