diff --git a/contracts/interfaces/IBasePolygonZkEVMGlobalExitRoot.sol b/contracts/interfaces/IBasePolygonZkEVMGlobalExitRoot.sol index 5d765ccf..f1b0a1b1 100644 --- a/contracts/interfaces/IBasePolygonZkEVMGlobalExitRoot.sol +++ b/contracts/interfaces/IBasePolygonZkEVMGlobalExitRoot.sol @@ -11,7 +11,7 @@ interface IBasePolygonZkEVMGlobalExitRoot { /** * @dev Thrown when the caller is not the trusted sequencer */ - error OnlyTrustedSequencer(); + error OnlyCoinbase(); function updateExitRoot(bytes32 newRollupExitRoot) external; diff --git a/contracts/v2/PolygonZkEVMGlobalExitRootV2.sol b/contracts/v2/PolygonZkEVMGlobalExitRootV2.sol index c904686b..820d0184 100644 --- a/contracts/v2/PolygonZkEVMGlobalExitRootV2.sol +++ b/contracts/v2/PolygonZkEVMGlobalExitRootV2.sol @@ -25,6 +25,12 @@ contract PolygonZkEVMGlobalExitRootV2 is // Store every l1InfoLeaf mapping(uint32 leafCount => bytes32 l1InfoRoot) public l1InfoRootMap; + /** + * @dev This empty reserved space is put in place to allow future versions to add new + * variables without shifting down storage in the inheritance chain. + */ + uint256[50] private _gap; + /** * @dev Emitted when the global exit root is updated */ @@ -77,7 +83,7 @@ contract PolygonZkEVMGlobalExitRootV2 is * @notice Update the exit root of one of the networks and the global exit root * @param newRoot new exit tree root */ - function updateExitRoot(bytes32 newRoot) external { + function updateExitRoot(bytes32 newRoot) external virtual { // Store storage variables into temporal variables since will be used multiple times bytes32 cacheLastRollupExitRoot; bytes32 cacheLastMainnetExitRoot; diff --git a/contracts/v2/sovereignChains/GlobalExitRootManagerL2SovereignChain.sol b/contracts/v2/sovereignChains/GlobalExitRootManagerL2SovereignChain.sol index f798c75c..b53e905c 100644 --- a/contracts/v2/sovereignChains/GlobalExitRootManagerL2SovereignChain.sol +++ b/contracts/v2/sovereignChains/GlobalExitRootManagerL2SovereignChain.sol @@ -3,42 +3,23 @@ pragma solidity 0.8.20; import "../../interfaces/IBasePolygonZkEVMGlobalExitRoot.sol"; import {PolygonAccessControlUpgradeable} from "../lib/PolygonAccessControlUpgradeable.sol"; +import "../PolygonZkEVMGlobalExitRootV2.sol"; /** * Contract responsible for managing the exit roots for the Sovereign chains and global exit roots */ -contract GlobalExitRootManagerL2SovereignChain is - PolygonAccessControlUpgradeable, - IBasePolygonZkEVMGlobalExitRoot -{ - // Store every global exit root: Root --> timestamp - mapping(bytes32 => uint256) public globalExitRootMap; - - // Rollup exit root will be updated for every Sovereign chain call - bytes32 public lastRollupExitRoot; - - // Sovereign chain Bridge address - address public immutable bridgeAddress; - +contract GlobalExitRootManagerL2SovereignChain is PolygonZkEVMGlobalExitRootV2 { /** * @dev Emitted when a new global exit root is inserted */ event InsertGlobalExitRoot(bytes32 indexed newGlobalExitRoot); - /** - * @param _bridgeAddress BridgeL2SovereignChain contract address - */ - constructor(address _bridgeAddress) { - bridgeAddress = _bridgeAddress; - _disableInitializers(); - } - /** * @notice Only allows a function to be callable if its called by coinbase (trusted sequencer in sovereign chains) */ - modifier onlyTrustedSequencer() { + modifier onlyCoinbase() { if (block.coinbase != msg.sender) { - revert OnlyTrustedSequencer(); + revert OnlyCoinbase(); } _; } @@ -53,17 +34,31 @@ contract GlobalExitRootManagerL2SovereignChain is _; } + /** + * @param _bridgeAddress PolygonZkEVMBridge contract address + */ + constructor( + address _rollupManager, + address _bridgeAddress + ) PolygonZkEVMGlobalExitRootV2(_rollupManager, _bridgeAddress) {} + /** * @notice Update the exit root of one of the networks and the global exit root * @param newRoot new exit tree root */ - function updateExitRoot(bytes32 newRoot) external onlyBridgeAddress() { + function updateExitRoot( + bytes32 newRoot + ) external override onlyBridgeAddress { lastRollupExitRoot = newRoot; } + /** + * @notice Insert a new global exit root + * @param _newRoot new global exit root + */ function insertGlobalExitRoot( bytes32 _newRoot - ) external onlyTrustedSequencer { + ) external onlyCoinbase { // do not update timestamp if already set if (globalExitRootMap[_newRoot] == 0) { globalExitRootMap[_newRoot] = block.timestamp; diff --git a/test/contractsv2/BridgeL2SovereignChain.test.ts b/test/contractsv2/BridgeL2SovereignChain.test.ts index 440a57d9..a2370eec 100644 --- a/test/contractsv2/BridgeL2SovereignChain.test.ts +++ b/test/contractsv2/BridgeL2SovereignChain.test.ts @@ -71,6 +71,7 @@ describe("BridgeL2SovereignChain Contract", () => { "GlobalExitRootManagerL2SovereignChain" ); sovereignChainGlobalExitRoot = await PolygonZkEVMGlobalExitRootFactory.deploy( + rollupManager.address, sovereignChainBridgeContract.target );