From a229cc1774b4f519b4ba740c1dba12e80fa8c4d9 Mon Sep 17 00:00:00 2001 From: CheyenneAtapour Date: Wed, 21 Aug 2024 13:19:24 -0700 Subject: [PATCH] fix: address pr comments --- src/contracts/misc/GhoAaveSteward.sol | 117 +++++------------- src/contracts/misc/GhoBucketSteward.sol | 2 +- src/contracts/misc/GhoCcipSteward.sol | 10 +- src/contracts/misc/GhoGsmSteward.sol | 4 +- src/contracts/misc/RiskCouncilControlled.sol | 12 +- .../misc/interfaces/IGhoAaveSteward.sol | 21 +--- .../misc/interfaces/IGhoBucketSteward.sol | 12 +- src/test/TestGhoAaveSteward.t.sol | 18 --- 8 files changed, 52 insertions(+), 144 deletions(-) diff --git a/src/contracts/misc/GhoAaveSteward.sol b/src/contracts/misc/GhoAaveSteward.sol index 7af3b56f..d7b18284 100644 --- a/src/contracts/misc/GhoAaveSteward.sol +++ b/src/contracts/misc/GhoAaveSteward.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.10; import {Address} from 'solidity-utils/contracts/oz-common/Address.sol'; import {Ownable} from '@openzeppelin/contracts/access/Ownable.sol'; -import {IPoolDataProvider} from 'aave-address-book/AaveV3.sol'; +import {IPoolDataProvider} from '@aave/core-v3/contracts/interfaces/IPoolDataProvider.sol'; import {IPoolAddressesProvider} from '@aave/core-v3/contracts/interfaces/IPoolAddressesProvider.sol'; import {IPool} from '@aave/core-v3/contracts/interfaces/IPool.sol'; import {DataTypes} from '@aave/core-v3/contracts/protocol/libraries/types/DataTypes.sol'; @@ -23,7 +23,6 @@ import {RiskCouncilControlled} from './RiskCouncilControlled.sol'; */ contract GhoAaveSteward is Ownable, RiskCouncilControlled, IGhoAaveSteward { using ReserveConfiguration for DataTypes.ReserveConfigurationMap; - using Address for address; /// @inheritdoc IGhoAaveSteward uint256 public constant GHO_BORROW_RATE_MAX = 0.25e4; // 25.00% @@ -61,7 +60,7 @@ contract GhoAaveSteward is Ownable, RiskCouncilControlled, IGhoAaveSteward { * @param poolDataProvider The pool data provider of the pool to be controlled by the steward * @param ghoToken The address of the GhoToken * @param riskCouncil The address of the risk council - * @param borrowRateConfig The initial borrow rate configuration for the Gho reserve + * @param borrowRateConfig The configuration conditions for GHO borrow rate changes */ constructor( address owner, @@ -97,9 +96,19 @@ contract GhoAaveSteward is Ownable, RiskCouncilControlled, IGhoAaveSteward { variableRateSlope1, variableRateSlope2 ); - _updateRates(optimalUsageRatio, baseVariableBorrowRate, variableRateSlope1, variableRateSlope2); + + IDefaultInterestRateStrategyV2.InterestRateData + memory rateParams = IDefaultInterestRateStrategyV2.InterestRateData({ + optimalUsageRatio: uint16(optimalUsageRatio), + baseVariableBorrowRate: uint32(baseVariableBorrowRate), + variableRateSlope1: uint32(variableRateSlope1), + variableRateSlope2: uint32(variableRateSlope2) + }); _ghoTimelocks.ghoBorrowRateLastUpdate = uint40(block.timestamp); + + IPoolConfigurator(IPoolAddressesProvider(POOL_ADDRESSES_PROVIDER).getPoolConfigurator()) + .setReserveInterestRateData(GHO_TOKEN, abi.encode(rateParams)); } /// @inheritdoc IGhoAaveSteward @@ -148,20 +157,11 @@ contract GhoAaveSteward is Ownable, RiskCouncilControlled, IGhoAaveSteward { uint256 baseVariableBorrowRateMaxChange, uint256 variableRateSlope1MaxChange, uint256 variableRateSlope2MaxChange - ) external onlyOwner notTimelocked(_ghoTimelocks.riskConfigLastUpdate) { + ) external onlyOwner { _borrowRateConfig.optimalUsageRatioMaxChange = optimalUsageRatioMaxChange; _borrowRateConfig.baseVariableBorrowRateMaxChange = baseVariableBorrowRateMaxChange; _borrowRateConfig.variableRateSlope1MaxChange = variableRateSlope1MaxChange; _borrowRateConfig.variableRateSlope2MaxChange = variableRateSlope2MaxChange; - - _ghoTimelocks.riskConfigLastUpdate = uint40(block.timestamp); - - emit BorrowRateConfigSet( - optimalUsageRatioMaxChange, - baseVariableBorrowRateMaxChange, - variableRateSlope1MaxChange, - variableRateSlope2MaxChange - ); } /// @inheritdoc IGhoAaveSteward @@ -176,36 +176,11 @@ contract GhoAaveSteward is Ownable, RiskCouncilControlled, IGhoAaveSteward { /// @inheritdoc IGhoAaveSteward function RISK_COUNCIL() public view override returns (address) { - return COUNCIL; + return riskCouncil; } /** - * @notice method to update the interest rates params using the config engine and updates the debounce - * @param optimalUsageRatio The new optimal usage ratio - * @param baseVariableBorrowRate The new base variable borrow rate - * @param variableRateSlope1 The new variable rate slope 1 - * @param variableRateSlope2 The new variable rate slope 2 - */ - function _updateRates( - uint256 optimalUsageRatio, - uint256 baseVariableBorrowRate, - uint256 variableRateSlope1, - uint256 variableRateSlope2 - ) internal { - IDefaultInterestRateStrategyV2.InterestRateData - memory rateParams = IDefaultInterestRateStrategyV2.InterestRateData({ - optimalUsageRatio: uint16(optimalUsageRatio), - baseVariableBorrowRate: uint32(baseVariableBorrowRate), - variableRateSlope1: uint32(variableRateSlope1), - variableRateSlope2: uint32(variableRateSlope2) - }); - - IPoolConfigurator(IPoolAddressesProvider(POOL_ADDRESSES_PROVIDER).getPoolConfigurator()) - .setReserveInterestRateData(GHO_TOKEN, abi.encode(rateParams)); - } - - /** - * @notice method to validate the interest rates update + * @dev Validates the interest rates update * @param optimalUsageRatio The new optimal usage ratio to validate * @param baseVariableBorrowRate The new base variable borrow rate to validate * @param variableRateSlope1 The new variable rate slope 1 to validate @@ -217,24 +192,23 @@ contract GhoAaveSteward is Ownable, RiskCouncilControlled, IGhoAaveSteward { uint256 variableRateSlope1, uint256 variableRateSlope2 ) internal view { - ( - uint256 currentOptimalUsageRatio, - uint256 currentBaseVariableBorrowRate, - uint256 currentVariableRateSlope1, - uint256 currentVariableRateSlope2 - ) = _getInterestRatesForAsset(GHO_TOKEN); + address rateStrategyAddress = IPoolDataProvider(POOL_DATA_PROVIDER) + .getInterestRateStrategyAddress(GHO_TOKEN); + IDefaultInterestRateStrategyV2.InterestRateData + memory currentRates = IDefaultInterestRateStrategyV2(rateStrategyAddress) + .getInterestRateDataBps(GHO_TOKEN); require( - optimalUsageRatio != currentOptimalUsageRatio || - baseVariableBorrowRate != currentBaseVariableBorrowRate || - variableRateSlope1 != currentVariableRateSlope1 || - variableRateSlope2 != currentVariableRateSlope2, + optimalUsageRatio != currentRates.optimalUsageRatio || + baseVariableBorrowRate != currentRates.baseVariableBorrowRate || + variableRateSlope1 != currentRates.variableRateSlope1 || + variableRateSlope2 != currentRates.variableRateSlope2, 'NO_CHANGE_IN_RATES' ); require( _updateWithinAllowedRange( - currentOptimalUsageRatio, + currentRates.optimalUsageRatio, optimalUsageRatio, _borrowRateConfig.optimalUsageRatioMaxChange, false @@ -243,7 +217,7 @@ contract GhoAaveSteward is Ownable, RiskCouncilControlled, IGhoAaveSteward { ); require( _updateWithinAllowedRange( - currentBaseVariableBorrowRate, + currentRates.baseVariableBorrowRate, baseVariableBorrowRate, _borrowRateConfig.baseVariableBorrowRateMaxChange, false @@ -252,7 +226,7 @@ contract GhoAaveSteward is Ownable, RiskCouncilControlled, IGhoAaveSteward { ); require( _updateWithinAllowedRange( - currentVariableRateSlope1, + currentRates.variableRateSlope1, variableRateSlope1, _borrowRateConfig.variableRateSlope1MaxChange, false @@ -261,7 +235,7 @@ contract GhoAaveSteward is Ownable, RiskCouncilControlled, IGhoAaveSteward { ); require( _updateWithinAllowedRange( - currentVariableRateSlope2, + currentRates.variableRateSlope2, variableRateSlope2, _borrowRateConfig.variableRateSlope2MaxChange, false @@ -276,39 +250,6 @@ contract GhoAaveSteward is Ownable, RiskCouncilControlled, IGhoAaveSteward { ); } - /** - * @notice method to fetch the current interest rate params of the asset - * @param asset the address of the underlying asset - * @return optimalUsageRatio the current optimal usage ratio of the asset - * @return baseVariableBorrowRate the current base variable borrow rate of the asset - * @return variableRateSlope1 the current variable rate slope 1 of the asset - * @return variableRateSlope2 the current variable rate slope 2 of the asset - */ - function _getInterestRatesForAsset( - address asset - ) - internal - view - returns ( - uint256 optimalUsageRatio, - uint256 baseVariableBorrowRate, - uint256 variableRateSlope1, - uint256 variableRateSlope2 - ) - { - address rateStrategyAddress = IPoolDataProvider(POOL_DATA_PROVIDER) - .getInterestRateStrategyAddress(asset); - IDefaultInterestRateStrategyV2.InterestRateData - memory interestRateData = IDefaultInterestRateStrategyV2(rateStrategyAddress) - .getInterestRateDataBps(asset); - return ( - interestRateData.optimalUsageRatio, - interestRateData.baseVariableBorrowRate, - interestRateData.variableRateSlope1, - interestRateData.variableRateSlope2 - ); - } - /** * @dev Ensures that the change difference is lower than max. * @param from current value diff --git a/src/contracts/misc/GhoBucketSteward.sol b/src/contracts/misc/GhoBucketSteward.sol index a97aec7a..9a7252fa 100644 --- a/src/contracts/misc/GhoBucketSteward.sol +++ b/src/contracts/misc/GhoBucketSteward.sol @@ -102,7 +102,7 @@ contract GhoBucketSteward is Ownable, RiskCouncilControlled, IGhoBucketSteward { /// @inheritdoc IGhoBucketSteward function RISK_COUNCIL() public view override returns (address) { - return COUNCIL; + return riskCouncil; } /** diff --git a/src/contracts/misc/GhoCcipSteward.sol b/src/contracts/misc/GhoCcipSteward.sol index 0e13e2c8..cba9c647 100644 --- a/src/contracts/misc/GhoCcipSteward.sol +++ b/src/contracts/misc/GhoCcipSteward.sol @@ -70,9 +70,9 @@ contract GhoCcipSteward is RiskCouncilControlled, IGhoCcipSteward { 'INVALID_BRIDGE_LIMIT_UPDATE' ); - IUpgradeableLockReleaseTokenPool(GHO_TOKEN_POOL).setBridgeLimit(newBridgeLimit); - _ccipTimelocks.bridgeLimitLastUpdate = uint40(block.timestamp); + + IUpgradeableLockReleaseTokenPool(GHO_TOKEN_POOL).setBridgeLimit(newBridgeLimit); } /// @inheritdoc IGhoCcipSteward @@ -117,6 +117,8 @@ contract GhoCcipSteward is RiskCouncilControlled, IGhoCcipSteward { 'INVALID_RATE_LIMIT_UPDATE' ); + _ccipTimelocks.rateLimitLastUpdate = uint40(block.timestamp); + IUpgradeableLockReleaseTokenPool(GHO_TOKEN_POOL).setChainRateLimiterConfig( remoteChainSelector, RateLimiter.Config({ @@ -126,13 +128,11 @@ contract GhoCcipSteward is RiskCouncilControlled, IGhoCcipSteward { }), RateLimiter.Config({isEnabled: inboundEnabled, capacity: inboundCapacity, rate: inboundRate}) ); - - _ccipTimelocks.rateLimitLastUpdate = uint40(block.timestamp); } /// @inheritdoc IGhoCcipSteward function RISK_COUNCIL() public view override returns (address) { - return COUNCIL; + return riskCouncil; } /** diff --git a/src/contracts/misc/GhoGsmSteward.sol b/src/contracts/misc/GhoGsmSteward.sol index 42cef195..b6341237 100644 --- a/src/contracts/misc/GhoGsmSteward.sol +++ b/src/contracts/misc/GhoGsmSteward.sol @@ -3,9 +3,9 @@ pragma solidity ^0.8.10; import {IGsm} from '../facilitators/gsm/interfaces/IGsm.sol'; import {IGsmFeeStrategy} from '../facilitators/gsm/feeStrategy/interfaces/IGsmFeeStrategy.sol'; +import {IFixedFeeStrategyFactory} from '../facilitators/gsm/feeStrategy/interfaces/IFixedFeeStrategyFactory.sol'; import {IGhoGsmSteward} from './interfaces/IGhoGsmSteward.sol'; import {RiskCouncilControlled} from './RiskCouncilControlled.sol'; -import {IFixedFeeStrategyFactory} from '../facilitators/gsm/feeStrategy/interfaces/IFixedFeeStrategyFactory.sol'; /** * @title GhoGsmSteward @@ -106,7 +106,7 @@ contract GhoGsmSteward is RiskCouncilControlled, IGhoGsmSteward { /// @inheritdoc IGhoGsmSteward function RISK_COUNCIL() public view override returns (address) { - return COUNCIL; + return riskCouncil; } /** diff --git a/src/contracts/misc/RiskCouncilControlled.sol b/src/contracts/misc/RiskCouncilControlled.sol index ce6d0449..63b7f2f1 100644 --- a/src/contracts/misc/RiskCouncilControlled.sol +++ b/src/contracts/misc/RiskCouncilControlled.sol @@ -7,22 +7,22 @@ pragma solidity ^0.8.10; * @notice Helper contract for controlling access to Steward and other functions restricted to Risk Council */ abstract contract RiskCouncilControlled { - address public immutable COUNCIL; + address internal immutable riskCouncil; /** * @dev Constructor - * @param riskCouncil The address of the risk council + * @param _riskCouncil The address of the risk council */ - constructor(address riskCouncil) { - require(riskCouncil != address(0), 'INVALID_RISK_COUNCIL'); - COUNCIL = riskCouncil; + constructor(address _riskCouncil) { + require(_riskCouncil != address(0), 'INVALID_RISK_COUNCIL'); + riskCouncil = _riskCouncil; } /** * @dev Only Risk Council can call functions marked by this modifier. */ modifier onlyRiskCouncil() { - require(COUNCIL == msg.sender, 'INVALID_CALLER'); + require(riskCouncil == msg.sender, 'INVALID_CALLER'); _; } } diff --git a/src/contracts/misc/interfaces/IGhoAaveSteward.sol b/src/contracts/misc/interfaces/IGhoAaveSteward.sol index e6e54e73..68728d34 100644 --- a/src/contracts/misc/interfaces/IGhoAaveSteward.sol +++ b/src/contracts/misc/interfaces/IGhoAaveSteward.sol @@ -7,20 +7,6 @@ pragma solidity ^0.8.10; * @notice Defines the basic interface of the GhoAaveSteward */ interface IGhoAaveSteward { - /** - * @notice Emitted when the borrow rate configuration has been updated - * @param optimalUsageRatioMaxChange The new allowed max percentage change for optimal usage ratio - * @param baseVariableBorrowRateMaxChange The new allowed max percentage change for base variable borrow rate - * @param variableRateSlope1MaxChange The new allowed max percentage change for variable rate slope 1 - * @param variableRateSlope2MaxChange The new allowed max percentage change for variable rate slope 2 - */ - event BorrowRateConfigSet( - uint256 optimalUsageRatioMaxChange, - uint256 baseVariableBorrowRateMaxChange, - uint256 variableRateSlope1MaxChange, - uint256 variableRateSlope2MaxChange - ); - /** * @notice Struct storing the last update by the steward of each borrow rate param */ @@ -28,7 +14,6 @@ interface IGhoAaveSteward { uint40 ghoBorrowCapLastUpdate; uint40 ghoSupplyCapLastUpdate; uint40 ghoBorrowRateLastUpdate; - uint40 riskConfigLastUpdate; } /** @@ -44,7 +29,7 @@ interface IGhoAaveSteward { /** * @notice Updates the borrow rate of GHO, only if: * - respects `MINIMUM_DELAY`, the minimum time delay between updates - * - the update changes up to 5% upwards or downwards + * - the update changes parameters up to the maximum allowed change according to risk config * - the update is lower than `GHO_BORROW_RATE_MAX` * @dev Only callable by Risk Council * @param optimalUsageRatio The new optimal usage ratio @@ -78,7 +63,7 @@ interface IGhoAaveSteward { function updateGhoSupplyCap(uint256 newSupplyCap) external; /** - * @notice method called by the Risk Council to set the borrow rate configuration params + * @notice Updates the configuration conditions for borrow rate changes * @param optimalUsageRatioMaxChange The new allowed max percentage change for optimal usage ratio * @param baseVariableBorrowRateMaxChange The new allowed max percentage change for base variable borrow rate * @param variableRateSlope1MaxChange The new allowed max percentage change for variable rate slope 1 @@ -92,7 +77,7 @@ interface IGhoAaveSteward { ) external; /** - * @notice method to get the borrow rate configuration + * @notice Returns the configuration conditions for a GHO borrow rate change * @return struct containing the borrow rate configuration */ function getBorrowRateConfig() external view returns (BorrowRateConfig memory); diff --git a/src/contracts/misc/interfaces/IGhoBucketSteward.sol b/src/contracts/misc/interfaces/IGhoBucketSteward.sol index dab1e56a..1dba429b 100644 --- a/src/contracts/misc/interfaces/IGhoBucketSteward.sol +++ b/src/contracts/misc/interfaces/IGhoBucketSteward.sol @@ -39,12 +39,6 @@ interface IGhoBucketSteward { */ function getFacilitatorBucketCapacityTimelock(address facilitator) external view returns (uint40); - /** - * @notice Returns the address of the risk council - * @return The address of the RiskCouncil - */ - function RISK_COUNCIL() external view returns (address); - /** * @notice Returns the minimum delay that must be respected between parameters update. * @return The minimum delay between parameter updates (in seconds) @@ -56,4 +50,10 @@ interface IGhoBucketSteward { * @return The address of the GhoToken */ function GHO_TOKEN() external view returns (address); + + /** + * @notice Returns the address of the risk council + * @return The address of the RiskCouncil + */ + function RISK_COUNCIL() external view returns (address); } diff --git a/src/test/TestGhoAaveSteward.t.sol b/src/test/TestGhoAaveSteward.t.sol index 53511700..63ae9776 100644 --- a/src/test/TestGhoAaveSteward.t.sol +++ b/src/test/TestGhoAaveSteward.t.sol @@ -733,24 +733,6 @@ contract TestGhoAaveSteward is TestGhoBase { ); } - function testSetRiskConfigIfUpdatedTooSoon() public { - vm.prank(SHORT_EXECUTOR); - GHO_AAVE_STEWARD.setBorrowRateConfig( - defaultBorrowRateConfig.optimalUsageRatioMaxChange, - defaultBorrowRateConfig.baseVariableBorrowRateMaxChange, - defaultBorrowRateConfig.variableRateSlope1MaxChange, - defaultBorrowRateConfig.variableRateSlope2MaxChange - ); - vm.expectRevert('DEBOUNCE_NOT_RESPECTED'); - vm.prank(SHORT_EXECUTOR); - GHO_AAVE_STEWARD.setBorrowRateConfig( - defaultBorrowRateConfig.optimalUsageRatioMaxChange, - defaultBorrowRateConfig.baseVariableBorrowRateMaxChange, - defaultBorrowRateConfig.variableRateSlope1MaxChange, - defaultBorrowRateConfig.variableRateSlope2MaxChange - ); - } - function _setGhoBorrowCapViaConfigurator(uint256 newBorrowCap) internal { CONFIGURATOR.setBorrowCap(address(GHO_TOKEN), newBorrowCap); }