Partially Parametric Rules
The provided code snippet illustrates a partially parametric rule in CVL that defines specific behavior based on the method invoked (f) and its arguments (calldataarg). Let’s break down the example for better understanding:
rule partially_parametric_rule(env e, method f, calldataarg args)
{
if (f.selector == sig:withdraw(uint256, address).selector) {
uint256 shares;
address to;
require e.msg.sender != currentContract;
require shares == totalSupply();
withdraw(e, shares, to);
assert balanceOf(to) >= balanceOf(currentContract);
}
else if (f.selector == sig:deposit(uint256, address).selector) {
uint256 depositedAmount = balanceOf(e.msg.sender);
address to;
require e.msg.sender != currentContract;
deposit(e, depositedAmount, to);
assert balanceOf(to) >= balanceOf(e.msg.sender);
}
else {
uint256 currentContract_balance_before = balanceOf(currentContract);
f(e, args);
assert balanceOf(currentContract) == currentContract_balance_before;
}
}
Withdrawal Case:
If the invoked method (
f) corresponds to thewithdrawfunction with arguments of typeuint256andaddress, the rule checks certain conditions:Ensures that the sender is not the current contract (
currentContract).Requires that the variable
sharesis equal to the total supply.Invokes the
withdrawfunction with specified parameters (e,shares,to).Asserts that the balance of the recipient (
to) is greater than or equal to the balance of the current contract.
Deposit Case:
If the invoked method (
f) corresponds to thedepositfunction with arguments of typeuint256andaddress, the rule checks similar conditions:Ensures that the sender is not the current contract (
currentContract).Computes the
depositedAmountas the balance of the sender (e.msg.sender).Invokes the
depositfunction with specified parameters (e,depositedAmount,to).Asserts that the balance of the recipient (
to) is greater than or equal to the balance of the sender.
Default Case:
For any other method, the rule captures the state of the current contract’s balance before the method (
f) execution in the variablecurrentContract_balance_before.Invokes the method (
f) with its corresponding arguments (args).Asserts that the balance of the current contract after the method execution is equal to the recorded
currentContract_balance_before.
This partially parametric rule demonstrates conditional logic based on the type of method invoked, allowing for specific actions and assertions tailored to different scenarios within the smart contract.