From 215ccf6af702698822fc90c5d4371181aa97a533 Mon Sep 17 00:00:00 2001 From: Santiago Sanchez Avalos Date: Tue, 4 Jun 2024 00:39:16 -0300 Subject: [PATCH] =?UTF-8?q?=E2=9A=A1=EF=B8=8F=20rewards:=20avoid=20update?= =?UTF-8?q?=20after=20period=20ends?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .changeset/khaki-geese-heal.md | 5 ++ .gas-snapshot | 143 ++++++++++++++++---------------- contracts/RewardsController.sol | 2 +- test/RewardsController.t.sol | 25 ++++++ 4 files changed, 103 insertions(+), 72 deletions(-) create mode 100644 .changeset/khaki-geese-heal.md diff --git a/.changeset/khaki-geese-heal.md b/.changeset/khaki-geese-heal.md new file mode 100644 index 00000000..dc695f99 --- /dev/null +++ b/.changeset/khaki-geese-heal.md @@ -0,0 +1,5 @@ +--- +"@exactly/protocol": patch +--- + +⚡️ rewards: avoid update after period ends diff --git a/.gas-snapshot b/.gas-snapshot index a9f34adf..2f4b42dc 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -294,8 +294,8 @@ PreviewerTest:testAccountsWithAccountOnlyDeposit() (gas: 862391) PreviewerTest:testAccountsWithAccountThatHasBalances() (gas: 2265104) PreviewerTest:testAccountsWithEmptyAccount() (gas: 690558) PreviewerTest:testAccountsWithIntermediateOperationsReturningAccurateAmounts() (gas: 17628100) -PreviewerTest:testActualTimeBeforeStartDistributionRewards() (gas: 7759515) -PreviewerTest:testEmptyExactly() (gas: 5651562) +PreviewerTest:testActualTimeBeforeStartDistributionRewards() (gas: 7768578) +PreviewerTest:testEmptyExactly() (gas: 5660590) PreviewerTest:testExactlyReturningInterestRateModelData() (gas: 688149) PreviewerTest:testFixedAvailableLiquidityProjectingNewFloatingDebt() (gas: 13312154) PreviewerTest:testFixedPoolsA() (gas: 19328899) @@ -306,7 +306,7 @@ PreviewerTest:testFlexibleAvailableLiquidity() (gas: 17252956) PreviewerTest:testFlexibleBorrowSharesAndAssets() (gas: 4401038) PreviewerTest:testFloatingAvailableLiquidityProjectingNewFloatingDebt() (gas: 12564814) PreviewerTest:testFloatingRateAndUtilization() (gas: 1128246) -PreviewerTest:testJustUpdatedRewardRatesShouldStillReturnRate() (gas: 7180914) +PreviewerTest:testJustUpdatedRewardRatesShouldStillReturnRate() (gas: 7190152) PreviewerTest:testMaxBorrowAssetsCapacity() (gas: 2469700) PreviewerTest:testMaxBorrowAssetsCapacityForAccountWithShortfall() (gas: 11002333) PreviewerTest:testMaxBorrowAssetsCapacityPerMarket() (gas: 13192458) @@ -353,12 +353,12 @@ PreviewerTest:testPreviewWithdrawAtMaturityWithOneUnit() (gas: 251718) PreviewerTest:testPreviewWithdrawAtMaturityWithSameTimestamp() (gas: 233406) PreviewerTest:testPreviewWithdrawAtMaturityWithZeroAmount() (gas: 251675) PreviewerTest:testReserveFactor() (gas: 707280) -PreviewerTest:testReturnRewardAssetUsdPrice() (gas: 6703410) -PreviewerTest:testRewardsRateAfterDistributionEnd() (gas: 7487215) -PreviewerTest:testRewardsRateOnlyWithFixedBorrows() (gas: 6794429) -PreviewerTest:testRewardsRateWithDifferentRewardLengths() (gas: 19257836) -PreviewerTest:testRewardsRateWithMarketWithDifferentDecimals() (gas: 18388899) -PreviewerTest:testRewardsRateX() (gas: 8133789) +PreviewerTest:testReturnRewardAssetUsdPrice() (gas: 6712433) +PreviewerTest:testRewardsRateAfterDistributionEnd() (gas: 7496473) +PreviewerTest:testRewardsRateOnlyWithFixedBorrows() (gas: 6803647) +PreviewerTest:testRewardsRateWithDifferentRewardLengths() (gas: 19266979) +PreviewerTest:testRewardsRateWithMarketWithDifferentDecimals() (gas: 18398132) +PreviewerTest:testRewardsRateX() (gas: 8143022) PriceFeedDoubleTest:testPriceFeedDoubleReturningAccurateDecimals() (gas: 597567) PriceFeedDoubleTest:testPriceFeedDoubleReturningPrice() (gas: 53190) PriceFeedDoubleTest:testPriceFeedDoubleWithActualOnChainValues() (gas: 76310) @@ -375,70 +375,71 @@ PriceFeedWrapperTest:testPriceFeedWrapperReturningPriceAfterRebase() (gas: 48989 PriceFeedWrapperTest:testPriceFeedWrapperWithActualOnChainValues() (gas: 75210) PriceFeedWrapperTest:testPriceFeedWrapperWithNegativePriceShouldRevert() (gas: 164216) PriceFeedWrapperTest:testPriceFeedWrapperWithUsdPriceFeed() (gas: 1243191) -RewardsControllerTest:testAccrueRewardsForWholeDistributionPeriod() (gas: 1245252) -RewardsControllerTest:testAccrueRewardsWithBadDebtClearingOfFixedBorrow() (gas: 3339358) -RewardsControllerTest:testAccrueRewardsWithRepayOfBorrowBalance() (gas: 1603189) -RewardsControllerTest:testAccrueRewardsWithRepayOfFixedBorrowBalance() (gas: 1792302) -RewardsControllerTest:testAccrueRewardsWithSeizeOfAllDepositShares() (gas: 1991754) -RewardsControllerTest:testAfterDistributionPeriodEnd() (gas: 1818275) -RewardsControllerTest:testAllClaimableUSDCWithAnotherAccountInPool() (gas: 2273354) -RewardsControllerTest:testAllClaimableUSDCWithDeposit() (gas: 1627706) -RewardsControllerTest:testAllClaimableUSDCWithFloatingBorrow() (gas: 1560044) -RewardsControllerTest:testAllClaimableUSDCWithFloatingRefund() (gas: 1667236) -RewardsControllerTest:testAllClaimableUSDCWithFloatingRepay() (gas: 1673750) -RewardsControllerTest:testAllClaimableUSDCWithMint() (gas: 1284296) -RewardsControllerTest:testAllClaimableUSDCWithRedeem() (gas: 1640399) -RewardsControllerTest:testAllClaimableUSDCWithTransfer() (gas: 2220308) -RewardsControllerTest:testAllClaimableUSDCWithTransferFrom() (gas: 2135247) -RewardsControllerTest:testAllClaimableUSDCWithWithdraw() (gas: 1641434) -RewardsControllerTest:testAllClaimableWETH() (gas: 1247789) -RewardsControllerTest:testAllClaimableWithMaturedFixedPool() (gas: 1127914) -RewardsControllerTest:testAllClaimableWithTimeElapsedZero() (gas: 1624635) -RewardsControllerTest:testAllRewards() (gas: 216384) -RewardsControllerTest:testClaim() (gas: 1192157) -RewardsControllerTest:testClaimAll() (gas: 2188734) -RewardsControllerTest:testClaimMarketWithoutRewards() (gas: 1241057) -RewardsControllerTest:testClaimWithNotEnabledRewardAsset() (gas: 1222633) -RewardsControllerTest:testConfigSettingNewStartWithOnGoingDistributionShouldNotUpdate() (gas: 430275) -RewardsControllerTest:testConfigWithDistributionNotYetStartedShouldNotFail() (gas: 613404) +RewardsControllerTest:testAccrueRewardsForWholeDistributionPeriod() (gas: 1245824) +RewardsControllerTest:testAccrueRewardsWithBadDebtClearingOfFixedBorrow() (gas: 3340160) +RewardsControllerTest:testAccrueRewardsWithRepayOfBorrowBalance() (gas: 1603649) +RewardsControllerTest:testAccrueRewardsWithRepayOfFixedBorrowBalance() (gas: 1793044) +RewardsControllerTest:testAccrueRewardsWithSeizeOfAllDepositShares() (gas: 1992236) +RewardsControllerTest:testAfterDistributionPeriodEnd() (gas: 1818847) +RewardsControllerTest:testAllClaimableUSDCWithAnotherAccountInPool() (gas: 2273836) +RewardsControllerTest:testAllClaimableUSDCWithDeposit() (gas: 1627808) +RewardsControllerTest:testAllClaimableUSDCWithFloatingBorrow() (gas: 1560146) +RewardsControllerTest:testAllClaimableUSDCWithFloatingRefund() (gas: 1667569) +RewardsControllerTest:testAllClaimableUSDCWithFloatingRepay() (gas: 1674192) +RewardsControllerTest:testAllClaimableUSDCWithMint() (gas: 1284289) +RewardsControllerTest:testAllClaimableUSDCWithRedeem() (gas: 1640881) +RewardsControllerTest:testAllClaimableUSDCWithTransfer() (gas: 2220830) +RewardsControllerTest:testAllClaimableUSDCWithTransferFrom() (gas: 2135769) +RewardsControllerTest:testAllClaimableUSDCWithWithdraw() (gas: 1641894) +RewardsControllerTest:testAllClaimableWETH() (gas: 1247851) +RewardsControllerTest:testAllClaimableWithMaturedFixedPool() (gas: 1128294) +RewardsControllerTest:testAllClaimableWithTimeElapsedZero() (gas: 1625327) +RewardsControllerTest:testAllRewards() (gas: 216315) +RewardsControllerTest:testClaim() (gas: 1192577) +RewardsControllerTest:testClaimAll() (gas: 2189364) +RewardsControllerTest:testClaimMarketWithoutRewards() (gas: 1241247) +RewardsControllerTest:testClaimWithNotEnabledRewardAsset() (gas: 1223075) +RewardsControllerTest:testConfigSettingNewStartWithOnGoingDistributionShouldNotUpdate() (gas: 430465) +RewardsControllerTest:testConfigWithDistributionNotYetStartedShouldNotFail() (gas: 613446) RewardsControllerTest:testConfigWithTransitionFactorHigherOrEqThanCap() (gas: 107189) -RewardsControllerTest:testConfigWithZeroDepositAllocationWeightFactorShouldRevert() (gas: 71542) -RewardsControllerTest:testDifferentDistributionTimeForDifferentRewards() (gas: 2025727) -RewardsControllerTest:testEmitAccrue() (gas: 1317912) -RewardsControllerTest:testEmitClaimRewards() (gas: 1112371) -RewardsControllerTest:testEmitConfigUpdate() (gas: 439567) -RewardsControllerTest:testEmitIndexUpdate() (gas: 1445522) -RewardsControllerTest:testLastUndistributed() (gas: 2189649) -RewardsControllerTest:testOperationAfterDistributionEnded() (gas: 722976) -RewardsControllerTest:testOperationsBeforeDistributionStart() (gas: 1674572) -RewardsControllerTest:testPermitClaim() (gas: 1275278) -RewardsControllerTest:testSetDistributionConfigWithDifferentDecimals() (gas: 11455542) +RewardsControllerTest:testConfigWithZeroDepositAllocationWeightFactorShouldRevert() (gas: 71475) +RewardsControllerTest:testDifferentDistributionTimeForDifferentRewards() (gas: 2026279) +RewardsControllerTest:testEmitAccrue() (gas: 1318654) +RewardsControllerTest:testEmitClaimRewards() (gas: 1112943) +RewardsControllerTest:testEmitConfigUpdate() (gas: 439500) +RewardsControllerTest:testEmitIndexUpdate() (gas: 1446604) +RewardsControllerTest:testLastUndistributed() (gas: 2191515) +RewardsControllerTest:testLastUpdateAfterDistributionPeriodEnd() (gas: 1848042) +RewardsControllerTest:testOperationAfterDistributionEnded() (gas: 723078) +RewardsControllerTest:testOperationsBeforeDistributionStart() (gas: 1675436) +RewardsControllerTest:testPermitClaim() (gas: 1275720) +RewardsControllerTest:testSetDistributionConfigWithDifferentDecimals() (gas: 11456364) RewardsControllerTest:testSetDistributionOperationShouldUpdateIndex() (gas: 136200) -RewardsControllerTest:testSetDistributionWithOnGoingMarketOperations() (gas: 1202354) -RewardsControllerTest:testSetHigherTotalDistribution() (gas: 1831286) -RewardsControllerTest:testSetLowerAndEqualDistributionPeriodThanCurrentTimestampShouldRevert() (gas: 1274975) -RewardsControllerTest:testSetLowerAndEqualTotalDistributionThanReleasedShouldRevert() (gas: 1268000) -RewardsControllerTest:testSetLowerDistributionPeriod() (gas: 2284257) -RewardsControllerTest:testSetLowerDistributionPeriodAndLowerTotalDistribution() (gas: 2286982) -RewardsControllerTest:testSetLowerTotalDistribution() (gas: 1831199) -RewardsControllerTest:testSetNewDistributionPeriod() (gas: 3144049) -RewardsControllerTest:testSetNewDistributionPeriodAfterDistributionEnds() (gas: 1406662) -RewardsControllerTest:testSetNewTargetDebt() (gas: 1671610) -RewardsControllerTest:testSetNewTargetDebtAfterDistributionEnds() (gas: 1734958) -RewardsControllerTest:testSetNewTargetDebtWithClaimOnlyAtEnd() (gas: 1389750) -RewardsControllerTest:testSetNewTreasuryFeeShouldImpactAllocation() (gas: 658882) -RewardsControllerTest:testSetTargetDebtMultipleTimes() (gas: 2719569) -RewardsControllerTest:testSetTargetDebtMultipleTimesAfterEnd() (gas: 2756086) -RewardsControllerTest:testSetTotalDistributionMultipleTimes() (gas: 1838471) -RewardsControllerTest:testTriggerHandleBorrowHookBeforeUpdatingFloatingDebt() (gas: 1879378) -RewardsControllerTest:testUpdateConfig() (gas: 1328944) -RewardsControllerTest:testUpdateIndexesWithUtilizationEqualToOne() (gas: 1257767) -RewardsControllerTest:testUpdateIndexesWithUtilizationHigherThanOne() (gas: 1352508) -RewardsControllerTest:testUpdateWithTotalDebtZeroShouldUpdateLastUndistributed() (gas: 575506) -RewardsControllerTest:testUtilizationEqualZero() (gas: 921863) -RewardsControllerTest:testWithTwelveFixedPools() (gas: 8055527) -RewardsControllerTest:testWithdrawAllRewardBalance() (gas: 71913) -RewardsControllerTest:testWithdrawOnlyAdminRole() (gas: 122309) +RewardsControllerTest:testSetDistributionWithOnGoingMarketOperations() (gas: 1202546) +RewardsControllerTest:testSetHigherTotalDistribution() (gas: 1833017) +RewardsControllerTest:testSetLowerAndEqualDistributionPeriodThanCurrentTimestampShouldRevert() (gas: 1275675) +RewardsControllerTest:testSetLowerAndEqualTotalDistributionThanReleasedShouldRevert() (gas: 1268722) +RewardsControllerTest:testSetLowerDistributionPeriod() (gas: 2286644) +RewardsControllerTest:testSetLowerDistributionPeriodAndLowerTotalDistribution() (gas: 2289457) +RewardsControllerTest:testSetLowerTotalDistribution() (gas: 1832952) +RewardsControllerTest:testSetNewDistributionPeriod() (gas: 3147502) +RewardsControllerTest:testSetNewDistributionPeriodAfterDistributionEnds() (gas: 1407532) +RewardsControllerTest:testSetNewTargetDebt() (gas: 1672829) +RewardsControllerTest:testSetNewTargetDebtAfterDistributionEnds() (gas: 1736539) +RewardsControllerTest:testSetNewTargetDebtWithClaimOnlyAtEnd() (gas: 1390642) +RewardsControllerTest:testSetNewTreasuryFeeShouldImpactAllocation() (gas: 658922) +RewardsControllerTest:testSetTargetDebtMultipleTimes() (gas: 2721660) +RewardsControllerTest:testSetTargetDebtMultipleTimesAfterEnd() (gas: 2758550) +RewardsControllerTest:testSetTotalDistributionMultipleTimes() (gas: 1839593) +RewardsControllerTest:testTriggerHandleBorrowHookBeforeUpdatingFloatingDebt() (gas: 1879760) +RewardsControllerTest:testUpdateConfig() (gas: 1329664) +RewardsControllerTest:testUpdateIndexesWithUtilizationEqualToOne() (gas: 1258467) +RewardsControllerTest:testUpdateIndexesWithUtilizationHigherThanOne() (gas: 1353230) +RewardsControllerTest:testUpdateWithTotalDebtZeroShouldUpdateLastUndistributed() (gas: 575908) +RewardsControllerTest:testUtilizationEqualZero() (gas: 922133) +RewardsControllerTest:testWithTwelveFixedPools() (gas: 8060108) +RewardsControllerTest:testWithdrawAllRewardBalance() (gas: 71935) +RewardsControllerTest:testWithdrawOnlyAdminRole() (gas: 122220) SwapperTest:testSwapBasic() (gas: 216831) SwapperTest:testSwapWithAllowance() (gas: 481530) SwapperTest:testSwapWithInaccurateSlippageSendsETHToAccount() (gas: 297968) diff --git a/contracts/RewardsController.sol b/contracts/RewardsController.sol index 40e9420f..0319170c 100644 --- a/contracts/RewardsController.sol +++ b/contracts/RewardsController.sol @@ -315,7 +315,7 @@ contract RewardsController is Initializable, AccessControlUpgradeable { { uint256 lastUpdate = rewardData.lastUpdate; // `lastUpdate` can be greater than `block.timestamp` if distribution is set to start on a future date - if (block.timestamp > lastUpdate) { + if (block.timestamp > lastUpdate && (lastUpdate < rewardData.end || rewardData.lastUndistributed != 0)) { (uint256 borrowIndex, uint256 depositIndex, uint256 newUndistributed) = previewAllocation( rewardData, market, diff --git a/test/RewardsController.t.sol b/test/RewardsController.t.sol index 451037fe..c6d5ca5a 100644 --- a/test/RewardsController.t.sol +++ b/test/RewardsController.t.sol @@ -799,6 +799,31 @@ contract RewardsControllerTest is Test { assertEq(opRewardAsset.balanceOf(address(this)), opRewards); } + function testLastUpdateAfterDistributionPeriodEnd() external { + marketWETH.deposit(40_000 ether, address(this)); + marketWETH.borrow(20_000 ether, address(this), address(this)); + + (, uint256 distributionEnd, ) = rewardsController.distributionTime(marketWETH, opRewardAsset); + vm.warp(distributionEnd / 2); + rewardsController.claimAll(address(this)); + + vm.warp(distributionEnd + 1); + rewardsController.claimAll(address(this)); + (, , uint256 lastUndistributed) = rewardsController.rewardIndexes(marketWETH, opRewardAsset); + (, , uint256 lastUpdate) = rewardsController.distributionTime(marketWETH, opRewardAsset); + assertEq(lastUndistributed, 0); + assertEq(lastUpdate, distributionEnd + 1); + + vm.warp(distributionEnd * 2); + rewardsController.claimAll(address(this)); + (, , lastUpdate) = rewardsController.distributionTime(marketWETH, opRewardAsset); + + (, , lastUndistributed) = rewardsController.rewardIndexes(marketWETH, opRewardAsset); + (, , lastUpdate) = rewardsController.distributionTime(marketWETH, opRewardAsset); + assertEq(lastUndistributed, 0); + assertEq(lastUpdate, distributionEnd + 1); + } + function testSetDistributionWithOnGoingMarketOperations() external { vm.warp(1 days); marketWBTC.deposit(10e8, address(this));