Skip to content

Commit

Permalink
feat: add equivalent input liquidate rule
Browse files Browse the repository at this point in the history
  • Loading branch information
QGarchery committed Dec 20, 2023
1 parent 5afa588 commit a35dab1
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 0 deletions.
19 changes: 19 additions & 0 deletions certora/specs/AccrueInterest.spec
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ methods {
function extSloads(bytes32[]) external returns bytes32[] => NONDET DELETE;

function maxFee() external returns uint256 envfree;
function libId(MorphoHarness.MarketParams) external returns MorphoHarness.Id envfree;

function MathLib.mulDivDown(uint256 a, uint256 b, uint256 c) internal returns uint256 => ghostMulDivDown(a,b,c);
function MathLib.mulDivUp(uint256 a, uint256 b, uint256 c) internal returns uint256 => ghostMulDivUp(a,b,c);
Expand Down Expand Up @@ -136,3 +137,21 @@ filtered {
assert revert1 <=> revert2;
assert store1 == store2;
}

// Checks that the debt input or the colleteral input of the liquidate function lead to the same repaid assets amount.
rule liquidateEquivalentInputDebtAndInputCollateral(env e, MorphoHarness.MarketParams marketParams, address borrower, uint256 seized, uint256 repaidShares, bytes data) {
MorphoHarness.Id id = libId(marketParams);

storage init = lastStorage;

uint256 seizedAssets1;
uint256 repaidAssets1;
seizedAssets1, repaidAssets1 = liquidate(e, marketParams, borrower, 0, repaidShares, data);

uint256 seizedAssets2;
uint256 repaidAssets2;
seizedAssets2, repaidAssets2 = liquidate(e, marketParams, borrower, seizedAssets1, 0, data) at init;

assert seizedAssets1 == seizedAssets2;
assert repaidAssets1 == repaidAssets2;
}
21 changes: 21 additions & 0 deletions certora/specs/Health.spec
Original file line number Diff line number Diff line change
Expand Up @@ -106,3 +106,24 @@ filtered { f -> !f.isView }
// This invariant ensures that bad debt realization cannot be bypassed.
invariant alwaysCollateralized(MorphoHarness.Id id, address borrower)
borrowShares(id, borrower) != 0 => collateral(id, borrower) != 0;

// Checks that the debt input or the colleteral input of the liquidate function lead to the same repaid assets amount.
rule liquidateEquivalentInputDebtAndInputCollateral(env e, MorphoHarness.MarketParams marketParams, address borrower, uint256 seized, uint256 repaidShares, bytes data) {
MorphoHarness.Id id = libId(marketParams);

storage init = lastStorage;

uint256 seizedAssets1;
uint256 repaidAssets1;
seizedAssets1, repaidAssets1 = liquidate(e, marketParams, borrower, 0, repaidShares, data);

uint256 seizedAssets2;
uint256 repaidAssets2;
seizedAssets2, repaidAssets2 = liquidate(e, marketParams, borrower, seizedAssets1, 0, data) at init;

// Assume same context, including the oracle answer.
require !priceChanged;

assert seizedAssets1 == seizedAssets2;
assert repaidAssets1 == repaidAssets2;
}

0 comments on commit a35dab1

Please sign in to comment.