Merge branch 'master' into feat/10

This commit is contained in:
emilio 2020-08-07 19:32:34 +02:00
commit 50bb9d39b0
13 changed files with 269 additions and 196 deletions

View File

@ -12,10 +12,11 @@ import '../configuration/LendingPoolAddressesProvider.sol';
import '../tokenization/AToken.sol';
import '../libraries/WadRayMath.sol';
import '../libraries/ReserveLogic.sol';
import '../libraries/UserLogic.sol';
import '../libraries/Helpers.sol';
import '../libraries/GenericLogic.sol';
import '../libraries/ValidationLogic.sol';
import '../libraries/ReserveConfiguration.sol';
import '../libraries/UserConfiguration.sol';
import '../libraries/UniversalERC20.sol';
import '../tokenization/interfaces/IStableDebtToken.sol';
import '../tokenization/interfaces/IVariableDebtToken.sol';
@ -37,8 +38,8 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
using WadRayMath for uint256;
using Address for address payable;
using ReserveLogic for ReserveLogic.ReserveData;
using UserLogic for UserLogic.UserReserveData;
using ReserveConfiguration for ReserveConfiguration.Map;
using UserConfiguration for UserConfiguration.Map;
//main configuration parameters
uint256 private constant REBALANCE_DOWN_RATE_DELTA = (1e27) / 5;
@ -51,7 +52,7 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
using UniversalERC20 for IERC20;
mapping(address => ReserveLogic.ReserveData) internal reserves;
mapping(address => mapping(address => UserLogic.UserReserveData)) internal usersReserveData;
mapping(address => UserConfiguration.Map) internal usersConfig;
address[] public reservesList;
@ -261,7 +262,6 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
uint16 _referralCode
) external payable nonReentrant {
ReserveLogic.ReserveData storage reserve = reserves[_reserve];
UserLogic.UserReserveData storage user = usersReserveData[msg.sender][_reserve];
ValidationLogic.validateDeposit(reserve, _amount);
@ -273,7 +273,7 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
reserve.updateInterestRates(_reserve, _amount, 0);
if (isFirstDeposit) {
user.useAsCollateral = true;
usersConfig[msg.sender].setUsingAsCollateral(reserve.index, true);
}
//minting AToken to user 1:1 with the specific exchange rate
@ -300,7 +300,6 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
uint256 _aTokenBalanceAfterRedeem
) external nonReentrant {
ReserveLogic.ReserveData storage reserve = reserves[_reserve];
UserLogic.UserReserveData storage user = usersReserveData[_user][_reserve];
AToken aToken = AToken(payable(reserve.aTokenAddress));
@ -311,7 +310,7 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
reserve.updateInterestRates(_reserve, 0, _amount);
if (_aTokenBalanceAfterRedeem == 0) {
user.useAsCollateral = false;
usersConfig[_user].setUsingAsCollateral(reserve.index, false);
}
AToken(reserve.aTokenAddress).transferUnderlyingTo(_user, _amount);
@ -334,7 +333,7 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
uint16 _referralCode
) external nonReentrant {
ReserveLogic.ReserveData storage reserve = reserves[_reserve];
UserLogic.UserReserveData storage user = usersReserveData[msg.sender][_reserve];
UserConfiguration.Map storage userConfig = usersConfig[msg.sender];
uint256 amountInETH = IPriceOracleGetter(addressesProvider.getPriceOracle())
.getAssetPrice(_reserve)
@ -343,14 +342,13 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
ValidationLogic.validateBorrow(
reserve,
user,
_reserve,
_amount,
amountInETH,
_interestRateMode,
MAX_STABLE_RATE_BORROW_SIZE_PERCENT,
reserves,
usersReserveData,
usersConfig[msg.sender],
reservesList,
addressesProvider.getPriceOracle()
);
@ -373,6 +371,10 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
reserve.updateInterestRates(_reserve, 0, _amount);
if(!userConfig.isBorrowing(reserve.index)){
userConfig.setBorrowing(reserve.index, true);
}
//if we reached this point, we can transfer
AToken(reserve.aTokenAddress).transferUnderlyingTo(msg.sender, _amount);
@ -404,6 +406,7 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
uint256 variableDebt;
uint256 paybackAmount;
uint256 currentStableRate;
uint256 totalDebt;
}
function repay(
@ -414,9 +417,10 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
) external payable nonReentrant {
RepayLocalVars memory vars;
ReserveLogic.ReserveData storage reserve = reserves[_reserve];
UserLogic.UserReserveData storage user = usersReserveData[_onBehalfOf][_reserve];
(vars.stableDebt, vars.variableDebt) = UserLogic.getUserCurrentDebt(_onBehalfOf, reserve);
(vars.stableDebt, vars.variableDebt) = Helpers.getUserCurrentDebt(_onBehalfOf, reserve);
vars.totalDebt = vars.stableDebt.add(vars.variableDebt);
ReserveLogic.InterestRateMode rateMode = ReserveLogic.InterestRateMode(_rateMode);
@ -451,6 +455,10 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
}
reserve.updateInterestRates(_reserve, vars.paybackAmount, 0);
if(vars.totalDebt.sub(vars.paybackAmount) == 0){
usersConfig[_onBehalfOf].setBorrowing(reserve.index, false);
}
IERC20(_reserve).universalTransferFrom(
msg.sender,
@ -485,13 +493,12 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
**/
function swapBorrowRateMode(address _reserve, uint256 _rateMode) external nonReentrant {
ReserveLogic.ReserveData storage reserve = reserves[_reserve];
UserLogic.UserReserveData storage user = usersReserveData[msg.sender][_reserve];
(uint256 stableDebt, uint256 variableDebt) = UserLogic.getUserCurrentDebt(msg.sender, reserve);
(uint256 stableDebt, uint256 variableDebt) = Helpers.getUserCurrentDebt(msg.sender, reserve);
ReserveLogic.InterestRateMode rateMode = ReserveLogic.InterestRateMode(_rateMode);
ValidationLogic.validateSwapRateMode(reserve, user, stableDebt, variableDebt, rateMode);
ValidationLogic.validateSwapRateMode(reserve, usersConfig[msg.sender], stableDebt, variableDebt, rateMode);
reserve.updateCumulativeIndexesAndTimestamp();
@ -581,18 +588,17 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
nonReentrant
{
ReserveLogic.ReserveData storage reserve = reserves[_reserve];
UserLogic.UserReserveData storage user = usersReserveData[msg.sender][_reserve];
ValidationLogic.validateSetUseReserveAsCollateral(
reserve,
_reserve,
reserves,
usersReserveData,
usersConfig[msg.sender],
reservesList,
addressesProvider.getPriceOracle()
);
user.useAsCollateral = _useAsCollateral;
usersConfig[msg.sender].setUsingAsCollateral(reserve.index, _useAsCollateral);
if (_useAsCollateral) {
emit ReserveUsedAsCollateralEnabled(_reserve, msg.sender);
@ -829,7 +835,7 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
) = GenericLogic.calculateUserAccountData(
_user,
reserves,
usersReserveData,
usersConfig[_user],
reservesList,
addressesProvider.getPriceOracle()
);
@ -860,14 +866,14 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
ReserveLogic.ReserveData storage reserve = reserves[_reserve];
currentATokenBalance = IERC20(reserve.aTokenAddress).balanceOf(_user);
(currentStableDebt, currentVariableDebt) = UserLogic.getUserCurrentDebt(_user, reserve);
(principalStableDebt, principalVariableDebt) = UserLogic.getUserPrincipalDebt(_user, reserve);
(currentStableDebt, currentVariableDebt) = Helpers.getUserCurrentDebt(_user, reserve);
(principalStableDebt, principalVariableDebt) = Helpers.getUserPrincipalDebt(_user, reserve);
liquidityRate = reserve.currentLiquidityRate;
stableBorrowRate = IStableDebtToken(reserve.stableDebtTokenAddress).getUserStableRate(_user);
stableRateLastUpdated = IStableDebtToken(reserve.stableDebtTokenAddress).getUserLastUpdated(
_user
);
usageAsCollateralEnabled = usersReserveData[_user][_reserve].useAsCollateral;
usageAsCollateralEnabled = usersConfig[_user].isUsingAsCollateral(reserve.index);
variableBorrowIndex = IVariableDebtToken(reserve.variableDebtTokenAddress).getUserIndex(_user);
}
@ -943,7 +949,10 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
if (reservesList[i] == _reserve) {
reserveAlreadyAdded = true;
}
if (!reserveAlreadyAdded) reservesList.push(_reserve);
if (!reserveAlreadyAdded) {
reserves[_reserve].index = uint8(reservesList.length);
reservesList.push(_reserve);
}
}
function getReserveNormalizedIncome(address _reserve) external view returns (uint256) {
@ -965,7 +974,7 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
_user,
_amount,
reserves,
usersReserveData,
usersConfig[_user],
reservesList,
addressesProvider.getPriceOracle()
);

View File

@ -16,10 +16,11 @@ import '../tokenization/interfaces/IVariableDebtToken.sol';
import '../libraries/WadRayMath.sol';
import '../interfaces/IPriceOracleGetter.sol';
import '../libraries/GenericLogic.sol';
import '../libraries/UserLogic.sol';
import '../libraries/Helpers.sol';
import '../libraries/ReserveLogic.sol';
import '../libraries/UniversalERC20.sol';
import '../libraries/ReserveConfiguration.sol';
import '../libraries/UserConfiguration.sol';
import {PercentageMath} from '../libraries/PercentageMath.sol';
/**
@ -34,14 +35,14 @@ contract LendingPoolLiquidationManager is ReentrancyGuard, VersionedInitializabl
using PercentageMath for uint256;
using Address for address;
using ReserveLogic for ReserveLogic.ReserveData;
using UserLogic for UserLogic.UserReserveData;
using ReserveConfiguration for ReserveConfiguration.Map;
using UserConfiguration for UserConfiguration.Map;
LendingPoolAddressesProvider public addressesProvider;
IFeeProvider feeProvider;
mapping(address => ReserveLogic.ReserveData) internal reserves;
mapping(address => mapping(address => UserLogic.UserReserveData)) internal usersReserveData;
mapping(address => UserConfiguration.Map) internal usersConfig;
address[] public reservesList;
@ -124,14 +125,14 @@ contract LendingPoolLiquidationManager is ReentrancyGuard, VersionedInitializabl
) external payable returns (uint256, string memory) {
ReserveLogic.ReserveData storage principalReserve = reserves[_reserve];
ReserveLogic.ReserveData storage collateralReserve = reserves[_collateral];
UserLogic.UserReserveData storage userCollateral = usersReserveData[_user][_collateral];
UserConfiguration.Map storage userConfig = usersConfig[_user];
LiquidationCallLocalVars memory vars;
(, , , , vars.healthFactor) = GenericLogic.calculateUserAccountData(
_user,
reserves,
usersReserveData,
usersConfig[_user],
reservesList,
addressesProvider.getPriceOracle()
);
@ -145,17 +146,10 @@ contract LendingPoolLiquidationManager is ReentrancyGuard, VersionedInitializabl
vars.userCollateralBalance = IERC20(collateralReserve.aTokenAddress).balanceOf(_user);
//if _user hasn't deposited this specific collateral, nothing can be liquidated
if (vars.userCollateralBalance == 0) {
return (
uint256(LiquidationErrors.NO_COLLATERAL_AVAILABLE),
'Invalid collateral to liquidate'
);
}
vars.isCollateralEnabled =
collateralReserve.configuration.getLiquidationThreshold() > 0 &&
userCollateral.useAsCollateral;
userConfig.isUsingAsCollateral(collateralReserve.index);
//if _collateral isn't enabled as collateral by _user, it cannot be liquidated
if (!vars.isCollateralEnabled) {
@ -166,7 +160,7 @@ contract LendingPoolLiquidationManager is ReentrancyGuard, VersionedInitializabl
}
//if the user hasn't borrowed the specific currency defined by _reserve, it cannot be liquidated
(vars.userStableDebt, vars.userVariableDebt) = UserLogic.getUserCurrentDebt(
(vars.userStableDebt, vars.userVariableDebt) = Helpers.getUserCurrentDebt(
_user,
principalReserve
);

View File

@ -1,12 +1,13 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.6.8;
pragma experimental ABIEncoderV2;
import {SafeMath} from '@openzeppelin/contracts/math/SafeMath.sol';
import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
import {ReserveLogic} from './ReserveLogic.sol';
import {ReserveConfiguration} from './ReserveConfiguration.sol';
import {UserLogic} from './UserLogic.sol';
import {UserConfiguration} from './UserConfiguration.sol';
import {WadRayMath} from './WadRayMath.sol';
import {PercentageMath} from './PercentageMath.sol';
import '../interfaces/IPriceOracleGetter.sol';
@ -20,11 +21,11 @@ import '@nomiclabs/buidler/console.sol';
*/
library GenericLogic {
using ReserveLogic for ReserveLogic.ReserveData;
using UserLogic for UserLogic.UserReserveData;
using SafeMath for uint256;
using WadRayMath for uint256;
using PercentageMath for uint256;
using ReserveConfiguration for ReserveConfiguration.Map;
using UserConfiguration for UserConfiguration.Map;
uint256 public constant HEALTH_FACTOR_LIQUIDATION_THRESHOLD = 1e18;
@ -55,16 +56,21 @@ library GenericLogic {
address _user,
uint256 _amount,
mapping(address => ReserveLogic.ReserveData) storage _reservesData,
mapping(address => mapping(address => UserLogic.UserReserveData)) storage _usersData,
UserConfiguration.Map calldata _userConfig,
address[] calldata _reserves,
address _oracle
) external view returns (bool) {
if (!_userConfig.isBorrowingAny() || !_userConfig.isUsingAsCollateral(_reservesData[_reserve].index)) {
return true;
}
// Usage of a memory struct of vars to avoid "Stack too deep" errors due to local variables
balanceDecreaseAllowedLocalVars memory vars;
(vars.ltv, , , vars.decimals) = _reservesData[_reserve].configuration.getParams();
if (vars.ltv == 0 || !_usersData[_user][_reserve].useAsCollateral) {
if (vars.ltv == 0) {
return true; //if reserve is not used as collateral, no reasons to block the transfer
}
@ -74,7 +80,7 @@ library GenericLogic {
,
vars.currentLiquidationThreshold,
) = calculateUserAccountData(_user, _reservesData, _usersData, _reserves, _oracle);
) = calculateUserAccountData(_user, _reservesData, _userConfig, _reserves, _oracle);
if (vars.borrowBalanceETH == 0) {
return true; //no borrows - no reasons to block the transfer
@ -134,18 +140,20 @@ library GenericLogic {
* the average Loan To Value, the average Liquidation Ratio, and the Health factor.
* @param _user the address of the user
* @param _reservesData data of all the reserves
* @param _usersReserveData data
* @return the total liquidity, total collateral, total borrow balances of the user in ETH.
* @param _userConfig the configuration of the user
* @param _reserves the list of the available reserves
* @param _oracle the price oracle address
* @return the total collateral and total borrow balance of the user in ETH, the avg ltv and liquidation threshold and the HF
* also the average Ltv, liquidation threshold, and the health factor
**/
function calculateUserAccountData(
address _user,
mapping(address => ReserveLogic.ReserveData) storage _reservesData,
mapping(address => mapping(address => UserLogic.UserReserveData)) storage _usersReserveData,
UserConfiguration.Map memory _userConfig,
address[] memory _reserves,
address _oracle
)
public
internal
view
returns (
uint256,
@ -157,46 +165,48 @@ library GenericLogic {
{
CalculateUserAccountDataVars memory vars;
if (_userConfig.isEmpty()) {
return (0, 0, 0, 0, uint256(-1));
}
for (vars.i = 0; vars.i < _reserves.length; vars.i++) {
vars.currentReserveAddress = _reserves[vars.i];
ReserveLogic.ReserveData storage currentReserve = _reservesData[vars.currentReserveAddress];
vars.compoundedLiquidityBalance = IERC20(currentReserve.aTokenAddress).balanceOf(_user);
vars.compoundedBorrowBalance = IERC20(currentReserve.stableDebtTokenAddress).balanceOf(_user);
vars.compoundedBorrowBalance = vars.compoundedBorrowBalance.add(
IERC20(currentReserve.variableDebtTokenAddress).balanceOf(_user)
);
if (vars.compoundedLiquidityBalance == 0 && vars.compoundedBorrowBalance == 0) {
if (!_userConfig.isUsingAsCollateralOrBorrowing(vars.i)) {
continue;
}
vars.currentReserveAddress = _reserves[vars.i];
ReserveLogic.ReserveData storage currentReserve = _reservesData[vars.currentReserveAddress];
(vars.ltv, vars.liquidationThreshold, , vars.decimals) = currentReserve
.configuration
.getParams();
vars.tokenUnit = 10**vars.decimals;
vars.reserveUnitPrice = IPriceOracleGetter(_oracle).getAssetPrice(_reserves[vars.i]);
vars.reserveUnitPrice = IPriceOracleGetter(_oracle).getAssetPrice(vars.currentReserveAddress);
if (vars.ltv != 0 && _userConfig.isUsingAsCollateral(vars.i)) {
vars.compoundedLiquidityBalance = IERC20(currentReserve.aTokenAddress).balanceOf(_user);
//liquidity and collateral balance
if (vars.compoundedLiquidityBalance > 0) {
uint256 liquidityBalanceETH = vars
.reserveUnitPrice
.mul(vars.compoundedLiquidityBalance)
.div(vars.tokenUnit);
if (vars.ltv != 0 && _usersReserveData[_user][_reserves[vars.i]].useAsCollateral) {
vars.totalCollateralBalanceETH = vars.totalCollateralBalanceETH.add(liquidityBalanceETH);
vars.totalCollateralBalanceETH = vars.totalCollateralBalanceETH.add(liquidityBalanceETH);
vars.avgLtv = vars.avgLtv.add(liquidityBalanceETH.mul(vars.ltv));
vars.avgLiquidationThreshold = vars.avgLiquidationThreshold.add(
liquidityBalanceETH.mul(vars.liquidationThreshold)
);
}
vars.avgLtv = vars.avgLtv.add(liquidityBalanceETH.mul(vars.ltv));
vars.avgLiquidationThreshold = vars.avgLiquidationThreshold.add(
liquidityBalanceETH.mul(vars.liquidationThreshold)
);
}
if (vars.compoundedBorrowBalance > 0) {
if (_userConfig.isBorrowing(vars.i)) {
vars.compoundedBorrowBalance = IERC20(currentReserve.stableDebtTokenAddress).balanceOf(
_user
);
vars.compoundedBorrowBalance = vars.compoundedBorrowBalance.add(
IERC20(currentReserve.variableDebtTokenAddress).balanceOf(_user)
);
vars.totalBorrowBalanceETH = vars.totalBorrowBalanceETH.add(
vars.reserveUnitPrice.mul(vars.compoundedBorrowBalance).div(vars.tokenUnit)
);

View File

@ -1,49 +1,17 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.6.8;
import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol';
import {SafeMath} from '@openzeppelin/contracts/math/SafeMath.sol';
import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
import '../tokenization/base/DebtTokenBase.sol';
import './ReserveLogic.sol';
import './ReserveConfiguration.sol';
/**
* @title UserLogic library
* @title Helpers library
* @author Aave
* @notice Implements user specific logic.
* @notice Implements calculation helpers.
*/
library UserLogic {
using SafeMath for uint256;
using ReserveConfiguration for ReserveConfiguration.Map;
struct UserReserveData {
//defines if a specific deposit should or not be used as a collateral in borrows
bool useAsCollateral;
}
/**
* @dev checks if a user is allowed to borrow at a stable rate
* @param _reserve the reserve address
* @param _user the user
* @param _amount the amount the the user wants to borrow
* @return true if the user is allowed to borrow at a stable rate, false otherwise
**/
function isAllowedToBorrowAtStable(
UserReserveData storage _user,
ReserveLogic.ReserveData storage _reserve,
address _userAddress,
uint256 _amount
) external view returns (bool) {
if (!_reserve.isStableBorrowRateEnabled) return false;
return
!_user.useAsCollateral ||
_reserve.configuration.getLtv() == 0 ||
_amount > IERC20(_reserve.aTokenAddress).balanceOf(_userAddress);
}
library Helpers {
/**
* @dev fetches the user current stable and variable debt balances

View File

@ -5,7 +5,6 @@ import {SafeMath} from '@openzeppelin/contracts/math/SafeMath.sol';
import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
import {ReserveLogic} from './ReserveLogic.sol';
import {UserLogic} from './UserLogic.sol';
import {WadRayMath} from './WadRayMath.sol';
import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol';

View File

@ -3,8 +3,6 @@ pragma solidity ^0.6.8;
import {SafeMath} from '@openzeppelin/contracts/math/SafeMath.sol';
import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
import {UserLogic} from './UserLogic.sol';
import {MathUtils} from './MathUtils.sol';
import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol';
import {UniversalERC20} from './UniversalERC20.sol';
@ -28,7 +26,6 @@ library ReserveLogic {
using WadRayMath for uint256;
using UniversalERC20 for IERC20;
using Address for address;
using UserLogic for UserLogic.UserReserveData;
using ReserveLogic for ReserveLogic.ReserveData;
using ReserveConfiguration for ReserveConfiguration.Map;
@ -62,6 +59,8 @@ library ReserveLogic {
uint40 lastUpdateTimestamp;
// isStableBorrowRateEnabled = true means users can borrow at a stable rate
bool isStableBorrowRateEnabled;
uint8 index;
}
/**

View File

@ -0,0 +1,109 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.6.8;
import {SafeMath} from '@openzeppelin/contracts/math/SafeMath.sol';
import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
import {WadRayMath} from './WadRayMath.sol';
import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol';
import {IFeeProvider} from '../interfaces/IFeeProvider.sol';
/**
* @title UserConfiguration library
* @author Aave
* @notice Implements the bitmap logic to handle the user configuration
*/
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
* @param _reserveIndex the index of the reserve in the bitmap
* @param _borrowing true if the user is borrowing the reserve, false otherwise
**/
function setBorrowing(
UserConfiguration.Map storage _self,
uint256 _reserveIndex,
bool _borrowing
) internal {
_self.data = (_self.data & ~(1 << _reserveIndex*2)) | uint256(_borrowing ? 1 : 0) << (_reserveIndex * 2);
}
/**
* @dev sets if the user is using as collateral the reserve identified by _reserveIndex
* @param _self the configuration object
* @param _reserveIndex the index of the reserve in the bitmap
* @param _usingAsCollateral true if the user is usin the reserve as collateral, false otherwise
**/
function setUsingAsCollateral(
UserConfiguration.Map storage _self,
uint256 _reserveIndex,
bool _usingAsCollateral
) internal {
_self.data = (_self.data & ~(1 << _reserveIndex*2+1)) | uint256(_usingAsCollateral ? 1 : 0) << (_reserveIndex * 2 + 1);
}
/**
* @dev used to validate if a user has been using the reserve for borrowing or as collateral
* @param _self the configuration object
* @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)
internal
view
returns (bool)
{
return (_self.data >> (_reserveIndex * 2)) & 3 != 0;
}
/**
* @dev used to validate if a user has been using the reserve for borrowing
* @param _self the configuration object
* @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)
internal
view
returns (bool)
{
return (_self.data >> (_reserveIndex * 2)) & 1 != 0;
}
/**
* @dev used to validate if a user has been using the reserve as collateral
* @param _self the configuration object
* @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)
internal
view
returns (bool)
{
return (_self.data >> (_reserveIndex * 2 + 1)) & 1 != 0;
}
/**
* @dev used to validate if a user has been borrowing from any reserve
* @param _self the configuration object
* @return true if the user has been borrowing any reserve, false otherwise
**/
function isBorrowingAny(UserConfiguration.Map memory _self) internal view returns (bool) {
return _self.data & BORROWING_MASK != 0;
}
/**
* @dev used to validate if a user has not been using any reserve
* @param _self the configuration object
* @return true if the user has been borrowing any reserve, false otherwise
**/
function isEmpty(UserConfiguration.Map memory _self) internal view returns(bool) {
return _self.data == 0;
}
}

View File

@ -1,16 +1,17 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.6.8;
pragma experimental ABIEncoderV2;
import {SafeMath} from '@openzeppelin/contracts/math/SafeMath.sol';
import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
import {ReserveLogic} from './ReserveLogic.sol';
import {UserLogic} from './UserLogic.sol';
import {GenericLogic} from './GenericLogic.sol';
import {WadRayMath} from './WadRayMath.sol';
import {PercentageMath} from './PercentageMath.sol';
import {UniversalERC20} from './UniversalERC20.sol';
import {ReserveConfiguration} from './ReserveConfiguration.sol';
import {UserConfiguration} from './UserConfiguration.sol';
import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol';
import {IFeeProvider} from '../interfaces/IFeeProvider.sol';
import '@nomiclabs/buidler/console.sol';
@ -22,12 +23,12 @@ import '@nomiclabs/buidler/console.sol';
*/
library ValidationLogic {
using ReserveLogic for ReserveLogic.ReserveData;
using UserLogic for UserLogic.UserReserveData;
using SafeMath for uint256;
using WadRayMath for uint256;
using PercentageMath for uint256;
using UniversalERC20 for IERC20;
using ReserveConfiguration for ReserveConfiguration.Map;
using UserConfiguration for UserConfiguration.Map;
/**
* @dev validates a deposit.
@ -89,35 +90,31 @@ library ValidationLogic {
/**
* @dev validates a borrow.
* @param _reserve the reserve state from which the user is borrowing
* @param _user the state of the user for the specific reserve
* @param _reserveAddress the address of the reserve
* @param _amount the amount to be borrowed
* @param _amountInETH the amount to be borrowed, in ETH
* @param _interestRateMode the interest rate mode at which the user is borrowing
* @param _maxStableLoanPercent the max amount of the liquidity that can be borrowed at stable rate, in percentage
* @param _reservesData the state of all the reserves
* @param _usersData the state of all the users for all the reserves
* @param _userConfig the state of the user for the specific reserve
* @param _reserves the addresses of all the active reserves
* @param _oracle the price oracle
*/
function validateBorrow(
ReserveLogic.ReserveData storage _reserve,
UserLogic.UserReserveData storage _user,
address _reserveAddress,
uint256 _amount,
uint256 _amountInETH,
uint256 _interestRateMode,
uint256 _maxStableLoanPercent,
mapping(address => ReserveLogic.ReserveData) storage _reservesData,
mapping(address => mapping(address => UserLogic.UserReserveData)) storage _usersData,
UserConfiguration.Map storage _userConfig,
address[] calldata _reserves,
address _oracle
) external view {
ValidateBorrowLocalVars memory vars;
//internalValidateReserveStateAndAmount(_reserve, _amount);
(
vars.isActive,
vars.isFreezed,
@ -153,7 +150,7 @@ library ValidationLogic {
) = GenericLogic.calculateUserAccountData(
msg.sender,
_reservesData,
_usersData,
_userConfig,
_reserves,
_oracle
);
@ -187,7 +184,7 @@ library ValidationLogic {
require(vars.stableRateBorrowingEnabled, '11');
require(
!_user.useAsCollateral ||
!_userConfig.isUsingAsCollateral(_reserve.index) ||
_reserve.configuration.getLtv() == 0 ||
_amount > IERC20(_reserve.aTokenAddress).balanceOf(msg.sender),
'12'
@ -251,14 +248,14 @@ library ValidationLogic {
/**
* @dev validates a swap of borrow rate mode.
* @param _reserve the reserve state on which the user is swapping the rate
* @param _user the user state for the reserve on which user is swapping the rate
* @param _userConfig the user reserves configuration
* @param _stableBorrowBalance the stable borrow balance of the user
* @param _variableBorrowBalance the stable borrow balance of the user
* @param _currentRateMode the rate mode of the borrow
*/
function validateSwapRateMode(
ReserveLogic.ReserveData storage _reserve,
UserLogic.UserReserveData storage _user,
UserConfiguration.Map storage _userConfig,
uint256 _stableBorrowBalance,
uint256 _variableBorrowBalance,
ReserveLogic.InterestRateMode _currentRateMode
@ -288,7 +285,7 @@ library ValidationLogic {
require(stableRateEnabled, '11');
require(
!_user.useAsCollateral ||
!_userConfig.isUsingAsCollateral(_reserve.index) ||
_reserve.configuration.getLtv() == 0 ||
_stableBorrowBalance.add(_variableBorrowBalance) >
IERC20(_reserve.aTokenAddress).balanceOf(msg.sender),
@ -304,13 +301,15 @@ library ValidationLogic {
* @param _reserve the state of the reserve that the user is enabling or disabling as collateral
* @param _reserveAddress the address of the reserve
* @param _reservesData the data of all the reserves
* @param _usersData the data of all the users
* @param _userConfig the state of the user for the specific reserve
* @param _reserves the addresses of all the active reserves
* @param _oracle the price oracle
*/
function validateSetUseReserveAsCollateral(
ReserveLogic.ReserveData storage _reserve,
address _reserveAddress,
mapping(address => ReserveLogic.ReserveData) storage _reservesData,
mapping(address => mapping(address => UserLogic.UserReserveData)) storage _usersData,
UserConfiguration.Map storage _userConfig,
address[] calldata _reserves,
address _oracle
) external view {
@ -324,7 +323,7 @@ library ValidationLogic {
msg.sender,
underlyingBalance,
_reservesData,
_usersData,
_userConfig,
_reserves,
_oracle
),

View File

@ -5,7 +5,7 @@
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"localhost": {
"address": "0x35A2624888e207e4B3434E9a9E250bF6Ee68FeA3",
"address": "0x7AC94fC704557bFBB6E743c797C45b3384b95bB6",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
},
@ -15,7 +15,7 @@
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"localhost": {
"address": "0x1f569c307949a908A4b8Ff7453a88Ca0b8D8df13",
"address": "0x9e3C887092123acf59a1819e78a95B37e46BC886",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
},
@ -25,7 +25,7 @@
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"localhost": {
"address": "0x0766c9592a8686CAB0081b4f35449462c6e82F11",
"address": "0xe9ECaCA2FAe7ecCB11242B393E545F293E33096f",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
},
@ -34,7 +34,7 @@
"address": "0x852e3718A320aD93Ad8692E8D663d247e4c1b400"
},
"localhost": {
"address": "0x635138E91E191ec54DE7173e24c7E6C1EB4C6739"
"address": "0xFC16126DBD017331464103385809E4113A61Fe3A"
}
},
"LendingPoolParametersProvider": {
@ -52,7 +52,7 @@
"address": "0xA10958a24032283FbE2D23cedf264d6eC9411CBA"
},
"localhost": {
"address": "0x598cF9a680a3bac08BD271E782F40339B193f84B"
"address": "0xC6627778273999AeF86ab786d3f6088e9C60F535"
}
},
"LendingPoolDataProvider": {
@ -65,56 +65,56 @@
"address": "0x2C4603396dE2F08642354A3A102760827FfFe113"
},
"localhost": {
"address": "0x0aA65C476219C5507F920252A84a766fBA750f7d"
"address": "0x6Ad44DDbF6564F0abc078340e11100d44406dD12"
}
},
"PriceOracle": {
"buidlerevm": {
"address": "0x85bdE212E66e2BAE510E44Ed59116c1eC712795b",
"address": "0xE4C10Db67595aF2Cb4166c8C274e0140f7E43059",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"localhost": {
"address": "0xE0fC5Da76E489677078d00d3f321e9777c76381B",
"address": "0x372AED51F78c3CaB8b632986b689888caf25Ffa5",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
},
"MockAggregator": {
"buidlerevm": {
"address": "0xAF6BA11790D1942625C0c2dA07da19AB63845cfF",
"address": "0xEC1C93A9f6a9e18E97784c76aC52053587FcDB89",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"localhost": {
"address": "0xDCAB55FBf59a253B3Fb0CD2Ba45F0c02413dF375",
"address": "0xea0ddFACb2c3392b8DCD3B827534496b585aAcc7",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
},
"ChainlinkProxyPriceProvider": {
"buidlerevm": {
"address": "0xD83D2773a7873ae2b5f8Fb92097e20a8C64F691E",
"address": "0x7B6C3e5486D9e6959441ab554A889099eed76290",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"localhost": {
"address": "0x293965D84cE150Cbf5F36332ba47e997e2763bf2",
"address": "0xD859214080050ddC8745c2A6dF41439Bb851D5Bc",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
},
"LendingRateOracle": {
"buidlerevm": {
"address": "0xf91aC1098F3b154671Ce83290114aaE45ac0225f",
"address": "0xD83D2773a7873ae2b5f8Fb92097e20a8C64F691E",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"localhost": {
"address": "0x7549d6bb05083613eF87b723595553dCc570Ca21",
"address": "0x4a8527a3657a358B956571EEf857Fe5A8567A378",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
},
"DefaultReserveInterestRateStrategy": {
"buidlerevm": {
"address": "0x09d7cb7a0606a7f10DC8a37b3e0E420F39f0FAF1",
"address": "0x63b9792E7A95e3aa037255E8cAa0Dfd76f7383e7",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"localhost": {
"address": "0xA106BFbDB5C925A04358bE49db41aDd308a1458f",
"address": "0x52EF9F7d7dc2EFF6D691080204Adae9002b9AE67",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
},
@ -146,37 +146,37 @@
},
"TokenDistributor": {
"buidlerevm": {
"address": "0x9D37fB22EA7d655f12E68DABBf6B6585A00774C3"
"address": "0x1bb3d8FA7bDa74Af0D64d348a2545E7570863fA8"
},
"localhost": {
"address": "0x8E2a05B9Abd9a2a3046879074d7D136213AaDCb9"
"address": "0xf2923EBa2C4AF250D93e8201Bc20a0096B3A8f89"
}
},
"InitializableAdminUpgradeabilityProxy": {
"buidlerevm": {
"address": "0x9D37fB22EA7d655f12E68DABBf6B6585A00774C3",
"address": "0x1bb3d8FA7bDa74Af0D64d348a2545E7570863fA8",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"localhost": {
"address": "0x8E2a05B9Abd9a2a3046879074d7D136213AaDCb9",
"address": "0xf2923EBa2C4AF250D93e8201Bc20a0096B3A8f89",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
},
"MockFlashLoanReceiver": {
"buidlerevm": {
"address": "0x22058276Dd278bD037591805E62E797012d666f6"
"address": "0xC5f7aC6895DcB76877E71db756433fB0E0478FEB"
},
"localhost": {
"address": "0x8EA6693b23224fFD1C2AfbB161f15b398F8cB5FA"
"address": "0x9D72c382e918491A463157Ea3e7633FE0F26F83d"
}
},
"WalletBalanceProvider": {
"buidlerevm": {
"address": "0x6D3540a9F1a769bfd91A4A33169a8361aa82dC0F",
"address": "0x51fa472EB89c046484B037B6125CF843C9d41b44",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"localhost": {
"address": "0xFb017937aB8EABb9506A03E6c76DcA99C6D095c7",
"address": "0xF1BbafE2063F81038079cCdC2E8e5100693B109b",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
},
@ -186,7 +186,7 @@
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"localhost": {
"address": "0xD5A0587aAEB195028909E98930B391dFB3f9F589",
"address": "0x07FcFF7B7953ff64969B3c4C8E7c386fC7Efaa55",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
},
@ -196,7 +196,7 @@
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"localhost": {
"address": "0xaD3AdbC18E4AD090034A6C74Eda61f4310dce313",
"address": "0x921d5f671e5892e43a292Fa1A5BCA3B4F6E62aE9",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
},
@ -206,7 +206,7 @@
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"localhost": {
"address": "0x25a88BbA9c8D2a46e3Ff4bFe98712DF7A1044fB6",
"address": "0x30d4f0D334822B2887C280A9540959e1dBdD340c",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
},
@ -216,7 +216,7 @@
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"localhost": {
"address": "0x16d1802cd7cfcb67955BBBa26bAae1cE559B5F5B",
"address": "0x62b9F2345e060F6B81bA677Eb1cCC39Ec47d162f",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
},
@ -226,7 +226,7 @@
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"localhost": {
"address": "0xE58d8c88f5A670f16BE8F7864707170F43e943A6",
"address": "0x18287eAe938cf3C2024A460C4759E9E081729FB2",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
},
@ -236,7 +236,7 @@
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"localhost": {
"address": "0xfdAF4f6e47e854c05bE158993d32872e784F0502",
"address": "0x6C12CB1315d28904AE67aaf4d21F1247e0Caf1E7",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
},
@ -246,7 +246,7 @@
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"localhost": {
"address": "0x92edC13A10036A3C50396f2B63148a3e9a8D589e",
"address": "0xf400aDA5C432462a380ae49ee9A84FE3F21B188d",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
},
@ -256,7 +256,7 @@
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"localhost": {
"address": "0xE5C277cDb7E10372918Ac54Ce54022910A24FE88",
"address": "0x1e3b37AA176ec7d5ae1A36e093A9f849742563F4",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
},
@ -266,7 +266,7 @@
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"localhost": {
"address": "0xF5742a599a0F4520089cbf2EBBa66Bb4F471B85F",
"address": "0xfDdff7952ab54f34FBE3E421b4DB1E8B0cf673Df",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
},
@ -276,7 +276,7 @@
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"localhost": {
"address": "0x380EF388e13D8cAdeACef6eF682C7B7D85865076",
"address": "0x378a425415BC1099820005E93448D877A5e02793",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
},
@ -286,7 +286,7 @@
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"localhost": {
"address": "0xC89577DED8441e52C17C13D527b85b225C5c8311",
"address": "0x2361fAEcc05E4e50D85c22E253bafD6B62f91F7A",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
},
@ -296,7 +296,7 @@
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"localhost": {
"address": "0xD4b06774A717Ff5A7c20c8712e31c6BbfFcb1F01",
"address": "0x1Bf05105664fA2eA4af77E88e637189d76e6283f",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
},
@ -306,7 +306,7 @@
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"localhost": {
"address": "0xbe66dC9DFEe580ED968403e35dF7b5159f873df8",
"address": "0x529D91657646F22e348c1B9870d0C0D88ED1151A",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
},
@ -316,7 +316,7 @@
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"localhost": {
"address": "0x93AfC6Df4bB8F62F2493B19e577f8382c0BA9EBC",
"address": "0x21a26892Ad0ee4b429BB768BaAF4A7fB623d91C7",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
},
@ -326,7 +326,7 @@
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"localhost": {
"address": "0x75Ded61646B5945BdDd0CD9a9Db7c8288DA6F810",
"address": "0x269615E7bA0C64666F8d7586dE868aD55EDD8577",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
},
@ -336,7 +336,7 @@
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"localhost": {
"address": "0xdE7c40e675bF1aA45c18cCbaEb9662B16b0Ddf7E",
"address": "0xc9b9B169eA13aB77079F62c5D2f038f50746A4cD",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
},
@ -346,7 +346,7 @@
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"localhost": {
"address": "0xEcb928A3c079a1696Aa5244779eEc3dE1717fACd",
"address": "0x2102f3e30ab514e35561C9499f49c3079957f407",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
},
@ -356,7 +356,7 @@
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"localhost": {
"address": "0xDFbeeed692AA81E7f86E72F7ACbEA2A1C4d63544",
"address": "0x87985DF0bf4c392F4114554fcCfC9Ef713463965",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
},
@ -366,7 +366,7 @@
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"localhost": {
"address": "0x5191aA68c7dB195181Dd2441dBE23A48EA24b040",
"address": "0xf20d0172C4F801762a1Fed1F969fF143BAf6740A",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
},
@ -376,7 +376,7 @@
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"localhost": {
"address": "0x8F9422aa37215c8b3D1Ea1674138107F84D68F26",
"address": "0x9707728C9D0C48a83fDA8eEaF39b104EDcFC4f4A",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
},
@ -386,7 +386,7 @@
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"localhost": {
"address": "0xa89E20284Bd638F31b0011D0fC754Fc9d2fa73e3",
"address": "0x078522E6413f005DA503EA2c72e161C54D27a5ec",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
},
@ -396,7 +396,7 @@
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"localhost": {
"address": "0xaA935993065F2dDB1d13623B1941C7AEE3A60F23",
"address": "0xFF8862c67087C7474e44693a017411E1783A6b50",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
},
@ -406,45 +406,35 @@
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"localhost": {
"address": "0x35A2624888e207e4B3434E9a9E250bF6Ee68FeA3",
"address": "0x7AC94fC704557bFBB6E743c797C45b3384b95bB6",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
},
"AaveProtocolTestHelpers": {
"buidlerevm": {
"address": "0x2ff3F0e437D7843a8100ac876A766081F4c4649D"
"address": "0x4b2c297ba5be42610994974b9543D56B864CA011"
},
"localhost": {
"address": "0xc6b70Da02A963fCA0016C7548E1f43511EFe11eC"
"address": "0x49CC1e6749f45e3BaB945B96c0d6723a606BDcDa"
}
},
"StableDebtToken": {
"buidlerevm": {
"address": "0x5Ea694f66BD0CBd08FC7967af01b67Dcef68cC5c",
"address": "0xc783bfC59158E888dA3E9c7768aaDC7a58ee7809",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"localhost": {
"address": "0x9c91aEaD98b1354C7B0EAfb8ff539d0796c79894",
"address": "0x34dB38AC79A5e23F6Ff6711098979Ca3159b80d7",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
},
"VariableDebtToken": {
"buidlerevm": {
"address": "0xd4e934C2749CA8C1618659D02E7B28B074bf4df7",
"address": "0xBdFE372Bb5a0db801A1a17796EC5cfF2F30A714C",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"localhost": {
"address": "0x145b7B6368Df63e7F3497b0A948B30fC1A4d5E55",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
},
"AToken": {
"buidlerevm": {
"address": "0x8280D40C9E9F04229D2435EAad6e0011309ce81B",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"localhost": {
"address": "0x142bFA0788F794d3D0aE1EC36373ee034aABC11f",
"address": "0x7BCb706a6C9cA7F9e51199d3d87A6A92b9cc05b4",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
}

View File

@ -118,7 +118,6 @@ const deployLibrary = async (libraryId: eContractid) => {
};
export const linkLibrariesToArtifact = async (artifact: Artifact) => {
const userLogic = await deployLibrary(eContractid.UserLogic);
const reserveLogic = await deployLibrary(eContractid.ReserveLogic);
const genericLogicArtifact = await readArtifact(
@ -127,7 +126,6 @@ export const linkLibrariesToArtifact = async (artifact: Artifact) => {
);
const linkedGenericLogicByteCode = linkBytecode(genericLogicArtifact, {
[eContractid.UserLogic]: userLogic.address,
[eContractid.ReserveLogic]: reserveLogic.address,
});
@ -144,7 +142,6 @@ export const linkLibrariesToArtifact = async (artifact: Artifact) => {
);
const linkedValidationLogicByteCode = linkBytecode(validationLogicArtifact, {
[eContractid.UserLogic]: userLogic.address,
[eContractid.ReserveLogic]: reserveLogic.address,
[eContractid.GenericLogic]: genericLogic.address,
});
@ -157,7 +154,6 @@ export const linkLibrariesToArtifact = async (artifact: Artifact) => {
const validationLogic = await (await validationLogicFactory.deploy()).deployed();
const linkedBytecode = linkBytecode(artifact, {
[eContractid.UserLogic]: userLogic.address,
[eContractid.ReserveLogic]: reserveLogic.address,
[eContractid.GenericLogic]: genericLogic.address,
[eContractid.ValidationLogic]: validationLogic.address,

View File

@ -62,7 +62,7 @@ export enum ProtocolErrors {
HF_IS_NOT_BELLOW_THRESHOLD = 'Health factor is not below the threshold',
INVALID_HF = 'Invalid health factor',
USER_DID_NOT_BORROW_SPECIFIED = 'User did not borrow the specified currency',
INVALID_COLLATERAL_TO_LIQUIDATE = 'Invalid collateral to liquidate',
THE_COLLATERAL_CHOSEN_CANNOT_BE_LIQUIDATED = 'The collateral chosen cannot be liquidated',
}
export type tEthereumAddress = string;

View File

@ -17,7 +17,7 @@ makeSuite('LendingPool liquidation - liquidator receiving aToken', (testEnv) =>
HF_IS_NOT_BELLOW_THRESHOLD,
INVALID_HF,
USER_DID_NOT_BORROW_SPECIFIED,
INVALID_COLLATERAL_TO_LIQUIDATE,
THE_COLLATERAL_CHOSEN_CANNOT_BE_LIQUIDATED,
} = ProtocolErrors;
it('LIQUIDATION - Deposits ETH, borrows DAI/Check liquidation fails because health factor is above 1', async () => {
@ -111,7 +111,7 @@ makeSuite('LendingPool liquidation - liquidator receiving aToken', (testEnv) =>
await expect(
pool.liquidationCall(dai.address, dai.address, borrower.address, oneEther.toString(), true)
).revertedWith(INVALID_COLLATERAL_TO_LIQUIDATE);
).revertedWith(THE_COLLATERAL_CHOSEN_CANNOT_BE_LIQUIDATED);
});
it('LIQUIDATION - Liquidates the borrow', async () => {

View File

@ -47,7 +47,7 @@ makeSuite('LendingPool liquidation - liquidator receiving the underlying asset',
HF_IS_NOT_BELLOW_THRESHOLD,
INVALID_HF,
USER_DID_NOT_BORROW_SPECIFIED,
INVALID_COLLATERAL_TO_LIQUIDATE,
THE_COLLATERAL_CHOSEN_CANNOT_BE_LIQUIDATED,
} = ProtocolErrors;
it('LIQUIDATION - Deposits ETH, borrows DAI', async () => {