Skip to content

Commit

Permalink
Merge pull request #390 from morpho-org/certora/reverts
Browse files Browse the repository at this point in the history
[Certora] Reverts
  • Loading branch information
MathisGD authored Jan 17, 2024
2 parents cf0bb56 + 0c2438f commit 74284aa
Show file tree
Hide file tree
Showing 5 changed files with 417 additions and 9 deletions.
9 changes: 8 additions & 1 deletion .github/workflows/certora.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ jobs:
matrix:
conf:
- ConsistentState
- Reverts
- Roles

steps:
Expand All @@ -30,7 +31,13 @@ jobs:
- name: Install certora
run: pip install certora-cli-beta

- name: Install solc
- name: Install solc (0.8.19)
run: |
wget https://github.com/ethereum/solidity/releases/download/v0.8.19/solc-static-linux
chmod +x solc-static-linux
sudo mv solc-static-linux /usr/local/bin/solc8.19
- name: Install solc (0.8.21)
run: |
wget https://github.com/ethereum/solidity/releases/download/v0.8.21/solc-static-linux
chmod +x solc-static-linux
Expand Down
25 changes: 25 additions & 0 deletions certora/confs/Reverts.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"files": [
"lib/morpho-blue/certora/harness/MorphoHarness.sol",
"certora/harness/MetaMorphoHarness.sol",
"certora/dispatch/ERC20Standard.sol",
],
"solc_map": {
"MorphoHarness": "solc8.19",
"MetaMorphoHarness": "solc",
"ERC20Standard": "solc",
},
"link": [
"MetaMorphoHarness:MORPHO=MorphoHarness",
],
"verify": "MetaMorphoHarness:certora/specs/Reverts.spec",
"optimistic_loop": true,
"prover_args": [
"-depth 3",
"-mediumTimeout 20",
"-timeout 120",
],
"rule_sanity": "basic",
"server": "production",
"msg": "MetaMorpho Reverts"
}
8 changes: 8 additions & 0 deletions certora/harness/MetaMorphoHarness.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@ contract MetaMorphoHarness is MetaMorpho {
string memory _symbol
) MetaMorpho(owner, morpho, initialTimelock, _asset, _name, _symbol) {}

function balanceOf(address token, address user) external view returns (uint256) {
return IERC20(token).balanceOf(user);
}

function totalSupply(address token) external view returns (uint256) {
return IERC20(token).totalSupply();
}

function minTimelock() external view returns (uint256) {
return ConstantsLib.MIN_TIMELOCK;
}
Expand Down
35 changes: 27 additions & 8 deletions certora/specs/ConsistentState.spec
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,20 @@ methods {
function multicall(bytes[]) external returns(bytes[]) => NONDET DELETE;

function pendingTimelock() external returns(uint192, uint64) envfree;
function timelock() external returns (uint256) envfree;
function guardian() external returns (address) envfree;
function timelock() external returns(uint256) envfree;
function guardian() external returns(address) envfree;
function pendingGuardian() external returns(address, uint64) envfree;
function pendingCap(MetaMorphoHarness.Id) external returns(uint192, uint64) envfree;
function config(MetaMorphoHarness.Id) external returns(uint184, bool, uint64) envfree;
function supplyQueueLength() external returns(uint256) envfree;
function withdrawQueueLength() external returns(uint256) envfree;
function fee() external returns (uint96) envfree;
function fee() external returns(uint96) envfree;
function feeRecipient() external returns(address) envfree;

function minTimelock() external returns (uint256) envfree;
function maxTimelock() external returns (uint256) envfree;
function maxQueueLength() external returns (uint256) envfree;
function maxFee() external returns (uint256) envfree;
function minTimelock() external returns(uint256) envfree;
function maxTimelock() external returns(uint256) envfree;
function maxQueueLength() external returns(uint256) envfree;
function maxFee() external returns(uint256) envfree;
}

invariant feeInRange()
Expand All @@ -32,8 +33,12 @@ function isPendingTimelockInRange() returns bool {
invariant pendingTimelockInRange()
isPendingTimelockInRange();

function isTimelockInRange() returns bool {
return timelock() <= maxTimelock() && timelock() >= minTimelock();
}

invariant timelockInRange()
timelock() <= maxTimelock() && timelock() >= minTimelock()
isTimelockInRange()
{
preserved {
requireInvariant pendingTimelockInRange();
Expand Down Expand Up @@ -138,3 +143,17 @@ function isDifferentPendingGuardian() returns bool {

invariant differentPendingGuardian()
isDifferentPendingGuardian();

invariant noFeeToUnsetFeeRecipient()
feeRecipient() == 0 => fee() == 0;

function hasSupplyCapIsEnabled(MetaMorphoHarness.Id id) returns bool {
uint192 supplyCap;
bool enabled;
supplyCap, enabled, _ = config(id);

return supplyCap > 0 => enabled;
}

invariant supplyCapIsEnabled(MetaMorphoHarness.Id id)
hasSupplyCapIsEnabled(id);
Loading

0 comments on commit 74284aa

Please sign in to comment.