mirror of
				https://github.com/Instadapp/aave-protocol-v2.git
				synced 2024-07-29 21:47:30 +00:00 
			
		
		
		
	- Refactored validation logic of liquidationCall() and repayWithCollateral() to ValidationLogic.
This commit is contained in:
		
							parent
							
								
									0911f907a8
								
							
						
					
					
						commit
						e2500d1532
					
				| 
						 | 
				
			
			@ -385,7 +385,6 @@ contract LendingPool is VersionedInitializable, ILendingPool {
 | 
			
		|||
    uint256 purchaseAmount,
 | 
			
		||||
    bool receiveAToken
 | 
			
		||||
  ) external override {
 | 
			
		||||
    ValidationLogic.validateLiquidation(_reserves[collateral], _reserves[asset]);
 | 
			
		||||
    
 | 
			
		||||
    address liquidationManager = _addressesProvider.getLendingPoolLiquidationManager();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -446,8 +445,6 @@ contract LendingPool is VersionedInitializable, ILendingPool {
 | 
			
		|||
    require(!_flashLiquidationLocked, Errors.REENTRANCY_NOT_ALLOWED);
 | 
			
		||||
    _flashLiquidationLocked = true;
 | 
			
		||||
 | 
			
		||||
    ValidationLogic.validateLiquidation(_reserves[collateral], _reserves[principal]);
 | 
			
		||||
 | 
			
		||||
    address liquidationManager = _addressesProvider.getLendingPoolLiquidationManager();
 | 
			
		||||
 | 
			
		||||
    //solium-disable-next-line
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,6 +21,7 @@ import {PercentageMath} from '../libraries/math/PercentageMath.sol';
 | 
			
		|||
import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol';
 | 
			
		||||
import {ISwapAdapter} from '../interfaces/ISwapAdapter.sol';
 | 
			
		||||
import {Errors} from '../libraries/helpers/Errors.sol';
 | 
			
		||||
import {ValidationLogic} from '../libraries/logic/ValidationLogic.sol';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @title LendingPoolLiquidationManager contract
 | 
			
		||||
| 
						 | 
				
			
			@ -88,15 +89,6 @@ contract LendingPoolLiquidationManager is VersionedInitializable {
 | 
			
		|||
    uint256 swappedCollateralAmount
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  enum LiquidationErrors {
 | 
			
		||||
    NO_ERROR,
 | 
			
		||||
    NO_COLLATERAL_AVAILABLE,
 | 
			
		||||
    COLLATERAL_CANNOT_BE_LIQUIDATED,
 | 
			
		||||
    CURRRENCY_NOT_BORROWED,
 | 
			
		||||
    HEALTH_FACTOR_ABOVE_THRESHOLD,
 | 
			
		||||
    NOT_ENOUGH_LIQUIDITY
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  struct LiquidationCallLocalVars {
 | 
			
		||||
    uint256 userCollateralBalance;
 | 
			
		||||
    uint256 userStableDebt;
 | 
			
		||||
| 
						 | 
				
			
			@ -112,6 +104,9 @@ contract LendingPoolLiquidationManager is VersionedInitializable {
 | 
			
		|||
    uint256 healthFactor;
 | 
			
		||||
    IAToken collateralAtoken;
 | 
			
		||||
    bool isCollateralEnabled;
 | 
			
		||||
    address principalAToken;
 | 
			
		||||
    uint256 errorCode;
 | 
			
		||||
    string errorMsg;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
| 
						 | 
				
			
			@ -138,8 +133,8 @@ contract LendingPoolLiquidationManager is VersionedInitializable {
 | 
			
		|||
    uint256 purchaseAmount,
 | 
			
		||||
    bool receiveAToken
 | 
			
		||||
  ) external returns (uint256, string memory) {
 | 
			
		||||
    ReserveLogic.ReserveData storage principalReserve = reserves[principal];
 | 
			
		||||
    ReserveLogic.ReserveData storage collateralReserve = reserves[collateral];
 | 
			
		||||
    ReserveLogic.ReserveData storage principalReserve = reserves[principal];
 | 
			
		||||
    UserConfiguration.Map storage userConfig = usersConfig[user];
 | 
			
		||||
 | 
			
		||||
    LiquidationCallLocalVars memory vars;
 | 
			
		||||
| 
						 | 
				
			
			@ -152,43 +147,29 @@ contract LendingPoolLiquidationManager is VersionedInitializable {
 | 
			
		|||
      addressesProvider.getPriceOracle()
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    if (vars.healthFactor >= GenericLogic.HEALTH_FACTOR_LIQUIDATION_THRESHOLD) {
 | 
			
		||||
      return (
 | 
			
		||||
        uint256(LiquidationErrors.HEALTH_FACTOR_ABOVE_THRESHOLD),
 | 
			
		||||
        Errors.HEALTH_FACTOR_NOT_BELOW_THRESHOLD
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    vars.collateralAtoken = IAToken(collateralReserve.aTokenAddress);
 | 
			
		||||
 | 
			
		||||
    vars.userCollateralBalance = vars.collateralAtoken.balanceOf(user);
 | 
			
		||||
 | 
			
		||||
    vars.isCollateralEnabled =
 | 
			
		||||
      collateralReserve.configuration.getLiquidationThreshold() > 0 &&
 | 
			
		||||
      userConfig.isUsingAsCollateral(collateralReserve.index);
 | 
			
		||||
 | 
			
		||||
    //if collateral isn't enabled as collateral by user, it cannot be liquidated
 | 
			
		||||
    if (!vars.isCollateralEnabled) {
 | 
			
		||||
      return (
 | 
			
		||||
        uint256(LiquidationErrors.COLLATERAL_CANNOT_BE_LIQUIDATED),
 | 
			
		||||
        Errors.COLLATERAL_CANNOT_BE_LIQUIDATED
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //if the user hasn't borrowed the specific currency defined by asset, it cannot be liquidated
 | 
			
		||||
    (vars.userStableDebt, vars.userVariableDebt) = Helpers.getUserCurrentDebt(
 | 
			
		||||
      user,
 | 
			
		||||
      principalReserve
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    if (vars.userStableDebt == 0 && vars.userVariableDebt == 0) {
 | 
			
		||||
      return (
 | 
			
		||||
        uint256(LiquidationErrors.CURRRENCY_NOT_BORROWED),
 | 
			
		||||
        Errors.SPECIFIED_CURRENCY_NOT_BORROWED_BY_USER
 | 
			
		||||
      );
 | 
			
		||||
    (vars.errorCode, vars.errorMsg) = ValidationLogic.validateLiquidationCall(
 | 
			
		||||
      collateralReserve,
 | 
			
		||||
      principalReserve,
 | 
			
		||||
      userConfig,
 | 
			
		||||
      vars.healthFactor,
 | 
			
		||||
      vars.userStableDebt,
 | 
			
		||||
      vars.userVariableDebt
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    if (Errors.LiquidationErrors(vars.errorCode) != Errors.LiquidationErrors.NO_ERROR) {
 | 
			
		||||
      return (vars.errorCode, vars.errorMsg);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //all clear - calculate the max principal amount that can be liquidated
 | 
			
		||||
    vars.collateralAtoken = IAToken(collateralReserve.aTokenAddress);
 | 
			
		||||
 | 
			
		||||
    vars.userCollateralBalance = vars.collateralAtoken.balanceOf(user);
 | 
			
		||||
 | 
			
		||||
    vars.maxPrincipalAmountToLiquidate = vars.userStableDebt.add(vars.userVariableDebt).percentMul(
 | 
			
		||||
      LIQUIDATION_CLOSE_FACTOR_PERCENT
 | 
			
		||||
    );
 | 
			
		||||
| 
						 | 
				
			
			@ -224,7 +205,7 @@ contract LendingPoolLiquidationManager is VersionedInitializable {
 | 
			
		|||
      );
 | 
			
		||||
      if (currentAvailableCollateral < vars.maxCollateralToLiquidate) {
 | 
			
		||||
        return (
 | 
			
		||||
          uint256(LiquidationErrors.NOT_ENOUGH_LIQUIDITY),
 | 
			
		||||
          uint256(Errors.LiquidationErrors.NOT_ENOUGH_LIQUIDITY),
 | 
			
		||||
          Errors.NOT_ENOUGH_LIQUIDITY_TO_LIQUIDATE
 | 
			
		||||
        );
 | 
			
		||||
      }
 | 
			
		||||
| 
						 | 
				
			
			@ -291,7 +272,7 @@ contract LendingPoolLiquidationManager is VersionedInitializable {
 | 
			
		|||
      receiveAToken
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    return (uint256(LiquidationErrors.NO_ERROR), Errors.NO_ERRORS);
 | 
			
		||||
    return (uint256(Errors.LiquidationErrors.NO_ERROR), Errors.NO_ERRORS);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
| 
						 | 
				
			
			@ -314,9 +295,8 @@ contract LendingPoolLiquidationManager is VersionedInitializable {
 | 
			
		|||
    address receiver,
 | 
			
		||||
    bytes calldata params
 | 
			
		||||
  ) external returns (uint256, string memory) {
 | 
			
		||||
    ReserveLogic.ReserveData storage debtReserve = reserves[principal];
 | 
			
		||||
    ReserveLogic.ReserveData storage collateralReserve = reserves[collateral];
 | 
			
		||||
 | 
			
		||||
    ReserveLogic.ReserveData storage debtReserve = reserves[principal];
 | 
			
		||||
    UserConfiguration.Map storage userConfig = usersConfig[user];
 | 
			
		||||
 | 
			
		||||
    LiquidationCallLocalVars memory vars;
 | 
			
		||||
| 
						 | 
				
			
			@ -329,36 +309,20 @@ contract LendingPoolLiquidationManager is VersionedInitializable {
 | 
			
		|||
      addressesProvider.getPriceOracle()
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    if (
 | 
			
		||||
      msg.sender != user && vars.healthFactor >= GenericLogic.HEALTH_FACTOR_LIQUIDATION_THRESHOLD
 | 
			
		||||
    ) {
 | 
			
		||||
      return (
 | 
			
		||||
        uint256(LiquidationErrors.HEALTH_FACTOR_ABOVE_THRESHOLD),
 | 
			
		||||
        Errors.HEALTH_FACTOR_NOT_BELOW_THRESHOLD
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (msg.sender != user) {
 | 
			
		||||
      vars.isCollateralEnabled =
 | 
			
		||||
        collateralReserve.configuration.getLiquidationThreshold() > 0 &&
 | 
			
		||||
        userConfig.isUsingAsCollateral(collateralReserve.index);
 | 
			
		||||
 | 
			
		||||
      //if collateral isn't enabled as collateral by user, it cannot be liquidated
 | 
			
		||||
      if (!vars.isCollateralEnabled) {
 | 
			
		||||
        return (
 | 
			
		||||
          uint256(LiquidationErrors.COLLATERAL_CANNOT_BE_LIQUIDATED),
 | 
			
		||||
          Errors.COLLATERAL_CANNOT_BE_LIQUIDATED
 | 
			
		||||
        );
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    (vars.userStableDebt, vars.userVariableDebt) = Helpers.getUserCurrentDebt(user, debtReserve);
 | 
			
		||||
 | 
			
		||||
    if (vars.userStableDebt == 0 && vars.userVariableDebt == 0) {
 | 
			
		||||
      return (
 | 
			
		||||
        uint256(LiquidationErrors.CURRRENCY_NOT_BORROWED),
 | 
			
		||||
        Errors.SPECIFIED_CURRENCY_NOT_BORROWED_BY_USER
 | 
			
		||||
      );
 | 
			
		||||
    (vars.errorCode, vars.errorMsg) = ValidationLogic.validateRepayWithCollateral(
 | 
			
		||||
      collateralReserve,
 | 
			
		||||
      debtReserve,
 | 
			
		||||
      userConfig,
 | 
			
		||||
      user,
 | 
			
		||||
      vars.healthFactor,
 | 
			
		||||
      vars.userStableDebt,
 | 
			
		||||
      vars.userVariableDebt
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    if (Errors.LiquidationErrors(vars.errorCode) != Errors.LiquidationErrors.NO_ERROR) {
 | 
			
		||||
      return (vars.errorCode, vars.errorMsg);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    vars.maxPrincipalAmountToLiquidate = vars.userStableDebt.add(vars.userVariableDebt);
 | 
			
		||||
| 
						 | 
				
			
			@ -397,7 +361,7 @@ contract LendingPoolLiquidationManager is VersionedInitializable {
 | 
			
		|||
      usersConfig[user].setUsingAsCollateral(collateralReserve.index, false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    address principalAToken = debtReserve.aTokenAddress;
 | 
			
		||||
    vars.principalAToken = debtReserve.aTokenAddress;
 | 
			
		||||
 | 
			
		||||
    // Notifies the receiver to proceed, sending as param the underlying already transferred
 | 
			
		||||
    ISwapAdapter(receiver).executeOperation(
 | 
			
		||||
| 
						 | 
				
			
			@ -410,8 +374,8 @@ contract LendingPoolLiquidationManager is VersionedInitializable {
 | 
			
		|||
 | 
			
		||||
    //updating debt reserve
 | 
			
		||||
    debtReserve.updateCumulativeIndexesAndTimestamp();
 | 
			
		||||
    debtReserve.updateInterestRates(principal, principalAToken, vars.actualAmountToLiquidate, 0);
 | 
			
		||||
    IERC20(principal).transferFrom(receiver, principalAToken, vars.actualAmountToLiquidate);
 | 
			
		||||
    debtReserve.updateInterestRates(principal, vars.principalAToken, vars.actualAmountToLiquidate, 0);
 | 
			
		||||
    IERC20(principal).transferFrom(receiver, vars.principalAToken, vars.actualAmountToLiquidate);
 | 
			
		||||
 | 
			
		||||
    if (vars.userVariableDebt >= vars.actualAmountToLiquidate) {
 | 
			
		||||
      IVariableDebtToken(debtReserve.variableDebtTokenAddress).burn(
 | 
			
		||||
| 
						 | 
				
			
			@ -443,7 +407,7 @@ contract LendingPoolLiquidationManager is VersionedInitializable {
 | 
			
		|||
      vars.maxCollateralToLiquidate
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    return (uint256(LiquidationErrors.NO_ERROR), Errors.NO_ERRORS);
 | 
			
		||||
    return (uint256(Errors.LiquidationErrors.NO_ERROR), Errors.NO_ERRORS);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  struct AvailableCollateralToLiquidateLocalVars {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -76,4 +76,14 @@ library Errors {
 | 
			
		|||
  string public constant MULTIPLICATION_OVERFLOW = '44';
 | 
			
		||||
  string public constant ADDITION_OVERFLOW = '45';
 | 
			
		||||
  string public constant DIVISION_BY_ZERO = '46';
 | 
			
		||||
 | 
			
		||||
  enum LiquidationErrors {
 | 
			
		||||
    NO_ERROR,
 | 
			
		||||
    NO_COLLATERAL_AVAILABLE,
 | 
			
		||||
    COLLATERAL_CANNOT_BE_LIQUIDATED,
 | 
			
		||||
    CURRRENCY_NOT_BORROWED,
 | 
			
		||||
    HEALTH_FACTOR_ABOVE_THRESHOLD,
 | 
			
		||||
    NOT_ENOUGH_LIQUIDITY,
 | 
			
		||||
    NO_ACTIVE_RESERVE
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,6 +13,7 @@ import {ReserveConfiguration} from '../configuration/ReserveConfiguration.sol';
 | 
			
		|||
import {UserConfiguration} from '../configuration/UserConfiguration.sol';
 | 
			
		||||
import {IPriceOracleGetter} from '../../interfaces/IPriceOracleGetter.sol';
 | 
			
		||||
import {Errors} from '../helpers/Errors.sol';
 | 
			
		||||
import {Helpers} from '../helpers/Helpers.sol';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @title ReserveLogic library
 | 
			
		||||
| 
						 | 
				
			
			@ -331,18 +332,114 @@ library ValidationLogic {
 | 
			
		|||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * @dev Validates configurations for liquidation actions, both liquidationCall() and repayWithCollateral()
 | 
			
		||||
   * @dev Validates the liquidationCall() action
 | 
			
		||||
   * @param collateralReserve The reserve data of the collateral
 | 
			
		||||
   * @param principalReserve The reserve data of the principal
 | 
			
		||||
   * @param userConfig The user configuration
 | 
			
		||||
   * @param userHealthFactor The user's health factor
 | 
			
		||||
   * @param userStableDebt Total stable debt balance of the user
 | 
			
		||||
   * @param userVariableDebt Total variable debt balance of the user
 | 
			
		||||
   **/
 | 
			
		||||
  function validateLiquidation(
 | 
			
		||||
  function validateLiquidationCall(
 | 
			
		||||
    ReserveLogic.ReserveData storage collateralReserve,
 | 
			
		||||
    ReserveLogic.ReserveData storage principalReserve
 | 
			
		||||
  ) internal view {
 | 
			
		||||
    require(
 | 
			
		||||
        collateralReserve.configuration.getActive() && 
 | 
			
		||||
        principalReserve.configuration.getActive(), 
 | 
			
		||||
      Errors.NO_ACTIVE_RESERVE
 | 
			
		||||
    );
 | 
			
		||||
    ReserveLogic.ReserveData storage principalReserve,
 | 
			
		||||
    UserConfiguration.Map storage userConfig,
 | 
			
		||||
    uint256 userHealthFactor,
 | 
			
		||||
    uint256 userStableDebt,
 | 
			
		||||
    uint256 userVariableDebt
 | 
			
		||||
  ) internal view returns(uint256, string memory) {
 | 
			
		||||
    if ( !collateralReserve.configuration.getActive() || !principalReserve.configuration.getActive()) {
 | 
			
		||||
      return (
 | 
			
		||||
        uint256(Errors.LiquidationErrors.NO_ACTIVE_RESERVE),
 | 
			
		||||
        Errors.NO_ACTIVE_RESERVE
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (userHealthFactor >= GenericLogic.HEALTH_FACTOR_LIQUIDATION_THRESHOLD) {
 | 
			
		||||
      return (
 | 
			
		||||
        uint256(Errors.LiquidationErrors.HEALTH_FACTOR_ABOVE_THRESHOLD),
 | 
			
		||||
        Errors.HEALTH_FACTOR_NOT_BELOW_THRESHOLD
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool isCollateralEnabled =
 | 
			
		||||
      collateralReserve.configuration.getLiquidationThreshold() > 0 &&
 | 
			
		||||
      userConfig.isUsingAsCollateral(collateralReserve.index);
 | 
			
		||||
 | 
			
		||||
    //if collateral isn't enabled as collateral by user, it cannot be liquidated
 | 
			
		||||
    if (!isCollateralEnabled) {
 | 
			
		||||
      return (
 | 
			
		||||
        uint256(Errors.LiquidationErrors.COLLATERAL_CANNOT_BE_LIQUIDATED),
 | 
			
		||||
        Errors.COLLATERAL_CANNOT_BE_LIQUIDATED
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (userStableDebt == 0 && userVariableDebt == 0) {
 | 
			
		||||
      return (
 | 
			
		||||
        uint256(Errors.LiquidationErrors.CURRRENCY_NOT_BORROWED),
 | 
			
		||||
        Errors.SPECIFIED_CURRENCY_NOT_BORROWED_BY_USER
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return (uint256(Errors.LiquidationErrors.NO_ERROR), Errors.NO_ERRORS);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * @dev Validates the repayWithCollateral() action
 | 
			
		||||
   * @param collateralReserve The reserve data of the collateral
 | 
			
		||||
   * @param principalReserve The reserve data of the principal
 | 
			
		||||
   * @param userConfig The user configuration
 | 
			
		||||
   * @param user The address of the user
 | 
			
		||||
   * @param userHealthFactor The user's health factor
 | 
			
		||||
   * @param userStableDebt Total stable debt balance of the user
 | 
			
		||||
   * @param userVariableDebt Total variable debt balance of the user
 | 
			
		||||
   **/
 | 
			
		||||
  function validateRepayWithCollateral(
 | 
			
		||||
    ReserveLogic.ReserveData storage collateralReserve,
 | 
			
		||||
    ReserveLogic.ReserveData storage principalReserve,
 | 
			
		||||
    UserConfiguration.Map storage userConfig,
 | 
			
		||||
    address user,
 | 
			
		||||
    uint256 userHealthFactor,
 | 
			
		||||
    uint256 userStableDebt,
 | 
			
		||||
    uint256 userVariableDebt
 | 
			
		||||
  ) internal view returns(uint256, string memory) {
 | 
			
		||||
    if ( !collateralReserve.configuration.getActive() || !principalReserve.configuration.getActive()) {
 | 
			
		||||
      return (
 | 
			
		||||
        uint256(Errors.LiquidationErrors.NO_ACTIVE_RESERVE),
 | 
			
		||||
        Errors.NO_ACTIVE_RESERVE
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (
 | 
			
		||||
      msg.sender != user && userHealthFactor >= GenericLogic.HEALTH_FACTOR_LIQUIDATION_THRESHOLD
 | 
			
		||||
    ) {
 | 
			
		||||
      return (
 | 
			
		||||
        uint256(Errors.LiquidationErrors.HEALTH_FACTOR_ABOVE_THRESHOLD),
 | 
			
		||||
        Errors.HEALTH_FACTOR_NOT_BELOW_THRESHOLD
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (msg.sender != user) {
 | 
			
		||||
      bool isCollateralEnabled =
 | 
			
		||||
        collateralReserve.configuration.getLiquidationThreshold() > 0 &&
 | 
			
		||||
        userConfig.isUsingAsCollateral(collateralReserve.index);
 | 
			
		||||
 | 
			
		||||
      //if collateral isn't enabled as collateral by user, it cannot be liquidated
 | 
			
		||||
      if (!isCollateralEnabled) {
 | 
			
		||||
        return (
 | 
			
		||||
          uint256(Errors.LiquidationErrors.COLLATERAL_CANNOT_BE_LIQUIDATED),
 | 
			
		||||
          Errors.COLLATERAL_CANNOT_BE_LIQUIDATED
 | 
			
		||||
        );
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (userStableDebt == 0 && userVariableDebt == 0) {
 | 
			
		||||
      return (
 | 
			
		||||
        uint256(Errors.LiquidationErrors.CURRRENCY_NOT_BORROWED),
 | 
			
		||||
        Errors.SPECIFIED_CURRENCY_NOT_BORROWED_BY_USER
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return (uint256(Errors.LiquidationErrors.NO_ERROR), Errors.NO_ERRORS);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user