mirror of
https://github.com/Instadapp/aave-protocol-v2.git
synced 2024-07-29 21:47:30 +00:00
Merge branch 'master' into 'certora/integrationStep2'
# Conflicts: # specs/harness/LendingPoolHarnessForVariableDebtToken.sol
This commit is contained in:
commit
513c7c09f1
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -7,7 +7,7 @@ dist/
|
|||
build/
|
||||
.vscode
|
||||
.idea
|
||||
types
|
||||
/types
|
||||
|
||||
deployed-contracts.json
|
||||
|
||||
|
|
|
@ -2,10 +2,9 @@
|
|||
pragma solidity 0.6.12;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import {ReserveConfiguration} from '../protocol/libraries/configuration/ReserveConfiguration.sol';
|
||||
import {UserConfiguration} from '../protocol/libraries/configuration/UserConfiguration.sol';
|
||||
import {ReserveLogic} from '../protocol/libraries/logic/ReserveLogic.sol';
|
||||
import {ILendingPoolAddressesProvider} from './ILendingPoolAddressesProvider.sol';
|
||||
import {DataTypes} from '../protocol/libraries/types/DataTypes.sol';
|
||||
|
||||
|
||||
interface ILendingPool {
|
||||
/**
|
||||
|
@ -355,14 +354,20 @@ interface ILendingPool {
|
|||
* @param asset The address of the underlying asset of the reserve
|
||||
* @return The configuration of the reserve
|
||||
**/
|
||||
function getConfiguration(address asset) external view returns (ReserveConfiguration.Map memory);
|
||||
function getConfiguration(address asset)
|
||||
external
|
||||
view
|
||||
returns (DataTypes.ReserveConfigurationMap memory);
|
||||
|
||||
/**
|
||||
* @dev Returns the configuration of the user across all the reserves
|
||||
* @param user The user address
|
||||
* @return The configuration of the user
|
||||
**/
|
||||
function getUserConfiguration(address user) external view returns (UserConfiguration.Map memory);
|
||||
function getUserConfiguration(address user)
|
||||
external
|
||||
view
|
||||
returns (DataTypes.UserConfigurationMap memory);
|
||||
|
||||
/**
|
||||
* @dev Returns the normalized income normalized income of the reserve
|
||||
|
@ -383,7 +388,7 @@ interface ILendingPool {
|
|||
* @param asset The address of the underlying asset of the reserve
|
||||
* @return The state of the reserve
|
||||
**/
|
||||
function getReserveData(address asset) external view returns (ReserveLogic.ReserveData memory);
|
||||
function getReserveData(address asset) external view returns (DataTypes.ReserveData memory);
|
||||
|
||||
function finalizeTransfer(
|
||||
address asset,
|
||||
|
|
|
@ -49,5 +49,5 @@ interface ILendingPoolCollateralManager {
|
|||
address user,
|
||||
uint256 debtToCover,
|
||||
bool receiveAToken
|
||||
) external virtual returns (uint256, string memory);
|
||||
) external returns (uint256, string memory);
|
||||
}
|
||||
|
|
|
@ -5,15 +5,15 @@ pragma experimental ABIEncoderV2;
|
|||
import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddressesProvider.sol';
|
||||
import {IERC20Detailed} from '../dependencies/openzeppelin/contracts/IERC20Detailed.sol';
|
||||
import {ILendingPool} from '../interfaces/ILendingPool.sol';
|
||||
import {ReserveLogic} from '../protocol/libraries/logic/ReserveLogic.sol';
|
||||
import {ReserveConfiguration} from '../protocol/libraries/configuration/ReserveConfiguration.sol';
|
||||
import {UserConfiguration} from '../protocol/libraries/configuration/UserConfiguration.sol';
|
||||
import {IStableDebtToken} from '../protocol/tokenization/interfaces/IStableDebtToken.sol';
|
||||
import {IVariableDebtToken} from '../protocol/tokenization/interfaces/IVariableDebtToken.sol';
|
||||
import {DataTypes} from '../protocol/libraries/types/DataTypes.sol';
|
||||
|
||||
contract AaveProtocolDataProvider {
|
||||
using ReserveConfiguration for ReserveConfiguration.Map;
|
||||
using UserConfiguration for UserConfiguration.Map;
|
||||
using ReserveConfiguration for DataTypes.ReserveConfigurationMap;
|
||||
using UserConfiguration for DataTypes.UserConfigurationMap;
|
||||
|
||||
address constant MKR = 0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2;
|
||||
address constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
|
||||
|
@ -55,7 +55,7 @@ contract AaveProtocolDataProvider {
|
|||
address[] memory reserves = pool.getReservesList();
|
||||
TokenData[] memory aTokens = new TokenData[](reserves.length);
|
||||
for (uint256 i = 0; i < reserves.length; i++) {
|
||||
ReserveLogic.ReserveData memory reserveData = pool.getReserveData(reserves[i]);
|
||||
DataTypes.ReserveData memory reserveData = pool.getReserveData(reserves[i]);
|
||||
aTokens[i] = TokenData({
|
||||
symbol: IERC20Detailed(reserveData.aTokenAddress).symbol(),
|
||||
tokenAddress: reserveData.aTokenAddress
|
||||
|
@ -80,7 +80,7 @@ contract AaveProtocolDataProvider {
|
|||
bool isFrozen
|
||||
)
|
||||
{
|
||||
ReserveConfiguration.Map memory configuration =
|
||||
DataTypes.ReserveConfigurationMap memory configuration =
|
||||
ILendingPool(ADDRESSES_PROVIDER.getLendingPool()).getConfiguration(asset);
|
||||
|
||||
(ltv, liquidationThreshold, liquidationBonus, decimals, reserveFactor) = configuration
|
||||
|
@ -108,7 +108,7 @@ contract AaveProtocolDataProvider {
|
|||
uint40 lastUpdateTimestamp
|
||||
)
|
||||
{
|
||||
ReserveLogic.ReserveData memory reserve =
|
||||
DataTypes.ReserveData memory reserve =
|
||||
ILendingPool(ADDRESSES_PROVIDER.getLendingPool()).getReserveData(asset);
|
||||
|
||||
return (
|
||||
|
@ -140,10 +140,10 @@ contract AaveProtocolDataProvider {
|
|||
bool usageAsCollateralEnabled
|
||||
)
|
||||
{
|
||||
ReserveLogic.ReserveData memory reserve =
|
||||
DataTypes.ReserveData memory reserve =
|
||||
ILendingPool(ADDRESSES_PROVIDER.getLendingPool()).getReserveData(asset);
|
||||
|
||||
UserConfiguration.Map memory userConfig =
|
||||
DataTypes.UserConfigurationMap memory userConfig =
|
||||
ILendingPool(ADDRESSES_PROVIDER.getLendingPool()).getUserConfiguration(user);
|
||||
|
||||
currentATokenBalance = IERC20Detailed(reserve.aTokenAddress).balanceOf(user);
|
||||
|
@ -168,7 +168,7 @@ contract AaveProtocolDataProvider {
|
|||
address variableDebtTokenAddress
|
||||
)
|
||||
{
|
||||
ReserveLogic.ReserveData memory reserve =
|
||||
DataTypes.ReserveData memory reserve =
|
||||
ILendingPool(ADDRESSES_PROVIDER.getLendingPool()).getReserveData(asset);
|
||||
|
||||
return (
|
||||
|
|
|
@ -12,17 +12,17 @@ import {IVariableDebtToken} from '../protocol/tokenization/interfaces/IVariableD
|
|||
import {IStableDebtToken} from '../protocol/tokenization/interfaces/IStableDebtToken.sol';
|
||||
|
||||
import {WadRayMath} from '../protocol/libraries/math/WadRayMath.sol';
|
||||
import {ReserveLogic} from '../protocol/libraries/logic/ReserveLogic.sol';
|
||||
import {ReserveConfiguration} from '../protocol/libraries/configuration/ReserveConfiguration.sol';
|
||||
import {UserConfiguration} from '../protocol/libraries/configuration/UserConfiguration.sol';
|
||||
import {
|
||||
DefaultReserveInterestRateStrategy
|
||||
} from '../protocol/lendingpool/DefaultReserveInterestRateStrategy.sol';
|
||||
import {DataTypes} from '../protocol/libraries/types/DataTypes.sol';
|
||||
|
||||
contract UiPoolDataProvider is IUiPoolDataProvider {
|
||||
using WadRayMath for uint256;
|
||||
using ReserveConfiguration for ReserveConfiguration.Map;
|
||||
using UserConfiguration for UserConfiguration.Map;
|
||||
using ReserveConfiguration for DataTypes.ReserveConfigurationMap;
|
||||
using UserConfiguration for DataTypes.UserConfigurationMap;
|
||||
|
||||
address public constant MOCK_USD_ADDRESS = 0x10F7Fc1F91Ba351f9C629c5947AD69bD03C05b96;
|
||||
|
||||
|
@ -57,7 +57,7 @@ contract UiPoolDataProvider is IUiPoolDataProvider {
|
|||
ILendingPool lendingPool = ILendingPool(provider.getLendingPool());
|
||||
IPriceOracleGetter oracle = IPriceOracleGetter(provider.getPriceOracle());
|
||||
address[] memory reserves = lendingPool.getReservesList();
|
||||
UserConfiguration.Map memory userConfig = lendingPool.getUserConfiguration(user);
|
||||
DataTypes.UserConfigurationMap memory userConfig = lendingPool.getUserConfiguration(user);
|
||||
|
||||
AggregatedReserveData[] memory reservesData = new AggregatedReserveData[](reserves.length);
|
||||
UserReserveData[] memory userReservesData =
|
||||
|
@ -68,7 +68,7 @@ contract UiPoolDataProvider is IUiPoolDataProvider {
|
|||
reserveData.underlyingAsset = reserves[i];
|
||||
|
||||
// reserve current state
|
||||
ReserveLogic.ReserveData memory baseData =
|
||||
DataTypes.ReserveData memory baseData =
|
||||
lendingPool.getReserveData(reserveData.underlyingAsset);
|
||||
reserveData.liquidityIndex = baseData.liquidityIndex;
|
||||
reserveData.variableBorrowIndex = baseData.variableBorrowIndex;
|
||||
|
|
|
@ -6,16 +6,16 @@ import {IWETH} from './interfaces/IWETH.sol';
|
|||
import {IWETHGateway} from './interfaces/IWETHGateway.sol';
|
||||
import {ILendingPool} from '../interfaces/ILendingPool.sol';
|
||||
import {IAToken} from '../protocol/tokenization/interfaces/IAToken.sol';
|
||||
import {ReserveLogic} from '../protocol/libraries/logic/ReserveLogic.sol';
|
||||
import {ReserveConfiguration} from '../protocol/libraries/configuration/ReserveConfiguration.sol';
|
||||
import {UserConfiguration} from '../protocol/libraries/configuration/UserConfiguration.sol';
|
||||
import {Helpers} from '../protocol/libraries/helpers/Helpers.sol';
|
||||
import {Ownable} from '../dependencies/openzeppelin/contracts/Ownable.sol';
|
||||
import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol';
|
||||
import {DataTypes} from '../protocol/libraries/types/DataTypes.sol';
|
||||
|
||||
contract WETHGateway is IWETHGateway, Ownable {
|
||||
using ReserveConfiguration for ReserveConfiguration.Map;
|
||||
using UserConfiguration for UserConfiguration.Map;
|
||||
using ReserveConfiguration for DataTypes.ReserveConfigurationMap;
|
||||
using UserConfiguration for DataTypes.UserConfigurationMap;
|
||||
|
||||
IWETH internal immutable WETH;
|
||||
ILendingPool internal immutable POOL;
|
||||
|
@ -79,7 +79,7 @@ contract WETHGateway is IWETHGateway, Ownable {
|
|||
Helpers.getUserCurrentDebtMemory(onBehalfOf, POOL.getReserveData(address(WETH)));
|
||||
|
||||
uint256 paybackAmount =
|
||||
ReserveLogic.InterestRateMode(rateMode) == ReserveLogic.InterestRateMode.STABLE
|
||||
DataTypes.InterestRateMode(rateMode) == DataTypes.InterestRateMode.STABLE
|
||||
? stableDebt
|
||||
: variableDebt;
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddresses
|
|||
import {ILendingPool} from '../interfaces/ILendingPool.sol';
|
||||
import {SafeERC20} from '../dependencies/openzeppelin/contracts/SafeERC20.sol';
|
||||
import {ReserveConfiguration} from '../protocol/libraries/configuration/ReserveConfiguration.sol';
|
||||
import {DataTypes} from '../protocol/libraries/types/DataTypes.sol';
|
||||
|
||||
/**
|
||||
* @title WalletBalanceProvider contract
|
||||
|
@ -22,7 +23,7 @@ contract WalletBalanceProvider {
|
|||
using Address for address payable;
|
||||
using Address for address;
|
||||
using SafeERC20 for IERC20;
|
||||
using ReserveConfiguration for ReserveConfiguration.Map;
|
||||
using ReserveConfiguration for DataTypes.ReserveConfigurationMap;
|
||||
|
||||
address constant MOCK_ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
|
||||
|
||||
|
@ -92,7 +93,7 @@ contract WalletBalanceProvider {
|
|||
uint256[] memory balances = new uint256[](reservesWithEth.length);
|
||||
|
||||
for (uint256 j = 0; j < reserves.length; j++) {
|
||||
ReserveConfiguration.Map memory configuration = pool.getConfiguration(reservesWithEth[j]);
|
||||
DataTypes.ReserveConfigurationMap memory configuration = pool.getConfiguration(reservesWithEth[j]);
|
||||
|
||||
(bool isActive, , , ) = configuration.getFlagsMemory();
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@ pragma solidity 0.6.12;
|
|||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import {ILendingPoolAddressesProvider} from '../../interfaces/ILendingPoolAddressesProvider.sol';
|
||||
import {ReserveLogic} from '../../protocol/libraries/logic/ReserveLogic.sol';
|
||||
|
||||
interface IUiPoolDataProvider {
|
||||
struct AggregatedReserveData {
|
||||
|
|
|
@ -24,6 +24,7 @@ import {SafeERC20} from '../../dependencies/openzeppelin/contracts/SafeERC20.sol
|
|||
import {ILendingPool} from '../../interfaces/ILendingPool.sol';
|
||||
import {LendingPoolStorage} from './LendingPoolStorage.sol';
|
||||
import {Address} from '../../dependencies/openzeppelin/contracts/Address.sol';
|
||||
import {DataTypes} from '../libraries/types/DataTypes.sol';
|
||||
|
||||
/**
|
||||
* @title LendingPool contract
|
||||
|
@ -107,7 +108,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
address onBehalfOf,
|
||||
uint16 referralCode
|
||||
) external override whenNotPaused {
|
||||
ReserveLogic.ReserveData storage reserve = _reserves[asset];
|
||||
DataTypes.ReserveData storage reserve = _reserves[asset];
|
||||
|
||||
ValidationLogic.validateDeposit(reserve, amount);
|
||||
|
||||
|
@ -143,7 +144,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
uint256 amount,
|
||||
address to
|
||||
) external override whenNotPaused {
|
||||
ReserveLogic.ReserveData storage reserve = _reserves[asset];
|
||||
DataTypes.ReserveData storage reserve = _reserves[asset];
|
||||
|
||||
address aToken = reserve.aTokenAddress;
|
||||
|
||||
|
@ -202,7 +203,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
uint16 referralCode,
|
||||
address onBehalfOf
|
||||
) external override whenNotPaused {
|
||||
ReserveLogic.ReserveData storage reserve = _reserves[asset];
|
||||
DataTypes.ReserveData storage reserve = _reserves[asset];
|
||||
|
||||
_executeBorrow(
|
||||
ExecuteBorrowParams(
|
||||
|
@ -235,11 +236,11 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
uint256 rateMode,
|
||||
address onBehalfOf
|
||||
) external override whenNotPaused {
|
||||
ReserveLogic.ReserveData storage reserve = _reserves[asset];
|
||||
DataTypes.ReserveData storage reserve = _reserves[asset];
|
||||
|
||||
(uint256 stableDebt, uint256 variableDebt) = Helpers.getUserCurrentDebt(onBehalfOf, reserve);
|
||||
|
||||
ReserveLogic.InterestRateMode interestRateMode = ReserveLogic.InterestRateMode(rateMode);
|
||||
DataTypes.InterestRateMode interestRateMode = DataTypes.InterestRateMode(rateMode);
|
||||
|
||||
ValidationLogic.validateRepay(
|
||||
reserve,
|
||||
|
@ -250,7 +251,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
variableDebt
|
||||
);
|
||||
|
||||
uint256 paybackAmount = interestRateMode == ReserveLogic.InterestRateMode.STABLE
|
||||
uint256 paybackAmount = interestRateMode == DataTypes.InterestRateMode.STABLE
|
||||
? stableDebt
|
||||
: variableDebt;
|
||||
|
||||
|
@ -260,7 +261,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
|
||||
reserve.updateState();
|
||||
|
||||
if (interestRateMode == ReserveLogic.InterestRateMode.STABLE) {
|
||||
if (interestRateMode == DataTypes.InterestRateMode.STABLE) {
|
||||
IStableDebtToken(reserve.stableDebtTokenAddress).burn(onBehalfOf, paybackAmount);
|
||||
} else {
|
||||
IVariableDebtToken(reserve.variableDebtTokenAddress).burn(
|
||||
|
@ -288,11 +289,11 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
* @param rateMode The rate mode that the user wants to swap to
|
||||
**/
|
||||
function swapBorrowRateMode(address asset, uint256 rateMode) external override whenNotPaused {
|
||||
ReserveLogic.ReserveData storage reserve = _reserves[asset];
|
||||
DataTypes.ReserveData storage reserve = _reserves[asset];
|
||||
|
||||
(uint256 stableDebt, uint256 variableDebt) = Helpers.getUserCurrentDebt(msg.sender, reserve);
|
||||
|
||||
ReserveLogic.InterestRateMode interestRateMode = ReserveLogic.InterestRateMode(rateMode);
|
||||
DataTypes.InterestRateMode interestRateMode = DataTypes.InterestRateMode(rateMode);
|
||||
|
||||
ValidationLogic.validateSwapRateMode(
|
||||
reserve,
|
||||
|
@ -304,7 +305,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
|
||||
reserve.updateState();
|
||||
|
||||
if (interestRateMode == ReserveLogic.InterestRateMode.STABLE) {
|
||||
if (interestRateMode == DataTypes.InterestRateMode.STABLE) {
|
||||
IStableDebtToken(reserve.stableDebtTokenAddress).burn(msg.sender, stableDebt);
|
||||
IVariableDebtToken(reserve.variableDebtTokenAddress).mint(
|
||||
msg.sender,
|
||||
|
@ -341,7 +342,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
* @param user The address of the user to be rebalanced
|
||||
**/
|
||||
function rebalanceStableBorrowRate(address asset, address user) external override whenNotPaused {
|
||||
ReserveLogic.ReserveData storage reserve = _reserves[asset];
|
||||
DataTypes.ReserveData storage reserve = _reserves[asset];
|
||||
|
||||
IERC20 stableDebtToken = IERC20(reserve.stableDebtTokenAddress);
|
||||
IERC20 variableDebtToken = IERC20(reserve.variableDebtTokenAddress);
|
||||
|
@ -382,7 +383,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
override
|
||||
whenNotPaused
|
||||
{
|
||||
ReserveLogic.ReserveData storage reserve = _reserves[asset];
|
||||
DataTypes.ReserveData storage reserve = _reserves[asset];
|
||||
|
||||
ValidationLogic.validateSetUseReserveAsCollateral(
|
||||
reserve,
|
||||
|
@ -509,7 +510,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
vars.currentATokenAddress = aTokenAddresses[vars.i];
|
||||
vars.currentAmountPlusPremium = vars.currentAmount.add(vars.currentPremium);
|
||||
|
||||
if (ReserveLogic.InterestRateMode(modes[vars.i]) == ReserveLogic.InterestRateMode.NONE) {
|
||||
if (DataTypes.InterestRateMode(modes[vars.i]) == DataTypes.InterestRateMode.NONE) {
|
||||
_reserves[vars.currentAsset].updateState();
|
||||
_reserves[vars.currentAsset].cumulateToLiquidityIndex(
|
||||
IERC20(vars.currentATokenAddress).totalSupply(),
|
||||
|
@ -563,7 +564,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
external
|
||||
view
|
||||
override
|
||||
returns (ReserveLogic.ReserveData memory)
|
||||
returns (DataTypes.ReserveData memory)
|
||||
{
|
||||
return _reserves[asset];
|
||||
}
|
||||
|
@ -622,7 +623,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
external
|
||||
view
|
||||
override
|
||||
returns (ReserveConfiguration.Map memory)
|
||||
returns (DataTypes.ReserveConfigurationMap memory)
|
||||
{
|
||||
return _reserves[asset].configuration;
|
||||
}
|
||||
|
@ -636,7 +637,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
external
|
||||
view
|
||||
override
|
||||
returns (UserConfiguration.Map memory)
|
||||
returns (DataTypes.UserConfigurationMap memory)
|
||||
{
|
||||
return _usersConfig[user];
|
||||
}
|
||||
|
@ -729,13 +730,13 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
|
||||
if (from != to) {
|
||||
if (balanceFromBefore.sub(amount) == 0) {
|
||||
UserConfiguration.Map storage fromConfig = _usersConfig[from];
|
||||
DataTypes.UserConfigurationMap storage fromConfig = _usersConfig[from];
|
||||
fromConfig.setUsingAsCollateral(reserveId, false);
|
||||
emit ReserveUsedAsCollateralDisabled(asset, from);
|
||||
}
|
||||
|
||||
if (balanceToBefore == 0 && amount != 0) {
|
||||
UserConfiguration.Map storage toConfig = _usersConfig[to];
|
||||
DataTypes.UserConfigurationMap storage toConfig = _usersConfig[to];
|
||||
toConfig.setUsingAsCollateral(reserveId, true);
|
||||
emit ReserveUsedAsCollateralEnabled(asset, to);
|
||||
}
|
||||
|
@ -823,8 +824,8 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
}
|
||||
|
||||
function _executeBorrow(ExecuteBorrowParams memory vars) internal {
|
||||
ReserveLogic.ReserveData storage reserve = _reserves[vars.asset];
|
||||
UserConfiguration.Map storage userConfig = _usersConfig[vars.onBehalfOf];
|
||||
DataTypes.ReserveData storage reserve = _reserves[vars.asset];
|
||||
DataTypes.UserConfigurationMap storage userConfig = _usersConfig[vars.onBehalfOf];
|
||||
|
||||
address oracle = _addressesProvider.getPriceOracle();
|
||||
|
||||
|
@ -854,7 +855,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
|
||||
bool isFirstBorrowing = false;
|
||||
if (
|
||||
ReserveLogic.InterestRateMode(vars.interestRateMode) == ReserveLogic.InterestRateMode.STABLE
|
||||
DataTypes.InterestRateMode(vars.interestRateMode) == DataTypes.InterestRateMode.STABLE
|
||||
) {
|
||||
currentStableRate = reserve.currentStableBorrowRate;
|
||||
|
||||
|
@ -894,7 +895,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
vars.onBehalfOf,
|
||||
vars.amount,
|
||||
vars.interestRateMode,
|
||||
ReserveLogic.InterestRateMode(vars.interestRateMode) == ReserveLogic.InterestRateMode.STABLE
|
||||
DataTypes.InterestRateMode(vars.interestRateMode) == DataTypes.InterestRateMode.STABLE
|
||||
? currentStableRate
|
||||
: reserve.currentVariableBorrowRate,
|
||||
vars.referralCode
|
||||
|
|
|
@ -10,8 +10,6 @@ import {IVariableDebtToken} from '../tokenization/interfaces/IVariableDebtToken.
|
|||
import {IPriceOracleGetter} from '../../interfaces/IPriceOracleGetter.sol';
|
||||
import {ILendingPoolCollateralManager} from '../../interfaces/ILendingPoolCollateralManager.sol';
|
||||
import {GenericLogic} from '../libraries/logic/GenericLogic.sol';
|
||||
import {ReserveLogic} from '../libraries/logic/ReserveLogic.sol';
|
||||
import {UserConfiguration} from '../libraries/configuration/UserConfiguration.sol';
|
||||
import {Helpers} from '../libraries/helpers/Helpers.sol';
|
||||
import {WadRayMath} from '../libraries/math/WadRayMath.sol';
|
||||
import {PercentageMath} from '../libraries/math/PercentageMath.sol';
|
||||
|
@ -19,82 +17,76 @@ import {SafeERC20} from '../../dependencies/openzeppelin/contracts/SafeERC20.sol
|
|||
import {Errors} from '../libraries/helpers/Errors.sol';
|
||||
import {ValidationLogic} from '../libraries/logic/ValidationLogic.sol';
|
||||
import {LendingPoolStorage} from './LendingPoolStorage.sol';
|
||||
import {DataTypes} from '../libraries/types/DataTypes.sol';
|
||||
|
||||
/**
|
||||
* @title LendingPoolCollateralManager contract
|
||||
* @author Aave
|
||||
* @notice Implements actions involving management of collateral in the protocol.
|
||||
* @notice this contract will be ran always through delegatecall
|
||||
* @dev LendingPoolCollateralManager inherits VersionedInitializable from OpenZeppelin to have the same storage layout as LendingPool
|
||||
* @dev Implements actions involving management of collateral in the protocol, the main one being the liquidations
|
||||
* IMPORTANT This contract will run always via DELEGATECALL, through the LendingPool, so the chain of inheritance
|
||||
* is the same as the LendingPool, to have compatible storage layouts
|
||||
**/
|
||||
contract LendingPoolCollateralManager is ILendingPoolCollateralManager, VersionedInitializable, LendingPoolStorage {
|
||||
contract LendingPoolCollateralManager is
|
||||
ILendingPoolCollateralManager,
|
||||
VersionedInitializable,
|
||||
LendingPoolStorage
|
||||
{
|
||||
using SafeERC20 for IERC20;
|
||||
using SafeMath for uint256;
|
||||
using WadRayMath for uint256;
|
||||
using PercentageMath for uint256;
|
||||
|
||||
// IMPORTANT The storage layout of the LendingPool is reproduced here because this contract
|
||||
// is gonna be used through DELEGATECALL
|
||||
|
||||
uint256 internal constant LIQUIDATION_CLOSE_FACTOR_PERCENT = 5000;
|
||||
|
||||
struct LiquidationCallLocalVars {
|
||||
uint256 userCollateralBalance;
|
||||
uint256 userStableDebt;
|
||||
uint256 userVariableDebt;
|
||||
uint256 maxPrincipalAmountToLiquidate;
|
||||
uint256 actualAmountToLiquidate;
|
||||
uint256 maxLiquidatableDebt;
|
||||
uint256 actualDebtToLiquidate;
|
||||
uint256 liquidationRatio;
|
||||
uint256 maxAmountCollateralToLiquidate;
|
||||
uint256 userStableRate;
|
||||
uint256 maxCollateralToLiquidate;
|
||||
uint256 principalAmountNeeded;
|
||||
uint256 debtAmountNeeded;
|
||||
uint256 healthFactor;
|
||||
IAToken collateralAtoken;
|
||||
bool isCollateralEnabled;
|
||||
ReserveLogic.InterestRateMode borrowRateMode;
|
||||
address principalAToken;
|
||||
DataTypes.InterestRateMode borrowRateMode;
|
||||
uint256 errorCode;
|
||||
string errorMsg;
|
||||
}
|
||||
|
||||
struct AvailableCollateralToLiquidateLocalVars {
|
||||
uint256 userCompoundedBorrowBalance;
|
||||
uint256 liquidationBonus;
|
||||
uint256 collateralPrice;
|
||||
uint256 principalCurrencyPrice;
|
||||
uint256 maxAmountCollateralToLiquidate;
|
||||
uint256 principalDecimals;
|
||||
uint256 collateralDecimals;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev as the contract extends the VersionedInitializable contract to match the state
|
||||
* of the LendingPool contract, the getRevision() function is needed.
|
||||
* @dev As thIS contract extends the VersionedInitializable contract to match the state
|
||||
* of the LendingPool contract, the getRevision() function is needed, but the value is not
|
||||
* important, as the initialize() function will never be called here
|
||||
*/
|
||||
function getRevision() internal pure override returns (uint256) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev users can invoke this function to liquidate an undercollateralized position.
|
||||
* @param collateral the address of the collateral to liquidated
|
||||
* @param principal the address of the principal reserve
|
||||
* @param user the address of the borrower
|
||||
* @param debtToCover the amount of principal that the liquidator wants to repay
|
||||
* @param receiveAToken true if the liquidators wants to receive the aTokens, false if
|
||||
* he wants to receive the underlying asset directly
|
||||
* @dev Function to liquidate a position if its Health Factor drops below 1
|
||||
* - The caller (liquidator) covers `debtToCover` amount of debt of the user getting liquidated, and receives
|
||||
* a proportionally amount of the `collateralAsset` plus a bonus to cover market risk
|
||||
* @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation
|
||||
* @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation
|
||||
* @param user The address of the borrower getting liquidated
|
||||
* @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover
|
||||
* @param receiveAToken `true` if the liquidators wants to receive the collateral aTokens, `false` if he wants
|
||||
* to receive the underlying collateral asset directly
|
||||
**/
|
||||
function liquidationCall(
|
||||
address collateral,
|
||||
address principal,
|
||||
address collateralAsset,
|
||||
address debtAsset,
|
||||
address user,
|
||||
uint256 debtToCover,
|
||||
bool receiveAToken
|
||||
) external override returns (uint256, string memory) {
|
||||
ReserveLogic.ReserveData storage collateralReserve = _reserves[collateral];
|
||||
ReserveLogic.ReserveData storage principalReserve = _reserves[principal];
|
||||
UserConfiguration.Map storage userConfig = _usersConfig[user];
|
||||
DataTypes.ReserveData storage collateralReserve = _reserves[collateralAsset];
|
||||
DataTypes.ReserveData storage debtReserve = _reserves[debtAsset];
|
||||
DataTypes.UserConfigurationMap storage userConfig = _usersConfig[user];
|
||||
|
||||
LiquidationCallLocalVars memory vars;
|
||||
|
||||
|
@ -107,15 +99,11 @@ contract LendingPoolCollateralManager is ILendingPoolCollateralManager, Versione
|
|||
_addressesProvider.getPriceOracle()
|
||||
);
|
||||
|
||||
//if the user hasn't borrowed the specific currency defined by asset, it cannot be liquidated
|
||||
(vars.userStableDebt, vars.userVariableDebt) = Helpers.getUserCurrentDebt(
|
||||
user,
|
||||
principalReserve
|
||||
);
|
||||
(vars.userStableDebt, vars.userVariableDebt) = Helpers.getUserCurrentDebt(user, debtReserve);
|
||||
|
||||
(vars.errorCode, vars.errorMsg) = ValidationLogic.validateLiquidationCall(
|
||||
collateralReserve,
|
||||
principalReserve,
|
||||
debtReserve,
|
||||
userConfig,
|
||||
vars.healthFactor,
|
||||
vars.userStableDebt,
|
||||
|
@ -130,38 +118,39 @@ contract LendingPoolCollateralManager is ILendingPoolCollateralManager, Versione
|
|||
|
||||
vars.userCollateralBalance = vars.collateralAtoken.balanceOf(user);
|
||||
|
||||
vars.maxPrincipalAmountToLiquidate = vars.userStableDebt.add(vars.userVariableDebt).percentMul(
|
||||
vars.maxLiquidatableDebt = vars.userStableDebt.add(vars.userVariableDebt).percentMul(
|
||||
LIQUIDATION_CLOSE_FACTOR_PERCENT
|
||||
);
|
||||
|
||||
vars.actualAmountToLiquidate = debtToCover > vars.maxPrincipalAmountToLiquidate
|
||||
? vars.maxPrincipalAmountToLiquidate
|
||||
vars.actualDebtToLiquidate = debtToCover > vars.maxLiquidatableDebt
|
||||
? vars.maxLiquidatableDebt
|
||||
: debtToCover;
|
||||
|
||||
(
|
||||
vars.maxCollateralToLiquidate,
|
||||
vars.principalAmountNeeded
|
||||
vars.debtAmountNeeded
|
||||
) = _calculateAvailableCollateralToLiquidate(
|
||||
collateralReserve,
|
||||
principalReserve,
|
||||
collateral,
|
||||
principal,
|
||||
vars.actualAmountToLiquidate,
|
||||
debtReserve,
|
||||
collateralAsset,
|
||||
debtAsset,
|
||||
vars.actualDebtToLiquidate,
|
||||
vars.userCollateralBalance
|
||||
);
|
||||
|
||||
//if principalAmountNeeded < vars.ActualAmountToLiquidate, there isn't enough
|
||||
//of collateral to cover the actual amount that is being liquidated, hence we liquidate
|
||||
//a smaller amount
|
||||
// If debtAmountNeeded < actualDebtToLiquidate, there isn't enough
|
||||
// collateral to cover the actual amount that is being liquidated, hence we liquidate
|
||||
// a smaller amount
|
||||
|
||||
if (vars.principalAmountNeeded < vars.actualAmountToLiquidate) {
|
||||
vars.actualAmountToLiquidate = vars.principalAmountNeeded;
|
||||
if (vars.debtAmountNeeded < vars.actualDebtToLiquidate) {
|
||||
vars.actualDebtToLiquidate = vars.debtAmountNeeded;
|
||||
}
|
||||
|
||||
//if liquidator reclaims the underlying asset, we make sure there is enough available collateral in the reserve
|
||||
// If the liquidator reclaims the underlying asset, we make sure there is enough available liquidity in the
|
||||
// collateral reserve
|
||||
if (!receiveAToken) {
|
||||
uint256 currentAvailableCollateral =
|
||||
IERC20(collateral).balanceOf(address(vars.collateralAtoken));
|
||||
IERC20(collateralAsset).balanceOf(address(vars.collateralAtoken));
|
||||
if (currentAvailableCollateral < vars.maxCollateralToLiquidate) {
|
||||
return (
|
||||
uint256(Errors.CollateralManagerErrors.NOT_ENOUGH_LIQUIDITY),
|
||||
|
@ -170,54 +159,48 @@ contract LendingPoolCollateralManager is ILendingPoolCollateralManager, Versione
|
|||
}
|
||||
}
|
||||
|
||||
//update the principal reserve
|
||||
principalReserve.updateState();
|
||||
debtReserve.updateState();
|
||||
|
||||
if (vars.userVariableDebt >= vars.actualAmountToLiquidate) {
|
||||
IVariableDebtToken(principalReserve.variableDebtTokenAddress).burn(
|
||||
if (vars.userVariableDebt >= vars.actualDebtToLiquidate) {
|
||||
IVariableDebtToken(debtReserve.variableDebtTokenAddress).burn(
|
||||
user,
|
||||
vars.actualAmountToLiquidate,
|
||||
principalReserve.variableBorrowIndex
|
||||
vars.actualDebtToLiquidate,
|
||||
debtReserve.variableBorrowIndex
|
||||
);
|
||||
} else {
|
||||
//if the user does not have variable debt, no need to try to burn variable
|
||||
//debt tokens
|
||||
// If the user doesn't have variable debt, no need to try to burn variable debt tokens
|
||||
if (vars.userVariableDebt > 0) {
|
||||
IVariableDebtToken(principalReserve.variableDebtTokenAddress).burn(
|
||||
IVariableDebtToken(debtReserve.variableDebtTokenAddress).burn(
|
||||
user,
|
||||
vars.userVariableDebt,
|
||||
principalReserve.variableBorrowIndex
|
||||
debtReserve.variableBorrowIndex
|
||||
);
|
||||
}
|
||||
IStableDebtToken(principalReserve.stableDebtTokenAddress).burn(
|
||||
IStableDebtToken(debtReserve.stableDebtTokenAddress).burn(
|
||||
user,
|
||||
vars.actualAmountToLiquidate.sub(vars.userVariableDebt)
|
||||
vars.actualDebtToLiquidate.sub(vars.userVariableDebt)
|
||||
);
|
||||
}
|
||||
|
||||
principalReserve.updateInterestRates(
|
||||
principal,
|
||||
principalReserve.aTokenAddress,
|
||||
vars.actualAmountToLiquidate,
|
||||
debtReserve.updateInterestRates(
|
||||
debtAsset,
|
||||
debtReserve.aTokenAddress,
|
||||
vars.actualDebtToLiquidate,
|
||||
0
|
||||
);
|
||||
|
||||
//if liquidator reclaims the aToken, he receives the equivalent atoken amount
|
||||
if (receiveAToken) {
|
||||
vars.collateralAtoken.transferOnLiquidation(user, msg.sender, vars.maxCollateralToLiquidate);
|
||||
} else {
|
||||
//otherwise receives the underlying asset
|
||||
|
||||
//updating collateral reserve
|
||||
collateralReserve.updateState();
|
||||
collateralReserve.updateInterestRates(
|
||||
collateral,
|
||||
collateralAsset,
|
||||
address(vars.collateralAtoken),
|
||||
0,
|
||||
vars.maxCollateralToLiquidate
|
||||
);
|
||||
|
||||
//burn the equivalent amount of atoken
|
||||
// Burn the equivalent amount of aToken, sending the underlying to the liquidator
|
||||
vars.collateralAtoken.burn(
|
||||
user,
|
||||
msg.sender,
|
||||
|
@ -226,26 +209,25 @@ contract LendingPoolCollateralManager is ILendingPoolCollateralManager, Versione
|
|||
);
|
||||
}
|
||||
|
||||
//if the collateral being liquidated is equal to the user balance,
|
||||
//we set the currency as not being used as collateral anymore
|
||||
|
||||
// If the collateral being liquidated is equal to the user balance,
|
||||
// we set the currency as not being used as collateral anymore
|
||||
if (vars.maxCollateralToLiquidate == vars.userCollateralBalance) {
|
||||
userConfig.setUsingAsCollateral(collateralReserve.id, false);
|
||||
emit ReserveUsedAsCollateralDisabled(collateral, user);
|
||||
emit ReserveUsedAsCollateralDisabled(collateralAsset, user);
|
||||
}
|
||||
|
||||
//transfers the principal currency to the aToken
|
||||
IERC20(principal).safeTransferFrom(
|
||||
// Transfers the debt asset being repaid to the aToken, where the liquidity is kept
|
||||
IERC20(debtAsset).safeTransferFrom(
|
||||
msg.sender,
|
||||
principalReserve.aTokenAddress,
|
||||
vars.actualAmountToLiquidate
|
||||
debtReserve.aTokenAddress,
|
||||
vars.actualDebtToLiquidate
|
||||
);
|
||||
|
||||
emit LiquidationCall(
|
||||
collateral,
|
||||
principal,
|
||||
collateralAsset,
|
||||
debtAsset,
|
||||
user,
|
||||
vars.actualAmountToLiquidate,
|
||||
vars.actualDebtToLiquidate,
|
||||
vars.maxCollateralToLiquidate,
|
||||
msg.sender,
|
||||
receiveAToken
|
||||
|
@ -254,60 +236,74 @@ contract LendingPoolCollateralManager is ILendingPoolCollateralManager, Versione
|
|||
return (uint256(Errors.CollateralManagerErrors.NO_ERROR), Errors.LPCM_NO_ERRORS);
|
||||
}
|
||||
|
||||
struct AvailableCollateralToLiquidateLocalVars {
|
||||
uint256 userCompoundedBorrowBalance;
|
||||
uint256 liquidationBonus;
|
||||
uint256 collateralPrice;
|
||||
uint256 debtAssetPrice;
|
||||
uint256 maxAmountCollateralToLiquidate;
|
||||
uint256 debtAssetDecimals;
|
||||
uint256 collateralDecimals;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev calculates how much of a specific collateral can be liquidated, given
|
||||
* a certain amount of principal currency. This function needs to be called after
|
||||
* all the checks to validate the liquidation have been performed, otherwise it might fail.
|
||||
* @param collateralAddress the collateral to be liquidated
|
||||
* @param principalAddress the principal currency to be liquidated
|
||||
* @param debtToCover the amount of principal being liquidated
|
||||
* @param userCollateralBalance the collatera balance for the specific collateral asset of the user being liquidated
|
||||
* @return collateralAmount the maximum amount that is possible to liquidated given all the liquidation constraints (user balance, close factor)
|
||||
* @return principalAmountNeeded the purchase amount
|
||||
* @dev Calculates how much of a specific collateral can be liquidated, given
|
||||
* a certain amount of debt asset.
|
||||
* - This function needs to be called after all the checks to validate the liquidation have been performed,
|
||||
* otherwise it might fail.
|
||||
* @param collateralReserve The data of the collateral reserve
|
||||
* @param debtReserve The data of the debt reserve
|
||||
* @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation
|
||||
* @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation
|
||||
* @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover
|
||||
* @param userCollateralBalance The collateral balance for the specific `collateralAsset` of the user being liquidated
|
||||
* @return collateralAmount: The maximum amount that is possible to liquidate given all the liquidation constraints
|
||||
* (user balance, close factor)
|
||||
* debtAmountNeeded: The amount to repay with the liquidation
|
||||
**/
|
||||
function _calculateAvailableCollateralToLiquidate(
|
||||
ReserveLogic.ReserveData storage collateralReserve,
|
||||
ReserveLogic.ReserveData storage principalReserve,
|
||||
address collateralAddress,
|
||||
address principalAddress,
|
||||
DataTypes.ReserveData storage collateralReserve,
|
||||
DataTypes.ReserveData storage debtReserve,
|
||||
address collateralAsset,
|
||||
address debtAsset,
|
||||
uint256 debtToCover,
|
||||
uint256 userCollateralBalance
|
||||
) internal view returns (uint256, uint256) {
|
||||
uint256 collateralAmount = 0;
|
||||
uint256 principalAmountNeeded = 0;
|
||||
uint256 debtAmountNeeded = 0;
|
||||
IPriceOracleGetter oracle = IPriceOracleGetter(_addressesProvider.getPriceOracle());
|
||||
|
||||
AvailableCollateralToLiquidateLocalVars memory vars;
|
||||
|
||||
vars.collateralPrice = oracle.getAssetPrice(collateralAddress);
|
||||
vars.principalCurrencyPrice = oracle.getAssetPrice(principalAddress);
|
||||
vars.collateralPrice = oracle.getAssetPrice(collateralAsset);
|
||||
vars.debtAssetPrice = oracle.getAssetPrice(debtAsset);
|
||||
|
||||
(, , vars.liquidationBonus, vars.collateralDecimals, ) = collateralReserve
|
||||
.configuration
|
||||
.getParams();
|
||||
vars.principalDecimals = principalReserve.configuration.getDecimals();
|
||||
vars.debtAssetDecimals = debtReserve.configuration.getDecimals();
|
||||
|
||||
//this is the maximum possible amount of the selected collateral that can be liquidated, given the
|
||||
//max amount of principal currency that is available for liquidation.
|
||||
// This is the maximum possible amount of the selected collateral that can be liquidated, given the
|
||||
// max amount of liquidatable debt
|
||||
vars.maxAmountCollateralToLiquidate = vars
|
||||
.principalCurrencyPrice
|
||||
.debtAssetPrice
|
||||
.mul(debtToCover)
|
||||
.mul(10**vars.collateralDecimals)
|
||||
.percentMul(vars.liquidationBonus)
|
||||
.div(vars.collateralPrice.mul(10**vars.principalDecimals));
|
||||
.div(vars.collateralPrice.mul(10**vars.debtAssetDecimals));
|
||||
|
||||
if (vars.maxAmountCollateralToLiquidate > userCollateralBalance) {
|
||||
collateralAmount = userCollateralBalance;
|
||||
principalAmountNeeded = vars
|
||||
debtAmountNeeded = vars
|
||||
.collateralPrice
|
||||
.mul(collateralAmount)
|
||||
.mul(10**vars.principalDecimals)
|
||||
.div(vars.principalCurrencyPrice.mul(10**vars.collateralDecimals))
|
||||
.mul(10**vars.debtAssetDecimals)
|
||||
.div(vars.debtAssetPrice.mul(10**vars.collateralDecimals))
|
||||
.percentDiv(vars.liquidationBonus);
|
||||
} else {
|
||||
collateralAmount = vars.maxAmountCollateralToLiquidate;
|
||||
principalAmountNeeded = debtToCover;
|
||||
debtAmountNeeded = debtToCover;
|
||||
}
|
||||
return (collateralAmount, principalAmountNeeded);
|
||||
return (collateralAmount, debtAmountNeeded);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,26 +14,26 @@ import {ITokenConfiguration} from '../tokenization/interfaces/ITokenConfiguratio
|
|||
import {IERC20Detailed} from '../../dependencies/openzeppelin/contracts/IERC20Detailed.sol';
|
||||
import {Errors} from '../libraries/helpers/Errors.sol';
|
||||
import {PercentageMath} from '../libraries/math/PercentageMath.sol';
|
||||
import {ReserveLogic} from '../libraries/logic/ReserveLogic.sol';
|
||||
import {DataTypes} from '../libraries/types/DataTypes.sol';
|
||||
|
||||
/**
|
||||
* @title LendingPoolConfigurator contract
|
||||
* @author Aave
|
||||
* @notice Executes configuration methods on the LendingPoolCore contract. Allows to enable/disable reserves
|
||||
* and set different protocol parameters.
|
||||
* @dev Implements the configuration methods for the Aave protocol
|
||||
**/
|
||||
|
||||
contract LendingPoolConfigurator is VersionedInitializable {
|
||||
using SafeMath for uint256;
|
||||
using ReserveConfiguration for ReserveConfiguration.Map;
|
||||
using PercentageMath for uint256;
|
||||
using ReserveConfiguration for DataTypes.ReserveConfigurationMap;
|
||||
|
||||
/**
|
||||
* @dev emitted when a reserve is initialized.
|
||||
* @param asset the address of the reserve
|
||||
* @param aToken the address of the overlying aToken contract
|
||||
* @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
|
||||
* @dev Emitted when a reserve is initialized.
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
* @param aToken The address of the associated aToken contract
|
||||
* @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(
|
||||
address indexed asset,
|
||||
|
@ -44,24 +44,24 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
);
|
||||
|
||||
/**
|
||||
* @dev emitted when borrowing is enabled on a reserve
|
||||
* @param asset the address of the reserve
|
||||
* @param stableRateEnabled true if stable rate borrowing is enabled, false otherwise
|
||||
* @dev Emitted when borrowing is enabled on a reserve
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
* @param stableRateEnabled True if stable rate borrowing is enabled, false otherwise
|
||||
**/
|
||||
event BorrowingEnabledOnReserve(address indexed asset, bool stableRateEnabled);
|
||||
|
||||
/**
|
||||
* @dev emitted when borrowing is disabled on a reserve
|
||||
* @param asset the address of the reserve
|
||||
* @dev Emitted when borrowing is disabled on a reserve
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
**/
|
||||
event BorrowingDisabledOnReserve(address indexed asset);
|
||||
|
||||
/**
|
||||
* @dev emitted when a a reserve collateralization risk parameters are updated.
|
||||
* @param asset the address of the reserve
|
||||
* @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 liquidationBonus the bonus liquidators receive to liquidate this asset
|
||||
* @dev Emitted when the collateralization risk parameters for the specified asset are updated.
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
* @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 liquidationBonus The bonus liquidators receive to liquidate this asset
|
||||
**/
|
||||
event CollateralConfigurationChanged(
|
||||
address indexed asset,
|
||||
|
@ -71,67 +71,67 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
);
|
||||
|
||||
/**
|
||||
* @dev emitted when stable rate borrowing is enabled on a reserve
|
||||
* @param asset the address of the reserve
|
||||
* @dev Emitted when stable rate borrowing is enabled on a reserve
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
**/
|
||||
event StableRateEnabledOnReserve(address indexed asset);
|
||||
|
||||
/**
|
||||
* @dev emitted when stable rate borrowing is disabled on a reserve
|
||||
* @param asset the address of the reserve
|
||||
* @dev Emitted when stable rate borrowing is disabled on a reserve
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
**/
|
||||
event StableRateDisabledOnReserve(address indexed asset);
|
||||
|
||||
/**
|
||||
* @dev emitted when a reserve is activated
|
||||
* @param asset the address of the reserve
|
||||
* @dev Emitted when a reserve is activated
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
**/
|
||||
event ReserveActivated(address indexed asset);
|
||||
|
||||
/**
|
||||
* @dev emitted when a reserve is deactivated
|
||||
* @param asset the address of the reserve
|
||||
* @dev Emitted when a reserve is deactivated
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
**/
|
||||
event ReserveDeactivated(address indexed asset);
|
||||
|
||||
/**
|
||||
* @dev emitted when a reserve is frozen
|
||||
* @param asset the address of the reserve
|
||||
* @dev Emitted when a reserve is frozen
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
**/
|
||||
event ReserveFrozen(address indexed asset);
|
||||
|
||||
/**
|
||||
* @dev emitted when a reserve is unfrozen
|
||||
* @param asset the address of the reserve
|
||||
* @dev Emitted when a reserve is unfrozen
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
**/
|
||||
event ReserveUnfrozen(address indexed asset);
|
||||
|
||||
/**
|
||||
* @dev emitted when a reserve factor is updated
|
||||
* @param asset the address of the reserve
|
||||
* @param factor the new reserve factor
|
||||
* @dev Emitted when a reserve factor is updated
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
* @param factor The new reserve factor
|
||||
**/
|
||||
event ReserveFactorChanged(address indexed asset, uint256 factor);
|
||||
|
||||
/**
|
||||
* @dev emitted when the reserve decimals are updated
|
||||
* @param asset the address of the reserve
|
||||
* @param decimals the new decimals
|
||||
* @dev Emitted when the reserve decimals are updated
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
* @param decimals The new decimals
|
||||
**/
|
||||
event ReserveDecimalsChanged(address indexed asset, uint256 decimals);
|
||||
|
||||
/**
|
||||
* @dev emitted when a reserve interest strategy contract is updated
|
||||
* @param asset the address of the reserve
|
||||
* @param strategy the new address of the interest strategy contract
|
||||
* @dev Emitted when a reserve interest strategy contract is updated
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
* @param strategy The new address of the interest strategy contract
|
||||
**/
|
||||
event ReserveInterestRateStrategyChanged(address indexed asset, address strategy);
|
||||
|
||||
/**
|
||||
* @dev emitted when an aToken implementation is upgraded
|
||||
* @param asset the address of the reserve
|
||||
* @param proxy the aToken proxy address
|
||||
* @param implementation the new aToken implementation
|
||||
* @dev Emitted when an aToken implementation is upgraded
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
* @param proxy The aToken proxy address
|
||||
* @param implementation The new aToken implementation
|
||||
**/
|
||||
event ATokenUpgraded(
|
||||
address indexed asset,
|
||||
|
@ -140,10 +140,10 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
);
|
||||
|
||||
/**
|
||||
* @dev emitted when the implementation of a stable debt token is upgraded
|
||||
* @param asset the address of the reserve
|
||||
* @param proxy the stable debt token proxy address
|
||||
* @param implementation the new aToken implementation
|
||||
* @dev Emitted when the implementation of a stable debt token is upgraded
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
* @param proxy The stable debt token proxy address
|
||||
* @param implementation The new aToken implementation
|
||||
**/
|
||||
event StableDebtTokenUpgraded(
|
||||
address indexed asset,
|
||||
|
@ -152,10 +152,10 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
);
|
||||
|
||||
/**
|
||||
* @dev emitted when the implementation of a variable debt token is upgraded
|
||||
* @param asset the address of the reserve
|
||||
* @param proxy the variable debt token proxy address
|
||||
* @param implementation the new aToken implementation
|
||||
* @dev Emitted when the implementation of a variable debt token is upgraded
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
* @param proxy The variable debt token proxy address
|
||||
* @param implementation The new aToken implementation
|
||||
**/
|
||||
event VariableDebtTokenUpgraded(
|
||||
address indexed asset,
|
||||
|
@ -166,17 +166,11 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
ILendingPoolAddressesProvider internal addressesProvider;
|
||||
ILendingPool internal pool;
|
||||
|
||||
/**
|
||||
* @dev only the pool admin can call functions affected by this modifier
|
||||
**/
|
||||
modifier onlyPoolAdmin {
|
||||
require(addressesProvider.getPoolAdmin() == msg.sender, Errors.CALLER_NOT_POOL_ADMIN);
|
||||
_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev only the emergency admin can call functions affected by this modifier
|
||||
**/
|
||||
modifier onlyEmergencyAdmin {
|
||||
require(
|
||||
addressesProvider.getEmergencyAdmin() == msg.sender,
|
||||
|
@ -185,7 +179,7 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
_;
|
||||
}
|
||||
|
||||
uint256 internal constant CONFIGURATOR_REVISION = 0x3;
|
||||
uint256 internal constant CONFIGURATOR_REVISION = 0x1;
|
||||
|
||||
function getRevision() internal pure override returns (uint256) {
|
||||
return CONFIGURATOR_REVISION;
|
||||
|
@ -197,12 +191,12 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
}
|
||||
|
||||
/**
|
||||
* @dev initializes a reserve
|
||||
* @param aTokenImpl the address of the aToken contract implementation
|
||||
* @param stableDebtTokenImpl the address of the stable debt token contract
|
||||
* @param variableDebtTokenImpl the address of the variable debt token contract
|
||||
* @param underlyingAssetDecimals the decimals of the reserve underlying asset
|
||||
* @param interestRateStrategyAddress the address of the interest rate strategy contract for this reserve
|
||||
* @dev Initializes a reserve
|
||||
* @param aTokenImpl The address of the aToken contract implementation
|
||||
* @param stableDebtTokenImpl The address of the stable debt token contract
|
||||
* @param variableDebtTokenImpl The address of the variable debt token contract
|
||||
* @param underlyingAssetDecimals The decimals of the reserve underlying asset
|
||||
* @param interestRateStrategyAddress The address of the interest rate strategy contract for this reserve
|
||||
**/
|
||||
function initReserve(
|
||||
address aTokenImpl,
|
||||
|
@ -250,7 +244,7 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
interestRateStrategyAddress
|
||||
);
|
||||
|
||||
ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset);
|
||||
DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset);
|
||||
|
||||
currentConfig.setDecimals(underlyingAssetDecimals);
|
||||
|
||||
|
@ -269,12 +263,12 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
}
|
||||
|
||||
/**
|
||||
* @dev updates the aToken implementation for the asset
|
||||
* @param asset the address of the reserve to be updated
|
||||
* @param implementation the address of the new aToken implementation
|
||||
* @dev Updates the aToken implementation for the reserve
|
||||
* @param asset The address of the underlying asset of the reserve to be updated
|
||||
* @param implementation The address of the new aToken implementation
|
||||
**/
|
||||
function updateAToken(address asset, address implementation) external onlyPoolAdmin {
|
||||
ReserveLogic.ReserveData memory reserveData = pool.getReserveData(asset);
|
||||
DataTypes.ReserveData memory reserveData = pool.getReserveData(asset);
|
||||
|
||||
_upgradeTokenImplementation(asset, reserveData.aTokenAddress, implementation);
|
||||
|
||||
|
@ -282,12 +276,12 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
}
|
||||
|
||||
/**
|
||||
* @dev updates the stable debt token implementation for the asset
|
||||
* @param asset the address of the reserve to be updated
|
||||
* @param implementation the address of the new aToken implementation
|
||||
* @dev Updates the stable debt token implementation for the reserve
|
||||
* @param asset The address of the underlying asset of the reserve to be updated
|
||||
* @param implementation The address of the new aToken implementation
|
||||
**/
|
||||
function updateStableDebtToken(address asset, address implementation) external onlyPoolAdmin {
|
||||
ReserveLogic.ReserveData memory reserveData = pool.getReserveData(asset);
|
||||
DataTypes.ReserveData memory reserveData = pool.getReserveData(asset);
|
||||
|
||||
_upgradeTokenImplementation(asset, reserveData.stableDebtTokenAddress, implementation);
|
||||
|
||||
|
@ -295,12 +289,12 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
}
|
||||
|
||||
/**
|
||||
* @dev updates the variable debt token implementation for the asset
|
||||
* @param asset the address of the reserve to be updated
|
||||
* @param implementation the address of the new aToken implementation
|
||||
* @dev Updates the variable debt token implementation for the asset
|
||||
* @param asset The address of the underlying asset of the reserve to be updated
|
||||
* @param implementation The address of the new aToken implementation
|
||||
**/
|
||||
function updateVariableDebtToken(address asset, address implementation) external onlyPoolAdmin {
|
||||
ReserveLogic.ReserveData memory reserveData = pool.getReserveData(asset);
|
||||
DataTypes.ReserveData memory reserveData = pool.getReserveData(asset);
|
||||
|
||||
_upgradeTokenImplementation(asset, reserveData.variableDebtTokenAddress, implementation);
|
||||
|
||||
|
@ -308,15 +302,15 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
}
|
||||
|
||||
/**
|
||||
* @dev enables borrowing on a reserve
|
||||
* @param asset the address of the reserve
|
||||
* @param stableBorrowRateEnabled true if stable borrow rate needs to be enabled by default on this reserve
|
||||
* @dev Enables borrowing on a reserve
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
* @param stableBorrowRateEnabled True if stable borrow rate needs to be enabled by default on this reserve
|
||||
**/
|
||||
function enableBorrowingOnReserve(address asset, bool stableBorrowRateEnabled)
|
||||
external
|
||||
onlyPoolAdmin
|
||||
{
|
||||
ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset);
|
||||
DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset);
|
||||
|
||||
currentConfig.setBorrowingEnabled(true);
|
||||
currentConfig.setStableRateBorrowingEnabled(stableBorrowRateEnabled);
|
||||
|
@ -327,11 +321,11 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
}
|
||||
|
||||
/**
|
||||
* @dev disables borrowing on a reserve
|
||||
* @param asset the address of the reserve
|
||||
* @dev Disables borrowing on a reserve
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
**/
|
||||
function disableBorrowingOnReserve(address asset) external onlyPoolAdmin {
|
||||
ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset);
|
||||
DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset);
|
||||
|
||||
currentConfig.setBorrowingEnabled(false);
|
||||
|
||||
|
@ -340,12 +334,12 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
}
|
||||
|
||||
/**
|
||||
* @dev configures the reserve collateralization parameters.
|
||||
* @dev Configures the reserve collateralization parameters
|
||||
* all the values are expressed in percentages with two decimals of precision. A valid value is 10000, which means 100.00%
|
||||
* @param asset the address of the reserve
|
||||
* @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 liquidationBonus the bonus liquidators receive to liquidate this asset. The values is always above 100%. A value of 105%
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
* @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 liquidationBonus The bonus liquidators receive to liquidate this asset. The values is always above 100%. A value of 105%
|
||||
* means the liquidator will receive a 5% bonus
|
||||
**/
|
||||
function configureReserveAsCollateral(
|
||||
|
@ -354,7 +348,7 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
uint256 liquidationThreshold,
|
||||
uint256 liquidationBonus
|
||||
) external onlyPoolAdmin {
|
||||
ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset);
|
||||
DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset);
|
||||
|
||||
//validation of the parameters: the LTV can
|
||||
//only be lower or equal than the liquidation threshold
|
||||
|
@ -363,15 +357,16 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
|
||||
if (liquidationThreshold != 0) {
|
||||
//liquidation bonus must be bigger than 100.00%, otherwise the liquidator would receive less
|
||||
//collateral than needed to cover the debt.
|
||||
uint256 absoluteBonus =
|
||||
liquidationBonus.sub(PercentageMath.PERCENTAGE_FACTOR, Errors.LPC_INVALID_CONFIGURATION);
|
||||
require(absoluteBonus > 0, Errors.LPC_INVALID_CONFIGURATION);
|
||||
|
||||
//we also need to require that the liq threshold is lower or equal than the liquidation bonus, to ensure that
|
||||
//there is always enough margin for liquidators to receive the bonus.
|
||||
//collateral than needed to cover the debt
|
||||
require(
|
||||
liquidationThreshold.add(absoluteBonus) <= PercentageMath.PERCENTAGE_FACTOR,
|
||||
liquidationBonus > PercentageMath.PERCENTAGE_FACTOR,
|
||||
Errors.LPC_INVALID_CONFIGURATION
|
||||
);
|
||||
|
||||
//if threshold * bonus is less than PERCENTAGE_FACTOR, it's guaranteed that at the moment
|
||||
//a loan is taken there is enough collateral available to cover the liquidation bonus
|
||||
require(
|
||||
liquidationThreshold.percentMul(liquidationBonus) <= PercentageMath.PERCENTAGE_FACTOR,
|
||||
Errors.LPC_INVALID_CONFIGURATION
|
||||
);
|
||||
} else {
|
||||
|
@ -392,11 +387,11 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
}
|
||||
|
||||
/**
|
||||
* @dev enable stable rate borrowing on a reserve
|
||||
* @param asset the address of the reserve
|
||||
* @dev Enable stable rate borrowing on a reserve
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
**/
|
||||
function enableReserveStableRate(address asset) external onlyPoolAdmin {
|
||||
ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset);
|
||||
DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset);
|
||||
|
||||
currentConfig.setStableRateBorrowingEnabled(true);
|
||||
|
||||
|
@ -406,11 +401,11 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
}
|
||||
|
||||
/**
|
||||
* @dev disable stable rate borrowing on a reserve
|
||||
* @param asset the address of the reserve
|
||||
* @dev Disable stable rate borrowing on a reserve
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
**/
|
||||
function disableReserveStableRate(address asset) external onlyPoolAdmin {
|
||||
ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset);
|
||||
DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset);
|
||||
|
||||
currentConfig.setStableRateBorrowingEnabled(false);
|
||||
|
||||
|
@ -420,11 +415,11 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
}
|
||||
|
||||
/**
|
||||
* @dev activates a reserve
|
||||
* @param asset the address of the reserve
|
||||
* @dev Activates a reserve
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
**/
|
||||
function activateReserve(address asset) external onlyPoolAdmin {
|
||||
ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset);
|
||||
DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset);
|
||||
|
||||
currentConfig.setActive(true);
|
||||
|
||||
|
@ -434,13 +429,13 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
}
|
||||
|
||||
/**
|
||||
* @dev deactivates a reserve
|
||||
* @param asset the address of the reserve
|
||||
* @dev Deactivates a reserve
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
**/
|
||||
function deactivateReserve(address asset) external onlyPoolAdmin {
|
||||
_checkNoLiquidity(asset);
|
||||
|
||||
ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset);
|
||||
DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset);
|
||||
|
||||
currentConfig.setActive(false);
|
||||
|
||||
|
@ -450,11 +445,12 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
}
|
||||
|
||||
/**
|
||||
* @dev freezes a reserve. A frozen reserve doesn't accept any new deposit, borrow or rate swap, but can accept repayments, liquidations, rate rebalances and redeems
|
||||
* @param asset the address of the reserve
|
||||
* @dev Freezes a reserve. A frozen reserve doesn't allow any new deposit, borrow or rate swap
|
||||
* but allows repayments, liquidations, rate rebalances and withdrawals
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
**/
|
||||
function freezeReserve(address asset) external onlyPoolAdmin {
|
||||
ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset);
|
||||
DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset);
|
||||
|
||||
currentConfig.setFrozen(true);
|
||||
|
||||
|
@ -464,11 +460,11 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
}
|
||||
|
||||
/**
|
||||
* @dev unfreezes a reserve
|
||||
* @param asset the address of the reserve
|
||||
* @dev Unfreezes a reserve
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
**/
|
||||
function unfreezeReserve(address asset) external onlyPoolAdmin {
|
||||
ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset);
|
||||
DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset);
|
||||
|
||||
currentConfig.setFrozen(false);
|
||||
|
||||
|
@ -478,12 +474,12 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
}
|
||||
|
||||
/**
|
||||
* @dev updates the reserve factor of a reserve
|
||||
* @param asset the address of the reserve
|
||||
* @param reserveFactor the new reserve factor of the reserve
|
||||
* @dev Updates the reserve factor of a reserve
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
* @param reserveFactor The new reserve factor of the reserve
|
||||
**/
|
||||
function setReserveFactor(address asset, uint256 reserveFactor) external onlyPoolAdmin {
|
||||
ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset);
|
||||
DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset);
|
||||
|
||||
currentConfig.setReserveFactor(reserveFactor);
|
||||
|
||||
|
@ -493,9 +489,9 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
}
|
||||
|
||||
/**
|
||||
* @dev sets the interest rate strategy of a reserve
|
||||
* @param asset the address of the reserve
|
||||
* @param rateStrategyAddress the new address of the interest strategy contract
|
||||
* @dev Sets the interest rate strategy of a reserve
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
* @param rateStrategyAddress The new address of the interest strategy contract
|
||||
**/
|
||||
function setReserveInterestRateStrategyAddress(address asset, address rateStrategyAddress)
|
||||
external
|
||||
|
@ -506,10 +502,13 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
}
|
||||
|
||||
/**
|
||||
* @dev initializes a token with a proxy and a specific implementation
|
||||
* @param implementation the address of the implementation
|
||||
* @param decimals the decimals of the token
|
||||
* @dev pauses or unpauses all the actions of the protocol, including aToken transfers
|
||||
* @param val true if protocol needs to be paused, false otherwise
|
||||
**/
|
||||
function setPoolPause(bool val) external onlyEmergencyAdmin {
|
||||
pool.setPause(val);
|
||||
}
|
||||
|
||||
function _initTokenWithProxy(address implementation, uint8 decimals) internal returns (address) {
|
||||
InitializableImmutableAdminUpgradeabilityProxy proxy =
|
||||
new InitializableImmutableAdminUpgradeabilityProxy(address(this));
|
||||
|
@ -535,7 +534,7 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
InitializableImmutableAdminUpgradeabilityProxy proxy =
|
||||
InitializableImmutableAdminUpgradeabilityProxy(payable(proxyAddress));
|
||||
|
||||
ReserveConfiguration.Map memory configuration = pool.getConfiguration(asset);
|
||||
DataTypes.ReserveConfigurationMap memory configuration = pool.getConfiguration(asset);
|
||||
|
||||
(, , , uint256 decimals, ) = configuration.getParamsMemory();
|
||||
|
||||
|
@ -550,16 +549,8 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
proxy.upgradeToAndCall(implementation, params);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev pauses or unpauses LendingPool actions
|
||||
* @param val the boolean value to set the current pause state of LendingPool
|
||||
**/
|
||||
function setPoolPause(bool val) external onlyEmergencyAdmin {
|
||||
pool.setPause(val);
|
||||
}
|
||||
|
||||
function _checkNoLiquidity(address asset) internal view {
|
||||
ReserveLogic.ReserveData memory reserveData = pool.getReserveData(asset);
|
||||
DataTypes.ReserveData memory reserveData = pool.getReserveData(asset);
|
||||
|
||||
uint256 availableLiquidity = IERC20Detailed(asset).balanceOf(reserveData.aTokenAddress);
|
||||
|
||||
|
|
|
@ -5,16 +5,17 @@ import {UserConfiguration} from '../libraries/configuration/UserConfiguration.so
|
|||
import {ReserveConfiguration} from '../libraries/configuration/ReserveConfiguration.sol';
|
||||
import {ReserveLogic} from '../libraries/logic/ReserveLogic.sol';
|
||||
import {ILendingPoolAddressesProvider} from '../../interfaces/ILendingPoolAddressesProvider.sol';
|
||||
import {DataTypes} from '../libraries/types/DataTypes.sol';
|
||||
|
||||
contract LendingPoolStorage {
|
||||
using ReserveLogic for ReserveLogic.ReserveData;
|
||||
using ReserveConfiguration for ReserveConfiguration.Map;
|
||||
using UserConfiguration for UserConfiguration.Map;
|
||||
using ReserveLogic for DataTypes.ReserveData;
|
||||
using ReserveConfiguration for DataTypes.ReserveConfigurationMap;
|
||||
using UserConfiguration for DataTypes.UserConfigurationMap;
|
||||
|
||||
ILendingPoolAddressesProvider internal _addressesProvider;
|
||||
|
||||
mapping(address => ReserveLogic.ReserveData) internal _reserves;
|
||||
mapping(address => UserConfiguration.Map) internal _usersConfig;
|
||||
mapping(address => DataTypes.ReserveData) internal _reserves;
|
||||
mapping(address => DataTypes.UserConfigurationMap) internal _usersConfig;
|
||||
|
||||
// the list of the available reserves, structured as a mapping for gas savings reasons
|
||||
mapping(uint256 => address) internal _reservesList;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
pragma solidity 0.6.12;
|
||||
|
||||
import {Errors} from '../helpers/Errors.sol';
|
||||
import {DataTypes} from '../types/DataTypes.sol';
|
||||
|
||||
/**
|
||||
* @title ReserveConfiguration library
|
||||
|
@ -35,26 +36,12 @@ library ReserveConfiguration {
|
|||
uint256 constant MAX_VALID_DECIMALS = 255;
|
||||
uint256 constant MAX_VALID_RESERVE_FACTOR = 65535;
|
||||
|
||||
struct Map {
|
||||
//bit 0-15: LTV
|
||||
//bit 16-31: Liq. threshold
|
||||
//bit 32-47: Liq. bonus
|
||||
//bit 48-55: Decimals
|
||||
//bit 56: Reserve is active
|
||||
//bit 57: reserve is frozen
|
||||
//bit 58: borrowing is enabled
|
||||
//bit 59: stable rate borrowing enabled
|
||||
//bit 60-63: reserved
|
||||
//bit 64-79: reserve factor
|
||||
uint256 data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev sets the Loan to Value of the reserve
|
||||
* @param self the reserve configuration
|
||||
* @param ltv the new ltv
|
||||
**/
|
||||
function setLtv(ReserveConfiguration.Map memory self, uint256 ltv) internal pure {
|
||||
function setLtv(DataTypes.ReserveConfigurationMap memory self, uint256 ltv) internal pure {
|
||||
require(ltv <= MAX_VALID_LTV, Errors.RC_INVALID_LTV);
|
||||
|
||||
self.data = (self.data & LTV_MASK) | ltv;
|
||||
|
@ -65,7 +52,7 @@ library ReserveConfiguration {
|
|||
* @param self the reserve configuration
|
||||
* @return the loan to value
|
||||
**/
|
||||
function getLtv(ReserveConfiguration.Map storage self) internal view returns (uint256) {
|
||||
function getLtv(DataTypes.ReserveConfigurationMap storage self) internal view returns (uint256) {
|
||||
return self.data & ~LTV_MASK;
|
||||
}
|
||||
|
||||
|
@ -74,7 +61,7 @@ library ReserveConfiguration {
|
|||
* @param self the reserve configuration
|
||||
* @param threshold the new liquidation threshold
|
||||
**/
|
||||
function setLiquidationThreshold(ReserveConfiguration.Map memory self, uint256 threshold)
|
||||
function setLiquidationThreshold(DataTypes.ReserveConfigurationMap memory self, uint256 threshold)
|
||||
internal
|
||||
pure
|
||||
{
|
||||
|
@ -90,7 +77,7 @@ library ReserveConfiguration {
|
|||
* @param self the reserve configuration
|
||||
* @return the liquidation threshold
|
||||
**/
|
||||
function getLiquidationThreshold(ReserveConfiguration.Map storage self)
|
||||
function getLiquidationThreshold(DataTypes.ReserveConfigurationMap storage self)
|
||||
internal
|
||||
view
|
||||
returns (uint256)
|
||||
|
@ -103,7 +90,7 @@ library ReserveConfiguration {
|
|||
* @param self the reserve configuration
|
||||
* @param bonus the new liquidation bonus
|
||||
**/
|
||||
function setLiquidationBonus(ReserveConfiguration.Map memory self, uint256 bonus) internal pure {
|
||||
function setLiquidationBonus(DataTypes.ReserveConfigurationMap memory self, uint256 bonus) internal pure {
|
||||
require(bonus <= MAX_VALID_LIQUIDATION_BONUS, Errors.RC_INVALID_LIQ_BONUS);
|
||||
|
||||
self.data =
|
||||
|
@ -116,7 +103,7 @@ library ReserveConfiguration {
|
|||
* @param self the reserve configuration
|
||||
* @return the liquidation bonus
|
||||
**/
|
||||
function getLiquidationBonus(ReserveConfiguration.Map storage self)
|
||||
function getLiquidationBonus(DataTypes.ReserveConfigurationMap storage self)
|
||||
internal
|
||||
view
|
||||
returns (uint256)
|
||||
|
@ -129,7 +116,7 @@ library ReserveConfiguration {
|
|||
* @param self the reserve configuration
|
||||
* @param decimals the decimals
|
||||
**/
|
||||
function setDecimals(ReserveConfiguration.Map memory self, uint256 decimals) internal pure {
|
||||
function setDecimals(DataTypes.ReserveConfigurationMap memory self, uint256 decimals) internal pure {
|
||||
require(decimals <= MAX_VALID_DECIMALS, Errors.RC_INVALID_DECIMALS);
|
||||
|
||||
self.data = (self.data & DECIMALS_MASK) | (decimals << RESERVE_DECIMALS_START_BIT_POSITION);
|
||||
|
@ -140,7 +127,7 @@ library ReserveConfiguration {
|
|||
* @param self the reserve configuration
|
||||
* @return the decimals of the asset
|
||||
**/
|
||||
function getDecimals(ReserveConfiguration.Map storage self) internal view returns (uint256) {
|
||||
function getDecimals(DataTypes.ReserveConfigurationMap storage self) internal view returns (uint256) {
|
||||
return (self.data & ~DECIMALS_MASK) >> RESERVE_DECIMALS_START_BIT_POSITION;
|
||||
}
|
||||
|
||||
|
@ -149,7 +136,7 @@ library ReserveConfiguration {
|
|||
* @param self the reserve configuration
|
||||
* @param active the active state
|
||||
**/
|
||||
function setActive(ReserveConfiguration.Map memory self, bool active) internal pure {
|
||||
function setActive(DataTypes.ReserveConfigurationMap memory self, bool active) internal pure {
|
||||
self.data =
|
||||
(self.data & ACTIVE_MASK) |
|
||||
(uint256(active ? 1 : 0) << IS_ACTIVE_START_BIT_POSITION);
|
||||
|
@ -160,7 +147,7 @@ library ReserveConfiguration {
|
|||
* @param self the reserve configuration
|
||||
* @return the active state
|
||||
**/
|
||||
function getActive(ReserveConfiguration.Map storage self) internal view returns (bool) {
|
||||
function getActive(DataTypes.ReserveConfigurationMap storage self) internal view returns (bool) {
|
||||
return (self.data & ~ACTIVE_MASK) != 0;
|
||||
}
|
||||
|
||||
|
@ -169,7 +156,7 @@ library ReserveConfiguration {
|
|||
* @param self the reserve configuration
|
||||
* @param frozen the frozen state
|
||||
**/
|
||||
function setFrozen(ReserveConfiguration.Map memory self, bool frozen) internal pure {
|
||||
function setFrozen(DataTypes.ReserveConfigurationMap memory self, bool frozen) internal pure {
|
||||
self.data =
|
||||
(self.data & FROZEN_MASK) |
|
||||
(uint256(frozen ? 1 : 0) << IS_FROZEN_START_BIT_POSITION);
|
||||
|
@ -180,7 +167,7 @@ library ReserveConfiguration {
|
|||
* @param self the reserve configuration
|
||||
* @return the frozen state
|
||||
**/
|
||||
function getFrozen(ReserveConfiguration.Map storage self) internal view returns (bool) {
|
||||
function getFrozen(DataTypes.ReserveConfigurationMap storage self) internal view returns (bool) {
|
||||
return (self.data & ~FROZEN_MASK) != 0;
|
||||
}
|
||||
|
||||
|
@ -189,7 +176,7 @@ library ReserveConfiguration {
|
|||
* @param self the reserve configuration
|
||||
* @param enabled true if the borrowing needs to be enabled, false otherwise
|
||||
**/
|
||||
function setBorrowingEnabled(ReserveConfiguration.Map memory self, bool enabled) internal pure {
|
||||
function setBorrowingEnabled(DataTypes.ReserveConfigurationMap memory self, bool enabled) internal pure {
|
||||
self.data =
|
||||
(self.data & BORROWING_MASK) |
|
||||
(uint256(enabled ? 1 : 0) << BORROWING_ENABLED_START_BIT_POSITION);
|
||||
|
@ -200,7 +187,7 @@ library ReserveConfiguration {
|
|||
* @param self the reserve configuration
|
||||
* @return the borrowing state
|
||||
**/
|
||||
function getBorrowingEnabled(ReserveConfiguration.Map storage self) internal view returns (bool) {
|
||||
function getBorrowingEnabled(DataTypes.ReserveConfigurationMap storage self) internal view returns (bool) {
|
||||
return (self.data & ~BORROWING_MASK) != 0;
|
||||
}
|
||||
|
||||
|
@ -209,7 +196,7 @@ library ReserveConfiguration {
|
|||
* @param self the reserve configuration
|
||||
* @param enabled true if the stable rate borrowing needs to be enabled, false otherwise
|
||||
**/
|
||||
function setStableRateBorrowingEnabled(ReserveConfiguration.Map memory self, bool enabled)
|
||||
function setStableRateBorrowingEnabled(DataTypes.ReserveConfigurationMap memory self, bool enabled)
|
||||
internal
|
||||
pure
|
||||
{
|
||||
|
@ -223,7 +210,7 @@ library ReserveConfiguration {
|
|||
* @param self the reserve configuration
|
||||
* @return the stable rate borrowing state
|
||||
**/
|
||||
function getStableRateBorrowingEnabled(ReserveConfiguration.Map storage self)
|
||||
function getStableRateBorrowingEnabled(DataTypes.ReserveConfigurationMap storage self)
|
||||
internal
|
||||
view
|
||||
returns (bool)
|
||||
|
@ -236,7 +223,7 @@ library ReserveConfiguration {
|
|||
* @param self the reserve configuration
|
||||
* @param reserveFactor the reserve factor
|
||||
**/
|
||||
function setReserveFactor(ReserveConfiguration.Map memory self, uint256 reserveFactor)
|
||||
function setReserveFactor(DataTypes.ReserveConfigurationMap memory self, uint256 reserveFactor)
|
||||
internal
|
||||
pure
|
||||
{
|
||||
|
@ -252,7 +239,7 @@ library ReserveConfiguration {
|
|||
* @param self the reserve configuration
|
||||
* @return the reserve factor
|
||||
**/
|
||||
function getReserveFactor(ReserveConfiguration.Map storage self) internal view returns (uint256) {
|
||||
function getReserveFactor(DataTypes.ReserveConfigurationMap storage self) internal view returns (uint256) {
|
||||
return (self.data & ~RESERVE_FACTOR_MASK) >> RESERVE_FACTOR_START_BIT_POSITION;
|
||||
}
|
||||
|
||||
|
@ -261,7 +248,7 @@ library ReserveConfiguration {
|
|||
* @param self the reserve configuration
|
||||
* @return the state flags representing active, frozen, borrowing enabled, stableRateBorrowing enabled
|
||||
**/
|
||||
function getFlags(ReserveConfiguration.Map storage self)
|
||||
function getFlags(DataTypes.ReserveConfigurationMap storage self)
|
||||
internal
|
||||
view
|
||||
returns (
|
||||
|
@ -286,7 +273,7 @@ library ReserveConfiguration {
|
|||
* @param self the reserve configuration
|
||||
* @return the state params representing ltv, liquidation threshold, liquidation bonus, the reserve decimals
|
||||
**/
|
||||
function getParams(ReserveConfiguration.Map storage self)
|
||||
function getParams(DataTypes.ReserveConfigurationMap storage self)
|
||||
internal
|
||||
view
|
||||
returns (
|
||||
|
@ -313,7 +300,7 @@ library ReserveConfiguration {
|
|||
* @param self the reserve configuration
|
||||
* @return the state params representing ltv, liquidation threshold, liquidation bonus, the reserve decimals
|
||||
**/
|
||||
function getParamsMemory(ReserveConfiguration.Map memory self)
|
||||
function getParamsMemory(DataTypes.ReserveConfigurationMap memory self)
|
||||
internal
|
||||
pure
|
||||
returns (
|
||||
|
@ -338,7 +325,7 @@ library ReserveConfiguration {
|
|||
* @param self the reserve configuration
|
||||
* @return the state flags representing active, frozen, borrowing enabled, stableRateBorrowing enabled
|
||||
**/
|
||||
function getFlagsMemory(ReserveConfiguration.Map memory self)
|
||||
function getFlagsMemory(DataTypes.ReserveConfigurationMap memory self)
|
||||
internal
|
||||
pure
|
||||
returns (
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
pragma solidity 0.6.12;
|
||||
|
||||
import {Errors} from '../helpers/Errors.sol';
|
||||
import {DataTypes} from '../types/DataTypes.sol';
|
||||
|
||||
/**
|
||||
* @title UserConfiguration library
|
||||
|
@ -12,10 +13,6 @@ library UserConfiguration {
|
|||
uint256 internal constant BORROWING_MASK =
|
||||
0x5555555555555555555555555555555555555555555555555555555555555555;
|
||||
|
||||
struct Map {
|
||||
uint256 data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev sets if the user is borrowing the reserve identified by reserveIndex
|
||||
* @param self the configuration object
|
||||
|
@ -23,7 +20,7 @@ library UserConfiguration {
|
|||
* @param borrowing true if the user is borrowing the reserve, false otherwise
|
||||
**/
|
||||
function setBorrowing(
|
||||
UserConfiguration.Map storage self,
|
||||
DataTypes.UserConfigurationMap storage self,
|
||||
uint256 reserveIndex,
|
||||
bool borrowing
|
||||
) internal {
|
||||
|
@ -40,7 +37,7 @@ library UserConfiguration {
|
|||
* @param _usingAsCollateral true if the user is usin the reserve as collateral, false otherwise
|
||||
**/
|
||||
function setUsingAsCollateral(
|
||||
UserConfiguration.Map storage self,
|
||||
DataTypes.UserConfigurationMap storage self,
|
||||
uint256 reserveIndex,
|
||||
bool _usingAsCollateral
|
||||
) internal {
|
||||
|
@ -56,7 +53,7 @@ library UserConfiguration {
|
|||
* @param reserveIndex the index of the reserve in the bitmap
|
||||
* @return true if the user has been using a reserve for borrowing or as collateral, false otherwise
|
||||
**/
|
||||
function isUsingAsCollateralOrBorrowing(UserConfiguration.Map memory self, uint256 reserveIndex)
|
||||
function isUsingAsCollateralOrBorrowing(DataTypes.UserConfigurationMap memory self, uint256 reserveIndex)
|
||||
internal
|
||||
pure
|
||||
returns (bool)
|
||||
|
@ -71,7 +68,7 @@ library UserConfiguration {
|
|||
* @param reserveIndex the index of the reserve in the bitmap
|
||||
* @return true if the user has been using a reserve for borrowing, false otherwise
|
||||
**/
|
||||
function isBorrowing(UserConfiguration.Map memory self, uint256 reserveIndex)
|
||||
function isBorrowing(DataTypes.UserConfigurationMap memory self, uint256 reserveIndex)
|
||||
internal
|
||||
pure
|
||||
returns (bool)
|
||||
|
@ -86,7 +83,7 @@ library UserConfiguration {
|
|||
* @param reserveIndex the index of the reserve in the bitmap
|
||||
* @return true if the user has been using a reserve as collateral, false otherwise
|
||||
**/
|
||||
function isUsingAsCollateral(UserConfiguration.Map memory self, uint256 reserveIndex)
|
||||
function isUsingAsCollateral(DataTypes.UserConfigurationMap memory self, uint256 reserveIndex)
|
||||
internal
|
||||
pure
|
||||
returns (bool)
|
||||
|
@ -100,7 +97,7 @@ library UserConfiguration {
|
|||
* @param self the configuration object
|
||||
* @return true if the user has been borrowing any reserve, false otherwise
|
||||
**/
|
||||
function isBorrowingAny(UserConfiguration.Map memory self) internal pure returns (bool) {
|
||||
function isBorrowingAny(DataTypes.UserConfigurationMap memory self) internal pure returns (bool) {
|
||||
return self.data & BORROWING_MASK != 0;
|
||||
}
|
||||
|
||||
|
@ -109,7 +106,7 @@ library UserConfiguration {
|
|||
* @param self the configuration object
|
||||
* @return true if the user has been borrowing any reserve, false otherwise
|
||||
**/
|
||||
function isEmpty(UserConfiguration.Map memory self) internal pure returns (bool) {
|
||||
function isEmpty(DataTypes.UserConfigurationMap memory self) internal pure returns (bool) {
|
||||
return self.data == 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
import {DebtTokenBase} from '../../tokenization/base/DebtTokenBase.sol';
|
||||
import {ReserveLogic} from '../logic/ReserveLogic.sol';
|
||||
import {IERC20} from '../../../dependencies/openzeppelin/contracts/IERC20.sol';
|
||||
import {DataTypes} from '../types/DataTypes.sol';
|
||||
|
||||
/**
|
||||
* @title Helpers library
|
||||
|
@ -16,25 +16,25 @@ library Helpers {
|
|||
* @param reserve the reserve object
|
||||
* @return the stable and variable debt balance
|
||||
**/
|
||||
function getUserCurrentDebt(address user, ReserveLogic.ReserveData storage reserve)
|
||||
function getUserCurrentDebt(address user, DataTypes.ReserveData storage reserve)
|
||||
internal
|
||||
view
|
||||
returns (uint256, uint256)
|
||||
{
|
||||
return (
|
||||
DebtTokenBase(reserve.stableDebtTokenAddress).balanceOf(user),
|
||||
DebtTokenBase(reserve.variableDebtTokenAddress).balanceOf(user)
|
||||
IERC20(reserve.stableDebtTokenAddress).balanceOf(user),
|
||||
IERC20(reserve.variableDebtTokenAddress).balanceOf(user)
|
||||
);
|
||||
}
|
||||
|
||||
function getUserCurrentDebtMemory(address user, ReserveLogic.ReserveData memory reserve)
|
||||
function getUserCurrentDebtMemory(address user, DataTypes.ReserveData memory reserve)
|
||||
internal
|
||||
view
|
||||
returns (uint256, uint256)
|
||||
{
|
||||
return (
|
||||
DebtTokenBase(reserve.stableDebtTokenAddress).balanceOf(user),
|
||||
DebtTokenBase(reserve.variableDebtTokenAddress).balanceOf(user)
|
||||
IERC20(reserve.stableDebtTokenAddress).balanceOf(user),
|
||||
IERC20(reserve.variableDebtTokenAddress).balanceOf(user)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import {UserConfiguration} from '../configuration/UserConfiguration.sol';
|
|||
import {WadRayMath} from '../math/WadRayMath.sol';
|
||||
import {PercentageMath} from '../math/PercentageMath.sol';
|
||||
import {IPriceOracleGetter} from '../../../interfaces/IPriceOracleGetter.sol';
|
||||
import {DataTypes} from '../types/DataTypes.sol';
|
||||
|
||||
/**
|
||||
* @title GenericLogic library
|
||||
|
@ -17,12 +18,12 @@ import {IPriceOracleGetter} from '../../../interfaces/IPriceOracleGetter.sol';
|
|||
* @title Implements protocol-level logic to check the status of the user across all the reserves
|
||||
*/
|
||||
library GenericLogic {
|
||||
using ReserveLogic for ReserveLogic.ReserveData;
|
||||
using ReserveLogic for DataTypes.ReserveData;
|
||||
using SafeMath for uint256;
|
||||
using WadRayMath for uint256;
|
||||
using PercentageMath for uint256;
|
||||
using ReserveConfiguration for ReserveConfiguration.Map;
|
||||
using UserConfiguration for UserConfiguration.Map;
|
||||
using ReserveConfiguration for DataTypes.ReserveConfigurationMap;
|
||||
using UserConfiguration for DataTypes.UserConfigurationMap;
|
||||
|
||||
uint256 public constant HEALTH_FACTOR_LIQUIDATION_THRESHOLD = 1 ether;
|
||||
|
||||
|
@ -55,8 +56,8 @@ library GenericLogic {
|
|||
address asset,
|
||||
address user,
|
||||
uint256 amount,
|
||||
mapping(address => ReserveLogic.ReserveData) storage reservesData,
|
||||
UserConfiguration.Map calldata userConfig,
|
||||
mapping(address => DataTypes.ReserveData) storage reservesData,
|
||||
DataTypes.UserConfigurationMap calldata userConfig,
|
||||
mapping(uint256 => address) storage reserves,
|
||||
uint256 reservesCount,
|
||||
address oracle
|
||||
|
@ -150,8 +151,8 @@ library GenericLogic {
|
|||
**/
|
||||
function calculateUserAccountData(
|
||||
address user,
|
||||
mapping(address => ReserveLogic.ReserveData) storage reservesData,
|
||||
UserConfiguration.Map memory userConfig,
|
||||
mapping(address => DataTypes.ReserveData) storage reservesData,
|
||||
DataTypes.UserConfigurationMap memory userConfig,
|
||||
mapping(uint256 => address) storage reserves,
|
||||
uint256 reservesCount,
|
||||
address oracle
|
||||
|
@ -177,7 +178,7 @@ library GenericLogic {
|
|||
}
|
||||
|
||||
vars.currentReserveAddress = reserves[vars.i];
|
||||
ReserveLogic.ReserveData storage currentReserve = reservesData[vars.currentReserveAddress];
|
||||
DataTypes.ReserveData storage currentReserve = reservesData[vars.currentReserveAddress];
|
||||
|
||||
(vars.ltv, vars.liquidationThreshold, , vars.decimals, ) = currentReserve
|
||||
.configuration
|
||||
|
|
|
@ -13,6 +13,7 @@ import {IReserveInterestRateStrategy} from '../../../interfaces/IReserveInterest
|
|||
import {WadRayMath} from '../math/WadRayMath.sol';
|
||||
import {PercentageMath} from '../math/PercentageMath.sol';
|
||||
import {Errors} from '../helpers/Errors.sol';
|
||||
import {DataTypes} from '../types/DataTypes.sol';
|
||||
|
||||
/**
|
||||
* @title ReserveLogic library
|
||||
|
@ -43,35 +44,8 @@ library ReserveLogic {
|
|||
uint256 variableBorrowIndex
|
||||
);
|
||||
|
||||
using ReserveLogic for ReserveLogic.ReserveData;
|
||||
using ReserveConfiguration for ReserveConfiguration.Map;
|
||||
|
||||
enum InterestRateMode {NONE, STABLE, VARIABLE}
|
||||
|
||||
// refer to the whitepaper, section 1.1 basic concepts for a formal description of these properties.
|
||||
struct ReserveData {
|
||||
//stores the reserve configuration
|
||||
ReserveConfiguration.Map configuration;
|
||||
//the liquidity index. Expressed in ray
|
||||
uint128 liquidityIndex;
|
||||
//variable borrow index. Expressed in ray
|
||||
uint128 variableBorrowIndex;
|
||||
//the current supply rate. Expressed in ray
|
||||
uint128 currentLiquidityRate;
|
||||
//the current variable borrow rate. Expressed in ray
|
||||
uint128 currentVariableBorrowRate;
|
||||
//the current stable borrow rate. Expressed in ray
|
||||
uint128 currentStableBorrowRate;
|
||||
uint40 lastUpdateTimestamp;
|
||||
//tokens addresses
|
||||
address aTokenAddress;
|
||||
address stableDebtTokenAddress;
|
||||
address variableDebtTokenAddress;
|
||||
//address of the interest rate strategy
|
||||
address interestRateStrategyAddress;
|
||||
//the id of the reserve. Represents the position in the list of the active reserves
|
||||
uint8 id;
|
||||
}
|
||||
using ReserveLogic for DataTypes.ReserveData;
|
||||
using ReserveConfiguration for DataTypes.ReserveConfigurationMap;
|
||||
|
||||
/**
|
||||
* @dev returns the ongoing normalized income for the reserve.
|
||||
|
@ -80,7 +54,11 @@ library ReserveLogic {
|
|||
* @param reserve the reserve object
|
||||
* @return the normalized income. expressed in ray
|
||||
**/
|
||||
function getNormalizedIncome(ReserveData storage reserve) internal view returns (uint256) {
|
||||
function getNormalizedIncome(DataTypes.ReserveData storage reserve)
|
||||
internal
|
||||
view
|
||||
returns (uint256)
|
||||
{
|
||||
uint40 timestamp = reserve.lastUpdateTimestamp;
|
||||
|
||||
//solium-disable-next-line
|
||||
|
@ -104,7 +82,11 @@ library ReserveLogic {
|
|||
* @param reserve the reserve object
|
||||
* @return the normalized variable debt. expressed in ray
|
||||
**/
|
||||
function getNormalizedDebt(ReserveData storage reserve) internal view returns (uint256) {
|
||||
function getNormalizedDebt(DataTypes.ReserveData storage reserve)
|
||||
internal
|
||||
view
|
||||
returns (uint256)
|
||||
{
|
||||
uint40 timestamp = reserve.lastUpdateTimestamp;
|
||||
|
||||
//solium-disable-next-line
|
||||
|
@ -126,7 +108,7 @@ library ReserveLogic {
|
|||
* a formal specification.
|
||||
* @param reserve the reserve object
|
||||
**/
|
||||
function updateState(ReserveData storage reserve) internal {
|
||||
function updateState(DataTypes.ReserveData storage reserve) internal {
|
||||
uint256 scaledVariableDebt =
|
||||
IVariableDebtToken(reserve.variableDebtTokenAddress).scaledTotalSupply();
|
||||
uint256 previousVariableBorrowIndex = reserve.variableBorrowIndex;
|
||||
|
@ -160,7 +142,7 @@ library ReserveLogic {
|
|||
* @param amount the amount to accomulate
|
||||
**/
|
||||
function cumulateToLiquidityIndex(
|
||||
ReserveData storage reserve,
|
||||
DataTypes.ReserveData storage reserve,
|
||||
uint256 totalLiquidity,
|
||||
uint256 amount
|
||||
) internal {
|
||||
|
@ -181,7 +163,7 @@ library ReserveLogic {
|
|||
* @param interestRateStrategyAddress the address of the interest rate strategy contract
|
||||
**/
|
||||
function init(
|
||||
ReserveData storage reserve,
|
||||
DataTypes.ReserveData storage reserve,
|
||||
address aTokenAddress,
|
||||
address stableDebtTokenAddress,
|
||||
address variableDebtTokenAddress,
|
||||
|
@ -216,7 +198,7 @@ library ReserveLogic {
|
|||
* @param liquidityTaken the amount of liquidity taken from the protocol (redeem or borrow)
|
||||
**/
|
||||
function updateInterestRates(
|
||||
ReserveData storage reserve,
|
||||
DataTypes.ReserveData storage reserve,
|
||||
address reserveAddress,
|
||||
address aTokenAddress,
|
||||
uint256 liquidityAdded,
|
||||
|
@ -292,7 +274,7 @@ library ReserveLogic {
|
|||
* @param newVariableBorrowIndex the variable borrow index after the last accumulation of the interest
|
||||
**/
|
||||
function _mintToTreasury(
|
||||
ReserveData storage reserve,
|
||||
DataTypes.ReserveData storage reserve,
|
||||
uint256 scaledVariableDebt,
|
||||
uint256 previousVariableBorrowIndex,
|
||||
uint256 newLiquidityIndex,
|
||||
|
@ -352,7 +334,7 @@ library ReserveLogic {
|
|||
* @param variableBorrowIndex the last stored variable borrow index
|
||||
**/
|
||||
function _updateIndexes(
|
||||
ReserveData storage reserve,
|
||||
DataTypes.ReserveData storage reserve,
|
||||
uint256 scaledVariableDebt,
|
||||
uint256 liquidityIndex,
|
||||
uint256 variableBorrowIndex,
|
||||
|
|
|
@ -14,6 +14,7 @@ import {UserConfiguration} from '../configuration/UserConfiguration.sol';
|
|||
import {Errors} from '../helpers/Errors.sol';
|
||||
import {Helpers} from '../helpers/Helpers.sol';
|
||||
import {IReserveInterestRateStrategy} from '../../../interfaces/IReserveInterestRateStrategy.sol';
|
||||
import {DataTypes} from '../types/DataTypes.sol';
|
||||
|
||||
/**
|
||||
* @title ReserveLogic library
|
||||
|
@ -21,13 +22,13 @@ import {IReserveInterestRateStrategy} from '../../../interfaces/IReserveInterest
|
|||
* @notice Implements functions to validate specific action on the protocol.
|
||||
*/
|
||||
library ValidationLogic {
|
||||
using ReserveLogic for ReserveLogic.ReserveData;
|
||||
using ReserveLogic for DataTypes.ReserveData;
|
||||
using SafeMath for uint256;
|
||||
using WadRayMath for uint256;
|
||||
using PercentageMath for uint256;
|
||||
using SafeERC20 for IERC20;
|
||||
using ReserveConfiguration for ReserveConfiguration.Map;
|
||||
using UserConfiguration for UserConfiguration.Map;
|
||||
using ReserveConfiguration for DataTypes.ReserveConfigurationMap;
|
||||
using UserConfiguration for DataTypes.UserConfigurationMap;
|
||||
|
||||
uint256 public constant REBALANCE_UP_LIQUIDITY_RATE_THRESHOLD = 4000;
|
||||
uint256 public constant REBALANCE_UP_USAGE_RATIO_THRESHOLD = 0.95 * 1e27; //usage ratio of 95%
|
||||
|
@ -37,7 +38,7 @@ library ValidationLogic {
|
|||
* @param reserve the reserve state on which the user is depositing
|
||||
* @param amount the amount to be deposited
|
||||
*/
|
||||
function validateDeposit(ReserveLogic.ReserveData storage reserve, uint256 amount) external view {
|
||||
function validateDeposit(DataTypes.ReserveData storage reserve, uint256 amount) external view {
|
||||
(bool isActive, bool isFrozen, , ) = reserve.configuration.getFlags();
|
||||
|
||||
require(amount != 0, Errors.VL_INVALID_AMOUNT);
|
||||
|
@ -60,8 +61,8 @@ library ValidationLogic {
|
|||
address reserveAddress,
|
||||
uint256 amount,
|
||||
uint256 userBalance,
|
||||
mapping(address => ReserveLogic.ReserveData) storage reservesData,
|
||||
UserConfiguration.Map storage userConfig,
|
||||
mapping(address => DataTypes.ReserveData) storage reservesData,
|
||||
DataTypes.UserConfigurationMap storage userConfig,
|
||||
mapping(uint256 => address) storage reserves,
|
||||
uint256 reservesCount,
|
||||
address oracle
|
||||
|
@ -100,7 +101,7 @@ library ValidationLogic {
|
|||
uint256 availableLiquidity;
|
||||
uint256 finalUserBorrowRate;
|
||||
uint256 healthFactor;
|
||||
ReserveLogic.InterestRateMode rateMode;
|
||||
DataTypes.InterestRateMode rateMode;
|
||||
bool healthFactorBelowThreshold;
|
||||
bool isActive;
|
||||
bool isFrozen;
|
||||
|
@ -125,14 +126,14 @@ library ValidationLogic {
|
|||
|
||||
function validateBorrow(
|
||||
address asset,
|
||||
ReserveLogic.ReserveData storage reserve,
|
||||
DataTypes.ReserveData storage reserve,
|
||||
address userAddress,
|
||||
uint256 amount,
|
||||
uint256 amountInETH,
|
||||
uint256 interestRateMode,
|
||||
uint256 maxStableLoanPercent,
|
||||
mapping(address => ReserveLogic.ReserveData) storage reservesData,
|
||||
UserConfiguration.Map storage userConfig,
|
||||
mapping(address => DataTypes.ReserveData) storage reservesData,
|
||||
DataTypes.UserConfigurationMap storage userConfig,
|
||||
mapping(uint256 => address) storage reserves,
|
||||
uint256 reservesCount,
|
||||
address oracle
|
||||
|
@ -151,8 +152,8 @@ library ValidationLogic {
|
|||
|
||||
//validate interest rate mode
|
||||
require(
|
||||
uint256(ReserveLogic.InterestRateMode.VARIABLE) == interestRateMode ||
|
||||
uint256(ReserveLogic.InterestRateMode.STABLE) == interestRateMode,
|
||||
uint256(DataTypes.InterestRateMode.VARIABLE) == interestRateMode ||
|
||||
uint256(DataTypes.InterestRateMode.STABLE) == interestRateMode,
|
||||
Errors.VL_INVALID_INTEREST_RATE_MODE_SELECTED
|
||||
);
|
||||
|
||||
|
@ -197,7 +198,7 @@ library ValidationLogic {
|
|||
* liquidity
|
||||
**/
|
||||
|
||||
if (vars.rateMode == ReserveLogic.InterestRateMode.STABLE) {
|
||||
if (vars.rateMode == DataTypes.InterestRateMode.STABLE) {
|
||||
//check if the borrow mode is stable and if stable rate borrowing is enabled on this reserve
|
||||
|
||||
require(vars.stableRateBorrowingEnabled, Errors.VL_STABLE_BORROWING_NOT_ENABLED);
|
||||
|
@ -228,9 +229,9 @@ library ValidationLogic {
|
|||
* @param variableDebt the borrow balance of the user
|
||||
*/
|
||||
function validateRepay(
|
||||
ReserveLogic.ReserveData storage reserve,
|
||||
DataTypes.ReserveData storage reserve,
|
||||
uint256 amountSent,
|
||||
ReserveLogic.InterestRateMode rateMode,
|
||||
DataTypes.InterestRateMode rateMode,
|
||||
address onBehalfOf,
|
||||
uint256 stableDebt,
|
||||
uint256 variableDebt
|
||||
|
@ -243,9 +244,9 @@ library ValidationLogic {
|
|||
|
||||
require(
|
||||
(stableDebt > 0 &&
|
||||
ReserveLogic.InterestRateMode(rateMode) == ReserveLogic.InterestRateMode.STABLE) ||
|
||||
DataTypes.InterestRateMode(rateMode) == DataTypes.InterestRateMode.STABLE) ||
|
||||
(variableDebt > 0 &&
|
||||
ReserveLogic.InterestRateMode(rateMode) == ReserveLogic.InterestRateMode.VARIABLE),
|
||||
DataTypes.InterestRateMode(rateMode) == DataTypes.InterestRateMode.VARIABLE),
|
||||
Errors.VL_NO_DEBT_OF_SELECTED_TYPE
|
||||
);
|
||||
|
||||
|
@ -264,20 +265,20 @@ library ValidationLogic {
|
|||
* @param currentRateMode the rate mode of the borrow
|
||||
*/
|
||||
function validateSwapRateMode(
|
||||
ReserveLogic.ReserveData storage reserve,
|
||||
UserConfiguration.Map storage userConfig,
|
||||
DataTypes.ReserveData storage reserve,
|
||||
DataTypes.UserConfigurationMap storage userConfig,
|
||||
uint256 stableDebt,
|
||||
uint256 variableDebt,
|
||||
ReserveLogic.InterestRateMode currentRateMode
|
||||
DataTypes.InterestRateMode currentRateMode
|
||||
) external view {
|
||||
(bool isActive, bool isFrozen, , bool stableRateEnabled) = reserve.configuration.getFlags();
|
||||
|
||||
require(isActive, Errors.VL_NO_ACTIVE_RESERVE);
|
||||
require(!isFrozen, Errors.VL_RESERVE_FROZEN);
|
||||
|
||||
if (currentRateMode == ReserveLogic.InterestRateMode.STABLE) {
|
||||
if (currentRateMode == DataTypes.InterestRateMode.STABLE) {
|
||||
require(stableDebt > 0, Errors.VL_NO_STABLE_RATE_LOAN_IN_RESERVE);
|
||||
} else if (currentRateMode == ReserveLogic.InterestRateMode.VARIABLE) {
|
||||
} else if (currentRateMode == DataTypes.InterestRateMode.VARIABLE) {
|
||||
require(variableDebt > 0, Errors.VL_NO_VARIABLE_RATE_LOAN_IN_RESERVE);
|
||||
/**
|
||||
* user wants to swap to stable, before swapping we need to ensure that
|
||||
|
@ -308,7 +309,7 @@ library ValidationLogic {
|
|||
* @param aTokenAddress the address of the aToken contract
|
||||
*/
|
||||
function validateRebalanceStableBorrowRate(
|
||||
ReserveLogic.ReserveData storage reserve,
|
||||
DataTypes.ReserveData storage reserve,
|
||||
address reserveAddress,
|
||||
IERC20 stableDebtToken,
|
||||
IERC20 variableDebtToken,
|
||||
|
@ -349,11 +350,11 @@ library ValidationLogic {
|
|||
* @param oracle the price oracle
|
||||
*/
|
||||
function validateSetUseReserveAsCollateral(
|
||||
ReserveLogic.ReserveData storage reserve,
|
||||
DataTypes.ReserveData storage reserve,
|
||||
address reserveAddress,
|
||||
bool useAsCollateral,
|
||||
mapping(address => ReserveLogic.ReserveData) storage reservesData,
|
||||
UserConfiguration.Map storage userConfig,
|
||||
mapping(address => DataTypes.ReserveData) storage reservesData,
|
||||
DataTypes.UserConfigurationMap storage userConfig,
|
||||
mapping(uint256 => address) storage reserves,
|
||||
uint256 reservesCount,
|
||||
address oracle
|
||||
|
@ -397,9 +398,9 @@ library ValidationLogic {
|
|||
* @param userVariableDebt Total variable debt balance of the user
|
||||
**/
|
||||
function validateLiquidationCall(
|
||||
ReserveLogic.ReserveData storage collateralReserve,
|
||||
ReserveLogic.ReserveData storage principalReserve,
|
||||
UserConfiguration.Map storage userConfig,
|
||||
DataTypes.ReserveData storage collateralReserve,
|
||||
DataTypes.ReserveData storage principalReserve,
|
||||
DataTypes.UserConfigurationMap storage userConfig,
|
||||
uint256 userHealthFactor,
|
||||
uint256 userStableDebt,
|
||||
uint256 userVariableDebt
|
||||
|
@ -452,8 +453,8 @@ library ValidationLogic {
|
|||
*/
|
||||
function validateTransfer(
|
||||
address from,
|
||||
mapping(address => ReserveLogic.ReserveData) storage reservesData,
|
||||
UserConfiguration.Map storage userConfig,
|
||||
mapping(address => DataTypes.ReserveData) storage reservesData,
|
||||
DataTypes.UserConfigurationMap storage userConfig,
|
||||
mapping(uint256 => address) storage reserves,
|
||||
uint256 reservesCount,
|
||||
address oracle
|
||||
|
|
49
contracts/protocol/libraries/types/DataTypes.sol
Normal file
49
contracts/protocol/libraries/types/DataTypes.sol
Normal file
|
@ -0,0 +1,49 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
library DataTypes {
|
||||
// refer to the whitepaper, section 1.1 basic concepts for a formal description of these properties.
|
||||
struct ReserveData {
|
||||
//stores the reserve configuration
|
||||
ReserveConfigurationMap configuration;
|
||||
//the liquidity index. Expressed in ray
|
||||
uint128 liquidityIndex;
|
||||
//variable borrow index. Expressed in ray
|
||||
uint128 variableBorrowIndex;
|
||||
//the current supply rate. Expressed in ray
|
||||
uint128 currentLiquidityRate;
|
||||
//the current variable borrow rate. Expressed in ray
|
||||
uint128 currentVariableBorrowRate;
|
||||
//the current stable borrow rate. Expressed in ray
|
||||
uint128 currentStableBorrowRate;
|
||||
uint40 lastUpdateTimestamp;
|
||||
//tokens addresses
|
||||
address aTokenAddress;
|
||||
address stableDebtTokenAddress;
|
||||
address variableDebtTokenAddress;
|
||||
//address of the interest rate strategy
|
||||
address interestRateStrategyAddress;
|
||||
//the id of the reserve. Represents the position in the list of the active reserves
|
||||
uint8 id;
|
||||
}
|
||||
|
||||
struct ReserveConfigurationMap {
|
||||
//bit 0-15: LTV
|
||||
//bit 16-31: Liq. threshold
|
||||
//bit 32-47: Liq. bonus
|
||||
//bit 48-55: Decimals
|
||||
//bit 56: Reserve is active
|
||||
//bit 57: reserve is frozen
|
||||
//bit 58: borrowing is enabled
|
||||
//bit 59: stable rate borrowing enabled
|
||||
//bit 60-63: reserved
|
||||
//bit 64-79: reserve factor
|
||||
uint256 data;
|
||||
}
|
||||
|
||||
struct UserConfigurationMap {
|
||||
uint256 data;
|
||||
}
|
||||
|
||||
enum InterestRateMode {NONE, STABLE, VARIABLE}
|
||||
}
|
|
@ -1,16 +1,12 @@
|
|||
pragma solidity 0.6.12;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import {
|
||||
ReserveConfiguration
|
||||
} from '../../contracts/protocol/libraries/configuration/ReserveConfiguration.sol';
|
||||
import {UserConfiguration} from '../../contracts/protocol/libraries/configuration/UserConfiguration.sol';
|
||||
import {ReserveLogic} from '../../contracts/protocol/libraries/logic/ReserveLogic.sol';
|
||||
import {ILendingPool} from '../../contracts/interfaces/ILendingPool.sol';
|
||||
import {LendingPool} from '../../contracts/protocol/lendingpool/LendingPool.sol';
|
||||
import {
|
||||
ILendingPoolAddressesProvider
|
||||
} from '../../contracts/interfaces/ILendingPoolAddressesProvider.sol';
|
||||
import {DataTypes} from '../protocol/libraries/types/DataTypes.sol';
|
||||
|
||||
/*
|
||||
Certora: Harness that delegates calls to the original LendingPool.
|
||||
|
@ -77,24 +73,24 @@ contract LendingPoolHarnessForVariableDebtToken is ILendingPool {
|
|||
originalPool.liquidationCall(collateral, asset, user, debtToCover, receiveAToken);
|
||||
}
|
||||
|
||||
function getReservesList() external override view returns (address[] memory) {
|
||||
function getReservesList() external view override returns (address[] memory) {
|
||||
return originalPool.getReservesList();
|
||||
}
|
||||
|
||||
function getReserveData(address asset)
|
||||
external
|
||||
override
|
||||
view
|
||||
returns (ReserveLogic.ReserveData memory)
|
||||
override
|
||||
returns (DataTypes.ReserveData memory)
|
||||
{
|
||||
return originalPool.getReserveData(asset);
|
||||
}
|
||||
|
||||
function getUserConfiguration(address user)
|
||||
external
|
||||
override
|
||||
view
|
||||
returns (UserConfiguration.Map memory)
|
||||
override
|
||||
returns (DataTypes.UserConfigurationMap memory)
|
||||
{
|
||||
return originalPool.getUserConfiguration(user);
|
||||
}
|
||||
|
@ -144,16 +140,16 @@ contract LendingPoolHarnessForVariableDebtToken is ILendingPool {
|
|||
|
||||
function getConfiguration(address asset)
|
||||
external
|
||||
override
|
||||
view
|
||||
returns (ReserveConfiguration.Map memory)
|
||||
override
|
||||
returns (DataTypes.ReserveConfigurationMap memory)
|
||||
{
|
||||
return originalPool.getConfiguration(asset);
|
||||
}
|
||||
|
||||
mapping(uint256 => uint256) private reserveNormalizedIncome;
|
||||
|
||||
function getReserveNormalizedIncome(address asset) external override view returns (uint256) {
|
||||
function getReserveNormalizedIncome(address asset) external view override returns (uint256) {
|
||||
require(reserveNormalizedIncome[block.timestamp] == 1e27);
|
||||
return reserveNormalizedIncome[block.timestamp];
|
||||
}
|
||||
|
@ -162,8 +158,8 @@ contract LendingPoolHarnessForVariableDebtToken is ILendingPool {
|
|||
|
||||
function getReserveNormalizedVariableDebt(address asset)
|
||||
external
|
||||
override
|
||||
view
|
||||
override
|
||||
returns (uint256)
|
||||
{
|
||||
require(reserveNormalizedVariableDebt[block.timestamp] == 1e27);
|
||||
|
@ -174,7 +170,7 @@ contract LendingPoolHarnessForVariableDebtToken is ILendingPool {
|
|||
originalPool.setPause(val);
|
||||
}
|
||||
|
||||
function paused() external override view returns (bool) {
|
||||
function paused() external view override returns (bool) {
|
||||
return originalPool.paused();
|
||||
}
|
||||
|
||||
|
@ -201,7 +197,7 @@ contract LendingPoolHarnessForVariableDebtToken is ILendingPool {
|
|||
originalPool.finalizeTransfer(asset, from, to, amount, balanceFromAfter, balanceToBefore);
|
||||
}
|
||||
|
||||
function getAddressesProvider() external override view returns (ILendingPoolAddressesProvider) {
|
||||
function getAddressesProvider() external view override returns (ILendingPoolAddressesProvider) {
|
||||
return originalPool.getAddressesProvider();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ import {UserConfiguration} from '../../contracts/protocol/libraries/configuratio
|
|||
A wrapper contract for calling functions from the library UserConfiguration.
|
||||
*/
|
||||
contract UserConfigurationHarness {
|
||||
UserConfiguration.Map internal usersConfig;
|
||||
DataTypes.UserConfigurationMap internal usersConfig;
|
||||
|
||||
function setBorrowing(
|
||||
address user,
|
||||
|
|
Loading…
Reference in New Issue
Block a user