@@ -5,6 +5,7 @@ pragma solidity ^0.8.10;
55
66import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol " ;
77import {IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol " ;
8+ import {IERC20Metadata } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol " ;
89import {SafeERC20} from "@1inch/solidity-utils/contracts/libraries/SafeERC20.sol " ;
910
1011import {IPartialLiquidator, IntermediateData, LiquidationResult} from "./interfaces/IPartialLiquidator.sol " ;
@@ -288,34 +289,59 @@ abstract contract AbstractLiquidator is Ownable, IPartialLiquidator {
288289 address underlying = creditManager.underlying ();
289290
290291 CollateralDebtData memory cdd =
291- creditManager.calcDebtAndCollateral (creditAccount, CollateralCalcTask.DEBT_COLLATERAL );
292+ creditManager.calcDebtAndCollateral (creditAccount, CollateralCalcTask.DEBT_COLLATERAL_SAFE_PRICES );
292293
293294 uint256 discount;
294295 uint256 optimalValueSeized;
295296
296297 {
297298 uint256 ltTokenOut = creditManager.liquidationThresholds (tokenOut);
298299
299- (, uint256 feeLiquidation , uint256 liquidationDiscount ,,) = creditManager.fees ();
300- uint256 totalFee = (
301- (PERCENTAGE_FACTOR - liquidationDiscount)
302- * IPartialLiquidationBotV3 (partialLiquidationBot).premiumScaleFactor ()
303- + feeLiquidation * IPartialLiquidationBotV3 (partialLiquidationBot).feeScaleFactor ()
304- ) / PERCENTAGE_FACTOR;
305- discount = PERCENTAGE_FACTOR - totalFee;
300+ discount = _getLiquidationDiscount (creditManager);
306301
307302 optimalValueSeized = (
308303 CreditLogic.calcTotalDebt (cdd) * hfOptimal
309304 - priceOracle.convertFromUSD (cdd.twvUSD, underlying) * PERCENTAGE_FACTOR
310305 ) / (discount * hfOptimal / PERCENTAGE_FACTOR - ltTokenOut);
311306 }
312307
313- uint256 optimalAmount = priceOracle. convert (optimalValueSeized, underlying, tokenOut);
314- uint256 repaidAmount = optimalValueSeized * discount / PERCENTAGE_FACTOR ;
308+ ( uint256 optimalAmount , uint256 repaidAmount ) =
309+ _getAmounts ( optimalValueSeized, underlying, tokenOut, creditManager, priceOracle) ;
315310
316311 return _adjustToDebtLimits (creditManager, optimalAmount, repaidAmount, CreditLogic.calcTotalDebt (cdd));
317312 }
318313
314+ function _getLiquidationDiscount (ICreditManagerV3 creditManager ) internal view returns (uint256 ) {
315+ (, uint256 feeLiquidation , uint256 liquidationDiscount ,,) = creditManager.fees ();
316+ uint256 totalFee = (
317+ (PERCENTAGE_FACTOR - liquidationDiscount)
318+ * IPartialLiquidationBotV3 (partialLiquidationBot).premiumScaleFactor ()
319+ + feeLiquidation * IPartialLiquidationBotV3 (partialLiquidationBot).feeScaleFactor ()
320+ ) / PERCENTAGE_FACTOR;
321+ return PERCENTAGE_FACTOR - totalFee;
322+ }
323+
324+ function _getAmounts (
325+ uint256 optimalValueSeized ,
326+ address underlying ,
327+ address tokenOut ,
328+ ICreditManagerV3 creditManager ,
329+ IPriceOracleV3 priceOracle
330+ ) internal view returns (uint256 , uint256 ) {
331+ uint256 discount = _getLiquidationDiscount (creditManager);
332+ uint256 optimalAmount = _safeConvert (priceOracle, optimalValueSeized, underlying, tokenOut);
333+ uint256 repaidAmount = priceOracle.convert (optimalAmount, tokenOut, underlying) * discount / PERCENTAGE_FACTOR;
334+
335+ return (optimalAmount, repaidAmount);
336+ }
337+
338+ function _getRepaidAmount (uint256 chargedAmount , ICreditManagerV3 creditManager ) internal view returns (uint256 ) {
339+ (, uint256 feeLiquidation ,,,) = creditManager.fees ();
340+ uint256 partialFeeLiquidation =
341+ feeLiquidation * IPartialLiquidationBotV3 (partialLiquidationBot).feeScaleFactor () / PERCENTAGE_FACTOR;
342+ return chargedAmount * (PERCENTAGE_FACTOR - partialFeeLiquidation) / PERCENTAGE_FACTOR;
343+ }
344+
319345 function _getChargedAmount (uint256 repaidAmount , ICreditManagerV3 creditManager ) internal view returns (uint256 ) {
320346 (, uint256 feeLiquidation ,,,) = creditManager.fees ();
321347 uint256 partialFeeLiquidation =
@@ -359,6 +385,17 @@ abstract contract AbstractLiquidator is Ownable, IPartialLiquidator {
359385 }
360386 }
361387
388+ function _safeConvert (IPriceOracleV3 priceOracle , uint256 amount , address underlying , address tokenOut )
389+ internal
390+ view
391+ returns (uint256 )
392+ {
393+ uint256 underlyingUSD = priceOracle.convertToUSD (amount, underlying);
394+ uint256 tokenOutPrice = priceOracle.getPriceSafe (tokenOut);
395+ uint256 tokenOutScale = 10 ** IERC20Metadata (tokenOut).decimals ();
396+ return underlyingUSD * tokenOutScale / tokenOutPrice;
397+ }
398+
362399 function setRouter (address newRouter ) external onlyOwner {
363400 if (router == newRouter) return ;
364401 router = newRouter;
0 commit comments