chore(certora): add invariant that totalSupply is sumOfBalances
This invariant ensures that the total supply of the used token in the contract is always greater equal to the sum of all balances within the token combined.
This commit is contained in:
parent
2e3f775a0d
commit
e04f8ae909
|
@ -2,12 +2,25 @@ using ERC20A as Token;
|
||||||
|
|
||||||
methods {
|
methods {
|
||||||
function Token.balanceOf(address) external returns (uint256) envfree;
|
function Token.balanceOf(address) external returns (uint256) envfree;
|
||||||
|
function Token.totalSupply() external returns (uint256) envfree;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*--------------------------------------------
|
/*--------------------------------------------
|
||||||
| Ghosts and hooks |
|
| Ghosts and hooks |
|
||||||
--------------------------------------------*/
|
--------------------------------------------*/
|
||||||
|
|
||||||
|
ghost mathint sumOfBalances {
|
||||||
|
init_state axiom sumOfBalances == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
hook Sload uint256 balance Token._balances[KEY address addr] {
|
||||||
|
require sumOfBalances >= to_mathint(balance);
|
||||||
|
}
|
||||||
|
|
||||||
|
hook Sstore Token._balances[KEY address addr] uint256 newValue (uint256 oldValue) {
|
||||||
|
sumOfBalances = sumOfBalances - oldValue + newValue;
|
||||||
|
}
|
||||||
|
|
||||||
ghost mathint totalReceived;
|
ghost mathint totalReceived;
|
||||||
|
|
||||||
hook Sload uint256 defaultValue currentContract._marketplaceTotals.received {
|
hook Sload uint256 defaultValue currentContract._marketplaceTotals.received {
|
||||||
|
@ -28,6 +41,10 @@ hook Sstore currentContract._marketplaceTotals.sent uint256 defaultValue (uint25
|
||||||
totalSent = totalSent + defaultValue - defaultValue_old;
|
totalSent = totalSent + defaultValue - defaultValue_old;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------
|
||||||
|
| Helper functions |
|
||||||
|
--------------------------------------------*/
|
||||||
|
|
||||||
function canCancelRequest(method f) returns bool {
|
function canCancelRequest(method f) returns bool {
|
||||||
return f.selector == sig:withdrawFunds(Marketplace.RequestId).selector;
|
return f.selector == sig:withdrawFunds(Marketplace.RequestId).selector;
|
||||||
}
|
}
|
||||||
|
@ -45,6 +62,13 @@ function canFailRequest(method f) returns bool {
|
||||||
f.selector == sig:freeSlot(Marketplace.SlotId).selector;
|
f.selector == sig:freeSlot(Marketplace.SlotId).selector;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------
|
||||||
|
| Invariants |
|
||||||
|
--------------------------------------------*/
|
||||||
|
|
||||||
|
invariant totalSupplyIsSumOfBalances()
|
||||||
|
to_mathint(Token.totalSupply()) == sumOfBalances;
|
||||||
|
|
||||||
invariant requestStartedWhenSlotsFilled(env e, Marketplace.RequestId requestId, Marketplace.SlotId slotId)
|
invariant requestStartedWhenSlotsFilled(env e, Marketplace.RequestId requestId, Marketplace.SlotId slotId)
|
||||||
to_mathint(currentContract.requestContext(e, requestId).slotsFilled) == to_mathint(currentContract.getRequest(e, requestId).ask.slots) => currentContract.requestState(e, requestId) == Marketplace.RequestState.Started;
|
to_mathint(currentContract.requestContext(e, requestId).slotsFilled) == to_mathint(currentContract.getRequest(e, requestId).ask.slots) => currentContract.requestState(e, requestId) == Marketplace.RequestState.Started;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue