Skip to content

Commit

Permalink
Merge pull request #411 from morpho-org/certora/distinct-performance
Browse files Browse the repository at this point in the history
[Certora] Fix solver setup
  • Loading branch information
MerlinEgalite authored Apr 18, 2024
2 parents 549cc21 + 6e3ce22 commit 3066d68
Show file tree
Hide file tree
Showing 15 changed files with 48 additions and 93 deletions.
2 changes: 1 addition & 1 deletion certora/confs/DistinctIdentifiers.conf
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"loop_iter": "2",
"optimistic_loop": true,
"prover_args": [
"-solvers [z3:lia2,cvc5:nonlinNoDio,cvc4:nonlin,yices:def,z3:arith2]",
"-solvers [z3:def{randomSeed=1},z3:def{randomSeed=2},z3:def{randomSeed=3},z3:def{randomSeed=4},z3:def{randomSeed=5},z3:def{randomSeed=6},z3:def{randomSeed=7},z3:lia2]",
"-depth 3",
"-mediumTimeout 20",
"-timeout 2000",
Expand Down
2 changes: 1 addition & 1 deletion certora/confs/PendingValues.conf
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"prover_args": [
"-depth 3",
"-mediumTimeout 20",
"-timeout 300",
"-timeout 3600",
],
"rule_sanity": "basic",
"server": "production",
Expand Down
11 changes: 8 additions & 3 deletions certora/confs/Reverts.conf
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,14 @@
"loop_iter": "2",
"optimistic_loop": true,
"prover_args": [
"-depth 3",
"-mediumTimeout 20",
"-timeout 120",
"-depth 5",
"-mediumTimeout 40",
"-newSplitParallel true",
"-splitParallelInitialDepth 4",
"-splitParallelTimelimit 7000",
"-adaptiveSolverConfig false",
"-smt_nonLinearArithmetic true",
"-solvers [z3:def{randomSeed=1},z3:def{randomSeed=2},z3:def{randomSeed=3},z3:def{randomSeed=4},z3:def{randomSeed=5},z3:def{randomSeed=6},z3:def{randomSeed=7},z3:def{randomSeed=8},z3:def{randomSeed=9},z3:def{randomSeed=10}]"
],
"rule_sanity": "basic",
"server": "production",
Expand Down
2 changes: 1 addition & 1 deletion certora/confs/Timelock.conf
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"prover_args": [
"-depth 3",
"-mediumTimeout 20",
"-timeout 300",
"-timeout 3600",
],
"rule_sanity": "basic",
"server": "production",
Expand Down
6 changes: 1 addition & 5 deletions certora/specs/ConsistentState.spec
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,6 @@ function isNotEnabledIsNotMarkedForRemoval(MetaMorphoHarness.Id id) returns bool
invariant notEnabledIsNotMarkedForRemoval(MetaMorphoHarness.Id id)
isNotEnabledIsNotMarkedForRemoval(id);

function hasPendingCapIsNotMarkedForRemoval(MetaMorphoHarness.Id id) returns bool {
return pendingCap_(id).validAt > 0 => config_(id).removableAt == 0;
}

// Check that a market with a pending cap cannot be marked for removal.
invariant pendingCapIsNotMarkedForRemoval(MetaMorphoHarness.Id id)
hasPendingCapIsNotMarkedForRemoval(id);
pendingCap_(id).validAt > 0 => config_(id).removableAt == 0;
6 changes: 1 addition & 5 deletions certora/specs/DistinctIdentifiers.spec
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
// SPDX-License-Identifier: GPL-2.0-or-later
import "PendingValues.spec";

function hasDistinctIdentifiers(uint256 i, uint256 j) returns bool {
return i != j => withdrawQueue(i) != withdrawQueue(j);
}

// Check that there are no duplicate markets in the withdraw queue.
invariant distinctIdentifiers(uint256 i, uint256 j)
hasDistinctIdentifiers(i, j)
i != j => withdrawQueue(i) != withdrawQueue(j)
{
preserved updateWithdrawQueue(uint256[] indexes) with (env e) {
requireInvariant distinctIdentifiers(indexes[i], indexes[j]);
Expand Down
9 changes: 2 additions & 7 deletions certora/specs/Enabled.spec
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ rule inWithdrawQueueIsEnabledPreservedUpdateWithdrawQueue(env e, uint256 i, uint
uint256 j;
require isInWithdrawQueueIsEnabled(indexes[i]);

// Safe require because it is a verified invariant.
require hasDistinctIdentifiers(indexes[i], j);
requireInvariant distinctIdentifiers(indexes[i], j);

updateWithdrawQueue(e, indexes);

Expand All @@ -45,13 +44,9 @@ function isWithdrawRankCorrect(MetaMorphoHarness.Id id) returns bool {
invariant withdrawRankCorrect(MetaMorphoHarness.Id id)
isWithdrawRankCorrect(id);

function isEnabledHasPositiveRank(MetaMorphoHarness.Id id) returns bool {
return config_(id).enabled => withdrawRank(id) > 0;
}

// Checks that enabled markets have a positive withdraw rank, according to the withdrawRank ghost variable.
invariant enabledHasPositiveRank(MetaMorphoHarness.Id id)
isEnabledHasPositiveRank(id);
config_(id).enabled => withdrawRank(id) > 0;

// Check that enabled markets are in the withdraw queue.
rule enabledIsInWithdrawQueue(MetaMorphoHarness.Id id) {
Expand Down
2 changes: 1 addition & 1 deletion certora/specs/LastUpdated.spec
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ function hasGuardianRole(address user) returns bool {
}

// Check that any market with positive cap is created on Morpho Blue.
// The corresponding invariant cannot be verified because it requires to check properties on MetaMorpho and on Blue at the same time:
// The corresponding invariant is difficult to verify because it requires to check properties on MetaMorpho and on Blue at the same time:
// - on MetaMorpho, that it holds when the cap is positive for the first time
// - on Blue, that a created market always has positive last update
function hasPositiveSupplyCapIsUpdated(MetaMorphoHarness.Id id) returns bool {
Expand Down
11 changes: 4 additions & 7 deletions certora/specs/Liveness.spec
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,9 @@ rule canPauseSupply() {
rule canForceRemoveMarket(MetaMorphoHarness.MarketParams marketParams) {
MetaMorphoHarness.Id id = Util.libId(marketParams);

// Safe require because it is a verified invariant.
require hasSupplyCapIsEnabled(id);
// Safe require because it is a verified invariant.
require isEnabledHasConsistentAsset(marketParams);
// Safe require because it is a verified invariant.
requireInvariant supplyCapIsEnabled(id);
requireInvariant enabledHasConsistentAsset(marketParams);
// Safe require because this holds as an invariant.
require hasPositiveSupplyCapIsUpdated(id);

MetaMorphoHarness.MarketConfig config = config_(id);
Expand All @@ -55,8 +53,7 @@ rule canForceRemoveMarket(MetaMorphoHarness.MarketParams marketParams) {
assert !lastReverted;

require e3.msg.value == 0;
// Safe require because it is a verified invariant.
require isTimelockInRange();
requireInvariant timelockInRange();
// Safe require as it corresponds to some time very far into the future.
require e3.block.timestamp < 2^63;
submitMarketRemoval@withrevert(e3, marketParams);
Expand Down
6 changes: 2 additions & 4 deletions certora/specs/MarketInteractions.spec
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ function summarySupply(MetaMorphoHarness.MarketParams marketParams, uint256 asse
assert data.length == 0;

MetaMorphoHarness.Id id = Util.libId(marketParams);
// Safe require because it is a verified invariant
require hasSupplyCapIsEnabled(id);
requireInvariant supplyCapIsEnabled(id);

// Check that all markets on which MetaMorpho supplies are enabled markets.
assert config_(id).enabled;
Expand All @@ -44,8 +43,7 @@ function summaryWithdraw(MetaMorphoHarness.MarketParams marketParams, uint256 as

MetaMorphoHarness.Id id = Util.libId(marketParams);
uint256 index = lastIndexWithdraw();
// Safe require because it is a verified invariant.
require isInWithdrawQueueIsEnabled(index);
requireInvariant inWithdrawQueueIsEnabled(index);

// Check that all markets from which MetaMorpho withdraws are enabled markets.
assert config_(id).enabled;
Expand Down
21 changes: 6 additions & 15 deletions certora/specs/PendingValues.spec
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,19 @@ invariant noBadPendingTimelock()
hasNoBadPendingTimelock()
{
preserved with (env e) {
// Safe require because it is a verified invariant.
require isTimelockInRange();
requireInvariant timelockInRange();
// Safe require as it corresponds to some time very far into the future.
require e.block.timestamp < 2^63;
}
}

function isSmallerPendingTimelock() returns bool {
return assert_uint256(pendingTimelock_().value) < timelock();
}
// Check that the pending timelock value is always strictly smaller than the current timelock value.
invariant smallerPendingTimelock()
isSmallerPendingTimelock()
assert_uint256(pendingTimelock_().value) < timelock()
{
preserved {
// safe require as it is a verified invariant.
require isPendingTimelockInRange();
// Safe require because it is a verified invariant.
require isTimelockInRange();
requireInvariant pendingTimelockInRange();
requireInvariant timelockInRange();
}
}

Expand All @@ -46,8 +39,7 @@ invariant noBadPendingCap(MetaMorphoHarness.Id id)
hasNoBadPendingCap(id)
{
preserved with (env e) {
// Safe require because it is a verified invariant.
require isTimelockInRange();
requireInvariant timelockInRange();
// Safe require as it corresponds to some time very far into the future.
require e.block.timestamp < 2^63;
}
Expand Down Expand Up @@ -76,8 +68,7 @@ invariant noBadPendingGuardian()
hasNoBadPendingGuardian()
{
preserved with (env e) {
// Safe require because it is a verified invariant.
require isTimelockInRange();
requireInvariant timelockInRange();
// Safe require as it corresponds to some time very far into the future.
require e.block.timestamp < 2^63;
}
Expand Down
6 changes: 1 addition & 5 deletions certora/specs/Range.spec
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,9 @@ function isPendingTimelockInRange() returns bool {
invariant pendingTimelockInRange()
isPendingTimelockInRange();

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

// Check that the timelock is bounded by the min timelock and the max timelock.
invariant timelockInRange()
isTimelockInRange()
timelock() <= maxTimelock() && timelock() >= minTimelock()
{
preserved {
requireInvariant pendingTimelockInRange();
Expand Down
12 changes: 4 additions & 8 deletions certora/specs/Reverts.spec
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,7 @@ rule submitGuardianRevertCondition(env e, address newGuardian) {
address oldGuardian = guardian();
uint64 pendingGuardianValidAt = pendingGuardian_().validAt;

// Safe require because it is a verified invariant.
require isTimelockInRange();
requireInvariant timelockInRange();
// Safe require as it corresponds to some time very far into the future.
require e.block.timestamp < 2^63;

Expand All @@ -107,12 +106,10 @@ rule submitCapRevertCondition(env e, MetaMorphoHarness.MarketParams marketParams
uint256 pendingCapValidAt = pendingCap_(id).validAt;
MetaMorphoHarness.MarketConfig config = config_(id);

// Safe require because it is a verified invariant.
require isTimelockInRange();
requireInvariant timelockInRange();
// Safe require as it corresponds to some time very far into the future.
require e.block.timestamp < 2^63;
// Safe require because it is a verified invariant.
require hasSupplyCapIsEnabled(id);
requireInvariant supplyCapIsEnabled(id);

submitCap@withrevert(e, marketParams, newSupplyCap);

Expand All @@ -135,8 +132,7 @@ rule submitMarketRemovalRevertCondition(env e, MetaMorphoHarness.MarketParams ma
uint256 pendingCapValidAt = pendingCap_(id).validAt;
MetaMorphoHarness.MarketConfig config = config_(id);

// Safe require because it is a verified invariant.
require isTimelockInRange();
requireInvariant timelockInRange();
// Safe require as it corresponds to some time very far into the future.
require e.block.timestamp < 2^63;

Expand Down
36 changes: 12 additions & 24 deletions certora/specs/Timelock.spec
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,8 @@ rule nextGuardianUpdateTimeDoesNotRevert() {
env e;
require e.msg.value == 0;

// Safe require because it is a verified invariant.
require isTimelockInRange();
// Safe require because it is a verified invariant.
require isPendingTimelockInRange();
requireInvariant timelockInRange();
requireInvariant pendingTimelockInRange();

nextGuardianUpdateTime@withrevert(e);

Expand All @@ -44,8 +42,7 @@ rule guardianUpdateTime(env e_next, method f, calldataarg args) {
// The environment e yields the current time.
env e;

// Safe require because it is a verified invariant.
require isTimelockInRange();
requireInvariant timelockInRange();

uint256 nextTime = nextGuardianUpdateTime(e);
address prevGuardian = guardian();
Expand Down Expand Up @@ -73,10 +70,8 @@ rule nextCapIncreaseTimeDoesNotRevert(MetaMorphoHarness.Id id) {
env e;
require e.msg.value == 0;

// Safe require because it is a verified invariant.
require isTimelockInRange();
// Safe require because it is a verified invariant.
require isPendingTimelockInRange();
requireInvariant timelockInRange();
requireInvariant pendingTimelockInRange();

nextCapIncreaseTime@withrevert(e, id);

Expand All @@ -90,8 +85,7 @@ rule capIncreaseTime(env e_next, method f, calldataarg args) {

MetaMorphoHarness.Id id;

// Safe require because it is a verified invariant.
require isTimelockInRange();
requireInvariant timelockInRange();

uint256 nextTime = nextCapIncreaseTime(e, id);
uint184 prevCap = config_(id).cap;
Expand All @@ -117,10 +111,8 @@ rule nextTimelockDecreaseTimeDoesNotRevert() {
env e;
require e.msg.value == 0;

// Safe require because it is a verified invariant.
require isTimelockInRange();
// Safe require because it is a verified invariant.
require isPendingTimelockInRange();
requireInvariant timelockInRange();
requireInvariant pendingTimelockInRange();

nextTimelockDecreaseTime@withrevert(e);

Expand All @@ -132,8 +124,7 @@ rule timelockDecreaseTime(env e_next, method f, calldataarg args) {
// The environment e yields the current time.
env e;

// Safe require because it is a verified invariant.
require isTimelockInRange();
requireInvariant timelockInRange();

uint256 nextTime = nextTimelockDecreaseTime(e);
uint256 prevTimelock = timelock();
Expand All @@ -159,10 +150,8 @@ rule nextRemovableTimeDoesNotRevert(MetaMorphoHarness.Id id) {
env e;
require e.msg.value == 0;

// Safe require because it is a verified invariant.
require isTimelockInRange();
// Safe require because it is a verified invariant.
require isPendingTimelockInRange();
requireInvariant timelockInRange();
requireInvariant pendingTimelockInRange();

nextRemovableTime@withrevert(e, id);

Expand All @@ -178,8 +167,7 @@ rule removableTime(env e_next, method f, calldataarg args) {

MetaMorphoHarness.Id id;

// Safe require because it is a verified invariant.
require isTimelockInRange();
requireInvariant timelockInRange();

uint256 nextTime = nextRemovableTime(e, id);

Expand Down
9 changes: 3 additions & 6 deletions certora/specs/Tokens.spec
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,8 @@ function summarySupply(MetaMorphoHarness.MarketParams marketParams, uint256 asse
assert onBehalf == currentContract;
assert data.length == 0;

// Safe require because it is a verified invariant.
require hasSupplyCapIsEnabled(Util.libId(marketParams));
// Safe require because it is a verified invariant.
require isEnabledHasConsistentAsset(marketParams);
requireInvariant supplyCapIsEnabled(Util.libId(marketParams));
requireInvariant enabledHasConsistentAsset(marketParams);

// Summarize supply as just a transfer for the purpose of this specification file, which is sound because only the properties about tokens are verified in this file.
Util.safeTransferFrom(marketParams.loanToken, currentContract, MORPHO(), assets);
Expand All @@ -50,8 +48,7 @@ function summaryWithdraw(MetaMorphoHarness.MarketParams marketParams, uint256 as

// Safe require because it is verifed in MarketInteractions.
require config_(id).enabled;
// Safe require because it is a verified invariant.
require isEnabledHasConsistentAsset(marketParams);
requireInvariant enabledHasConsistentAsset(marketParams);

// Use effective withdrawn assets if shares are given as input.
uint256 withdrawn = Util.withdrawnAssets(MORPHO(), id, assets, shares);
Expand Down

0 comments on commit 3066d68

Please sign in to comment.