This repository puts together different contracts to carry out liquidations on Morpho with specific parameters chosen by the borrower. We call these user-defined Morpho Blue transactions pre-liquidations. Borrowers can set custom pre-liquidation parameters, allowing them to specify pre-liquidation incentive factors and pre-liquidation close factors. Pre-liquidation incentive factors determine incentives given to liquidators and pre-liquidation close factors limit the proportion of the position that can be closed during a liquidation.
The PreLiquidation
contract serves as the endpoint for pre-liquidations using parameters chosen by borrowers.
Note that pre-liquidation must be authorized on Morpho.
Liquidators may perform pre-liquidations on a position using the preLiquidate
entry point on a deployed PreLiquidation
contract.
The PreLiquidationFactory
factory contract simplifies the deployment and indexing of pre-liquidation contracts.
The set of pre-liquidation parameters is composed of
- a Morpho market (
id
); - a pre-liquidation loan-to-value (
preLltv
); - two pre-liquidation close factor parameters (
preLCF1
andpreLCF2
); - two pre-liquidation incentive factor parameters (
preLIF1
andpreLIF2
); - a pre-liquidation oracle (
preLiquidationOracle
).
The pre-liquidation close factor and the pre-liquidation incentive factor evolve linearly with the user's LTV:
- the pre-liquidation close factor is
preLCF1
when the position LTV is equal topreLltv
andpreLCF2
when the LTV is equal toLLTV
; - the pre-liquidation incentive factor is
preLIF1
when the position LTV equalspreLltv
andpreLIF2
when the LTV is equal toLLTV
.
These functions are illustrated in the following figure:
The two main use-cases are:
- Using normal fixed parameters when
preLIF1 = preLIF2
andpreLCF1 = preLCF2
. - Using health dependent liquidation when either
preLIF1 < preLIF2
orpreLCF1 < preLCF2
, similar to a Quasi Dutch Auction (as in Euler liquidations).
The PreLiquidation smart-contract enforces the properties:
- preLltv < LLTV;
- preLCF1 <= preLCF2;
- preLFC1 <= 1;
- 1 <= preLIF1 <= preLIF2 <= 1 / LLTV.
Note: using
preLCF2 > 1
, one can select at which LTV between preLltv and LLTV the entire position can be pre-liquidated. A pre-liquidation close factor higher than 100% means that the whole position is pre-liquidatable.
By calling preLiquidate
with a smart contract that implements the IPreLiquidationCallback
interface, the liquidator can be called back.
More precisely, the onPreLiquidate
function of the liquidator's smart contract will be called after the collateral withdrawal and before the debt repayment.
This mechanism eliminates the need for a flashloan.
The PreLiquidationParams
struct includes a preLiquidationOracle
attribute, allowing pre-liquidation using any compatible oracle.
This oracle should implement Morpho's IOracle
interface and adhere to the behavior specified in the documentation.
It's possible to use the corresponding market oracle or any other oracle including OEV solutions.
PreLiquidation contract addresses are generated using the CREATE2 opcode, allowing for predictable address computation depending on pre-liquidation parameters.
The PreLiquidationAddressLib
library provides a computePreLiquidationAddress
function, simplifying the computation of a PreLiquidation contract's address.
A pre-liquidation cannot repay a proportion of the position's debt greater than preLCF
.
However, it's possible to pre-liquidate a proportion of the position while keeping it pre-liquidatable before performing another pre-liquidation.
This manipulation can lead to repaying a proportion of the position's debt higher than preLCF
.
It has been studied in the part 5.2 of An Empirical Study of DeFi Liquidations:Incentives, Risks, and Instabilities, in the case of a constant liquidation close factor.
Implementing a preLCF
linear in the health factor can help mitigating this manipulation when choosing the right slope.
Install Foundry.
Run forge test
.
As a consequence of using Solidity 0.8.27, the bytecode of the contracts could contain new opcodes (e.g., PUSH0
, MCOPY
, TSTORE
, TLOAD
) so one should make sure that the contract bytecode can be handled by the target chain for deployment.
All audits are stored in the audits
folder.
Files in this repository are publicly available under license GPL-2.0-or-later
, see LICENSE
.