From c2510baa4a0b0039b3806d053274e2c0043da81b Mon Sep 17 00:00:00 2001 From: MerlinEgalite Date: Thu, 22 Sep 2022 10:27:09 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9A=A1=EF=B8=8F=20(#1303)=20Improve=20perfor?= =?UTF-8?q?mance?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contracts/aave-v2/ExitPositionsManager.sol | 34 ++++++++++++------ contracts/aave-v3/ExitPositionsManager.sol | 42 +++++++++++++--------- contracts/compound/PositionsManager.sol | 6 ++-- 3 files changed, 53 insertions(+), 29 deletions(-) diff --git a/contracts/aave-v2/ExitPositionsManager.sol b/contracts/aave-v2/ExitPositionsManager.sol index 76709eeda1..e889a124dc 100644 --- a/contracts/aave-v2/ExitPositionsManager.sol +++ b/contracts/aave-v2/ExitPositionsManager.sol @@ -129,6 +129,7 @@ contract ExitPositionsManager is IExitPositionsManager, PositionsManagerUtils { uint256 borrowedReserveDecimals; // The number of decimals of the borrowed asset in the reserve. uint256 borrowedTokenUnit; // The unit of borrowed token considering its decimals. uint256 closeFactor; // The close factor used during the liquidation. + bool liquidationAllowed; // Whether the liquidation is allowed or not. } // Struct to avoid stack too deep. @@ -223,21 +224,21 @@ contract ExitPositionsManager is IExitPositionsManager, PositionsManagerUtils { _updateIndexes(_poolTokenCollateral); LiquidateVars memory vars; - if (!borrowedMarket.isDeprecated) { - if (!_liquidationAllowed(_borrower)) revert UnauthorisedLiquidate(); - vars.closeFactor = DEFAULT_LIQUIDATION_CLOSE_FACTOR; - } else vars.closeFactor = MAX_BASIS_POINTS; // Allow liquidation of the whole debt. + (vars.closeFactor, vars.liquidationAllowed) = _liquidationAllowed( + _borrower, + borrowedMarket.isDeprecated + ); + if (!vars.liquidationAllowed) revert UnauthorisedLiquidate(); - address tokenBorrowedAddress = market[_poolTokenBorrowed].underlyingToken; uint256 amountToLiquidate = Math.min( _amount, _getUserBorrowBalanceInOf(_poolTokenBorrowed, _borrower).percentMul(vars.closeFactor) // Max liquidatable debt. ); - address tokenCollateralAddress = market[_poolTokenCollateral].underlyingToken; - IPriceOracleGetter oracle = IPriceOracleGetter(addressesProvider.getPriceOracle()); + address tokenCollateralAddress = market[_poolTokenCollateral].underlyingToken; + address tokenBorrowedAddress = market[_poolTokenBorrowed].underlyingToken; { ILendingPool poolMem = pool; (, , vars.liquidationBonus, vars.collateralReserveDecimals, ) = poolMem @@ -690,8 +691,21 @@ contract ExitPositionsManager is IExitPositionsManager, PositionsManagerUtils { /// @dev Checks if the user is liquidatable. /// @param _user The user to check. - /// @return Whether the user is liquidatable or not. - function _liquidationAllowed(address _user) internal returns (bool) { - return _getUserHealthFactor(_user, address(0), 0) < HEALTH_FACTOR_LIQUIDATION_THRESHOLD; + /// @param _isDeprecated Whether the market is deprecated or not. + /// @return closeFactor The close factor to apply. + /// @return liquidationAllowed Whether the liquidation is allowed or not. + function _liquidationAllowed(address _user, bool _isDeprecated) + internal + returns (uint256 closeFactor, bool liquidationAllowed) + { + if (_isDeprecated) { + // Allow liquidation of the whole debt. + closeFactor = MAX_BASIS_POINTS; + liquidationAllowed = true; + } else { + closeFactor = DEFAULT_LIQUIDATION_CLOSE_FACTOR; + liquidationAllowed = (_getUserHealthFactor(_user, address(0), 0) < + HEALTH_FACTOR_LIQUIDATION_THRESHOLD); + } } } diff --git a/contracts/aave-v3/ExitPositionsManager.sol b/contracts/aave-v3/ExitPositionsManager.sol index 0c7dadf856..34f4443333 100644 --- a/contracts/aave-v3/ExitPositionsManager.sol +++ b/contracts/aave-v3/ExitPositionsManager.sol @@ -229,10 +229,11 @@ contract ExitPositionsManager is IExitPositionsManager, PositionsManagerUtils { _updateIndexes(_poolTokenCollateral); LiquidateVars memory vars; - if (!borrowedMarket.isDeprecated) { - (vars.closeFactor, vars.liquidationAllowed) = _liquidationAllowed(_borrower); - if (!vars.liquidationAllowed) revert UnauthorisedLiquidate(); - } else vars.closeFactor = MAX_BASIS_POINTS; // Allow liquidation of the whole debt. + (vars.closeFactor, vars.liquidationAllowed) = _liquidationAllowed( + _borrower, + borrowedMarket.isDeprecated + ); + if (!vars.liquidationAllowed) revert UnauthorisedLiquidate(); vars.amountToLiquidate = Math.min( _amount, @@ -700,23 +701,30 @@ contract ExitPositionsManager is IExitPositionsManager, PositionsManagerUtils { /// @dev Checks if the user is liquidatable. /// @param _user The user to check. + /// @param _isDeprecated Whether the market is deprecated or not. /// @return closeFactor The close factor to apply. /// @return liquidationAllowed Whether the liquidation is allowed or not. - function _liquidationAllowed(address _user) + function _liquidationAllowed(address _user, bool _isDeprecated) internal returns (uint256 closeFactor, bool liquidationAllowed) { - uint256 healthFactor = _getUserHealthFactor(_user, address(0), 0); - address priceOracleSentinel = addressesProvider.getPriceOracleSentinel(); - - closeFactor = healthFactor > MINIMUM_HEALTH_FACTOR_LIQUIDATION_THRESHOLD - ? DEFAULT_LIQUIDATION_CLOSE_FACTOR - : MAX_LIQUIDATION_CLOSE_FACTOR; - - if (priceOracleSentinel != address(0)) - liquidationAllowed = (healthFactor < MINIMUM_HEALTH_FACTOR_LIQUIDATION_THRESHOLD || - (IPriceOracleSentinel(priceOracleSentinel).isLiquidationAllowed() && - healthFactor < HEALTH_FACTOR_LIQUIDATION_THRESHOLD)); - else liquidationAllowed = healthFactor < HEALTH_FACTOR_LIQUIDATION_THRESHOLD; + if (_isDeprecated) { + // Allow liquidation of the whole debt. + closeFactor = MAX_BASIS_POINTS; + liquidationAllowed = true; + } else { + uint256 healthFactor = _getUserHealthFactor(_user, address(0), 0); + address priceOracleSentinel = addressesProvider.getPriceOracleSentinel(); + + closeFactor = healthFactor > MINIMUM_HEALTH_FACTOR_LIQUIDATION_THRESHOLD + ? DEFAULT_LIQUIDATION_CLOSE_FACTOR + : MAX_LIQUIDATION_CLOSE_FACTOR; + + if (priceOracleSentinel != address(0)) + liquidationAllowed = (healthFactor < MINIMUM_HEALTH_FACTOR_LIQUIDATION_THRESHOLD || + (IPriceOracleSentinel(priceOracleSentinel).isLiquidationAllowed() && + healthFactor < HEALTH_FACTOR_LIQUIDATION_THRESHOLD)); + else liquidationAllowed = healthFactor < HEALTH_FACTOR_LIQUIDATION_THRESHOLD; + } } } diff --git a/contracts/compound/PositionsManager.sol b/contracts/compound/PositionsManager.sol index fc9b2ada1e..d62ff2954a 100644 --- a/contracts/compound/PositionsManager.sol +++ b/contracts/compound/PositionsManager.sol @@ -502,10 +502,12 @@ contract PositionsManager is IPositionsManager, MatchingEngine { _updateP2PIndexes(_poolTokenCollateral); LiquidateVars memory vars; - if (!borrowedMarket.isDeprecated) { + if (borrowedMarket.isDeprecated) + vars.closeFactor = WAD; // Allow liquidation of the whole debt. + else { if (!_isLiquidatable(_borrower, address(0), 0, 0)) revert UnauthorisedLiquidate(); vars.closeFactor = comptroller.closeFactorMantissa(); - } else vars.closeFactor = WAD; // Allow liquidation of the whole debt. + } vars.borrowBalance = _getUserBorrowBalanceInOf(_poolTokenBorrowed, _borrower);