From 1962c0e9dcecbc23b3de931f74b1b9cf9bf94584 Mon Sep 17 00:00:00 2001 From: Joaquin Battilana Date: Tue, 5 Mar 2024 03:33:46 +0000 Subject: [PATCH] feat: made strategy factory initializable and moved it to correct directory --- .../FixedRateStrategyFactory.sol | 33 ++++++++++++++- .../interfaces/IFixedRateStrategyFactory.sol | 6 +++ src/contracts/misc/GhoStewardV2.sol | 2 +- src/test/TestFixedRateStrategyFactory.t.sol | 42 +++++++++++++++++++ src/test/TestGhoBase.t.sol | 4 +- src/test/helpers/Constants.sol | 1 + 6 files changed, 83 insertions(+), 5 deletions(-) rename src/contracts/{misc => facilitators/aave/interestStrategy}/FixedRateStrategyFactory.sol (57%) rename src/contracts/{misc => facilitators/aave/interestStrategy}/interfaces/IFixedRateStrategyFactory.sol (89%) diff --git a/src/contracts/misc/FixedRateStrategyFactory.sol b/src/contracts/facilitators/aave/interestStrategy/FixedRateStrategyFactory.sol similarity index 57% rename from src/contracts/misc/FixedRateStrategyFactory.sol rename to src/contracts/facilitators/aave/interestStrategy/FixedRateStrategyFactory.sol index 95fcbe6b..2bdc9e44 100644 --- a/src/contracts/misc/FixedRateStrategyFactory.sol +++ b/src/contracts/facilitators/aave/interestStrategy/FixedRateStrategyFactory.sol @@ -2,8 +2,10 @@ pragma solidity ^0.8.10; import {IPoolAddressesProvider} from '@aave/core-v3/contracts/interfaces/IPoolAddressesProvider.sol'; -import {GhoInterestRateStrategy} from '../facilitators/aave/interestStrategy/GhoInterestRateStrategy.sol'; +import {IDefaultInterestRateStrategy} from '@aave/core-v3/contracts/interfaces/IDefaultInterestRateStrategy.sol'; +import {VersionedInitializable} from '@aave/core-v3/contracts/protocol/libraries/aave-upgradeability/VersionedInitializable.sol'; import {IFixedRateStrategyFactory} from './interfaces/IFixedRateStrategyFactory.sol'; +import {GhoInterestRateStrategy} from './GhoInterestRateStrategy.sol'; /** * @title FixedRateStrategyFactory @@ -12,7 +14,7 @@ import {IFixedRateStrategyFactory} from './interfaces/IFixedRateStrategyFactory. * @dev For creating the strategies `GhoInterestRateStrategy` is used. * @dev Associated to an specific Aave v3 Pool, via its addresses provider */ -contract FixedRateStrategyFactory is IFixedRateStrategyFactory { +contract FixedRateStrategyFactory is VersionedInitializable, IFixedRateStrategyFactory { ///@inheritdoc IFixedRateStrategyFactory address public immutable POOL_ADDRESSES_PROVIDER; @@ -24,6 +26,23 @@ contract FixedRateStrategyFactory is IFixedRateStrategyFactory { POOL_ADDRESSES_PROVIDER = addressesProvider; } + /** + * @notice FixedRateStrategyFactory initializer + * @dev asumes that the addresses provided are fixed rate deployed strategies. + * @param fixedRateStrategiesList List of fixed rate strategies + */ + function initialize(address[] memory fixedRateStrategiesList) external initializer { + for (uint256 i = 0; i < fixedRateStrategiesList.length; i++) { + address fixedRateStrategy = fixedRateStrategiesList[i]; + uint256 rate = IDefaultInterestRateStrategy(fixedRateStrategy).getBaseVariableBorrowRate(); + + _strategiesByRate[rate] = fixedRateStrategy; + _strategies.push(fixedRateStrategy); + + emit RateStrategyCreated(fixedRateStrategy, rate); + } + } + ///@inheritdoc IFixedRateStrategyFactory function createStrategies(uint256[] memory fixedRateList) public returns (address[] memory) { address[] memory strategies = new address[](fixedRateList.length); @@ -54,4 +73,14 @@ contract FixedRateStrategyFactory is IFixedRateStrategyFactory { function getStrategyByRate(uint256 borrowRate) external view returns (address) { return _strategiesByRate[borrowRate]; } + + /// @inheritdoc IFixedRateStrategyFactory + function FIXED_RATE_STRATEGY_FACTORY_REVISION() public pure virtual override returns (uint256) { + return 1; + } + + /// @inheritdoc VersionedInitializable + function getRevision() internal pure virtual override returns (uint256) { + return FIXED_RATE_STRATEGY_FACTORY_REVISION(); + } } diff --git a/src/contracts/misc/interfaces/IFixedRateStrategyFactory.sol b/src/contracts/facilitators/aave/interestStrategy/interfaces/IFixedRateStrategyFactory.sol similarity index 89% rename from src/contracts/misc/interfaces/IFixedRateStrategyFactory.sol rename to src/contracts/facilitators/aave/interestStrategy/interfaces/IFixedRateStrategyFactory.sol index 2a06c7d9..5e23fca7 100644 --- a/src/contracts/misc/interfaces/IFixedRateStrategyFactory.sol +++ b/src/contracts/facilitators/aave/interestStrategy/interfaces/IFixedRateStrategyFactory.sol @@ -40,4 +40,10 @@ interface IFixedRateStrategyFactory { * @return The address of the strategy */ function getStrategyByRate(uint256 rate) external view returns (address); + + /** + * @notice Returns the FixedRateStrategyFactory revision number + * @return The revision number + */ + function FIXED_RATE_STRATEGY_FACTORY_REVISION() external pure returns (uint256); } diff --git a/src/contracts/misc/GhoStewardV2.sol b/src/contracts/misc/GhoStewardV2.sol index 4910b656..b381748c 100644 --- a/src/contracts/misc/GhoStewardV2.sol +++ b/src/contracts/misc/GhoStewardV2.sol @@ -9,12 +9,12 @@ import {IPool} from '@aave/core-v3/contracts/interfaces/IPool.sol'; import {DataTypes} from '@aave/core-v3/contracts/protocol/libraries/types/DataTypes.sol'; import {ReserveConfiguration} from '@aave/core-v3/contracts/protocol/libraries/configuration/ReserveConfiguration.sol'; import {GhoInterestRateStrategy} from '../facilitators/aave/interestStrategy/GhoInterestRateStrategy.sol'; +import {IFixedRateStrategyFactory} from '../facilitators/aave/interestStrategy/interfaces/IFixedRateStrategyFactory.sol'; import {FixedFeeStrategy} from '../facilitators/gsm/feeStrategy/FixedFeeStrategy.sol'; import {IGsm} from '../facilitators/gsm/interfaces/IGsm.sol'; import {IGsmFeeStrategy} from '../facilitators/gsm/feeStrategy/interfaces/IGsmFeeStrategy.sol'; import {IGhoToken} from '../gho/interfaces/IGhoToken.sol'; import {IGhoStewardV2} from './interfaces/IGhoStewardV2.sol'; -import {IFixedRateStrategyFactory} from './interfaces/IFixedRateStrategyFactory.sol'; /** * @title GhoStewardV2 diff --git a/src/test/TestFixedRateStrategyFactory.t.sol b/src/test/TestFixedRateStrategyFactory.t.sol index 8ed2e5a6..8f643396 100644 --- a/src/test/TestFixedRateStrategyFactory.t.sol +++ b/src/test/TestFixedRateStrategyFactory.t.sol @@ -18,6 +18,41 @@ contract TestFixedRateStrategyFactory is TestGhoBase { new FixedRateStrategyFactory(address(0)); } + function testInitialize() public { + address[] memory strategies = new address[](1); + strategies[0] = address(new GhoInterestRateStrategy(address(PROVIDER), 100)); + + FIXED_RATE_STRATEGY_FACTORY.initialize(strategies); + address[] memory strategiesCall = FIXED_RATE_STRATEGY_FACTORY.getAllStrategies(); + + assertEq(strategiesCall.length, 1); + assertEq(strategiesCall[0], strategies[0]); + } + + function testInitializeMultiple() public { + address[] memory strategies = new address[](3); + strategies[0] = address(new GhoInterestRateStrategy(address(PROVIDER), 100)); + strategies[1] = address(new GhoInterestRateStrategy(address(PROVIDER), 200)); + strategies[2] = address(new GhoInterestRateStrategy(address(PROVIDER), 300)); + + FIXED_RATE_STRATEGY_FACTORY.initialize(strategies); + address[] memory strategiesCall = FIXED_RATE_STRATEGY_FACTORY.getAllStrategies(); + + assertEq(strategiesCall.length, 3); + assertEq(strategiesCall[0], strategies[0]); + assertEq(strategiesCall[1], strategies[1]); + assertEq(strategiesCall[2], strategies[2]); + } + + function testRevertInitializeTwice() public { + address[] memory strategies = new address[](1); + strategies[0] = address(new GhoInterestRateStrategy(address(PROVIDER), 100)); + + FIXED_RATE_STRATEGY_FACTORY.initialize(strategies); + vm.expectRevert('Contract instance has already been initialized'); + FIXED_RATE_STRATEGY_FACTORY.initialize(strategies); + } + function testCreateStrategies() public { uint256[] memory rates = new uint256[](1); rates[0] = 100; @@ -97,4 +132,11 @@ contract TestFixedRateStrategyFactory is TestGhoBase { assertEq(FIXED_RATE_STRATEGY_FACTORY.getStrategyByRate(rates[1]), strategies[1]); assertEq(FIXED_RATE_STRATEGY_FACTORY.getStrategyByRate(rates[2]), strategies[2]); } + + function testGetFixedRateStrategyRevision() public { + assertEq( + FIXED_RATE_STRATEGY_FACTORY.FIXED_RATE_STRATEGY_FACTORY_REVISION(), + FIXED_RATE_STRATEGY_FACTORY_REVISION + ); + } } diff --git a/src/test/TestGhoBase.t.sol b/src/test/TestGhoBase.t.sol index 650d414b..8711f15c 100644 --- a/src/test/TestGhoBase.t.sol +++ b/src/test/TestGhoBase.t.sol @@ -41,6 +41,7 @@ import {IGhoVariableDebtTokenTransferHook} from 'aave-stk-v1-5/src/interfaces/IG import {IPool} from '@aave/core-v3/contracts/interfaces/IPool.sol'; import {IPoolAddressesProvider} from '@aave/core-v3/contracts/interfaces/IPoolAddressesProvider.sol'; import {IStakedAaveV3} from 'aave-stk-v1-5/src/interfaces/IStakedAaveV3.sol'; +import {IFixedRateStrategyFactory} from '../contracts/facilitators/aave/interestStrategy/interfaces/IFixedRateStrategyFactory.sol'; // non-GHO contracts import {AdminUpgradeabilityProxy} from '@aave/core-v3/contracts/dependencies/openzeppelin/upgradeability/AdminUpgradeabilityProxy.sol'; @@ -56,13 +57,12 @@ import {GhoInterestRateStrategy} from '../contracts/facilitators/aave/interestSt import {GhoSteward} from '../contracts/misc/GhoSteward.sol'; import {IGhoSteward} from '../contracts/misc/interfaces/IGhoSteward.sol'; import {IGhoStewardV2} from '../contracts/misc/interfaces/IGhoStewardV2.sol'; -import {IFixedRateStrategyFactory} from '../contracts/misc/interfaces/IFixedRateStrategyFactory.sol'; import {GhoOracle} from '../contracts/facilitators/aave/oracle/GhoOracle.sol'; import {GhoStableDebtToken} from '../contracts/facilitators/aave/tokens/GhoStableDebtToken.sol'; import {GhoToken} from '../contracts/gho/GhoToken.sol'; import {GhoVariableDebtToken} from '../contracts/facilitators/aave/tokens/GhoVariableDebtToken.sol'; import {GhoStewardV2} from '../contracts/misc/GhoStewardV2.sol'; -import {FixedRateStrategyFactory} from '../contracts/misc/FixedRateStrategyFactory.sol'; +import {FixedRateStrategyFactory} from '../contracts/facilitators/aave/interestStrategy/FixedRateStrategyFactory.sol'; // GSM contracts import {IGsm} from '../contracts/facilitators/gsm/interfaces/IGsm.sol'; diff --git a/src/test/helpers/Constants.sol b/src/test/helpers/Constants.sol index 04f2cadc..21ad4832 100644 --- a/src/test/helpers/Constants.sol +++ b/src/test/helpers/Constants.sol @@ -57,6 +57,7 @@ contract Constants { uint256 constant GSM_FEE_RATE_CHANGE_MAX = 0.0050e4; uint256 constant GHO_BORROW_RATE_MAX = 0.095e27; uint256 constant MINIMUM_DELAY_V2 = 7 days; + uint256 constant FIXED_RATE_STRATEGY_FACTORY_REVISION = 1; // sample users used across unit tests address constant ALICE = address(0x1111);