[英]Hey Can someone explain something about this Smart contract to me - LP Staking Contract
嘿,所以我正在通過 github 尋找 LP staking 智能合約,我遇到了這個
// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/math/SafeMath.sol";
import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol";
contract StakingV2 is Ownable {
using SafeMath for uint;
using SafeERC20 for IERC20;
struct Stake {
uint amount;
uint stakeTime;
uint fraction;
uint rewardOut;
}
mapping(uint => mapping(address => Stake)) public stakes;
// Info of each pool.
struct Pool {
uint rewardAmount; // Pool reward tokens limit
uint startTime;
uint endTime;
uint total;
uint freezeTime;
uint freezePercent;
}
Pool[] public pools;
address public stakeToken; // Uniswap LP token from pool MRCH/USDT
address public rewardToken; // MRCH token
event AddPool(uint pid, uint reward, uint startTime, uint endTime, uint freezeTime, uint percent);
event PoolTotal(uint pid, uint oldTotal, uint newTotal);
event StakerFraction(uint pid, address staker, uint oldFraction, uint newFraction);
event Staked(uint pid, address staker, uint amount);
event RewardOut(uint pid, address staker, address token, uint amount);
constructor(
address stakeToken_,
address rewardToken_
) {
require(stakeToken_ != address(0), "MRCHStaking::constructor: stake token address is 0x0");
stakeToken = stakeToken_;
require(rewardToken_ != address(0), "MRCHStaking::constructor: reward token address is 0x0");
rewardToken = rewardToken_;
}
function addPool(uint rewardAmount_, uint startTime_, uint endTime_, uint freezeTime_, uint freezePercent_) public onlyOwner {
require(getTimeStamp() <= startTime_, "MRCHStaking::addPool: bad timing for the request");
require(startTime_ < endTime_, "MRCHStaking::addPool: endTime > startTime");
doTransferIn(msg.sender, rewardToken, rewardAmount_);
pools.push(
Pool({
rewardAmount: rewardAmount_,
startTime: startTime_,
endTime: endTime_,
total: 0,
freezeTime: freezeTime_,
freezePercent: freezePercent_ // scaled by 1e18, for example 5% = 5e18, 0.01% = 1e16
})
);
emit AddPool(pools.length - 1, rewardAmount_, startTime_, endTime_, freezeTime_, freezePercent_);
}
function stake(uint pid, uint amount) public returns (bool) {
require(amount > 0, "MRCHStaking::stake: amount must be positive");
uint timeStamp = getTimeStamp();
require(timeStamp < pools[pid].endTime, "MRCHStaking::stake: bad timing for the request");
address staker = msg.sender;
doTransferIn(staker, stakeToken, amount);
// Transfer is completed
stakes[pid][staker].amount = stakes[pid][staker].amount.add(amount);
uint addition;
if (timeStamp < pools[pid].startTime) {
stakes[pid][staker].stakeTime = pools[pid].startTime;
addition = (pools[pid].endTime.sub(pools[pid].startTime)).mul(amount);
} else {
stakes[pid][staker].stakeTime = timeStamp;
addition = (pools[pid].endTime.sub(timeStamp)).mul(amount);
}
uint oldFraction = stakes[pid][staker].fraction;
stakes[pid][staker].fraction = stakes[pid][staker].fraction.add(addition);
uint oldTotal = pools[pid].total;
pools[pid].total = pools[pid].total.add(addition);
emit Staked(pid, staker, amount);
emit StakerFraction(pid, staker, oldFraction, stakes[pid][staker].fraction);
emit PoolTotal(pid, oldTotal, pools[pid].total);
return true;
}
function withdraw(uint pid) public returns (bool) {
require(claim(pid), "MRCHStaking::withdraw: claim error");
uint amount = stakes[pid][msg.sender].amount;
return withdrawWithoutReward(pid, amount);
}
function withdrawWithoutReward(uint pid, uint amount) public returns (bool) {
return withdrawInternal(pid, msg.sender, amount);
}
function withdrawInternal(uint pid, address staker, uint amount) internal returns (bool) {
require(amount > 0, "MRCHStaking::withdrawInternal: amount must be positive");
require(amount <= stakes[pid][msg.sender].amount, "MRCHStaking::withdrawInternal: not enough balance");
stakes[pid][staker].amount = stakes[pid][staker].amount.sub(amount);
uint freezeTime = stakes[pid][staker].stakeTime.add(pools[pid].freezeTime);
if (getTimeStamp() < freezeTime) {
uint freezeAmount = amount.mul(pools[pid].freezePercent).div(100);
amount = amount.sub(freezeAmount);
}
doTransferOut(stakeToken, staker, amount);
return true;
}
function claim(uint pid) public returns (bool) {
require(getTimeStamp() > pools[pid].endTime, "MRCHStaking::claim: bad timing for the request");
address staker = msg.sender;
uint rewardAmount = currentTotalReward(pid, staker);
if (rewardAmount == 0) {
return true;
}
doTransferOut(rewardToken, staker, rewardAmount);
stakes[pid][staker].rewardOut = stakes[pid][staker].rewardOut.add(rewardAmount);
emit RewardOut(pid, staker, rewardToken, rewardAmount);
return true;
}
function currentTotalReward(uint pid, address staker) public view returns (uint) {
uint totalRewardAmount = pools[pid].rewardAmount;
uint total = pools[pid].total;
if (total == 0) {
return 0;
}
uint fraction = stakes[pid][staker].fraction;
uint rewardOut = stakes[pid][staker].rewardOut;
uint rewardAmount = totalRewardAmount.mul(fraction).div(total);
return rewardAmount.sub(rewardOut);
}
function doTransferOut(address token, address to, uint amount) internal {
if (amount == 0) {
return;
}
IERC20 ERC20Interface = IERC20(token);
ERC20Interface.safeTransfer(to, amount);
}
function doTransferIn(address from, address token, uint amount) internal {
IERC20 ERC20Interface = IERC20(token);
ERC20Interface.safeTransferFrom(from, address(this), amount);
}
function transferTokens(address token, address to, uint amount) public onlyOwner {
doTransferOut(token, to, amount);
}
function getTimeStamp() public view virtual returns (uint) {
return block.timestamp;
}
function getPoolLength() public view returns(uint) {
return pools.length;
}
}
所以在成功部署到 rinkeby 測試網后,我不確定這意味着什么(其中一些)。
所以我知道一個事實,rewardAmount_ - 是每個區塊將分配多少獎勵。
startTime_ 是池應該開始的時間(例如您可以使用https://www.epochconverter.com/的日期和時間。
startTime_是合約停止分配獎勵的時間。
凍結時間就像鎖定令牌,所以當用戶嘗試在凍結時間之前取出時,他們將無法取出。
凍結百分比是 Apy,它會隨着時間的推移而降低。
我不太了解它,所以如果錯了,請糾正。 我在這里的原因是; 如果我對 freezetime 和 freezepercentage 的理解是正確的,我將如何做到這一點或將其輸入到該字段中。
我知道可以像這樣輸入 freezePercentage 5% = 5e18。
但是 freezeTime 呢?
如果有人有更好的理解,請與我分享
要回答您的問題:
我知道可以像這樣輸入 freezePercentage 5% = 5e18。 -這是正確的。 您可以將百分比作為整數輸入並按此處理,例如,5 將是 0.05
但是凍結時間呢? 凍結時間是質押 LP 代幣凍結部分可以以 unix 時間戳格式釋放的結束日期。 在這種情況下,當有人提取他們的質押時,如果您使用 AddPool 創建池,並在凍結時間輸入諸如“1679505397(2023 年 3 月)”之類的值,它將提取他們的質押減去凍結的金額,在這種情況下上面,它被硬編碼為 5%。 例如,我質押了 10 個 LP 代幣。 我選擇今天提現,但我只會取回9.5,因為凍結百分比是5,並且時間戳小於凍結時間。 我將不得不等到 2023 年 3 月才能撤回最終的 0.5。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.