Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(StakeManager): add checks for whether lockup period is in range #39

Merged
merged 1 commit into from
Dec 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 18 additions & 16 deletions .gas-snapshot
Original file line number Diff line number Diff line change
@@ -1,24 +1,26 @@
CreateVaultTest:testDeployment() (gas: 9774)
CreateVaultTest:test_createVault() (gas: 650992)
ExecuteAccountTest:testDeployment() (gas: 26400)
ExecuteAccountTest:test_RevertWhen_InvalidLimitEpoch() (gas: 991602)
LeaveTest:testDeployment() (gas: 26172)
LeaveTest:test_RevertWhen_NoPendingMigration() (gas: 678051)
LeaveTest:test_RevertWhen_SenderIsNotVault() (gas: 10562)
LockTest:testDeployment() (gas: 26400)
LockTest:test_RevertWhen_DecreasingLockTime() (gas: 994528)
LockTest:test_RevertWhen_SenderIsNotVault() (gas: 10607)
MigrateTest:testDeployment() (gas: 26172)
MigrateTest:test_RevertWhen_NoPendingMigration() (gas: 677890)
CreateVaultTest:test_createVault() (gas: 650970)
ExecuteAccountTest:testDeployment() (gas: 26421)
ExecuteAccountTest:test_RevertWhen_InvalidLimitEpoch() (gas: 992511)
LeaveTest:testDeployment() (gas: 26193)
LeaveTest:test_RevertWhen_NoPendingMigration() (gas: 678007)
LeaveTest:test_RevertWhen_SenderIsNotVault() (gas: 10540)
LockTest:testDeployment() (gas: 26421)
LockTest:test_RevertWhen_DecreasingLockTime() (gas: 995651)
LockTest:test_RevertWhen_InvalidLockupPeriod() (gas: 815891)
LockTest:test_RevertWhen_SenderIsNotVault() (gas: 10652)
MigrateTest:testDeployment() (gas: 26193)
MigrateTest:test_RevertWhen_NoPendingMigration() (gas: 677868)
MigrateTest:test_RevertWhen_SenderIsNotVault() (gas: 10629)
SetStakeManagerTest:testDeployment() (gas: 9774)
SetStakeManagerTest:test_RevertWhen_InvalidStakeManagerAddress() (gas: 20481)
SetStakeManagerTest:test_SetStakeManager() (gas: 19869)
StakeManagerTest:testDeployment() (gas: 26172)
StakeTest:testDeployment() (gas: 26172)
StakeTest:test_RevertWhen_SenderIsNotVault() (gas: 10638)
StakeManagerTest:testDeployment() (gas: 26193)
StakeTest:testDeployment() (gas: 26421)
StakeTest:test_RevertWhen_InvalidLockupPeriod() (gas: 827181)
StakeTest:test_RevertWhen_SenderIsNotVault() (gas: 10672)
StakedTokenTest:testStakeToken() (gas: 7638)
UnstakeTest:testDeployment() (gas: 26355)
UnstakeTest:test_RevertWhen_FundsLocked() (gas: 990991)
UnstakeTest:testDeployment() (gas: 26376)
UnstakeTest:test_RevertWhen_FundsLocked() (gas: 991901)
UnstakeTest:test_RevertWhen_SenderIsNotVault() (gas: 10609)
VaultFactoryTest:testDeployment() (gas: 9774)
14 changes: 14 additions & 0 deletions contracts/StakeManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ contract StakeManager is Ownable {
error StakeManager__PendingMigration();
error StakeManager__SenderIsNotPreviousStakeManager();
error StakeManager__InvalidLimitEpoch();
error StakeManager__InvalidLockupPeriod();

struct Account {
uint256 lockUntil;
Expand All @@ -32,6 +33,8 @@ contract StakeManager is Ownable {

uint256 public constant EPOCH_SIZE = 1 weeks;
uint256 public constant YEAR = 365 days;
uint256 public constant MIN_LOCKUP_PERIOD = 12 weeks; // 3 months
uint256 public constant MAX_LOCKUP_PERIOD = 4 * YEAR; // 4 years
uint256 public constant MP_APY = 1;
uint256 public constant MAX_BOOST = 4;

Expand Down Expand Up @@ -64,8 +67,13 @@ contract StakeManager is Ownable {
* Increases balance of msg.sender;
* @param _amount Amount of balance to be decreased.
* @param _time Seconds from block.timestamp to lock balance.
*
* @dev Reverts when `_time` is not in range of [MIN_LOCKUP_PERIOD, MAX_LOCKUP_PERIOD]
*/
function stake(uint256 _amount, uint256 _time) external onlyVault {
if (_time > 0 && (_time < MIN_LOCKUP_PERIOD || _time > MAX_LOCKUP_PERIOD)) {
revert StakeManager__InvalidLockupPeriod();
}
Account storage account = accounts[msg.sender];
processAccount(account, currentEpoch);
account.balance += _amount;
Expand Down Expand Up @@ -94,8 +102,14 @@ contract StakeManager is Ownable {
/**
* @notice Locks entire balance for more amount of time.
* @param _time amount of time to lock from now.
*
* @dev Reverts when `_time` is bigger than `MAX_LOCKUP_PERIOD`
* @dev Reverts when `_time + block.timestamp` is smaller than current lock time.
*/
function lock(uint256 _time) external onlyVault {
if (_time > MAX_LOCKUP_PERIOD) {
revert StakeManager__InvalidLockupPeriod();
}
Account storage account = accounts[msg.sender];
processAccount(account, currentEpoch);
if (block.timestamp + _time < account.lockUntil) {
Expand Down
37 changes: 34 additions & 3 deletions test/StakeManager.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,23 @@ contract StakeTest is StakeManagerTest {
vm.expectRevert(StakeManager.StakeManager__SenderIsNotVault.selector);
stakeManager.stake(100, 1);
}

function test_RevertWhen_InvalidLockupPeriod() public {
// ensure user has funds
deal(stakeToken, testUser, 1000);
StakeVault userVault = _createTestVault(testUser);

vm.startPrank(testUser);
ERC20(stakeToken).approve(address(userVault), 100);

uint256 lockTime = stakeManager.MIN_LOCKUP_PERIOD() - 1;
vm.expectRevert(StakeManager.StakeManager__InvalidLockupPeriod.selector);
userVault.stake(100, lockTime);

lockTime = stakeManager.MAX_LOCKUP_PERIOD() + 1;
vm.expectRevert(StakeManager.StakeManager__InvalidLockupPeriod.selector);
userVault.stake(100, lockTime);
}
}

contract UnstakeTest is StakeManagerTest {
Expand All @@ -74,7 +91,7 @@ contract UnstakeTest is StakeManagerTest {
vm.startPrank(testUser);
ERC20(stakeToken).approve(address(userVault), 100);

uint256 lockTime = 1 days;
uint256 lockTime = stakeManager.MIN_LOCKUP_PERIOD();
userVault.stake(100, lockTime);

vm.expectRevert(StakeManager.StakeManager__FundsLocked.selector);
Expand All @@ -92,6 +109,20 @@ contract LockTest is StakeManagerTest {
stakeManager.lock(100);
}

function test_RevertWhen_InvalidLockupPeriod() public {
// ensure user has funds
deal(stakeToken, testUser, 1000);
StakeVault userVault = _createTestVault(testUser);

vm.startPrank(testUser);
// ensure user vault can spend user tokens
ERC20(stakeToken).approve(address(userVault), 100);

uint256 lockTime = stakeManager.MAX_LOCKUP_PERIOD() + 1;
vm.expectRevert(StakeManager.StakeManager__InvalidLockupPeriod.selector);
userVault.stake(100, lockTime);
}

function test_RevertWhen_DecreasingLockTime() public {
// ensure user has funds
deal(stakeToken, testUser, 1000);
Expand All @@ -101,7 +132,7 @@ contract LockTest is StakeManagerTest {
// ensure user vault can spend user tokens
ERC20(stakeToken).approve(address(userVault), 100);

uint256 lockTime = 1 days;
uint256 lockTime = stakeManager.MIN_LOCKUP_PERIOD() + 1;
userVault.stake(100, lockTime);

vm.expectRevert(StakeManager.StakeManager__DecreasingLockTime.selector);
Expand Down Expand Up @@ -157,7 +188,7 @@ contract ExecuteAccountTest is StakeManagerTest {
vm.startPrank(testUser);
ERC20(stakeToken).approve(address(userVault), 100);

uint256 lockTime = 1 days;
uint256 lockTime = stakeManager.MIN_LOCKUP_PERIOD();
userVault.stake(100, lockTime);

uint256 currentEpoch = stakeManager.currentEpoch();
Expand Down
Loading