Files
uupl-smart-contract/test/NamedErrorExercises.t.sol
T
2026-08-21 04:57:14 -06:00

93 lines
3.7 KiB
Solidity

// SPDX-License-Identifier: MIT
pragma solidity 0.8.35;
import {Test} from "forge-std/Test.sol";
import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
import {BankV1} from "../src/BankV1.sol";
import {MockUSDC} from "../src/MockUSDC.sol";
import {CheckState} from "../script/CheckState.s.sol";
import {DemoScript} from "../script/lib/DemoScript.sol";
contract NamedErrorHarness is DemoScript {
function assertUint(string calldata label, uint256 expected, uint256 actual) external pure {
_assertUint(label, expected, actual);
}
function writeManifest(string calldata path, Manifest calldata manifest) external {
_writeManifest(path, manifest);
}
}
contract NamedErrorExercisesTest is Test {
address internal constant OWNER = 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266;
address internal constant ALICE = 0x70997970C51812dc3A010C7d01b50e0d17dc79C8;
address internal constant BOB = 0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC;
NamedErrorHarness internal harness;
function setUp() public {
vm.chainId(31337);
harness = new NamedErrorHarness();
}
function testUnexpectedStateExerciseRevertsThroughAssertionBranch() public {
vm.expectRevert(
abi.encodeWithSelector(DemoScript.UnexpectedState.selector, "reserves", uint256(1_400e6), uint256(1_399e6))
);
harness.assertUint("reserves", 1_400e6, 1_399e6);
}
function testCheckStateExercisesRevertThroughInsolventAndUnknownStageBranches() public {
(MockUSDC token, BankV1 bank) = _deployFixture("insolvent.json");
token.mint(ALICE, 1_400e6);
vm.startPrank(ALICE);
token.approve(address(bank), 1_400e6);
bank.deposit(1_400e6);
vm.stopPrank();
deal(address(token), address(bank), 1_399e6);
vm.setEnv("DEMO_EXPECTED_STAGE", "invariants");
CheckState checker = new CheckState();
vm.expectRevert(abi.encodeWithSelector(CheckState.Insolvent.selector, uint256(1_399e6), uint256(1_400e6)));
checker.run();
_deployFixture("unknown-stage.json");
vm.setEnv("DEMO_EXPECTED_STAGE", "mystery");
checker = new CheckState();
vm.expectRevert(abi.encodeWithSelector(CheckState.UnknownStage.selector, "mystery"));
checker.run();
}
function _deployFixture(string memory fixtureName) internal returns (MockUSDC token, BankV1 bank) {
token = new MockUSDC(address(this));
BankV1 implementation = new BankV1();
ERC1967Proxy proxy =
new ERC1967Proxy(address(implementation), abi.encodeCall(BankV1.initialize, (address(token), OWNER)));
bank = BankV1(address(proxy));
DemoScript.Actor[] memory actors = new DemoScript.Actor[](3);
actors[0] = DemoScript.Actor({label: "owner", address_: OWNER});
actors[1] = DemoScript.Actor({label: "Alice", address_: ALICE});
actors[2] = DemoScript.Actor({label: "Bob", address_: BOB});
DemoScript.Manifest memory manifest = DemoScript.Manifest({
schemaVersion: 1,
network: "anvil",
chainId: 31337,
deploymentBlock: 1,
rpcUrl: "http://127.0.0.1:8545",
explorerBaseUrl: "",
token: address(token),
proxy: address(proxy),
implementation: address(implementation),
owner: OWNER,
actors: actors
});
string memory fixtureDir = string.concat(vm.projectRoot(), "/deployments/test-named-error-exercises");
vm.createDir(fixtureDir, true);
string memory manifestPath = string.concat(fixtureDir, "/", fixtureName);
harness.writeManifest(manifestPath, manifest);
vm.setEnv("DEPLOYMENT_MANIFEST_PATH", manifestPath);
}
}