Skip to content

Commit 3d5a1be

Browse files
authored
Merge pull request #85 from morpho-org/fix/cantina
Audit fixes
2 parents 758138b + c951b54 commit 3d5a1be

File tree

4 files changed

+22
-9
lines changed

4 files changed

+22
-9
lines changed

README.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ The two main use-cases are:
3838

3939
### Pre-liquidation parameters restrictions
4040

41-
The PreLiquidation smart-contract enforces the following properties:
41+
The PreLiquidation smart-contract enforces the properties:
4242

4343
- preLltv < LLTV;
4444
- preLCF1 <= preLCF2;
@@ -64,6 +64,14 @@ It's possible to use the corresponding market oracle or any other oracle includi
6464
PreLiquidation contract addresses are generated using the CREATE2 opcode, allowing for predictable address computation depending on pre-liquidation parameters.
6565
The [`PreLiquidationAddressLib`](./src/libraries/periphery/PreLiquidationAddressLib.sol) library provides a `computePreLiquidationAddress` function, simplifying the computation of a PreLiquidation contract's address.
6666

67+
### Potential preLCF manipulation
68+
69+
A pre-liquidation cannot repay a proportion of the position's debt greater than `preLCF`.
70+
However, it's possible to pre-liquidate a proportion of the position while keeping it pre-liquidatable before performing another pre-liquidation.
71+
This manipulation can lead to repaying a proportion of the position's debt higher than `preLCF`.
72+
It has been studied in the part 5.2 of [An Empirical Study of DeFi Liquidations:Incentives, Risks, and Instabilities](https://arxiv.org/pdf/2106.06389), in the case of a constant liquidation close factor.
73+
Implementing a `preLCF` linear in the health factor can help mitigating this manipulation when choosing the right slope.
74+
6775
## Getting started
6876

6977
### Package installation
@@ -74,6 +82,10 @@ Install [Foundry](https://book.getfoundry.sh/getting-started/installation).
7482

7583
Run `forge test`.
7684

85+
## Solidity version
86+
87+
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.
88+
7789
## Audits
7890

7991
All audits are stored in the [`audits`](./audits) folder.

src/PreLiquidation.sol

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,8 @@ contract PreLiquidation is IPreLiquidation, IMorphoRepayCallback {
150150
require(borrowed > collateralQuoted.wMulDown(PRE_LLTV), ErrorsLib.NotPreLiquidatablePosition());
151151

152152
uint256 ltv = borrowed.wDivUp(collateralQuoted);
153-
uint256 preLIF = (ltv - PRE_LLTV).wDivDown(LLTV - PRE_LLTV).wMulDown(PRE_LIF_2 - PRE_LIF_1) + PRE_LIF_1;
153+
uint256 quotient = (ltv - PRE_LLTV).wDivDown(LLTV - PRE_LLTV);
154+
uint256 preLIF = quotient.wMulDown(PRE_LIF_2 - PRE_LIF_1) + PRE_LIF_1;
154155

155156
if (seizedAssets > 0) {
156157
uint256 seizedAssetsQuoted = seizedAssets.mulDivUp(collateralPrice, ORACLE_PRICE_SCALE);
@@ -165,7 +166,7 @@ contract PreLiquidation is IPreLiquidation, IMorphoRepayCallback {
165166

166167
// Note that the pre-liquidation close factor can be greater than WAD (100%).
167168
// In this case the position can be fully pre-liquidated.
168-
uint256 preLCF = (ltv - PRE_LLTV).wDivDown(LLTV - PRE_LLTV).wMulDown(PRE_LCF_2 - PRE_LCF_1) + PRE_LCF_1;
169+
uint256 preLCF = quotient.wMulDown(PRE_LCF_2 - PRE_LCF_1) + PRE_LCF_1;
169170

170171
uint256 repayableShares = uint256(position.borrowShares).wMulDown(preLCF);
171172
require(repaidShares <= repayableShares, ErrorsLib.PreLiquidationTooLarge(repaidShares, repayableShares));

src/interfaces/IPreLiquidation.sol

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ pragma solidity >= 0.5.0;
44
import {Id, IMorpho, MarketParams} from "../../lib/morpho-blue/src/interfaces/IMorpho.sol";
55

66
/// @notice The pre-liquidation parameters are:
7-
/// - preLltv, the maximum LTV of a position before allowing pre-liquidation.
8-
/// - preLCF1, the pre-liquidation close factor when the position LTV is equal to preLltv.
9-
/// - preLCF2, the pre-liquidation close factor when the position LTV is equal to LLTV.
10-
/// - preLIF1, the pre-liquidation incentive factor when the position LTV is equal to preLltv.
11-
/// - preLIF2, the pre-liquidation incentive factor when the position LTV is equal to LLTV.
7+
/// - preLltv, the maximum LTV of a position before allowing pre-liquidation, scaled by WAD.
8+
/// - preLCF1, the pre-liquidation close factor when the position LTV is equal to preLltv, scaled by WAD.
9+
/// - preLCF2, the pre-liquidation close factor when the position LTV is equal to LLTV, scaled by WAD.
10+
/// - preLIF1, the pre-liquidation incentive factor when the position LTV is equal to preLltv, scaled by WAD.
11+
/// - preLIF2, the pre-liquidation incentive factor when the position LTV is equal to LLTV, scaled by WAD.
1212
/// - preLiquidationOracle, the oracle used to assess whether or not a position can be preliquidated.
1313
struct PreLiquidationParams {
1414
uint256 preLltv;

src/libraries/ErrorsLib.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// SPDX-License-Identifier: GPL-2.0-or-later
2-
pragma solidity ^0.8.27;
2+
pragma solidity ^0.8.0;
33

44
/// @title ErrorsLib
55
/// @author Morpho Labs

0 commit comments

Comments
 (0)