From 6c12715f528ef612898bc3ba28944801d878ef11 Mon Sep 17 00:00:00 2001 From: r4bbit <445106+0x-r4bbit@users.noreply.github.com> Date: Thu, 10 Oct 2024 15:19:46 +0200 Subject: [PATCH] test(RewardsStreamerMP): ensure bonusMP and maxMP are decreased correctly at unstake This commit adds some tests to check that, if a user (partically) unstakes their funds, their initial and bonus MP get decreased proportionally, as well as their max mp. Closes #46 --- .gas-report | 34 +++++++-------- .gas-snapshot | 12 +++--- test/RewardsStreamerMP.t.sol | 83 ++++++++++++++++++++++++++++++++++++ 3 files changed, 107 insertions(+), 22 deletions(-) diff --git a/.gas-report b/.gas-report index b871745..82f82aa 100644 --- a/.gas-report +++ b/.gas-report @@ -17,21 +17,21 @@ | Deployment Cost | Deployment Size | | | | | | 1111690 | 5010 | | | | | | Function Name | min | avg | median | max | # calls | -| MAX_LOCKING_PERIOD | 228 | 228 | 228 | 228 | 18 | -| MAX_MULTIPLIER | 252 | 252 | 252 | 252 | 34 | -| MIN_LOCKING_PERIOD | 229 | 229 | 229 | 229 | 8 | +| MAX_LOCKING_PERIOD | 228 | 228 | 228 | 228 | 21 | +| MAX_MULTIPLIER | 252 | 252 | 252 | 252 | 40 | +| MIN_LOCKING_PERIOD | 229 | 229 | 229 | 229 | 10 | | MP_RATE_PER_YEAR | 231 | 231 | 231 | 231 | 2 | -| SCALE_FACTOR | 251 | 251 | 251 | 251 | 30 | -| accountedRewards | 373 | 921 | 373 | 2373 | 62 | -| getUserInfo | 1576 | 1576 | 1576 | 1576 | 61 | -| rewardIndex | 373 | 405 | 373 | 2373 | 62 | -| stake | 167787 | 215016 | 228586 | 249238 | 43 | -| totalMP | 330 | 330 | 330 | 330 | 62 | -| totalMaxMP | 329 | 329 | 329 | 329 | 62 | -| totalStaked | 373 | 373 | 373 | 373 | 62 | -| unstake | 75511 | 107624 | 110519 | 134250 | 10 | -| updateGlobalState | 30008 | 56733 | 47387 | 80335 | 22 | -| updateUserMP | 34631 | 36857 | 37133 | 37431 | 16 | +| SCALE_FACTOR | 251 | 251 | 251 | 251 | 36 | +| accountedRewards | 373 | 931 | 373 | 2373 | 68 | +| getUserInfo | 1576 | 1576 | 1576 | 1576 | 62 | +| rewardIndex | 373 | 402 | 373 | 2373 | 68 | +| stake | 167787 | 216078 | 228586 | 249238 | 45 | +| totalMP | 330 | 330 | 330 | 330 | 68 | +| totalMaxMP | 329 | 329 | 329 | 329 | 68 | +| totalStaked | 373 | 373 | 373 | 373 | 68 | +| unstake | 75511 | 104952 | 91588 | 134250 | 12 | +| updateGlobalState | 30008 | 55954 | 47387 | 80335 | 24 | +| updateUserMP | 34631 | 36888 | 37133 | 37431 | 18 | | test/mocks/MockToken.sol:MockToken contract | | | | | | @@ -39,9 +39,9 @@ | Deployment Cost | Deployment Size | | | | | | 639406 | 3369 | | | | | | Function Name | min | avg | median | max | # calls | -| approve | 46346 | 46346 | 46346 | 46346 | 150 | -| balanceOf | 561 | 1321 | 561 | 2561 | 271 | -| mint | 51284 | 58124 | 51284 | 68384 | 150 | +| approve | 46346 | 46346 | 46346 | 46346 | 160 | +| balanceOf | 561 | 1324 | 561 | 2561 | 288 | +| mint | 51284 | 58124 | 51284 | 68384 | 160 | | transfer | 34390 | 48070 | 51490 | 51490 | 10 | diff --git a/.gas-snapshot b/.gas-snapshot index 07bc460..0c1f376 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -14,8 +14,8 @@ StakeTest:test_StakeOneAccountWithMinLockUp() (gas: 284055) StakeTest:test_StakeOneAccountWithRandomLockUp() (gas: 284099) UnstakeTest:test_StakeMultipleAccounts() (gas: 438822) UnstakeTest:test_StakeMultipleAccountsAndRewards() (gas: 586066) -UnstakeTest:test_StakeMultipleAccountsMPIncreasesMaxMPDoesNotChange() (gas: 743414) -UnstakeTest:test_StakeMultipleAccountsWithMinLockUp() (gas: 449118) +UnstakeTest:test_StakeMultipleAccountsMPIncreasesMaxMPDoesNotChange() (gas: 743436) +UnstakeTest:test_StakeMultipleAccountsWithMinLockUp() (gas: 449140) UnstakeTest:test_StakeMultipleAccountsWithRandomLockUp() (gas: 470688) UnstakeTest:test_StakeOneAccount() (gas: 267816) UnstakeTest:test_StakeOneAccountAndRewards() (gas: 415080) @@ -23,8 +23,10 @@ UnstakeTest:test_StakeOneAccountMPIncreasesMaxMPDoesNotChange() (gas: 472851) UnstakeTest:test_StakeOneAccountReachingMPLimit() (gas: 468459) UnstakeTest:test_StakeOneAccountWithMaxLockUp() (gas: 284068) UnstakeTest:test_StakeOneAccountWithMinLockUp() (gas: 284055) -UnstakeTest:test_StakeOneAccountWithRandomLockUp() (gas: 284144) +UnstakeTest:test_StakeOneAccountWithRandomLockUp() (gas: 284121) UnstakeTest:test_UnstakeMultipleAccounts() (gas: 616415) UnstakeTest:test_UnstakeMultipleAccountsAndRewards() (gas: 937787) -UnstakeTest:test_UnstakeOneAccount() (gas: 446390) -UnstakeTest:test_UnstakeOneAccountAndRewards() (gas: 557241) \ No newline at end of file +UnstakeTest:test_UnstakeOneAccount() (gas: 446348) +UnstakeTest:test_UnstakeOneAccountAndAccruedMP() (gas: 467641) +UnstakeTest:test_UnstakeOneAccountAndRewards() (gas: 557241) +UnstakeTest:test_UnstakeOneAccountWithLockUpAndAccruedMP() (gas: 493412) \ No newline at end of file diff --git a/test/RewardsStreamerMP.t.sol b/test/RewardsStreamerMP.t.sol index 34b090f..1ac05b3 100644 --- a/test/RewardsStreamerMP.t.sol +++ b/test/RewardsStreamerMP.t.sol @@ -1102,6 +1102,89 @@ contract UnstakeTest is StakeTest { ); } + function test_UnstakeOneAccountAndAccruedMP() public { + test_StakeOneAccount(); + + // wait for 1 year + uint256 currentTime = vm.getBlockTimestamp(); + vm.warp(currentTime + (365 days)); + + streamer.updateGlobalState(); + streamer.updateUserMP(alice); + + checkStreamer( + CheckStreamerParams({ + totalStaked: 10e18, + totalMP: 20e18, // total MP must have been doubled + totalMaxMP: 40e18, + stakingBalance: 10e18, + rewardBalance: 0, + rewardIndex: 0, + accountedRewards: 0 + }) + ); + + // unstake half of the tokens + _unstake(alice, 5e18); + + checkStreamer( + CheckStreamerParams({ + totalStaked: 5e18, // 10 - 5 + totalMP: 10e18, // 20 - 10 (5 initial + 5 accrued) + totalMaxMP: 20e18, + stakingBalance: 5e18, + rewardBalance: 0, + rewardIndex: 0, + accountedRewards: 0 + }) + ); + } + + function test_UnstakeOneAccountWithLockUpAndAccruedMP() public { + test_StakeOneAccountWithMinLockUp(); + + uint256 stakeAmount = 10e18; + uint256 lockUpPeriod = streamer.MIN_LOCKING_PERIOD(); + // 10e18 is what's used in `test_StakeOneAccountWithMinLockUp` + uint256 expectedBonusMP = _calculateBonusMP(stakeAmount, lockUpPeriod); + + // wait for 1 year + uint256 currentTime = vm.getBlockTimestamp(); + vm.warp(currentTime + (365 days)); + + streamer.updateGlobalState(); + streamer.updateUserMP(alice); + + checkStreamer( + CheckStreamerParams({ + totalStaked: stakeAmount, + totalMP: (stakeAmount + expectedBonusMP) + stakeAmount, // we do `+ stakeAmount` we've accrued + // `stakeAmount` after 1 year + totalMaxMP: stakeAmount * streamer.MAX_MULTIPLIER() + expectedBonusMP, + stakingBalance: 10e18, + rewardBalance: 0, + rewardIndex: 0, + accountedRewards: 0 + }) + ); + + // unstake half of the tokens + _unstake(alice, 5e18); + expectedBonusMP = _calculateBonusMP(5e18, lockUpPeriod); + + checkStreamer( + CheckStreamerParams({ + totalStaked: 5e18, + totalMP: (5e18 + expectedBonusMP) + 5e18, + totalMaxMP: 5e18 * streamer.MAX_MULTIPLIER() + expectedBonusMP, + stakingBalance: 5e18, + rewardBalance: 0, + rewardIndex: 0, + accountedRewards: 0 + }) + ); + } + function test_UnstakeOneAccountAndRewards() public { test_StakeOneAccountAndRewards();