123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 |
- import "erc20.spec"
- /*
- โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
- โ Ghost & hooks: sum of all balances โ
- โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
- */
- ghost sumOfBalances() returns uint256 {
- init_state axiom sumOfBalances() == 0;
- }
- hook Sstore _balances[KEY address addr] uint256 newValue (uint256 oldValue) STORAGE {
- havoc sumOfBalances assuming sumOfBalances@new() == sumOfBalances@old() + newValue - oldValue;
- }
- /*
- โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
- โ Invariant: totalSupply is the sum of all balances โ
- โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
- */
- invariant totalSupplyIsSumOfBalances()
- totalSupply() == sumOfBalances()
- /*
- โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
- โ Invariant: balance of address(0) is 0 โ
- โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
- */
- invariant zeroAddressNoBalance()
- balanceOf(0) == 0
- /*
- โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
- โ Rules: totalSupply only changes through mint or burn โ
- โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
- */
- rule noChangeTotalSupply() {
- requireInvariant totalSupplyIsSumOfBalances();
- env e;
- method f;
- calldataarg args;
- uint256 totalSupplyBefore = totalSupply();
- f(e, args);
- uint256 totalSupplyAfter = totalSupply();
- assert (totalSupplyAfter > totalSupplyBefore) => (f.selector == mint(address,uint256).selector);
- assert (totalSupplyAfter < totalSupplyBefore) => (f.selector == burn(address,uint256).selector);
- }
- /*
- โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
- โ Rules: totalSupply change matches minted or burned amount โ
- โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
- */
- rule mintIncreasesTotalSupply() {
- requireInvariant totalSupplyIsSumOfBalances();
- env e;
- address to;
- uint256 amount;
- uint256 totalSupplyBefore = totalSupply();
- mint(e, to, amount);
- uint256 totalSupplyAfter = totalSupply();
- assert totalSupplyAfter == totalSupplyBefore + amount;
- }
- rule burnDecreasesTotalSupply() {
- requireInvariant totalSupplyIsSumOfBalances();
- env e;
- address from;
- uint256 amount;
- uint256 totalSupplyBefore = totalSupply();
- burn(e, from, amount);
- uint256 totalSupplyAfter = totalSupply();
- assert totalSupplyAfter == totalSupplyBefore - amount;
- }
- /*
- โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
- โ Rules: Balance of an account can only decrease if the tx was sent by owner or by approved โ
- โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
- */
- rule onlyAuthorizedCanTransfer() {
- requireInvariant totalSupplyIsSumOfBalances();
- env e;
- method f;
- calldataarg args;
- address account;
- uint256 allowanceBefore = allowance(account, e.msg.sender);
- uint256 balanceBefore = balanceOf(account);
- f(e, args);
- uint256 balanceAfter = balanceOf(account);
- assert (
- balanceAfter < balanceBefore
- ) => (
- f.selector == burn(address,uint256).selector ||
- e.msg.sender == account ||
- balanceBefore - balanceAfter <= allowanceBefore
- );
- }
- /*
- โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
- โ Rule: transfer moves correct amount from sender to receiver โ
- โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
- */
- rule transferAmount() {
- requireInvariant totalSupplyIsSumOfBalances();
- env e;
- address holder = e.msg.sender;
- address recipient;
- uint256 amount;
- uint256 holderBalanceBefore = balanceOf(holder);
- uint256 recipientBalanceBefore = balanceOf(recipient);
- transfer(e, recipient, amount);
- assert balanceOf(holder) == holderBalanceBefore - (holder == recipient ? 0 : amount);
- assert balanceOf(recipient) == recipientBalanceBefore + (holder == recipient ? 0 : amount);
- }
- /*
- โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
- โ Rule: transferFrom moves correct amount from holder to receiver, and updates allowance โ
- โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
- */
- rule transferFomAmountAndApproval() {
- requireInvariant totalSupplyIsSumOfBalances();
- env e;
- address holder;
- address recipient;
- uint256 amount;
- uint256 allowanceBefore = allowance(holder, e.msg.sender);
- uint256 holderBalanceBefore = balanceOf(holder);
- uint256 recipientBalanceBefore = balanceOf(recipient);
- transferFrom(e, holder, recipient, amount);
- assert allowanceBefore >= amount;
- assert allowance(holder, e.msg.sender) == (allowanceBefore == max_uint256 ? to_uint256(max_uint256) : allowanceBefore - amount);
- assert balanceOf(holder) == holderBalanceBefore - (holder == recipient ? 0 : amount);
- assert balanceOf(recipient) == recipientBalanceBefore + (holder == recipient ? 0 : amount);
- }
|