Skip to content

Commit

Permalink
Locks Mechanism Changed (#742)
Browse files Browse the repository at this point in the history
* fix: lock mechanism changes

* fix: docs generated

* fix: test fix

* fix: reset unstake lock bug fix
  • Loading branch information
SamAg19 committed Mar 16, 2022
1 parent 887c7c9 commit 02ec060
Show file tree
Hide file tree
Showing 7 changed files with 192 additions and 95 deletions.
27 changes: 13 additions & 14 deletions contracts/Core/StakeManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ contract StakeManager is Initializable, StakeStorage, StateManager, Pause, Stake
* @param staker address of the staker/delegator
* @param epoch in which the extension took place
*/
event ExtendUnstakeLock(uint32 indexed stakerId, address staker, uint32 epoch);
event ResetUnstakeLock(uint32 indexed stakerId, address staker, uint32 epoch);

/**
* @dev Emitted when the staker changes commission
Expand Down Expand Up @@ -290,7 +290,7 @@ contract StakeManager is Initializable, StakeStorage, StateManager, Pause, Stake
/** @notice staker/delegator must call unstake() to lock their sRZRs
* and should wait for params.withdraw_after period
* after which he/she can call initiateWithdraw() in withdrawInitiationPeriod.
* If this period pass, lock expires and she will have to extendUnstakeLock() to able to initiateWithdraw again
* If this period pass, lock expires and she will have to resetUnstakeLock() to able to initiateWithdraw again
* @param stakerId The Id of staker associated with sRZR which user want to unstake
* @param sAmount The Amount in sRZR
*/
Expand Down Expand Up @@ -447,32 +447,30 @@ contract StakeManager is Initializable, StakeStorage, StateManager, Pause, Stake
emit CommissionChanged(stakerId, commission);
}

/** @notice Used by anyone whose lock expired or who lost funds, and want to request initiateWithdraw
* Here we have added penalty to avoid repeating front-run unstake/witndraw attack
/**
* @notice Used by anyone whose has not initiated withdraw within the WithdrawInitiationPeriod
* or someone who just wants to extend unstake lock.
* Here we have added penalty to avoid repeating front-running
*/
function extendUnstakeLock(uint32 stakerId) external initialized whenNotPaused {
function resetUnstakeLock(uint32 stakerId) external initialized whenNotPaused {
// Lock should be expired if you want to extend
uint32 epoch = _getEpoch();
// slither-disable-next-line timestamp
require(locks[msg.sender][stakers[stakerId].tokenAddress][LockType.Unstake].amount != 0, "Unstake Lock doesnt exist");
// slither-disable-next-line timestamp
require(
locks[msg.sender][stakers[stakerId].tokenAddress][LockType.Unstake].unlockAfter + withdrawInitiationPeriod < epoch,
"Initiation Period Not yet passed"
);
require(locks[msg.sender][stakers[stakerId].tokenAddress][LockType.Withdraw].unlockAfter == 0, "Withdraw Lock exists");

Structs.Staker storage staker = stakers[stakerId];
Structs.Lock storage lock = locks[msg.sender][staker.tokenAddress][LockType.Unstake];
IStakedToken sToken = IStakedToken(staker.tokenAddress);

//Giving out the extendLock penalty
uint256 penalty = (lock.amount * extendUnstakeLockPenalty) / 100;
uint256 penalty = (lock.amount * resetUnstakeLockPenalty) / 100;
uint256 rPenalty = _convertSRZRToRZR(penalty, staker.stake, sToken.totalSupply());

lock.amount = lock.amount - penalty;
staker.stake = staker.stake - rPenalty;
lock.unlockAfter = epoch;
emit ExtendUnstakeLock(stakerId, msg.sender, _getEpoch());
lock.unlockAfter = epoch + unstakeLockPeriod;
emit ResetUnstakeLock(stakerId, msg.sender, _getEpoch());
// Ignoring below line for testing as this is standard erc20 function
require(sToken.burn(address(this), penalty), "Token burn Failed");
}
Expand Down Expand Up @@ -528,7 +526,8 @@ contract StakeManager is Initializable, StakeStorage, StateManager, Pause, Stake
razor.transfer(BURN_ADDRESS, amountToBeBurned);
}

/** @notice Allows bountyHunter to redeem their bounty once its locking period is over
/**
* @notice Allows bountyHunter to redeem their bounty once its locking period is over
* @param bountyId The ID of the bounty
*/
function redeemBounty(uint32 bountyId) external {
Expand Down
4 changes: 2 additions & 2 deletions contracts/Core/parameters/Governance.sol
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,9 @@ contract Governance is Initializable, ACL, Constants {
* @dev can be called only by the the address that has the governer role
* @param _extendLockPenalty updated value to be set for extendLockPenalty
*/
function setExtendUnstakeLockPenalty(uint8 _extendLockPenalty) external initialized onlyRole(GOVERNER_ROLE) {
function setResetUnstakeLockPenalty(uint8 _extendLockPenalty) external initialized onlyRole(GOVERNER_ROLE) {
emit ParameterChanged(msg.sender, "extendLockPenalty", _extendLockPenalty, block.timestamp);
stakeManagerParams.setExtendUnstakeLockPenalty(_extendLockPenalty);
stakeManagerParams.setResetUnstakeLockPenalty(_extendLockPenalty);
}

/**
Expand Down
6 changes: 3 additions & 3 deletions contracts/Core/parameters/child/StakeManagerParams.sol
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ abstract contract StakeManagerParams is ACL, IStakeManagerParams, Constants {
* @notice percentage stake penalty from the locked amount for extending unstake lock
* incase withdrawInitiationPeriod was missed
*/
uint8 public extendUnstakeLockPenalty = 1;
uint8 public resetUnstakeLockPenalty = 1;
/// @notice maximum commission stakers can charge from delegators on their profits
uint8 public maxCommission = 20;
/// @notice maximum commission change a staker can do
Expand Down Expand Up @@ -89,9 +89,9 @@ abstract contract StakeManagerParams is ACL, IStakeManagerParams, Constants {
}

/// @inheritdoc IStakeManagerParams
function setExtendUnstakeLockPenalty(uint8 _extendUnstakeLockPenalty) external override onlyRole(GOVERNANCE_ROLE) {
function setResetUnstakeLockPenalty(uint8 _resetUnstakeLockPenalty) external override onlyRole(GOVERNANCE_ROLE) {
// slither-disable-next-line events-maths
extendUnstakeLockPenalty = _extendUnstakeLockPenalty;
resetUnstakeLockPenalty = _resetUnstakeLockPenalty;
}

/// @inheritdoc IStakeManagerParams
Expand Down
4 changes: 2 additions & 2 deletions contracts/Core/parameters/interfaces/IStakeManagerParams.sol
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ interface IStakeManagerParams {
* @notice changing percentage stake penalty from the locked amount for extending unstake lock
* incase withdrawInitiationPeriod was missed
* @dev can be called only by the the address that has the governance role
* @param _extendLockPenalty updated value to be set for extendLockPenalty
* @param _resetUnstakePenalty updated value to be set for resetUnstakePenalty
*/
function setExtendUnstakeLockPenalty(uint8 _extendLockPenalty) external;
function setResetUnstakeLockPenalty(uint8 _resetUnstakePenalty) external;

/**
* @notice changing minimum amount that to be staked for participation
Expand Down
8 changes: 4 additions & 4 deletions scenarios/scenarios.js
Original file line number Diff line number Diff line change
Expand Up @@ -658,17 +658,17 @@ describe('Scenarios', async () => {

staker = await stakeManager.getStaker(1);
let lock = await stakeManager.locks(signers[1].address, staker.tokenAddress, 0);
const extendUnstakeLockPenalty = await stakeManager.extendUnstakeLockPenalty();
const resetUnstakeLockPenalty = await stakeManager.resetUnstakeLockPenalty();
let lockedAmount = lock.amount;
const penalty = ((lockedAmount).mul(extendUnstakeLockPenalty)).div(100);
const penalty = ((lockedAmount).mul(resetUnstakeLockPenalty)).div(100);
lockedAmount = lockedAmount.sub(penalty);
staker = await stakeManager.getStaker(1);
await stakeManager.connect(signers[1]).extendUnstakeLock(staker.id);
await stakeManager.connect(signers[1]).resetUnstakeLock(staker.id);
staker = await stakeManager.getStaker(1);
lock = await stakeManager.locks(signers[1].address, staker.tokenAddress, 0);
epoch = await getEpoch();
assertBNEqual((lock.amount), (lockedAmount), 'Stake is not equal to calculated stake');
assertBNEqual(epoch, lock.unlockAfter, 'lock.withdrawAfter assigned incorrectly');
assertBNEqual(epoch + UNSTAKE_LOCK_PERIOD, lock.unlockAfter, 'lock.withdrawAfter assigned incorrectly');
});
it('Staker unstakes and in withdraw lock period, there is a change in governance parameter and withdraw lock period is reduced', async function () {
const secret = '0x747d5c9e6d18ed15ce7ac8decececbcbcbcbc8555555c0823ea4ecececececec';
Expand Down
14 changes: 7 additions & 7 deletions test/Governance.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ describe('Governance contract Test', async () => {
const minimumSafeRazor = tokenAmount('10000');
const blockReward = tokenAmount('100');
const withdrawReleasePeriod = toBigNumber('5');
const extendUnstakeLockPenalty = toBigNumber('1');
const resetUnstakeLockPenalty = toBigNumber('1');
const maxAge = toBigNumber('1000000');
const maxTolerance = toBigNumber('1000000');
const maxCommission = toBigNumber('20');
Expand Down Expand Up @@ -80,7 +80,7 @@ describe('Governance contract Test', async () => {
tx = governance.connect(signers[0]).setWithdrawInitiationPeriod(toBigNumber('1'));
await assertRevert(tx, expectedRevertMessage);

tx = governance.connect(signers[0]).setExtendUnstakeLockPenalty(toBigNumber('1'));
tx = governance.connect(signers[0]).setResetUnstakeLockPenalty(toBigNumber('1'));
await assertRevert(tx, expectedRevertMessage);

tx = governance.connect(signers[0]).setMaxAltBlocks(toBigNumber('1'));
Expand Down Expand Up @@ -159,9 +159,9 @@ describe('Governance contract Test', async () => {
const withdrawInitiationPeriod = await stakeManager.withdrawInitiationPeriod();
assertBNEqual(withdrawInitiationPeriod, toBigNumber('16'));

await governance.setExtendUnstakeLockPenalty(toBigNumber('17'));
const extendUnstakeLockPenalty = await stakeManager.extendUnstakeLockPenalty();
assertBNEqual(extendUnstakeLockPenalty, toBigNumber('17'));
await governance.setResetUnstakeLockPenalty(toBigNumber('17'));
const resetUnstakeLockPenalty = await stakeManager.resetUnstakeLockPenalty();
assertBNEqual(resetUnstakeLockPenalty, toBigNumber('17'));

await governance.setMaxAge(toBigNumber('18'));
const maxAge = await rewardManager.maxAge();
Expand Down Expand Up @@ -229,8 +229,8 @@ describe('Governance contract Test', async () => {
const withdrawReleasePeriodValue = await stakeManager.withdrawInitiationPeriod();
assertBNEqual(withdrawReleasePeriod, withdrawReleasePeriodValue);

const extendUnstakeLockPenaltyValue = await stakeManager.extendUnstakeLockPenalty();
assertBNEqual(extendUnstakeLockPenalty, extendUnstakeLockPenaltyValue);
const resetUnstakeLockPenaltyValue = await stakeManager.resetUnstakeLockPenalty();
assertBNEqual(resetUnstakeLockPenalty, resetUnstakeLockPenaltyValue);

const maxAltBlocksValue = await blockManager.maxAltBlocks();
assertBNEqual(maxAltBlocks, maxAltBlocksValue);
Expand Down
Loading

0 comments on commit 02ec060

Please sign in to comment.