split stateTransitionFn as multiple rules with requires

This commit is contained in:
Hadrien Croubois
2023-05-05 15:07:56 +02:00
parent a97d3f5ce9
commit 9a33b0d2a2

View File

@ -28,30 +28,77 @@ rule stateConsistency(env e, uint256 pId) {
Rule: State transitions caused by function calls Rule: State transitions caused by function calls
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ └─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
*/ */
rule stateTransitionFn(uint256 pId, env e, method f, calldataarg args) /// Previous version that results in the prover timing out.
filtered { f -> !assumedSafe(f) // rule stateTransitionFn(uint256 pId, env e, method f, calldataarg args)
&& f.selector != castVoteBySig(uint256,uint8,uint8,bytes32,bytes32).selector // filtered { f -> !assumedSafe(f) }
&& f.selector != castVoteWithReasonAndParams(uint256,uint8,string,bytes).selector // {
&& f.selector != castVoteWithReason(uint256,uint8,string).selector // require clockSanity(e);
&& f.selector != castVoteWithReasonAndParamsBySig(uint256,uint8,string,bytes,uint8,bytes32,bytes32).selector // require quorumNumeratorLength() < max_uint256; // sanity
} //
{ // uint8 stateBefore = state(e, pId);
// f(e, args);
// uint8 stateAfter = state(e, pId);
//
// assert (stateBefore != stateAfter) => (
// (stateBefore == UNSET() && stateAfter == PENDING() && f.selector == propose(address[],uint256[],bytes[],string).selector ) ||
// (stateBefore == PENDING() && stateAfter == CANCELED() && f.selector == cancel(address[],uint256[],bytes[],bytes32).selector ) ||
// (stateBefore == SUCCEEDED() && stateAfter == QUEUED() && f.selector == queue(address[],uint256[],bytes[],bytes32).selector ) ||
// (stateBefore == SUCCEEDED() && stateAfter == EXECUTED() && f.selector == execute(address[],uint256[],bytes[],bytes32).selector) ||
// (stateBefore == QUEUED() && stateAfter == EXECUTED() && f.selector == execute(address[],uint256[],bytes[],bytes32).selector)
// );
// }
function stateTransitionFnHelper(method f, uint8 s) returns uint8 {
uint256 pId; env e; calldataarg args;
require clockSanity(e); require clockSanity(e);
require quorumNumeratorLength() < max_uint256; // sanity require quorumNumeratorLength() < max_uint256; // sanity
uint8 stateBefore = state(e, pId); require state(e, pId) == s; // constrain state before
f(e, args); f(e, args);
uint8 stateAfter = state(e, pId); require state(e, pId) != s; // constrain state after
assert (stateBefore != stateAfter) => ( return state(e, pId);
(stateBefore == UNSET() && stateAfter == PENDING() && f.selector == propose(address[],uint256[],bytes[],string).selector ) || }
(stateBefore == PENDING() && stateAfter == CANCELED() && f.selector == cancel(address[],uint256[],bytes[],bytes32).selector ) ||
(stateBefore == SUCCEEDED() && stateAfter == QUEUED() && f.selector == queue(address[],uint256[],bytes[],bytes32).selector ) || rule stateTransitionFn_PENDING(method f) filtered { f -> !assumedSafe(f) } {
(stateBefore == SUCCEEDED() && stateAfter == EXECUTED() && f.selector == execute(address[],uint256[],bytes[],bytes32).selector) || uint8 stateAfter = stateTransitionFnHelper(f, PENDING());
(stateBefore == QUEUED() && stateAfter == EXECUTED() && f.selector == execute(address[],uint256[],bytes[],bytes32).selector) assert stateAfter == CANCELED() && f.selector == cancel(address[],uint256[],bytes[],bytes32).selector;
}
rule stateTransitionFn_ACTIVE(method f) filtered { f -> !assumedSafe(f) } {
uint8 stateAfter = stateTransitionFnHelper(f, ACTIVE());
assert false;
}
rule stateTransitionFn_CANCELED(method f) filtered { f -> !assumedSafe(f) } {
uint8 stateAfter = stateTransitionFnHelper(f, CANCELED());
assert false;
}
rule stateTransitionFn_DEFEATED(method f) filtered { f -> !assumedSafe(f) } {
uint8 stateAfter = stateTransitionFnHelper(f, DEFEATED());
assert false;
}
rule stateTransitionFn_SUCCEEDED(method f) filtered { f -> !assumedSafe(f) } {
uint8 stateAfter = stateTransitionFnHelper(f, SUCCEEDED());
assert (
(stateAfter == QUEUED() && f.selector == queue(address[],uint256[],bytes[],bytes32).selector) ||
(stateAfter == EXECUTED() && f.selector == execute(address[],uint256[],bytes[],bytes32).selector)
); );
} }
rule stateTransitionFn_QUEUED(method f) filtered { f -> !assumedSafe(f) } {
uint8 stateAfter = stateTransitionFnHelper(f, QUEUED());
assert state(e, pId) == EXECUTED() && f.selector == execute(address[],uint256[],bytes[],bytes32).selector;
}
rule stateTransitionFn_EXECUTED(method f) filtered { f -> !assumedSafe(f) } {
uint8 stateAfter = stateTransitionFnHelper(f, EXECUTED());
assert false;
}
/* /*
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ ┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
Rule: State transitions caused by time passing Rule: State transitions caused by time passing