Skip to content

Commit a5499f8

Browse files
committed
Add tests for diamond upgrade initializers
1 parent ac908b1 commit a5499f8

File tree

1 file changed

+104
-0
lines changed

1 file changed

+104
-0
lines changed
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
// SPDX-License-Identifier: AGPL-3.0-only
2+
pragma solidity ^0.8.19;
3+
4+
import "forge-std/Test.sol";
5+
6+
import {DiamondInit} from "../src/diamonds/upgradeInitializers/DiamondInit.sol";
7+
import {
8+
DiamondMultiInit,
9+
AddressAndCalldataLengthDoNotMatch
10+
} from "../src/diamonds/upgradeInitializers/DiamondMultiInit.sol";
11+
import {IDiamondCut} from "../src/diamonds/interfaces/IDiamondCut.sol";
12+
import {IDiamondLoupe} from "../src/diamonds/interfaces/IDiamondLoupe.sol";
13+
import {IERC165} from "../src/diamonds/interfaces/IERC165.sol";
14+
import {IERC173} from "../src/diamonds/interfaces/IERC173.sol";
15+
import {LibDiamond} from "../src/diamonds/libraries/LibDiamond.sol";
16+
17+
contract InitSupportFacet {
18+
function mark(bytes4 key) external {
19+
LibDiamond.diamondStorage().supportedInterfaces[key] = true;
20+
}
21+
}
22+
23+
contract DiamondInitHarness {
24+
constructor(address owner) {
25+
LibDiamond.setContractOwner(owner);
26+
}
27+
28+
function runInit(address init, bytes memory data) external {
29+
LibDiamond.initializeDiamondCut(init, data);
30+
}
31+
32+
function isSupported(bytes4 interfaceId) external view returns (bool) {
33+
return LibDiamond.diamondStorage().supportedInterfaces[interfaceId];
34+
}
35+
}
36+
37+
contract DiamondUpgradeInitializersTest is Test {
38+
DiamondInitHarness private diamond;
39+
DiamondInit private singleInit;
40+
DiamondMultiInit private multiInit;
41+
InitSupportFacet private supportA;
42+
InitSupportFacet private supportB;
43+
44+
address private owner;
45+
46+
function setUp() public {
47+
owner = makeAddr("owner");
48+
diamond = new DiamondInitHarness(owner);
49+
singleInit = new DiamondInit();
50+
multiInit = new DiamondMultiInit();
51+
supportA = new InitSupportFacet();
52+
supportB = new InitSupportFacet();
53+
}
54+
55+
function test_DiamondInit_setsBaseInterfaces() public {
56+
diamond.runInit(address(singleInit), abi.encodeWithSelector(DiamondInit.init.selector));
57+
58+
assertTrue(diamond.isSupported(type(IERC165).interfaceId));
59+
assertTrue(diamond.isSupported(type(IDiamondCut).interfaceId));
60+
assertTrue(diamond.isSupported(type(IDiamondLoupe).interfaceId));
61+
assertTrue(diamond.isSupported(type(IERC173).interfaceId));
62+
}
63+
64+
function test_DiamondMultiInit_executesAllInitializers() public {
65+
address[] memory targets = new address[](2);
66+
targets[0] = address(supportA);
67+
targets[1] = address(supportB);
68+
69+
bytes[] memory calls = new bytes[](2);
70+
bytes4 keyA = bytes4(keccak256("A"));
71+
bytes4 keyB = bytes4(keccak256("B"));
72+
calls[0] = abi.encodeWithSelector(InitSupportFacet.mark.selector, keyA);
73+
calls[1] = abi.encodeWithSelector(InitSupportFacet.mark.selector, keyB);
74+
75+
diamond.runInit(
76+
address(multiInit),
77+
abi.encodeWithSelector(DiamondMultiInit.multiInit.selector, targets, calls)
78+
);
79+
80+
assertTrue(diamond.isSupported(keyA));
81+
assertTrue(diamond.isSupported(keyB));
82+
}
83+
84+
function test_DiamondMultiInit_revertsOnLengthMismatch() public {
85+
address[] memory targets = new address[](2);
86+
targets[0] = address(supportA);
87+
targets[1] = address(supportB);
88+
89+
bytes[] memory calls = new bytes[](1);
90+
calls[0] = abi.encodeWithSelector(InitSupportFacet.mark.selector, bytes4(0));
91+
92+
vm.expectRevert(
93+
abi.encodeWithSelector(
94+
AddressAndCalldataLengthDoNotMatch.selector,
95+
targets.length,
96+
calls.length
97+
)
98+
);
99+
diamond.runInit(
100+
address(multiInit),
101+
abi.encodeWithSelector(DiamondMultiInit.multiInit.selector, targets, calls)
102+
);
103+
}
104+
}

0 commit comments

Comments
 (0)