Skip to content

Commit 0544c0e

Browse files
committed
refactor(RewardStreamerMP): extract MP and Stake mathematical formulas to abstract contracts
1 parent 9807f49 commit 0544c0e

File tree

10 files changed

+614
-336
lines changed

10 files changed

+614
-336
lines changed

.gas-report

Lines changed: 60 additions & 87 deletions
Large diffs are not rendered by default.

.gas-snapshot

Lines changed: 65 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,74 +1,75 @@
1-
EmergencyExitTest:test_CannotEnableEmergencyModeTwice() (gas: 92734)
2-
EmergencyExitTest:test_CannotLeaveBeforeEmergencyMode() (gas: 299008)
3-
EmergencyExitTest:test_EmergencyExitBasic() (gas: 385662)
4-
EmergencyExitTest:test_EmergencyExitMultipleUsers() (gas: 664160)
5-
EmergencyExitTest:test_EmergencyExitToAlternateAddress() (gas: 393691)
6-
EmergencyExitTest:test_EmergencyExitWithLock() (gas: 393030)
7-
EmergencyExitTest:test_EmergencyExitWithRewards() (gas: 378630)
8-
EmergencyExitTest:test_OnlyOwnerCanEnableEmergencyMode() (gas: 39470)
9-
IntegrationTest:testStakeFoo() (gas: 1212157)
10-
LeaveTest:test_LeaveShouldProperlyUpdateAccounting() (gas: 5836880)
11-
LeaveTest:test_RevertWhenStakeManagerIsTrusted() (gas: 296161)
12-
LeaveTest:test_TrustNewStakeManager() (gas: 5907277)
13-
LockTest:test_LockFailsWithInvalidPeriod() (gas: 311224)
14-
LockTest:test_LockFailsWithNoStake() (gas: 63663)
15-
LockTest:test_LockWithoutPriorLock() (gas: 390931)
16-
MaliciousUpgradeTest:test_UpgradeStackOverflowStakeManager() (gas: 1746581)
17-
MathTest:test_CalcAbsoluteMaxTotalMP() (gas: 18995)
18-
MathTest:test_CalcAccrueMP() (gas: 22229)
19-
MathTest:test_CalcBonusMP() (gas: 17645)
20-
MathTest:test_CalcInitialMP() (gas: 5330)
21-
MathTest:test_CalcMaxAccruedMP() (gas: 15696)
22-
MathTest:test_CalcMaxTotalMP() (gas: 23339)
23-
MultipleVaultsStakeTest:test_StakeMultipleVaults() (gas: 725540)
1+
EmergencyExitTest:test_CannotEnableEmergencyModeTwice() (gas: 92757)
2+
EmergencyExitTest:test_CannotLeaveBeforeEmergencyMode() (gas: 300544)
3+
EmergencyExitTest:test_EmergencyExitBasic() (gas: 387340)
4+
EmergencyExitTest:test_EmergencyExitMultipleUsers() (gas: 667427)
5+
EmergencyExitTest:test_EmergencyExitToAlternateAddress() (gas: 395139)
6+
EmergencyExitTest:test_EmergencyExitWithLock() (gas: 394708)
7+
EmergencyExitTest:test_EmergencyExitWithRewards() (gas: 380241)
8+
EmergencyExitTest:test_OnlyOwnerCanEnableEmergencyMode() (gas: 39471)
9+
IntegrationTest:testStakeFoo() (gas: 1218594)
10+
LeaveTest:test_LeaveShouldProperlyUpdateAccounting() (gas: 6214173)
11+
LeaveTest:test_RevertWhenStakeManagerIsTrusted() (gas: 297675)
12+
LeaveTest:test_TrustNewStakeManager() (gas: 6269901)
13+
LockTest:test_LockFailsWithInvalidPeriod(uint256) (runs: 1002, μ: 344783, ~: 344801)
14+
LockTest:test_LockFailsWithNoStake() (gas: 102637)
15+
LockTest:test_LockFailsWithZero() (gas: 315022)
16+
LockTest:test_LockWithoutPriorLock() (gas: 393335)
17+
MaliciousUpgradeTest:test_UpgradeStackOverflowStakeManager() (gas: 1752531)
18+
MathTest:test_CalcAbsoluteMaxTotalMP() (gas: 4996)
19+
MathTest:test_CalcAccrueMP() (gas: 7990)
20+
MathTest:test_CalcBonusMP() (gas: 18676)
21+
MathTest:test_CalcInitialMP() (gas: 5352)
22+
MathTest:test_CalcMaxAccruedMP() (gas: 4642)
23+
MathTest:test_CalcMaxTotalMP() (gas: 19449)
24+
MultipleVaultsStakeTest:test_StakeMultipleVaults() (gas: 731369)
2425
NFTMetadataGeneratorSVGTest:testGenerateMetadata() (gas: 85934)
2526
NFTMetadataGeneratorSVGTest:testSetImageStrings() (gas: 58332)
2627
NFTMetadataGeneratorSVGTest:testSetImageStringsRevert() (gas: 35804)
2728
NFTMetadataGeneratorURLTest:testGenerateMetadata() (gas: 102512)
2829
NFTMetadataGeneratorURLTest:testSetBaseURL() (gas: 49555)
2930
NFTMetadataGeneratorURLTest:testSetBaseURLRevert() (gas: 35979)
30-
RewardsStreamerMP_RewardsTest:testRewardsBalanceOf() (gas: 486274)
31-
RewardsStreamerMP_RewardsTest:testSetRewards() (gas: 160637)
32-
RewardsStreamerMP_RewardsTest:testSetRewards_RevertsBadAmount() (gas: 39317)
33-
RewardsStreamerMP_RewardsTest:testSetRewards_RevertsBadDuration() (gas: 39340)
34-
RewardsStreamerMP_RewardsTest:testSetRewards_RevertsNotAuthorized() (gas: 39375)
35-
RewardsStreamerMP_RewardsTest:testTotalRewardsSupply() (gas: 618553)
36-
StakeTest:test_StakeMultipleAccounts() (gas: 499457)
37-
StakeTest:test_StakeMultipleAccountsAndRewards() (gas: 505374)
38-
StakeTest:test_StakeMultipleAccountsMPIncreasesMaxMPDoesNotChange() (gas: 842563)
39-
StakeTest:test_StakeMultipleAccountsWithMinLockUp() (gas: 515891)
40-
StakeTest:test_StakeMultipleAccountsWithRandomLockUp() (gas: 538001)
41-
StakeTest:test_StakeOneAccount() (gas: 278207)
42-
StakeTest:test_StakeOneAccountAndRewards() (gas: 284155)
43-
StakeTest:test_StakeOneAccountMPIncreasesMaxMPDoesNotChange() (gas: 507692)
44-
StakeTest:test_StakeOneAccountReachingMPLimit() (gas: 499083)
45-
StakeTest:test_StakeOneAccountWithMaxLockUp() (gas: 298124)
46-
StakeTest:test_StakeOneAccountWithMinLockUp() (gas: 299768)
47-
StakeTest:test_StakeOneAccountWithRandomLockUp() (gas: 299857)
31+
RewardsStreamerMP_RewardsTest:testRewardsBalanceOf() (gas: 490632)
32+
RewardsStreamerMP_RewardsTest:testSetRewards() (gas: 160880)
33+
RewardsStreamerMP_RewardsTest:testSetRewards_RevertsBadAmount() (gas: 39384)
34+
RewardsStreamerMP_RewardsTest:testSetRewards_RevertsBadDuration() (gas: 39407)
35+
RewardsStreamerMP_RewardsTest:testSetRewards_RevertsNotAuthorized() (gas: 39442)
36+
RewardsStreamerMP_RewardsTest:testTotalRewardsSupply() (gas: 620722)
37+
StakeTest:test_StakeMultipleAccounts() (gas: 502561)
38+
StakeTest:test_StakeMultipleAccountsAndRewards() (gas: 508596)
39+
StakeTest:test_StakeMultipleAccountsMPIncreasesMaxMPDoesNotChange() (gas: 847390)
40+
StakeTest:test_StakeMultipleAccountsWithMinLockUp() (gas: 517705)
41+
StakeTest:test_StakeMultipleAccountsWithRandomLockUp() (gas: 539649)
42+
StakeTest:test_StakeOneAccount() (gas: 279841)
43+
StakeTest:test_StakeOneAccountAndRewards() (gas: 285896)
44+
StakeTest:test_StakeOneAccountMPIncreasesMaxMPDoesNotChange() (gas: 510467)
45+
StakeTest:test_StakeOneAccountReachingMPLimit() (gas: 500009)
46+
StakeTest:test_StakeOneAccountWithMaxLockUp() (gas: 300111)
47+
StakeTest:test_StakeOneAccountWithMinLockUp() (gas: 300696)
48+
StakeTest:test_StakeOneAccountWithRandomLockUp() (gas: 300763)
4849
StakingTokenTest:testStakeToken() (gas: 10422)
49-
UnstakeTest:test_StakeMultipleAccounts() (gas: 499479)
50-
UnstakeTest:test_StakeMultipleAccountsAndRewards() (gas: 505396)
51-
UnstakeTest:test_StakeMultipleAccountsMPIncreasesMaxMPDoesNotChange() (gas: 842585)
52-
UnstakeTest:test_StakeMultipleAccountsWithMinLockUp() (gas: 515935)
53-
UnstakeTest:test_StakeMultipleAccountsWithRandomLockUp() (gas: 537957)
54-
UnstakeTest:test_StakeOneAccount() (gas: 278230)
55-
UnstakeTest:test_StakeOneAccountAndRewards() (gas: 284133)
56-
UnstakeTest:test_StakeOneAccountMPIncreasesMaxMPDoesNotChange() (gas: 507736)
57-
UnstakeTest:test_StakeOneAccountReachingMPLimit() (gas: 499040)
58-
UnstakeTest:test_StakeOneAccountWithMaxLockUp() (gas: 298124)
59-
UnstakeTest:test_StakeOneAccountWithMinLockUp() (gas: 299768)
60-
UnstakeTest:test_StakeOneAccountWithRandomLockUp() (gas: 299856)
61-
UnstakeTest:test_UnstakeBonusMPAndAccuredMP() (gas: 546251)
62-
UnstakeTest:test_UnstakeMultipleAccounts() (gas: 704925)
63-
UnstakeTest:test_UnstakeMultipleAccountsAndRewards() (gas: 800718)
64-
UnstakeTest:test_UnstakeOneAccount() (gas: 479941)
65-
UnstakeTest:test_UnstakeOneAccountAndAccruedMP() (gas: 502893)
66-
UnstakeTest:test_UnstakeOneAccountAndRewards() (gas: 409031)
67-
UnstakeTest:test_UnstakeOneAccountWithLockUpAndAccruedMP() (gas: 531430)
68-
UpgradeTest:test_RevertWhenNotOwner() (gas: 2709437)
69-
UpgradeTest:test_UpgradeStakeManager() (gas: 5749376)
70-
VaultRegistrationTest:test_VaultRegistration() (gas: 62017)
71-
WithdrawTest:test_CannotWithdrawStakedFunds() (gas: 311841)
50+
UnstakeTest:test_StakeMultipleAccounts() (gas: 502560)
51+
UnstakeTest:test_StakeMultipleAccountsAndRewards() (gas: 508640)
52+
UnstakeTest:test_StakeMultipleAccountsMPIncreasesMaxMPDoesNotChange() (gas: 847367)
53+
UnstakeTest:test_StakeMultipleAccountsWithMinLockUp() (gas: 517704)
54+
UnstakeTest:test_StakeMultipleAccountsWithRandomLockUp() (gas: 539693)
55+
UnstakeTest:test_StakeOneAccount() (gas: 279841)
56+
UnstakeTest:test_StakeOneAccountAndRewards() (gas: 285874)
57+
UnstakeTest:test_StakeOneAccountMPIncreasesMaxMPDoesNotChange() (gas: 510511)
58+
UnstakeTest:test_StakeOneAccountReachingMPLimit() (gas: 500008)
59+
UnstakeTest:test_StakeOneAccountWithMaxLockUp() (gas: 300111)
60+
UnstakeTest:test_StakeOneAccountWithMinLockUp() (gas: 300718)
61+
UnstakeTest:test_StakeOneAccountWithRandomLockUp() (gas: 300762)
62+
UnstakeTest:test_UnstakeBonusMPAndAccuredMP() (gas: 546541)
63+
UnstakeTest:test_UnstakeMultipleAccounts() (gas: 707663)
64+
UnstakeTest:test_UnstakeMultipleAccountsAndRewards() (gas: 803659)
65+
UnstakeTest:test_UnstakeOneAccount() (gas: 481480)
66+
UnstakeTest:test_UnstakeOneAccountAndAccruedMP() (gas: 505028)
67+
UnstakeTest:test_UnstakeOneAccountAndRewards() (gas: 410671)
68+
UnstakeTest:test_UnstakeOneAccountWithLockUpAndAccruedMP() (gas: 530083)
69+
UpgradeTest:test_RevertWhenNotOwner() (gas: 2897740)
70+
UpgradeTest:test_UpgradeStakeManager() (gas: 6114750)
71+
VaultRegistrationTest:test_VaultRegistration() (gas: 62154)
72+
WithdrawTest:test_CannotWithdrawStakedFunds() (gas: 313397)
7273
XPNFTTokenTest:testApproveNotAllowed() (gas: 10500)
7374
XPNFTTokenTest:testGetApproved() (gas: 10523)
7475
XPNFTTokenTest:testIsApprovedForAll() (gas: 10698)

certora/specs/EmergencyMode.spec

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,12 @@ definition isViewFunction(method f) returns bool = (
99
f.selector == sig:streamer.YEAR().selector ||
1010
f.selector == sig:streamer.STAKING_TOKEN().selector ||
1111
f.selector == sig:streamer.SCALE_FACTOR().selector ||
12-
f.selector == sig:streamer.MP_RATE_PER_YEAR().selector ||
12+
f.selector == sig:streamer.MP_APY().selector ||
13+
f.selector == sig:streamer.MP_MPY().selector ||
14+
f.selector == sig:streamer.MP_MPY_ABSOLUTE().selector ||
15+
f.selector == sig:streamer.ACCRUE_RATE().selector ||
16+
f.selector == sig:streamer.MIN_BALANCE().selector ||
17+
f.selector == sig:streamer.MAX_BALANCE().selector ||
1318
f.selector == sig:streamer.MIN_LOCKUP_PERIOD().selector ||
1419
f.selector == sig:streamer.MAX_LOCKUP_PERIOD().selector ||
1520
f.selector == sig:streamer.MAX_MULTIPLIER().selector ||

src/RewardsStreamerMP.sol

Lines changed: 37 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { IStakeManager } from "./interfaces/IStakeManager.sol";
1010
import { IStakeVault } from "./interfaces/IStakeVault.sol";
1111
import { IRewardProvider } from "./interfaces/IRewardProvider.sol";
1212
import { TrustedCodehashAccess } from "./TrustedCodehashAccess.sol";
13+
import { StakeMath } from "./math/StakeMath.sol";
1314

1415
// Rewards Streamer with Multiplier Points
1516
contract RewardsStreamerMP is
@@ -18,15 +19,16 @@ contract RewardsStreamerMP is
1819
IStakeManager,
1920
TrustedCodehashAccess,
2021
ReentrancyGuardUpgradeable,
21-
IRewardProvider
22+
IRewardProvider,
23+
StakeMath
2224
{
2325
error StakingManager__InvalidVault();
2426
error StakingManager__VaultNotRegistered();
2527
error StakingManager__VaultAlreadyRegistered();
2628
error StakingManager__AmountCannotBeZero();
2729
error StakingManager__TransferFailed();
2830
error StakingManager__InsufficientBalance();
29-
error StakingManager__InvalidLockingPeriod();
31+
error StakingManager__LockingPeriodCannotBeZero();
3032
error StakingManager__CannotRestakeWithLockedFunds();
3133
error StakingManager__TokensAreLocked();
3234
error StakingManager__AlreadyLocked();
@@ -36,12 +38,6 @@ contract RewardsStreamerMP is
3638
IERC20 public STAKING_TOKEN;
3739

3840
uint256 public constant SCALE_FACTOR = 1e18;
39-
uint256 public constant MP_RATE_PER_YEAR = 1;
40-
41-
uint256 public constant YEAR = 365 days;
42-
uint256 public constant MIN_LOCKUP_PERIOD = 90 days;
43-
uint256 public constant MAX_LOCKUP_PERIOD = 4 * YEAR;
44-
uint256 public constant MAX_MULTIPLIER = 4;
4541

4642
uint256 public totalStaked;
4743
uint256 public totalMPAccrued;
@@ -193,40 +189,30 @@ contract RewardsStreamerMP is
193189
revert StakingManager__AmountCannotBeZero();
194190
}
195191

196-
if (lockPeriod != 0 && (lockPeriod < MIN_LOCKUP_PERIOD || lockPeriod > MAX_LOCKUP_PERIOD)) {
197-
revert StakingManager__InvalidLockingPeriod();
198-
}
199-
200192
_updateGlobalState();
201193
_updateVaultMP(msg.sender, true);
202194

203195
VaultData storage vault = vaultData[msg.sender];
204196
if (vault.lockUntil != 0 && vault.lockUntil > block.timestamp) {
205197
revert StakingManager__CannotRestakeWithLockedFunds();
206198
}
199+
(uint256 _deltaMpTotal, uint256 _deltaMPMax, uint256 _newLockEnd) =
200+
_calculateStake(vault.stakedBalance, vault.maxMP, vault.lockUntil, block.timestamp, amount, lockPeriod);
207201

208202
vault.stakedBalance += amount;
209203
totalStaked += amount;
210204

211-
uint256 initialMP = amount;
212-
uint256 potentialMP = amount * MAX_MULTIPLIER;
213-
uint256 bonusMP = 0;
214-
215205
if (lockPeriod != 0) {
216-
bonusMP = _calculateBonusMP(amount, lockPeriod);
217-
vault.lockUntil = block.timestamp + lockPeriod;
206+
vault.lockUntil = _newLockEnd;
218207
} else {
219208
vault.lockUntil = 0;
220209
}
221210

222-
uint256 vaultMaxMP = initialMP + bonusMP + potentialMP;
223-
uint256 vaultMP = initialMP + bonusMP;
224-
225-
vault.mpAccrued += vaultMP;
226-
totalMPAccrued += vaultMP;
211+
vault.mpAccrued += _deltaMpTotal;
212+
totalMPAccrued += _deltaMpTotal;
227213

228-
vault.maxMP += vaultMaxMP;
229-
totalMaxMP += vaultMaxMP;
214+
vault.maxMP += _deltaMPMax;
215+
totalMaxMP += _deltaMPMax;
230216

231217
vault.rewardIndex = rewardIndex;
232218
}
@@ -238,33 +224,29 @@ contract RewardsStreamerMP is
238224
onlyRegisteredVault
239225
nonReentrant
240226
{
241-
if (lockPeriod < MIN_LOCKUP_PERIOD || lockPeriod > MAX_LOCKUP_PERIOD) {
242-
revert StakingManager__InvalidLockingPeriod();
243-
}
244-
245227
VaultData storage vault = vaultData[msg.sender];
246228

247229
if (vault.lockUntil > 0) {
248230
revert StakingManager__AlreadyLocked();
249231
}
250232

251-
if (vault.stakedBalance == 0) {
252-
revert StakingManager__InsufficientBalance();
233+
if (lockPeriod == 0) {
234+
revert StakingManager__LockingPeriodCannotBeZero();
253235
}
254236

255237
_updateGlobalState();
256238
_updateVaultMP(msg.sender, true);
239+
(uint256 deltaMp, uint256 newLockEnd) =
240+
_calculateLock(vault.stakedBalance, vault.maxMP, vault.lockUntil, block.timestamp, lockPeriod);
257241

258-
uint256 additionalBonusMP = _calculateBonusMP(vault.stakedBalance, lockPeriod);
259-
260-
// Update vault state
261-
vault.lockUntil = block.timestamp + lockPeriod;
262-
vault.mpAccrued += additionalBonusMP;
263-
vault.maxMP += additionalBonusMP;
242+
// Update account state
243+
vault.lockUntil = newLockEnd;
244+
vault.mpAccrued += deltaMp;
245+
vault.maxMP += deltaMp;
264246

265247
// Update global state
266-
totalMPAccrued += additionalBonusMP;
267-
totalMaxMP += additionalBonusMP;
248+
totalMPAccrued += deltaMp;
249+
totalMaxMP += deltaMp;
268250

269251
vault.rewardIndex = rewardIndex;
270252
}
@@ -277,32 +259,22 @@ contract RewardsStreamerMP is
277259
nonReentrant
278260
{
279261
VaultData storage vault = vaultData[msg.sender];
280-
if (amount > vault.stakedBalance) {
281-
revert StakingManager__InsufficientBalance();
282-
}
283-
284-
if (block.timestamp < vault.lockUntil) {
285-
revert StakingManager__TokensAreLocked();
286-
}
287262
_unstake(amount, vault, msg.sender);
288263
}
289264

290265
function _unstake(uint256 amount, VaultData storage vault, address vaultAddress) internal {
291266
_updateGlobalState();
292267
_updateVaultMP(vaultAddress, true);
293268

294-
uint256 previousStakedBalance = vault.stakedBalance;
295-
296-
// solhint-disable-next-line
297-
uint256 mpToReduce = Math.mulDiv(vault.mpAccrued, amount, previousStakedBalance);
298-
uint256 maxMPToReduce = Math.mulDiv(vault.maxMP, amount, previousStakedBalance);
299-
269+
(uint256 _deltaMpTotal, uint256 _deltaMpMax) = _calculateUnstake(
270+
vault.stakedBalance, vault.lockUntil, block.timestamp, vault.mpAccrued, vault.maxMP, amount
271+
);
300272
vault.stakedBalance -= amount;
301-
vault.mpAccrued -= mpToReduce;
302-
vault.maxMP -= maxMPToReduce;
273+
vault.mpAccrued -= _deltaMpTotal;
274+
vault.maxMP -= _deltaMpMax;
303275
vault.rewardIndex = rewardIndex;
304-
totalMPAccrued -= mpToReduce;
305-
totalMaxMP -= maxMPToReduce;
276+
totalMPAccrued -= _deltaMpTotal;
277+
totalMaxMP -= _deltaMpMax;
306278
totalStaked -= amount;
307279
}
308280

@@ -315,6 +287,8 @@ contract RewardsStreamerMP is
315287
VaultData storage vault = vaultData[msg.sender];
316288

317289
if (vault.stakedBalance > 0) {
290+
//updates lockuntil to allow unstake early
291+
vault.lockUntil = block.timestamp;
318292
// calling `_unstake` to update accounting accordingly
319293
_unstake(vault.stakedBalance, vault, msg.sender);
320294

@@ -358,7 +332,7 @@ contract RewardsStreamerMP is
358332
return (adjustedRewardIndex, totalMPAccrued);
359333
}
360334

361-
uint256 accruedMP = (timeDiff * totalStaked * MP_RATE_PER_YEAR) / YEAR;
335+
uint256 accruedMP = _accrueMP(totalStaked, timeDiff);
362336
if (totalMPAccrued + accruedMP > totalMaxMP) {
363337
accruedMP = totalMaxMP - totalMPAccrued;
364338
}
@@ -465,26 +439,19 @@ contract RewardsStreamerMP is
465439
return (accruedRewards, newRewardIndex);
466440
}
467441

468-
function _calculateBonusMP(uint256 amount, uint256 lockPeriod) internal pure returns (uint256) {
469-
return Math.mulDiv(amount, lockPeriod, YEAR);
470-
}
471-
472442
function _getVaultPendingMP(VaultData storage vault) internal view returns (uint256) {
473-
if (vault.maxMP == 0 || vault.stakedBalance == 0) {
443+
if (block.timestamp == vault.lastMPUpdateTime) {
474444
return 0;
475445
}
476-
477-
uint256 timeDiff = block.timestamp - vault.lastMPUpdateTime;
478-
if (timeDiff == 0) {
446+
if (vault.maxMP == 0 || vault.stakedBalance == 0) {
479447
return 0;
480448
}
481449

482-
uint256 accruedMP = Math.mulDiv(timeDiff * vault.stakedBalance, MP_RATE_PER_YEAR, YEAR);
450+
uint256 deltaMpTotal = _calculateAccrual(
451+
vault.stakedBalance, vault.mpAccrued, vault.maxMP, vault.lastMPUpdateTime, block.timestamp
452+
);
483453

484-
if (vault.mpAccrued + accruedMP > vault.maxMP) {
485-
accruedMP = vault.maxMP - vault.mpAccrued;
486-
}
487-
return accruedMP;
454+
return deltaMpTotal;
488455
}
489456

490457
function _updateVaultMP(address vaultAddress, bool forceMPUpdate) internal {

src/interfaces/IStakeConstants.sol

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.26;
3+
4+
import { ITrustedCodehashAccess } from "./ITrustedCodehashAccess.sol";
5+
6+
/**
7+
* @title IStakeConstants
8+
* @author Ricardo Guilherme Schmidt <ricardo3@status.im>
9+
* @notice Interface for Stake Constants
10+
* @dev This interface is necessary to linearize the inheritance of StakeMath and MultiplierPointMath
11+
*/
12+
interface IStakeConstants {
13+
function MIN_LOCKUP_PERIOD() external view returns (uint256);
14+
function MAX_LOCKUP_PERIOD() external view returns (uint256);
15+
function MP_APY() external view returns (uint256);
16+
function MAX_MULTIPLIER() external view returns (uint256);
17+
}

0 commit comments

Comments
 (0)