Skip to content

Commit 14ce8c0

Browse files
Inbox contract unit test.
1 parent 6fd44f8 commit 14ce8c0

File tree

1 file changed

+182
-0
lines changed

1 file changed

+182
-0
lines changed
Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity 0.8.28;
3+
4+
// Testing
5+
import { Test } from "forge-std/Test.sol";
6+
7+
// Contracts
8+
import { BatchInbox } from "src/L1/BatchInbox.sol";
9+
import { IBatchAuthenticator } from "interfaces/L1/IBatchAuthenticator.sol";
10+
11+
/// @title MockBatchAuthenticator
12+
/// @notice Mock implementation for testing - only implements validBatchInfo
13+
contract MockBatchAuthenticator {
14+
mapping(bytes32 => bool) private validHashes;
15+
16+
function setValidBatchInfo(bytes32 hash, bool valid) external {
17+
validHashes[hash] = valid;
18+
}
19+
20+
function validBatchInfo(bytes32 hash) external view returns (bool) {
21+
return validHashes[hash];
22+
}
23+
}
24+
25+
/// @title BatchInbox_Test
26+
/// @notice Base test contract with common setup
27+
contract BatchInbox_Test is Test {
28+
BatchInbox public inbox;
29+
MockBatchAuthenticator public authenticator;
30+
31+
address public teeBatcher = address(0x1234);
32+
address public nonTeeBatcher = address(0x5678);
33+
address public deployer = address(0xABCD);
34+
address public unauthorized = address(0xDEAD);
35+
36+
function setUp() public virtual {
37+
authenticator = new MockBatchAuthenticator();
38+
inbox = new BatchInbox(teeBatcher, nonTeeBatcher, IBatchAuthenticator(address(authenticator)));
39+
}
40+
}
41+
42+
/// @title BatchInbox_Constructor_Test
43+
/// @notice Tests for the BatchInbox constructor
44+
contract BatchInbox_Constructor_Test is Test {
45+
address teeBatcher = address(0x1234);
46+
address nonTeeBatcher = address(0x5678);
47+
address batchAuthenticator = address(0x9ABC);
48+
49+
/// @notice Test that constructor reverts when TEE batcher is zero address
50+
function test_constructor_revertsWhenTeeBatcherIsZero() external {
51+
vm.expectRevert("BatchInbox: zero batcher");
52+
new BatchInbox(address(0), nonTeeBatcher, IBatchAuthenticator(batchAuthenticator));
53+
}
54+
55+
/// @notice Test that constructor reverts when non-TEE batcher is zero address
56+
function test_constructor_revertsWhenNonTeeBatcherIsZero() external {
57+
vm.expectRevert("BatchInbox: zero batcher");
58+
new BatchInbox(teeBatcher, address(0), IBatchAuthenticator(batchAuthenticator));
59+
}
60+
61+
/// @notice Test that constructor reverts when both batchers are zero addresses
62+
function test_constructor_revertsWhenBothBatchersAreZero() external {
63+
vm.expectRevert("BatchInbox: zero batcher");
64+
new BatchInbox(address(0), address(0), IBatchAuthenticator(batchAuthenticator));
65+
}
66+
67+
/// @notice Test that constructor succeeds with valid addresses
68+
function test_constructor_succeedsWithValidAddresses() external {
69+
BatchInbox testInbox = new BatchInbox(teeBatcher, nonTeeBatcher, IBatchAuthenticator(batchAuthenticator));
70+
71+
assertEq(testInbox.teeBatcher(), teeBatcher, "TEE batcher should match");
72+
assertEq(testInbox.nonTeeBatcher(), nonTeeBatcher, "Non-TEE batcher should match");
73+
assertEq(address(testInbox.batchAuthenticator()), batchAuthenticator, "Batch authenticator should match");
74+
assertTrue(testInbox.activeIsTee(), "Active batcher should be TEE by default");
75+
}
76+
}
77+
78+
/// @title BatchInbox_SwitchBatcher_Test
79+
/// @notice Tests for switching between batchers
80+
contract BatchInbox_SwitchBatcher_Test is BatchInbox_Test {
81+
/// @notice Test that switchBatcher toggles the active batcher
82+
function test_switchBatcher_togglesActiveBatcher() external {
83+
// Initially TEE batcher is active
84+
assertTrue(inbox.activeIsTee(), "Should start with TEE batcher active");
85+
86+
// Switch to non-TEE batcher
87+
inbox.switchBatcher();
88+
assertFalse(inbox.activeIsTee(), "Should switch to non-TEE batcher");
89+
90+
// Switch back to TEE batcher
91+
inbox.switchBatcher();
92+
assertTrue(inbox.activeIsTee(), "Should switch back to TEE batcher");
93+
}
94+
}
95+
96+
/// @title BatchInbox_Fallback_Test
97+
/// @notice Tests for the fallback function
98+
contract BatchInbox_Fallback_Test is BatchInbox_Test {
99+
/// @notice Test that non-TEE batcher can post after switching
100+
function test_fallback_nonTeeBatcherCanPostAfterSwitch() external {
101+
// Switch to non-TEE batcher
102+
inbox.switchBatcher();
103+
104+
// Non-TEE batcher should be able to post
105+
vm.prank(nonTeeBatcher);
106+
(bool success,) = address(inbox).call("hello");
107+
assertTrue(success, "Non-TEE batcher should be able to post");
108+
}
109+
110+
/// @notice Test that inactive batcher reverts
111+
function test_fallback_inactiveBatcherReverts() external {
112+
// Switch to non-TEE batcher (making TEE batcher inactive)
113+
inbox.switchBatcher();
114+
115+
// TEE batcher (now inactive) should revert
116+
vm.prank(teeBatcher);
117+
(bool success, bytes memory returnData) = address(inbox).call("unauthorized");
118+
assertFalse(success, "Should revert");
119+
// Check the revert reason
120+
assertEq(string(returnData), string(abi.encodeWithSignature("Error(string)", "BatchInbox: unauthorized batcher")));
121+
}
122+
123+
/// @notice Test that TEE batcher requires authentication
124+
function test_fallback_teeBatcherRequiresAuthentication() external {
125+
// TEE batcher is active by default
126+
bytes memory data = "needs-auth";
127+
bytes32 hash = keccak256(data);
128+
129+
// Don't set the hash as valid in authenticator
130+
authenticator.setValidBatchInfo(hash, false);
131+
132+
// TEE batcher should revert due to invalid authentication
133+
vm.prank(teeBatcher);
134+
(bool success, bytes memory returnData) = address(inbox).call(data);
135+
assertFalse(success, "Should revert");
136+
// Check the revert reason
137+
assertEq(string(returnData), string(abi.encodeWithSignature("Error(string)", "Invalid calldata batch")));
138+
}
139+
140+
/// @notice Test that TEE batcher succeeds with valid authentication
141+
function test_fallback_teeBatcherSucceedsWithValidAuth() external {
142+
// TEE batcher is active by default
143+
bytes memory data = "valid-batch";
144+
bytes32 hash = keccak256(data);
145+
146+
// Set the hash as valid in authenticator
147+
authenticator.setValidBatchInfo(hash, true);
148+
149+
// TEE batcher should succeed
150+
vm.prank(teeBatcher);
151+
(bool success,) = address(inbox).call(data);
152+
assertTrue(success, "TEE batcher should succeed with valid auth");
153+
}
154+
155+
/// @notice Test that non-TEE batcher doesn't require authentication
156+
function test_fallback_nonTeeBatcherDoesNotRequireAuth() external {
157+
// Switch to non-TEE batcher
158+
inbox.switchBatcher();
159+
160+
bytes memory data = "no-auth-needed";
161+
// Don't set any authentication
162+
163+
// Non-TEE batcher should succeed without authentication
164+
vm.prank(nonTeeBatcher);
165+
(bool success,) = address(inbox).call(data);
166+
assertTrue(success, "Non-TEE batcher should not require auth");
167+
}
168+
169+
/// @notice Test that unauthorized address cannot post
170+
function test_fallback_unauthorizedAddressReverts() external {
171+
// Try with unauthorized address when TEE is active
172+
vm.prank(unauthorized);
173+
(bool success,) = address(inbox).call("unauthorized");
174+
assertFalse(success, "Unauthorized should revert when TEE is active");
175+
176+
// Switch to non-TEE and try again
177+
inbox.switchBatcher();
178+
vm.prank(unauthorized);
179+
(success,) = address(inbox).call("unauthorized");
180+
assertFalse(success, "Unauthorized should revert when non-TEE is active");
181+
}
182+
}

0 commit comments

Comments
 (0)