From 8bebfbc9d283b6f570c2f645093954618638be1a Mon Sep 17 00:00:00 2001 From: Ricardo Guilherme Schmidt <3esmit@gmail.com> Date: Wed, 13 Aug 2025 10:37:40 -0300 Subject: [PATCH] refactor(StakeManager, StakeVault): decouple StakeManager <-> StakeVault - BREAKING CHANGE: Updated stake and lock functions in StakeManager to accept an additional parameter for current lock until timestamp. - BREAKING CHANGE: Modified StakeVault to handle the new locking mechanism and removed the old updateLockUntil function. - Adjusted related tests to reflect changes in function signatures and expected behaviors. - Ensured that funds locked checks are properly referenced in tests and contracts. --- .gas-report | 130 ++++++++--------- .gas-snapshot | 178 +++++++++++------------ certora/specs/EmergencyMode.spec | 4 +- certora/specs/StakeManager.spec | 8 +- src/StakeManager.sol | 37 ++--- src/StakeVault.sol | 31 ++-- src/interfaces/IStakeManager.sol | 10 +- src/interfaces/IStakeVault.sol | 2 +- test/RewardsStreamerMP.t.sol | 8 +- test/mocks/MockStakeManager.sol | 8 +- test/mocks/StackOverflowStakeManager.sol | 14 +- 11 files changed, 225 insertions(+), 205 deletions(-) diff --git a/.gas-report b/.gas-report index 00ccf1e..a494422 100644 --- a/.gas-report +++ b/.gas-report @@ -60,13 +60,13 @@ +=============================================================================================================================+ | Deployment Cost | Deployment Size | | | | | |-------------------------------------------------------------------+-----------------+---------+---------+---------+---------| -| 8406945 | 40092 | | | | | +| 8323525 | 39701 | | | | | |-------------------------------------------------------------------+-----------------+---------+---------+---------+---------| | | | | | | | |-------------------------------------------------------------------+-----------------+---------+---------+---------+---------| | Function Name | Min | Avg | Median | Max | # Calls | |-------------------------------------------------------------------+-----------------+---------+---------+---------+---------| -| run | 7342367 | 7342367 | 7342367 | 7342367 | 88 | +| run | 7263905 | 7263905 | 7263905 | 7263905 | 88 | ╰-------------------------------------------------------------------+-----------------+---------+---------+---------+---------╯ ╭---------------------------------------------------------+-----------------+------+--------+------+---------╮ @@ -88,13 +88,13 @@ +===============================================================================================================================+ | Deployment Cost | Deployment Size | | | | | |---------------------------------------------------------------------+-----------------+---------+---------+---------+---------| -| 6005462 | 28878 | | | | | +| 5895538 | 28363 | | | | | |---------------------------------------------------------------------+-----------------+---------+---------+---------+---------| | | | | | | | |---------------------------------------------------------------------+-----------------+---------+---------+---------+---------| | Function Name | Min | Avg | Median | Max | # Calls | |---------------------------------------------------------------------+-----------------+---------+---------+---------+---------| -| runWithAdminAndProxy | 3407494 | 3407494 | 3407494 | 3407494 | 3 | +| runWithAdminAndProxy | 3304282 | 3304282 | 3304282 | 3304282 | 3 | ╰---------------------------------------------------------------------+-----------------+---------+---------+---------+---------╯ ╭------------------------------+-----------------+--------+--------+--------+---------╮ @@ -210,7 +210,7 @@ +===================================================================================================+ | Deployment Cost | Deployment Size | | | | | |--------------------------------------------+-----------------+--------+--------+--------+---------| -| 3619677 | 16775 | | | | | +| 3509773 | 16260 | | | | | |--------------------------------------------+-----------------+--------+--------+--------+---------| | | | | | | | |--------------------------------------------+-----------------+--------+--------+--------+---------| @@ -218,87 +218,87 @@ |--------------------------------------------+-----------------+--------+--------+--------+---------| | MAX_LOCKUP_PERIOD | 383 | 383 | 383 | 383 | 4 | |--------------------------------------------+-----------------+--------+--------+--------+---------| -| MAX_MULTIPLIER | 263 | 263 | 263 | 263 | 20 | +| MAX_MULTIPLIER | 285 | 285 | 285 | 285 | 20 | |--------------------------------------------+-----------------+--------+--------+--------+---------| | MIN_LOCKUP_PERIOD | 331 | 331 | 331 | 331 | 17 | |--------------------------------------------+-----------------+--------+--------+--------+---------| | emergencyModeEnabled | 2421 | 2421 | 2421 | 2421 | 263 | |--------------------------------------------+-----------------+--------+--------+--------+---------| -| enableEmergencyMode | 2543 | 25291 | 25457 | 25457 | 264 | +| enableEmergencyMode | 2476 | 25224 | 25390 | 25390 | 264 | |--------------------------------------------+-----------------+--------+--------+--------+---------| -| getAccountTotalMaxMP | 21191 | 21191 | 21191 | 21191 | 1 | +| getAccountTotalMaxMP | 21213 | 21213 | 21213 | 21213 | 1 | |--------------------------------------------+-----------------+--------+--------+--------+---------| -| getAccountTotalStakedBalance | 21170 | 21170 | 21170 | 21170 | 1 | +| getAccountTotalStakedBalance | 21192 | 21192 | 21192 | 21192 | 1 | |--------------------------------------------+-----------------+--------+--------+--------+---------| | getAccountVaults | 5230 | 5230 | 5230 | 5230 | 4 | |--------------------------------------------+-----------------+--------+--------+--------+---------| -| getVault | 13653 | 13653 | 13653 | 13653 | 4181 | +| getVault | 13653 | 13653 | 13653 | 13653 | 4182 | |--------------------------------------------+-----------------+--------+--------+--------+---------| -| initialize | 92752 | 92752 | 92752 | 92752 | 88 | +| initialize | 92774 | 92774 | 92774 | 92774 | 88 | |--------------------------------------------+-----------------+--------+--------+--------+---------| | lastRewardTime | 2407 | 2407 | 2407 | 2407 | 2 | |--------------------------------------------+-----------------+--------+--------+--------+---------| -| leave | 66348 | 66348 | 66348 | 66348 | 2 | +| leave | 66358 | 66358 | 66358 | 66358 | 2 | |--------------------------------------------+-----------------+--------+--------+--------+---------| -| lock | 7040 | 43192 | 46735 | 86561 | 1034 | +| lock | 7096 | 40159 | 43888 | 62877 | 1034 | |--------------------------------------------+-----------------+--------+--------+--------+---------| -| migrateToVault | 9294 | 52631 | 16883 | 167465 | 4 | +| migrateToVault | 9229 | 57567 | 16864 | 187311 | 4 | |--------------------------------------------+-----------------+--------+--------+--------+---------| | mpAccruedOf | 2629 | 2629 | 2629 | 2629 | 20 | |--------------------------------------------+-----------------+--------+--------+--------+---------| -| mpBalanceOf | 4917 | 8695 | 10316 | 10316 | 12 | +| mpBalanceOf | 4939 | 8717 | 10338 | 10338 | 12 | |--------------------------------------------+-----------------+--------+--------+--------+---------| -| mpBalanceOfAccount | 30210 | 31283 | 31283 | 32356 | 2 | +| mpBalanceOfAccount | 30232 | 31305 | 31305 | 32378 | 2 | |--------------------------------------------+-----------------+--------+--------+--------+---------| -| proxiableUUID | 342 | 342 | 342 | 342 | 3 | +| proxiableUUID | 364 | 364 | 364 | 364 | 3 | |--------------------------------------------+-----------------+--------+--------+--------+---------| -| registerVault | 2583 | 74434 | 75014 | 75014 | 361 | +| registerVault | 2605 | 74457 | 75037 | 75037 | 361 | |--------------------------------------------+-----------------+--------+--------+--------+---------| -| rewardEndTime | 2429 | 2429 | 2429 | 2429 | 2 | +| rewardEndTime | 2364 | 2364 | 2364 | 2364 | 2 | |--------------------------------------------+-----------------+--------+--------+--------+---------| -| rewardStartTime | 2364 | 2364 | 2364 | 2364 | 2 | +| rewardStartTime | 2386 | 2386 | 2386 | 2386 | 2 | |--------------------------------------------+-----------------+--------+--------+--------+---------| -| rewardsBalanceOf | 20295 | 24409 | 25908 | 26129 | 268 | +| rewardsBalanceOf | 20317 | 24410 | 25930 | 26151 | 268 | |--------------------------------------------+-----------------+--------+--------+--------+---------| -| rewardsBalanceOfAccount | 62220 | 62220 | 62220 | 62220 | 1 | +| rewardsBalanceOfAccount | 62242 | 62242 | 62242 | 62242 | 1 | |--------------------------------------------+-----------------+--------+--------+--------+---------| | setReward | 2508 | 105565 | 107076 | 107076 | 265 | |--------------------------------------------+-----------------+--------+--------+--------+---------| -| setRewardsSupplier | 26875 | 26875 | 26875 | 26875 | 88 | +| setRewardsSupplier | 26809 | 26809 | 26809 | 26809 | 88 | |--------------------------------------------+-----------------+--------+--------+--------+---------| -| setTrustedCodehash | 24238 | 24238 | 24238 | 24238 | 88 | +| setTrustedCodehash | 24171 | 24171 | 24171 | 24171 | 88 | |--------------------------------------------+-----------------+--------+--------+--------+---------| -| stake | 2639 | 131939 | 60747 | 227511 | 2667 | +| stake | 2713 | 125321 | 57926 | 213584 | 2667 | |--------------------------------------------+-----------------+--------+--------+--------+---------| -| totalMP | 6805 | 8257 | 8257 | 9710 | 6 | +| totalMP | 6827 | 8279 | 8279 | 9732 | 6 | |--------------------------------------------+-----------------+--------+--------+--------+---------| -| totalMPAccrued | 2385 | 2385 | 2385 | 2385 | 4161 | +| totalMPAccrued | 2407 | 2407 | 2407 | 2407 | 4162 | |--------------------------------------------+-----------------+--------+--------+--------+---------| -| totalMPStaked | 2429 | 2429 | 2429 | 2429 | 4164 | +| totalMPStaked | 2363 | 2363 | 2363 | 2363 | 4165 | |--------------------------------------------+-----------------+--------+--------+--------+---------| -| totalMaxMP | 2407 | 2407 | 2407 | 2407 | 4161 | +| totalMaxMP | 2429 | 2429 | 2429 | 2429 | 4162 | |--------------------------------------------+-----------------+--------+--------+--------+---------| | totalRewardsAccrued | 2407 | 2407 | 2407 | 2407 | 3 | |--------------------------------------------+-----------------+--------+--------+--------+---------| -| totalRewardsSupply | 6737 | 11058 | 11792 | 11903 | 290 | +| totalRewardsSupply | 6759 | 11071 | 11814 | 11925 | 290 | |--------------------------------------------+-----------------+--------+--------+--------+---------| -| totalShares | 4597 | 4597 | 4597 | 4597 | 6 | +| totalShares | 4619 | 4619 | 4619 | 4619 | 6 | |--------------------------------------------+-----------------+--------+--------+--------+---------| -| totalStaked | 2408 | 2408 | 2408 | 2408 | 4167 | +| totalStaked | 2408 | 2408 | 2408 | 2408 | 4168 | |--------------------------------------------+-----------------+--------+--------+--------+---------| -| unstake | 9908 | 40701 | 39803 | 79572 | 271 | +| unstake | 36868 | 39344 | 36894 | 76663 | 258 | |--------------------------------------------+-----------------+--------+--------+--------+---------| -| updateAccount | 347677 | 347677 | 347677 | 347677 | 1 | +| updateAccount | 347651 | 347651 | 347651 | 347651 | 1 | |--------------------------------------------+-----------------+--------+--------+--------+---------| -| updateGlobalState | 15820 | 25876 | 29230 | 29230 | 8 | +| updateGlobalState | 15809 | 25865 | 29219 | 29219 | 8 | |--------------------------------------------+-----------------+--------+--------+--------+---------| -| updateVault | 31948 | 34474 | 31948 | 110579 | 1023 | +| updateVault | 31936 | 34446 | 31936 | 110567 | 1024 | |--------------------------------------------+-----------------+--------+--------+--------+---------| -| upgradeTo | 10279 | 10895 | 10279 | 12745 | 4 | +| upgradeTo | 10323 | 10939 | 10323 | 12789 | 4 | |--------------------------------------------+-----------------+--------+--------+--------+---------| -| upgradeToAndCall | 3228 | 3228 | 3228 | 3228 | 1 | +| upgradeToAndCall | 3161 | 3161 | 3161 | 3161 | 1 | |--------------------------------------------+-----------------+--------+--------+--------+---------| -| vaultShares | 4893 | 4893 | 4893 | 4893 | 12 | +| vaultShares | 4915 | 4915 | 4915 | 4915 | 12 | ╰--------------------------------------------+-----------------+--------+--------+--------+---------╯ ╭----------------------------------------+-----------------+--------+--------+--------+---------╮ @@ -306,7 +306,7 @@ +===============================================================================================+ | Deployment Cost | Deployment Size | | | | | |----------------------------------------+-----------------+--------+--------+--------+---------| -| 1597234 | 7549 | | | | | +| 1623745 | 7673 | | | | | |----------------------------------------+-----------------+--------+--------+--------+---------| | | | | | | | |----------------------------------------+-----------------+--------+--------+--------+---------| @@ -316,33 +316,33 @@ |----------------------------------------+-----------------+--------+--------+--------+---------| | emergencyExit | 15023 | 31463 | 31461 | 48561 | 263 | |----------------------------------------+-----------------+--------+--------+--------+---------| -| initialize | 70234 | 70234 | 70234 | 70234 | 374 | +| initialize | 70212 | 70212 | 70212 | 70212 | 374 | |----------------------------------------+-----------------+--------+--------+--------+---------| -| leave | 43417 | 143791 | 89206 | 353335 | 4 | +| leave | 43439 | 145443 | 89216 | 359902 | 4 | |----------------------------------------+-----------------+--------+--------+--------+---------| -| lock | 19468 | 55620 | 59163 | 98986 | 1034 | +| lock | 21526 | 54657 | 58318 | 80340 | 1034 | |----------------------------------------+-----------------+--------+--------+--------+---------| -| lockUntil | 2385 | 2385 | 2385 | 2385 | 7757 | +| lockUntil | 2363 | 2363 | 2363 | 2363 | 3819 | |----------------------------------------+-----------------+--------+--------+--------+---------| -| migrateToVault | 21788 | 73521 | 29377 | 213541 | 4 | +| migrateFromVault | 24497 | 24497 | 24497 | 24497 | 1 | |----------------------------------------+-----------------+--------+--------+--------+---------| -| owner | 379 | 411 | 379 | 2379 | 369 | +| migrateToVault | 21723 | 78456 | 29358 | 233387 | 4 | |----------------------------------------+-----------------+--------+--------+--------+---------| -| register | 3398 | 79818 | 83144 | 83144 | 374 | +| owner | 402 | 434 | 402 | 2402 | 369 | |----------------------------------------+-----------------+--------+--------+--------+---------| -| stake | 2593 | 163058 | 73202 | 280041 | 2673 | +| register | 3354 | 79838 | 83167 | 83167 | 374 | |----------------------------------------+-----------------+--------+--------+--------+---------| -| stakeManager | 369 | 369 | 369 | 369 | 360 | +| stake | 2636 | 167931 | 72429 | 288304 | 2673 | |----------------------------------------+-----------------+--------+--------+--------+---------| -| unstake(uint256) | 22335 | 54106 | 52230 | 107578 | 272 | +| stakeManager | 347 | 347 | 347 | 347 | 360 | |----------------------------------------+-----------------+--------+--------+--------+---------| -| unstake(uint256,address) | 2652 | 2652 | 2652 | 2652 | 1 | +| unstake(uint256) | 4655 | 52505 | 51424 | 106772 | 272 | |----------------------------------------+-----------------+--------+--------+--------+---------| -| updateLockUntil | 3298 | 19649 | 20398 | 20398 | 524 | +| unstake(uint256,address) | 2630 | 2630 | 2630 | 2630 | 1 | |----------------------------------------+-----------------+--------+--------+--------+---------| -| withdraw(address,uint256) | 13539 | 24440 | 24440 | 35341 | 2 | +| withdraw(address,uint256) | 13561 | 24451 | 24451 | 35341 | 2 | |----------------------------------------+-----------------+--------+--------+--------+---------| -| withdraw(address,uint256,address) | 2752 | 19118 | 19118 | 35484 | 2 | +| withdraw(address,uint256,address) | 2730 | 19096 | 19096 | 35462 | 2 | |----------------------------------------+-----------------+--------+--------+--------+---------| | withdrawFromVault | 20331 | 20331 | 20331 | 20331 | 1 | ╰----------------------------------------+-----------------+--------+--------+--------+---------╯ @@ -358,7 +358,7 @@ |----------------------------------------------------+-----------------+-------+--------+--------+---------| | Function Name | Min | Avg | Median | Max | # Calls | |----------------------------------------------------+-----------------+-------+--------+--------+---------| -| fallback | 5208 | 12834 | 7353 | 374054 | 23157 | +| fallback | 5230 | 12829 | 7353 | 374028 | 23163 | ╰----------------------------------------------------+-----------------+-------+--------+--------+---------╯ ╭--------------------------------------------+-----------------+--------+--------+--------+---------╮ @@ -372,7 +372,7 @@ |--------------------------------------------+-----------------+--------+--------+--------+---------| | Function Name | Min | Avg | Median | Max | # Calls | |--------------------------------------------+-----------------+--------+--------+--------+---------| -| createVault | 145396 | 221995 | 225142 | 225142 | 373 | +| createVault | 145330 | 221994 | 225143 | 225143 | 373 | |--------------------------------------------+-----------------+--------+--------+--------+---------| | vaultImplementation | 2345 | 2345 | 2345 | 2345 | 1 | ╰--------------------------------------------+-----------------+--------+--------+--------+---------╯ @@ -382,7 +382,7 @@ +===============================================================================================================================================+ | Deployment Cost | Deployment Size | | | | | |------------------------------------------------------------------------------------------+-----------------+-------+--------+-------+---------| -| 1204853 | 6207 | | | | | +| 1204853 | 6015 | | | | | |------------------------------------------------------------------------------------------+-----------------+-------+--------+-------+---------| | | | | | | | |------------------------------------------------------------------------------------------+-----------------+-------+--------+-------+---------| @@ -488,13 +488,13 @@ +============================================================================================================+ | Deployment Cost | Deployment Size | | | | | |-----------------------------------------------------------+-----------------+-----+--------+-----+---------| -| 212692 | 769 | | | | | +| 228844 | 844 | | | | | |-----------------------------------------------------------+-----------------+-----+--------+-----+---------| | | | | | | | |-----------------------------------------------------------+-----------------+-----+--------+-----+---------| | Function Name | Min | Avg | Median | Max | # Calls | |-----------------------------------------------------------+-----------------+-----+--------+-----+---------| -| stakedBalanceOf | 376 | 376 | 376 | 376 | 1 | +| stakedBalanceOf | 398 | 398 | 398 | 398 | 1 | ╰-----------------------------------------------------------+-----------------+-----+--------+-----+---------╯ ╭---------------------------------------------+-----------------+-------+--------+-------+---------╮ @@ -508,11 +508,11 @@ |---------------------------------------------+-----------------+-------+--------+-------+---------| | Function Name | Min | Avg | Median | Max | # Calls | |---------------------------------------------+-----------------+-------+--------+-------+---------| -| approve | 26359 | 31544 | 29183 | 46259 | 2676 | +| approve | 29075 | 31546 | 29183 | 46259 | 2676 | |---------------------------------------------+-----------------+-------+--------+-------+---------| -| balanceOf | 2561 | 2561 | 2561 | 2561 | 4965 | +| balanceOf | 2561 | 2561 | 2561 | 2561 | 4966 | |---------------------------------------------+-----------------+-------+--------+-------+---------| -| mint | 33964 | 37263 | 34072 | 68248 | 2688 | +| mint | 33964 | 37264 | 34072 | 68248 | 2688 | ╰---------------------------------------------+-----------------+-------+--------+-------+---------╯ ╭-----------------------------------------------------------------------------+-----------------+--------+--------+--------+---------╮ @@ -520,15 +520,15 @@ +====================================================================================================================================+ | Deployment Cost | Deployment Size | | | | | |-----------------------------------------------------------------------------+-----------------+--------+--------+--------+---------| -| 1232230 | 5554 | | | | | +| 1251192 | 5642 | | | | | |-----------------------------------------------------------------------------+-----------------+--------+--------+--------+---------| | | | | | | | |-----------------------------------------------------------------------------+-----------------+--------+--------+--------+---------| | Function Name | Min | Avg | Median | Max | # Calls | |-----------------------------------------------------------------------------+-----------------+--------+--------+--------+---------| -| leave | 26 | 161074 | 161074 | 322246 | 334 | +| leave | 237 | 164473 | 164473 | 328813 | 333 | |-----------------------------------------------------------------------------+-----------------+--------+--------+--------+---------| -| proxiableUUID | 308 | 308 | 308 | 308 | 1 | +| proxiableUUID | 330 | 330 | 330 | 330 | 1 | ╰-----------------------------------------------------------------------------+-----------------+--------+--------+--------+---------╯ diff --git a/.gas-snapshot b/.gas-snapshot index dcb5fb6..6e38e2a 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -8,24 +8,24 @@ AddRewardDistributorTest:testRemoveUnknownKarmaDistributor() (gas: 41666) AddRewardDistributorTest:testTotalSupply() (gas: 359391) AddRewardDistributorTest:testTransfersNotAllowed() (gas: 61947) AddRewardDistributorTest:test_RevertWhen_SenderIsNotDefaultAdmin() (gas: 68406) -EmergencyExitTest:test_CannotEnableEmergencyModeTwice() (gas: 93554) -EmergencyExitTest:test_CannotLeaveBeforeEmergencyMode() (gas: 332917) -EmergencyExitTest:test_EmergencyExitBasic() (gas: 521406) -EmergencyExitTest:test_EmergencyExitMultipleUsers() (gas: 931267) -EmergencyExitTest:test_EmergencyExitToAlternateAddress() (gas: 475936) -EmergencyExitTest:test_EmergencyExitWithLock() (gas: 448136) -EmergencyExitTest:test_EmergencyExitWithRewards() (gas: 481636) -EmergencyExitTest:test_OnlyOwnerCanEnableEmergencyMode() (gas: 39176) -FuzzTests:testFuzz_AccrueMP(uint128,uint64,uint64) (runs: 1024, μ: 580650, ~: 546005) -FuzzTests:testFuzz_AccrueMP_Relock(uint128,uint64,uint64,uint64) (runs: 1024, μ: 801595, ~: 771127) -FuzzTests:testFuzz_EmergencyExit(uint256,uint256) (runs: 1007, μ: 584678, ~: 575129) -FuzzTests:testFuzz_Lock(uint256,uint64) (runs: 1025, μ: 955205, ~: 955091) -FuzzTests:testFuzz_Relock(uint256,uint64,uint64) (runs: 1025, μ: 591734, ~: 568102) -FuzzTests:testFuzz_Rewards(uint256,uint256,uint256,uint16,uint16) (runs: 1001, μ: 646223, ~: 649020) -FuzzTests:testFuzz_Stake(uint256,uint64) (runs: 1025, μ: 373876, ~: 343023) -FuzzTests:testFuzz_Unstake(uint128,uint64,uint16,uint128) (runs: 1024, μ: 795765, ~: 774510) -FuzzTests:testFuzz_UpdateVault(uint128,uint64,uint64) (runs: 1024, μ: 580673, ~: 546028) -IntegrationTest:testStakeFoo() (gas: 2333475) +EmergencyExitTest:test_CannotEnableEmergencyModeTwice() (gas: 93420) +EmergencyExitTest:test_CannotLeaveBeforeEmergencyMode() (gas: 352335) +EmergencyExitTest:test_EmergencyExitBasic() (gas: 540735) +EmergencyExitTest:test_EmergencyExitMultipleUsers() (gas: 969992) +EmergencyExitTest:test_EmergencyExitToAlternateAddress() (gas: 495287) +EmergencyExitTest:test_EmergencyExitWithLock() (gas: 446582) +EmergencyExitTest:test_EmergencyExitWithRewards() (gas: 500965) +EmergencyExitTest:test_OnlyOwnerCanEnableEmergencyMode() (gas: 39109) +FuzzTests:testFuzz_AccrueMP(uint128,uint64,uint64) (runs: 1024, μ: 581604, ~: 545120) +FuzzTests:testFuzz_AccrueMP_Relock(uint128,uint64,uint64,uint64) (runs: 1024, μ: 802844, ~: 769362) +FuzzTests:testFuzz_EmergencyExit(uint256,uint256) (runs: 1007, μ: 593693, ~: 593595) +FuzzTests:testFuzz_Lock(uint256,uint64) (runs: 1025, μ: 992626, ~: 993766) +FuzzTests:testFuzz_Relock(uint256,uint64,uint64) (runs: 1025, μ: 592561, ~: 566387) +FuzzTests:testFuzz_Rewards(uint256,uint256,uint256,uint16,uint16) (runs: 1001, μ: 645371, ~: 647577) +FuzzTests:testFuzz_Stake(uint256,uint64) (runs: 1025, μ: 377229, ~: 342206) +FuzzTests:testFuzz_Unstake(uint128,uint64,uint16,uint128) (runs: 1024, μ: 794426, ~: 772803) +FuzzTests:testFuzz_UpdateVault(uint128,uint64,uint64) (runs: 1024, μ: 581627, ~: 545143) +IntegrationTest:testStakeFoo() (gas: 2389875) KarmaNFTTest:testApproveNotAllowed() (gas: 10507) KarmaNFTTest:testGetApproved() (gas: 10531) KarmaNFTTest:testIsApprovedForAll() (gas: 10705) @@ -63,23 +63,23 @@ KarmaTiersTest:test_Revert_When_TiersNotStartingAtZero() (gas: 37667) KarmaTiersTest:test_Revert_When_UpdateTiersCalledByNonOwner() (gas: 36642) KarmaTiersTest:test_Success_When_LastTierIsUnlimited() (gas: 242295) KarmaTiersTest:test_Success_When_TiersAreContiguous() (gas: 336294) -LeaveTest:test_LeaveShouldKeepFundsLockedInStakeVault() (gas: 9932270) -LeaveTest:test_LeaveShouldProperlyUpdateAccounting() (gas: 10006034) -LockTest:test_LockFailsWithInvalidPeriod(uint256) (runs: 1025, μ: 378373, ~: 378400) -LockTest:test_LockFailsWithNoStake() (gas: 86612) -LockTest:test_LockFailsWithZero() (gas: 337100) -LockTest:test_LockMultipleTimesExceedMaxLock() (gas: 736511) -LockTest:test_LockWithPriorLock() (gas: 669477) -LockTest:test_LockWithoutPriorLock() (gas: 514566) -LockTest:test_RevertWhenVaultToLockIsEmpty() (gas: 86612) -MaliciousUpgradeTest:test_UpgradeStackOverflowStakeManager() (gas: 2050418) +LeaveTest:test_LeaveShouldKeepFundsLockedInStakeVault() (gas: 9717501) +LeaveTest:test_LeaveShouldProperlyUpdateAccounting() (gas: 9812124) +LockTest:test_LockFailsWithInvalidPeriod(uint256) (runs: 1025, μ: 396949, ~: 396973) +LockTest:test_LockFailsWithNoStake() (gas: 85767) +LockTest:test_LockFailsWithZero() (gas: 358576) +LockTest:test_LockMultipleTimesExceedMaxLock() (gas: 736448) +LockTest:test_LockWithPriorLock() (gas: 668725) +LockTest:test_LockWithoutPriorLock() (gas: 515360) +LockTest:test_RevertWhenVaultToLockIsEmpty() (gas: 85767) +MaliciousUpgradeTest:test_UpgradeStackOverflowStakeManager() (gas: 2095407) MathTest:test_CalcAbsoluteMaxTotalMP() (gas: 5240) MathTest:test_CalcAccrueMP() (gas: 8599) MathTest:test_CalcBonusMP() (gas: 30744) MathTest:test_CalcInitialMP() (gas: 5836) MathTest:test_CalcMaxAccruedMP() (gas: 4886) MathTest:test_CalcMaxTotalMP() (gas: 31506) -MultipleVaultsStakeTest:test_StakeMultipleVaults() (gas: 909679) +MultipleVaultsStakeTest:test_StakeMultipleVaults() (gas: 967977) NFTMetadataGeneratorSVGTest:testGenerateMetadata() (gas: 92580) NFTMetadataGeneratorSVGTest:testSetImageStrings() (gas: 77581) NFTMetadataGeneratorSVGTest:testSetImageStringsRevert() (gas: 35891) @@ -150,69 +150,69 @@ SlashTest:test_RevertWhen_KarmaBalanceIsInvalid() (gas: 71550) SlashTest:test_RevertWhen_SenderIsNotDefaultAdminOrSlasher() (gas: 43232) SlashTest:test_Slash() (gas: 428385) SlashTest:test_SlashRemainingBalanceIfBalanceIsLow() (gas: 251800) -StakeManager_RewardsTest:testRewardsBalanceOf() (gas: 2705933) -StakeManager_RewardsTest:testSetRewards() (gas: 278149) +StakeManager_RewardsTest:testRewardsBalanceOf() (gas: 2745571) +StakeManager_RewardsTest:testSetRewards() (gas: 278063) StakeManager_RewardsTest:testSetRewards_RevertsBadAmount() (gas: 63800) StakeManager_RewardsTest:testSetRewards_RevertsBadDuration() (gas: 103558) StakeManager_RewardsTest:testSetRewards_RevertsNotAuthorized() (gas: 39367) -StakeManager_RewardsTest:testTotalRewardsSupply() (gas: 1277722) -StakeTest:test_StakeMultipleAccounts() (gas: 660608) -StakeTest:test_StakeMultipleAccountsAndRewards() (gas: 715600) -StakeTest:test_StakeMultipleAccountsMPIncreasesMaxMPDoesNotChange() (gas: 1318261) -StakeTest:test_StakeMultipleAccountsWithMinLockUp() (gas: 607740) -StakeTest:test_StakeMultipleAccountsWithRandomLockUp() (gas: 637264) -StakeTest:test_StakeMultipleTimesDoesNotExceedsMaxMP() (gas: 1746485) -StakeTest:test_StakeMultipleTimesWithLockIncreaseAtSameBlock() (gas: 679948) -StakeTest:test_StakeMultipleTimesWithLockZeroAfterMaxLock() (gas: 1169110) -StakeTest:test_StakeOneAccount() (gas: 387262) -StakeTest:test_StakeOneAccountAndRewards() (gas: 442317) -StakeTest:test_StakeOneAccountMPIncreasesMaxMPDoesNotChange() (gas: 822202) -StakeTest:test_StakeOneAccountReachingMPLimit() (gas: 711692) -StakeTest:test_StakeOneAccountWithMaxLockUp() (gas: 377349) -StakeTest:test_StakeOneAccountWithMinLockUp() (gas: 377989) -StakeTest:test_StakeOneAccountWithRandomLockUp() (gas: 378034) -StakeVaultCoverageTest:testOwner() (gas: 15367) -StakeVaultCoverageTest:test_LeaveTransfersAllFunds() (gas: 151083) -StakeVaultCoverageTest:test_StakeRevertsIfNotOwner() (gas: 37215) -StakeVaultCoverageTest:test_StakeTransfersTokensToVault() (gas: 90116) -StakeVaultCoverageTest:test_UnstakeRevertsWithInvalidDestination() (gas: 110127) -StakeVaultCoverageTest:test_UnstakeTransfersTokensBackToOwner() (gas: 138319) -StakeVaultCoverageTest:test_WithdrawOtherTokenTransfersToDestination() (gas: 142293) -StakeVaultCoverageTest:test_WithdrawRevertsIfInsufficientAvailableBalance() (gas: 123327) -StakeVaultCoverageTest:test_WithdrawRevertsIfInvalidDestination() (gas: 111137) +StakeManager_RewardsTest:testTotalRewardsSupply() (gas: 1297734) +StakeTest:test_StakeMultipleAccounts() (gas: 699422) +StakeTest:test_StakeMultipleAccountsAndRewards() (gas: 754392) +StakeTest:test_StakeMultipleAccountsMPIncreasesMaxMPDoesNotChange() (gas: 1357071) +StakeTest:test_StakeMultipleAccountsWithMinLockUp() (gas: 625649) +StakeTest:test_StakeMultipleAccountsWithRandomLockUp() (gas: 634268) +StakeTest:test_StakeMultipleTimesDoesNotExceedsMaxMP() (gas: 1734589) +StakeTest:test_StakeMultipleTimesWithLockIncreaseAtSameBlock() (gas: 676201) +StakeTest:test_StakeMultipleTimesWithLockZeroAfterMaxLock() (gas: 1163144) +StakeTest:test_StakeOneAccount() (gas: 406658) +StakeTest:test_StakeOneAccountAndRewards() (gas: 461691) +StakeTest:test_StakeOneAccountMPIncreasesMaxMPDoesNotChange() (gas: 841530) +StakeTest:test_StakeOneAccountReachingMPLimit() (gas: 731042) +StakeTest:test_StakeOneAccountWithMaxLockUp() (gas: 375840) +StakeTest:test_StakeOneAccountWithMinLockUp() (gas: 376480) +StakeTest:test_StakeOneAccountWithRandomLockUp() (gas: 376525) +StakeVaultCoverageTest:testOwner() (gas: 15390) +StakeVaultCoverageTest:test_LeaveTransfersAllFunds() (gas: 153521) +StakeVaultCoverageTest:test_StakeRevertsIfNotOwner() (gas: 37258) +StakeVaultCoverageTest:test_StakeTransfersTokensToVault() (gas: 92532) +StakeVaultCoverageTest:test_UnstakeRevertsWithInvalidDestination() (gas: 112521) +StakeVaultCoverageTest:test_UnstakeTransfersTokensBackToOwner() (gas: 142860) +StakeVaultCoverageTest:test_WithdrawOtherTokenTransfersToDestination() (gas: 142271) +StakeVaultCoverageTest:test_WithdrawRevertsIfInsufficientAvailableBalance() (gas: 125765) +StakeVaultCoverageTest:test_WithdrawRevertsIfInvalidDestination() (gas: 111115) StakeVaultCoverageTest:test_WithdrawTransfersGenericTokenToOwner() (gas: 139665) -StakeVaultMigrationTest:testMigrateToVault() (gas: 1124585) -StakeVaultMigrationTest:test_RevertWhenDestinationVaultIsNotRegistered() (gas: 163559) -StakeVaultMigrationTest:test_RevertWhenMigrationVaultNotEmpty() (gas: 602480) -StakeVaultMigrationTest:test_RevertWhenNotOwnerOfMigrationVault() (gas: 67303) -StakeVaultTest:testOwner() (gas: 15262) -StakingTokenTest:testOwner() (gas: 15262) +StakeVaultMigrationTest:testMigrateToVault() (gas: 1163794) +StakeVaultMigrationTest:test_RevertWhenDestinationVaultIsNotRegistered() (gas: 163494) +StakeVaultMigrationTest:test_RevertWhenMigrationVaultNotEmpty() (gas: 621880) +StakeVaultMigrationTest:test_RevertWhenNotOwnerOfMigrationVault() (gas: 67284) +StakeVaultTest:testOwner() (gas: 15285) +StakingTokenTest:testOwner() (gas: 15285) StakingTokenTest:testStakeToken() (gas: 13144) -TrustedCodehashAccessTest:test_RevertWhenProxyCloneCodehashNotTrusted() (gas: 1904991) -UnstakeTest:test_RevertWhen_FundsLocked() (gas: 452589) -UnstakeTest:test_StakeMultipleAccounts() (gas: 660587) -UnstakeTest:test_StakeMultipleAccountsAndRewards() (gas: 715644) -UnstakeTest:test_StakeMultipleAccountsMPIncreasesMaxMPDoesNotChange() (gas: 1318327) -UnstakeTest:test_StakeMultipleAccountsWithMinLockUp() (gas: 607806) -UnstakeTest:test_StakeMultipleAccountsWithRandomLockUp() (gas: 637263) -UnstakeTest:test_StakeMultipleTimesDoesNotExceedsMaxMP() (gas: 1746541) -UnstakeTest:test_StakeMultipleTimesWithLockIncreaseAtSameBlock() (gas: 679903) -UnstakeTest:test_StakeMultipleTimesWithLockZeroAfterMaxLock() (gas: 1169121) -UnstakeTest:test_StakeOneAccount() (gas: 387284) -UnstakeTest:test_StakeOneAccountAndRewards() (gas: 442316) -UnstakeTest:test_StakeOneAccountMPIncreasesMaxMPDoesNotChange() (gas: 822201) -UnstakeTest:test_StakeOneAccountReachingMPLimit() (gas: 711672) -UnstakeTest:test_StakeOneAccountWithMaxLockUp() (gas: 377371) -UnstakeTest:test_StakeOneAccountWithMinLockUp() (gas: 377989) -UnstakeTest:test_StakeOneAccountWithRandomLockUp() (gas: 378034) -UnstakeTest:test_UnstakeBonusMPAndAccuredMP() (gas: 747027) -UnstakeTest:test_UnstakeMultipleAccounts() (gas: 1024994) -UnstakeTest:test_UnstakeMultipleAccountsAndRewards() (gas: 1308669) -UnstakeTest:test_UnstakeOneAccount() (gas: 751152) -UnstakeTest:test_UnstakeOneAccountAndAccruedMP() (gas: 713311) -UnstakeTest:test_UnstakeOneAccountAndRewards() (gas: 667503) -UnstakeTest:test_UnstakeOneAccountWithLockUpAndAccruedMP() (gas: 714929) -UpdateVaultTest:test_UpdateAccount() (gas: 2505814) -UpgradeTest:test_RevertWhenNotOwner() (gas: 3696209) -UpgradeTest:test_UpgradeStakeManager() (gas: 9852247) +TrustedCodehashAccessTest:test_RevertWhenProxyCloneCodehashNotTrusted() (gas: 1933652) +UnstakeTest:test_RevertWhen_FundsLocked() (gas: 432938) +UnstakeTest:test_StakeMultipleAccounts() (gas: 699401) +UnstakeTest:test_StakeMultipleAccountsAndRewards() (gas: 754436) +UnstakeTest:test_StakeMultipleAccountsMPIncreasesMaxMPDoesNotChange() (gas: 1357137) +UnstakeTest:test_StakeMultipleAccountsWithMinLockUp() (gas: 625715) +UnstakeTest:test_StakeMultipleAccountsWithRandomLockUp() (gas: 634267) +UnstakeTest:test_StakeMultipleTimesDoesNotExceedsMaxMP() (gas: 1734645) +UnstakeTest:test_StakeMultipleTimesWithLockIncreaseAtSameBlock() (gas: 676156) +UnstakeTest:test_StakeMultipleTimesWithLockZeroAfterMaxLock() (gas: 1163155) +UnstakeTest:test_StakeOneAccount() (gas: 406680) +UnstakeTest:test_StakeOneAccountAndRewards() (gas: 461690) +UnstakeTest:test_StakeOneAccountMPIncreasesMaxMPDoesNotChange() (gas: 841529) +UnstakeTest:test_StakeOneAccountReachingMPLimit() (gas: 731022) +UnstakeTest:test_StakeOneAccountWithMaxLockUp() (gas: 375862) +UnstakeTest:test_StakeOneAccountWithMinLockUp() (gas: 376480) +UnstakeTest:test_StakeOneAccountWithRandomLockUp() (gas: 376525) +UnstakeTest:test_UnstakeBonusMPAndAccuredMP() (gas: 744854) +UnstakeTest:test_UnstakeMultipleAccounts() (gas: 1062174) +UnstakeTest:test_UnstakeMultipleAccountsAndRewards() (gas: 1345299) +UnstakeTest:test_UnstakeOneAccount() (gas: 769214) +UnstakeTest:test_UnstakeOneAccountAndAccruedMP() (gas: 731845) +UnstakeTest:test_UnstakeOneAccountAndRewards() (gas: 686049) +UnstakeTest:test_UnstakeOneAccountWithLockUpAndAccruedMP() (gas: 712558) +UpdateVaultTest:test_UpdateAccount() (gas: 2583507) +UpgradeTest:test_RevertWhenNotOwner() (gas: 3586110) +UpgradeTest:test_UpgradeStakeManager() (gas: 9658332) VaultRegistrationTest:test_VaultRegistration() (gas: 90138) \ No newline at end of file diff --git a/certora/specs/EmergencyMode.spec b/certora/specs/EmergencyMode.spec index d11f109..06fe9bd 100644 --- a/certora/specs/EmergencyMode.spec +++ b/certora/specs/EmergencyMode.spec @@ -33,8 +33,8 @@ definition noCallDuringEmergency(method f) returns bool = ( || f.selector == sig:streamer.updateAccount(address).selector || f.selector == sig:streamer.updateVault(address).selector || f.selector == sig:streamer.unstake(uint256).selector - || f.selector == sig:streamer.stake(uint256, uint256).selector - || f.selector == sig:streamer.lock(uint256).selector + || f.selector == sig:streamer.stake(uint256, uint256, uint256).selector + || f.selector == sig:streamer.lock(uint256, uint256).selector || f.selector == sig:enableEmergencyMode().selector ); diff --git a/certora/specs/StakeManager.spec b/certora/specs/StakeManager.spec index 1e138b9..900282d 100644 --- a/certora/specs/StakeManager.spec +++ b/certora/specs/StakeManager.spec @@ -16,7 +16,7 @@ methods { function leave() external; function Math.mulDiv(uint256 a, uint256 b, uint256 c) internal returns uint256 => mulDivSummary(a,b,c); - function _.updateLockUntil(uint256 _lockUntil) external => DISPATCHER(true); + function _.migrateFromVault(uint256 _lockUntil) external => DISPATCHER(true); function _.lockUntil() external => DISPATCHER(true); } @@ -80,7 +80,7 @@ rule stakingMintsMultiplierPoints1To1Ratio { multiplierPointsBefore = getVaultMPAccrued(e.msg.sender); - stake(e, amount, lockupTime); + stake(e, amount, lockupTime, 0); // we need to ensure time has not progressed because that would accrue MP // which makes it harder to proof this rule @@ -103,10 +103,10 @@ rule stakingGreaterLockupTimeMeansGreaterMPs { storage initalStorage = lastStorage; - stake(e, amount, lockupTime1); + stake(e, amount, lockupTime1, 0); multiplierPointsAfter1 = getVaultMPAccrued(e.msg.sender); - stake(e, amount, lockupTime2) at initalStorage; + stake(e, amount, lockupTime2, 0) at initalStorage; multiplierPointsAfter2 = getVaultMPAccrued(e.msg.sender); assert lockupTime1 >= lockupTime2 => to_mathint(multiplierPointsAfter1) >= to_mathint(multiplierPointsAfter2); diff --git a/src/StakeManager.sol b/src/StakeManager.sol index a13cb67..de6a88f 100644 --- a/src/StakeManager.sol +++ b/src/StakeManager.sol @@ -169,12 +169,14 @@ contract StakeManager is */ function stake( uint256 amount, - uint256 lockPeriod + uint256 lockPeriod, + uint256 currentLockUntil ) external onlyTrustedCodehash onlyNotEmergencyMode onlyRegisteredVault + returns (uint256 newLockUntil) { if (amount == 0) { revert StakeManager__AmountCannotBeZero(); @@ -185,18 +187,14 @@ contract StakeManager is VaultData storage vault = vaultData[msg.sender]; - (uint256 _deltaMpTotal, uint256 _deltaMPMax, uint256 _newLockEnd) = _calculateStake( - vault.stakedBalance, vault.maxMP, IStakeVault(msg.sender).lockUntil(), block.timestamp, amount, lockPeriod - ); + (uint256 _deltaMpTotal, uint256 _deltaMPMax, uint256 newLockEnd) = + _calculateStake(vault.stakedBalance, vault.maxMP, currentLockUntil, block.timestamp, amount, lockPeriod); + newLockUntil = newLockEnd; vault.stakedBalance += amount; totalStaked += amount; totalMPStaked += _deltaMpTotal; - if (lockPeriod != 0) { - IStakeVault(msg.sender).updateLockUntil(_newLockEnd); - } - vault.mpAccrued += _deltaMpTotal; totalMPAccrued += _deltaMpTotal; @@ -215,7 +213,16 @@ contract StakeManager is * @dev Only registered vaults are allowed to lock. * @param lockPeriod The duration to lock the stake */ - function lock(uint256 lockPeriod) external onlyTrustedCodehash onlyNotEmergencyMode onlyRegisteredVault { + function lock( + uint256 lockPeriod, + uint256 currentLockUntil + ) + external + onlyTrustedCodehash + onlyNotEmergencyMode + onlyRegisteredVault + returns (uint256 newLockUntil) + { VaultData storage vault = vaultData[msg.sender]; if (lockPeriod == 0) { @@ -224,14 +231,13 @@ contract StakeManager is _updateGlobalState(); _updateVault(msg.sender, false); - (uint256 deltaMp, uint256 newLockEnd) = _calculateLock( - vault.stakedBalance, vault.maxMP, IStakeVault(msg.sender).lockUntil(), block.timestamp, lockPeriod - ); + (uint256 deltaMp, uint256 newLockEnd) = + _calculateLock(vault.stakedBalance, vault.maxMP, currentLockUntil, block.timestamp, lockPeriod); + newLockUntil = newLockEnd; // Update account state vault.mpAccrued += deltaMp; vault.maxMP += deltaMp; - IStakeVault(msg.sender).updateLockUntil(newLockEnd); // Update global state totalMPAccrued += deltaMp; @@ -252,9 +258,6 @@ contract StakeManager is * @param amount The amount of tokens to unstake */ function unstake(uint256 amount) external onlyTrustedCodehash onlyNotEmergencyMode onlyRegisteredVault { - if (IStakeVault(msg.sender).lockUntil() > block.timestamp) { - revert StakeManager__FundsLocked(); - } VaultData storage vault = vaultData[msg.sender]; _unstake(amount, vault, msg.sender); emit Unstaked(msg.sender, amount); @@ -386,7 +389,7 @@ contract StakeManager is newVault.maxMP = oldVault.maxMP; newVault.lastMPUpdateTime = oldVault.lastMPUpdateTime; newVault.rewardsAccrued = oldVault.rewardsAccrued; - IStakeVault(migrateTo).updateLockUntil(IStakeVault(msg.sender).lockUntil()); + IStakeVault(migrateTo).migrateFromVault(IStakeVault(msg.sender).lockUntil()); delete vaultData[msg.sender]; diff --git a/src/StakeVault.sol b/src/StakeVault.sol index 107f26c..85b90b3 100644 --- a/src/StakeVault.sol +++ b/src/StakeVault.sol @@ -128,7 +128,7 @@ contract StakeVault is IStakeVault, Initializable, OwnableUpgradeable { * @param _seconds The time period to lock the staked amount for. */ function lock(uint256 _seconds) external onlyOwner { - stakeManager.lock(_seconds); + lockUntil = stakeManager.lock(_seconds, lockUntil); } /** @@ -192,6 +192,18 @@ contract StakeVault is IStakeVault, Initializable, OwnableUpgradeable { } } + /** + * @notice Updates the lock until timestamp. + * @dev This function is only callable by the stake manager. + * @param _lockUntil The new lock until timestamp. + */ + function migrateFromVault(uint256 _lockUntil) external { + if (msg.sender != address(stakeManager)) { + revert StakeVault__NotAuthorized(); + } + lockUntil = _lockUntil; + } + /** * @notice Withdraw tokens from the contract. * @dev This function is only callable by the owner. @@ -254,18 +266,6 @@ contract StakeVault is IStakeVault, Initializable, OwnableUpgradeable { return _token.balanceOf(address(this)); } - /** - * @notice Updates the lock until timestamp. - * @dev This function is only callable by the trusted stake manager. - * @param _lockUntil The new lock until timestamp. - */ - function updateLockUntil(uint256 _lockUntil) external { - if (msg.sender != address(stakeManager)) { - revert StakeVault__NotAuthorized(); - } - lockUntil = _lockUntil; - } - /*////////////////////////////////////////////////////////////////////////// INTERNAL FUNCTIONS //////////////////////////////////////////////////////////////////////////*/ @@ -278,7 +278,7 @@ contract StakeVault is IStakeVault, Initializable, OwnableUpgradeable { * @param _source The address from which tokens will be transferred. */ function _stake(uint256 _amount, uint256 _seconds, address _source) internal { - stakeManager.stake(_amount, _seconds); + lockUntil = stakeManager.stake(_amount, _seconds, lockUntil); bool success = STAKING_TOKEN.transferFrom(_source, address(this), _amount); if (!success) { revert StakeVault__StakingFailed(); @@ -292,6 +292,9 @@ contract StakeVault is IStakeVault, Initializable, OwnableUpgradeable { * @param _destination The address to receive the unstaked tokens. */ function _unstake(uint256 _amount, address _destination) internal { + if (lockUntil > block.timestamp) { + revert StakeVault__FundsLocked(); + } stakeManager.unstake(_amount); bool success = STAKING_TOKEN.transfer(_destination, _amount); if (!success) { diff --git a/src/interfaces/IStakeManager.sol b/src/interfaces/IStakeManager.sol index fdb2e70..92c991f 100644 --- a/src/interfaces/IStakeManager.sol +++ b/src/interfaces/IStakeManager.sol @@ -54,8 +54,14 @@ interface IStakeManager is ITrustedCodehashAccess, IStakeConstants { event VaultUpdated(address indexed vault, uint256 rewardsAccrued, uint256 mpAccrued); function registerVault() external; - function stake(uint256 _amount, uint256 _seconds) external; - function lock(uint256 _seconds) external; + function stake( + uint256 _amount, + uint256 _seconds, + uint256 _currentLockUntil + ) + external + returns (uint256 _lockUntil); + function lock(uint256 _seconds, uint256 _currentLockUntil) external returns (uint256 _lockUntil); function unstake(uint256 _amount) external; function leave() external; function migrateToVault(address migrateTo) external; diff --git a/src/interfaces/IStakeVault.sol b/src/interfaces/IStakeVault.sol index 345a984..b9627e6 100644 --- a/src/interfaces/IStakeVault.sol +++ b/src/interfaces/IStakeVault.sol @@ -8,5 +8,5 @@ interface IStakeVault { function stakeManager() external view returns (IStakeManagerProxy); function register() external; function lockUntil() external view returns (uint256); - function updateLockUntil(uint256 newLockUntil) external; + function migrateFromVault(uint256 newLockUntil) external; } diff --git a/test/RewardsStreamerMP.t.sol b/test/RewardsStreamerMP.t.sol index 6fdc2cc..7404dd5 100644 --- a/test/RewardsStreamerMP.t.sol +++ b/test/RewardsStreamerMP.t.sol @@ -1401,7 +1401,7 @@ contract UnstakeTest is StakeTest { _stake(alice, stakeAmount, lockUpPeriod); // Alice tries to unstake before lock up period has expired - vm.expectRevert(IStakeManager.StakeManager__FundsLocked.selector); + vm.expectRevert(StakeVault.StakeVault__FundsLocked.selector); _unstake(alice, stakeAmount); vm.warp(vm.getBlockTimestamp() + lockUpPeriod); @@ -2962,8 +2962,8 @@ contract FuzzTests is StakeManagerTest { function _expectUnstake(address account, uint256 amount) internal { CheckVaultParams storage expectedAccountParams = expectedAccountState[account]; expectedAccountParams.account = vaults[account]; - if (expectedVaultLockState[expectedAccountParams.account].lockEnd >= vm.getBlockTimestamp()) { - expectedRevert = IStakeManager.StakeManager__FundsLocked.selector; + if (expectedVaultLockState[expectedAccountParams.account].lockEnd > vm.getBlockTimestamp()) { + expectedRevert = StakeVault.StakeVault__FundsLocked.selector; return; } if (amount == 0) { @@ -3031,8 +3031,8 @@ contract FuzzTests is StakeManagerTest { if (lockUpPeriod > 0) { //update lockup end expectedVaultLockState[expectedAccountParams.account].totalLockUp += lockUpPeriod; - expectedVaultLockState[expectedAccountParams.account].lockEnd = calcLockEnd; } + expectedVaultLockState[expectedAccountParams.account].lockEnd = calcLockEnd; expectedAccountParams.stakedBalance = stakeAmount; expectedAccountParams.vaultBalance = stakeAmount; expectedSystemState.stakingBalance += stakeAmount; diff --git a/test/mocks/MockStakeManager.sol b/test/mocks/MockStakeManager.sol index 5bbbccc..48d319f 100644 --- a/test/mocks/MockStakeManager.sol +++ b/test/mocks/MockStakeManager.sol @@ -21,12 +21,12 @@ contract MockStakeManager is ITrustedCodehashAccess, IStakeManager { return; } - function stake(uint256, uint256) external { - return; + function stake(uint256, uint256, uint256) external returns (uint256) { + return 0; } - function lock(uint256) external { - return; + function lock(uint256, uint256) external returns (uint256) { + return 0; } function unstake(uint256) external { diff --git a/test/mocks/StackOverflowStakeManager.sol b/test/mocks/StackOverflowStakeManager.sol index 2b5406c..26c042b 100644 --- a/test/mocks/StackOverflowStakeManager.sol +++ b/test/mocks/StackOverflowStakeManager.sol @@ -41,11 +41,19 @@ contract StackOverflowStakeManager is UUPSUpgradeable, IStakeManager, TrustedCod // implementation } // solhint-disable-next-line - function lock(uint256 _seconds) external override { + function lock(uint256 _seconds, uint256 _currentLockUntil) external override returns (uint256 _lockUntil) { // implementation } // solhint-disable-next-line - function stake(uint256 _amount, uint256 _seconds) external override { + function stake( + uint256 _amount, + uint256 _seconds, + uint256 _currentLockUntil + ) + external + override + returns (uint256 _lockUntil) + { // implementation } // solhint-disable-next-line @@ -76,7 +84,7 @@ contract StackOverflowStakeManager is UUPSUpgradeable, IStakeManager, TrustedCod } // solhint-disable-next-line - function migrateToVault(address _migrateTo) external { + function migrateToVault(address _migrateTo) external override { // implementation } }