Skip to content
This repository was archived by the owner on Aug 4, 2025. It is now read-only.

Commit a4feb90

Browse files
authored
Merge pull request #74 from base-org/jack/coverage
Improve test coverage
2 parents 42ef88d + 1a69eda commit a4feb90

8 files changed

Lines changed: 225 additions & 3 deletions

File tree

contracts/src/libraries/SSZ.sol

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,6 @@ library SSZ {
3838
// Call sha256 precompile
3939
let result := staticcall(gas(), SHA256, 0x00, 0x40, 0x00, 0x20)
4040

41-
if eq(result, 0) { revert(0, 0) }
42-
4341
// Reuse `leaf` to store the hash to reduce stack operations.
4442
leaf := mload(0x00)
4543
offset := add(offset, 0x20)

contracts/src/libraries/StateValidator.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ library StateValidator {
177177
/// @param encodedAccount An RLP-encoded account object
178178
///
179179
/// @return _ The account's storage root
180-
function _extractStorageRoot(bytes memory encodedAccount) private pure returns (bytes32) {
180+
function _extractStorageRoot(bytes memory encodedAccount) internal pure returns (bytes32) {
181181
RLPReader.RLPItem[] memory accountFields = encodedAccount.readList();
182182

183183
if (accountFields.length != 4) {

contracts/test/ArbitrumProver.t.sol

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ contract ArbitrumProverTest is BaseTest {
2121
using Strings for address;
2222

2323
MockArbitrumProver prover;
24+
string unconfirmedState;
2425

2526
address private constant _INBOX_CONTRACT = 0xdac62f96404AB882F5a61CFCaFb0C470a19FC514;
2627

@@ -35,11 +36,13 @@ contract ArbitrumProverTest is BaseTest {
3536
string.concat(rootPath, "/test/data/invalids/ArbitrumInvalidBlockHeaders.json");
3637
string memory invalidL2StoragePath =
3738
string.concat(rootPath, "/test/data/invalids/ArbitrumInvalidL2Storage.json");
39+
string memory unconfirmedStatePath = string.concat(rootPath, "/test/data/invalids/ArbitrumUnconfirmed.json");
3840

3941
validProof = vm.readFile(path);
4042
invalidL1State = vm.readFile(invalidPath);
4143
invalidBlockHeaders = vm.readFile(invalidBlockHeadersPath);
4244
invalidL2Storage = vm.readFile(invalidL2StoragePath);
45+
unconfirmedState = vm.readFile(unconfirmedStatePath);
4346
}
4447

4548
function test_reverts_ifFinalityDelaySecondsStillInProgress() external fundAlice(_REWARD_AMOUNT) {
@@ -69,6 +72,19 @@ contract ArbitrumProverTest is BaseTest {
6972
prover.validateProof(inboxStorageKey, _INBOX_CONTRACT, attributes, abi.encode(proof));
7073
}
7174

75+
function test_reverts_ifUnconfirmed() external fundAlice(_REWARD_AMOUNT) {
76+
(string memory sourceChain, string memory sender, Message[] memory calls, bytes[] memory attributes) =
77+
_initMessage(_REWARD_AMOUNT);
78+
bytes32 messageId = _getMessageId(sourceChain, sender, calls, attributes);
79+
80+
ArbitrumProver.RIP7755Proof memory proof = _buildProof(unconfirmedState);
81+
bytes memory inboxStorageKey = _deriveStorageKey(messageId);
82+
83+
vm.prank(FILLER);
84+
vm.expectRevert(ArbitrumProver.NodeNotConfirmed.selector);
85+
prover.validateProof(inboxStorageKey, _INBOX_CONTRACT, attributes, abi.encode(proof));
86+
}
87+
7288
function test_reverts_ifInvalidRLPHeaders() external fundAlice(_REWARD_AMOUNT) {
7389
(string memory sourceChain, string memory sender, Message[] memory calls, bytes[] memory attributes) =
7490
_initMessage(_REWARD_AMOUNT);

contracts/test/RIP7755Inbox.t.sol

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,21 @@ contract RIP7755InboxTest is BaseTest {
111111
assertEq(ALICE.balance, amount);
112112
}
113113

114+
function test_executeMessages_doesntSendsEth(uint256 amount) external {
115+
TestMessage memory m = _initMessage(false, false);
116+
117+
bytes[] memory attributes = new bytes[](1);
118+
attributes[0] = abi.encodeWithSelector(_FULFILLER_ATTRIBUTE_SELECTOR, FILLER);
119+
120+
_appendMessage(m, Message({receiver: ALICE.toChecksumHexString(), payload: "", attributes: attributes}));
121+
122+
vm.deal(FILLER, amount);
123+
vm.prank(FILLER);
124+
inbox.executeMessages(m.sourceChain, m.sender, m.messages, m.attributes);
125+
126+
assertEq(ALICE.balance, 0);
127+
}
128+
114129
function test_executeMessages_reverts_ifTargetContractReverts() external {
115130
TestMessage memory m = _initMessage(false, false);
116131

contracts/test/SSZ.t.sol

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity 0.8.24;
3+
4+
import {Test} from "forge-std/Test.sol";
5+
6+
import {SSZ} from "../src/libraries/SSZ.sol";
7+
8+
contract SSZTest is Test {
9+
bytes32[] proof;
10+
bytes32 root;
11+
bytes32 leaf;
12+
uint256 index;
13+
14+
function setUp() public {
15+
proof.push(0xd526ab81e92ee5f1cc067756a28fabace998cbcdc4dfc15be4e7a1e20556dd77);
16+
proof.push(0x91fef64270acd9eaa77515c225e1ff733405ad5c9ef6af09348a81d494d91153);
17+
proof.push(0xc29d2435ffdaae8e956a6ff850f93785e9088fc361df4b65fc4e5eda3dc48e5e);
18+
proof.push(0xdf1fe9c339af0ab637e1657df29f04f6013844ffa492e4f48679f688d298c96b);
19+
proof.push(0xd2ccf2d7b4fd6e881e9ef3eb79d21b67bf9541ad211e0a10568eedbec0a4c91c);
20+
proof.push(0x869e40e6d2a1efca3d0d6b9d199c1ee48a0b4a232e05431f30372bacc620dec1);
21+
proof.push(0xf17a619ac2d0dcc48af70c205dea3aba52c412df929f133f886ffbb6f52105b3);
22+
proof.push(0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71);
23+
proof.push(0x476ccb90633a03e07abffc0d8b9136e7428b938e1d99990dd57c8254869a2915);
24+
proof.push(0x0000000000000000000000000000000000000000000000000000000000000000);
25+
proof.push(0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b);
26+
proof.push(0x0398b3a4f9a61cdc13bcc5265c6860c6d6a13ce06d03d46663c0c54cf8bb4d01);
27+
root = 0xd19bacd555eff238f7c814e0eca799246746322f663c1811564ef07bc2b68dda;
28+
leaf = 0x4576ea3c05186e1df84e1c71036bf90bfc192f36063f6efed2a9c6fabe8de9db;
29+
index = 6434;
30+
}
31+
32+
function test_verifyProof_returnsTrue() public view {
33+
assertEq(SSZ.verifyProof(proof, root, leaf, index), true);
34+
}
35+
36+
function test_verifyProof_reverts_invalidIndex() public {
37+
vm.expectRevert(0x5849603f);
38+
SSZ.verifyProof(proof, root, leaf, 1);
39+
}
40+
41+
function test_verifyProof_reverts_missingItem() public {
42+
vm.expectRevert(0x1b6661c3);
43+
SSZ.verifyProof(new bytes32[](0), root, leaf, 2);
44+
}
45+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity 0.8.24;
3+
4+
import {Test} from "forge-std/Test.sol";
5+
6+
import {StateValidator} from "../src/libraries/StateValidator.sol";
7+
import {MockStateValidator} from "./mocks/MockStateValidator.sol";
8+
9+
contract StateValidatorTest is Test {
10+
MockStateValidator mockStateValidator;
11+
12+
function setUp() public {
13+
mockStateValidator = new MockStateValidator();
14+
}
15+
16+
function test_validateState_reverts_oracleCallFails() external {
17+
deployCodeTo("MockStateValidator.sol", abi.encode(), 0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02);
18+
vm.expectRevert(abi.encodeWithSelector(StateValidator.BeaconRootsOracleCallFailed.selector, abi.encode(1)));
19+
mockStateValidator.validateState(
20+
address(0),
21+
StateValidator.StateProofParameters({
22+
beaconRoot: bytes32(uint256(1)),
23+
beaconOracleTimestamp: 1,
24+
executionStateRoot: bytes32(uint256(1)),
25+
stateRootProof: new bytes32[](0)
26+
}),
27+
StateValidator.AccountProofParameters({
28+
storageKey: abi.encode(uint256(1)),
29+
storageValue: abi.encode(uint256(1)),
30+
accountProof: new bytes[](0),
31+
storageProof: new bytes[](0)
32+
})
33+
);
34+
}
35+
36+
function test_validateAccountStorage_reverts_ifInvalidAccountStructure() external {
37+
bytes memory encodedAccount =
38+
hex"f90224a0645c2c097705aef7a67aab8e7bebe9ccdef7277e1c4287e052d264444ed6118da01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794a4b000000000000000000073657175656e636572a04fce9af672aa9a624f43fcdecb7dc2f137220cf9e8a40f9555ac7df54bd82a42a0beec0b13d083ebbe53fe2ba98509acc5aa127e494e8b05dd1de851bcd675a5cea0b745fc54204ae8f5f8c600191da48237f2502c941dc4e8ec057d690651f96f8cb901000000002000000000000000020000a001400000000000000000800000000000000000280000000000000000000000000000000000000000000000000000200000000100000000000000080409000000008001000000000010000000800000010000000000020000000000000000000800008000000000004000000810000000400000000001000080000000000000280000040000000000001800000000200000020400400000800000000000000200000202000000000000000000000000000000008002000000200000000000000000000000000000000000000000000020000010000000240000000000000000004400100000480000000000020000100000018406fc59ae870400000000000083155208846792b144a00bf10cf6053bf44b0bf8e379d29072165857d5326142f5f2c7692d9bfbd1797fa0000000000000eedb0000000000734da000000000000000200000000000000000880000000000142f058405f5e100";
39+
vm.expectRevert(StateValidator.InvalidAccountRLP.selector);
40+
mockStateValidator.extractStorageRoot(encodedAccount);
41+
}
42+
}

0 commit comments

Comments
 (0)