diff --git a/certora/steward/specs/rules.spec b/certora/steward/specs/rules.spec index 883eabb0..7a49ab70 100644 --- a/certora/steward/specs/rules.spec +++ b/certora/steward/specs/rules.spec @@ -289,19 +289,19 @@ rule updateGhoBorrowCap__correctness() { assert BORROW_CAP==newBorrowCap; uint256 borrow_cap_after = BORROW_CAP; - assert borrow_cap_before <= borrow_cap_after && to_mathint(borrow_cap_after) <= 2*borrow_cap_before; + assert to_mathint(borrow_cap_after) <= 2*borrow_cap_before; } rule updateGhoBorrowRate__correctness() { env e; uint256 newBorrowRate; - uint256 borrow_rate_begore = BORROW_RATE; + uint256 borrow_rate_before = BORROW_RATE; updateGhoBorrowRate(e,newBorrowRate); assert FAC.getStrategyByRate(newBorrowRate) == STRATEGY; - assert (borrow_rate_begore-GHO_BORROW_RATE_CHANGE_MAX() <= to_mathint(newBorrowRate) + assert (borrow_rate_before-GHO_BORROW_RATE_CHANGE_MAX() <= to_mathint(newBorrowRate) && - to_mathint(newBorrowRate) <= borrow_rate_begore+GHO_BORROW_RATE_CHANGE_MAX()); + to_mathint(newBorrowRate) <= borrow_rate_before+GHO_BORROW_RATE_CHANGE_MAX()); assert (newBorrowRate <= GHO_BORROW_RATE_MAX()); } @@ -313,8 +313,7 @@ rule updateGsmExposureCap__correctness() { assert EXPOSURE_CAP==newExposureCap; uint128 exposure_cap_after = EXPOSURE_CAP; - assert exposure_cap_before <= exposure_cap_after && - to_mathint(exposure_cap_after) <= 2*exposure_cap_before; + assert to_mathint(exposure_cap_after) <= 2*exposure_cap_before; } diff --git a/src/contracts/misc/GhoStewardV2.sol b/src/contracts/misc/GhoStewardV2.sol index 3553848b..40311ed4 100644 --- a/src/contracts/misc/GhoStewardV2.sol +++ b/src/contracts/misc/GhoStewardV2.sol @@ -20,10 +20,10 @@ import {IGhoStewardV2} from './interfaces/IGhoStewardV2.sol'; * @title GhoStewardV2 * @author Aave Labs * @notice Helper contract for managing parameters of the GHO reserve and GSM - * @dev This contract must be granted `PoolAdmin` in the Aave V3 Ethereum Pool, `BucketManager` in GHO Token and `Configurator` in every GSM asset to be managed. + * @dev This contract must be granted `RiskAdmin` in the Aave V3 Ethereum Pool, `BucketManager` in GHO Token and `Configurator` in every GSM asset to be managed. * @dev Only the Risk Council is able to action contract's functions, based on specific conditions that have been agreed upon with the community. * @dev Only the Aave DAO is able add or remove approved GSMs. - * @dev When updating GSM fee strategy the method asumes that the current strategy is FixedFeeStrategy for enforcing parameters + * @dev When updating GSM fee strategy the method assumes that the current strategy is FixedFeeStrategy for enforcing parameters * @dev FixedFeeStrategy is used when creating a new strategy for GSM * @dev FixedRateStrategyFactory is used when creating a new borrow rate strategy for GHO */ @@ -136,7 +136,7 @@ contract GhoStewardV2 is Ownable, IGhoStewardV2 { ).getConfiguration(GHO_TOKEN); uint256 currentBorrowCap = configuration.getBorrowCap(); require( - _isIncreaseLowerThanMax(currentBorrowCap, newBorrowCap, currentBorrowCap), + _isDifferenceLowerThanMax(currentBorrowCap, newBorrowCap, currentBorrowCap), 'INVALID_BORROW_CAP_UPDATE' ); @@ -186,7 +186,7 @@ contract GhoStewardV2 is Ownable, IGhoStewardV2 { ) external onlyRiskCouncil notTimelocked(_gsmTimelocksByAddress[gsm].gsmExposureCapLastUpdated) { uint128 currentExposureCap = IGsm(gsm).getExposureCap(); require( - _isIncreaseLowerThanMax(currentExposureCap, newExposureCap, currentExposureCap), + _isDifferenceLowerThanMax(currentExposureCap, newExposureCap, currentExposureCap), 'INVALID_EXPOSURE_CAP_UPDATE' ); @@ -207,11 +207,11 @@ contract GhoStewardV2 is Ownable, IGhoStewardV2 { uint256 currentBuyFee = IGsmFeeStrategy(currentFeeStrategy).getBuyFee(1e4); uint256 currentSellFee = IGsmFeeStrategy(currentFeeStrategy).getSellFee(1e4); require( - _isIncreaseLowerThanMax(currentBuyFee, buyFee, GSM_FEE_RATE_CHANGE_MAX), + _isDifferenceLowerThanMax(currentBuyFee, buyFee, GSM_FEE_RATE_CHANGE_MAX), 'INVALID_BUY_FEE_UPDATE' ); require( - _isIncreaseLowerThanMax(currentSellFee, sellFee, GSM_FEE_RATE_CHANGE_MAX), + _isDifferenceLowerThanMax(currentSellFee, sellFee, GSM_FEE_RATE_CHANGE_MAX), 'INVALID_SELL_FEE_UPDATE' ); diff --git a/src/contracts/misc/interfaces/IGhoStewardV2.sol b/src/contracts/misc/interfaces/IGhoStewardV2.sol index 5f3aa7a8..2b0138da 100644 --- a/src/contracts/misc/interfaces/IGhoStewardV2.sol +++ b/src/contracts/misc/interfaces/IGhoStewardV2.sol @@ -31,7 +31,7 @@ interface IGhoStewardV2 { /** * @notice Updates the GHO borrow cap, only if: * - respects `MINIMUM_DELAY`, the minimum time delay between updates - * - the update changes up to 100% upwards + * - the update changes up to 100% upwards or downwards * @dev Only callable by Risk Council * @param newBorrowCap The new borrow cap (in whole tokens) */ @@ -50,7 +50,7 @@ interface IGhoStewardV2 { /** * @notice Updates the exposure cap of the GSM, only if: * - respects `MINIMUM_DELAY`, the minimum time delay between updates - * - the update changes up to 100% upwards + * - the update changes up to 100% upwards or downwards * @dev Only callable by Risk Council * @param gsm The gsm address to update * @param newExposureCap The new exposure cap (in underlying asset terms) @@ -60,7 +60,7 @@ interface IGhoStewardV2 { /** * @notice Updates the fixed percent fees of the GSM, only if: * - respects `MINIMUM_DELAY`, the minimum time delay between updates - * - the update changes up to `GSM_FEE_RATE_CHANGE_MAX` upwards (for both buy and sell individually); + * - the update changes up to `GSM_FEE_RATE_CHANGE_MAX` upwards or downwards (for both buy and sell individually) * @dev Only callable by Risk Council * @param gsm The gsm address to update * @param buyFee The new buy fee (expressed in bps) (e.g. 0.0150e4 results in 1.50%) diff --git a/src/test/TestGhoStewardV2.t.sol b/src/test/TestGhoStewardV2.t.sol index 3eefe5eb..dabefdc7 100644 --- a/src/test/TestGhoStewardV2.t.sol +++ b/src/test/TestGhoStewardV2.t.sol @@ -153,16 +153,6 @@ contract TestGhoStewardV2 is TestGhoBase { ); } - function testRevertUpdateFacilitatorBucketCapacityIfValueLowerThanCurrent() public { - (uint256 currentBucketCapacity, ) = GHO_TOKEN.getFacilitatorBucket(address(GHO_ATOKEN)); - vm.prank(RISK_COUNCIL); - vm.expectRevert('INVALID_BUCKET_CAPACITY_UPDATE'); - GHO_STEWARD_V2.updateFacilitatorBucketCapacity( - address(GHO_ATOKEN), - uint128(currentBucketCapacity) - 1 - ); - } - function testRevertUpdateFacilitatorBucketCapacityIfMoreThanDouble() public { (uint256 currentBucketCapacity, ) = GHO_TOKEN.getFacilitatorBucket(address(GHO_ATOKEN)); vm.prank(RISK_COUNCIL); @@ -183,7 +173,7 @@ contract TestGhoStewardV2 is TestGhoBase { assertEq(newBorrowCap, currentBorrowCap); } - function testUpdateGhoBorrowCapMaxValue() public { + function testUpdateGhoBorrowCapMaxIncrease() public { uint256 oldBorrowCap = 1e6; _setGhoBorrowCapViaConfigurator(oldBorrowCap); uint256 newBorrowCap = oldBorrowCap * 2; @@ -193,6 +183,13 @@ contract TestGhoStewardV2 is TestGhoBase { assertEq(newBorrowCap, currentBorrowCap); } + function testUpdateGhoBorrowCapMaxDecrease() public { + vm.prank(RISK_COUNCIL); + GHO_STEWARD_V2.updateGhoBorrowCap(0); + uint256 currentBorrowCap = _getGhoBorrowCap(); + assertEq(currentBorrowCap, 0); + } + function testUpdateGhoBorrowCapTimelock() public { uint256 oldBorrowCap = 1e6; _setGhoBorrowCapViaConfigurator(oldBorrowCap); @@ -231,14 +228,6 @@ contract TestGhoStewardV2 is TestGhoBase { GHO_STEWARD_V2.updateGhoBorrowCap(oldBorrowCap + 2); } - function testRevertUpdateGhoBorrowCapIfValueLowerThanCurrent() public { - uint256 oldBorrowCap = 1e6; - _setGhoBorrowCapViaConfigurator(oldBorrowCap); - vm.prank(RISK_COUNCIL); - vm.expectRevert('INVALID_BORROW_CAP_UPDATE'); - GHO_STEWARD_V2.updateGhoBorrowCap(oldBorrowCap - 1); - } - function testRevertUpdateGhoBorrowCapIfValueMoreThanDouble() public { uint256 oldBorrowCap = 1e6; _setGhoBorrowCapViaConfigurator(oldBorrowCap); @@ -247,7 +236,7 @@ contract TestGhoStewardV2 is TestGhoBase { GHO_STEWARD_V2.updateGhoBorrowCap(oldBorrowCap * 2 + 1); } - function testUpdateGhoBorrowRate() public { + function testUpdateGhoBorrowRateUpwards() public { uint256 oldBorrowRate = _getGhoBorrowRate(); uint256 newBorrowRate = oldBorrowRate + 1; vm.prank(RISK_COUNCIL); @@ -256,6 +245,15 @@ contract TestGhoStewardV2 is TestGhoBase { assertEq(currentBorrowRate, newBorrowRate); } + function testUpdateGhoBorrowRateDownwards() public { + uint256 oldBorrowRate = _getGhoBorrowRate(); + uint256 newBorrowRate = oldBorrowRate - 1; + vm.prank(RISK_COUNCIL); + GHO_STEWARD_V2.updateGhoBorrowRate(newBorrowRate); + uint256 currentBorrowRate = _getGhoBorrowRate(); + assertEq(currentBorrowRate, newBorrowRate); + } + function testUpdateGhoBorrowRateMaxValue() public { uint256 ghoBorrowRateMax = GHO_STEWARD_V2.GHO_BORROW_RATE_MAX(); (, uint256 oldBorrowRate) = _setGhoBorrowRateViaConfigurator(ghoBorrowRateMax - 1); @@ -382,7 +380,7 @@ contract TestGhoStewardV2 is TestGhoBase { vm.stopPrank(); } - function testUpdateGsmExposureCap() public { + function testUpdateGsmExposureCapUpwards() public { uint128 oldExposureCap = GHO_GSM.getExposureCap(); vm.prank(RISK_COUNCIL); uint128 newExposureCap = oldExposureCap + 1; @@ -391,7 +389,16 @@ contract TestGhoStewardV2 is TestGhoBase { assertEq(currentExposureCap, newExposureCap); } - function testUpdateGsmExposureCapMaxValue() public { + function testUpdateGsmExposureCapDownwards() public { + uint128 oldExposureCap = GHO_GSM.getExposureCap(); + vm.prank(RISK_COUNCIL); + uint128 newExposureCap = oldExposureCap - 1; + GHO_STEWARD_V2.updateGsmExposureCap(address(GHO_GSM), newExposureCap); + uint128 currentExposureCap = GHO_GSM.getExposureCap(); + assertEq(currentExposureCap, newExposureCap); + } + + function testUpdateGsmExposureCapMaxIncrease() public { uint128 oldExposureCap = GHO_GSM.getExposureCap(); uint128 newExposureCap = oldExposureCap * 2; vm.prank(RISK_COUNCIL); @@ -400,6 +407,13 @@ contract TestGhoStewardV2 is TestGhoBase { assertEq(currentExposureCap, newExposureCap); } + function testUpdateGsmExposureCapMaxDecrease() public { + vm.prank(RISK_COUNCIL); + GHO_STEWARD_V2.updateGsmExposureCap(address(GHO_GSM), 0); + uint128 currentExposureCap = GHO_GSM.getExposureCap(); + assertEq(currentExposureCap, 0); + } + function testUpdateGsmExposureCapTimelock() public { uint128 oldExposureCap = GHO_GSM.getExposureCap(); vm.prank(RISK_COUNCIL); @@ -435,13 +449,6 @@ contract TestGhoStewardV2 is TestGhoBase { GHO_STEWARD_V2.updateGsmExposureCap(address(GHO_GSM), oldExposureCap + 2); } - function testRevertUpdateGsmExposureCapIfValueLowerThanCurrent() public { - uint128 oldExposureCap = GHO_GSM.getExposureCap(); - vm.prank(RISK_COUNCIL); - vm.expectRevert('INVALID_EXPOSURE_CAP_UPDATE'); - GHO_STEWARD_V2.updateGsmExposureCap(address(GHO_GSM), oldExposureCap - 1); - } - function testRevertUpdateGsmExposureCapIfValueMoreThanDouble() public { uint128 oldExposureCap = GHO_GSM.getExposureCap(); vm.prank(RISK_COUNCIL); @@ -459,7 +466,7 @@ contract TestGhoStewardV2 is TestGhoBase { GHO_STEWARD_V2.updateGsmExposureCap(address(GHO_GSM), oldExposureCap + 1); } - function testUpdateGsmBuySellFeesBuyFee() public { + function testUpdateGsmBuySellFeesBuyFeeUpwards() public { address feeStrategy = GHO_GSM.getFeeStrategy(); uint256 buyFee = IGsmFeeStrategy(feeStrategy).getBuyFee(1e4); uint256 sellFee = IGsmFeeStrategy(feeStrategy).getSellFee(1e4); @@ -470,6 +477,17 @@ contract TestGhoStewardV2 is TestGhoBase { assertEq(newBuyFee, buyFee + 1); } + function testUpdateGsmBuySellFeesBuyFeeDownwards() public { + address feeStrategy = GHO_GSM.getFeeStrategy(); + uint256 buyFee = IGsmFeeStrategy(feeStrategy).getBuyFee(1e4); + uint256 sellFee = IGsmFeeStrategy(feeStrategy).getSellFee(1e4); + vm.prank(RISK_COUNCIL); + GHO_STEWARD_V2.updateGsmBuySellFees(address(GHO_GSM), buyFee - 1, sellFee); + address newStrategy = GHO_GSM.getFeeStrategy(); + uint256 newBuyFee = IGsmFeeStrategy(newStrategy).getBuyFee(1e4); + assertEq(newBuyFee, buyFee - 1); + } + function testUpdateGsmBuySellFeesBuyFeeMax() public { address feeStrategy = GHO_GSM.getFeeStrategy(); uint256 buyFee = IGsmFeeStrategy(feeStrategy).getBuyFee(1e4); @@ -482,7 +500,19 @@ contract TestGhoStewardV2 is TestGhoBase { assertEq(newBuyFee, buyFee + maxFeeUpdate); } - function testUpdateGsmBuySellFeesSellFee() public { + function testUpdateGsmBuySellFeesBuyFeeMin() public { + address feeStrategy = GHO_GSM.getFeeStrategy(); + uint256 buyFee = IGsmFeeStrategy(feeStrategy).getBuyFee(1e4); + uint256 sellFee = IGsmFeeStrategy(feeStrategy).getSellFee(1e4); + uint256 maxFeeUpdate = GHO_STEWARD_V2.GSM_FEE_RATE_CHANGE_MAX(); + vm.prank(RISK_COUNCIL); + GHO_STEWARD_V2.updateGsmBuySellFees(address(GHO_GSM), buyFee - maxFeeUpdate, sellFee); + address newStrategy = GHO_GSM.getFeeStrategy(); + uint256 newBuyFee = IGsmFeeStrategy(newStrategy).getBuyFee(1e4); + assertEq(newBuyFee, buyFee - maxFeeUpdate); + } + + function testUpdateGsmBuySellFeesSellFeeUpwards() public { address feeStrategy = GHO_GSM.getFeeStrategy(); uint256 buyFee = IGsmFeeStrategy(feeStrategy).getBuyFee(1e4); uint256 sellFee = IGsmFeeStrategy(feeStrategy).getSellFee(1e4); @@ -493,6 +523,17 @@ contract TestGhoStewardV2 is TestGhoBase { assertEq(newSellFee, sellFee + 1); } + function testUpdateGsmBuySellFeesSellFeeDownwards() public { + address feeStrategy = GHO_GSM.getFeeStrategy(); + uint256 buyFee = IGsmFeeStrategy(feeStrategy).getBuyFee(1e4); + uint256 sellFee = IGsmFeeStrategy(feeStrategy).getSellFee(1e4); + vm.prank(RISK_COUNCIL); + GHO_STEWARD_V2.updateGsmBuySellFees(address(GHO_GSM), buyFee, sellFee - 1); + address newStrategy = GHO_GSM.getFeeStrategy(); + uint256 newSellFee = IGsmFeeStrategy(newStrategy).getSellFee(1e4); + assertEq(newSellFee, sellFee - 1); + } + function testUpdateGsmBuySellFeesSellFeeMax() public { address feeStrategy = GHO_GSM.getFeeStrategy(); uint256 buyFee = IGsmFeeStrategy(feeStrategy).getBuyFee(1e4); @@ -505,7 +546,19 @@ contract TestGhoStewardV2 is TestGhoBase { assertEq(newSellFee, sellFee + maxFeeUpdate); } - function testUpdateGsmBuySellFeesBothFees() public { + function testUpdateGsmBuySellFeesSellFeeMin() public { + address feeStrategy = GHO_GSM.getFeeStrategy(); + uint256 buyFee = IGsmFeeStrategy(feeStrategy).getBuyFee(1e4); + uint256 sellFee = IGsmFeeStrategy(feeStrategy).getSellFee(1e4); + uint256 maxFeeUpdate = GHO_STEWARD_V2.GSM_FEE_RATE_CHANGE_MAX(); + vm.prank(RISK_COUNCIL); + GHO_STEWARD_V2.updateGsmBuySellFees(address(GHO_GSM), buyFee, sellFee - maxFeeUpdate); + address newStrategy = GHO_GSM.getFeeStrategy(); + uint256 newSellFee = IGsmFeeStrategy(newStrategy).getSellFee(1e4); + assertEq(newSellFee, sellFee - maxFeeUpdate); + } + + function testUpdateGsmBuySellFeesBothFeesUpwards() public { address feeStrategy = GHO_GSM.getFeeStrategy(); uint256 buyFee = IGsmFeeStrategy(feeStrategy).getBuyFee(1e4); uint256 sellFee = IGsmFeeStrategy(feeStrategy).getSellFee(1e4); @@ -518,6 +571,19 @@ contract TestGhoStewardV2 is TestGhoBase { assertEq(newSellFee, sellFee + 1); } + function testUpdateGsmBuySellFeesBothFeesDownwards() public { + address feeStrategy = GHO_GSM.getFeeStrategy(); + uint256 buyFee = IGsmFeeStrategy(feeStrategy).getBuyFee(1e4); + uint256 sellFee = IGsmFeeStrategy(feeStrategy).getSellFee(1e4); + vm.prank(RISK_COUNCIL); + GHO_STEWARD_V2.updateGsmBuySellFees(address(GHO_GSM), buyFee - 1, sellFee - 1); + address newStrategy = GHO_GSM.getFeeStrategy(); + uint256 newBuyFee = IGsmFeeStrategy(newStrategy).getBuyFee(1e4); + uint256 newSellFee = IGsmFeeStrategy(newStrategy).getSellFee(1e4); + assertEq(newBuyFee, buyFee - 1); + assertEq(newSellFee, sellFee - 1); + } + function testUpdateGsmBuySellFeesBothFeesMax() public { address feeStrategy = GHO_GSM.getFeeStrategy(); uint256 buyFee = IGsmFeeStrategy(feeStrategy).getBuyFee(1e4); @@ -536,6 +602,24 @@ contract TestGhoStewardV2 is TestGhoBase { assertEq(newSellFee, sellFee + maxFeeUpdate); } + function testUpdateGsmBuySellFeesBothFeesMin() public { + address feeStrategy = GHO_GSM.getFeeStrategy(); + uint256 buyFee = IGsmFeeStrategy(feeStrategy).getBuyFee(1e4); + uint256 sellFee = IGsmFeeStrategy(feeStrategy).getSellFee(1e4); + uint256 maxFeeUpdate = GHO_STEWARD_V2.GSM_FEE_RATE_CHANGE_MAX(); + vm.prank(RISK_COUNCIL); + GHO_STEWARD_V2.updateGsmBuySellFees( + address(GHO_GSM), + buyFee - maxFeeUpdate, + sellFee - maxFeeUpdate + ); + address newStrategy = GHO_GSM.getFeeStrategy(); + uint256 newBuyFee = IGsmFeeStrategy(newStrategy).getBuyFee(1e4); + uint256 newSellFee = IGsmFeeStrategy(newStrategy).getSellFee(1e4); + assertEq(newBuyFee, buyFee - maxFeeUpdate); + assertEq(newSellFee, sellFee - maxFeeUpdate); + } + function testUpdateGsmBuySellFeesTimelock() public { address feeStrategy = GHO_GSM.getFeeStrategy(); uint256 buyFee = IGsmFeeStrategy(feeStrategy).getBuyFee(1e4); @@ -623,54 +707,61 @@ contract TestGhoStewardV2 is TestGhoBase { GHO_STEWARD_V2.updateGsmBuySellFees(address(GHO_GSM), buyFee + 1, sellFee + 1); } - function testRevertUpdateGsmBuySellFeesIfBuyFeeDecrement() public { + function testRevertUpdateGsmBuySellFeesIfBuyFeeMoreThanMax() public { address feeStrategy = GHO_GSM.getFeeStrategy(); + uint256 maxFeeUpdate = GHO_STEWARD_V2.GSM_FEE_RATE_CHANGE_MAX(); uint256 buyFee = IGsmFeeStrategy(feeStrategy).getBuyFee(1e4); uint256 sellFee = IGsmFeeStrategy(feeStrategy).getSellFee(1e4); vm.prank(RISK_COUNCIL); vm.expectRevert('INVALID_BUY_FEE_UPDATE'); - GHO_STEWARD_V2.updateGsmBuySellFees(address(GHO_GSM), buyFee - 1, sellFee); + GHO_STEWARD_V2.updateGsmBuySellFees(address(GHO_GSM), buyFee + maxFeeUpdate + 1, sellFee); } - function testRevertUpdateGsmBuySellFeesIfSellFeeDecrement() public { + function testRevertUpdateGsmBuySellFeesIfBuyFeeLessThanMin() public { address feeStrategy = GHO_GSM.getFeeStrategy(); + uint256 maxFeeUpdate = GHO_STEWARD_V2.GSM_FEE_RATE_CHANGE_MAX(); uint256 buyFee = IGsmFeeStrategy(feeStrategy).getBuyFee(1e4); uint256 sellFee = IGsmFeeStrategy(feeStrategy).getSellFee(1e4); vm.prank(RISK_COUNCIL); - vm.expectRevert('INVALID_SELL_FEE_UPDATE'); - GHO_STEWARD_V2.updateGsmBuySellFees(address(GHO_GSM), buyFee, sellFee - 1); + vm.expectRevert('INVALID_BUY_FEE_UPDATE'); + GHO_STEWARD_V2.updateGsmBuySellFees(address(GHO_GSM), buyFee - maxFeeUpdate - 1, sellFee); } - function testRevertUpdateGsmBuySellFeesIfBothDecrement() public { + function testRevertUpdateGsmBuySellFeesIfSellFeeMoreThanMax() public { address feeStrategy = GHO_GSM.getFeeStrategy(); + uint256 maxFeeUpdate = GHO_STEWARD_V2.GSM_FEE_RATE_CHANGE_MAX(); uint256 buyFee = IGsmFeeStrategy(feeStrategy).getBuyFee(1e4); uint256 sellFee = IGsmFeeStrategy(feeStrategy).getSellFee(1e4); vm.prank(RISK_COUNCIL); - vm.expectRevert('INVALID_BUY_FEE_UPDATE'); - GHO_STEWARD_V2.updateGsmBuySellFees(address(GHO_GSM), buyFee - 1, sellFee - 1); + vm.expectRevert('INVALID_SELL_FEE_UPDATE'); + GHO_STEWARD_V2.updateGsmBuySellFees(address(GHO_GSM), buyFee, sellFee + maxFeeUpdate + 1); } - function testRevertUpdateGsmBuySellFeesIfBuyFeeMoreThanMax() public { + function testRevertUpdateGsmBuySellFeesIfSellFeeLessThanMin() public { address feeStrategy = GHO_GSM.getFeeStrategy(); uint256 maxFeeUpdate = GHO_STEWARD_V2.GSM_FEE_RATE_CHANGE_MAX(); uint256 buyFee = IGsmFeeStrategy(feeStrategy).getBuyFee(1e4); uint256 sellFee = IGsmFeeStrategy(feeStrategy).getSellFee(1e4); vm.prank(RISK_COUNCIL); - vm.expectRevert('INVALID_BUY_FEE_UPDATE'); - GHO_STEWARD_V2.updateGsmBuySellFees(address(GHO_GSM), buyFee + maxFeeUpdate + 1, sellFee); + vm.expectRevert('INVALID_SELL_FEE_UPDATE'); + GHO_STEWARD_V2.updateGsmBuySellFees(address(GHO_GSM), buyFee, sellFee - maxFeeUpdate - 1); } - function testRevertUpdateGsmBuySellFeesIfSellFeeMoreThanMax() public { + function testRevertUpdateGsmBuySellFeesIfBothMoreThanMax() public { address feeStrategy = GHO_GSM.getFeeStrategy(); uint256 maxFeeUpdate = GHO_STEWARD_V2.GSM_FEE_RATE_CHANGE_MAX(); uint256 buyFee = IGsmFeeStrategy(feeStrategy).getBuyFee(1e4); uint256 sellFee = IGsmFeeStrategy(feeStrategy).getSellFee(1e4); vm.prank(RISK_COUNCIL); - vm.expectRevert('INVALID_SELL_FEE_UPDATE'); - GHO_STEWARD_V2.updateGsmBuySellFees(address(GHO_GSM), buyFee, sellFee + maxFeeUpdate + 1); + vm.expectRevert('INVALID_BUY_FEE_UPDATE'); + GHO_STEWARD_V2.updateGsmBuySellFees( + address(GHO_GSM), + buyFee + maxFeeUpdate + 1, + sellFee + maxFeeUpdate + 1 + ); } - function testRevertUpdateGsmBuySellFeesIfBothMoreThanMax() public { + function testRevertUpdateGsmBuySellFeesIfBothLessThanMin() public { address feeStrategy = GHO_GSM.getFeeStrategy(); uint256 maxFeeUpdate = GHO_STEWARD_V2.GSM_FEE_RATE_CHANGE_MAX(); uint256 buyFee = IGsmFeeStrategy(feeStrategy).getBuyFee(1e4); @@ -679,8 +770,8 @@ contract TestGhoStewardV2 is TestGhoBase { vm.expectRevert('INVALID_BUY_FEE_UPDATE'); GHO_STEWARD_V2.updateGsmBuySellFees( address(GHO_GSM), - buyFee + maxFeeUpdate + 1, - sellFee + maxFeeUpdate + 1 + buyFee - maxFeeUpdate - 1, + sellFee - maxFeeUpdate - 1 ); }