// SPDX-License-Identifier: MIT pragma solidity 0.8.35; import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol"; import {UUPSUpgradeable} from "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol"; import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import {BankV1} from "../src/BankV1.sol"; import {BankTestBase} from "./helpers/BankTestBase.sol"; contract BankV1AdminTest is BankTestBase { bytes32 private constant ERC1967_IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; function testProxyStartsWithConfiguredAdministrationAndEmptyAccounting() public view { assertEq(address(bank.asset()), address(token)); assertEq(bank.owner(), owner); assertFalse(bank.paused()); assertEq(bank.balanceOf(alice), 0); assertEq(bank.totalLiabilities(), 0); assertEq(bank.contractVersion(), 1); } function testInitializationChecksZeroAssetBeforeZeroOwner() public { vm.expectRevert(abi.encodeWithSelector(BankV1.InvalidAsset.selector, address(0))); new ERC1967Proxy(implementation, abi.encodeCall(BankV1.initialize, (address(0), address(0)))); } function testInitializationRejectsZeroOwner() public { vm.expectRevert(abi.encodeWithSelector(OwnableUpgradeable.OwnableInvalidOwner.selector, address(0))); new ERC1967Proxy(implementation, abi.encodeCall(BankV1.initialize, (address(token), address(0)))); } function testProxyCannotBeInitializedTwice() public { vm.expectRevert(Initializable.InvalidInitialization.selector); bank.initialize(address(token), owner); } function testImplementationCannotBeInitialized() public { vm.expectRevert(Initializable.InvalidInitialization.selector); BankV1(implementation).initialize(address(token), owner); } function testOwnerCanPauseAndUnpause() public { vm.prank(owner); bank.pause(); assertTrue(bank.paused()); vm.prank(owner); bank.unpause(); assertFalse(bank.paused()); } function testNonOwnerCannotPause() public { vm.prank(stranger); vm.expectRevert(abi.encodeWithSelector(OwnableUpgradeable.OwnableUnauthorizedAccount.selector, stranger)); bank.pause(); } function testNonOwnerCannotUnpause() public { vm.prank(owner); bank.pause(); vm.prank(stranger); vm.expectRevert(abi.encodeWithSelector(OwnableUpgradeable.OwnableUnauthorizedAccount.selector, stranger)); bank.unpause(); } function testViewsRemainAvailableWhilePaused() public { vm.prank(owner); bank.pause(); assertEq(address(bank.asset()), address(token)); assertEq(bank.balanceOf(alice), 0); assertEq(bank.totalLiabilities(), 0); assertEq(bank.contractVersion(), 1); } function testNonOwnerCannotAuthorizeUpgrade() public { vm.prank(stranger); vm.expectRevert(abi.encodeWithSelector(OwnableUpgradeable.OwnableUnauthorizedAccount.selector, stranger)); bank.upgradeToAndCall(implementation, ""); } function testImplementationExposesERC1967ProxiableUUID() public view { assertEq(BankV1(implementation).proxiableUUID(), ERC1967_IMPLEMENTATION_SLOT); } function testProxyRejectsProxiableUUIDCall() public { vm.expectRevert(UUPSUpgradeable.UUPSUnauthorizedCallContext.selector); bank.proxiableUUID(); } }