Files
openzeppelin-contracts/certora/specs/ERC20FlashMint.spec
Ernesto García fd812ee954 Group typographical errors (#5443)
Co-authored-by: futreall <86553580+futreall@users.noreply.github.com>
Co-authored-by: Marco <wudmytrotest200@gmail.com>
Co-authored-by: Dmitry <98899785+mdqst@users.noreply.github.com>
Co-authored-by: Dmytrol <46675332+Dimitrolito@users.noreply.github.com>
Co-authored-by: Noisy <125606576+donatik27@users.noreply.github.com>
Co-authored-by: Danil <37103154+Danyylka@users.noreply.github.com>
Co-authored-by: CrazyFrog <anna.shuraeva13@gmail.com>
Co-authored-by: Bryer <0xbryer@gmail.com>
Co-authored-by: Viktor Pavlik <160131789+Vikt0rPavlik@users.noreply.github.com>
Co-authored-by: Skylar Ray <137945430+sky-coderay@users.noreply.github.com>
Co-authored-by: Brawn <nftdropped@gmail.com>
Co-authored-by: fuder.eth <139509124+vtjl10@users.noreply.github.com>
Co-authored-by: FT <140458077+zeevick10@users.noreply.github.com>
Co-authored-by: Ann Wagner <chant_77_swirly@icloud.com>
Co-authored-by: Hopium <135053852+Hopium21@users.noreply.github.com>
Co-authored-by: Arr00 <13561405+arr00@users.noreply.github.com>
Co-authored-by: Hadrien Croubois <hadrien.croubois@gmail.com>
2025-01-24 18:18:59 +01:00

56 lines
3.2 KiB
Ruby

import "helpers/helpers.spec";
import "methods/IERC20.spec";
import "methods/IERC3156FlashLender.spec";
import "methods/IERC3156FlashBorrower.spec";
methods {
// non standard ERC-3156 functions
function flashFeeReceiver() external returns (address) envfree;
// function summaries below
function _._update(address from, address to, uint256 amount) internal => specUpdate(from, to, amount) expect void ALL;
}
/*
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Ghost: track mint and burns in the CVL │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
*/
ghost mapping(address => mathint) trackedMintAmount;
ghost mapping(address => mathint) trackedBurnAmount;
ghost mapping(address => mapping(address => mathint)) trackedTransferredAmount;
function specUpdate(address from, address to, uint256 amount) {
if (from == 0 && to == 0) { assert(false); } // defensive
if (from == 0) {
trackedMintAmount[to] = amount;
} else if (to == 0) {
trackedBurnAmount[from] = amount;
} else {
trackedTransferredAmount[from][to] = amount;
}
}
/*
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Rule: When doing a flashLoan, "amount" is minted and burnt, additionally, the fee is either burnt │
│ (if the fee recipient is 0) or transferred (if the fee recipient is not 0) │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
*/
rule checkMintAndBurn(env e) {
address receiver;
address token;
uint256 amount;
bytes data;
uint256 fees = flashFee(token, amount);
address recipient = flashFeeReceiver();
flashLoan(e, receiver, token, amount, data);
assert trackedMintAmount[receiver] == to_mathint(amount);
assert trackedBurnAmount[receiver] == amount + to_mathint(recipient == 0 ? fees : 0);
assert (fees > 0 && recipient != 0) => trackedTransferredAmount[receiver][recipient] == to_mathint(fees);
}