mirror of
https://github.com/Instadapp/aave-protocol-v2.git
synced 2024-07-29 21:47:30 +00:00
refactor: removed balanceDecreaseAllowed
This commit is contained in:
parent
45acc0b854
commit
ed987ac46e
|
@ -156,16 +156,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
||||||
amountToWithdraw = userBalance;
|
amountToWithdraw = userBalance;
|
||||||
}
|
}
|
||||||
|
|
||||||
ValidationLogic.validateWithdraw(
|
ValidationLogic.validateWithdraw(reserve, amountToWithdraw, userBalance);
|
||||||
asset,
|
|
||||||
amountToWithdraw,
|
|
||||||
userBalance,
|
|
||||||
_reserves,
|
|
||||||
_usersConfig[msg.sender],
|
|
||||||
_reservesList,
|
|
||||||
_reservesCount,
|
|
||||||
_addressesProvider.getPriceOracle()
|
|
||||||
);
|
|
||||||
|
|
||||||
reserve.updateState();
|
reserve.updateState();
|
||||||
|
|
||||||
|
@ -178,6 +169,15 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
||||||
|
|
||||||
IAToken(aToken).burn(msg.sender, to, amountToWithdraw, reserve.liquidityIndex);
|
IAToken(aToken).burn(msg.sender, to, amountToWithdraw, reserve.liquidityIndex);
|
||||||
|
|
||||||
|
ValidationLogic.validateHealthFactor(
|
||||||
|
msg.sender,
|
||||||
|
_reserves,
|
||||||
|
_usersConfig[msg.sender],
|
||||||
|
_reservesList,
|
||||||
|
_reservesCount,
|
||||||
|
_addressesProvider.getPriceOracle()
|
||||||
|
);
|
||||||
|
|
||||||
emit Withdraw(asset, msg.sender, to, amountToWithdraw);
|
emit Withdraw(asset, msg.sender, to, amountToWithdraw);
|
||||||
|
|
||||||
return amountToWithdraw;
|
return amountToWithdraw;
|
||||||
|
@ -391,22 +391,22 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
||||||
{
|
{
|
||||||
DataTypes.ReserveData storage reserve = _reserves[asset];
|
DataTypes.ReserveData storage reserve = _reserves[asset];
|
||||||
|
|
||||||
ValidationLogic.validateSetUseReserveAsCollateral(
|
ValidationLogic.validateSetUseReserveAsCollateral(reserve);
|
||||||
reserve,
|
|
||||||
asset,
|
|
||||||
useAsCollateral,
|
|
||||||
_reserves,
|
|
||||||
_usersConfig[msg.sender],
|
|
||||||
_reservesList,
|
|
||||||
_reservesCount,
|
|
||||||
_addressesProvider.getPriceOracle()
|
|
||||||
);
|
|
||||||
|
|
||||||
_usersConfig[msg.sender].setUsingAsCollateral(reserve.id, useAsCollateral);
|
_usersConfig[msg.sender].setUsingAsCollateral(reserve.id, useAsCollateral);
|
||||||
|
|
||||||
if (useAsCollateral) {
|
if (useAsCollateral) {
|
||||||
emit ReserveUsedAsCollateralEnabled(asset, msg.sender);
|
emit ReserveUsedAsCollateralEnabled(asset, msg.sender);
|
||||||
} else {
|
} else {
|
||||||
|
ValidationLogic.validateHealthFactor(
|
||||||
|
msg.sender,
|
||||||
|
_reserves,
|
||||||
|
_usersConfig[msg.sender],
|
||||||
|
_reservesList,
|
||||||
|
_reservesCount,
|
||||||
|
_addressesProvider.getPriceOracle()
|
||||||
|
);
|
||||||
|
|
||||||
emit ReserveUsedAsCollateralDisabled(asset, msg.sender);
|
emit ReserveUsedAsCollateralDisabled(asset, msg.sender);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -713,7 +713,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dev Returns the fee on flash loans
|
* @dev Returns the fee on flash loans
|
||||||
*/
|
*/
|
||||||
function FLASHLOAN_PREMIUM_TOTAL() public view returns (uint256) {
|
function FLASHLOAN_PREMIUM_TOTAL() public view returns (uint256) {
|
||||||
return _flashLoanPremiumTotal;
|
return _flashLoanPremiumTotal;
|
||||||
|
@ -746,7 +746,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
||||||
) external override whenNotPaused {
|
) external override whenNotPaused {
|
||||||
require(msg.sender == _reserves[asset].aTokenAddress, Errors.LP_CALLER_MUST_BE_AN_ATOKEN);
|
require(msg.sender == _reserves[asset].aTokenAddress, Errors.LP_CALLER_MUST_BE_AN_ATOKEN);
|
||||||
|
|
||||||
ValidationLogic.validateTransfer(
|
ValidationLogic.validateHealthFactor(
|
||||||
from,
|
from,
|
||||||
_reserves,
|
_reserves,
|
||||||
_usersConfig[from],
|
_usersConfig[from],
|
||||||
|
|
|
@ -30,7 +30,6 @@ library Errors {
|
||||||
string public constant VL_RESERVE_FROZEN = '3'; // 'Action cannot be performed because the reserve is frozen'
|
string public constant VL_RESERVE_FROZEN = '3'; // 'Action cannot be performed because the reserve is frozen'
|
||||||
string public constant VL_CURRENT_AVAILABLE_LIQUIDITY_NOT_ENOUGH = '4'; // 'The current liquidity is not enough'
|
string public constant VL_CURRENT_AVAILABLE_LIQUIDITY_NOT_ENOUGH = '4'; // 'The current liquidity is not enough'
|
||||||
string public constant VL_NOT_ENOUGH_AVAILABLE_USER_BALANCE = '5'; // 'User cannot withdraw more than the available balance'
|
string public constant VL_NOT_ENOUGH_AVAILABLE_USER_BALANCE = '5'; // 'User cannot withdraw more than the available balance'
|
||||||
string public constant VL_TRANSFER_NOT_ALLOWED = '6'; // 'Transfer cannot be allowed.'
|
|
||||||
string public constant VL_BORROWING_NOT_ENABLED = '7'; // 'Borrowing is not enabled'
|
string public constant VL_BORROWING_NOT_ENABLED = '7'; // 'Borrowing is not enabled'
|
||||||
string public constant VL_INVALID_INTEREST_RATE_MODE_SELECTED = '8'; // 'Invalid interest rate mode selected'
|
string public constant VL_INVALID_INTEREST_RATE_MODE_SELECTED = '8'; // 'Invalid interest rate mode selected'
|
||||||
string public constant VL_COLLATERAL_BALANCE_IS_0 = '9'; // 'The collateral balance is 0'
|
string public constant VL_COLLATERAL_BALANCE_IS_0 = '9'; // 'The collateral balance is 0'
|
||||||
|
|
|
@ -28,94 +28,6 @@ library GenericLogic {
|
||||||
|
|
||||||
uint256 public constant HEALTH_FACTOR_LIQUIDATION_THRESHOLD = 1 ether;
|
uint256 public constant HEALTH_FACTOR_LIQUIDATION_THRESHOLD = 1 ether;
|
||||||
|
|
||||||
struct balanceDecreaseAllowedLocalVars {
|
|
||||||
uint256 decimals;
|
|
||||||
uint256 liquidationThreshold;
|
|
||||||
uint256 totalCollateralInETH;
|
|
||||||
uint256 totalDebtInETH;
|
|
||||||
uint256 avgLiquidationThreshold;
|
|
||||||
uint256 amountToDecreaseInETH;
|
|
||||||
uint256 collateralBalanceAfterDecrease;
|
|
||||||
uint256 liquidationThresholdAfterDecrease;
|
|
||||||
uint256 healthFactorAfterDecrease;
|
|
||||||
bool reserveUsageAsCollateralEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @dev Checks if a specific balance decrease is allowed
|
|
||||||
* (i.e. doesn't bring the user borrow position health factor under HEALTH_FACTOR_LIQUIDATION_THRESHOLD)
|
|
||||||
* @param asset The address of the underlying asset of the reserve
|
|
||||||
* @param user The address of the user
|
|
||||||
* @param amount The amount to decrease
|
|
||||||
* @param reservesData The data of all the reserves
|
|
||||||
* @param userConfig The user configuration
|
|
||||||
* @param reserves The list of all the active reserves
|
|
||||||
* @param oracle The address of the oracle contract
|
|
||||||
* @return true if the decrease of the balance is allowed
|
|
||||||
**/
|
|
||||||
function balanceDecreaseAllowed(
|
|
||||||
address asset,
|
|
||||||
address user,
|
|
||||||
uint256 amount,
|
|
||||||
mapping(address => DataTypes.ReserveData) storage reservesData,
|
|
||||||
DataTypes.UserConfigurationMap calldata userConfig,
|
|
||||||
mapping(uint256 => address) storage reserves,
|
|
||||||
uint256 reservesCount,
|
|
||||||
address oracle
|
|
||||||
) external view returns (bool) {
|
|
||||||
if (!userConfig.isBorrowingAny() || !userConfig.isUsingAsCollateral(reservesData[asset].id)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
balanceDecreaseAllowedLocalVars memory vars;
|
|
||||||
|
|
||||||
(, vars.liquidationThreshold, , vars.decimals, ) = reservesData[asset]
|
|
||||||
.configuration
|
|
||||||
.getParams();
|
|
||||||
|
|
||||||
if (vars.liquidationThreshold == 0) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
(
|
|
||||||
vars.totalCollateralInETH,
|
|
||||||
vars.totalDebtInETH,
|
|
||||||
,
|
|
||||||
vars.avgLiquidationThreshold,
|
|
||||||
|
|
||||||
) = calculateUserAccountData(user, reservesData, userConfig, reserves, reservesCount, oracle);
|
|
||||||
|
|
||||||
if (vars.totalDebtInETH == 0) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
vars.amountToDecreaseInETH = IPriceOracleGetter(oracle).getAssetPrice(asset).mul(amount).div(
|
|
||||||
10**vars.decimals
|
|
||||||
);
|
|
||||||
|
|
||||||
vars.collateralBalanceAfterDecrease = vars.totalCollateralInETH.sub(vars.amountToDecreaseInETH);
|
|
||||||
|
|
||||||
//if there is a borrow, there can't be 0 collateral
|
|
||||||
if (vars.collateralBalanceAfterDecrease == 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
vars.liquidationThresholdAfterDecrease = vars
|
|
||||||
.totalCollateralInETH
|
|
||||||
.mul(vars.avgLiquidationThreshold)
|
|
||||||
.sub(vars.amountToDecreaseInETH.mul(vars.liquidationThreshold))
|
|
||||||
.div(vars.collateralBalanceAfterDecrease);
|
|
||||||
|
|
||||||
uint256 healthFactorAfterDecrease =
|
|
||||||
calculateHealthFactorFromBalances(
|
|
||||||
vars.collateralBalanceAfterDecrease,
|
|
||||||
vars.totalDebtInETH,
|
|
||||||
vars.liquidationThresholdAfterDecrease
|
|
||||||
);
|
|
||||||
|
|
||||||
return healthFactorAfterDecrease >= GenericLogic.HEALTH_FACTOR_LIQUIDATION_THRESHOLD;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct CalculateUserAccountDataVars {
|
struct CalculateUserAccountDataVars {
|
||||||
uint256 assetPrice;
|
uint256 assetPrice;
|
||||||
uint256 assetUnit;
|
uint256 assetUnit;
|
||||||
|
@ -220,8 +132,7 @@ library GenericLogic {
|
||||||
IERC20(currentReserve.stableDebtTokenAddress).balanceOf(user)
|
IERC20(currentReserve.stableDebtTokenAddress).balanceOf(user)
|
||||||
);
|
);
|
||||||
vars.userDebtETH = vars.assetPrice.mul(vars.userDebt).div(vars.assetUnit);
|
vars.userDebtETH = vars.assetPrice.mul(vars.userDebt).div(vars.assetUnit);
|
||||||
vars.totalDebtInETH = vars.totalDebtInETH.add(vars.userDebtETH);
|
vars.totalDebtInETH = vars.totalDebtInETH.add(vars.userDebtETH);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ library ValidationLogic {
|
||||||
* @param reserve The reserve object on which the user is depositing
|
* @param reserve The reserve object on which the user is depositing
|
||||||
* @param amount The amount to be deposited
|
* @param amount The amount to be deposited
|
||||||
*/
|
*/
|
||||||
function validateDeposit(DataTypes.ReserveData storage reserve, uint256 amount) external view {
|
function validateDeposit(DataTypes.ReserveData storage reserve, uint256 amount) internal view {
|
||||||
(bool isActive, bool isFrozen, , ) = reserve.configuration.getFlags();
|
(bool isActive, bool isFrozen, , ) = reserve.configuration.getFlags();
|
||||||
|
|
||||||
require(amount != 0, Errors.VL_INVALID_AMOUNT);
|
require(amount != 0, Errors.VL_INVALID_AMOUNT);
|
||||||
|
@ -46,46 +46,23 @@ library ValidationLogic {
|
||||||
require(!isFrozen, Errors.VL_RESERVE_FROZEN);
|
require(!isFrozen, Errors.VL_RESERVE_FROZEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dev Validates a withdraw action
|
* @dev Validates a withdraw action
|
||||||
* @param reserveAddress The address of the reserve
|
* @param reserve The reserve object
|
||||||
* @param amount The amount to be withdrawn
|
* @param amount The amount to be withdrawn
|
||||||
* @param userBalance The balance of the user
|
* @param userBalance The balance of the user
|
||||||
* @param reservesData The reserves state
|
|
||||||
* @param userConfig The user configuration
|
|
||||||
* @param reserves The addresses of the reserves
|
|
||||||
* @param reservesCount The number of reserves
|
|
||||||
* @param oracle The price oracle
|
|
||||||
*/
|
*/
|
||||||
function validateWithdraw(
|
function validateWithdraw(
|
||||||
address reserveAddress,
|
DataTypes.ReserveData storage reserve,
|
||||||
uint256 amount,
|
uint256 amount,
|
||||||
uint256 userBalance,
|
uint256 userBalance
|
||||||
mapping(address => DataTypes.ReserveData) storage reservesData,
|
) internal view {
|
||||||
DataTypes.UserConfigurationMap storage userConfig,
|
|
||||||
mapping(uint256 => address) storage reserves,
|
|
||||||
uint256 reservesCount,
|
|
||||||
address oracle
|
|
||||||
) external view {
|
|
||||||
require(amount != 0, Errors.VL_INVALID_AMOUNT);
|
require(amount != 0, Errors.VL_INVALID_AMOUNT);
|
||||||
require(amount <= userBalance, Errors.VL_NOT_ENOUGH_AVAILABLE_USER_BALANCE);
|
require(amount <= userBalance, Errors.VL_NOT_ENOUGH_AVAILABLE_USER_BALANCE);
|
||||||
|
|
||||||
(bool isActive, , , ) = reservesData[reserveAddress].configuration.getFlags();
|
(bool isActive, , , ) = reserve.configuration.getFlags();
|
||||||
require(isActive, Errors.VL_NO_ACTIVE_RESERVE);
|
require(isActive, Errors.VL_NO_ACTIVE_RESERVE);
|
||||||
|
|
||||||
require(
|
|
||||||
GenericLogic.balanceDecreaseAllowed(
|
|
||||||
reserveAddress,
|
|
||||||
msg.sender,
|
|
||||||
amount,
|
|
||||||
reservesData,
|
|
||||||
userConfig,
|
|
||||||
reserves,
|
|
||||||
reservesCount,
|
|
||||||
oracle
|
|
||||||
),
|
|
||||||
Errors.VL_TRANSFER_NOT_ALLOWED
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ValidateBorrowLocalVars {
|
struct ValidateBorrowLocalVars {
|
||||||
|
@ -130,7 +107,7 @@ library ValidationLogic {
|
||||||
mapping(uint256 => address) storage reserves,
|
mapping(uint256 => address) storage reserves,
|
||||||
uint256 reservesCount,
|
uint256 reservesCount,
|
||||||
address oracle
|
address oracle
|
||||||
) external view {
|
) internal view {
|
||||||
ValidateBorrowLocalVars memory vars;
|
ValidateBorrowLocalVars memory vars;
|
||||||
|
|
||||||
(vars.isActive, vars.isFrozen, vars.borrowingEnabled, vars.stableRateBorrowingEnabled) = reserve
|
(vars.isActive, vars.isFrozen, vars.borrowingEnabled, vars.stableRateBorrowingEnabled) = reserve
|
||||||
|
@ -227,7 +204,7 @@ library ValidationLogic {
|
||||||
address onBehalfOf,
|
address onBehalfOf,
|
||||||
uint256 stableDebt,
|
uint256 stableDebt,
|
||||||
uint256 variableDebt
|
uint256 variableDebt
|
||||||
) external view {
|
) internal view {
|
||||||
bool isActive = reserve.configuration.getActive();
|
bool isActive = reserve.configuration.getActive();
|
||||||
|
|
||||||
require(isActive, Errors.VL_NO_ACTIVE_RESERVE);
|
require(isActive, Errors.VL_NO_ACTIVE_RESERVE);
|
||||||
|
@ -306,7 +283,7 @@ library ValidationLogic {
|
||||||
IERC20 stableDebtToken,
|
IERC20 stableDebtToken,
|
||||||
IERC20 variableDebtToken,
|
IERC20 variableDebtToken,
|
||||||
address aTokenAddress
|
address aTokenAddress
|
||||||
) external view {
|
) internal view {
|
||||||
(bool isActive, , , ) = reserve.configuration.getFlags();
|
(bool isActive, , , ) = reserve.configuration.getFlags();
|
||||||
|
|
||||||
require(isActive, Errors.VL_NO_ACTIVE_RESERVE);
|
require(isActive, Errors.VL_NO_ACTIVE_RESERVE);
|
||||||
|
@ -335,40 +312,13 @@ library ValidationLogic {
|
||||||
/**
|
/**
|
||||||
* @dev Validates the action of setting an asset as collateral
|
* @dev Validates the action of setting an asset as collateral
|
||||||
* @param reserve The state of the reserve that the user is enabling or disabling as collateral
|
* @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 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(
|
function validateSetUseReserveAsCollateral(
|
||||||
DataTypes.ReserveData storage reserve,
|
DataTypes.ReserveData storage reserve
|
||||||
address reserveAddress,
|
) internal view {
|
||||||
bool useAsCollateral,
|
|
||||||
mapping(address => DataTypes.ReserveData) storage reservesData,
|
|
||||||
DataTypes.UserConfigurationMap storage userConfig,
|
|
||||||
mapping(uint256 => address) storage reserves,
|
|
||||||
uint256 reservesCount,
|
|
||||||
address oracle
|
|
||||||
) external view {
|
|
||||||
uint256 underlyingBalance = IERC20(reserve.aTokenAddress).balanceOf(msg.sender);
|
uint256 underlyingBalance = IERC20(reserve.aTokenAddress).balanceOf(msg.sender);
|
||||||
|
|
||||||
require(underlyingBalance > 0, Errors.VL_UNDERLYING_BALANCE_NOT_GREATER_THAN_0);
|
require(underlyingBalance > 0, Errors.VL_UNDERLYING_BALANCE_NOT_GREATER_THAN_0);
|
||||||
|
|
||||||
require(
|
|
||||||
useAsCollateral ||
|
|
||||||
GenericLogic.balanceDecreaseAllowed(
|
|
||||||
reserveAddress,
|
|
||||||
msg.sender,
|
|
||||||
underlyingBalance,
|
|
||||||
reservesData,
|
|
||||||
userConfig,
|
|
||||||
reserves,
|
|
||||||
reservesCount,
|
|
||||||
oracle
|
|
||||||
),
|
|
||||||
Errors.VL_DEPOSIT_ALREADY_IN_USE
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -436,14 +386,14 @@ library ValidationLogic {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dev Validates an aToken transfer
|
* @dev Validates the health factor of a user
|
||||||
* @param from The user from which the aTokens are being transferred
|
* @param from The user from which the aTokens are being transferred
|
||||||
* @param reservesData The state of all the reserves
|
* @param reservesData The state of all the reserves
|
||||||
* @param userConfig The state of the user for the specific reserve
|
* @param userConfig The state of the user for the specific reserve
|
||||||
* @param reserves The addresses of all the active reserves
|
* @param reserves The addresses of all the active reserves
|
||||||
* @param oracle The price oracle
|
* @param oracle The price oracle
|
||||||
*/
|
*/
|
||||||
function validateTransfer(
|
function validateHealthFactor(
|
||||||
address from,
|
address from,
|
||||||
mapping(address => DataTypes.ReserveData) storage reservesData,
|
mapping(address => DataTypes.ReserveData) storage reservesData,
|
||||||
DataTypes.UserConfigurationMap storage userConfig,
|
DataTypes.UserConfigurationMap storage userConfig,
|
||||||
|
@ -463,7 +413,7 @@ library ValidationLogic {
|
||||||
|
|
||||||
require(
|
require(
|
||||||
healthFactor >= GenericLogic.HEALTH_FACTOR_LIQUIDATION_THRESHOLD,
|
healthFactor >= GenericLogic.HEALTH_FACTOR_LIQUIDATION_THRESHOLD,
|
||||||
Errors.VL_TRANSFER_NOT_ALLOWED
|
Errors.VL_HEALTH_FACTOR_LOWER_THAN_LIQUIDATION_THRESHOLD
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user