Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 23 additions & 6 deletions src/contracts/provers/optimism/ParentToChildProver.sol
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ contract ParentToChildProver is IStateProver {

error CallNotOnHomeChain();
error CallOnHomeChain();
error InvalidHomeBlockHeader();
error AnchorGameAccountDoesNotExist();
error InvalidGameProxyCode();
error InvalidRootClaimPreimage();
error InvalidGameProxy();

constructor(address _anchorStateRegistry, uint256 _homeChainId) {
anchorStateRegistry = _anchorStateRegistry;
Expand Down Expand Up @@ -79,7 +84,9 @@ contract ParentToChildProver is IStateProver {
) = abi.decode(input, (bytes, bytes, bytes, bytes, bytes, OutputRootProof));

// check the block hash
require(homeBlockHash == keccak256(rlpBlockHeader), "Invalid home block header");
if (homeBlockHash != keccak256(rlpBlockHeader)) {
revert InvalidHomeBlockHeader();
}
bytes32 stateRoot = ProverUtils.extractStateRootFromBlockHeader(rlpBlockHeader);

// grab the anchor game address
Expand All @@ -96,17 +103,23 @@ contract ParentToChildProver is IStateProver {
// get the anchor game's code hash from the account proof
(bool accountExists, bytes memory accountValue) =
ProverUtils.getAccountDataFromStateRoot(stateRoot, gameProxyAccountProof, anchorGame);
require(accountExists, "Anchor game account does not exist");
if (!accountExists) {
revert AnchorGameAccountDoesNotExist();
}
bytes32 codeHash = ProverUtils.extractCodeHashFromAccountData(accountValue);

// verify the game proxy code against the code hash
require(keccak256(gameProxyCode) == codeHash, "Invalid game proxy code");
if (keccak256(gameProxyCode) != codeHash) {
revert InvalidGameProxyCode();
}

// extract the root claim from the game proxy code
bytes32 rootClaim = _getRootClaimFromGameProxyCode(gameProxyCode);

// verify the root claim preimage
require(rootClaim == keccak256(abi.encode(rootClaimPreimage)), "Invalid root claim preimage");
if (rootClaim != keccak256(abi.encode(rootClaimPreimage))) {
revert InvalidRootClaimPreimage();
}

// return the target block hash from the root claim preimage
return rootClaimPreimage.latestBlockhash;
Expand All @@ -126,10 +139,14 @@ contract ParentToChildProver is IStateProver {
(address gameProxy, OutputRootProof memory rootClaimPreimage) = abi.decode(input, (address, OutputRootProof));

// check the game proxy address
require(IAnchorStateRegistry(anchorStateRegistry).isGameClaimValid(gameProxy), "Invalid game proxy");
if (!IAnchorStateRegistry(anchorStateRegistry).isGameClaimValid(gameProxy)) {
revert InvalidGameProxy();
}

bytes32 rootClaim = IFaultDisputeGame(gameProxy).rootClaim();
require(rootClaim == keccak256(abi.encode(rootClaimPreimage)), "Invalid root claim preimage");
if (rootClaim != keccak256(abi.encode(rootClaimPreimage))) {
revert InvalidRootClaimPreimage();
}

return rootClaimPreimage.latestBlockhash;
}
Expand Down