diff --git a/src/contracts/extensions/v3-config-engine/AaveV3ConfigEngine.sol b/src/contracts/extensions/v3-config-engine/AaveV3ConfigEngine.sol index 0331bfbd..ed817352 100644 --- a/src/contracts/extensions/v3-config-engine/AaveV3ConfigEngine.sol +++ b/src/contracts/extensions/v3-config-engine/AaveV3ConfigEngine.sol @@ -187,21 +187,10 @@ contract AaveV3ConfigEngine is IAaveV3ConfigEngine { } /// @inheritdoc IAaveV3ConfigEngine - function updateEModeCollaterals(EModeCollateralUpdate[] calldata updates) external { + function updateAssetEMode(AssetEModeUpdate[] calldata updates) external { EMODE_ENGINE.functionDelegateCall( abi.encodeWithSelector( - EModeEngine.executeEModeCollateralUpdate.selector, - _getEngineConstants(), - updates - ) - ); - } - - /// @inheritdoc IAaveV3ConfigEngine - function updateEModeBorrowables(EModeBorrowableUpdate[] calldata updates) external { - EMODE_ENGINE.functionDelegateCall( - abi.encodeWithSelector( - EModeEngine.executeEModeBorrowableUpdate.selector, + EModeEngine.executeAssetEModeUpdate.selector, _getEngineConstants(), updates ) diff --git a/src/contracts/extensions/v3-config-engine/AaveV3Payload.sol b/src/contracts/extensions/v3-config-engine/AaveV3Payload.sol index bdaa17c6..8618056f 100644 --- a/src/contracts/extensions/v3-config-engine/AaveV3Payload.sol +++ b/src/contracts/extensions/v3-config-engine/AaveV3Payload.sol @@ -49,8 +49,7 @@ abstract contract AaveV3Payload { IEngine.BorrowUpdate[] memory borrows = borrowsUpdates(); IEngine.RateStrategyUpdate[] memory rates = rateStrategiesUpdates(); IEngine.PriceFeedUpdate[] memory priceFeeds = priceFeedsUpdates(); - IEngine.EModeCollateralUpdate[] memory eModeCollaterals = eModeCollateralUpdates(); - IEngine.EModeBorrowableUpdate[] memory eModeBorrowables = eModeBorrowableUpdates(); + IEngine.AssetEModeUpdate[] memory assetEModes = assetEModeUpdates(); IEngine.CapsUpdate[] memory caps = capsUpdates(); if (eModeCategories.length != 0) { @@ -99,15 +98,9 @@ abstract contract AaveV3Payload { ); } - if (eModeCollaterals.length != 0) { + if (assetEModes.length != 0) { address(CONFIG_ENGINE).functionDelegateCall( - abi.encodeWithSelector(CONFIG_ENGINE.updateEModeCollaterals.selector, eModeCollaterals) - ); - } - - if (eModeBorrowables.length != 0) { - address(CONFIG_ENGINE).functionDelegateCall( - abi.encodeWithSelector(CONFIG_ENGINE.updateEModeBorrowables.selector, eModeBorrowables) + abi.encodeWithSelector(CONFIG_ENGINE.updateAssetEMode.selector, assetEModes) ); } @@ -159,20 +152,7 @@ abstract contract AaveV3Payload { {} /// @dev to be defined in the child with a list of assets for which eMode collateral to update - function eModeCollateralUpdates() - public - view - virtual - returns (IEngine.EModeCollateralUpdate[] memory) - {} - - /// @dev to be defined in the child with a list of assets for which eMode borrowable to update - function eModeBorrowableUpdates() - public - view - virtual - returns (IEngine.EModeBorrowableUpdate[] memory) - {} + function assetEModeUpdates() public view virtual returns (IEngine.AssetEModeUpdate[] memory) {} /// @dev to be defined in the child with a list of set of parameters of rate strategies function rateStrategiesUpdates() diff --git a/src/contracts/extensions/v3-config-engine/IAaveV3ConfigEngine.sol b/src/contracts/extensions/v3-config-engine/IAaveV3ConfigEngine.sol index d716cf9a..6c743d30 100644 --- a/src/contracts/extensions/v3-config-engine/IAaveV3ConfigEngine.sol +++ b/src/contracts/extensions/v3-config-engine/IAaveV3ConfigEngine.sol @@ -190,27 +190,15 @@ interface IAaveV3ConfigEngine { * EModeCollateralUpdate({ * asset: AaveV3EthereumAssets.rETH_UNDERLYING, * eModeCategory: 1, // ETH correlated - * enabled: true, + * borrowable: EngineFlags.ENABLED, + * collateral: EngineFlags.KEEP_CURRENT, * }) */ - struct EModeCollateralUpdate { + struct AssetEModeUpdate { address asset; uint8 eModeCategory; - bool enabled; - } - - /** - * @dev Example (mock): - * EModeBorrowableUpdate({ - * asset: AaveV3EthereumAssets.rETH_UNDERLYING, - * eModeCategory: 1, // ETH correlated - * enabled: true, - * }) - */ - struct EModeBorrowableUpdate { - address asset; - uint8 eModeCategory; - bool enabled; + uint256 borrowable; + uint256 collateral; } /** @@ -315,18 +303,12 @@ interface IAaveV3ConfigEngine { function updateEModeCategories(EModeCategoryUpdate[] memory updates) external; /** - * @notice Performs an update of the e-mode category collateral, in the Aave pool configured in this engine instance - * @param updates `EModeCollateralUpdate[]` list of declarative updates containing the new parameters - * More information on the documentation of the struct. - */ - function updateEModeCollaterals(EModeCollateralUpdate[] memory updates) external; - - /** - * @notice Performs an update of the e-mode category borrowable, in the Aave pool configured in this engine instance + * @notice Performs an update of the e-mode category. + * Sets a specified asset collateral and/or borrowable, in the Aave pool configured in this engine instance * @param updates `EModeCollateralUpdate[]` list of declarative updates containing the new parameters * More information on the documentation of the struct. */ - function updateEModeBorrowables(EModeBorrowableUpdate[] memory updates) external; + function updateAssetEMode(AssetEModeUpdate[] memory updates) external; function DEFAULT_INTEREST_RATE_STRATEGY() external view returns (address); diff --git a/src/contracts/extensions/v3-config-engine/libraries/EModeEngine.sol b/src/contracts/extensions/v3-config-engine/libraries/EModeEngine.sol index a279cd35..f0894198 100644 --- a/src/contracts/extensions/v3-config-engine/libraries/EModeEngine.sol +++ b/src/contracts/extensions/v3-config-engine/libraries/EModeEngine.sol @@ -11,22 +11,13 @@ library EModeEngine { using PercentageMath for uint256; using SafeCast for uint256; - function executeEModeCollateralUpdate( + function executeAssetEModeUpdate( IEngine.EngineConstants calldata engineConstants, - IEngine.EModeCollateralUpdate[] memory updates + IEngine.AssetEModeUpdate[] memory updates ) external { require(updates.length != 0, 'AT_LEAST_ONE_UPDATE_REQUIRED'); - _configEModeCollateral(engineConstants.poolConfigurator, updates); - } - - function executeEModeBorrowableUpdate( - IEngine.EngineConstants calldata engineConstants, - IEngine.EModeBorrowableUpdate[] memory updates - ) external { - require(updates.length != 0, 'AT_LEAST_ONE_UPDATE_REQUIRED'); - - _configEModeBorrowable(engineConstants.poolConfigurator, updates); + _configAssetEMode(engineConstants.poolConfigurator, updates); } function executeEModeCategoriesUpdate( @@ -38,29 +29,25 @@ library EModeEngine { _configEModeCategories(engineConstants.poolConfigurator, engineConstants.pool, updates); } - function _configEModeCollateral( - IPoolConfigurator poolConfigurator, - IEngine.EModeCollateralUpdate[] memory updates - ) internal { - for (uint256 i = 0; i < updates.length; i++) { - poolConfigurator.setAssetCollateralInEMode( - updates[i].asset, - updates[i].eModeCategory, - updates[i].enabled - ); - } - } - - function _configEModeBorrowable( + function _configAssetEMode( IPoolConfigurator poolConfigurator, - IEngine.EModeBorrowableUpdate[] memory updates + IEngine.AssetEModeUpdate[] memory updates ) internal { for (uint256 i = 0; i < updates.length; i++) { - poolConfigurator.setAssetBorrowableInEMode( - updates[i].asset, - updates[i].eModeCategory, - updates[i].enabled - ); + if (updates[i].collateral != EngineFlags.KEEP_CURRENT) { + poolConfigurator.setAssetCollateralInEMode( + updates[i].asset, + updates[i].eModeCategory, + EngineFlags.toBool(updates[i].collateral) + ); + } + if (updates[i].borrowable != EngineFlags.KEEP_CURRENT) { + poolConfigurator.setAssetBorrowableInEMode( + updates[i].asset, + updates[i].eModeCategory, + EngineFlags.toBool(updates[i].borrowable) + ); + } } } diff --git a/tests/extensions/v3-config-engine/AaveV3ConfigEngineTest.t.sol b/tests/extensions/v3-config-engine/AaveV3ConfigEngineTest.t.sol index 4a5bd84e..62a3a1d8 100644 --- a/tests/extensions/v3-config-engine/AaveV3ConfigEngineTest.t.sol +++ b/tests/extensions/v3-config-engine/AaveV3ConfigEngineTest.t.sol @@ -629,11 +629,16 @@ contract AaveV3ConfigEngineTest is TestnetProcedures, ProtocolV3TestBase { function testAssetEModeUpdates() public { address asset = tokenList.usdx; + address asset2 = tokenList.wbtc; AaveV3MockEModeCategoryUpdate payloadToAddEMode = new AaveV3MockEModeCategoryUpdate( configEngine ); - AaveV3MockAssetEModeUpdate payload = new AaveV3MockAssetEModeUpdate(asset, configEngine); + AaveV3MockAssetEModeUpdate payload = new AaveV3MockAssetEModeUpdate( + asset, + asset2, + configEngine + ); vm.startPrank(roleList.marketOwner); contracts.aclManager.addPoolAdmin(address(payload)); @@ -658,6 +663,19 @@ contract AaveV3ConfigEngineTest is TestnetProcedures, ProtocolV3TestBase { DataTypes.ReserveDataLegacy memory reserveData = contracts.poolProxy.getReserveData(asset); DataTypes.EModeCategory memory eMode = contracts.poolProxy.getEModeCategoryData(1); - EModeConfiguration.isCollateralAsset(eMode.isCollateralBitmap, reserveData.id); + assertEq(EModeConfiguration.isCollateralAsset(eMode.isCollateralBitmap, reserveData.id), false); + assertEq(EModeConfiguration.isCollateralAsset(eMode.isBorrowableBitmap, reserveData.id), true); + + DataTypes.ReserveDataLegacy memory reserveDataAsset2 = contracts.poolProxy.getReserveData( + asset2 + ); + assertEq( + EModeConfiguration.isCollateralAsset(eMode.isCollateralBitmap, reserveDataAsset2.id), + true + ); + assertEq( + EModeConfiguration.isCollateralAsset(eMode.isBorrowableBitmap, reserveDataAsset2.id), + false + ); } } diff --git a/tests/extensions/v3-config-engine/mocks/AaveV3MockAssetEModeUpdate.sol b/tests/extensions/v3-config-engine/mocks/AaveV3MockAssetEModeUpdate.sol index 4e047fff..9a36644e 100644 --- a/tests/extensions/v3-config-engine/mocks/AaveV3MockAssetEModeUpdate.sol +++ b/tests/extensions/v3-config-engine/mocks/AaveV3MockAssetEModeUpdate.sol @@ -10,23 +10,31 @@ import '../../../../src/contracts/extensions/v3-config-engine/AaveV3Payload.sol' */ contract AaveV3MockAssetEModeUpdate is AaveV3Payload { address public immutable ASSET_ADDRESS; + address public immutable ASSET_2_ADDRESS; - constructor(address assetAddress, address customEngine) AaveV3Payload(IEngine(customEngine)) { + constructor( + address assetAddress, + address asset2Address, + address customEngine + ) AaveV3Payload(IEngine(customEngine)) { ASSET_ADDRESS = assetAddress; + ASSET_2_ADDRESS = asset2Address; } - function eModeCollateralUpdates() - public - view - override - returns (IEngine.EModeCollateralUpdate[] memory) - { - IEngine.EModeCollateralUpdate[] memory eModeUpdate = new IEngine.EModeCollateralUpdate[](1); + function assetEModeUpdates() public view override returns (IEngine.AssetEModeUpdate[] memory) { + IEngine.AssetEModeUpdate[] memory eModeUpdate = new IEngine.AssetEModeUpdate[](2); - eModeUpdate[0] = IEngine.EModeCollateralUpdate({ + eModeUpdate[0] = IEngine.AssetEModeUpdate({ asset: ASSET_ADDRESS, eModeCategory: 1, - enabled: true + collateral: EngineFlags.DISABLED, + borrowable: EngineFlags.ENABLED + }); + eModeUpdate[1] = IEngine.AssetEModeUpdate({ + asset: ASSET_2_ADDRESS, + eModeCategory: 1, + collateral: EngineFlags.ENABLED, + borrowable: EngineFlags.KEEP_CURRENT }); return eModeUpdate;