From d30bc74177e05a0411c53a07c64884e45a7f11b7 Mon Sep 17 00:00:00 2001 From: josojo Date: Sat, 30 Dec 2023 09:42:49 +0100 Subject: [PATCH] Sets global exit root duing forking process (#137) * Sets global exit root duing forking process * linting * update zkevm-contract deps --- contracts/ForkableGlobalExitRoot.sol | 39 +++-------- contracts/ForkingManager.sol | 8 ++- .../interfaces/IForkableGlobalExitRoot.sol | 11 ++- lib/zkevm-contracts | 2 +- test/ForkableGlobalExitRoot.t.sol | 4 +- test/ForkingManager.t.sol | 70 +++++++++++++++++-- test/L1GlobalChainInfoPublisher.t.sol | 4 +- test/L1GlobalForkRequester.t.sol | 4 +- 8 files changed, 99 insertions(+), 43 deletions(-) diff --git a/contracts/ForkableGlobalExitRoot.sol b/contracts/ForkableGlobalExitRoot.sol index 125ca5d3..535e6c1f 100644 --- a/contracts/ForkableGlobalExitRoot.sol +++ b/contracts/ForkableGlobalExitRoot.sol @@ -13,42 +13,21 @@ contract ForkableGlobalExitRoot is ForkableStructure, PolygonZkEVMGlobalExitRoot { - /// @dev Initializting function - /// @param _forkmanager The address of the forkmanager - /// @param _parentContract The address of the parent contract - /// @param _rollupAddress The address of the rollup contract - /// @param _bridgeAddress The address of the bridge contract + /// @inheritdoc IForkableGlobalExitRoot function initialize( address _forkmanager, address _parentContract, address _rollupAddress, - address _bridgeAddress + address _bridgeAddress, + bytes32 _lastMainnetExitRoot, + bytes32 _lastRollupExitRoot ) public initializer { ForkableStructure.initialize(_forkmanager, _parentContract); - PolygonZkEVMGlobalExitRoot.initialize(_rollupAddress, _bridgeAddress); - } - - /// @dev Overrites the other initialize functions from ForkableStructure and PolygonZkEVMGlobalExitRoot - /// @notice If we would not do it, it would throw the following error: - /// "Derived contract must override function "initialize". Two or more base classes - /// define function with same name and parameter types." - function initialize( - address forkmanager, - address parentContract - ) - public - virtual - override(ForkableStructure, PolygonZkEVMGlobalExitRoot) - onlyInitializing - { - revert( - string( - abi.encode( - "illicit call to initialize with arguments:", - forkmanager, - parentContract - ) - ) + PolygonZkEVMGlobalExitRoot.initialize( + _rollupAddress, + _bridgeAddress, + _lastMainnetExitRoot, + _lastRollupExitRoot ); } diff --git a/contracts/ForkingManager.sol b/contracts/ForkingManager.sol index d3668aa3..8332ede4 100644 --- a/contracts/ForkingManager.sol +++ b/contracts/ForkingManager.sol @@ -283,7 +283,9 @@ contract ForkingManager is IForkingManager, ForkableStructure { newInstances.forkingManager.one, globalExitRoot, newInstances.zkEVM.one, - newInstances.bridge.one + newInstances.bridge.one, + IForkableGlobalExitRoot(globalExitRoot).lastMainnetExitRoot(), + IForkableGlobalExitRoot(globalExitRoot).lastRollupExitRoot() ); } @@ -396,7 +398,9 @@ contract ForkingManager is IForkingManager, ForkableStructure { newInstances.forkingManager.two, globalExitRoot, newInstances.zkEVM.two, - newInstances.bridge.two + newInstances.bridge.two, + IForkableGlobalExitRoot(globalExitRoot).lastMainnetExitRoot(), + IForkableGlobalExitRoot(globalExitRoot).lastRollupExitRoot() ); } } diff --git a/contracts/interfaces/IForkableGlobalExitRoot.sol b/contracts/interfaces/IForkableGlobalExitRoot.sol index d4b485c7..89a2b203 100644 --- a/contracts/interfaces/IForkableGlobalExitRoot.sol +++ b/contracts/interfaces/IForkableGlobalExitRoot.sol @@ -8,11 +8,20 @@ interface IForkableGlobalExitRoot is IForkableStructure, IPolygonZkEVMGlobalExitRoot { + /// @dev Initializting function + /// @param _forkmanager The address of the forkmanager + /// @param _parentContract The address of the parent contract + /// @param _rollupAddress The address of the rollup contract + /// @param _bridgeAddress The address of the bridge contract + /// @param _lastMainnetExitRoot The last exit root on mainnet + /// @param _lastRollupExitRoot The last exit root on rollup function initialize( address _forkmanager, address _parentContract, address _rollupAddress, - address _bridgeAddress + address _bridgeAddress, + bytes32 _lastMainnetExitRoot, + bytes32 _lastRollupExitRoot ) external; function createChildren( diff --git a/lib/zkevm-contracts b/lib/zkevm-contracts index 98773c5c..a0904581 160000 --- a/lib/zkevm-contracts +++ b/lib/zkevm-contracts @@ -1 +1 @@ -Subproject commit 98773c5cbaffb6d4b14b523d29b4b0b3ab4f4e37 +Subproject commit a090458140cdfce23763af887ff0767469368923 diff --git a/test/ForkableGlobalExitRoot.t.sol b/test/ForkableGlobalExitRoot.t.sol index 435db0c8..3936bd7d 100644 --- a/test/ForkableGlobalExitRoot.t.sol +++ b/test/ForkableGlobalExitRoot.t.sol @@ -37,7 +37,9 @@ contract ForkableGlobalExitRootTest is Test { forkmanager, parentContract, rollupAddress, - bridgeAddress + bridgeAddress, + bytes32(0), + bytes32(0) ); } diff --git a/test/ForkingManager.t.sol b/test/ForkingManager.t.sol index 1bf5203c..62dc9ace 100644 --- a/test/ForkingManager.t.sol +++ b/test/ForkingManager.t.sol @@ -9,7 +9,7 @@ import {ForkableBridge} from "../contracts/ForkableBridge.sol"; import {ForkableZkEVM} from "../contracts/ForkableZkEVM.sol"; import {ForkonomicToken} from "../contracts/ForkonomicToken.sol"; import {ForkableGlobalExitRoot} from "../contracts/ForkableGlobalExitRoot.sol"; -import {IBasePolygonZkEVMGlobalExitRoot} from "@RealityETH/zkevm-contracts/contracts/interfaces/IPolygonZkEVMGlobalExitRoot.sol"; +import {IPolygonZkEVMGlobalExitRoot} from "@RealityETH/zkevm-contracts/contracts/interfaces/IPolygonZkEVMGlobalExitRoot.sol"; import {IForkingManager} from "../contracts/interfaces/IForkingManager.sol"; import {IVerifierRollup} from "@RealityETH/zkevm-contracts/contracts/interfaces/IVerifierRollup.sol"; import {IPolygonZkEVMBridge} from "@RealityETH/zkevm-contracts/contracts/interfaces/IPolygonZkEVMBridge.sol"; @@ -37,10 +37,8 @@ contract ForkingManagerTest is Test { bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; - IBasePolygonZkEVMGlobalExitRoot public globalExitMock = - IBasePolygonZkEVMGlobalExitRoot( - 0x1234567890123456789012345678901234567892 - ); + IPolygonZkEVMGlobalExitRoot public globalExitMock = + IPolygonZkEVMGlobalExitRoot(0x1234567890123456789012345678901234567892); bytes32 public genesisRoot = bytes32( 0x827a9240c96ccb855e4943cc9bc49a50b1e91ba087007441a1ae5f9df8d1c57c @@ -142,7 +140,9 @@ contract ForkingManagerTest is Test { address(forkmanager), address(0x0), address(zkevm), - address(bridge) + address(bridge), + bytes32(0), + bytes32(0) ); bridge.initialize( address(forkmanager), @@ -797,4 +797,62 @@ contract ForkingManagerTest is Test { }) ); } + + function testSetsCorrectGlobalExitRoot() public { + // Set completely randcom exit hashes to make them non-zero + bytes32 lastMainnetExitRoot = keccak256(abi.encode(2)); + bytes32 lastRollupExitRoot = keccak256(abi.encode(1)); + vm.prank(address(bridge)); + globalExitRoot.updateExitRoot(lastMainnetExitRoot); + vm.prank(address(zkevm)); + globalExitRoot.updateExitRoot(lastRollupExitRoot); + + // Mint and approve the arbitration fee for the test contract + forkonomicToken.approve(address(forkmanager), arbitrationFee); + vm.prank(address(this)); + forkonomicToken.mint(address(this), arbitrationFee); + + // Call the initiateFork function to create a new fork + uint256 testTimestamp = 12354234; + vm.warp(testTimestamp); + forkmanager.initiateFork( + disputeData, + IForkingManager.NewImplementations({ + bridgeImplementation: newBridgeImplementation, + zkEVMImplementation: newZkevmImplementation, + forkonomicTokenImplementation: newForkonomicTokenImplementation, + forkingManagerImplementation: newForkmanagerImplementation, + globalExitRootImplementation: newGlobalExitRootImplementation, + verifier: newVerifierImplementation, + forkID: newForkID + }) + ); + + vm.warp(testTimestamp + forkmanager.forkPreparationTime() + 1); + forkmanager.executeFork1(); + (address child1, address child2) = globalExitRoot.getChildren(); + + assertEq( + IPolygonZkEVMGlobalExitRoot(globalExitRoot).lastMainnetExitRoot(), + IPolygonZkEVMGlobalExitRoot(child1).lastMainnetExitRoot() + ); + assertEq( + IPolygonZkEVMGlobalExitRoot(globalExitRoot).lastRollupExitRoot(), + IPolygonZkEVMGlobalExitRoot(child1).lastRollupExitRoot(), + "lastRollupExitRoot not the same" + ); + assertEq( + IPolygonZkEVMGlobalExitRoot(globalExitRoot).getLastGlobalExitRoot(), + IPolygonZkEVMGlobalExitRoot(child1).getLastGlobalExitRoot() + ); + forkmanager.executeFork2(); + assertEq( + IPolygonZkEVMGlobalExitRoot(globalExitRoot).lastMainnetExitRoot(), + IPolygonZkEVMGlobalExitRoot(child2).lastMainnetExitRoot() + ); + assertEq( + IPolygonZkEVMGlobalExitRoot(globalExitRoot).lastRollupExitRoot(), + IPolygonZkEVMGlobalExitRoot(child2).lastRollupExitRoot() + ); + } } diff --git a/test/L1GlobalChainInfoPublisher.t.sol b/test/L1GlobalChainInfoPublisher.t.sol index f0f2c477..c522dcaa 100644 --- a/test/L1GlobalChainInfoPublisher.t.sol +++ b/test/L1GlobalChainInfoPublisher.t.sol @@ -181,7 +181,9 @@ contract L1GlobalChainInfoPublisherTest is Test { address(forkmanager), address(0x0), address(zkevm), - address(bridge) + address(bridge), + bytes32(0), + bytes32(0) ); bridge.initialize( address(forkmanager), diff --git a/test/L1GlobalForkRequester.t.sol b/test/L1GlobalForkRequester.t.sol index 2b99e71c..2967a334 100644 --- a/test/L1GlobalForkRequester.t.sol +++ b/test/L1GlobalForkRequester.t.sol @@ -144,7 +144,9 @@ contract L1GlobalForkRequesterTest is Test { address(forkmanager), address(0x0), address(zkevm), - address(bridge) + address(bridge), + bytes32(0), + bytes32(0) ); bridge.initialize( address(forkmanager),