Cleaned up configurator, LendingPooL

This commit is contained in:
The3D 2020-08-21 14:03:17 +02:00
parent 05fac16063
commit b4b9ff604a
2 changed files with 272 additions and 256 deletions

View File

@ -8,7 +8,7 @@ import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
import { import {
VersionedInitializable VersionedInitializable
} from '../libraries/openzeppelin-upgradeability/VersionedInitializable.sol'; } from '../libraries/openzeppelin-upgradeability/VersionedInitializable.sol';
import {LendingPoolAddressesProvider} from '../configuration/LendingPoolAddressesProvider.sol'; import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddressesProvider.sol';
import {IAToken} from '../interfaces/IAToken.sol'; import {IAToken} from '../interfaces/IAToken.sol';
import {Helpers} from '../libraries/helpers/Helpers.sol'; import {Helpers} from '../libraries/helpers/Helpers.sol';
import {WadRayMath} from '../libraries/math/WadRayMath.sol'; import {WadRayMath} from '../libraries/math/WadRayMath.sol';
@ -37,19 +37,19 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
using ReserveLogic for ReserveLogic.ReserveData; using ReserveLogic for ReserveLogic.ReserveData;
using ReserveConfiguration for ReserveConfiguration.Map; using ReserveConfiguration for ReserveConfiguration.Map;
using UserConfiguration for UserConfiguration.Map; using UserConfiguration for UserConfiguration.Map;
using SafeERC20 for IERC20;
//main configuration parameters //main configuration parameters
uint256 private constant REBALANCE_DOWN_RATE_DELTA = (1e27) / 5; uint256 public constant REBALANCE_DOWN_RATE_DELTA = (1e27) / 5;
uint256 private constant MAX_STABLE_RATE_BORROW_SIZE_PERCENT = 25; uint256 public constant MAX_STABLE_RATE_BORROW_SIZE_PERCENT = 25;
uint256 private constant FLASHLOAN_FEE_TOTAL = 9; uint256 public constant FLASHLOAN_FEE_TOTAL = 9;
LendingPoolAddressesProvider public addressesProvider; ILendingPoolAddressesProvider internal addressesProvider;
using SafeERC20 for IERC20;
mapping(address => ReserveLogic.ReserveData) internal _reserves; mapping(address => ReserveLogic.ReserveData) internal _reserves;
mapping(address => UserConfiguration.Map) internal _usersConfig; mapping(address => UserConfiguration.Map) internal _usersConfig;
address[] public reservesList; address[] internal reservesList;
/** /**
* @dev emitted on deposit * @dev emitted on deposit
@ -207,7 +207,7 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
* AddressesProvider. * AddressesProvider.
* @param provider the address of the LendingPoolAddressesProvider registry * @param provider the address of the LendingPoolAddressesProvider registry
**/ **/
function initialize(LendingPoolAddressesProvider provider) public initializer { function initialize(ILendingPoolAddressesProvider provider) public initializer {
addressesProvider = provider; addressesProvider = provider;
} }
@ -821,29 +821,29 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
_variableDebtAddress, _variableDebtAddress,
_interestRateStrategyAddress _interestRateStrategyAddress
); );
addReserveToListInternal(asset); _addReserveToList(asset);
} }
/** /**
* @dev updates the address of the interest rate strategy contract * @dev updates the address of the interest rate strategy contract
* @param asset the address of the reserve * @param asset the address of the reserve
* @param _rateStrategyAddress the address of the interest rate strategy contract * @param rateStrategyAddress the address of the interest rate strategy contract
**/ **/
function setReserveInterestRateStrategyAddress(address asset, address _rateStrategyAddress) function setReserveInterestRateStrategyAddress(address asset, address rateStrategyAddress)
external external
override override
onlyLendingPoolConfigurator onlyLendingPoolConfigurator
{ {
_reserves[asset].interestRateStrategyAddress = _rateStrategyAddress; _reserves[asset].interestRateStrategyAddress = rateStrategyAddress;
} }
function setConfiguration(address asset, uint256 _configuration) function setConfiguration(address asset, uint256 configuration)
external external
override override
onlyLendingPoolConfigurator onlyLendingPoolConfigurator
{ {
_reserves[asset].configuration.data = _configuration; _reserves[asset].configuration.data = configuration;
} }
function getConfiguration(address asset) function getConfiguration(address asset)
@ -862,7 +862,7 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
/** /**
* @dev adds a reserve to the array of the _reserves address * @dev adds a reserve to the array of the _reserves address
**/ **/
function addReserveToListInternal(address asset) internal { function _addReserveToList(address asset) internal {
bool reserveAlreadyAdded = false; bool reserveAlreadyAdded = false;
for (uint256 i = 0; i < reservesList.length; i++) for (uint256 i = 0; i < reservesList.length; i++)
if (reservesList[i] == asset) { if (reservesList[i] == asset) {
@ -874,10 +874,20 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
} }
} }
/**
* @dev returns the normalized income per unit of asset
* @param asset the address of the reserve
* @return the reserve normalized income
*/
function getReserveNormalizedIncome(address asset) external override view returns (uint256) { function getReserveNormalizedIncome(address asset) external override view returns (uint256) {
return _reserves[asset].getNormalizedIncome(); return _reserves[asset].getNormalizedIncome();
} }
/**
* @dev returns the normalized variable debt per unit of asset
* @param asset the address of the reserve
* @return the reserve normalized debt
*/
function getReserveNormalizedVariableDebt(address asset) function getReserveNormalizedVariableDebt(address asset)
external external
override override
@ -887,20 +897,35 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
return _reserves[asset].getNormalizedDebt(); return _reserves[asset].getNormalizedDebt();
} }
/**
* @dev validate if a balance decrease for an asset is allowed
* @param asset the address of the reserve
* @param user the user related to the balance decrease
* @param amount the amount being transferred/redeemed
* @return true if the balance decrease can be allowed, false otherwise
*/
function balanceDecreaseAllowed( function balanceDecreaseAllowed(
address asset, address asset,
address _user, address user,
uint256 amount uint256 amount
) external override view returns (bool) { ) external override view returns (bool) {
return return
GenericLogic.balanceDecreaseAllowed( GenericLogic.balanceDecreaseAllowed(
asset, asset,
_user, user,
amount, amount,
_reserves, _reserves,
_usersConfig[_user], _usersConfig[user],
reservesList, reservesList,
addressesProvider.getPriceOracle() addressesProvider.getPriceOracle()
); );
} }
function getReservesList() external view returns(address[] memory){
return reservesList;
}
function getAddressesProvider() external view returns(ILendingPoolAddressesProvider){
return addressesProvider;
}
} }

View File

@ -10,7 +10,7 @@ import {
InitializableAdminUpgradeabilityProxy InitializableAdminUpgradeabilityProxy
} from '../libraries/openzeppelin-upgradeability/InitializableAdminUpgradeabilityProxy.sol'; } from '../libraries/openzeppelin-upgradeability/InitializableAdminUpgradeabilityProxy.sol';
import {ReserveConfiguration} from '../libraries/configuration/ReserveConfiguration.sol'; import {ReserveConfiguration} from '../libraries/configuration/ReserveConfiguration.sol';
import {LendingPoolAddressesProvider} from '../configuration/LendingPoolAddressesProvider.sol'; import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddressesProvider.sol';
import {ILendingPool} from '../interfaces/ILendingPool.sol'; import {ILendingPool} from '../interfaces/ILendingPool.sol';
import {IERC20Detailed} from '../interfaces/IERC20Detailed.sol'; import {IERC20Detailed} from '../interfaces/IERC20Detailed.sol';
@ -27,155 +27,157 @@ contract LendingPoolConfigurator is VersionedInitializable {
/** /**
* @dev emitted when a reserve is initialized. * @dev emitted when a reserve is initialized.
* @param _reserve the address of the reserve * @param asset the address of the reserve
* @param _aToken the address of the overlying aToken contract * @param aToken the address of the overlying aToken contract
* @param _interestRateStrategyAddress the address of the interest rate strategy for the reserve * @param stableDebtToken the address of the associated stable rate debt token
* @param variableDebtToken the address of the associated variable rate debt token
* @param interestRateStrategyAddress the address of the interest rate strategy for the reserve
**/ **/
event ReserveInitialized( event ReserveInitialized(
address indexed _reserve, address indexed asset,
address indexed _aToken, address indexed aToken,
address _stableDebtToken, address stableDebtToken,
address _variableDebtToken, address variableDebtToken,
address _interestRateStrategyAddress address interestRateStrategyAddress
); );
/** /**
* @dev emitted when borrowing is enabled on a reserve * @dev emitted when borrowing is enabled on a reserve
* @param _reserve the address of the reserve * @param asset the address of the reserve
* @param _stableRateEnabled true if stable rate borrowing is enabled, false otherwise * @param stableRateEnabled true if stable rate borrowing is enabled, false otherwise
**/ **/
event BorrowingEnabledOnReserve(address _reserve, bool _stableRateEnabled); event BorrowingEnabledOnReserve(address asset, bool stableRateEnabled);
/** /**
* @dev emitted when borrowing is disabled on a reserve * @dev emitted when borrowing is disabled on a reserve
* @param _reserve the address of the reserve * @param asset the address of the reserve
**/ **/
event BorrowingDisabledOnReserve(address indexed _reserve); event BorrowingDisabledOnReserve(address indexed asset);
/** /**
* @dev emitted when a reserve is enabled as collateral. * @dev emitted when a reserve is enabled as collateral.
* @param _reserve the address of the reserve * @param asset the address of the reserve
* @param _ltv the loan to value of the asset when used as collateral * @param ltv the loan to value of the asset when used as collateral
* @param _liquidationThreshold the threshold at which loans using this asset as collateral will be considered undercollateralized * @param liquidationThreshold the threshold at which loans using this asset as collateral will be considered undercollateralized
* @param _liquidationBonus the bonus liquidators receive to liquidate this asset * @param liquidationBonus the bonus liquidators receive to liquidate this asset
**/ **/
event ReserveEnabledAsCollateral( event ReserveEnabledAsCollateral(
address indexed _reserve, address indexed asset,
uint256 _ltv, uint256 ltv,
uint256 _liquidationThreshold, uint256 liquidationThreshold,
uint256 _liquidationBonus uint256 liquidationBonus
); );
/** /**
* @dev emitted when a reserve is disabled as collateral * @dev emitted when a reserve is disabled as collateral
* @param _reserve the address of the reserve * @param asset the address of the reserve
**/ **/
event ReserveDisabledAsCollateral(address indexed _reserve); event ReserveDisabledAsCollateral(address indexed asset);
/** /**
* @dev emitted when stable rate borrowing is enabled on a reserve * @dev emitted when stable rate borrowing is enabled on a reserve
* @param _reserve the address of the reserve * @param asset the address of the reserve
**/ **/
event StableRateEnabledOnReserve(address indexed _reserve); event StableRateEnabledOnReserve(address indexed asset);
/** /**
* @dev emitted when stable rate borrowing is disabled on a reserve * @dev emitted when stable rate borrowing is disabled on a reserve
* @param _reserve the address of the reserve * @param asset the address of the reserve
**/ **/
event StableRateDisabledOnReserve(address indexed _reserve); event StableRateDisabledOnReserve(address indexed asset);
/** /**
* @dev emitted when a reserve is activated * @dev emitted when a reserve is activated
* @param _reserve the address of the reserve * @param asset the address of the reserve
**/ **/
event ReserveActivated(address indexed _reserve); event ReserveActivated(address indexed asset);
/** /**
* @dev emitted when a reserve is deactivated * @dev emitted when a reserve is deactivated
* @param _reserve the address of the reserve * @param asset the address of the reserve
**/ **/
event ReserveDeactivated(address indexed _reserve); event ReserveDeactivated(address indexed asset);
/** /**
* @dev emitted when a reserve is freezed * @dev emitted when a reserve is freezed
* @param _reserve the address of the reserve * @param asset the address of the reserve
**/ **/
event ReserveFreezed(address indexed _reserve); event ReserveFreezed(address indexed asset);
/** /**
* @dev emitted when a reserve is unfreezed * @dev emitted when a reserve is unfreezed
* @param _reserve the address of the reserve * @param asset the address of the reserve
**/ **/
event ReserveUnfreezed(address indexed _reserve); event ReserveUnfreezed(address indexed asset);
/** /**
* @dev emitted when a reserve loan to value is updated * @dev emitted when a reserve loan to value is updated
* @param _reserve the address of the reserve * @param asset the address of the reserve
* @param _ltv the new value for the loan to value * @param ltv the new value for the loan to value
**/ **/
event ReserveBaseLtvChanged(address _reserve, uint256 _ltv); event ReserveBaseLtvChanged(address asset, uint256 ltv);
/** /**
* @dev emitted when a reserve liquidation threshold is updated * @dev emitted when a reserve liquidation threshold is updated
* @param _reserve the address of the reserve * @param asset the address of the reserve
* @param _threshold the new value for the liquidation threshold * @param threshold the new value for the liquidation threshold
**/ **/
event ReserveLiquidationThresholdChanged(address _reserve, uint256 _threshold); event ReserveLiquidationThresholdChanged(address asset, uint256 threshold);
/** /**
* @dev emitted when a reserve liquidation bonus is updated * @dev emitted when a reserve liquidation bonus is updated
* @param _reserve the address of the reserve * @param asset the address of the reserve
* @param _bonus the new value for the liquidation bonus * @param bonus the new value for the liquidation bonus
**/ **/
event ReserveLiquidationBonusChanged(address _reserve, uint256 _bonus); event ReserveLiquidationBonusChanged(address asset, uint256 bonus);
/** /**
* @dev emitted when the reserve decimals are updated * @dev emitted when the reserve decimals are updated
* @param _reserve the address of the reserve * @param asset the address of the reserve
* @param _decimals the new decimals * @param decimals the new decimals
**/ **/
event ReserveDecimalsChanged(address _reserve, uint256 _decimals); event ReserveDecimalsChanged(address asset, uint256 decimals);
/** /**
* @dev emitted when a reserve interest strategy contract is updated * @dev emitted when a reserve interest strategy contract is updated
* @param _reserve the address of the reserve * @param asset the address of the reserve
* @param _strategy the new address of the interest strategy contract * @param strategy the new address of the interest strategy contract
**/ **/
event ReserveInterestRateStrategyChanged(address _reserve, address _strategy); event ReserveInterestRateStrategyChanged(address asset, address strategy);
/** /**
* @dev emitted when an aToken implementation is upgraded * @dev emitted when an aToken implementation is upgraded
* @param _reserve the address of the reserve * @param asset the address of the reserve
* @param _proxy the aToken proxy address * @param proxy the aToken proxy address
* @param _implementation the new aToken implementation * @param implementation the new aToken implementation
**/ **/
event ATokenUpgraded(address _reserve, address _proxy, address _implementation); event ATokenUpgraded(address asset, address proxy, address implementation);
/** /**
* @dev emitted when the implementation of a stable debt token is upgraded * @dev emitted when the implementation of a stable debt token is upgraded
* @param _reserve the address of the reserve * @param asset the address of the reserve
* @param _proxy the stable debt token proxy address * @param proxy the stable debt token proxy address
* @param _implementation the new aToken implementation * @param implementation the new aToken implementation
**/ **/
event StableDebtTokenUpgraded(address _reserve, address _proxy, address _implementation); event StableDebtTokenUpgraded(address asset, address proxy, address implementation);
/** /**
* @dev emitted when the implementation of a variable debt token is upgraded * @dev emitted when the implementation of a variable debt token is upgraded
* @param _reserve the address of the reserve * @param asset the address of the reserve
* @param _proxy the variable debt token proxy address * @param _proxy the variable debt token proxy address
* @param _implementation the new aToken implementation * @param _implementation the new aToken implementation
**/ **/
event VariableDebtTokenUpgraded(address _reserve, address _proxy, address _implementation); event VariableDebtTokenUpgraded(address asset, address _proxy, address _implementation);
LendingPoolAddressesProvider public poolAddressesProvider; ILendingPoolAddressesProvider internal addressesProvider;
ILendingPool public pool; ILendingPool internal pool;
/** /**
* @dev only the lending pool manager can call functions affected by this modifier * @dev only the lending pool manager can call functions affected by this modifier
**/ **/
modifier onlyLendingPoolManager { modifier onlyLendingPoolManager {
require( require(
poolAddressesProvider.getLendingPoolManager() == msg.sender, addressesProvider.getLendingPoolManager() == msg.sender,
'The caller must be a lending pool manager' 'The caller must be a lending pool manager'
); );
_; _;
@ -187,242 +189,235 @@ contract LendingPoolConfigurator is VersionedInitializable {
return CONFIGURATOR_REVISION; return CONFIGURATOR_REVISION;
} }
function initialize(LendingPoolAddressesProvider _poolAddressesProvider) public initializer { function initialize(ILendingPoolAddressesProvider provider) public initializer {
poolAddressesProvider = _poolAddressesProvider; addressesProvider = provider;
pool = ILendingPool(poolAddressesProvider.getLendingPool()); pool = ILendingPool(addressesProvider.getLendingPool());
} }
/** /**
* @dev initializes a reserve * @dev initializes a reserve
* @param _reserve the address of the reserve to be initialized * @param asset the address of the reserve to be initialized
* @param _aTokenImpl the address of the aToken contract implementation * @param aTokenImpl the address of the aToken contract implementation
* @param _stableDebtTokenImpl the address of the stable debt token contract * @param stableDebtTokenImpl the address of the stable debt token contract
* @param _variableDebtTokenImpl the address of the variable debt token contract * @param variableDebtTokenImpl the address of the variable debt token contract
* @param _underlyingAssetDecimals the decimals of the reserve underlying asset * @param underlyingAssetDecimals the decimals of the reserve underlying asset
* @param _interestRateStrategyAddress the address of the interest rate strategy contract for this reserve * @param interestRateStrategyAddress the address of the interest rate strategy contract for this reserve
**/ **/
function initReserve( function initReserve(
address _reserve, address asset,
address _aTokenImpl, address aTokenImpl,
address _stableDebtTokenImpl, address stableDebtTokenImpl,
address _variableDebtTokenImpl, address variableDebtTokenImpl,
uint8 _underlyingAssetDecimals, uint8 underlyingAssetDecimals,
address _interestRateStrategyAddress address interestRateStrategyAddress
) public onlyLendingPoolManager { ) public onlyLendingPoolManager {
address aTokenProxyAddress = _initTokenWithProxy( address aTokenProxyAddress = _initTokenWithProxy(
_aTokenImpl, aTokenImpl,
_underlyingAssetDecimals, underlyingAssetDecimals
IERC20Detailed(_aTokenImpl).name(),
IERC20Detailed(_aTokenImpl).symbol()
); );
address stableDebtTokenProxyAddress = _initTokenWithProxy( address stableDebtTokenProxyAddress = _initTokenWithProxy(
_stableDebtTokenImpl, stableDebtTokenImpl,
_underlyingAssetDecimals, underlyingAssetDecimals
IERC20Detailed(_stableDebtTokenImpl).name(),
IERC20Detailed(_stableDebtTokenImpl).symbol()
); );
address variableDebtTokenProxyAddress = _initTokenWithProxy( address variableDebtTokenProxyAddress = _initTokenWithProxy(
_variableDebtTokenImpl, variableDebtTokenImpl,
_underlyingAssetDecimals, underlyingAssetDecimals
IERC20Detailed(_variableDebtTokenImpl).name(),
IERC20Detailed(_variableDebtTokenImpl).symbol()
); );
pool.initReserve( pool.initReserve(
_reserve, asset,
aTokenProxyAddress, aTokenProxyAddress,
stableDebtTokenProxyAddress, stableDebtTokenProxyAddress,
variableDebtTokenProxyAddress, variableDebtTokenProxyAddress,
_interestRateStrategyAddress interestRateStrategyAddress
); );
ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(_reserve); ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset);
currentConfig.setDecimals(_underlyingAssetDecimals); currentConfig.setDecimals(underlyingAssetDecimals);
currentConfig.setActive(true); currentConfig.setActive(true);
currentConfig.setFrozen(false); currentConfig.setFrozen(false);
pool.setConfiguration(_reserve, currentConfig.data); pool.setConfiguration(asset, currentConfig.data);
emit ReserveInitialized( emit ReserveInitialized(
_reserve, asset,
aTokenProxyAddress, aTokenProxyAddress,
stableDebtTokenProxyAddress, stableDebtTokenProxyAddress,
variableDebtTokenProxyAddress, variableDebtTokenProxyAddress,
_interestRateStrategyAddress interestRateStrategyAddress
); );
} }
/** /**
* @dev updates the aToken implementation for the _reserve * @dev updates the aToken implementation for the asset
* @param _reserve the address of the reserve to be updated * @param asset the address of the reserve to be updated
* @param _implementation the address of the new aToken implementation * @param implementation the address of the new aToken implementation
**/ **/
function updateAToken(address _reserve, address _implementation) external onlyLendingPoolManager { function updateAToken(address asset, address implementation) external onlyLendingPoolManager {
(address aTokenAddress, , ) = pool.getReserveTokensAddresses(_reserve); (address aTokenAddress, , ) = pool.getReserveTokensAddresses(asset);
_upgradeTokenImplementation(_reserve, aTokenAddress, _implementation); _upgradeTokenImplementation(asset, aTokenAddress, implementation);
emit ATokenUpgraded(_reserve, aTokenAddress, _implementation); emit ATokenUpgraded(asset, aTokenAddress, implementation);
} }
/** /**
* @dev updates the stable debt token implementation for the _reserve * @dev updates the stable debt token implementation for the asset
* @param _reserve the address of the reserve to be updated * @param asset the address of the reserve to be updated
* @param _implementation the address of the new aToken implementation * @param implementation the address of the new aToken implementation
**/ **/
function updateStableDebtToken(address _reserve, address _implementation) function updateStableDebtToken(address asset, address implementation)
external external
onlyLendingPoolManager onlyLendingPoolManager
{ {
(, address stableDebtToken, ) = pool.getReserveTokensAddresses(_reserve); (, address stableDebtToken, ) = pool.getReserveTokensAddresses(asset);
_upgradeTokenImplementation(_reserve, stableDebtToken, _implementation); _upgradeTokenImplementation(asset, stableDebtToken, implementation);
emit StableDebtTokenUpgraded(_reserve, stableDebtToken, _implementation); emit StableDebtTokenUpgraded(asset, stableDebtToken, implementation);
} }
/** /**
* @dev updates the variable debt token implementation for the _reserve * @dev updates the variable debt token implementation for the asset
* @param _reserve the address of the reserve to be updated * @param asset the address of the reserve to be updated
* @param _implementation the address of the new aToken implementation * @param implementation the address of the new aToken implementation
**/ **/
function updateVariableDebtToken(address _reserve, address _implementation) function updateVariableDebtToken(address asset, address implementation)
external external
onlyLendingPoolManager onlyLendingPoolManager
{ {
(, , address variableDebtToken) = pool.getReserveTokensAddresses(_reserve); (, , address variableDebtToken) = pool.getReserveTokensAddresses(asset);
_upgradeTokenImplementation(_reserve, variableDebtToken, _implementation); _upgradeTokenImplementation(asset, variableDebtToken, implementation);
emit VariableDebtTokenUpgraded(_reserve, variableDebtToken, _implementation); emit VariableDebtTokenUpgraded(asset, variableDebtToken, implementation);
} }
/** /**
* @dev enables borrowing on a reserve * @dev enables borrowing on a reserve
* @param _reserve the address of the reserve * @param asset the address of the reserve
* @param _stableBorrowRateEnabled true if stable borrow rate needs to be enabled by default on this reserve * @param stableBorrowRateEnabled true if stable borrow rate needs to be enabled by default on this reserve
**/ **/
function enableBorrowingOnReserve(address _reserve, bool _stableBorrowRateEnabled) function enableBorrowingOnReserve(address asset, bool stableBorrowRateEnabled)
external external
onlyLendingPoolManager onlyLendingPoolManager
{ {
ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(_reserve); ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset);
currentConfig.setBorrowingEnabled(true); currentConfig.setBorrowingEnabled(true);
currentConfig.setStableRateBorrowingEnabled(_stableBorrowRateEnabled); currentConfig.setStableRateBorrowingEnabled(stableBorrowRateEnabled);
pool.setConfiguration(_reserve, currentConfig.data); pool.setConfiguration(asset, currentConfig.data);
emit BorrowingEnabledOnReserve(_reserve, _stableBorrowRateEnabled); emit BorrowingEnabledOnReserve(asset, stableBorrowRateEnabled);
} }
/** /**
* @dev disables borrowing on a reserve * @dev disables borrowing on a reserve
* @param _reserve the address of the reserve * @param asset the address of the reserve
**/ **/
function disableBorrowingOnReserve(address _reserve) external onlyLendingPoolManager { function disableBorrowingOnReserve(address asset) external onlyLendingPoolManager {
ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(_reserve); ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset);
currentConfig.setBorrowingEnabled(false); currentConfig.setBorrowingEnabled(false);
pool.setConfiguration(_reserve, currentConfig.data); pool.setConfiguration(asset, currentConfig.data);
emit BorrowingDisabledOnReserve(_reserve); emit BorrowingDisabledOnReserve(asset);
} }
/** /**
* @dev enables a reserve to be used as collateral * @dev enables a reserve to be used as collateral
* @param _reserve the address of the reserve * @param asset the address of the reserve
* @param _baseLTVasCollateral the loan to value of the asset when used as collateral * @param ltv the loan to value of the asset when used as collateral
* @param _liquidationThreshold the threshold at which loans using this asset as collateral will be considered undercollateralized * @param liquidationThreshold the threshold at which loans using this asset as collateral will be considered undercollateralized
* @param _liquidationBonus the bonus liquidators receive to liquidate this asset * @param liquidationBonus the bonus liquidators receive to liquidate this asset
**/ **/
function enableReserveAsCollateral( function enableReserveAsCollateral(
address _reserve, address asset,
uint256 _baseLTVasCollateral, uint256 ltv,
uint256 _liquidationThreshold, uint256 liquidationThreshold,
uint256 _liquidationBonus uint256 liquidationBonus
) external onlyLendingPoolManager { ) external onlyLendingPoolManager {
ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(_reserve); ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset);
currentConfig.setLtv(_baseLTVasCollateral); currentConfig.setLtv(ltv);
currentConfig.setLiquidationThreshold(_liquidationThreshold); currentConfig.setLiquidationThreshold(liquidationThreshold);
currentConfig.setLiquidationBonus(_liquidationBonus); currentConfig.setLiquidationBonus(liquidationBonus);
pool.setConfiguration(_reserve, currentConfig.data); pool.setConfiguration(asset, currentConfig.data);
emit ReserveEnabledAsCollateral( emit ReserveEnabledAsCollateral(
_reserve, asset,
_baseLTVasCollateral, ltv,
_liquidationThreshold, liquidationThreshold,
_liquidationBonus liquidationBonus
); );
} }
/** /**
* @dev disables a reserve as collateral * @dev disables a reserve as collateral
* @param _reserve the address of the reserve * @param asset the address of the reserve
**/ **/
function disableReserveAsCollateral(address _reserve) external onlyLendingPoolManager { function disableReserveAsCollateral(address asset) external onlyLendingPoolManager {
ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(_reserve); ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset);
currentConfig.setLtv(0); currentConfig.setLtv(0);
pool.setConfiguration(_reserve, currentConfig.data); pool.setConfiguration(asset, currentConfig.data);
emit ReserveDisabledAsCollateral(_reserve); emit ReserveDisabledAsCollateral(asset);
} }
/** /**
* @dev enable stable rate borrowing on a reserve * @dev enable stable rate borrowing on a reserve
* @param _reserve the address of the reserve * @param asset the address of the reserve
**/ **/
function enableReserveStableRate(address _reserve) external onlyLendingPoolManager { function enableReserveStableRate(address asset) external onlyLendingPoolManager {
ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(_reserve); ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset);
currentConfig.setStableRateBorrowingEnabled(true); currentConfig.setStableRateBorrowingEnabled(true);
pool.setConfiguration(_reserve, currentConfig.data); pool.setConfiguration(asset, currentConfig.data);
emit StableRateEnabledOnReserve(_reserve); emit StableRateEnabledOnReserve(asset);
} }
/** /**
* @dev disable stable rate borrowing on a reserve * @dev disable stable rate borrowing on a reserve
* @param _reserve the address of the reserve * @param asset the address of the reserve
**/ **/
function disableReserveStableRate(address _reserve) external onlyLendingPoolManager { function disableReserveStableRate(address asset) external onlyLendingPoolManager {
ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(_reserve); ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset);
currentConfig.setStableRateBorrowingEnabled(false); currentConfig.setStableRateBorrowingEnabled(false);
pool.setConfiguration(_reserve, currentConfig.data); pool.setConfiguration(asset, currentConfig.data);
emit StableRateDisabledOnReserve(_reserve); emit StableRateDisabledOnReserve(asset);
} }
/** /**
* @dev activates a reserve * @dev activates a reserve
* @param _reserve the address of the reserve * @param asset the address of the reserve
**/ **/
function activateReserve(address _reserve) external onlyLendingPoolManager { function activateReserve(address asset) external onlyLendingPoolManager {
ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(_reserve); ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset);
currentConfig.setActive(true); currentConfig.setActive(true);
pool.setConfiguration(_reserve, currentConfig.data); pool.setConfiguration(asset, currentConfig.data);
emit ReserveActivated(_reserve); emit ReserveActivated(asset);
} }
/** /**
* @dev deactivates a reserve * @dev deactivates a reserve
* @param _reserve the address of the reserve * @param asset the address of the reserve
**/ **/
function deactivateReserve(address _reserve) external onlyLendingPoolManager { function deactivateReserve(address asset) external onlyLendingPoolManager {
( (
uint256 availableLiquidity, uint256 availableLiquidity,
uint256 totalBorrowsStable, uint256 totalBorrowsStable,
@ -434,170 +429,166 @@ contract LendingPoolConfigurator is VersionedInitializable {
, ,
, ,
) = pool.getReserveData(_reserve); ) = pool.getReserveData(asset);
require( require(
availableLiquidity == 0 && totalBorrowsStable == 0 && totalBorrowsVariable == 0, availableLiquidity == 0 && totalBorrowsStable == 0 && totalBorrowsVariable == 0,
'The liquidity of the reserve needs to be 0' 'The liquidity of the reserve needs to be 0'
); );
ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(_reserve); ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset);
currentConfig.setActive(false); currentConfig.setActive(false);
pool.setConfiguration(_reserve, currentConfig.data); pool.setConfiguration(asset, currentConfig.data);
emit ReserveDeactivated(_reserve); emit ReserveDeactivated(asset);
} }
/** /**
* @dev freezes a reserve. A freezed reserve doesn't accept any new deposit, borrow or rate swap, but can accept repayments, liquidations, rate rebalances and redeems * @dev freezes a reserve. A freezed reserve doesn't accept any new deposit, borrow or rate swap, but can accept repayments, liquidations, rate rebalances and redeems
* @param _reserve the address of the reserve * @param asset the address of the reserve
**/ **/
function freezeReserve(address _reserve) external onlyLendingPoolManager { function freezeReserve(address asset) external onlyLendingPoolManager {
ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(_reserve); ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset);
currentConfig.setFrozen(true); currentConfig.setFrozen(true);
pool.setConfiguration(_reserve, currentConfig.data); pool.setConfiguration(asset, currentConfig.data);
emit ReserveFreezed(_reserve); emit ReserveFreezed(asset);
} }
/** /**
* @dev unfreezes a reserve * @dev unfreezes a reserve
* @param _reserve the address of the reserve * @param asset the address of the reserve
**/ **/
function unfreezeReserve(address _reserve) external onlyLendingPoolManager { function unfreezeReserve(address asset) external onlyLendingPoolManager {
ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(_reserve); ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset);
currentConfig.setFrozen(false); currentConfig.setFrozen(false);
pool.setConfiguration(_reserve, currentConfig.data); pool.setConfiguration(asset, currentConfig.data);
emit ReserveUnfreezed(_reserve); emit ReserveUnfreezed(asset);
} }
/** /**
* @dev emitted when a reserve loan to value is updated * @dev emitted when a reserve loan to value is updated
* @param _reserve the address of the reserve * @param asset the address of the reserve
* @param _ltv the new value for the loan to value * @param ltv the new value for the loan to value
**/ **/
function setLtv(address _reserve, uint256 _ltv) external onlyLendingPoolManager { function setLtv(address asset, uint256 ltv) external onlyLendingPoolManager {
ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(_reserve); ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset);
currentConfig.setLtv(_ltv); currentConfig.setLtv(ltv);
pool.setConfiguration(_reserve, currentConfig.data); pool.setConfiguration(asset, currentConfig.data);
emit ReserveBaseLtvChanged(_reserve, _ltv); emit ReserveBaseLtvChanged(asset, ltv);
} }
/** /**
* @dev updates the liquidation threshold of a reserve. * @dev updates the liquidation threshold of a reserve.
* @param _reserve the address of the reserve * @param asset the address of the reserve
* @param _threshold the new value for the liquidation threshold * @param threshold the new value for the liquidation threshold
**/ **/
function setLiquidationThreshold(address _reserve, uint256 _threshold) function setLiquidationThreshold(address asset, uint256 threshold)
external external
onlyLendingPoolManager onlyLendingPoolManager
{ {
ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(_reserve); ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset);
currentConfig.setLiquidationThreshold(_threshold); currentConfig.setLiquidationThreshold(threshold);
pool.setConfiguration(_reserve, currentConfig.data); pool.setConfiguration(asset, currentConfig.data);
emit ReserveLiquidationThresholdChanged(_reserve, _threshold); emit ReserveLiquidationThresholdChanged(asset, threshold);
} }
/** /**
* @dev updates the liquidation bonus of a reserve * @dev updates the liquidation bonus of a reserve
* @param _reserve the address of the reserve * @param asset the address of the reserve
* @param _bonus the new value for the liquidation bonus * @param bonus the new value for the liquidation bonus
**/ **/
function setLiquidationBonus(address _reserve, uint256 _bonus) external onlyLendingPoolManager { function setLiquidationBonus(address asset, uint256 bonus) external onlyLendingPoolManager {
ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(_reserve); ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset);
currentConfig.setLiquidationBonus(_bonus); currentConfig.setLiquidationBonus(bonus);
pool.setConfiguration(_reserve, currentConfig.data); pool.setConfiguration(asset, currentConfig.data);
emit ReserveLiquidationBonusChanged(_reserve, _bonus); emit ReserveLiquidationBonusChanged(asset, bonus);
} }
/** /**
* @dev updates the reserve decimals * @dev updates the reserve decimals
* @param _reserve the address of the reserve * @param asset the address of the reserve
* @param _decimals the new number of decimals * @param decimals the new number of decimals
**/ **/
function setReserveDecimals(address _reserve, uint256 _decimals) external onlyLendingPoolManager { function setReserveDecimals(address asset, uint256 decimals) external onlyLendingPoolManager {
ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(_reserve); ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset);
currentConfig.setDecimals(_decimals); currentConfig.setDecimals(decimals);
pool.setConfiguration(_reserve, currentConfig.data); pool.setConfiguration(asset, currentConfig.data);
emit ReserveDecimalsChanged(_reserve, _decimals); emit ReserveDecimalsChanged(asset, decimals);
} }
/** /**
* @dev sets the interest rate strategy of a reserve * @dev sets the interest rate strategy of a reserve
* @param _reserve the address of the reserve * @param asset the address of the reserve
* @param _rateStrategyAddress the new address of the interest strategy contract * @param rateStrategyAddress the new address of the interest strategy contract
**/ **/
function setReserveInterestRateStrategyAddress(address _reserve, address _rateStrategyAddress) function setReserveInterestRateStrategyAddress(address asset, address rateStrategyAddress)
external external
onlyLendingPoolManager onlyLendingPoolManager
{ {
pool.setReserveInterestRateStrategyAddress(_reserve, _rateStrategyAddress); pool.setReserveInterestRateStrategyAddress(asset, rateStrategyAddress);
emit ReserveInterestRateStrategyChanged(_reserve, _rateStrategyAddress); emit ReserveInterestRateStrategyChanged(asset, rateStrategyAddress);
} }
/** /**
* @dev initializes a token with a proxy and a specific implementation * @dev initializes a token with a proxy and a specific implementation
* @param _implementation the address of the implementation * @param implementation the address of the implementation
* @param _decimals the decimals of the token * @param decimals the decimals of the token
* @param _name the name of the token
* @param _symbol the symbol of the token
**/ **/
function _initTokenWithProxy( function _initTokenWithProxy(
address _implementation, address implementation,
uint8 _decimals, uint8 decimals
string memory _name,
string memory _symbol
) internal returns (address) { ) internal returns (address) {
InitializableAdminUpgradeabilityProxy proxy = new InitializableAdminUpgradeabilityProxy(); InitializableAdminUpgradeabilityProxy proxy = new InitializableAdminUpgradeabilityProxy();
bytes memory params = abi.encodeWithSignature( bytes memory params = abi.encodeWithSignature(
'initialize(uint8,string,string)', 'initialize(uint8,string,string)',
_decimals, decimals,
_name, IERC20Detailed(implementation).name(),
_symbol IERC20Detailed(implementation).symbol()
); );
proxy.initialize(_implementation, address(this), params); proxy.initialize(implementation, address(this), params);
return address(proxy); return address(proxy);
} }
function _upgradeTokenImplementation( function _upgradeTokenImplementation(
address _reserve, address asset,
address _proxy, address proxyAddress,
address _implementation address implementation
) internal { ) internal {
InitializableAdminUpgradeabilityProxy proxy = InitializableAdminUpgradeabilityProxy( InitializableAdminUpgradeabilityProxy proxy = InitializableAdminUpgradeabilityProxy(
payable(_proxy) payable(proxyAddress)
); );
(uint256 decimals, , , , , , , , , ) = pool.getReserveConfigurationData(_reserve); (uint256 decimals, , , , , , , , , ) = pool.getReserveConfigurationData(asset);
bytes memory params = abi.encodeWithSignature( bytes memory params = abi.encodeWithSignature(
'initialize(uint8,string,string)', 'initialize(uint8,string,string)',
uint8(decimals), uint8(decimals),
IERC20Detailed(_implementation).name(), IERC20Detailed(implementation).name(),
IERC20Detailed(_implementation).symbol() IERC20Detailed(implementation).symbol()
); );
proxy.upgradeToAndCall(_implementation, params); proxy.upgradeToAndCall(implementation, params);
} }
} }