Producing Positive Examples
Sometimes it is useful to produce examples of an expected behavior instead of
counterexamples that demonstrate unexpected behavior. You can do this by
writing a rule that uses satisfy statements instead of the assert
command. For
each satisfy
command in a rule, the Prover will produce an example that makes
the condition true, or report an error.
The purpose of the satisfy
statement is to produce examples that demonstrate
some execution of the code. Not every example is interesting — users
should inspect the example to ensure that it demonstrates the expected
behavior.
For example, we may be interested in showing that it is possible for someone to deposit some assets into a pool and then immediately withdraw them. The following rule demonstrates this scenario:
rule possibleToFullyWithdraw(address sender, uint256 amount) {
env eT0;
env eM;
setup(eM);
uint256 balanceBefore = _token0.balanceOf(sender);
require eM.msg.sender == sender;
require eT0.msg.sender == sender;
require amount > 0;
_token0.transfer(eT0, currentContract, amount);
uint256 amountOut0 = mint(eM,sender);
// immediately withdraw
burnSingle(eM, _token0, amountOut0, sender);
satisfy (balanceBefore == _token0.balanceOf(sender));
}
The Prover will produce an example that satisfies this condition.
Sometimes the example will be uninteresting, such as having
amount == 0
in the example for possibleToFullyWithdraw
.
In such cases we need to strengthen the conditions in order
to produce more interesting examples.
In possibleToFullyWithdraw
we added a
require amount > 0;
statement to prevent such a case.
Alternatively, we could have strengthened the satisfy
condition by adding
satisfy (amount > 0) && ...