63 lines
2.3 KiB
Solidity
63 lines
2.3 KiB
Solidity
// SPDX-License-Identifier: MIT
|
|
pragma solidity 0.8.35;
|
|
|
|
import {BankTestBase} from "./helpers/BankTestBase.sol";
|
|
import {BankV2} from "../src/BankV2.sol";
|
|
import {Options, Upgrades} from "openzeppelin-foundry-upgrades/Upgrades.sol";
|
|
import {BankV2Handler} from "./helpers/BankV2Handler.sol";
|
|
|
|
contract BankInvariantTest is BankTestBase {
|
|
BankV2Handler internal handler;
|
|
|
|
function setUp() public override {
|
|
super.setUp();
|
|
Options memory opts;
|
|
opts.referenceContract = "BankV1.sol:BankV1";
|
|
Upgrades.upgradeProxy(proxy, "BankV2.sol:BankV2", "", opts, owner);
|
|
BankV2 bankV2 = BankV2(proxy);
|
|
|
|
handler = new BankV2Handler(token, bankV2);
|
|
vm.prank(owner);
|
|
token.transferOwnership(address(handler));
|
|
|
|
targetContract(address(handler));
|
|
bytes4[] memory selectors = new bytes4[](4);
|
|
selectors[0] = handler.deposit.selector;
|
|
selectors[1] = handler.withdraw.selector;
|
|
selectors[2] = handler.donate.selector;
|
|
selectors[3] = handler.transfer.selector;
|
|
targetSelector(FuzzSelector({addr: address(handler), selectors: selectors}));
|
|
}
|
|
|
|
function testHandlerExecutesDeterministicTrackedTransfer() public {
|
|
handler.deposit(0, 40e6);
|
|
|
|
handler.transfer(0, 0, 15e6);
|
|
|
|
assertEq(bank.balanceOf(handler.actorAt(0)), 25e6);
|
|
assertEq(bank.balanceOf(handler.actorAt(1)), 15e6);
|
|
assertEq(handler.ghostTransferred(), 15e6);
|
|
assertEq(bank.totalLiabilities(), 40e6);
|
|
assertEq(token.balanceOf(address(bank)), 40e6);
|
|
}
|
|
|
|
function invariant_liabilitiesEqualTrackedBalances() public view {
|
|
uint256 sum;
|
|
for (uint256 i; i < handler.actorCount(); ++i) {
|
|
sum += bank.balanceOf(handler.actorAt(i));
|
|
}
|
|
assertEq(sum, bank.totalLiabilities());
|
|
}
|
|
|
|
function invariant_reservesCoverLiabilities() public view {
|
|
assertGe(token.balanceOf(address(bank)), bank.totalLiabilities());
|
|
}
|
|
|
|
function invariant_ghostAccountingMatchesChain() public view {
|
|
assertEq(handler.ghostDeposited() - handler.ghostWithdrawn(), bank.totalLiabilities());
|
|
assertEq(
|
|
handler.ghostDeposited() + handler.ghostDonated() - handler.ghostWithdrawn(), token.balanceOf(address(bank))
|
|
);
|
|
}
|
|
}
|