Skip to content

Commit

Permalink
Merge pull request #85 from morpho-org/fix/cantina
Browse files Browse the repository at this point in the history
Audit fixes
  • Loading branch information
MathisGD authored Oct 31, 2024
2 parents 758138b + c951b54 commit 3d5a1be
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 9 deletions.
14 changes: 13 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ The two main use-cases are:

### Pre-liquidation parameters restrictions

The PreLiquidation smart-contract enforces the following properties:
The PreLiquidation smart-contract enforces the properties:

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

### Potential preLCF manipulation

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](https://arxiv.org/pdf/2106.06389), 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.

## Getting started

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

Run `forge test`.

## Solidity version

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.

## Audits

All audits are stored in the [`audits`](./audits) folder.
Expand Down
5 changes: 3 additions & 2 deletions src/PreLiquidation.sol
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,8 @@ contract PreLiquidation is IPreLiquidation, IMorphoRepayCallback {
require(borrowed > collateralQuoted.wMulDown(PRE_LLTV), ErrorsLib.NotPreLiquidatablePosition());

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

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

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

uint256 repayableShares = uint256(position.borrowShares).wMulDown(preLCF);
require(repaidShares <= repayableShares, ErrorsLib.PreLiquidationTooLarge(repaidShares, repayableShares));
Expand Down
10 changes: 5 additions & 5 deletions src/interfaces/IPreLiquidation.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ pragma solidity >= 0.5.0;
import {Id, IMorpho, MarketParams} from "../../lib/morpho-blue/src/interfaces/IMorpho.sol";

/// @notice The pre-liquidation parameters are:
/// - preLltv, the maximum LTV of a position before allowing pre-liquidation.
/// - preLCF1, the pre-liquidation close factor when the position LTV is equal to preLltv.
/// - preLCF2, the pre-liquidation close factor when the position LTV is equal to LLTV.
/// - preLIF1, the pre-liquidation incentive factor when the position LTV is equal to preLltv.
/// - preLIF2, the pre-liquidation incentive factor when the position LTV is equal to LLTV.
/// - preLltv, the maximum LTV of a position before allowing pre-liquidation, scaled by WAD.
/// - preLCF1, the pre-liquidation close factor when the position LTV is equal to preLltv, scaled by WAD.
/// - preLCF2, the pre-liquidation close factor when the position LTV is equal to LLTV, scaled by WAD.
/// - preLIF1, the pre-liquidation incentive factor when the position LTV is equal to preLltv, scaled by WAD.
/// - preLIF2, the pre-liquidation incentive factor when the position LTV is equal to LLTV, scaled by WAD.
/// - preLiquidationOracle, the oracle used to assess whether or not a position can be preliquidated.
struct PreLiquidationParams {
uint256 preLltv;
Expand Down
2 changes: 1 addition & 1 deletion src/libraries/ErrorsLib.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.27;
pragma solidity ^0.8.0;

/// @title ErrorsLib
/// @author Morpho Labs
Expand Down

0 comments on commit 3d5a1be

Please sign in to comment.