refactor(RewardStreamerMP): rename user vars to account

Closes #59
This commit is contained in:
r4bbit
2024-10-17 15:00:35 +02:00
parent 753c62db3a
commit ba26e7cc79
5 changed files with 310 additions and 303 deletions

View File

@@ -17,21 +17,21 @@
| Deployment Cost | Deployment Size | | | | |
| 1115122 | 5026 | | | | |
| Function Name | min | avg | median | max | # calls |
| MAX_LOCKING_PERIOD | 228 | 228 | 228 | 228 | 22 |
| MAX_LOCKING_PERIOD | 273 | 273 | 273 | 273 | 22 |
| MAX_MULTIPLIER | 252 | 252 | 252 | 252 | 28 |
| MIN_LOCKING_PERIOD | 229 | 229 | 229 | 229 | 11 |
| MIN_LOCKING_PERIOD | 273 | 273 | 273 | 273 | 11 |
| MP_RATE_PER_YEAR | 231 | 231 | 231 | 231 | 3 |
| SCALE_FACTOR | 251 | 251 | 251 | 251 | 39 |
| accountedRewards | 373 | 931 | 373 | 2373 | 68 |
| getUserInfo | 1576 | 1576 | 1576 | 1576 | 65 |
| rewardIndex | 373 | 402 | 373 | 2373 | 68 |
| stake | 168040 | 217000 | 228839 | 249323 | 46 |
| totalMP | 330 | 330 | 330 | 330 | 71 |
| totalMaxMP | 329 | 329 | 329 | 329 | 71 |
| totalStaked | 373 | 373 | 373 | 373 | 71 |
| unstake | 75511 | 103924 | 91588 | 134250 | 13 |
| updateGlobalState | 30008 | 55589 | 47387 | 80335 | 25 |
| updateUserMP | 34631 | 36869 | 37133 | 37133 | 19 |
| SCALE_FACTOR | 229 | 229 | 229 | 229 | 39 |
| accountedRewards | 351 | 909 | 351 | 2351 | 68 |
| getAccount | 1574 | 1574 | 1574 | 1574 | 65 |
| rewardIndex | 351 | 380 | 351 | 2351 | 68 |
| stake | 168062 | 217022 | 228861 | 249345 | 46 |
| totalMP | 374 | 374 | 374 | 374 | 71 |
| totalMaxMP | 351 | 351 | 351 | 351 | 71 |
| totalStaked | 330 | 330 | 330 | 330 | 71 |
| unstake | 75493 | 103902 | 91566 | 134228 | 13 |
| updateAccountMP | 34610 | 36848 | 37112 | 37112 | 19 |
| updateGlobalState | 29986 | 55567 | 47365 | 80313 | 25 |
| src/XPNFTToken.sol:XPNFTToken contract | | | | | |

View File

@@ -1,4 +1,4 @@
IntegrationTest:testStake() (gas: 1376278)
IntegrationTest:testStake() (gas: 1376068)
NFTMetadataGeneratorSVGTest:testGenerateMetadata() (gas: 92874)
NFTMetadataGeneratorSVGTest:testSetImageStrings() (gas: 60081)
NFTMetadataGeneratorSVGTest:testSetImageStringsRevert() (gas: 35818)
@@ -6,37 +6,37 @@ NFTMetadataGeneratorURLTest:testGenerateMetadata() (gas: 109345)
NFTMetadataGeneratorURLTest:testSetBaseURL() (gas: 50653)
NFTMetadataGeneratorURLTest:testSetBaseURLRevert() (gas: 35993)
RewardsStreamerTest:testStake() (gas: 869874)
StakeTest:test_StakeMultipleAccounts() (gas: 439306)
StakeTest:test_StakeMultipleAccountsAndRewards() (gas: 586550)
StakeTest:test_StakeMultipleAccountsMPIncreasesMaxMPDoesNotChange() (gas: 744051)
StakeTest:test_StakeMultipleAccountsWithMinLockUp() (gas: 448548)
StakeTest:test_StakeMultipleAccountsWithRandomLockUp() (gas: 469950)
StakeTest:test_StakeOneAccount() (gas: 268069)
StakeTest:test_StakeOneAccountAndRewards() (gas: 415355)
StakeTest:test_StakeOneAccountMPIncreasesMaxMPDoesNotChange() (gas: 473161)
StakeTest:test_StakeOneAccountReachingMPLimit() (gas: 468272)
StakeTest:test_StakeOneAccountWithMaxLockUp() (gas: 283222)
StakeTest:test_StakeOneAccountWithMinLockUp() (gas: 283254)
StakeTest:test_StakeOneAccountWithRandomLockUp() (gas: 283321)
UnstakeTest:test_StakeMultipleAccounts() (gas: 439328)
UnstakeTest:test_StakeMultipleAccountsAndRewards() (gas: 586572)
UnstakeTest:test_StakeMultipleAccountsMPIncreasesMaxMPDoesNotChange() (gas: 744073)
UnstakeTest:test_StakeMultipleAccountsWithMinLockUp() (gas: 448592)
UnstakeTest:test_StakeMultipleAccountsWithRandomLockUp() (gas: 469972)
UnstakeTest:test_StakeOneAccount() (gas: 268092)
UnstakeTest:test_StakeOneAccountAndRewards() (gas: 415333)
UnstakeTest:test_StakeOneAccountMPIncreasesMaxMPDoesNotChange() (gas: 473205)
UnstakeTest:test_StakeOneAccountReachingMPLimit() (gas: 468229)
UnstakeTest:test_StakeOneAccountWithMaxLockUp() (gas: 283267)
UnstakeTest:test_StakeOneAccountWithMinLockUp() (gas: 283254)
UnstakeTest:test_StakeOneAccountWithRandomLockUp() (gas: 283320)
UnstakeTest:test_UnstakeBonusMPAndAccuredMP() (gas: 472749)
UnstakeTest:test_UnstakeMultipleAccounts() (gas: 616899)
UnstakeTest:test_UnstakeMultipleAccountsAndRewards() (gas: 938271)
UnstakeTest:test_UnstakeOneAccount() (gas: 446601)
UnstakeTest:test_UnstakeOneAccountAndAccruedMP() (gas: 467894)
UnstakeTest:test_UnstakeOneAccountAndRewards() (gas: 557494)
UnstakeTest:test_UnstakeOneAccountWithLockUpAndAccruedMP() (gas: 490861)
StakeTest:test_StakeMultipleAccounts() (gas: 439303)
StakeTest:test_StakeMultipleAccountsAndRewards() (gas: 586526)
StakeTest:test_StakeMultipleAccountsMPIncreasesMaxMPDoesNotChange() (gas: 743870)
StakeTest:test_StakeMultipleAccountsWithMinLockUp() (gas: 448640)
StakeTest:test_StakeMultipleAccountsWithRandomLockUp() (gas: 470042)
StakeTest:test_StakeOneAccount() (gas: 268046)
StakeTest:test_StakeOneAccountAndRewards() (gas: 415311)
StakeTest:test_StakeOneAccountMPIncreasesMaxMPDoesNotChange() (gas: 473030)
StakeTest:test_StakeOneAccountReachingMPLimit() (gas: 468097)
StakeTest:test_StakeOneAccountWithMaxLockUp() (gas: 283269)
StakeTest:test_StakeOneAccountWithMinLockUp() (gas: 283300)
StakeTest:test_StakeOneAccountWithRandomLockUp() (gas: 283411)
UnstakeTest:test_StakeMultipleAccounts() (gas: 439325)
UnstakeTest:test_StakeMultipleAccountsAndRewards() (gas: 586548)
UnstakeTest:test_StakeMultipleAccountsMPIncreasesMaxMPDoesNotChange() (gas: 743892)
UnstakeTest:test_StakeMultipleAccountsWithMinLockUp() (gas: 448639)
UnstakeTest:test_StakeMultipleAccountsWithRandomLockUp() (gas: 470064)
UnstakeTest:test_StakeOneAccount() (gas: 268069)
UnstakeTest:test_StakeOneAccountAndRewards() (gas: 415289)
UnstakeTest:test_StakeOneAccountMPIncreasesMaxMPDoesNotChange() (gas: 473074)
UnstakeTest:test_StakeOneAccountReachingMPLimit() (gas: 468099)
UnstakeTest:test_StakeOneAccountWithMaxLockUp() (gas: 283314)
UnstakeTest:test_StakeOneAccountWithMinLockUp() (gas: 283300)
UnstakeTest:test_StakeOneAccountWithRandomLockUp() (gas: 283389)
UnstakeTest:test_UnstakeBonusMPAndAccuredMP() (gas: 472770)
UnstakeTest:test_UnstakeMultipleAccounts() (gas: 616827)
UnstakeTest:test_UnstakeMultipleAccountsAndRewards() (gas: 938166)
UnstakeTest:test_UnstakeOneAccount() (gas: 446562)
UnstakeTest:test_UnstakeOneAccountAndAccruedMP() (gas: 467764)
UnstakeTest:test_UnstakeOneAccountAndRewards() (gas: 557405)
UnstakeTest:test_UnstakeOneAccountWithLockUpAndAccruedMP() (gas: 490824)
XPNFTTokenTest:testApproveNotAllowed() (gas: 10507)
XPNFTTokenTest:testGetApproved() (gas: 10531)
XPNFTTokenTest:testIsApprovedForAll() (gas: 10705)

View File

@@ -3,41 +3,41 @@ using ERC20A as staked;
methods {
function totalStaked() external returns (uint256) envfree;
function users(address) external returns (uint256, uint256, uint256, uint256, uint256, uint256) envfree;
function accounts(address) external returns (uint256, uint256, uint256, uint256, uint256, uint256) envfree;
function lastMPUpdatedTime() external returns (uint256) envfree;
function updateGlobalState() external;
function updateUserMP(address userAddress) external;
function updateAccountMP(address accountAddress) external;
}
ghost mathint sumOfBalances {
init_state axiom sumOfBalances == 0;
}
hook Sstore users[KEY address account].stakedBalance uint256 newValue (uint256 oldValue) {
hook Sstore accounts[KEY address account].stakedBalance uint256 newValue (uint256 oldValue) {
sumOfBalances = sumOfBalances - oldValue + newValue;
}
function getAccountMaxMP(address account) returns uint256 {
uint256 maxMP;
_, _, _, maxMP, _, _ = streamer.users(account);
_, _, _, maxMP, _, _ = streamer.accounts(account);
return maxMP;
}
function getAccountMP(address account) returns uint256 {
uint256 accountMP;
_, _, accountMP, _, _, _ = streamer.users(account);
_, _, accountMP, _, _, _ = streamer.accounts(account);
return accountMP;
}
function getAccountStakedBalance(address account) returns uint256 {
uint256 stakedBalance;
stakedBalance, _, _, _, _, _ = streamer.users(account);
stakedBalance, _, _, _, _, _ = streamer.accounts(account);
return stakedBalance;
}
function getAccountLockUntil(address account) returns uint256 {
uint256 lockUntil;
_, _, _, _, _, lockUntil = streamer.users(account);
_, _, _, _, _, lockUntil = streamer.accounts(account);
return lockUntil;
}
@@ -63,7 +63,7 @@ rule stakingMintsMultiplierPoints1To1Ratio {
require getAccountLockUntil(e.msg.sender) <= e.block.timestamp;
updateGlobalState(e);
updateUserMP(e, e.msg.sender);
updateAccountMP(e, e.msg.sender);
uint256 t = lastMPUpdatedTime();
multiplierPointsBefore = getAccountMP(e.msg.sender);

View File

@@ -30,16 +30,16 @@ contract RewardsStreamerMP is ReentrancyGuard {
uint256 public accountedRewards;
uint256 public lastMPUpdatedTime;
struct UserInfo {
struct Account {
uint256 stakedBalance;
uint256 userRewardIndex;
uint256 userMP;
uint256 accountRewardIndex;
uint256 accountMP;
uint256 maxMP;
uint256 lastMPUpdateTime;
uint256 lockUntil;
}
mapping(address account => UserInfo data) public users;
mapping(address account => Account data) public accounts;
constructor(address _stakingToken, address _rewardToken) {
STAKING_TOKEN = IERC20(_stakingToken);
@@ -57,16 +57,16 @@ contract RewardsStreamerMP is ReentrancyGuard {
}
_updateGlobalState();
_updateUserMP(msg.sender);
_updateAccountMP(msg.sender);
UserInfo storage user = users[msg.sender];
if (user.lockUntil != 0 && user.lockUntil > block.timestamp) {
Account storage account = accounts[msg.sender];
if (account.lockUntil != 0 && account.lockUntil > block.timestamp) {
revert StakingManager__CannotRestakeWithLockedFunds();
}
uint256 userRewards = calculateUserRewards(msg.sender);
if (userRewards > 0) {
distributeRewards(msg.sender, userRewards);
uint256 accountRewards = calculateAccountRewards(msg.sender);
if (accountRewards > 0) {
distributeRewards(msg.sender, accountRewards);
}
bool success = STAKING_TOKEN.transferFrom(msg.sender, address(this), amount);
@@ -74,7 +74,7 @@ contract RewardsStreamerMP is ReentrancyGuard {
revert StakingManager__TransferFailed();
}
user.stakedBalance += amount;
account.stakedBalance += amount;
totalStaked += amount;
uint256 initialMP = amount;
@@ -84,50 +84,50 @@ contract RewardsStreamerMP is ReentrancyGuard {
if (lockPeriod != 0) {
uint256 lockMultiplier = (lockPeriod * MAX_MULTIPLIER * SCALE_FACTOR) / MAX_LOCKING_PERIOD;
bonusMP = amount * lockMultiplier / SCALE_FACTOR;
user.lockUntil = block.timestamp + lockPeriod;
account.lockUntil = block.timestamp + lockPeriod;
} else {
user.lockUntil = 0;
account.lockUntil = 0;
}
uint256 userMaxMP = initialMP + bonusMP + potentialMP;
uint256 userMP = initialMP + bonusMP;
uint256 accountMaxMP = initialMP + bonusMP + potentialMP;
uint256 accountMP = initialMP + bonusMP;
user.userMP += userMP;
totalMP += userMP;
account.accountMP += accountMP;
totalMP += accountMP;
user.maxMP += userMaxMP;
totalMaxMP += userMaxMP;
account.maxMP += accountMaxMP;
totalMaxMP += accountMaxMP;
user.userRewardIndex = rewardIndex;
user.lastMPUpdateTime = block.timestamp;
account.accountRewardIndex = rewardIndex;
account.lastMPUpdateTime = block.timestamp;
}
function unstake(uint256 amount) external nonReentrant {
UserInfo storage user = users[msg.sender];
if (amount > user.stakedBalance) {
Account storage account = accounts[msg.sender];
if (amount > account.stakedBalance) {
revert StakingManager__InsufficientBalance();
}
if (block.timestamp < user.lockUntil) {
if (block.timestamp < account.lockUntil) {
revert StakingManager__TokensAreLocked();
}
_updateGlobalState();
_updateUserMP(msg.sender);
_updateAccountMP(msg.sender);
uint256 userRewards = calculateUserRewards(msg.sender);
if (userRewards > 0) {
distributeRewards(msg.sender, userRewards);
uint256 accountRewards = calculateAccountRewards(msg.sender);
if (accountRewards > 0) {
distributeRewards(msg.sender, accountRewards);
}
uint256 previousStakedBalance = user.stakedBalance;
uint256 previousStakedBalance = account.stakedBalance;
uint256 mpToReduce = (user.userMP * amount * SCALE_FACTOR) / (previousStakedBalance * SCALE_FACTOR);
uint256 maxMPToReduce = (user.maxMP * amount * SCALE_FACTOR) / (previousStakedBalance * SCALE_FACTOR);
uint256 mpToReduce = (account.accountMP * amount * SCALE_FACTOR) / (previousStakedBalance * SCALE_FACTOR);
uint256 maxMPToReduce = (account.maxMP * amount * SCALE_FACTOR) / (previousStakedBalance * SCALE_FACTOR);
user.stakedBalance -= amount;
user.userMP -= mpToReduce;
user.maxMP -= maxMPToReduce;
account.stakedBalance -= amount;
account.accountMP -= mpToReduce;
account.maxMP -= maxMPToReduce;
totalMP -= mpToReduce;
totalMaxMP -= maxMPToReduce;
totalStaked -= amount;
@@ -137,7 +137,7 @@ contract RewardsStreamerMP is ReentrancyGuard {
revert StakingManager__TransferFailed();
}
user.userRewardIndex = rewardIndex;
account.accountRewardIndex = rewardIndex;
}
function _updateGlobalState() internal {
@@ -193,38 +193,38 @@ contract RewardsStreamerMP is ReentrancyGuard {
}
}
function _updateUserMP(address userAddress) internal {
UserInfo storage user = users[userAddress];
function _updateAccountMP(address accountAddress) internal {
Account storage account = accounts[accountAddress];
if (user.maxMP == 0 || user.stakedBalance == 0) {
user.lastMPUpdateTime = block.timestamp;
if (account.maxMP == 0 || account.stakedBalance == 0) {
account.lastMPUpdateTime = block.timestamp;
return;
}
uint256 timeDiff = block.timestamp - user.lastMPUpdateTime;
uint256 timeDiff = block.timestamp - account.lastMPUpdateTime;
if (timeDiff == 0) {
return;
}
uint256 accruedMP = (timeDiff * user.stakedBalance * MP_RATE_PER_YEAR) / (365 days * SCALE_FACTOR);
uint256 accruedMP = (timeDiff * account.stakedBalance * MP_RATE_PER_YEAR) / (365 days * SCALE_FACTOR);
if (user.userMP + accruedMP > user.maxMP) {
accruedMP = user.maxMP - user.userMP;
if (account.accountMP + accruedMP > account.maxMP) {
accruedMP = account.maxMP - account.accountMP;
}
user.userMP += accruedMP;
user.lastMPUpdateTime = block.timestamp;
account.accountMP += accruedMP;
account.lastMPUpdateTime = block.timestamp;
}
function updateUserMP(address userAddress) external {
_updateUserMP(userAddress);
function updateAccountMP(address accountAddress) external {
_updateAccountMP(accountAddress);
}
function calculateUserRewards(address userAddress) public view returns (uint256) {
UserInfo storage user = users[userAddress];
uint256 userWeight = user.stakedBalance + user.userMP;
uint256 deltaRewardIndex = rewardIndex - user.userRewardIndex;
return (userWeight * deltaRewardIndex) / SCALE_FACTOR;
function calculateAccountRewards(address accountAddress) public view returns (uint256) {
Account storage account = accounts[accountAddress];
uint256 accountWeight = account.stakedBalance + account.accountMP;
uint256 deltaRewardIndex = rewardIndex - account.accountRewardIndex;
return (accountWeight * deltaRewardIndex) / SCALE_FACTOR;
}
function distributeRewards(address to, uint256 amount) internal {
@@ -242,15 +242,15 @@ contract RewardsStreamerMP is ReentrancyGuard {
}
}
function getStakedBalance(address userAddress) external view returns (uint256) {
return users[userAddress].stakedBalance;
function getStakedBalance(address accountAddress) external view returns (uint256) {
return accounts[accountAddress].stakedBalance;
}
function getPendingRewards(address userAddress) external view returns (uint256) {
return calculateUserRewards(userAddress);
function getPendingRewards(address accountAddress) external view returns (uint256) {
return calculateAccountRewards(accountAddress);
}
function getUserInfo(address userAddress) external view returns (UserInfo memory) {
return users[userAddress];
function getAccount(address accountAddress) external view returns (Account memory) {
return accounts[accountAddress];
}
}

View File

@@ -21,10 +21,10 @@ contract RewardsStreamerMPTest is Test {
stakingToken = new MockToken("Staking Token", "ST");
streamer = new RewardsStreamerMP(address(stakingToken), address(rewardToken));
address[4] memory users = [alice, bob, charlie, dave];
for (uint256 i = 0; i < users.length; i++) {
stakingToken.mint(users[i], 10_000e18);
vm.prank(users[i]);
address[4] memory accounts = [alice, bob, charlie, dave];
for (uint256 i = 0; i < accounts.length; i++) {
stakingToken.mint(accounts[i], 10_000e18);
vm.prank(accounts[i]);
stakingToken.approve(address(streamer), 10_000e18);
}
@@ -53,24 +53,24 @@ contract RewardsStreamerMPTest is Test {
assertEq(streamer.accountedRewards(), p.accountedRewards, "wrong accounted rewards");
}
struct CheckUserParams {
address user;
struct CheckAccountParams {
address account;
uint256 rewardBalance;
uint256 stakedBalance;
uint256 rewardIndex;
uint256 userMP;
uint256 accountMP;
uint256 maxMP;
}
function checkUser(CheckUserParams memory p) public view {
assertEq(rewardToken.balanceOf(p.user), p.rewardBalance, "wrong user reward balance");
function checkAccount(CheckAccountParams memory p) public view {
assertEq(rewardToken.balanceOf(p.account), p.rewardBalance, "wrong account reward balance");
RewardsStreamerMP.UserInfo memory userInfo = streamer.getUserInfo(p.user);
RewardsStreamerMP.Account memory accountInfo = streamer.getAccount(p.account);
assertEq(userInfo.stakedBalance, p.stakedBalance, "wrong user staked balance");
assertEq(userInfo.userRewardIndex, p.rewardIndex, "wrong user reward index");
assertEq(userInfo.userMP, p.userMP, "wrong user MP");
assertEq(userInfo.maxMP, p.maxMP, "wrong user max MP");
assertEq(accountInfo.stakedBalance, p.stakedBalance, "wrong account staked balance");
assertEq(accountInfo.accountRewardIndex, p.rewardIndex, "wrong account reward index");
assertEq(accountInfo.accountMP, p.accountMP, "wrong account MP");
assertEq(accountInfo.maxMP, p.maxMP, "wrong account max MP");
}
function _stake(address account, uint256 amount, uint256 lockupTime) public {
@@ -145,13 +145,13 @@ contract IntegrationTest is RewardsStreamerMPTest {
})
);
checkUser(
CheckUserParams({
user: alice,
checkAccount(
CheckAccountParams({
account: alice,
rewardBalance: 0,
stakedBalance: 10e18,
rewardIndex: 0,
userMP: 10e18,
accountMP: 10e18,
maxMP: 50e18
})
);
@@ -172,24 +172,24 @@ contract IntegrationTest is RewardsStreamerMPTest {
})
);
checkUser(
CheckUserParams({
user: alice,
checkAccount(
CheckAccountParams({
account: alice,
rewardBalance: 0,
stakedBalance: 10e18,
rewardIndex: 0,
userMP: 10e18,
accountMP: 10e18,
maxMP: 50e18
})
);
checkUser(
CheckUserParams({
user: bob,
checkAccount(
CheckAccountParams({
account: bob,
rewardBalance: 0,
stakedBalance: 30e18,
rewardIndex: 0,
userMP: 30e18,
accountMP: 30e18,
maxMP: 150e18
})
);
@@ -211,24 +211,24 @@ contract IntegrationTest is RewardsStreamerMPTest {
})
);
checkUser(
CheckUserParams({
user: alice,
checkAccount(
CheckAccountParams({
account: alice,
rewardBalance: 0,
stakedBalance: 10e18,
rewardIndex: 0,
userMP: 10e18,
accountMP: 10e18,
maxMP: 50e18
})
);
checkUser(
CheckUserParams({
user: bob,
checkAccount(
CheckAccountParams({
account: bob,
rewardBalance: 0,
stakedBalance: 30e18,
rewardIndex: 0,
userMP: 30e18,
accountMP: 30e18,
maxMP: 150e18
})
);
@@ -268,24 +268,24 @@ contract IntegrationTest is RewardsStreamerMPTest {
})
);
checkUser(
CheckUserParams({
user: alice,
checkAccount(
CheckAccountParams({
account: alice,
rewardBalance: 250e18,
stakedBalance: 0e18,
rewardIndex: 10e18,
userMP: 0e18,
accountMP: 0e18,
maxMP: 0e18
})
);
checkUser(
CheckUserParams({
user: bob,
checkAccount(
CheckAccountParams({
account: bob,
rewardBalance: 0,
stakedBalance: 30e18,
rewardIndex: 0,
userMP: 30e18,
accountMP: 30e18,
maxMP: 150e18
})
);
@@ -306,35 +306,35 @@ contract IntegrationTest is RewardsStreamerMPTest {
})
);
checkUser(
CheckUserParams({
user: alice,
checkAccount(
CheckAccountParams({
account: alice,
rewardBalance: 250e18,
stakedBalance: 0e18,
rewardIndex: 10e18,
userMP: 0e18,
accountMP: 0e18,
maxMP: 0e18
})
);
checkUser(
CheckUserParams({
user: bob,
checkAccount(
CheckAccountParams({
account: bob,
rewardBalance: 0,
stakedBalance: 30e18,
rewardIndex: 0,
userMP: 30e18,
accountMP: 30e18,
maxMP: 150e18
})
);
checkUser(
CheckUserParams({
user: charlie,
checkAccount(
CheckAccountParams({
account: charlie,
rewardBalance: 0,
stakedBalance: 30e18,
rewardIndex: 10e18,
userMP: 30e18,
accountMP: 30e18,
maxMP: 150e18
})
);
@@ -356,35 +356,35 @@ contract IntegrationTest is RewardsStreamerMPTest {
})
);
checkUser(
CheckUserParams({
user: alice,
checkAccount(
CheckAccountParams({
account: alice,
rewardBalance: 250e18,
stakedBalance: 0e18,
rewardIndex: 10e18,
userMP: 0e18,
accountMP: 0e18,
maxMP: 0e18
})
);
checkUser(
CheckUserParams({
user: bob,
checkAccount(
CheckAccountParams({
account: bob,
rewardBalance: 0,
stakedBalance: 30e18,
rewardIndex: 0,
userMP: 30e18,
accountMP: 30e18,
maxMP: 150e18
})
);
checkUser(
CheckUserParams({
user: charlie,
checkAccount(
CheckAccountParams({
account: charlie,
rewardBalance: 0,
stakedBalance: 30e18,
rewardIndex: 10e18,
userMP: 30e18,
accountMP: 30e18,
maxMP: 150e18
})
);
@@ -406,20 +406,20 @@ contract IntegrationTest is RewardsStreamerMPTest {
})
);
checkUser(
CheckUserParams({
user: alice,
checkAccount(
CheckAccountParams({
account: alice,
rewardBalance: 250e18,
stakedBalance: 0e18,
rewardIndex: 10e18,
userMP: 0,
accountMP: 0,
maxMP: 0
})
);
checkUser(
CheckUserParams({
user: bob,
checkAccount(
CheckAccountParams({
account: bob,
// bob had 30 staked + 30 initial MP + 15 MP accrued in 6 months
// so in the second bucket we have 1000 rewards with
// bob's weight = 75
@@ -430,18 +430,18 @@ contract IntegrationTest is RewardsStreamerMPTest {
rewardBalance: 1_305_555_555_555_555_555_525,
stakedBalance: 0e18,
rewardIndex: 17_407_407_407_407_407_407,
userMP: 0,
accountMP: 0,
maxMP: 0
})
);
checkUser(
CheckUserParams({
user: charlie,
checkAccount(
CheckAccountParams({
account: charlie,
rewardBalance: 0,
stakedBalance: 30e18,
rewardIndex: 10e18,
userMP: 30e18,
accountMP: 30e18,
maxMP: 150e18
})
);
@@ -468,13 +468,13 @@ contract StakeTest is RewardsStreamerMPTest {
accountedRewards: 0
})
);
checkUser(
CheckUserParams({
user: alice,
checkAccount(
CheckAccountParams({
account: alice,
rewardBalance: 0,
stakedBalance: 10e18,
rewardIndex: 0,
userMP: 10e18,
accountMP: 10e18,
maxMP: 50e18
})
);
@@ -495,13 +495,13 @@ contract StakeTest is RewardsStreamerMPTest {
})
);
checkUser(
CheckUserParams({
user: alice,
checkAccount(
CheckAccountParams({
account: alice,
rewardBalance: 0,
stakedBalance: 10e18,
rewardIndex: 0,
userMP: 10e18,
accountMP: 10e18,
maxMP: 50e18
})
);
@@ -608,7 +608,7 @@ contract StakeTest is RewardsStreamerMPTest {
vm.warp(currentTime + (365 days));
streamer.updateGlobalState();
streamer.updateUserMP(alice);
streamer.updateAccountMP(alice);
uint256 expectedMPIncrease = stakeAmount; // 1 year passed, 1 MP accrued per token staked
totalMP = totalMP + expectedMPIncrease;
@@ -625,13 +625,13 @@ contract StakeTest is RewardsStreamerMPTest {
})
);
checkUser(
CheckUserParams({
user: alice,
checkAccount(
CheckAccountParams({
account: alice,
rewardBalance: 0,
stakedBalance: stakeAmount,
rewardIndex: 0,
userMP: totalMP, // userMP == totalMP because only one user is staking
accountMP: totalMP, // accountMP == totalMP because only one account is staking
maxMP: totalMaxMP
})
);
@@ -640,7 +640,7 @@ contract StakeTest is RewardsStreamerMPTest {
vm.warp(currentTime + (365 days / 2));
streamer.updateGlobalState();
streamer.updateUserMP(alice);
streamer.updateAccountMP(alice);
expectedMPIncrease = stakeAmount / 2; // 1/2 year passed, 1/2 MP accrued per token staked
totalMP = totalMP + expectedMPIncrease;
@@ -657,13 +657,13 @@ contract StakeTest is RewardsStreamerMPTest {
})
);
checkUser(
CheckUserParams({
user: alice,
checkAccount(
CheckAccountParams({
account: alice,
rewardBalance: 0,
stakedBalance: stakeAmount,
rewardIndex: 0,
userMP: totalMP, // userMP == totalMP because only one user is staking
accountMP: totalMP, // accountMP == totalMP because only one account is staking
maxMP: totalMaxMP
})
);
@@ -688,14 +688,14 @@ contract StakeTest is RewardsStreamerMPTest {
})
);
checkUser(
CheckUserParams({
user: alice,
checkAccount(
CheckAccountParams({
account: alice,
rewardBalance: 0,
stakedBalance: stakeAmount,
rewardIndex: 0,
userMP: totalMP, // userMP == totalMP because only one user is staking
maxMP: totalMaxMP // maxMP == totalMaxMP because only one user is staking
accountMP: totalMP, // accountMP == totalMP because only one account is staking
maxMP: totalMaxMP // maxMP == totalMaxMP because only one account is staking
})
);
@@ -704,7 +704,7 @@ contract StakeTest is RewardsStreamerMPTest {
vm.warp(currentTime + timeToMaxMP);
streamer.updateGlobalState();
streamer.updateUserMP(alice);
streamer.updateAccountMP(alice);
checkStreamer(
CheckStreamerParams({
@@ -718,13 +718,13 @@ contract StakeTest is RewardsStreamerMPTest {
})
);
checkUser(
CheckUserParams({
user: alice,
checkAccount(
CheckAccountParams({
account: alice,
rewardBalance: 0,
stakedBalance: stakeAmount,
rewardIndex: 0,
userMP: totalMaxMP,
accountMP: totalMaxMP,
maxMP: totalMaxMP
})
);
@@ -734,7 +734,7 @@ contract StakeTest is RewardsStreamerMPTest {
vm.warp(currentTime + 1);
streamer.updateGlobalState();
streamer.updateUserMP(alice);
streamer.updateAccountMP(alice);
checkStreamer(
CheckStreamerParams({
@@ -768,24 +768,24 @@ contract StakeTest is RewardsStreamerMPTest {
})
);
checkUser(
CheckUserParams({
user: alice,
checkAccount(
CheckAccountParams({
account: alice,
rewardBalance: 0,
stakedBalance: 10e18,
rewardIndex: 0,
userMP: 10e18,
accountMP: 10e18,
maxMP: 50e18
})
);
checkUser(
CheckUserParams({
user: bob,
checkAccount(
CheckAccountParams({
account: bob,
rewardBalance: 0,
stakedBalance: 30e18,
rewardIndex: 0,
userMP: 30e18,
accountMP: 30e18,
maxMP: 150e18
})
);
@@ -810,24 +810,24 @@ contract StakeTest is RewardsStreamerMPTest {
})
);
checkUser(
CheckUserParams({
user: alice,
checkAccount(
CheckAccountParams({
account: alice,
rewardBalance: 0,
stakedBalance: 10e18,
rewardIndex: 0,
userMP: 10e18,
accountMP: 10e18,
maxMP: 50e18
})
);
checkUser(
CheckUserParams({
user: bob,
checkAccount(
CheckAccountParams({
account: bob,
rewardBalance: 0,
stakedBalance: 30e18,
rewardIndex: 0,
userMP: 30e18,
accountMP: 30e18,
maxMP: 150e18
})
);
@@ -937,23 +937,23 @@ contract StakeTest is RewardsStreamerMPTest {
})
);
checkUser(
CheckUserParams({
user: alice,
checkAccount(
CheckAccountParams({
account: alice,
rewardBalance: 0,
stakedBalance: aliceStakeAmount,
rewardIndex: 0,
userMP: aliceMP,
accountMP: aliceMP,
maxMP: aliceMaxMP
})
);
checkUser(
CheckUserParams({
user: bob,
checkAccount(
CheckAccountParams({
account: bob,
rewardBalance: 0,
stakedBalance: bobStakeAmount,
rewardIndex: 0,
userMP: bobMP,
accountMP: bobMP,
maxMP: bobMaxMP
})
);
@@ -962,8 +962,8 @@ contract StakeTest is RewardsStreamerMPTest {
vm.warp(currentTime + (365 days));
streamer.updateGlobalState();
streamer.updateUserMP(alice);
streamer.updateUserMP(bob);
streamer.updateAccountMP(alice);
streamer.updateAccountMP(bob);
uint256 aliceExpectedMPIncrease = aliceStakeAmount; // 1 year passed, 1 MP accrued per token staked
uint256 bobExpectedMPIncrease = bobStakeAmount; // 1 year passed, 1 MP accrued per token staked
@@ -985,23 +985,23 @@ contract StakeTest is RewardsStreamerMPTest {
})
);
checkUser(
CheckUserParams({
user: alice,
checkAccount(
CheckAccountParams({
account: alice,
rewardBalance: 0,
stakedBalance: aliceStakeAmount,
rewardIndex: 0,
userMP: aliceMP,
accountMP: aliceMP,
maxMP: aliceMaxMP
})
);
checkUser(
CheckUserParams({
user: bob,
checkAccount(
CheckAccountParams({
account: bob,
rewardBalance: 0,
stakedBalance: bobStakeAmount,
rewardIndex: 0,
userMP: bobMP,
accountMP: bobMP,
maxMP: bobMaxMP
})
);
@@ -1010,8 +1010,8 @@ contract StakeTest is RewardsStreamerMPTest {
vm.warp(currentTime + (365 days / 2));
streamer.updateGlobalState();
streamer.updateUserMP(alice);
streamer.updateUserMP(bob);
streamer.updateAccountMP(alice);
streamer.updateAccountMP(bob);
aliceExpectedMPIncrease = aliceStakeAmount / 2;
bobExpectedMPIncrease = bobStakeAmount / 2;
@@ -1033,23 +1033,23 @@ contract StakeTest is RewardsStreamerMPTest {
})
);
checkUser(
CheckUserParams({
user: alice,
checkAccount(
CheckAccountParams({
account: alice,
rewardBalance: 0,
stakedBalance: aliceStakeAmount,
rewardIndex: 0,
userMP: aliceMP,
accountMP: aliceMP,
maxMP: aliceMaxMP
})
);
checkUser(
CheckUserParams({
user: bob,
checkAccount(
CheckAccountParams({
account: bob,
rewardBalance: 0,
stakedBalance: bobStakeAmount,
rewardIndex: 0,
userMP: bobMP,
accountMP: bobMP,
maxMP: bobMaxMP
})
);
@@ -1078,13 +1078,13 @@ contract UnstakeTest is StakeTest {
})
);
checkUser(
CheckUserParams({
user: alice,
checkAccount(
CheckAccountParams({
account: alice,
rewardBalance: 0,
stakedBalance: 2e18,
rewardIndex: 0,
userMP: 2e18,
accountMP: 2e18,
maxMP: 10e18
})
);
@@ -1112,7 +1112,7 @@ contract UnstakeTest is StakeTest {
vm.warp(currentTime + (365 days));
streamer.updateGlobalState();
streamer.updateUserMP(alice);
streamer.updateAccountMP(alice);
checkStreamer(
CheckStreamerParams({
@@ -1155,7 +1155,7 @@ contract UnstakeTest is StakeTest {
vm.warp(currentTime + (365 days));
streamer.updateGlobalState();
streamer.updateUserMP(alice);
streamer.updateAccountMP(alice);
checkStreamer(
CheckStreamerParams({
@@ -1204,13 +1204,13 @@ contract UnstakeTest is StakeTest {
})
);
checkUser(
CheckUserParams({
user: alice,
checkAccount(
CheckAccountParams({
account: alice,
rewardBalance: 1000e18,
stakedBalance: 2e18,
rewardIndex: 50e18, // alice reward index has been updated
userMP: 2e18,
accountMP: 2e18,
maxMP: 10e18
})
);
@@ -1273,10 +1273,10 @@ contract UnstakeTest is StakeTest {
{
_stake(alice, amountStaked, secondsLocked);
{
RewardsStreamerMP.UserInfo memory userInfo = streamer.getUserInfo(alice);
assertEq(userInfo.stakedBalance, totalStaked[stage], "stage 1: wrong user staked balance");
assertEq(userInfo.userMP, predictedTotalMP[stage], "stage 1: wrong user MP");
assertEq(userInfo.maxMP, predictedTotalMaxMP[stage], "stage 1: wrong user max MP");
RewardsStreamerMP.Account memory accountInfo = streamer.getAccount(alice);
assertEq(accountInfo.stakedBalance, totalStaked[stage], "stage 1: wrong account staked balance");
assertEq(accountInfo.accountMP, predictedTotalMP[stage], "stage 1: wrong account MP");
assertEq(accountInfo.maxMP, predictedTotalMaxMP[stage], "stage 1: wrong account max MP");
assertEq(streamer.totalStaked(), totalStaked[stage], "stage 1: wrong total staked");
assertEq(streamer.totalMP(), predictedTotalMP[stage], "stage 1: wrong total MP");
@@ -1287,12 +1287,12 @@ contract UnstakeTest is StakeTest {
stage++; // second stage: progress in time
vm.warp(timestamp[stage]);
streamer.updateGlobalState();
streamer.updateUserMP(alice);
streamer.updateAccountMP(alice);
{
RewardsStreamerMP.UserInfo memory userInfo = streamer.getUserInfo(alice);
assertEq(userInfo.stakedBalance, totalStaked[stage], "stage 2: wrong user staked balance");
assertEq(userInfo.userMP, predictedTotalMP[stage], "stage 2: wrong user MP");
assertEq(userInfo.maxMP, predictedTotalMaxMP[stage], "stage 2: wrong user max MP");
RewardsStreamerMP.Account memory accountInfo = streamer.getAccount(alice);
assertEq(accountInfo.stakedBalance, totalStaked[stage], "stage 2: wrong account staked balance");
assertEq(accountInfo.accountMP, predictedTotalMP[stage], "stage 2: wrong account MP");
assertEq(accountInfo.maxMP, predictedTotalMaxMP[stage], "stage 2: wrong account max MP");
assertEq(streamer.totalStaked(), totalStaked[stage], "stage 2: wrong total staked");
assertEq(streamer.totalMP(), predictedTotalMP[stage], "stage 2: wrong total MP");
@@ -1302,10 +1302,10 @@ contract UnstakeTest is StakeTest {
stage++; // third stage: reduced stake
_unstake(alice, reducedStake);
{
RewardsStreamerMP.UserInfo memory userInfo = streamer.getUserInfo(alice);
assertEq(userInfo.stakedBalance, totalStaked[stage], "stage 3: wrong user staked balance");
assertEq(userInfo.userMP, predictedTotalMP[stage], "stage 3: wrong user MP");
assertEq(userInfo.maxMP, predictedTotalMaxMP[stage], "stage 3: wrong user max MP");
RewardsStreamerMP.Account memory accountInfo = streamer.getAccount(alice);
assertEq(accountInfo.stakedBalance, totalStaked[stage], "stage 3: wrong account staked balance");
assertEq(accountInfo.accountMP, predictedTotalMP[stage], "stage 3: wrong account MP");
assertEq(accountInfo.maxMP, predictedTotalMaxMP[stage], "stage 3: wrong account max MP");
assertEq(streamer.totalStaked(), totalStaked[stage], "stage 3: wrong total staked");
assertEq(streamer.totalMP(), predictedTotalMP[stage], "stage 3: wrong total MP");
@@ -1331,17 +1331,24 @@ contract UnstakeTest is StakeTest {
})
);
checkUser(
CheckUserParams({ user: alice, rewardBalance: 0, stakedBalance: 0, rewardIndex: 0, userMP: 0, maxMP: 0 })
checkAccount(
CheckAccountParams({
account: alice,
rewardBalance: 0,
stakedBalance: 0,
rewardIndex: 0,
accountMP: 0,
maxMP: 0
})
);
checkUser(
CheckUserParams({
user: bob,
checkAccount(
CheckAccountParams({
account: bob,
rewardBalance: 0,
stakedBalance: 20e18,
rewardIndex: 0,
userMP: 20e18,
accountMP: 20e18,
maxMP: 100e18
})
);
@@ -1365,13 +1372,13 @@ contract UnstakeTest is StakeTest {
})
);
checkUser(
CheckUserParams({
user: alice,
checkAccount(
CheckAccountParams({
account: alice,
rewardBalance: 250e18,
stakedBalance: 0,
rewardIndex: 125e17,
userMP: 0,
accountMP: 0,
maxMP: 0
})
);
@@ -1390,13 +1397,13 @@ contract UnstakeTest is StakeTest {
})
);
checkUser(
CheckUserParams({
user: bob,
checkAccount(
CheckAccountParams({
account: bob,
rewardBalance: 750e18,
stakedBalance: 20e18,
rewardIndex: 125e17,
userMP: 20e18,
accountMP: 20e18,
maxMP: 100e18
})
);
@@ -1415,13 +1422,13 @@ contract UnstakeTest is StakeTest {
})
);
checkUser(
CheckUserParams({
user: bob,
checkAccount(
CheckAccountParams({
account: bob,
rewardBalance: 750e18,
stakedBalance: 0,
rewardIndex: 125e17,
userMP: 0,
accountMP: 0,
maxMP: 0
})
);