Fix rewards accrual bug mentioned by T-Hax: in 'accrueOldRewards' function we added rewards that staker hasn't earned, because 'checkReward' function in Staking contract returns updated (actual) reward amount, but not update it in storage. Replace 'checkReward' function with getter 'accumulatedRewards', which returns actual accumulated reward amount (not updated)
This commit is contained in:
parent
861f4cddaf
commit
79d5bfd103
@ -5,7 +5,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"computeRewards": "npx ts-node scripts/writeStakersData.ts",
|
"computeRewards": "npx ts-node scripts/writeStakersData.ts",
|
||||||
"test": "forge test -vvv --fork-url https://rpc.mevblocker.io --fork-block-number 17466009",
|
"test": "forge test -vvv --fork-url https://rpc.mevblocker.io --fork-block-number 17466009",
|
||||||
"testGas": "forge test -vvv --fork-url https://rpc.mevblocker.io --fork-block-number 17466009 --gas-report"
|
"testGas": "forge test -vvv --fork-url https://rpc.mevblocker.io --gas-report"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
@ -22,7 +22,7 @@ contract RestoreRewardsProposal {
|
|||||||
function accrueOldReward(address stakerAddress, uint256 oldRewards) internal {
|
function accrueOldReward(address stakerAddress, uint256 oldRewards) internal {
|
||||||
ITornadoStakingRewards staking = ITornadoStakingRewards(stakingProxyAddress);
|
ITornadoStakingRewards staking = ITornadoStakingRewards(stakingProxyAddress);
|
||||||
|
|
||||||
staking.setReward(stakerAddress, staking.checkReward(stakerAddress) + oldRewards);
|
staking.setReward(stakerAddress, staking.accumulatedRewards(stakerAddress) + oldRewards);
|
||||||
}
|
}
|
||||||
|
|
||||||
function executeProposal() external {
|
function executeProposal() external {
|
||||||
|
@ -11,4 +11,6 @@ interface ITornadoStakingRewards {
|
|||||||
function setReward(address account, uint256 amount) external;
|
function setReward(address account, uint256 amount) external;
|
||||||
|
|
||||||
function checkReward(address account) external view returns (uint256);
|
function checkReward(address account) external view returns (uint256);
|
||||||
|
|
||||||
|
function accumulatedRewards(address account) external view returns (uint256);
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,18 @@ import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
|||||||
contract TestProposal is MockProposal {
|
contract TestProposal is MockProposal {
|
||||||
ITornadoStakingRewards staking = ITornadoStakingRewards(_stakingAddress);
|
ITornadoStakingRewards staking = ITornadoStakingRewards(_stakingAddress);
|
||||||
|
|
||||||
|
function testGovernanceBalance() internal {
|
||||||
|
IERC20 TORN = IERC20(_tokenAddress);
|
||||||
|
|
||||||
|
uint256 governanceBalanceBeforeExecution = TORN.balanceOf(_governanceAddress);
|
||||||
|
console2.log("Governance balance before proposal execution: %s TORN", governanceBalanceBeforeExecution / _tornDecimals);
|
||||||
|
|
||||||
|
createAndExecuteProposal();
|
||||||
|
|
||||||
|
uint256 governanceBalanceAfterExecution = TORN.balanceOf(_governanceAddress);
|
||||||
|
console2.log("Governance balance after proposal execution: %s TORN", governanceBalanceAfterExecution / _tornDecimals);
|
||||||
|
}
|
||||||
|
|
||||||
function testOtherUsersRewardUnchanged() public {
|
function testOtherUsersRewardUnchanged() public {
|
||||||
uint256 rewardsBeforeProposal = staking.checkReward(TEST_REAL_ADDRESS_WITH_BALANCE);
|
uint256 rewardsBeforeProposal = staking.checkReward(TEST_REAL_ADDRESS_WITH_BALANCE);
|
||||||
console2.log("Developer rewards before proposal execution: %s TORN", rewardsBeforeProposal);
|
console2.log("Developer rewards before proposal execution: %s TORN", rewardsBeforeProposal);
|
||||||
@ -44,26 +56,26 @@ contract TestProposal is MockProposal {
|
|||||||
function getStakersRewardsSum(Staker[385] memory stakers) internal returns (uint256) {
|
function getStakersRewardsSum(Staker[385] memory stakers) internal returns (uint256) {
|
||||||
uint256 rewardsSum = 0;
|
uint256 rewardsSum = 0;
|
||||||
for (uint16 i = 0; i < stakers.length; i++) {
|
for (uint16 i = 0; i < stakers.length; i++) {
|
||||||
rewardsSum += staking.checkReward(stakers[i].addr);
|
rewardsSum += staking.accumulatedRewards(stakers[i].addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rewardsSum;
|
return rewardsSum;
|
||||||
}
|
}
|
||||||
|
|
||||||
function testVerifyStakersAccrual() public {
|
function testVerifyStakersAccrual() internal {
|
||||||
Staker[385] memory stakers = getOldStakers();
|
Staker[385] memory stakers = getOldStakers();
|
||||||
|
|
||||||
uint256[385] memory rewardsBefore;
|
uint256[385] memory rewardsBefore;
|
||||||
uint256[385] memory rewardsAfter;
|
uint256[385] memory rewardsAfter;
|
||||||
|
|
||||||
for (uint16 i = 0; i < stakers.length; i++) {
|
for (uint16 i = 0; i < stakers.length; i++) {
|
||||||
rewardsBefore[i] = staking.checkReward(stakers[i].addr);
|
rewardsBefore[i] = staking.accumulatedRewards(stakers[i].addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
createAndExecuteProposal();
|
createAndExecuteProposal();
|
||||||
|
|
||||||
for (uint16 i = 0; i < stakers.length; i++) {
|
for (uint16 i = 0; i < stakers.length; i++) {
|
||||||
rewardsAfter[i] = staking.checkReward(stakers[i].addr);
|
rewardsAfter[i] = staking.accumulatedRewards(stakers[i].addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint16 i = 0; i < stakers.length; i++) {
|
for (uint16 i = 0; i < stakers.length; i++) {
|
||||||
|
Loading…
Reference in New Issue
Block a user