Skip to content

Commit

Permalink
add lockUpStake
Browse files Browse the repository at this point in the history
  • Loading branch information
devintegral2 committed Jun 7, 2020
1 parent ea12835 commit a676d9f
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 0 deletions.
44 changes: 44 additions & 0 deletions contracts/sfc/Staker.sol
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,13 @@ contract Stakers is Ownable, StakersConstants {
uint256 stakeTotalAmount;
uint256 delegationsTotalAmount;
uint256 totalSupply;
uint256 totalLockedAmount;
}

struct LockedAmount {
uint256 fromEpoch;
uint256 startTime;
uint256 endTime;
}

uint256 private reserved1;
Expand Down Expand Up @@ -140,6 +147,9 @@ contract Stakers is Ownable, StakersConstants {

mapping(address => mapping(uint256 => WithdrawalRequest)) public withdrawalRequests;

uint256 public firstLockedUpEpoch;
mapping(uint256 => LockedAmount) public lockedStakes; // stakerID -> LockedAmount

/*
Getters
*/
Expand Down Expand Up @@ -408,6 +418,17 @@ contract Stakers is Ownable, StakersConstants {
return 0; // avoid division by zero
}
uint256 weightedTotalStake = stake.add((delegatedTotal.mul(commission)).div(RATIO_UNIT));

if (firstLockedUpEpoch > 0 && epoch >= firstLockedUpEpoch) {
if (lockedStakes[stakerID].fromEpoch >= epoch && epochSnapshots[epoch.sub(1)].endTime > lockedStakes[stakerID].endTime) {
uint256 totalLockedAmount = epochSnapshots[epoch].totalLockedAmount;
uint256 lockedReward = rawReward.mul(RATIO_UNIT - unlockedRatio()).div(RATIO_UNIT).mul(weightedTotalStake).div(totalLockedAmount);
rawReward = (rawReward.mul(unlockedRatio()).div(RATIO_UNIT)).add(lockedReward);
} else {
rawReward = rawReward.mul(unlockedRatio()).div(RATIO_UNIT);
}
}

return (rawReward.mul(weightedTotalStake)).div(totalStake);
}

Expand Down Expand Up @@ -584,6 +605,7 @@ contract Stakers is Ownable, StakersConstants {
require(stakers[stakerID].stakeAmount != 0, "staker doesn't exist");
require(stakers[stakerID].deactivatedTime == 0, "staker is deactivated");
require(stakers[stakerID].paidUntilEpoch == currentSealedEpoch, "not all rewards claimed"); // for rewards burning
require(lockedStakes[stakerID].fromEpoch == 0 || lockedStakes[stakerID].endTime > block.timestamp, "stake is locked");

_mayBurnRewardsOnDeactivation(false, stakerID, stakerSfcAddr, stakers[stakerID].stakeAmount, stakers[stakerID].stakeAmount);

Expand All @@ -601,6 +623,7 @@ contract Stakers is Ownable, StakersConstants {
require(stakers[stakerID].stakeAmount != 0, "staker doesn't exist");
require(stakers[stakerID].deactivatedTime == 0, "staker is deactivated");
require(stakers[stakerID].paidUntilEpoch == currentSealedEpoch, "not all rewards claimed"); // for rewards burning
require(lockedStakes[stakerID].fromEpoch == 0 || lockedStakes[stakerID].endTime > block.timestamp, "stake is locked");
require(amount >= minStakeDecrease(), "too small amount"); // avoid confusing wrID and amount

// don't allow to withdraw full as a request, because amount==0 originally meant "not existing"
Expand Down Expand Up @@ -804,6 +827,27 @@ contract Stakers is Ownable, StakersConstants {
emit UpdatedBaseRewardPerSec(value);
}

function startLockedUp(uint256 epochNum) onlyOwner external {
if (epochNum > 0) {
firstLockedUpEpoch = epochNum;
}
}

function lockUpStake(uint256 lockDuration) external {
uint256 stakerID = _sfcAddressToStakerID(msg.sender);
require(stakers[stakerID].stakeAmount != 0, "staker doesn't exist");
require(stakers[stakerID].deactivatedTime == 0, "staker is deactivated");
require(lockDuration >= 86400 * 14 && lockDuration <= 86400 * 365, "incorrect duration");
require(lockedStakes[stakerID].endTime > block.timestamp.add(lockDuration), "stake already locked up");
require(firstLockedUpEpoch == 0 || firstLockedUpEpoch > currentSealedEpoch, "feature was not activated");
// require(stakers[stakerID].paidUntilEpoch == currentSealedEpoch, "not all rewards claimed"); // for rewards burning
LockedAmount memory lStake = LockedAmount(
currentSealedEpoch,
block.timestamp,
block.timestamp.add(lockDuration));
lockedStakes[stakerID] = lStake;
}

event UpdatedDelegation(address indexed delegator, uint256 indexed oldStakerID, uint256 indexed newStakerID, uint256 amount);

// syncDelegator updates the delegator data on node, if it differs for some reason
Expand Down
7 changes: 7 additions & 0 deletions contracts/sfc/StakerConstants.sol
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,13 @@ contract StakersConstants {
return (30 * RATIO_UNIT) / 100; // 30%
}

/**
* @dev The ratio of the reward rate at base rate (no lock), e.g., 30%
*/
function unlockedRatio() public pure returns (uint256) {
return (30 * RATIO_UNIT) / 100; // 30%
}

/**
* @dev the period of time that stake is locked
*/
Expand Down

0 comments on commit a676d9f

Please # to comment.