feat: establish UUPS bank V1
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
// 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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity 0.8.35;
|
||||
|
||||
import {Test} from "forge-std/Test.sol";
|
||||
import {Upgrades} from "openzeppelin-foundry-upgrades/Upgrades.sol";
|
||||
|
||||
import {BankV1} from "../../src/BankV1.sol";
|
||||
import {MockUSDC} from "../../src/MockUSDC.sol";
|
||||
|
||||
abstract contract BankTestBase is Test {
|
||||
address internal owner;
|
||||
address internal alice;
|
||||
address internal bob;
|
||||
address internal stranger;
|
||||
|
||||
MockUSDC internal token;
|
||||
address internal proxy;
|
||||
address internal implementation;
|
||||
BankV1 internal bank;
|
||||
|
||||
function setUp() public virtual {
|
||||
owner = makeAddr("owner");
|
||||
alice = makeAddr("alice");
|
||||
bob = makeAddr("bob");
|
||||
stranger = makeAddr("stranger");
|
||||
|
||||
token = new MockUSDC(owner);
|
||||
proxy =
|
||||
Upgrades.deployUUPSProxy("BankV1.sol:BankV1", abi.encodeCall(BankV1.initialize, (address(token), owner)));
|
||||
bank = BankV1(proxy);
|
||||
implementation = Upgrades.getImplementationAddress(proxy);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user