|
|
|
@ -86,6 +86,7 @@ rule singleTokenBurnBurnBatchEquivalence { |
|
|
|
|
address holder; |
|
|
|
|
uint256 token; uint256 burnAmount; |
|
|
|
|
uint256[] tokens; uint256[] burnAmounts; |
|
|
|
|
|
|
|
|
|
mathint startingBalance = balanceOf(holder, token); |
|
|
|
|
|
|
|
|
|
require tokens.length == 1; require burnAmounts.length == 1; |
|
|
|
@ -103,6 +104,48 @@ rule singleTokenBurnBurnBatchEquivalence { |
|
|
|
|
"Burning a single token via burn or burnBatch must be equivalent"; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// The results of burning multiple tokens must be equivalent whether done |
|
|
|
|
/// separately via burn or together via burnBatch. |
|
|
|
|
rule multipleTokenBurnBurnBatchEquivalence { |
|
|
|
|
storage beforeBurns = lastStorage; |
|
|
|
|
env e; |
|
|
|
|
|
|
|
|
|
address holder; |
|
|
|
|
uint256 tokenA; uint256 tokenB; uint256 tokenC; |
|
|
|
|
uint256 burnAmountA; uint256 burnAmountB; uint256 burnAmountC; |
|
|
|
|
uint256[] tokens; uint256[] burnAmounts; |
|
|
|
|
|
|
|
|
|
require tokenA != tokenB; require tokenB != tokenC; require tokenC != tokenA; |
|
|
|
|
|
|
|
|
|
mathint startingBalanceA = balanceOf(holder, tokenA); |
|
|
|
|
mathint startingBalanceB = balanceOf(holder, tokenB); |
|
|
|
|
mathint startingBalanceC = balanceOf(holder, tokenC); |
|
|
|
|
|
|
|
|
|
require tokens.length == 3; require burnAmounts.length == 3; |
|
|
|
|
require tokens[0] == tokenA; require burnAmounts[0] == burnAmountA; |
|
|
|
|
require tokens[1] == tokenB; require burnAmounts[1] == burnAmountB; |
|
|
|
|
require tokens[2] == tokenC; require burnAmounts[2] == burnAmountC; |
|
|
|
|
|
|
|
|
|
// burning via burn |
|
|
|
|
burn(e, holder, tokenA, burnAmountA) at beforeBurns; |
|
|
|
|
mathint burnBalanceChangeA = startingBalanceA - balanceOf(holder, tokenA); |
|
|
|
|
burn(e, holder, tokenB, burnAmountB) at beforeBurns; |
|
|
|
|
mathint burnBalanceChangeB = startingBalanceB - balanceOf(holder, tokenB); |
|
|
|
|
burn(e, holder, tokenC, burnAmountC) at beforeBurns; |
|
|
|
|
mathint burnBalanceChangeC = startingBalanceC - balanceOf(holder, tokenC); |
|
|
|
|
|
|
|
|
|
// burning via burnBatch |
|
|
|
|
burnBatch(e, holder, tokens, burnAmounts) at beforeBurns; |
|
|
|
|
mathint burnBatchBalanceChangeA = startingBalanceA - balanceOf(holder, tokenA); |
|
|
|
|
mathint burnBatchBalanceChangeB = startingBalanceB - balanceOf(holder, tokenB); |
|
|
|
|
mathint burnBatchBalanceChangeC = startingBalanceC - balanceOf(holder, tokenC); |
|
|
|
|
|
|
|
|
|
assert burnBalanceChangeA == burnBatchBalanceChangeA |
|
|
|
|
&& burnBalanceChangeB == burnBatchBalanceChangeB |
|
|
|
|
&& burnBalanceChangeC == burnBatchBalanceChangeC, |
|
|
|
|
"Burning multiple tokens via burn or burnBatch must be equivalent"; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// This rule should always fail. |
|
|
|
|
rule sanity { |
|
|
|
|
method f; env e; calldataarg args; |
|
|
|
|