diff --git a/src/L1/rollup/ScrollChainCommitmentVerifier.sol b/src/L1/rollup/ScrollChainCommitmentVerifier.sol index 3d5674f5..ba94ecca 100644 --- a/src/L1/rollup/ScrollChainCommitmentVerifier.sol +++ b/src/L1/rollup/ScrollChainCommitmentVerifier.sol @@ -2,8 +2,9 @@ pragma solidity =0.8.24; -import {IScrollChain} from "./IScrollChain.sol"; +import {ScrollChain} from "./ScrollChain.sol"; import {ZkTrieVerifier} from "../../libraries/verifier/ZkTrieVerifier.sol"; +import {PatriciaMerkleTrieVerifier} from "../../libraries/verifier/PatriciaMerkleTrieVerifier.sol"; contract ScrollChainCommitmentVerifier { /// @notice The address of poseidon hash contract @@ -17,7 +18,7 @@ contract ScrollChainCommitmentVerifier { rollup = _rollup; } - /// @notice Validates a proof from eth_getProof in l2geth. + /// @notice Validates a proof from eth_getProof in l2geth zktrie node. /// @param account The address of the contract. /// @param storageKey The storage slot to verify. /// @param proof The rlp encoding result of eth_getProof. @@ -37,6 +38,26 @@ contract ScrollChainCommitmentVerifier { return ZkTrieVerifier.verifyZkTrieProof(poseidon, account, storageKey, proof); } + /// @notice Validates a proof from eth_getProof in l2geth zktrie node. + /// @param account The address of the contract. + /// @param storageKey The storage slot to verify. + /// @param proof The rlp encoding result of eth_getProof. + /// @return stateRoot The computed state root. Must be checked by the caller. + /// @return storageValue The value of `storageKey`. + /// + /// The encoding order of `proof` is + /// ```text + /// | 1 byte | ... | 1 byte | ... | + /// | account proof length | account proof | storage proof length | storage proof | + /// ``` + function verifyPatriciaMerkleTrieProof( + address account, + bytes32 storageKey, + bytes calldata proof + ) public pure returns (bytes32 stateRoot, bytes32 storageValue) { + return PatriciaMerkleTrieVerifier.verifyPatriciaProof(account, storageKey, proof); + } + /// @notice Verifies a batch inclusion proof. /// @param batchIndex The index of the batch. /// @param account The address of the contract in L2. @@ -49,11 +70,16 @@ contract ScrollChainCommitmentVerifier { bytes32 storageKey, bytes calldata proof ) external view returns (bytes32 storageValue) { - require(IScrollChain(rollup).isBatchFinalized(batchIndex), "Batch not finalized"); + require(ScrollChain(rollup).isBatchFinalized(batchIndex), "Batch not finalized"); bytes32 computedStateRoot; - (computedStateRoot, storageValue) = verifyZkTrieProof(account, storageKey, proof); - bytes32 expectedStateRoot = IScrollChain(rollup).finalizedStateRoots(batchIndex); + uint256 initialEuclidBatchIndex = ScrollChain(rollup).initialEuclidBatchIndex(); + if (batchIndex < initialEuclidBatchIndex) { + (computedStateRoot, storageValue) = verifyZkTrieProof(account, storageKey, proof); + } else { + (computedStateRoot, storageValue) = verifyPatriciaMerkleTrieProof(account, storageKey, proof); + } + bytes32 expectedStateRoot = ScrollChain(rollup).finalizedStateRoots(batchIndex); require(computedStateRoot == expectedStateRoot, "Invalid inclusion proof"); } }