Skip to content

Commit b8bc824

Browse files
authored
Merge pull request #620 from morpho-org/certora/suggestions-from-review
[Certora] Fix suggestions
2 parents 2a137a8 + 7e9a1b8 commit b8bc824

File tree

7 files changed

+32
-36
lines changed

7 files changed

+32
-36
lines changed

certora/specs/ExitLiquidity.spec

+11-11
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ methods {
1616
function libId(MorphoHarness.MarketParams) external returns MorphoHarness.Id envfree;
1717
}
1818

19-
// Check that it's not possible to withdraw more assets than what the user has supplied.
19+
// Check that it's not possible to withdraw more assets than what the user owns.
2020
rule withdrawLiquidity(MorphoHarness.MarketParams marketParams, uint256 assets, uint256 shares, address onBehalf, address receiver) {
2121
env e;
2222
MorphoHarness.Id id = libId(marketParams);
@@ -27,27 +27,27 @@ rule withdrawLiquidity(MorphoHarness.MarketParams marketParams, uint256 assets,
2727
uint256 initialShares = supplyShares(id, onBehalf);
2828
uint256 initialTotalSupply = virtualTotalSupplyAssets(id);
2929
uint256 initialTotalSupplyShares = virtualTotalSupplyShares(id);
30-
uint256 owedAssets = libMulDivDown(initialShares, initialTotalSupply, initialTotalSupplyShares);
30+
uint256 ownedAssets = libMulDivDown(initialShares, initialTotalSupply, initialTotalSupplyShares);
3131

3232
uint256 withdrawnAssets;
3333
withdrawnAssets, _ = withdraw(e, marketParams, assets, shares, onBehalf, receiver);
3434

35-
assert withdrawnAssets <= owedAssets;
35+
assert withdrawnAssets <= ownedAssets;
3636
}
3737

38-
// Check that it's not possible to withdraw more collateral than what the user has supplied.
39-
rule withdrawCollateralLiquidity(MorphoHarness.MarketParams marketParams, uint256 assets, address onBehalf, address receiver) {
38+
// Check that it's not possible to withdraw more collateral than what the user owns.
39+
rule withdrawCollateralLiquidity(MorphoHarness.MarketParams marketParams, uint256 withdrawnAssets, address onBehalf, address receiver) {
4040
env e;
4141
MorphoHarness.Id id = libId(marketParams);
4242

43-
uint256 initialCollateral = collateral(id, onBehalf);
43+
uint256 ownedAssets = collateral(id, onBehalf);
4444

45-
withdrawCollateral(e, marketParams, assets, onBehalf, receiver);
45+
withdrawCollateral(e, marketParams, withdrawnAssets, onBehalf, receiver);
4646

47-
assert assets <= initialCollateral;
47+
assert withdrawnAssets <= ownedAssets;
4848
}
4949

50-
// Check than when repaying the full outstanding debt requires more assets than what was borrowed.
50+
// Check than when repaying the full outstanding debt requires more assets than what the user owes.
5151
rule repayLiquidity(MorphoHarness.MarketParams marketParams, uint256 assets, uint256 shares, address onBehalf, bytes data) {
5252
env e;
5353
MorphoHarness.Id id = libId(marketParams);
@@ -58,13 +58,13 @@ rule repayLiquidity(MorphoHarness.MarketParams marketParams, uint256 assets, uin
5858
uint256 initialShares = borrowShares(id, onBehalf);
5959
uint256 initialTotalBorrow = virtualTotalBorrowAssets(id);
6060
uint256 initialTotalBorrowShares = virtualTotalBorrowShares(id);
61-
uint256 assetsDue = libMulDivUp(initialShares, initialTotalBorrow, initialTotalBorrowShares);
61+
uint256 owedAssets = libMulDivUp(initialShares, initialTotalBorrow, initialTotalBorrowShares);
6262

6363
uint256 repaidAssets;
6464
repaidAssets, _ = repay(e, marketParams, assets, shares, onBehalf, data);
6565

6666
// Assume a full repay.
6767
require borrowShares(id, onBehalf) == 0;
6868

69-
assert repaidAssets >= assetsDue;
69+
assert repaidAssets >= owedAssets;
7070
}

certora/specs/Health.spec

+3-3
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,13 @@ function mockPrice() returns uint256 {
3030
}
3131

3232
function summaryMulDivUp(uint256 x, uint256 y, uint256 d) returns uint256 {
33-
// Safe requires because the reference implementation would revert.
33+
// Safe require because the reference implementation would revert.
3434
require d != 0;
3535
return require_uint256((x * y + (d - 1)) / d);
3636
}
3737

3838
function summaryMulDivDown(uint256 x, uint256 y, uint256 d) returns uint256 {
39-
// Safe requires because the reference implementation would revert.
39+
// Safe require because the reference implementation would revert.
4040
require d != 0;
4141
return require_uint256((x * y) / d);
4242
}
@@ -103,6 +103,6 @@ filtered { f -> !f.isView }
103103
}
104104

105105
// Check that users without collateral also have no debt.
106-
// This invariant ensures that bad debt is always accounted.
106+
// This invariant ensures that bad debt realization cannot be bypassed.
107107
invariant alwaysCollateralized(MorphoHarness.Id id, address borrower)
108108
borrowShares(id, borrower) != 0 => collateral(id, borrower) != 0;

certora/specs/Liveness.spec

+1-3
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,8 @@ function summaryAccrueInterest(env e, MorphoInternalAccess.MarketParams marketPa
5353
require e.block.timestamp < 2^128;
5454
if (e.block.timestamp != lastUpdate(id) && totalBorrowAssets(id) != 0) {
5555
uint128 interest;
56-
uint256 borrow = totalBorrowAssets(id);
5756
uint256 supply = totalSupplyAssets(id);
58-
// Safe requires because the reference implementation would revert.
59-
require interest + borrow < 2^256;
57+
// Safe require because the reference implementation would revert.
6058
require interest + supply < 2^256;
6159
increaseInterest(e, id, interest);
6260
}

certora/specs/RatioMath.spec

+1-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ rule accrueInterestIncreasesBorrowRatio(env e, MorphoHarness.MarketParams market
7575
}
7676

7777

78-
// Check that excepti for liquidate, every function increases the value of supply shares.
78+
// Check that except when not accruing interest and except for liquidate, every function increases the value of supply shares.
7979
rule onlyLiquidateCanDecreaseSupplyRatio(env e, method f, calldataarg args)
8080
filtered {
8181
f -> !f.isView && f.selector != sig:liquidate(MorphoHarness.MarketParams, address, uint256, uint256, bytes).selector

certora/specs/Reentrancy.spec

+8-6
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,14 @@ methods {
55
function _.borrowRate(MorphoHarness.MarketParams marketParams, MorphoHarness.Market) external => summaryBorrowRate() expect uint256;
66
}
77

8+
ghost bool delegateCall;
9+
ghost bool callIsBorrowRate;
10+
// True when storage has been accessed with either a SSTORE or a SLOAD.
811
ghost bool hasAccessedStorage;
12+
// True when a CALL has been done after storage has been accessed.
913
ghost bool hasCallAfterAccessingStorage;
14+
// True when storage has been accessed, after which an external call is made, followed by accessing storage again.
1015
ghost bool hasReentrancyUnsafeCall;
11-
ghost bool delegate_call;
12-
ghost bool callIsBorrowRate;
1316

1417
function summaryBorrowRate() returns uint256 {
1518
uint256 result;
@@ -31,14 +34,13 @@ hook CALL(uint g, address addr, uint value, uint argsOffset, uint argsLength, ui
3134
if (callIsBorrowRate) {
3235
// The calls to borrow rate are trusted and don't count.
3336
callIsBorrowRate = false;
34-
hasCallAfterAccessingStorage = hasCallAfterAccessingStorage;
3537
} else {
3638
hasCallAfterAccessingStorage = hasAccessedStorage;
3739
}
3840
}
3941

4042
hook DELEGATECALL(uint g, address addr, uint argsOffset, uint argsLength, uint retOffset, uint retLength) uint rc {
41-
delegate_call = true;
43+
delegateCall = true;
4244
}
4345

4446
// Check that no function is accessing storage, then making an external CALL other than to the IRM, and accessing storage again.
@@ -53,7 +55,7 @@ rule reentrancySafe(method f, env e, calldataarg data) {
5355
// Check that the contract is truly immutable.
5456
rule noDelegateCalls(method f, env e, calldataarg data) {
5557
// Set up the initial state.
56-
require !delegate_call;
58+
require !delegateCall;
5759
f(e,data);
58-
assert !delegate_call;
60+
assert !delegateCall;
5961
}

certora/specs/Reverts.spec

+8-8
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ definition exactlyOneZero(uint256 assets, uint256 shares) returns bool =
4242
(assets == 0 && shares != 0) || (assets != 0 && shares == 0);
4343

4444
// This invariant catches bugs when not checking that the market is created with lastUpdate.
45-
invariant notInitializedEmpty(MorphoHarness.Id id)
45+
invariant notCreatedIsEmpty(MorphoHarness.Id id)
4646
!isCreated(id) => emptyMarket(id)
4747
{
4848
preserved with (env e) {
@@ -108,9 +108,9 @@ rule createMarketRevertCondition(env e, MorphoHarness.MarketParams marketParams)
108108
MorphoHarness.Id id = libId(marketParams);
109109
bool irmEnabled = isIrmEnabled(marketParams.irm);
110110
bool lltvEnabled = isLltvEnabled(marketParams.lltv);
111-
uint256 lastUpdated = lastUpdate(id);
111+
bool wasCreated = isCreated(id);
112112
createMarket@withrevert(e, marketParams);
113-
assert lastReverted <=> e.msg.value != 0 || !irmEnabled || !lltvEnabled || lastUpdated != 0;
113+
assert lastReverted <=> e.msg.value != 0 || !irmEnabled || !lltvEnabled || wasCreated;
114114
}
115115

116116
// Check that supply reverts when its input are not validated.
@@ -125,7 +125,7 @@ rule withdrawInputValidation(env e, MorphoHarness.MarketParams marketParams, uin
125125
require e.msg.sender != 0;
126126
requireInvariant zeroDoesNotAuthorize(e.msg.sender);
127127
withdraw@withrevert(e, marketParams, assets, shares, onBehalf, receiver);
128-
assert !exactlyOneZero(assets, shares) || onBehalf == 0 => lastReverted;
128+
assert !exactlyOneZero(assets, shares) || onBehalf == 0 || receiver == 0 => lastReverted;
129129
}
130130

131131
// Check that borrow reverts when its inputs are not validated.
@@ -134,7 +134,7 @@ rule borrowInputValidation(env e, MorphoHarness.MarketParams marketParams, uint2
134134
require e.msg.sender != 0;
135135
requireInvariant zeroDoesNotAuthorize(e.msg.sender);
136136
borrow@withrevert(e, marketParams, assets, shares, onBehalf, receiver);
137-
assert !exactlyOneZero(assets, shares) || onBehalf == 0 => lastReverted;
137+
assert !exactlyOneZero(assets, shares) || onBehalf == 0 || receiver == 0 => lastReverted;
138138
}
139139

140140
// Check that repay reverts when its inputs are not validated.
@@ -155,7 +155,7 @@ rule withdrawCollateralInputValidation(env e, MorphoHarness.MarketParams marketP
155155
require e.msg.sender != 0;
156156
requireInvariant zeroDoesNotAuthorize(e.msg.sender);
157157
withdrawCollateral@withrevert(e, marketParams, assets, onBehalf, receiver);
158-
assert assets == 0 || onBehalf == 0 => lastReverted;
158+
assert assets == 0 || onBehalf == 0 || receiver == 0 => lastReverted;
159159
}
160160

161161
// Check that liquidate reverts when its inputs are not validated.
@@ -173,7 +173,7 @@ rule setAuthorizationWithSigInputValidation(env e, MorphoHarness.Authorization a
173173

174174
// Check that accrueInterest reverts when its inputs are not validated.
175175
rule accrueInterestInputValidation(env e, MorphoHarness.MarketParams marketParams) {
176-
uint256 lastUpdate = lastUpdate(libId(marketParams));
176+
bool wasCreated = isCreated(libId(marketParams));
177177
accrueInterest@withrevert(e, marketParams);
178-
assert lastUpdate == 0 => lastReverted;
178+
assert !wasCreated => lastReverted;
179179
}

certora/specs/Transfer.spec

-4
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,6 @@ rule transferRevertCondition(address token, address to, uint256 amount) {
6363
uint256 toInitialBalance = balanceOf(token, to);
6464
// Safe require because the total supply is greater than the sum of the balance of any two accounts.
6565
require to != currentContract => initialBalance + toInitialBalance <= to_mathint(totalSupply(token));
66-
// Some tokens revert when either the sender or the receiver is the zero address.
67-
require currentContract != 0 && to != 0;
6866

6967
libSafeTransfer@withrevert(token, to, amount);
7068

@@ -78,8 +76,6 @@ rule transferFromRevertCondition(address token, address from, address to, uint25
7876
uint256 allowance = allowance(token, from, currentContract);
7977
// Safe require because the total supply is greater than the sum of the balance of any two accounts.
8078
require to != from => initialBalance + toInitialBalance <= to_mathint(totalSupply(token));
81-
// Some tokens revert when either the sender or the receiver is the zero address.
82-
require from != 0 && to != 0;
8379

8480
libSafeTransferFrom@withrevert(token, from, to, amount);
8581

0 commit comments

Comments
 (0)