Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Verif pre-liquidations repay #38

Merged
merged 33 commits into from
Oct 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
f96a3de
feat: draft should revert spec
colin-morpho Sep 24, 2024
2ccb665
fix: reverts conf
colin-morpho Sep 24, 2024
b99d080
draft: add specs
colin-morpho Sep 24, 2024
99e902c
Merge branch 'feat/licence' into colin@verif/expected-reverts
colin-morpho Sep 25, 2024
7636e91
chore:remove pre-liquidation harness
colin-morpho Sep 27, 2024
bf7b83c
Merge branch 'main' into colin@verif/expected-reverts
colin-morpho Sep 27, 2024
b6fe2ea
feat: verify pre-liquidation repay
colin-morpho Sep 27, 2024
7eee316
doc: describe liveness in readme
colin-morpho Sep 27, 2024
27bed04
fix: simplify conf; ignore `extSload`
colin-morpho Sep 27, 2024
e003268
Merge branch 'colin@verif/setup' into colin@verif/pre-liquidations-repay
colin-morpho Sep 27, 2024
f6f4b6c
doc: add doc in spec
colin-morpho Sep 27, 2024
a4b6679
feat: setup CI for liveness specs
colin-morpho Sep 29, 2024
ad9fdd0
fix: patch spec
colin-morpho Sep 30, 2024
c0fb70a
Merge branch 'main' into colin@verif/pre-liquidations-repay
colin-morpho Oct 1, 2024
253eefb
fix: add a helper
colin-morpho Oct 1, 2024
982420f
fix: improve spec
colin-morpho Oct 1, 2024
1a43913
fix: patch helper
colin-morpho Oct 1, 2024
99d27d0
fix: simplify verif by removing harness
colin-morpho Oct 2, 2024
6e98c1c
fix: pass non vacuity test
colin-morpho Oct 2, 2024
ac1b180
chore: format liveness conf
colin-morpho Oct 2, 2024
06f6bd6
Merge branch 'main' into colin@verif/pre-liquidations-repay
colin-morpho Oct 2, 2024
ea9212f
fix: add docs and fix formatting
colin-morpho Oct 2, 2024
c03adab
Merge branch 'main' into colin@verif/pre-liquidations-repay
colin-morpho Oct 2, 2024
cffe9f2
fix: rollback mistake
colin-morpho Oct 2, 2024
0a194fb
fix: fmt README
colin-morpho Oct 2, 2024
557b0d7
refactor: format files
QGarchery Oct 3, 2024
0640540
refactor: one sentence per line in README
QGarchery Oct 3, 2024
2e54f89
refactor: small changes in README
QGarchery Oct 3, 2024
046509d
refactor: more sentence in newlines
QGarchery Oct 3, 2024
b20eaf9
Merge pull request #67 from morpho-org/certora/format
QGarchery Oct 3, 2024
84da5fb
fix: typo
colin-morpho Oct 3, 2024
89ff510
fix: add doc on spec
colin-morpho Oct 3, 2024
0c27b5c
fix: add more doc
colin-morpho Oct 3, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/certora.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ jobs:
matrix:
conf:
- Immutability
- Liveness
- Reentrancy

steps:
Expand Down
54 changes: 18 additions & 36 deletions certora/README.md
Original file line number Diff line number Diff line change
@@ -1,34 +1,22 @@
# Pre-liquidation Contract Formal Verification

This folder contains the
[CVL](https://docs.certora.com/en/latest/docs/cvl/index.html)
specification and verification setup for the
[pre-liquidation](../src/PreLiquidation.sol) contract using the
[Certora Prover](https://www.certora.com/).
This folder contains the [CVL](https://docs.certora.com/en/latest/docs/cvl/index.html) specification and verification setup for the [PreLiquidation](../src/PreLiquidation.sol) contract.

## Getting Started

This project depends on two different versions of
[Solidity](https://soliditylang.org/) which are required for running
the verification. The compiler binaries should be available under the
following path names:
This project depends on two different versions of [Solidity](https://soliditylang.org/) which are required for running the verification.
The compiler binaries should be available under the following path names:

- `solc-0.8.19` for the solidity compiler version `0.8.19`, which is
used for `Morpho`;
- `solc-0.8.27` for the solidity compiler version `0.8.27`, which is
used for `PreLiquidation`.
- `solc-0.8.19` for the solidity compiler version `0.8.19`, which is used for `Morpho`;
- `solc-0.8.27` for the solidity compiler version `0.8.27`, which is used for `PreLiquidation`.

To verifying a specification, run the command `certoraRun Spec.conf`
where `Spec.conf` is the configuration file of the matching CVL
specification. Configuration files are available in
[`certora/conf`](./confs). Please ensure that `CERTORAKEY` is set up
in your environment.
To verify a specification, run the command `certoraRun Spec.conf`where `Spec.conf` is the configuration file of the matching CVL specification.
Configuration files are available in [`certora/confs`](confs).
Please ensure that `CERTORAKEY` is set up in your environment.

## Overview

The PreLiquidation contract enables Morpho Blue borrowers to set up a
safer liquidation plan on a given position, thus preventing undesired
liquidations.
The PreLiquidation contract enables Morpho borrowers to set up a safer liquidation plan on a given position, thus preventing undesired liquidations.

### Reentrancy

Expand All @@ -38,28 +26,22 @@ This is checked in [`Reentrancy.spec`](specs/Reentrancy.spec).

This is checked in [`Immutability.spec`](specs/Immutability.spec).

### Liveness properties

This is checked in [`Liveness.spec`](specs/Liveness.spec).

## Verification architecture

### Folders and file structure

The [`certora/specs`](specs) folder contains the following files:

- [`Reentrancy.spec`](specs/Reentrancy.spec) checks that
PreLiquidation is reentrancy safe by checking that the storage is never
used.

- [`Immutability.spec`](specs/Immutability.spec) checks that
PreLiquidation contract is immutable because it doesn't perform any
delegate call.

The [`certora/confs`](confs) folder contains a configuration file for
each corresponding specification file.
- [`Reentrancy.spec`](specs/Reentrancy.spec) checks that PreLiquidation is reentrancy safe by checking that the storage is never used;
- [`Immutability.spec`](specs/Immutability.spec) checks that PreLiquidation contract is immutable because it doesn't perform any delegate call;
- [`Liveness.spec`](specs/Liveness.spec) ensure that expected computations will always be performed.
For instance, pre-liquidations will always trigger a repay operation.

The [`certora/helpers`](helpers) folder contains helper contracts that
enable the verification of PreLiquidation. Notably, this allows
handling the fact that library functions should be called from a
contract to be verified independently, and it allows defining needed
getters.
The [`certora/confs`](confs) folder contains a configuration file for each corresponding specification file.

## TODO

Expand Down
28 changes: 14 additions & 14 deletions certora/confs/Immutability.conf
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
{
"files": [
"src/PreLiquidation.sol",
],
"solc": "solc-0.8.27",
"solc_via_ir" : true,
"verify": "PreLiquidation:certora/specs/Immutability.spec",
"prover_args": [
"-depth 3",
"-mediumTimeout 20",
"-timeout 120",
],
"rule_sanity": "basic",
"server": "production",
"msg": "PreLiquidation Immutability",
"files": [
"src/PreLiquidation.sol"
],
"solc": "solc-0.8.27",
"solc_via_ir": true,
"verify": "PreLiquidation:certora/specs/Immutability.spec",
"prover_args": [
"-depth 3",
"-mediumTimeout 20",
"-timeout 120"
],
"rule_sanity": "basic",
"server": "production",
"msg": "PreLiquidation Immutability"
}
31 changes: 31 additions & 0 deletions certora/confs/Liveness.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"files": [
"src/PreLiquidation.sol",
"lib/morpho-blue/src/Morpho.sol"
],
"link": [
"PreLiquidation:MORPHO=Morpho"
],
"parametric_contracts": [
"PreLiquidation"
],
"solc_via_ir": true,
"verify": "PreLiquidation:certora/specs/Liveness.spec",
"solc_optimize_map": {
"Morpho": "99999",
"PreLiquidation": "99999"
},
"solc_map": {
"Morpho": "solc-0.8.19",
"PreLiquidation": "solc-0.8.27"
},
"prover_args": [
"-depth 3",
"-mediumTimeout 20",
"-timeout 120",
"-smt_nonLinearArithmetic true"
],
"rule_sanity": "basic",
"server": "production",
"msg": "PreLiquidation Liveness"
}
30 changes: 15 additions & 15 deletions certora/confs/Reentrancy.conf
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
{
"files": [
"src/PreLiquidation.sol",
],
"solc": "solc-0.8.27",
"solc_via_ir" : true,
"verify": "PreLiquidation:certora/specs/Reentrancy.spec",
"prover_args": [
"-enableStorageSplitting false",
"-depth 3",
"-mediumTimeout 20",
"-timeout 120",
],
"rule_sanity": "basic",
"server": "production",
"msg": "PreLiquidation Reentrancy",
"files": [
"src/PreLiquidation.sol"
],
"solc": "solc-0.8.27",
"solc_via_ir": true,
"verify": "PreLiquidation:certora/specs/Reentrancy.spec",
"prover_args": [
"-enableStorageSplitting false",
"-depth 3",
"-mediumTimeout 20",
"-timeout 120"
],
"rule_sanity": "basic",
"server": "production",
"msg": "PreLiquidation Reentrancy"
}
44 changes: 44 additions & 0 deletions certora/specs/Liveness.spec
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// SPDX-License-Identifier: GPL-2.0-or-later

using PreLiquidation as preLiq;
MathisGD marked this conversation as resolved.
Show resolved Hide resolved

methods {
function preLiq.MORPHO() external returns address envfree;
}

// True when `preLiquidate` has been called.
persistent ghost bool preLiquidateCalled;

// True when `onMorphoRepay` has been called.
persistent ghost bool onMorphoRepayCalled;

hook CALL(uint g, address addr, uint value, uint argsOffset, uint argsLength, uint retOffset, uint retLength) uint rc {
if (selector == sig:preLiquidate(address, uint256, uint256, bytes).selector) {
preLiquidateCalled = true;
MathisGD marked this conversation as resolved.
Show resolved Hide resolved
} else if (selector == sig:onMorphoRepay(uint256, bytes).selector) {
onMorphoRepayCalled = true;
}
}

// Check that pre-liquidations happen if and only if `onMorphoRepay` is called.
rule preLiquidateRepays(method f, env e, calldataarg data) {

// Set up the initial state.
require !preLiquidateCalled;
require !onMorphoRepayCalled;

// Safe require because Morpho cannot send transactions.
require e.msg.sender != preLiq.MORPHO();

// Capture the first method call which is not performed with a CALL opcode.
QGarchery marked this conversation as resolved.
Show resolved Hide resolved
if (f.selector == sig:preLiquidate(address, uint256, uint256, bytes).selector) {
preLiquidateCalled = true;
} else if (f.selector == sig:onMorphoRepay(uint256, bytes).selector) {
onMorphoRepayCalled = true;
}

f@withrevert(e,data);

// Avoid failing vacuity checks, either the proposition is true or the execution reverts.
assert !lastReverted => (preLiquidateCalled <=> onMorphoRepayCalled);
}
2 changes: 0 additions & 2 deletions certora/specs/Reentrancy.spec
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-or-later



// True when storage has been accessed with either a SSTORE or a SLOAD.
persistent ghost bool hasAccessedStorage;

Expand Down