From b1ec357362cd7b6a21b9cfc7b619de4b6316c99a Mon Sep 17 00:00:00 2001 From: peyha Date: Mon, 7 Oct 2024 10:27:26 +0200 Subject: [PATCH 1/3] doc: readme parameter restriction --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index b53ced1..b3a6f87 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,17 @@ The two main use-cases are: 1. Using normal fixed parameters when `preLIF1 = preLIF2` and `preLCF1 = preLCF2`. 2. Using health dependent liquidation when either `preLIF1 < preLIF2` or `preLCF1 < preLCF2`, similar to a Quasi Dutch Auction (as in [Euler liquidations](https://docs-v1.euler.finance/getting-started/white-paper#liquidations)). + +### Pre-liquidation parameters restrictions + +The PreLiquidation smart-contract enforces the following properties: +- preLltv < LLTV; +- preLCF1 <= preLCF2; +- 1 <= preLIF1 <= preLIF2 <= 1 / LLTV. +Note: it is not mandatory that `preLCF1 <= 1` and `preLCF1 <= 1` hold. +Indeed without this, the pre-liquidation close factor can reach 100% before the position is liquidatable allowing additionnal pre-liquidation close factor configurations. +A pre-liquidation close factor higher than 100% means that the whole position is pre-liquidatable. + ### `onPreLiquidate` callback By calling `preLiquidate` with a smart contract that implements the `IPreLiquidationCallback` interface, the liquidator can be called back. From 3d70ac5e8aa2097b8cbbc1dfb3395aef067956cc Mon Sep 17 00:00:00 2001 From: peyha Date: Mon, 7 Oct 2024 10:56:54 +0200 Subject: [PATCH 2/3] feat: implement preLCF1 <= 1 restriction --- README.md | 1 + src/PreLiquidation.sol | 2 ++ src/libraries/ErrorsLib.sol | 2 ++ test/PreLiquidationErrorTest.sol | 18 +++++++++++++++++- 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b3a6f87..2762953 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,7 @@ The two main use-cases are: The PreLiquidation smart-contract enforces the following properties: - preLltv < LLTV; - preLCF1 <= preLCF2; +- preLFC1 <= 1; - 1 <= preLIF1 <= preLIF2 <= 1 / LLTV. Note: it is not mandatory that `preLCF1 <= 1` and `preLCF1 <= 1` hold. Indeed without this, the pre-liquidation close factor can reach 100% before the position is liquidatable allowing additionnal pre-liquidation close factor configurations. diff --git a/src/PreLiquidation.sol b/src/PreLiquidation.sol index a1f37c2..6222d36 100644 --- a/src/PreLiquidation.sol +++ b/src/PreLiquidation.sol @@ -79,12 +79,14 @@ contract PreLiquidation is IPreLiquidation, IMorphoRepayCallback { /// @dev The following requirements should be met: /// - preLltv < LLTV; /// - preLCF1 <= preLCF2; + /// - preLCF1 <= 1 /// - 1 <= preLIF1 <= preLIF2 <= 1 / LLTV. constructor(address morpho, Id id, PreLiquidationParams memory _preLiquidationParams) { require(IMorpho(morpho).market(id).lastUpdate != 0, ErrorsLib.NonexistentMarket()); MarketParams memory _marketParams = IMorpho(morpho).idToMarketParams(id); require(_preLiquidationParams.preLltv < _marketParams.lltv, ErrorsLib.PreLltvTooHigh()); require(_preLiquidationParams.preLCF1 <= _preLiquidationParams.preLCF2, ErrorsLib.PreLCFDecreasing()); + require(_preLiquidationParams.preLCF1 <= WAD, ErrorsLib.PreLCFTooHigh()); require(WAD <= _preLiquidationParams.preLIF1, ErrorsLib.PreLIFTooLow()); require(_preLiquidationParams.preLIF1 <= _preLiquidationParams.preLIF2, ErrorsLib.PreLIFDecreasing()); require(_preLiquidationParams.preLIF2 <= WAD.wDivDown(_marketParams.lltv), ErrorsLib.PreLIFTooHigh()); diff --git a/src/libraries/ErrorsLib.sol b/src/libraries/ErrorsLib.sol index 38439b3..5c3393d 100644 --- a/src/libraries/ErrorsLib.sol +++ b/src/libraries/ErrorsLib.sol @@ -12,6 +12,8 @@ library ErrorsLib { error PreLCFDecreasing(); + error PreLCFTooHigh(); + error PreLIFTooLow(); error PreLIFDecreasing(); diff --git a/test/PreLiquidationErrorTest.sol b/test/PreLiquidationErrorTest.sol index 35928fe..6b3ee24 100644 --- a/test/PreLiquidationErrorTest.sol +++ b/test/PreLiquidationErrorTest.sol @@ -40,7 +40,7 @@ contract PreLiquidationErrorTest is BaseTest { factory.createPreLiquidation(id, preLiquidationParams); } - function testCloseFactorDecreasing(PreLiquidationParams memory preLiquidationParams) public virtual { + function testLCFDecreasing(PreLiquidationParams memory preLiquidationParams) public virtual { preLiquidationParams = boundPreLiquidationParameters({ preLiquidationParams: preLiquidationParams, minPreLltv: WAD / 100, @@ -57,6 +57,22 @@ contract PreLiquidationErrorTest is BaseTest { factory.createPreLiquidation(id, preLiquidationParams); } + function testLCFHigh(PreLiquidationParams memory preLiquidationParams) public virtual { + preLiquidationParams = boundPreLiquidationParameters({ + preLiquidationParams: preLiquidationParams, + minPreLltv: WAD / 100, + maxPreLltv: marketParams.lltv - 1, + minPreLCF: WAD + 1, + maxPreLCF: type(uint256).max, + minPreLIF: WAD + 1, + maxPreLIF: WAD.wDivDown(lltv), + preLiqOracle: marketParams.oracle + }); + + vm.expectRevert(ErrorsLib.PreLCFTooHigh.selector); + factory.createPreLiquidation(id, preLiquidationParams); + } + function testLowPreLIF(PreLiquidationParams memory preLiquidationParams) public virtual { preLiquidationParams = boundPreLiquidationParameters({ preLiquidationParams: preLiquidationParams, From 4402a29e11762201da628ca04821dfb8e7cde0c2 Mon Sep 17 00:00:00 2001 From: peyha Date: Mon, 7 Oct 2024 10:59:00 +0200 Subject: [PATCH 3/3] doc: improve phrasing --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 2762953..3230073 100644 --- a/README.md +++ b/README.md @@ -44,8 +44,7 @@ The PreLiquidation smart-contract enforces the following properties: - preLCF1 <= preLCF2; - preLFC1 <= 1; - 1 <= preLIF1 <= preLIF2 <= 1 / LLTV. -Note: it is not mandatory that `preLCF1 <= 1` and `preLCF1 <= 1` hold. -Indeed without this, the pre-liquidation close factor can reach 100% before the position is liquidatable allowing additionnal pre-liquidation close factor configurations. +Note: Using `preLCF2 > 1`, you can select at which LTV between preLltv and LLTV the entire position will be pre-liquidated. A pre-liquidation close factor higher than 100% means that the whole position is pre-liquidatable. ### `onPreLiquidate` callback