// SPDX-License-Identifier: agpl-3.0 pragma solidity ^0.6.8; import '@openzeppelin/contracts/access/Ownable.sol'; import '../libraries/openzeppelin-upgradeability/InitializableAdminUpgradeabilityProxy.sol'; import './AddressStorage.sol'; import '../interfaces/ILendingPoolAddressesProvider.sol'; /** * @title LendingPoolAddressesProvider contract * @notice Is the main registry of the protocol. All the different components of the protocol are accessible * through the addresses provider. * @author Aave **/ contract LendingPoolAddressesProvider is Ownable, ILendingPoolAddressesProvider, AddressStorage { //events event LendingPoolUpdated(address indexed newAddress); event LendingPoolManagerUpdated(address indexed newAddress); event LendingPoolConfiguratorUpdated(address indexed newAddress); event LendingPoolLiquidationManagerUpdated(address indexed newAddress); event EthereumAddressUpdated(address indexed newAddress); event PriceOracleUpdated(address indexed newAddress); event LendingRateOracleUpdated(address indexed newAddress); event FeeProviderUpdated(address indexed newAddress); event TokenDistributorUpdated(address indexed newAddress); event ProxyCreated(bytes32 id, address indexed newAddress); bytes32 private constant LENDING_POOL = 'LENDING_POOL'; bytes32 private constant LENDING_POOL_CORE = 'LENDING_POOL_CORE'; bytes32 private constant LENDING_POOL_CONFIGURATOR = 'LENDING_POOL_CONFIGURATOR'; bytes32 private constant LENDING_POOL_MANAGER = 'LENDING_POOL_MANAGER'; bytes32 private constant LENDING_POOL_LIQUIDATION_MANAGER = 'LIQUIDATION_MANAGER'; bytes32 private constant LENDING_POOL_FLASHLOAN_PROVIDER = 'FLASHLOAN_PROVIDER'; bytes32 private constant DATA_PROVIDER = 'DATA_PROVIDER'; bytes32 private constant ETHEREUM_ADDRESS = 'ETHEREUM_ADDRESS'; bytes32 private constant PRICE_ORACLE = 'PRICE_ORACLE'; bytes32 private constant LENDING_RATE_ORACLE = 'LENDING_RATE_ORACLE'; bytes32 private constant FEE_PROVIDER = 'FEE_PROVIDER'; bytes32 private constant WALLET_BALANCE_PROVIDER = 'WALLET_BALANCE_PROVIDER'; bytes32 private constant TOKEN_DISTRIBUTOR = 'TOKEN_DISTRIBUTOR'; /** * @dev returns the address of the LendingPool proxy * @return the lending pool proxy address **/ function getLendingPool() public override view returns (address) { return getAddress(LENDING_POOL); } /** * @dev updates the implementation of the lending pool * @param _pool the new lending pool implementation **/ function setLendingPoolImpl(address _pool) public override onlyOwner { updateImplInternal(LENDING_POOL, _pool); emit LendingPoolUpdated(_pool); } /** * @dev returns the address of the LendingPoolConfigurator proxy * @return the lending pool configurator proxy address **/ function getLendingPoolConfigurator() public override view returns (address) { return getAddress(LENDING_POOL_CONFIGURATOR); } /** * @dev updates the implementation of the lending pool configurator * @param _configurator the new lending pool configurator implementation **/ function setLendingPoolConfiguratorImpl(address _configurator) public override onlyOwner { updateImplInternal(LENDING_POOL_CONFIGURATOR, _configurator); emit LendingPoolConfiguratorUpdated(_configurator); } /** * @dev returns the address of the FeeProvider proxy * @return the address of the Fee provider proxy **/ function getFeeProvider() public override view returns (address) { return getAddress(FEE_PROVIDER); } /** * @dev updates the implementation of the FeeProvider proxy * @param _feeProvider the new lending pool fee provider implementation **/ function setFeeProviderImpl(address _feeProvider) public override onlyOwner { updateImplInternal(FEE_PROVIDER, _feeProvider); emit FeeProviderUpdated(_feeProvider); } /** * @dev returns the address of the LendingPoolLiquidationManager. Since the manager is used * through delegateCall within the LendingPool contract, the proxy contract pattern does not work properly hence * the addresses are changed directly. * @return the address of the Lending pool liquidation manager **/ function getLendingPoolLiquidationManager() public override view returns (address) { return getAddress(LENDING_POOL_LIQUIDATION_MANAGER); } /** * @dev updates the address of the Lending pool liquidation manager * @param _manager the new lending pool liquidation manager address **/ function setLendingPoolLiquidationManager(address _manager) public override onlyOwner { _setAddress(LENDING_POOL_LIQUIDATION_MANAGER, _manager); emit LendingPoolLiquidationManagerUpdated(_manager); } /** * @dev the functions below are storing specific addresses that are outside the context of the protocol * hence the upgradable proxy pattern is not used **/ function getLendingPoolManager() public override view returns (address) { return getAddress(LENDING_POOL_MANAGER); } function setLendingPoolManager(address _lendingPoolManager) public override onlyOwner { _setAddress(LENDING_POOL_MANAGER, _lendingPoolManager); emit LendingPoolManagerUpdated(_lendingPoolManager); } function getPriceOracle() public override view returns (address) { return getAddress(PRICE_ORACLE); } function setPriceOracle(address _priceOracle) public override onlyOwner { _setAddress(PRICE_ORACLE, _priceOracle); emit PriceOracleUpdated(_priceOracle); } function getLendingRateOracle() public override view returns (address) { return getAddress(LENDING_RATE_ORACLE); } function setLendingRateOracle(address _lendingRateOracle) public override onlyOwner { _setAddress(LENDING_RATE_ORACLE, _lendingRateOracle); emit LendingRateOracleUpdated(_lendingRateOracle); } function getTokenDistributor() public override view returns (address) { return getAddress(TOKEN_DISTRIBUTOR); } function setTokenDistributor(address _tokenDistributor) public override onlyOwner { _setAddress(TOKEN_DISTRIBUTOR, _tokenDistributor); emit TokenDistributorUpdated(_tokenDistributor); } /** * @dev internal function to update the implementation of a specific component of the protocol * @param _id the id of the contract to be updated * @param _newAddress the address of the new implementation **/ function updateImplInternal(bytes32 _id, address _newAddress) internal { address payable proxyAddress = address(uint160(getAddress(_id))); InitializableAdminUpgradeabilityProxy proxy = InitializableAdminUpgradeabilityProxy( proxyAddress ); bytes memory params = abi.encodeWithSignature('initialize(address)', address(this)); if (proxyAddress == address(0)) { proxy = new InitializableAdminUpgradeabilityProxy(); proxy.initialize(_newAddress, address(this), params); _setAddress(_id, address(proxy)); emit ProxyCreated(_id, address(proxy)); } else { proxy.upgradeToAndCall(_newAddress, params); } } }