diff --git a/docs/provers/ARBITRUM.md b/docs/provers/ARBITRUM.md index b3ebdd0..d93c26e 100644 --- a/docs/provers/ARBITRUM.md +++ b/docs/provers/ARBITRUM.md @@ -180,7 +180,7 @@ function getTargetStateCommitment(bytes calldata input) targetStateCommitment = IOutbox(outbox).roots(sendRoot); if (targetStateCommitment == bytes32(0)) { - revert TargetBlockHashNotFound(); + revert InvalidTargetStateCommitment(); } } ``` @@ -213,7 +213,7 @@ function verifyTargetStateCommitment(bytes32 homeBlockHash, bytes calldata input ); if (targetStateCommitment == bytes32(0)) { - revert TargetBlockHashNotFound(); + revert InvalidTargetStateCommitment(); } } ``` diff --git a/docs/provers/TAIKO.md b/docs/provers/TAIKO.md index 13f9560..af8e7f7 100644 --- a/docs/provers/TAIKO.md +++ b/docs/provers/TAIKO.md @@ -101,7 +101,7 @@ function getTargetStateCommitment(bytes calldata input) targetStateCommitment = checkpoint.blockHash; if (targetStateCommitment == bytes32(0)) { - revert TargetBlockHashNotFound(); + revert InvalidTargetStateCommitment(); } } ``` @@ -136,7 +136,7 @@ function verifyTargetStateCommitment(bytes32 homeBlockHash, bytes calldata input ); if (targetStateCommitment == bytes32(0)) { - revert TargetBlockHashNotFound(); + revert InvalidTargetStateCommitment(); } } ``` @@ -206,7 +206,7 @@ function getTargetStateCommitment(bytes calldata input) targetStateCommitment = checkpoint.blockHash; if (targetStateCommitment == bytes32(0)) { - revert TargetBlockHashNotFound(); + revert InvalidTargetStateCommitment(); } } ``` @@ -239,7 +239,7 @@ function verifyTargetStateCommitment(bytes32 homeBlockHash, bytes calldata input ); if (targetStateCommitment == bytes32(0)) { - revert TargetBlockHashNotFound(); + revert InvalidTargetStateCommitment(); } } ``` diff --git a/snapshots/verifyBroadcastMessage.json b/snapshots/verifyBroadcastMessage.json index 568f4a9..29b1931 100644 --- a/snapshots/verifyBroadcastMessage.json +++ b/snapshots/verifyBroadcastMessage.json @@ -1,9 +1,9 @@ { "EthereumToOptimism": "1639239", - "EthereumToTaikoL2": "1052214", - "LineaL2ToEthereum": "2551776", - "ScrollL2ToEthereum": "1361940", + "EthereumToTaikoL2": "1052244", + "LineaL2ToEthereum": "2551806", + "ScrollL2ToEthereum": "1361970", "ScrollToOptimism": "1348710", - "TaikoL2ToEthereum": "1022277", - "ZkSyncL2ToEthereum": "125663" + "TaikoL2ToEthereum": "1022307", + "ZkSyncL2ToEthereum": "125693" } \ No newline at end of file diff --git a/src/contracts/provers/arbitrum/ChildToParentProver.sol b/src/contracts/provers/arbitrum/ChildToParentProver.sol index b092ce9..b7c226a 100644 --- a/src/contracts/provers/arbitrum/ChildToParentProver.sol +++ b/src/contracts/provers/arbitrum/ChildToParentProver.sol @@ -23,6 +23,7 @@ contract ChildToParentProver is IStateProver { error CallNotOnHomeChain(); error CallOnHomeChain(); + error InvalidTargetStateCommitment(); constructor(uint256 _homeChainId) { homeChainId = _homeChainId; @@ -51,6 +52,8 @@ contract ChildToParentProver is IStateProver { targetStateCommitment = ProverUtils.getSlotFromBlockHeader( homeBlockHash, rlpBlockHeader, BLOCK_HASH_BUFFER, slot, accountProof, storageProof ); + + require(targetStateCommitment != bytes32(0), InvalidTargetStateCommitment()); } /// @notice Get a parent chain block hash from the buffer at `BLOCK_HASH_BUFFER`. @@ -64,6 +67,7 @@ contract ChildToParentProver is IStateProver { // get the block hash from the buffer targetStateCommitment = IBuffer(BLOCK_HASH_BUFFER).parentChainBlockHash(targetBlockNumber); + require(targetStateCommitment != bytes32(0), InvalidTargetStateCommitment()); } /// @notice Verify a storage slot given a target chain block hash and a proof. diff --git a/src/contracts/provers/arbitrum/ParentToChildProver.sol b/src/contracts/provers/arbitrum/ParentToChildProver.sol index 66caaf2..4b186cd 100644 --- a/src/contracts/provers/arbitrum/ParentToChildProver.sol +++ b/src/contracts/provers/arbitrum/ParentToChildProver.sol @@ -22,7 +22,7 @@ contract ParentToChildProver is IStateProver { error CallNotOnHomeChain(); error CallOnHomeChain(); - error TargetBlockHashNotFound(); + error InvalidTargetStateCommitment(); constructor(address _outbox, uint256 _rootsSlot, uint256 _homeChainId) { outbox = _outbox; @@ -54,9 +54,7 @@ contract ParentToChildProver is IStateProver { targetStateCommitment = ProverUtils.getSlotFromBlockHeader(homeBlockHash, rlpBlockHeader, outbox, slot, accountProof, storageProof); - if (targetStateCommitment == bytes32(0)) { - revert TargetBlockHashNotFound(); - } + require(targetStateCommitment != bytes32(0), InvalidTargetStateCommitment()); } /// @notice Get a target chain block hash given a target chain sendRoot @@ -71,9 +69,7 @@ contract ParentToChildProver is IStateProver { // get the target block hash from the outbox targetStateCommitment = IOutbox(outbox).roots(sendRoot); - if (targetStateCommitment == bytes32(0)) { - revert TargetBlockHashNotFound(); - } + require(targetStateCommitment != bytes32(0), InvalidTargetStateCommitment()); } /// @notice Verify a storage slot given a target chain block hash and a proof. diff --git a/src/contracts/provers/linea/ChildToParentProver.sol b/src/contracts/provers/linea/ChildToParentProver.sol index f3f1817..d2983f9 100644 --- a/src/contracts/provers/linea/ChildToParentProver.sol +++ b/src/contracts/provers/linea/ChildToParentProver.sol @@ -21,6 +21,7 @@ contract ChildToParentProver is IStateProver { error CallNotOnHomeChain(); error CallOnHomeChain(); + error InvalidTargetStateCommitment(); constructor(address _blockHashBuffer, uint256 _homeChainId) { blockHashBuffer = _blockHashBuffer; @@ -50,6 +51,7 @@ contract ChildToParentProver is IStateProver { targetStateCommitment = ProverUtils.getSlotFromBlockHeader( homeBlockHash, rlpBlockHeader, blockHashBuffer, slot, accountProof, storageProof ); + require(targetStateCommitment != bytes32(0), InvalidTargetStateCommitment()); } /// @notice Get a parent chain block hash from the buffer at `blockHashBuffer`. @@ -63,6 +65,7 @@ contract ChildToParentProver is IStateProver { // get the block hash from the buffer targetStateCommitment = IBuffer(blockHashBuffer).parentChainBlockHash(targetBlockNumber); + require(targetStateCommitment != bytes32(0), InvalidTargetStateCommitment()); } /// @notice Verify a storage slot given a target chain block hash and a proof. diff --git a/src/contracts/provers/linea/ParentToChildProver.sol b/src/contracts/provers/linea/ParentToChildProver.sol index 45f599e..3427b10 100644 --- a/src/contracts/provers/linea/ParentToChildProver.sol +++ b/src/contracts/provers/linea/ParentToChildProver.sol @@ -36,6 +36,7 @@ contract ParentToChildProver is IStateProver { error AccountKeyMismatch(); error AccountValueMismatch(); error StorageKeyMismatch(); + error InvalidTargetStateCommitment(); constructor(address _lineaRollup, uint256 _stateRootHashesSlot, uint256 _homeChainId) { lineaRollup = _lineaRollup; @@ -71,9 +72,7 @@ contract ParentToChildProver is IStateProver { homeStateCommitment, rlpBlockHeader, lineaRollup, slot, accountProof, storageProof ); - if (targetStateCommitment == bytes32(0)) { - revert TargetStateRootNotFound(); - } + require(targetStateCommitment != bytes32(0), InvalidTargetStateCommitment()); } /// @notice Get L2 state root directly from L1 LineaRollup @@ -91,9 +90,7 @@ contract ParentToChildProver is IStateProver { // Get the state root from LineaRollup targetStateCommitment = ZkEvmV2(lineaRollup).stateRootHashes(l2BlockNumber); - if (targetStateCommitment == bytes32(0)) { - revert TargetStateRootNotFound(); - } + require(targetStateCommitment != bytes32(0), TargetStateRootNotFound()); } /// @notice Verify a storage slot given a target chain state root and a Sparse Merkle Tree proof diff --git a/src/contracts/provers/optimism/ChildToParentProver.sol b/src/contracts/provers/optimism/ChildToParentProver.sol index 4896e33..6f5f950 100644 --- a/src/contracts/provers/optimism/ChildToParentProver.sol +++ b/src/contracts/provers/optimism/ChildToParentProver.sol @@ -25,6 +25,7 @@ contract ChildToParentProver is IStateProver { error CallNotOnHomeChain(); error CallOnHomeChain(); + error InvalidTargetStateCommitment(); constructor(uint256 _homeChainId) { homeChainId = _homeChainId; @@ -52,6 +53,7 @@ contract ChildToParentProver is IStateProver { targetStateCommitment = ProverUtils.getSlotFromBlockHeader( homeBlockHash, rlpBlockHeader, L1_BLOCK_PREDEPLOY, L1_BLOCK_HASH_SLOT, accountProof, storageProof ); + require(targetStateCommitment != bytes32(0), InvalidTargetStateCommitment()); } /// @notice Get the latest parent chain block hash from the L1Block predeploy. Bytes argument is ignored. diff --git a/src/contracts/provers/optimism/ParentToChildProver.sol b/src/contracts/provers/optimism/ParentToChildProver.sol index 35436a4..96a8746 100644 --- a/src/contracts/provers/optimism/ParentToChildProver.sol +++ b/src/contracts/provers/optimism/ParentToChildProver.sol @@ -41,6 +41,7 @@ contract ParentToChildProver is IStateProver { error InvalidGameProxyCode(); error InvalidRootClaimPreimage(); error InvalidGameProxy(); + error InvalidTargetStateCommitment(); constructor(address _anchorStateRegistry, uint256 _homeChainId) { anchorStateRegistry = _anchorStateRegistry; @@ -118,7 +119,8 @@ contract ParentToChildProver is IStateProver { } // return the target block hash from the root claim preimage - return rootClaimPreimage.latestBlockhash; + targetStateCommitment = rootClaimPreimage.latestBlockhash; + require(targetStateCommitment != bytes32(0), InvalidTargetStateCommitment()); } /// @notice Return the blockhash from a valid fault dispute game's root claim. The game's claim must be considered valid by the anchor state registry. diff --git a/src/contracts/provers/scroll/ChildToParentProver.sol b/src/contracts/provers/scroll/ChildToParentProver.sol index 3cc36f1..f1f2853 100644 --- a/src/contracts/provers/scroll/ChildToParentProver.sol +++ b/src/contracts/provers/scroll/ChildToParentProver.sol @@ -22,6 +22,7 @@ contract ChildToParentProver is IStateProver { error CallNotOnHomeChain(); error CallOnHomeChain(); + error InvalidTargetStateCommitment(); constructor(address _blockHashBuffer, uint256 _homeChainId) { blockHashBuffer = _blockHashBuffer; @@ -51,6 +52,7 @@ contract ChildToParentProver is IStateProver { targetStateCommitment = ProverUtils.getSlotFromBlockHeader( homeBlockHash, rlpBlockHeader, blockHashBuffer, slot, accountProof, storageProof ); + require(targetStateCommitment != bytes32(0), InvalidTargetStateCommitment()); } /// @notice Get a parent chain block hash from the buffer at `blockHashBuffer`. @@ -64,6 +66,7 @@ contract ChildToParentProver is IStateProver { // get the block hash from the buffer targetStateCommitment = IBuffer(blockHashBuffer).parentChainBlockHash(targetBlockNumber); + require(targetStateCommitment != bytes32(0), InvalidTargetStateCommitment()); } /// @notice Verify a storage slot given a target chain block hash and a proof. diff --git a/src/contracts/provers/scroll/ParentToChildProver.sol b/src/contracts/provers/scroll/ParentToChildProver.sol index 8d5297c..d48ef46 100644 --- a/src/contracts/provers/scroll/ParentToChildProver.sol +++ b/src/contracts/provers/scroll/ParentToChildProver.sol @@ -30,7 +30,7 @@ contract ParentToChildProver is IStateProver { error CallNotOnHomeChain(); error CallOnHomeChain(); - error StateRootNotFound(); + error InvalidTargetStateCommitment(); /// @param _scrollChain Address of the ScrollChain contract on L1 /// @param _finalizedStateRootsSlot Storage slot of the finalizedStateRoots mapping @@ -68,9 +68,7 @@ contract ParentToChildProver is IStateProver { homeBlockHash, rlpBlockHeader, scrollChain, slot, accountProof, storageProof ); - if (targetStateCommitment == bytes32(0)) { - revert StateRootNotFound(); - } + require(targetStateCommitment != bytes32(0), InvalidTargetStateCommitment()); } /// @notice Get L2 state root directly from L1 ScrollChain @@ -88,9 +86,7 @@ contract ParentToChildProver is IStateProver { // Get the state root from ScrollChain targetStateCommitment = IScrollChain(scrollChain).finalizedStateRoots(batchIndex); - if (targetStateCommitment == bytes32(0)) { - revert StateRootNotFound(); - } + require(targetStateCommitment != bytes32(0), InvalidTargetStateCommitment()); } /// @notice Verify a storage slot given an L2 state root and a proof diff --git a/src/contracts/provers/taiko/ChildToParentProver.sol b/src/contracts/provers/taiko/ChildToParentProver.sol index b3ab4d8..760d163 100644 --- a/src/contracts/provers/taiko/ChildToParentProver.sol +++ b/src/contracts/provers/taiko/ChildToParentProver.sol @@ -34,7 +34,7 @@ contract ChildToParentProver is IStateProver { error CallNotOnHomeChain(); error CallOnHomeChain(); - error TargetBlockHashNotFound(); + error InvalidTargetStateCommitment(); constructor(address _signalService, uint256 _checkpointsSlot, uint256 _homeChainId) { signalService = _signalService; @@ -70,9 +70,7 @@ contract ChildToParentProver is IStateProver { homeBlockHash, rlpBlockHeader, signalService, slot, accountProof, storageProof ); - if (targetStateCommitment == bytes32(0)) { - revert TargetBlockHashNotFound(); - } + require(targetStateCommitment != bytes32(0), InvalidTargetStateCommitment()); } /// @notice Get L1 block hash directly from L2 SignalService @@ -92,9 +90,7 @@ contract ChildToParentProver is IStateProver { targetStateCommitment = checkpoint.blockHash; - if (targetStateCommitment == bytes32(0)) { - revert TargetBlockHashNotFound(); - } + require(targetStateCommitment != bytes32(0), InvalidTargetStateCommitment()); } /// @notice Verify a storage slot given a target chain block hash and a proof diff --git a/src/contracts/provers/taiko/ParentToChildProver.sol b/src/contracts/provers/taiko/ParentToChildProver.sol index 228b3e5..9ec110a 100644 --- a/src/contracts/provers/taiko/ParentToChildProver.sol +++ b/src/contracts/provers/taiko/ParentToChildProver.sol @@ -34,7 +34,7 @@ contract ParentToChildProver is IStateProver { error CallNotOnHomeChain(); error CallOnHomeChain(); - error TargetBlockHashNotFound(); + error InvalidTargetStateCommitment(); constructor(address _signalService, uint256 _checkpointsSlot, uint256 _homeChainId) { signalService = _signalService; @@ -70,9 +70,7 @@ contract ParentToChildProver is IStateProver { homeBlockHash, rlpBlockHeader, signalService, slot, accountProof, storageProof ); - if (targetStateCommitment == bytes32(0)) { - revert TargetBlockHashNotFound(); - } + require(targetStateCommitment != bytes32(0), InvalidTargetStateCommitment()); } /// @notice Get L2 block hash directly from L1 SignalService @@ -92,9 +90,7 @@ contract ParentToChildProver is IStateProver { targetStateCommitment = checkpoint.blockHash; - if (targetStateCommitment == bytes32(0)) { - revert TargetBlockHashNotFound(); - } + require(targetStateCommitment != bytes32(0), InvalidTargetStateCommitment()); } /// @notice Verify a storage slot given a target chain block hash and a proof diff --git a/src/contracts/provers/zksync/ChildToParentProver.sol b/src/contracts/provers/zksync/ChildToParentProver.sol index 76990b8..43020df 100644 --- a/src/contracts/provers/zksync/ChildToParentProver.sol +++ b/src/contracts/provers/zksync/ChildToParentProver.sol @@ -22,6 +22,7 @@ contract ChildToParentProver is IStateProver { error CallNotOnHomeChain(); error CallOnHomeChain(); + error InvalidTargetStateCommitment(); constructor(address _blockHashBuffer, uint256 _homeChainId) { blockHashBuffer = _blockHashBuffer; @@ -51,6 +52,7 @@ contract ChildToParentProver is IStateProver { targetStateCommitment = ProverUtils.getSlotFromBlockHeader( homeBlockHash, rlpBlockHeader, blockHashBuffer, slot, accountProof, storageProof ); + require(targetStateCommitment != bytes32(0), InvalidTargetStateCommitment()); } /// @notice Get a parent chain block hash from the buffer at `blockHashBuffer`. @@ -64,6 +66,7 @@ contract ChildToParentProver is IStateProver { // get the block hash from the buffer targetStateCommitment = IBuffer(blockHashBuffer).parentChainBlockHash(targetBlockNumber); + require(targetStateCommitment != bytes32(0), InvalidTargetStateCommitment()); } /// @notice Verify a storage slot given a target chain block hash and a proof. diff --git a/src/contracts/provers/zksync/ParentToChildProver.sol b/src/contracts/provers/zksync/ParentToChildProver.sol index 0e04763..a591800 100644 --- a/src/contracts/provers/zksync/ParentToChildProver.sol +++ b/src/contracts/provers/zksync/ParentToChildProver.sol @@ -97,6 +97,9 @@ contract ParentToChildProver is IStateProver { /// @notice Error thrown when the slot does not match the expected slot. error SlotMismatch(); + /// @notice Error thrown when the target state commitment is invalid. + error InvalidTargetStateCommitment(); + constructor( address _gatewayZkChain, uint256 _l2LogsRootHashSlot, @@ -138,6 +141,7 @@ contract ParentToChildProver is IStateProver { targetStateCommitment = ProverUtils.getSlotFromBlockHeader( homeStateCommitment, rlpBlockHeader, address(gatewayZkChain), slot, accountProof, storageProof ); + require(targetStateCommitment != bytes32(0), InvalidTargetStateCommitment()); } /// @notice Get a target chain L2 logs root hash given a batch number. @@ -154,9 +158,7 @@ contract ParentToChildProver is IStateProver { uint256 batchNumber = abi.decode(input, (uint256)); targetStateCommitment = gatewayZkChain.l2LogsRootHash(batchNumber); - if (targetStateCommitment == bytes32(0)) { - revert L2LogsRootHashNotFound(); - } + require(targetStateCommitment != bytes32(0), L2LogsRootHashNotFound()); } /// @notice Verify a storage slot given a target chain L2 logs root hash and a proof. diff --git a/test/provers/scroll/ParentToChildProver.t.sol b/test/provers/scroll/ParentToChildProver.t.sol index 17ee513..7798567 100644 --- a/test/provers/scroll/ParentToChildProver.t.sol +++ b/test/provers/scroll/ParentToChildProver.t.sol @@ -122,7 +122,7 @@ contract ScrollChainMock is IScrollChain { bytes memory input = abi.encode(batchIndex); - vm.expectRevert(ParentToChildProver.StateRootNotFound.selector); + vm.expectRevert(ParentToChildProver.InvalidTargetStateCommitment.selector); parentToChildProver.getTargetStateCommitment(input); }