12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 |
- methods {
- balanceOf(address, uint256) returns uint256 envfree
- isApprovedForAll(address,address) returns bool envfree
- }
- /// If a method call reduces account balances, the caller must be either the
- /// holder of the account or approved to act on the holder's behalf.
- rule onlyHolderOrApprovedCanReduceBalance {
- address holder; uint256 token; uint256 amount;
- uint256 balanceBefore = balanceOf(holder, token);
- method f; env e; calldataarg args;
- f(e, args);
- uint256 balanceAfter = balanceOf(holder, token);
- assert balanceAfter < balanceBefore => e.msg.sender == holder || isApprovedForAll(holder, e.msg.sender),
- "An account balance may only be reduced by the holder or a holder-approved agent";
- }
- /// Burning a larger amount of a token must reduce that token's balance more
- /// than burning a smaller amount.
- rule burnAmountProportionalToBalanceReduction {
- storage beforeBurn = lastStorage;
- env e;
-
- address holder; uint256 token;
- mathint startingBalance = balanceOf(holder, token);
- uint256 smallBurn; uint256 largeBurn;
- require smallBurn < largeBurn;
- // smaller burn amount
- burn(e, holder, token, smallBurn) at beforeBurn;
- mathint smallBurnBalanceChange = startingBalance - balanceOf(holder, token);
- // larger burn amount
- burn(e, holder, token, largeBurn) at beforeBurn;
- mathint largeBurnBalanceChange = startingBalance - balanceOf(holder, token);
- assert smallBurnBalanceChange < largeBurnBalanceChange,
- "A larger burn must lead to a larger decrease in balance";
- }
- /// Unimplemented rule to verify monotonicity of burnBatch.
- rule burnBatchAmountProportionalToBalanceReduction { // TODO implement rule or remove
- assert true,
- "just a placeholder that should never show up";
- }
- /// Two sequential burns must be equivalent to a single burn of the sum of their
- /// amounts.
- rule sequentialBurnsEquivalentToSingleBurnOfSum {
- storage beforeBurns = lastStorage;
- env e;
- address holder; uint256 token;
- mathint startingBalance = balanceOf(holder, token);
- uint256 firstBurn; uint256 secondBurn; uint256 sumBurn;
- require sumBurn == firstBurn + secondBurn;
- // sequential burns
- burn(e, holder, token, firstBurn) at beforeBurns;
- burn(e, holder, token, secondBurn);
- mathint sequentialBurnsBalanceChange = startingBalance - balanceOf(holder, token);
- // burn of sum of sequential burns
- burn(e, holder, token, sumBurn) at beforeBurns;
- mathint sumBurnBalanceChange = startingBalance - balanceOf(holder, token);
- assert sequentialBurnsBalanceChange == sumBurnBalanceChange,
- "Sequential burns must be equivalent to a burn of their sum";
- }
- /// Unimplemented rule to verify additivty of burnBatch.
- rule sequentialBatchBurnsEquivalentToSingleBurnBatchOfSum { // TODO implement rule or remove
- assert true,
- "just a placeholder that should never show up";
- }
- /// This rule should always fail.
- rule sanity {
- method f; env e; calldataarg args;
- f(e, args);
- assert false,
- "This rule should always fail";
- }
|