ERC20FlashMint.spec 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637
  1. import "erc20.spec"
  2. methods {
  3. onFlashLoan(address, address, uint256, uint256, bytes) => HAVOC_ALL // HAVOC_ECF
  4. _burn(address account, uint256 amount) returns(bool) => specBurn(account, amount);
  5. }
  6. ghost mapping(address => uint256) trackedBurnAmount;
  7. function specBurn(address account, uint256 amount) returns bool { // retuns needed to overcome current CVL limitations: "could not type expression "specBurn(account,amount)", message: A summary must return a simple type, but specBurn(account,amount) returns 'void'"
  8. trackedBurnAmount[account] = amount;
  9. return true;
  10. }
  11. // ghost to save args that were passed to burn function
  12. // summarize burn
  13. // assert ghost == amount + fee
  14. // STATUS - in progress
  15. // HAVOC_ALL - everything is havoced => violation
  16. // HAVOC_ECF - verified
  17. // https://vaas-stg.certora.com/output/3106/8795450b626f2ca53a2b/?anonymousKey=dd774da10cc595e4e38357af9e4f50bf2c0cb02a
  18. // fee + flashLoan amount is burned
  19. rule letsWatchItBurns(env e){
  20. address receiver; address token; uint256 amount; bytes data;
  21. require amount > 0;
  22. uint256 feeBefore = flashFee(e, token, amount);
  23. flashLoan(e, receiver, token, amount, data);
  24. uint256 burned = trackedBurnAmount[receiver];
  25. assert to_mathint(amount + feeBefore) == burned, "cheater";
  26. }