From 1d67923ab5269c88594ac2145e737722021d0459 Mon Sep 17 00:00:00 2001 From: The3D Date: Mon, 28 Jun 2021 18:59:16 +0200 Subject: [PATCH] feat: prepared for liquidation protocol fee configuration --- .../interfaces/ILendingPoolConfigurator.sol | 14 ++++++++++ .../LendingPoolCollateralManager.sol | 27 +++++++++++-------- .../lendingpool/LendingPoolConfigurator.sol | 15 +++++++++++ .../configuration/ReserveConfiguration.sol | 24 +++++++++++++++++ 4 files changed, 69 insertions(+), 11 deletions(-) diff --git a/contracts/interfaces/ILendingPoolConfigurator.sol b/contracts/interfaces/ILendingPoolConfigurator.sol index 634bde26..fd91856c 100644 --- a/contracts/interfaces/ILendingPoolConfigurator.sol +++ b/contracts/interfaces/ILendingPoolConfigurator.sol @@ -159,6 +159,13 @@ interface ILendingPoolConfigurator { **/ event SupplyCapChanged(address indexed asset, uint256 supplyCap); + /** + * @dev Emitted when the protocol fee on liquidation is updated + * @param asset The address of the underlying asset of the reserve + * @param fee The new fee + **/ + event LiquidationProtocolFeeChanged(address indexed asset, uint256 fee); + /** * @dev Emitted when the reserve decimals are updated * @param asset The address of the underlying asset of the reserve @@ -387,6 +394,13 @@ interface ILendingPoolConfigurator { **/ function setSupplyCap(address asset, uint256 supplyCap) external; + /** + * @dev Sets the protocol fee on liquidation + * @param asset The address of the underlying asset of the reserve + * @param fee The fee on liquidaton bonus + **/ + function setReserveLiquidationProtocolFee(address asset, uint256 fee) external; + /** * @dev Registers a new admin with rights on risk related configurations * @param admin The address of the admin to register diff --git a/contracts/protocol/lendingpool/LendingPoolCollateralManager.sol b/contracts/protocol/lendingpool/LendingPoolCollateralManager.sol index 413cd9c8..efac0719 100644 --- a/contracts/protocol/lendingpool/LendingPoolCollateralManager.sol +++ b/contracts/protocol/lendingpool/LendingPoolCollateralManager.sol @@ -40,10 +40,10 @@ contract LendingPoolCollateralManager is using PercentageMath for uint256; using ReserveLogic for DataTypes.ReserveCache; - uint256 public constant STD_LIQUIDATION_CLOSE_FACTOR = 5000; + uint256 public constant DEFAULT_LIQUIDATION_CLOSE_FACTOR = 5000; uint256 public constant MAX_LIQUIDATION_CLOSE_FACTOR = 10000; - uint256 public constant CLOSE_FACTOR_HF_THRESHOLD = 0.95 * 1e18; + uint256 public constant CLOSE_FACTOR_HF_THRESHOLD = 0.98 * 1e18; struct LiquidationCallLocalVars { uint256 userCollateralBalance; @@ -59,6 +59,7 @@ contract LendingPoolCollateralManager is uint256 healthFactor; uint256 liquidatorPreviousATokenBalance; uint256 closeFactor; + uint256 protocolFee; IAToken collateralAtoken; IPriceOracleGetter oracle; bool isCollateralEnabled; @@ -130,7 +131,7 @@ contract LendingPoolCollateralManager is vars.userCollateralBalance = vars.collateralAtoken.balanceOf(user); vars.closeFactor = vars.healthFactor > CLOSE_FACTOR_HF_THRESHOLD - ? STD_LIQUIDATION_CLOSE_FACTOR + ? DEFAULT_LIQUIDATION_CLOSE_FACTOR : MAX_LIQUIDATION_CLOSE_FACTOR; vars.maxLiquidatableDebt = vars.userStableDebt.add(vars.userVariableDebt).percentMul( @@ -143,7 +144,8 @@ contract LendingPoolCollateralManager is ( vars.maxCollateralToLiquidate, - vars.debtAmountNeeded + vars.debtAmountNeeded, + vars.protocolFee ) = _calculateAvailableCollateralToLiquidate( collateralReserve, debtReserveCache, @@ -271,6 +273,9 @@ contract LendingPoolCollateralManager is uint256 maxAmountCollateralToLiquidate; uint256 debtAssetDecimals; uint256 collateralDecimals; + uint256 collateralProtocolFee; + uint256 collateralAmount; + uint256 debtAmountNeeded; } /** @@ -297,9 +302,7 @@ contract LendingPoolCollateralManager is uint256 userCollateralBalance, IPriceOracleGetter oracle ) internal view returns (uint256, uint256) { - uint256 collateralAmount = 0; - uint256 debtAmountNeeded = 0; - + AvailableCollateralToLiquidateLocalVars memory vars; vars.collateralPrice = oracle.getAssetPrice(collateralAsset); @@ -308,8 +311,10 @@ contract LendingPoolCollateralManager is (, , vars.liquidationBonus, vars.collateralDecimals, ) = collateralReserve .configuration .getParams(); + vars.debtAssetDecimals = debtReserveCache.reserveConfiguration.getDecimalsMemory(); + // This is the maximum possible amount of the selected collateral that can be liquidated, given the // max amount of liquidatable debt vars.maxAmountCollateralToLiquidate = vars @@ -320,16 +325,16 @@ contract LendingPoolCollateralManager is .div(vars.collateralPrice.mul(10**vars.debtAssetDecimals)); if (vars.maxAmountCollateralToLiquidate > userCollateralBalance) { - collateralAmount = userCollateralBalance; - debtAmountNeeded = vars + vars.collateralAmount = userCollateralBalance; + vars.debtAmountNeeded = vars .collateralPrice .mul(collateralAmount) .mul(10**vars.debtAssetDecimals) .div(vars.debtAssetPrice.mul(10**vars.collateralDecimals)) .percentDiv(vars.liquidationBonus); } else { - collateralAmount = vars.maxAmountCollateralToLiquidate; - debtAmountNeeded = debtToCover; + vars.collateralAmount = vars.maxAmountCollateralToLiquidate; + vars.debtAmountNeeded = debtToCover; } return (collateralAmount, debtAmountNeeded); } diff --git a/contracts/protocol/lendingpool/LendingPoolConfigurator.sol b/contracts/protocol/lendingpool/LendingPoolConfigurator.sol index f8b730ee..00e59d31 100644 --- a/contracts/protocol/lendingpool/LendingPoolConfigurator.sol +++ b/contracts/protocol/lendingpool/LendingPoolConfigurator.sol @@ -442,6 +442,21 @@ contract LendingPoolConfigurator is VersionedInitializable, ILendingPoolConfigur emit ReserveFactorChanged(asset, reserveFactor); } + /// @inheritdoc ILendingPoolConfigurator + function setReserveLiquidationProtocolFee(address asset, uint256 fee) + external + override + onlyRiskOrPoolAdmins + { + DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset); + + currentConfig.setLiquidationProtocolFee(fee); + + _pool.setConfiguration(asset, currentConfig.data); + + emit LiquidationProtocolFeeChanged(asset, fee); + } + ///@inheritdoc ILendingPoolConfigurator function setBorrowCap(address asset, uint256 borrowCap) external override onlyRiskOrPoolAdmins { DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset); diff --git a/contracts/protocol/libraries/configuration/ReserveConfiguration.sol b/contracts/protocol/libraries/configuration/ReserveConfiguration.sol index b369aaee..feaaf3bc 100644 --- a/contracts/protocol/libraries/configuration/ReserveConfiguration.sol +++ b/contracts/protocol/libraries/configuration/ReserveConfiguration.sol @@ -356,6 +356,30 @@ library ReserveConfiguration { return (self.data & ~BORROW_CAP_MASK) >> BORROW_CAP_START_BIT_POSITION; } + /** + * @dev Sets the borrow cap of the reserve + * @param self The reserve configuration + * @param borrowCap The borrow cap + **/ + function setLiquidationProtocolFee(DataTypes.ReserveConfigurationMap memory self, uint256 borrowCap) + internal + pure + { + } + + /** + * @dev Gets the liquidation protocol fee + * @param self The reserve configuration + * @return The liquidation protocol fee + **/ + function getLiquidationProtocolFee(DataTypes.ReserveConfigurationMap storage self) + internal + view + returns (uint256) + { + return 0; + } + /** * @dev Sets the supply cap of the reserve * @param self The reserve configuration