Branch data Line data Source code
1 : : // SPDX-License-Identifier: BUSL-1.1
2 : : pragma solidity ^0.8.10;
3 : :
4 : : import {IPool} from '../../../interfaces/IPool.sol';
5 : : import {IInitializableAToken} from '../../../interfaces/IInitializableAToken.sol';
6 : : import {IInitializableDebtToken} from '../../../interfaces/IInitializableDebtToken.sol';
7 : : import {InitializableImmutableAdminUpgradeabilityProxy} from '../../../misc/aave-upgradeability/InitializableImmutableAdminUpgradeabilityProxy.sol';
8 : : import {IReserveInterestRateStrategy} from '../../../interfaces/IReserveInterestRateStrategy.sol';
9 : : import {ReserveConfiguration} from '../configuration/ReserveConfiguration.sol';
10 : : import {DataTypes} from '../types/DataTypes.sol';
11 : : import {Errors} from '../helpers/Errors.sol';
12 : : import {ConfiguratorInputTypes} from '../types/ConfiguratorInputTypes.sol';
13 : : import {IERC20Detailed} from '../../../dependencies/openzeppelin/contracts/IERC20Detailed.sol';
14 : :
15 : : /**
16 : : * @title ConfiguratorLogic library
17 : : * @author Aave
18 : : * @notice Implements the functions to initialize reserves and update aTokens and debtTokens
19 : : */
20 : : library ConfiguratorLogic {
21 : : using ReserveConfiguration for DataTypes.ReserveConfigurationMap;
22 : :
23 : : // See `IPoolConfigurator` for descriptions
24 : : event ReserveInitialized(
25 : : address indexed asset,
26 : : address indexed aToken,
27 : : address stableDebtToken,
28 : : address variableDebtToken,
29 : : address interestRateStrategyAddress
30 : : );
31 : : event ATokenUpgraded(
32 : : address indexed asset,
33 : : address indexed proxy,
34 : : address indexed implementation
35 : : );
36 : : event VariableDebtTokenUpgraded(
37 : : address indexed asset,
38 : : address indexed proxy,
39 : : address indexed implementation
40 : : );
41 : :
42 : : /**
43 : : * @notice Initialize a reserve by creating and initializing aToken and variable debt token
44 : : * @dev Emits the `ReserveInitialized` event
45 : : * @param pool The Pool in which the reserve will be initialized
46 : : * @param input The needed parameters for the initialization
47 : : */
48 : : function executeInitReserve(
49 : : IPool pool,
50 : : ConfiguratorInputTypes.InitReserveInput calldata input
51 : : ) external {
52 : : // It is an assumption that the asset listed is non-malicious, and the external call doesn't create re-entrancies
53 : 167016 : uint8 underlyingAssetDecimals = IERC20Detailed(input.underlyingAsset).decimals();
54 : 167016 : require(underlyingAssetDecimals > 5, Errors.INVALID_DECIMALS);
55 : :
56 : 166016 : address aTokenProxyAddress = _initTokenWithProxy(
57 : : input.aTokenImpl,
58 : : abi.encodeWithSelector(
59 : : IInitializableAToken.initialize.selector,
60 : : pool,
61 : : input.treasury,
62 : : input.underlyingAsset,
63 : : input.incentivesController,
64 : : underlyingAssetDecimals,
65 : : input.aTokenName,
66 : : input.aTokenSymbol,
67 : : input.params
68 : : )
69 : : );
70 : :
71 : 166016 : address variableDebtTokenProxyAddress = _initTokenWithProxy(
72 : : input.variableDebtTokenImpl,
73 : : abi.encodeWithSelector(
74 : : IInitializableDebtToken.initialize.selector,
75 : : pool,
76 : : input.underlyingAsset,
77 : : input.incentivesController,
78 : : underlyingAssetDecimals,
79 : : input.variableDebtTokenName,
80 : : input.variableDebtTokenSymbol,
81 : : input.params
82 : : )
83 : : );
84 : :
85 : 166016 : pool.initReserve(
86 : : input.underlyingAsset,
87 : : aTokenProxyAddress,
88 : : variableDebtTokenProxyAddress,
89 : : input.interestRateStrategyAddress
90 : : );
91 : :
92 : 165016 : DataTypes.ReserveConfigurationMap memory currentConfig = DataTypes.ReserveConfigurationMap(0);
93 : :
94 : 165016 : currentConfig.setDecimals(underlyingAssetDecimals);
95 : :
96 : 165016 : currentConfig.setActive(true);
97 : 165016 : currentConfig.setPaused(false);
98 : 165016 : currentConfig.setFrozen(false);
99 : 165016 : currentConfig.setVirtualAccActive(input.useVirtualBalance);
100 : :
101 : 165016 : pool.setConfiguration(input.underlyingAsset, currentConfig);
102 : :
103 : 165016 : IReserveInterestRateStrategy(input.interestRateStrategyAddress).setInterestRateParams(
104 : : input.underlyingAsset,
105 : : input.interestRateData
106 : : );
107 : :
108 : 165016 : emit ReserveInitialized(
109 : : input.underlyingAsset,
110 : : aTokenProxyAddress,
111 : : address(0),
112 : : variableDebtTokenProxyAddress,
113 : : input.interestRateStrategyAddress
114 : : );
115 : : }
116 : :
117 : : /**
118 : : * @notice Updates the aToken implementation and initializes it
119 : : * @dev Emits the `ATokenUpgraded` event
120 : : * @param cachedPool The Pool containing the reserve with the aToken
121 : : * @param input The parameters needed for the initialize call
122 : : */
123 : : function executeUpdateAToken(
124 : : IPool cachedPool,
125 : : ConfiguratorInputTypes.UpdateATokenInput calldata input
126 : : ) external {
127 : 1 : DataTypes.ReserveDataLegacy memory reserveData = cachedPool.getReserveData(input.asset);
128 : :
129 : 1 : (, , , uint256 decimals, ) = cachedPool.getConfiguration(input.asset).getParams();
130 : :
131 : 1 : bytes memory encodedCall = abi.encodeWithSelector(
132 : : IInitializableAToken.initialize.selector,
133 : : cachedPool,
134 : : input.treasury,
135 : : input.asset,
136 : : input.incentivesController,
137 : : decimals,
138 : : input.name,
139 : : input.symbol,
140 : : input.params
141 : : );
142 : :
143 : 1 : _upgradeTokenImplementation(reserveData.aTokenAddress, input.implementation, encodedCall);
144 : :
145 : 1 : emit ATokenUpgraded(input.asset, reserveData.aTokenAddress, input.implementation);
146 : : }
147 : :
148 : : /**
149 : : * @notice Updates the variable debt token implementation and initializes it
150 : : * @dev Emits the `VariableDebtTokenUpgraded` event
151 : : * @param cachedPool The Pool containing the reserve with the variable debt token
152 : : * @param input The parameters needed for the initialize call
153 : : */
154 : : function executeUpdateVariableDebtToken(
155 : : IPool cachedPool,
156 : : ConfiguratorInputTypes.UpdateDebtTokenInput calldata input
157 : : ) external {
158 : 1 : DataTypes.ReserveDataLegacy memory reserveData = cachedPool.getReserveData(input.asset);
159 : :
160 : 1 : (, , , uint256 decimals, ) = cachedPool.getConfiguration(input.asset).getParams();
161 : :
162 : 1 : bytes memory encodedCall = abi.encodeWithSelector(
163 : : IInitializableDebtToken.initialize.selector,
164 : : cachedPool,
165 : : input.asset,
166 : : input.incentivesController,
167 : : decimals,
168 : : input.name,
169 : : input.symbol,
170 : : input.params
171 : : );
172 : :
173 : 1 : _upgradeTokenImplementation(
174 : : reserveData.variableDebtTokenAddress,
175 : : input.implementation,
176 : : encodedCall
177 : : );
178 : :
179 : 1 : emit VariableDebtTokenUpgraded(
180 : : input.asset,
181 : : reserveData.variableDebtTokenAddress,
182 : : input.implementation
183 : : );
184 : : }
185 : :
186 : : /**
187 : : * @notice Creates a new proxy and initializes the implementation
188 : : * @param implementation The address of the implementation
189 : : * @param initParams The parameters that is passed to the implementation to initialize
190 : : * @return The address of initialized proxy
191 : : */
192 : : function _initTokenWithProxy(
193 : : address implementation,
194 : : bytes memory initParams
195 : : ) internal returns (address) {
196 : 332032 : InitializableImmutableAdminUpgradeabilityProxy proxy = new InitializableImmutableAdminUpgradeabilityProxy(
197 : : address(this)
198 : : );
199 : :
200 : 332032 : proxy.initialize(implementation, initParams);
201 : :
202 : 332032 : return address(proxy);
203 : : }
204 : :
205 : : /**
206 : : * @notice Upgrades the implementation and makes call to the proxy
207 : : * @dev The call is used to initialize the new implementation.
208 : : * @param proxyAddress The address of the proxy
209 : : * @param implementation The address of the new implementation
210 : : * @param initParams The parameters to the call after the upgrade
211 : : */
212 : : function _upgradeTokenImplementation(
213 : : address proxyAddress,
214 : : address implementation,
215 : : bytes memory initParams
216 : : ) internal {
217 : 2 : InitializableImmutableAdminUpgradeabilityProxy proxy = InitializableImmutableAdminUpgradeabilityProxy(
218 : : payable(proxyAddress)
219 : : );
220 : :
221 : 2 : proxy.upgradeToAndCall(implementation, initParams);
222 : : }
223 : : }
|