From d2f0d4fb586c7f4331fff634bfe23e24c832c3c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien?= <3535019+leruaa@users.noreply.github.com> Date: Wed, 15 Jan 2025 01:25:55 -0800 Subject: [PATCH] feat: migrate OPSuccinctL2OutputOracle to OptimismPortalV2 (#277) * forge install: solady v0.0.281 * feat: impl IDisputeGame for OPSuccinctL2OutputOracle * feat: update deployment * add a thin, clonable wrapper on OPSuccinctL2OutputOracle * add a test for OPSuccinctDisputeGame initialize() * use a more recent tx to make `testOPSuccinctDisputeGame` test pass * revert useless OPSuccinctL2OutputOracle IDisputeGame impl * add OPSuccinctDisputeGame bindings * add OPSuccinctDisputeGameFactory * allow to propose output roots using DisputeGameFactory * init deployment scripts * fix server in mock mode * use DGF if the address is provided * fmt * add deploy-dispute-game-factory to justfile * fix: don't disable logs on the server (#320) * feat: rc10 bump + fix mock mode (#323) * add test for OPSuccinctL2OutputOracleFactory * update book * small fixes * impl ISemver * set permissionless proposing in the deployment * OPSuccinctDisputeGameFactory: allow to change impl * proposer small fixes * don't pin op-deployer version for Kurtosis * forge fmt * update book * small fixes * nits * add a to do for GameTypes.OP_SUCCINCT --- .gitmodules | 3 + book/SUMMARY.md | 2 + book/experimental/intro.md | 3 + book/experimental/optimism-portal-v2.md | 46 ++++ book/quick-start/full.md | 2 +- book/quick-start/mock.md | 2 +- contracts/foundry.toml | 7 +- contracts/lib/solady | 1 + contracts/opsuccinctl2ooconfig-test.json | 15 ++ contracts/script/OPSuccinctDGFDeployer.s.sol | 28 ++ contracts/src/OPSuccinctDisputeGame.sol | 120 +++++++++ .../src/OPSuccinctDisputeGameFactory.sol | 65 +++++ contracts/test/OPSuccinctDisputeGame.t.sol | 57 ++++ .../test/OPSuccinctDisputeGameFactory.t.sol | 48 ++++ justfile | 48 +++- op-network.yaml | 4 - proposer/op/Makefile | 3 + .../bindings/opsuccinctdisputegamefactory.go | 255 ++++++++++++++++++ .../op/bindings/opsuccinctl2outputoracle.go | 35 ++- proposer/op/op_proposer.sh | 1 + proposer/op/proposer/config.go | 8 +- proposer/op/proposer/driver.go | 39 ++- proposer/op/proposer/flags/flags.go | 6 + proposer/op/proposer/service.go | 10 + 24 files changed, 784 insertions(+), 24 deletions(-) create mode 100644 book/experimental/intro.md create mode 100644 book/experimental/optimism-portal-v2.md create mode 160000 contracts/lib/solady create mode 100644 contracts/opsuccinctl2ooconfig-test.json create mode 100644 contracts/script/OPSuccinctDGFDeployer.s.sol create mode 100644 contracts/src/OPSuccinctDisputeGame.sol create mode 100644 contracts/src/OPSuccinctDisputeGameFactory.sol create mode 100644 contracts/test/OPSuccinctDisputeGame.t.sol create mode 100644 contracts/test/OPSuccinctDisputeGameFactory.t.sol create mode 100644 proposer/op/bindings/opsuccinctdisputegamefactory.go diff --git a/.gitmodules b/.gitmodules index 6bfb6591..46f2bcc2 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,3 +10,6 @@ [submodule "contracts/lib/sp1-contracts"] path = contracts/lib/sp1-contracts url = https://github.com/succinctlabs/sp1-contracts +[submodule "contracts/lib/solady"] + path = contracts/lib/solady + url = https://github.com/vectorized/solady diff --git a/book/SUMMARY.md b/book/SUMMARY.md index 413391ac..954d75f6 100644 --- a/book/SUMMARY.md +++ b/book/SUMMARY.md @@ -22,5 +22,7 @@ - [Upgrade Contract](./contracts/upgrade.md) - [Update Contract Parameters](./contracts/update-parameters.md) - [Modifications to Original `L2OutputOracle`](./contracts/modifications.md) +- [Experimental](./experimental/intro.md) + - [OptimismPortalV2](./experimental/optimism-portal-v2.md) - [FAQ](./faq.md) - [Troubleshooting](./troubleshooting.md) diff --git a/book/experimental/intro.md b/book/experimental/intro.md new file mode 100644 index 00000000..3f5e9950 --- /dev/null +++ b/book/experimental/intro.md @@ -0,0 +1,3 @@ +# Experimental + +This section contains experimental topics for OP Succinct. diff --git a/book/experimental/optimism-portal-v2.md b/book/experimental/optimism-portal-v2.md new file mode 100644 index 00000000..38b31265 --- /dev/null +++ b/book/experimental/optimism-portal-v2.md @@ -0,0 +1,46 @@ +# OptimismPortalV2 + +If you want to use `OptimismPortalV2` or conform to Optimism's `IDisputeGame`, you can follow this section that describe how to deploy the 2 contracts: + +* `OPSuccinctDisputeGame` a thin wrapper around `OPSuccinctL2OutputOracle` that implements `IDisputeGame`. +* `OPSuccinctDisputeGameFactory` the proposer entry point when creating new dispute game. + +And instructions about how to configure the proposer to use them. + +After having done the step 2) either in mock or full mode, with `L2OO_ADDRESS` set with the address of the `OPSuccinctL2OutputOracle` contract in your `.env` file, +run the following to deploy the contracts: + +```shell +just deploy-dispute-game-factory +``` + +If successful, you should see the following output: + +``` +[⠊] Compiling... +[⠊] Compiling 1 files with Solc 0.8.15 +[⠒] Solc 0.8.15 finished in 1.93s +Compiler run successful! +Script ran successfully. + +== Return == +0: address 0x6B3342821680031732Bc7d4E88A6528478aF9E38 + +## Setting up 1 EVM. + +========================== + +Chain 3151908 + +Estimated gas price: 1.000000014 gwei + +Estimated total gas used for script: 1614671 + +Estimated amount required: 0.001614671022605394 ETH + +========================== +``` + +In these deployment logs, `0x6B3342821680031732Bc7d4E88A6528478aF9E38` is the address of the proxy for the `OPSuccinctDisputeGameFactory` contract. + +In order to have the poposer to use it, you have to add a new variable `DGF_ADDRESS` to your `.env` file with the value above. \ No newline at end of file diff --git a/book/quick-start/full.md b/book/quick-start/full.md index 3d2f5c01..e5a94faa 100644 --- a/book/quick-start/full.md +++ b/book/quick-start/full.md @@ -25,7 +25,7 @@ In the root directory, create a file called `.env` and set the following environ There are additional optional parameters that you can set in the `.env` file. See the [Advanced Parameters](../contracts/configuration.md#optional-advanced-parameters) section for more information. -### 2) Deploy the `OPSuccinctL2OutputOracle` contract. +### 2) Deploy the `OPSuccinctL2OutputOracle` contract This contract is a modification of the `L2OutputOracle` contract which verifies a proof along with the proposed state root. diff --git a/book/quick-start/mock.md b/book/quick-start/mock.md index f53127a3..d3dd8113 100644 --- a/book/quick-start/mock.md +++ b/book/quick-start/mock.md @@ -65,7 +65,7 @@ If you have multiple environments, you can pass the environment file to the `dep just deploy-mock-verifier ``` -### 3) Deploy the `OPSuccinctL2OutputOracle` contract. +### 3) Deploy the `OPSuccinctL2OutputOracle` contract This contract is a modification of the `L2OutputOracle` contract which verifies a proof along with the proposed state root. diff --git a/contracts/foundry.toml b/contracts/foundry.toml index 338e9f51..faae877d 100644 --- a/contracts/foundry.toml +++ b/contracts/foundry.toml @@ -7,6 +7,7 @@ remappings = [ "@openzeppelin/=lib/openzeppelin-contracts/", "@optimism/=lib/optimism/packages/contracts-bedrock/", "@forge-std/=lib/forge-std/src/", + "@solady/=lib/solady/src", # Note: Use zobront/sp1-contracts as the current version for SP1 contracts is not compatible with the hard # version for 0.8.15 on some Optimism contracts. "@sp1-contracts/=lib/sp1-contracts/contracts/", @@ -15,9 +16,13 @@ remappings = [ "src/libraries/=lib/optimism/packages/contracts-bedrock/src/libraries/", "src/L1/=lib/optimism/packages/contracts-bedrock/src/L1/", "src/L2/=lib/optimism/packages/contracts-bedrock/src/L2/", + "src/dispute/=lib/optimism/packages/contracts-bedrock/src/dispute/" ] # Enable read-write access to opsuccinctl2ooconfig.json -fs_permissions = [{ access = "read-write", path = "./opsuccinctl2ooconfig.json" }] +fs_permissions = [ + { access = "read-write", path = "./opsuccinctl2ooconfig.json" }, + { access = "read-write", path = "./opsuccinctl2ooconfig-test.json" } +] # See more config options https://github.com/foundry-rs/foundry/tree/master/config diff --git a/contracts/lib/solady b/contracts/lib/solady new file mode 160000 index 00000000..513f5816 --- /dev/null +++ b/contracts/lib/solady @@ -0,0 +1 @@ +Subproject commit 513f581675374706dbe947284d6b12d19ce35a2a diff --git a/contracts/opsuccinctl2ooconfig-test.json b/contracts/opsuccinctl2ooconfig-test.json new file mode 100644 index 00000000..a1eb6760 --- /dev/null +++ b/contracts/opsuccinctl2ooconfig-test.json @@ -0,0 +1,15 @@ +{ + "challenger": "0x0000000000000000000000000000000000000000", + "finalizationPeriod": 3600, + "l2BlockTime": 2, + "owner": "0xDEd0000E32f8F40414d3ab3a830f735a3553E18e", + "proposer": "0x0000000000000000000000000000000000000000", + "rollupConfigHash": "0x0d7101e2acc7eae1fb42cfce5c604d14da561726e4e01b509315e5a9f97a9816", + "startingBlockNumber": 5726082, + "startingOutputRoot": "0xafcc854e9d3af302a5c749703bb4593fff9471f2ea1b55ec0ade1e1d3c4a0d6e", + "startingTimestamp": 1733804652, + "submissionInterval": 1200, + "verifier": "0x397A5f7f3dBd538f23DE225B51f532c34448dA9B", + "aggregationVkey": "0x00d4e72bc998d0528b0722a53bedd9c6f0143c9157af194ad4bb2502e37a496f", + "rangeVkeyCommitment": "0x33e3678015df481724af3aac49d000923caeec277027610b1490f857769f9459" +} \ No newline at end of file diff --git a/contracts/script/OPSuccinctDGFDeployer.s.sol b/contracts/script/OPSuccinctDGFDeployer.s.sol new file mode 100644 index 00000000..00b21f88 --- /dev/null +++ b/contracts/script/OPSuccinctDGFDeployer.s.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.15; + +import {Script} from "forge-std/Script.sol"; +import {OPSuccinctL2OutputOracle} from "../src/OPSuccinctL2OutputOracle.sol"; +import {OPSuccinctDisputeGame} from "../src/OPSuccinctDisputeGame.sol"; +import {OPSuccinctDisputeGameFactory} from "../src/OPSuccinctDisputeGameFactory.sol"; +import {Utils} from "../test/helpers/Utils.sol"; +import {Proxy} from "@optimism/src/universal/Proxy.sol"; +import {console} from "forge-std/console.sol"; + +contract OPSuccinctDFGDeployer is Script, Utils { + function run() public returns (address) { + vm.startBroadcast(); + + OPSuccinctL2OutputOracle l2OutputOracleProxy = OPSuccinctL2OutputOracle(vm.envAddress("L2OO_ADDRESS")); + + l2OutputOracleProxy.addProposer(address(0)); + + // Initialize the dispute game based on the existing L2OO_ADDRESS. + OPSuccinctDisputeGame game = new OPSuccinctDisputeGame(address(l2OutputOracleProxy)); + OPSuccinctDisputeGameFactory gameFactory = new OPSuccinctDisputeGameFactory(msg.sender, address(game)); + + vm.stopBroadcast(); + + return address(gameFactory); + } +} diff --git a/contracts/src/OPSuccinctDisputeGame.sol b/contracts/src/OPSuccinctDisputeGame.sol new file mode 100644 index 00000000..b870880d --- /dev/null +++ b/contracts/src/OPSuccinctDisputeGame.sol @@ -0,0 +1,120 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.15; + +import {OPSuccinctL2OutputOracle} from "./OPSuccinctL2OutputOracle.sol"; +import {CWIA} from "@solady/utils/legacy/CWIA.sol"; +import {LibBytes} from "@solady/utils/LibBytes.sol"; +import {ISemver} from "@optimism/src/universal/ISemver.sol"; +import {IDisputeGame} from "@optimism/src/dispute/interfaces/IDisputeGame.sol"; +import {Claim, GameStatus, GameType, GameTypes, Hash, Timestamp} from "@optimism/src/dispute/lib/Types.sol"; +import {GameNotInProgress, OutOfOrderResolution} from "@optimism/src/dispute/lib/Errors.sol"; + +contract OPSuccinctDisputeGame is ISemver, CWIA, IDisputeGame { + using LibBytes for bytes; + + /// @notice The address of the L2 output oracle proxy contract. + address internal immutable l2OutpoutOracle; + + /// @notice The timestamp of the game's global creation. + Timestamp public createdAt; + + /// @notice The timestamp of the game's global resolution. + Timestamp public resolvedAt; + + /// @notice Returns the current status of the game. + GameStatus public status; + + /// @notice Semantic version. + /// @custom:semver v1.0.0-rc2 + string public constant version = "v1.0.0-rc2"; + + constructor(address _l2OutpoutOracle) { + l2OutpoutOracle = _l2OutpoutOracle; + } + + //////////////////////////////////////////////////////////// + // IDisputeGame impl // + //////////////////////////////////////////////////////////// + + function initialize() external payable { + createdAt = Timestamp.wrap(uint64(block.timestamp)); + status = GameStatus.IN_PROGRESS; + + (uint256 l2BlockNumber, uint256 l1BlockNumber, bytes memory proof) = + abi.decode(extraData(), (uint256, uint256, bytes)); + + OPSuccinctL2OutputOracle(l2OutpoutOracle).proposeL2Output( + rootClaim().raw(), l2BlockNumber, l1BlockNumber, proof + ); + + this.resolve(); + } + + /// @notice Getter for the game type. + /// @dev The reference impl should be entirely different depending on the type (fault, validity) + /// i.e. The game type should indicate the security model. + /// @return gameType_ The type of proof system being used. + function gameType() public pure returns (GameType) { + // TODO: Once the following PR https://github.com/ethereum-optimism/optimism/pull/13780 is merged, + // update this to return the correct game type: GameTypes.OP_SUCCINCT + return GameType.wrap(3); + } + + /// @notice Getter for the creator of the dispute game. + /// @dev `clones-with-immutable-args` argument #1 + /// @return The creator of the dispute game. + function gameCreator() public pure returns (address) { + return _getArgAddress(0x00); + } + + /// @notice Getter for the root claim. + /// @dev `clones-with-immutable-args` argument #2 + /// @return The root claim of the DisputeGame. + function rootClaim() public pure returns (Claim) { + return Claim.wrap(_getArgBytes32(0x14)); + } + + /// @notice Getter for the parent hash of the L1 block when the dispute game was created. + /// @dev `clones-with-immutable-args` argument #3 + /// @return The parent hash of the L1 block when the dispute game was created. + function l1Head() public pure returns (Hash) { + return Hash.wrap(_getArgBytes32(0x34)); + } + + /// @notice Getter for the extra data. + /// @dev `clones-with-immutable-args` argument #4 + /// @return Any extra data supplied to the dispute game contract by the creator. + function extraData() public pure returns (bytes memory) { + // The extra data starts at the second word within the cwia calldata + return _getArgBytes().slice(0x54); + } + + /// @notice If all necessary information has been gathered, this function should mark the game + /// status as either `CHALLENGER_WINS` or `DEFENDER_WINS` and return the status of + /// the resolved game. It is at this stage that the bonds should be awarded to the + /// necessary parties. + /// @dev May only be called if the `status` is `IN_PROGRESS`. + /// @return status_ The status of the game after resolution. + function resolve() external returns (GameStatus status_) { + // INVARIANT: Resolution cannot occur unless the game is currently in progress. + if (status != GameStatus.IN_PROGRESS) revert GameNotInProgress(); + + resolvedAt = Timestamp.wrap(uint64(block.timestamp)); + status_ = GameStatus.DEFENDER_WINS; + + emit Resolved(status = status_); + } + + /// @notice A compliant implementation of this interface should return the components of the + /// game UUID's preimage provided in the cwia payload. The preimage of the UUID is + /// constructed as `keccak256(gameType . rootClaim . extraData)` where `.` denotes + /// concatenation. + /// @return gameType_ The type of proof system being used. + /// @return rootClaim_ The root claim of the DisputeGame. + /// @return extraData_ Any extra data supplied to the dispute game contract by the creator. + function gameData() external pure returns (GameType gameType_, Claim rootClaim_, bytes memory extraData_) { + gameType_ = gameType(); + rootClaim_ = rootClaim(); + extraData_ = extraData(); + } +} diff --git a/contracts/src/OPSuccinctDisputeGameFactory.sol b/contracts/src/OPSuccinctDisputeGameFactory.sol new file mode 100644 index 00000000..84bd1f3f --- /dev/null +++ b/contracts/src/OPSuccinctDisputeGameFactory.sol @@ -0,0 +1,65 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.15; + +import {IDisputeGame} from "@optimism/src/dispute/interfaces/IDisputeGame.sol"; +import {LibCWIA} from "@solady/utils/legacy/LibCWIA.sol"; +import {ISemver} from "@optimism/src/universal/ISemver.sol"; + +contract OPSuccinctDisputeGameFactory is ISemver { + using LibCWIA for address; + + /// @notice The owner of the contract, who has admin permissions. + address public owner; + + /// @notice The address of the OP Succinct DisputeGame implementation contract. + address public gameImpl; + + /// @notice Semantic version. + /// @custom:semver v1.0.0-rc2 + string public constant version = "v1.0.0-rc2"; + + //////////////////////////////////////////////////////////// + // Modifiers // + //////////////////////////////////////////////////////////// + + modifier onlyOwner() { + require(msg.sender == owner, "OPSuccinctDisputeGameFactory: caller is not the owner"); + _; + } + + //////////////////////////////////////////////////////////// + // Functions // + //////////////////////////////////////////////////////////// + + /// @notice Constructs the OPSuccinctDisputeGameFactory contract. + constructor(address _owner, address _gameImpl) { + owner = _owner; + gameImpl = _gameImpl; + } + + /// @notice Creates a new DisputeGame proxy contract. + function create(bytes32 _rootClaim, uint256 _l2BlockNumber, uint256 _l1BlockNumber, bytes memory _proof) + external + payable + { + IDisputeGame game = IDisputeGame( + gameImpl.clone( + abi.encodePacked(msg.sender, _rootClaim, bytes32(0), abi.encode(_l2BlockNumber, _l1BlockNumber, _proof)) + ) + ); + + game.initialize{value: msg.value}(); + } + + /// Updates the owner address. + /// @param _owner The new owner address. + function transferOwnership(address _owner) external onlyOwner { + owner = _owner; + } + + /// @notice Sets the implementation address. + /// @param _implementation New implementation address. + function setImplementation(address _implementation) external onlyOwner { + gameImpl = _implementation; + } +} diff --git a/contracts/test/OPSuccinctDisputeGame.t.sol b/contracts/test/OPSuccinctDisputeGame.t.sol new file mode 100644 index 00000000..24a46141 --- /dev/null +++ b/contracts/test/OPSuccinctDisputeGame.t.sol @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.15; + +import {Test, console} from "forge-std/Test.sol"; +import {Utils} from "./helpers/Utils.sol"; +import {OPSuccinctL2OutputOracle} from "../src/OPSuccinctL2OutputOracle.sol"; +import {OPSuccinctDisputeGame} from "../src/OPSuccinctDisputeGame.sol"; +import {IDisputeGame} from "@optimism/src/dispute/interfaces/IDisputeGame.sol"; +import {LibCWIA} from "@solady/utils/legacy/LibCWIA.sol"; + +contract OPSuccinctL2OutputOracleTest is Test, Utils { + using LibCWIA for address; + + // Example proof data for the BoB testnet. Tx: https://sepolia.etherscan.io/tx/0x35df99dce5db3d7644a005bd582af2d66533b56fdb01970f248d96e8053fc0ba + uint256 checkpointedL1BlockNum = 7438547; + bytes32 claimedOutputRoot = 0x974323e1f533bf40923f6a5f9d8752d42743bb5b784d9a6d1ce223a5cc368ae6; + uint256 claimedL2BlockNum = 6940641; + bytes proof = + hex"09069090289d338bbce470b324757ae21b8846ba36d88feb8fc9e32aa477d193153db2bc1ffead4fb681196de556343a1cd61954d5e6863327d35e0f2e0b9781278b58231af27bb83226d60c1573639e400130ed49318f28dddb9768c8a71f20de8bc07d0355ef76ec0661b0d720d36943e7d8660b6e603733afb549ffba8773cec52097011525d1239e39b8da29bec5fb18d6f4bdfd84890fedd6c0cf67342a6843bb2a28e9ceae9069e52312b7b79d4a39b7d5527bbcfefd66de3887cea63f76b672081dd49279796f07bfdb04e9c5284dd0565ac923bc2c5c01be28a22c314402280001a7aa13b9a8a1c92850ae89fcede9142542fbc13298ecab89ad8fbfbdabbee3"; + + function setUp() public { + // Note: L1_RPC should be a valid Sepolia RPC. + vm.createSelectFork(vm.envString("L1_RPC"), checkpointedL1BlockNum + 1); + } + + // Test the DisputeGame contract. + function testOPSuccinctDisputeGame() public { + vm.startBroadcast(); + + Config memory cfg = readJson("opsuccinctl2ooconfig-test.json"); + + cfg.owner = msg.sender; + + address l2ooProxy = deployWithConfig(cfg); + + OPSuccinctL2OutputOracle l2oo = OPSuccinctL2OutputOracle(l2ooProxy); + OPSuccinctDisputeGame game = new OPSuccinctDisputeGame(l2ooProxy); + + l2oo.addProposer(address(0)); + l2oo.checkpointBlockHash(checkpointedL1BlockNum); + + IDisputeGame proxy = IDisputeGame( + address(game).clone( + abi.encodePacked( + msg.sender, + claimedOutputRoot, + bytes32(0), // TODO: This should be parentHash + abi.encode(claimedL2BlockNum, checkpointedL1BlockNum, proof) + ) + ) + ); + + vm.stopBroadcast(); + + proxy.initialize{value: 10}(); + } +} diff --git a/contracts/test/OPSuccinctDisputeGameFactory.t.sol b/contracts/test/OPSuccinctDisputeGameFactory.t.sol new file mode 100644 index 00000000..ab675a16 --- /dev/null +++ b/contracts/test/OPSuccinctDisputeGameFactory.t.sol @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.15; + +import {Test, console} from "forge-std/Test.sol"; +import {Utils} from "./helpers/Utils.sol"; +import {OPSuccinctL2OutputOracle} from "../src/OPSuccinctL2OutputOracle.sol"; +import {OPSuccinctDisputeGame} from "../src/OPSuccinctDisputeGame.sol"; +import {OPSuccinctDisputeGameFactory} from "../src/OPSuccinctDisputeGameFactory.sol"; +import {IDisputeGame} from "@optimism/src/dispute/interfaces/IDisputeGame.sol"; +import {LibCWIA} from "@solady/utils/legacy/LibCWIA.sol"; + +contract OPSuccinctL2OutputOracleFactoryTest is Test, Utils { + using LibCWIA for address; + + // Example proof data for the BoB testnet. Tx: https://sepolia.etherscan.io/tx/0x35df99dce5db3d7644a005bd582af2d66533b56fdb01970f248d96e8053fc0ba + uint256 checkpointedL1BlockNum = 7438547; + bytes32 claimedOutputRoot = 0x974323e1f533bf40923f6a5f9d8752d42743bb5b784d9a6d1ce223a5cc368ae6; + uint256 claimedL2BlockNum = 6940641; + bytes proof = + hex"09069090289d338bbce470b324757ae21b8846ba36d88feb8fc9e32aa477d193153db2bc1ffead4fb681196de556343a1cd61954d5e6863327d35e0f2e0b9781278b58231af27bb83226d60c1573639e400130ed49318f28dddb9768c8a71f20de8bc07d0355ef76ec0661b0d720d36943e7d8660b6e603733afb549ffba8773cec52097011525d1239e39b8da29bec5fb18d6f4bdfd84890fedd6c0cf67342a6843bb2a28e9ceae9069e52312b7b79d4a39b7d5527bbcfefd66de3887cea63f76b672081dd49279796f07bfdb04e9c5284dd0565ac923bc2c5c01be28a22c314402280001a7aa13b9a8a1c92850ae89fcede9142542fbc13298ecab89ad8fbfbdabbee3"; + + function setUp() public { + // Note: L1_RPC should be a valid Sepolia RPC. + vm.createSelectFork(vm.envString("L1_RPC"), checkpointedL1BlockNum + 1); + } + + // Test the DisputeGame contract. + function testOPSuccinctDisputeGameFactory() public { + vm.startBroadcast(); + + Config memory cfg = readJson("opsuccinctl2ooconfig-test.json"); + + cfg.owner = msg.sender; + + address l2ooProxy = deployWithConfig(cfg); + + OPSuccinctL2OutputOracle l2oo = OPSuccinctL2OutputOracle(l2ooProxy); + OPSuccinctDisputeGame game = new OPSuccinctDisputeGame(l2ooProxy); + OPSuccinctDisputeGameFactory gameFactory = new OPSuccinctDisputeGameFactory(msg.sender, address(game)); + + l2oo.addProposer(address(0)); + l2oo.checkpointBlockHash(checkpointedL1BlockNum); + + vm.stopBroadcast(); + + gameFactory.create(claimedOutputRoot, claimedL2BlockNum, checkpointedL1BlockNum, proof); + } +} diff --git a/justfile b/justfile index 769ae296..996da482 100644 --- a/justfile +++ b/justfile @@ -74,15 +74,18 @@ deploy-mock-verifier env_file=".env": fi cd contracts + + VERIFY="" + if [ $ETHERSCAN_API_KEY != "" ]; then + VERIFY="--verify --verifier etherscan --etherscan-api-key $ETHERSCAN_API_KEY" + fi forge script script/DeployMockVerifier.s.sol:DeployMockVerifier \ --rpc-url $L1_RPC \ --private-key $PRIVATE_KEY \ --broadcast \ - --verify \ - --verifier etherscan \ - --etherscan-api-key $ETHERSCAN_API_KEY - + $VERIFY + # Deploy the OPSuccinct L2 Output Oracle deploy-oracle env_file=".env": #!/usr/bin/env bash @@ -99,16 +102,18 @@ deploy-oracle env_file=".env": # forge install forge install + + VERIFY="" + if [ $ETHERSCAN_API_KEY != "" ]; then + VERIFY="--verify --verifier etherscan --etherscan-api-key $ETHERSCAN_API_KEY" + fi # Run the forge deployment script forge script script/OPSuccinctDeployer.s.sol:OPSuccinctDeployer \ --rpc-url $L1_RPC \ --private-key $PRIVATE_KEY \ --broadcast \ - --verify \ - --verifier etherscan \ - --etherscan-api-key $ETHERSCAN_API_KEY - + $VERIFY # Upgrade the OPSuccinct L2 Output Oracle upgrade-oracle env_file=".env": @@ -170,4 +175,29 @@ update-parameters env_file=".env": --rpc-url $L1_RPC \ --private-key $PRIVATE_KEY \ --broadcast - fi \ No newline at end of file + fi + +deploy-dispute-game-factory env_file=".env": + #!/usr/bin/env bash + set -euo pipefail + + # Load environment variables + source {{env_file}} + + # cd into contracts directory + cd contracts + + # forge install + forge install + + VERIFY="" + if [ $ETHERSCAN_API_KEY != "" ]; then + VERIFY="--verify --verifier etherscan --etherscan-api-key $ETHERSCAN_API_KEY" + fi + + # Run the forge deployment script + L2OO_ADDRESS=$L2OO_ADDRESS forge script script/OPSuccinctDGFDeployer.s.sol:OPSuccinctDFGDeployer \ + --rpc-url $L1_RPC \ + --private-key $PRIVATE_KEY \ + --broadcast \ + $VERIFY \ No newline at end of file diff --git a/op-network.yaml b/op-network.yaml index 98726267..fbf6e31c 100644 --- a/op-network.yaml +++ b/op-network.yaml @@ -20,10 +20,6 @@ optimism_package: # A list of optional extra params that will be passed to the batcher container for modifying its behaviour extra_params: ["--batch-type=1"] - op_contract_deployer_params: - image: us-docker.pkg.dev/oplabs-tools-artifacts/images/op-deployer:v0.0.6 - l1_artifacts_locator: tag://op-contracts/v1.6.0 - l2_artifacts_locator: tag://op-contracts/v1.7.0-beta.1+l2-contracts global_log_level: "info" global_node_selectors: {} global_tolerations: [] diff --git a/proposer/op/Makefile b/proposer/op/Makefile index 4f784ba6..35e157b3 100644 --- a/proposer/op/Makefile +++ b/proposer/op/Makefile @@ -9,5 +9,8 @@ bindings: @cd ../../contracts/ && forge inspect src/OPSuccinctL2OutputOracle.sol:OPSuccinctL2OutputOracle abi > ../proposer/op/generated_bindings/OPSuccinctL2OutputOracle.abi @cd ../../contracts/ && forge inspect src/OPSuccinctL2OutputOracle.sol:OPSuccinctL2OutputOracle bytecode > ../proposer/op/generated_bindings/OPSuccinctL2OutputOracle.bin @abigen --abi generated_bindings/OPSuccinctL2OutputOracle.abi --bin generated_bindings/OPSuccinctL2OutputOracle.bin --pkg bindings --type OPSuccinctL2OutputOracle --out ./bindings/opsuccinctl2outputoracle.go + @cd ../../contracts/ && forge inspect src/OPSuccinctDisputeGameFactory.sol:OPSuccinctDisputeGameFactory abi > ../proposer/op/generated_bindings/OPSuccinctDisputeGameFactory.abi + @cd ../../contracts/ && forge inspect src/OPSuccinctDisputeGameFactory.sol:OPSuccinctDisputeGameFactory bytecode > ../proposer/op/generated_bindings/OPSuccinctDisputeGameFactory.bin + @abigen --abi generated_bindings/OPSuccinctDisputeGameFactory.abi --bin generated_bindings/OPSuccinctDisputeGameFactory.bin --pkg bindings --type OPSuccinctDisputeGameFactory --out ./bindings/opsuccinctdisputegamefactory.go @rm -rf generated_bindings @echo "Bindings generated successfully." diff --git a/proposer/op/bindings/opsuccinctdisputegamefactory.go b/proposer/op/bindings/opsuccinctdisputegamefactory.go new file mode 100644 index 00000000..88268cfc --- /dev/null +++ b/proposer/op/bindings/opsuccinctdisputegamefactory.go @@ -0,0 +1,255 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package bindings + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// OPSuccinctDisputeGameFactoryMetaData contains all meta data concerning the OPSuccinctDisputeGameFactory contract. +var OPSuccinctDisputeGameFactoryMetaData = &bind.MetaData{ + ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_impl\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"create\",\"inputs\":[{\"name\":\"_rootClaim\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"_l2BlockNumber\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_l1BlockNumber\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"impl\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"}]", + Bin: "0x6080604052348015600e575f5ffd5b50604051610452380380610452833981016040819052602b91604e565b5f80546001600160a01b0319166001600160a01b03929092169190911790556079565b5f60208284031215605d575f5ffd5b81516001600160a01b03811681146072575f5ffd5b9392505050565b6103cc806100865f395ff3fe608060405260043610610028575f3560e01c80636dd7af7f1461002c5780638abf607714610041575b5f5ffd5b61003f61003a366004610244565b61007b565b005b34801561004c575f5ffd5b505f5461005f906001600160a01b031681565b6040516001600160a01b03909116815260200160405180910390f35b5f6100da33865f5f1b87878760405160200161009993929190610313565b60408051601f19818403018152908290526100b994939291602001610356565b60408051601f198184030181529190525f546001600160a01b031690610133565b9050806001600160a01b0316638129fc1c346040518263ffffffff1660e01b81526004015f604051808303818588803b158015610115575f5ffd5b505af1158015610127573d5f5f3e3d5ffd5b50505050505050505050565b5f61013f5f8484610146565b9392505050565b5f60608203516040830351602084035184518060208701018051600283016c5af43d3d93803e606057fd5bf3895289600d8a035278593da1005b363d3d373d3d3d3d610000806062363936013d738160481b1760218a03527f9e4ac34f21c619cefc926c8bd93b54bf5a39c7ab2127a895af1cc0691d7e3dff603a8a035272fd6100003d81600a3d39f336602c57343d527f6062820160781b1761ff9e82106059018a03528060f01b8352606c8101604c8a038cf0975050866102105763301164255f526004601cfd5b90528552601f19850152603f19840152605f199092019190915292915050565b634e487b7160e01b5f52604160045260245ffd5b5f5f5f5f60808587031215610257575f5ffd5b843593506020850135925060408501359150606085013567ffffffffffffffff811115610282575f5ffd5b8501601f81018713610292575f5ffd5b803567ffffffffffffffff8111156102ac576102ac610230565b604051601f8201601f19908116603f0116810167ffffffffffffffff811182821017156102db576102db610230565b6040528181528282016020018910156102f2575f5ffd5b816020840160208301375f6020838301015280935050505092959194509250565b838152826020820152606060408201525f82518060608401528060208501608085015e5f608082850101526080601f19601f830116840101915050949350505050565b6bffffffffffffffffffffffff198560601b1681528360148201528260348201525f82518060208501605485015e5f92016054019182525094935050505056fea2646970667358221220ce3719875c7a48c923f77a9f2a7d16403b8314678d8113d140c47bbec7e073eb64736f6c634300081c0033", +} + +// OPSuccinctDisputeGameFactoryABI is the input ABI used to generate the binding from. +// Deprecated: Use OPSuccinctDisputeGameFactoryMetaData.ABI instead. +var OPSuccinctDisputeGameFactoryABI = OPSuccinctDisputeGameFactoryMetaData.ABI + +// OPSuccinctDisputeGameFactoryBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use OPSuccinctDisputeGameFactoryMetaData.Bin instead. +var OPSuccinctDisputeGameFactoryBin = OPSuccinctDisputeGameFactoryMetaData.Bin + +// DeployOPSuccinctDisputeGameFactory deploys a new Ethereum contract, binding an instance of OPSuccinctDisputeGameFactory to it. +func DeployOPSuccinctDisputeGameFactory(auth *bind.TransactOpts, backend bind.ContractBackend, _impl common.Address) (common.Address, *types.Transaction, *OPSuccinctDisputeGameFactory, error) { + parsed, err := OPSuccinctDisputeGameFactoryMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(OPSuccinctDisputeGameFactoryBin), backend, _impl) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &OPSuccinctDisputeGameFactory{OPSuccinctDisputeGameFactoryCaller: OPSuccinctDisputeGameFactoryCaller{contract: contract}, OPSuccinctDisputeGameFactoryTransactor: OPSuccinctDisputeGameFactoryTransactor{contract: contract}, OPSuccinctDisputeGameFactoryFilterer: OPSuccinctDisputeGameFactoryFilterer{contract: contract}}, nil +} + +// OPSuccinctDisputeGameFactory is an auto generated Go binding around an Ethereum contract. +type OPSuccinctDisputeGameFactory struct { + OPSuccinctDisputeGameFactoryCaller // Read-only binding to the contract + OPSuccinctDisputeGameFactoryTransactor // Write-only binding to the contract + OPSuccinctDisputeGameFactoryFilterer // Log filterer for contract events +} + +// OPSuccinctDisputeGameFactoryCaller is an auto generated read-only Go binding around an Ethereum contract. +type OPSuccinctDisputeGameFactoryCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// OPSuccinctDisputeGameFactoryTransactor is an auto generated write-only Go binding around an Ethereum contract. +type OPSuccinctDisputeGameFactoryTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// OPSuccinctDisputeGameFactoryFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type OPSuccinctDisputeGameFactoryFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// OPSuccinctDisputeGameFactorySession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type OPSuccinctDisputeGameFactorySession struct { + Contract *OPSuccinctDisputeGameFactory // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// OPSuccinctDisputeGameFactoryCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type OPSuccinctDisputeGameFactoryCallerSession struct { + Contract *OPSuccinctDisputeGameFactoryCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// OPSuccinctDisputeGameFactoryTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type OPSuccinctDisputeGameFactoryTransactorSession struct { + Contract *OPSuccinctDisputeGameFactoryTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// OPSuccinctDisputeGameFactoryRaw is an auto generated low-level Go binding around an Ethereum contract. +type OPSuccinctDisputeGameFactoryRaw struct { + Contract *OPSuccinctDisputeGameFactory // Generic contract binding to access the raw methods on +} + +// OPSuccinctDisputeGameFactoryCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type OPSuccinctDisputeGameFactoryCallerRaw struct { + Contract *OPSuccinctDisputeGameFactoryCaller // Generic read-only contract binding to access the raw methods on +} + +// OPSuccinctDisputeGameFactoryTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type OPSuccinctDisputeGameFactoryTransactorRaw struct { + Contract *OPSuccinctDisputeGameFactoryTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewOPSuccinctDisputeGameFactory creates a new instance of OPSuccinctDisputeGameFactory, bound to a specific deployed contract. +func NewOPSuccinctDisputeGameFactory(address common.Address, backend bind.ContractBackend) (*OPSuccinctDisputeGameFactory, error) { + contract, err := bindOPSuccinctDisputeGameFactory(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &OPSuccinctDisputeGameFactory{OPSuccinctDisputeGameFactoryCaller: OPSuccinctDisputeGameFactoryCaller{contract: contract}, OPSuccinctDisputeGameFactoryTransactor: OPSuccinctDisputeGameFactoryTransactor{contract: contract}, OPSuccinctDisputeGameFactoryFilterer: OPSuccinctDisputeGameFactoryFilterer{contract: contract}}, nil +} + +// NewOPSuccinctDisputeGameFactoryCaller creates a new read-only instance of OPSuccinctDisputeGameFactory, bound to a specific deployed contract. +func NewOPSuccinctDisputeGameFactoryCaller(address common.Address, caller bind.ContractCaller) (*OPSuccinctDisputeGameFactoryCaller, error) { + contract, err := bindOPSuccinctDisputeGameFactory(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &OPSuccinctDisputeGameFactoryCaller{contract: contract}, nil +} + +// NewOPSuccinctDisputeGameFactoryTransactor creates a new write-only instance of OPSuccinctDisputeGameFactory, bound to a specific deployed contract. +func NewOPSuccinctDisputeGameFactoryTransactor(address common.Address, transactor bind.ContractTransactor) (*OPSuccinctDisputeGameFactoryTransactor, error) { + contract, err := bindOPSuccinctDisputeGameFactory(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &OPSuccinctDisputeGameFactoryTransactor{contract: contract}, nil +} + +// NewOPSuccinctDisputeGameFactoryFilterer creates a new log filterer instance of OPSuccinctDisputeGameFactory, bound to a specific deployed contract. +func NewOPSuccinctDisputeGameFactoryFilterer(address common.Address, filterer bind.ContractFilterer) (*OPSuccinctDisputeGameFactoryFilterer, error) { + contract, err := bindOPSuccinctDisputeGameFactory(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &OPSuccinctDisputeGameFactoryFilterer{contract: contract}, nil +} + +// bindOPSuccinctDisputeGameFactory binds a generic wrapper to an already deployed contract. +func bindOPSuccinctDisputeGameFactory(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := OPSuccinctDisputeGameFactoryMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_OPSuccinctDisputeGameFactory *OPSuccinctDisputeGameFactoryRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _OPSuccinctDisputeGameFactory.Contract.OPSuccinctDisputeGameFactoryCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_OPSuccinctDisputeGameFactory *OPSuccinctDisputeGameFactoryRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OPSuccinctDisputeGameFactory.Contract.OPSuccinctDisputeGameFactoryTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_OPSuccinctDisputeGameFactory *OPSuccinctDisputeGameFactoryRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _OPSuccinctDisputeGameFactory.Contract.OPSuccinctDisputeGameFactoryTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_OPSuccinctDisputeGameFactory *OPSuccinctDisputeGameFactoryCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _OPSuccinctDisputeGameFactory.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_OPSuccinctDisputeGameFactory *OPSuccinctDisputeGameFactoryTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _OPSuccinctDisputeGameFactory.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_OPSuccinctDisputeGameFactory *OPSuccinctDisputeGameFactoryTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _OPSuccinctDisputeGameFactory.Contract.contract.Transact(opts, method, params...) +} + +// Impl is a free data retrieval call binding the contract method 0x8abf6077. +// +// Solidity: function impl() view returns(address) +func (_OPSuccinctDisputeGameFactory *OPSuccinctDisputeGameFactoryCaller) Impl(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _OPSuccinctDisputeGameFactory.contract.Call(opts, &out, "impl") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Impl is a free data retrieval call binding the contract method 0x8abf6077. +// +// Solidity: function impl() view returns(address) +func (_OPSuccinctDisputeGameFactory *OPSuccinctDisputeGameFactorySession) Impl() (common.Address, error) { + return _OPSuccinctDisputeGameFactory.Contract.Impl(&_OPSuccinctDisputeGameFactory.CallOpts) +} + +// Impl is a free data retrieval call binding the contract method 0x8abf6077. +// +// Solidity: function impl() view returns(address) +func (_OPSuccinctDisputeGameFactory *OPSuccinctDisputeGameFactoryCallerSession) Impl() (common.Address, error) { + return _OPSuccinctDisputeGameFactory.Contract.Impl(&_OPSuccinctDisputeGameFactory.CallOpts) +} + +// Create is a paid mutator transaction binding the contract method 0x6dd7af7f. +// +// Solidity: function create(bytes32 _rootClaim, uint256 _l2BlockNumber, uint256 _l1BlockNumber, bytes _proof) payable returns() +func (_OPSuccinctDisputeGameFactory *OPSuccinctDisputeGameFactoryTransactor) Create(opts *bind.TransactOpts, _rootClaim [32]byte, _l2BlockNumber *big.Int, _l1BlockNumber *big.Int, _proof []byte) (*types.Transaction, error) { + return _OPSuccinctDisputeGameFactory.contract.Transact(opts, "create", _rootClaim, _l2BlockNumber, _l1BlockNumber, _proof) +} + +// Create is a paid mutator transaction binding the contract method 0x6dd7af7f. +// +// Solidity: function create(bytes32 _rootClaim, uint256 _l2BlockNumber, uint256 _l1BlockNumber, bytes _proof) payable returns() +func (_OPSuccinctDisputeGameFactory *OPSuccinctDisputeGameFactorySession) Create(_rootClaim [32]byte, _l2BlockNumber *big.Int, _l1BlockNumber *big.Int, _proof []byte) (*types.Transaction, error) { + return _OPSuccinctDisputeGameFactory.Contract.Create(&_OPSuccinctDisputeGameFactory.TransactOpts, _rootClaim, _l2BlockNumber, _l1BlockNumber, _proof) +} + +// Create is a paid mutator transaction binding the contract method 0x6dd7af7f. +// +// Solidity: function create(bytes32 _rootClaim, uint256 _l2BlockNumber, uint256 _l1BlockNumber, bytes _proof) payable returns() +func (_OPSuccinctDisputeGameFactory *OPSuccinctDisputeGameFactoryTransactorSession) Create(_rootClaim [32]byte, _l2BlockNumber *big.Int, _l1BlockNumber *big.Int, _proof []byte) (*types.Transaction, error) { + return _OPSuccinctDisputeGameFactory.Contract.Create(&_OPSuccinctDisputeGameFactory.TransactOpts, _rootClaim, _l2BlockNumber, _l1BlockNumber, _proof) +} diff --git a/proposer/op/bindings/opsuccinctl2outputoracle.go b/proposer/op/bindings/opsuccinctl2outputoracle.go index d4b6709a..e09bdddb 100644 --- a/proposer/op/bindings/opsuccinctl2outputoracle.go +++ b/proposer/op/bindings/opsuccinctl2outputoracle.go @@ -55,8 +55,8 @@ type TypesOutputProposal struct { // OPSuccinctL2OutputOracleMetaData contains all meta data concerning the OPSuccinctL2OutputOracle contract. var OPSuccinctL2OutputOracleMetaData = &bind.MetaData{ - ABI: "[{\"type\":\"constructor\",\"inputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"CHALLENGER\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"FINALIZATION_PERIOD_SECONDS\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"L2_BLOCK_TIME\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"PROPOSER\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"SUBMISSION_INTERVAL\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"addProposer\",\"inputs\":[{\"name\":\"_proposer\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"aggregationVkey\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"approvedProposers\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"challenger\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"checkpointBlockHash\",\"inputs\":[{\"name\":\"_blockNumber\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"computeL2Timestamp\",\"inputs\":[{\"name\":\"_l2BlockNumber\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"deleteL2Outputs\",\"inputs\":[{\"name\":\"_l2OutputIndex\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"finalizationPeriodSeconds\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getL2Output\",\"inputs\":[{\"name\":\"_l2OutputIndex\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structTypes.OutputProposal\",\"components\":[{\"name\":\"outputRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"timestamp\",\"type\":\"uint128\",\"internalType\":\"uint128\"},{\"name\":\"l2BlockNumber\",\"type\":\"uint128\",\"internalType\":\"uint128\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getL2OutputAfter\",\"inputs\":[{\"name\":\"_l2BlockNumber\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structTypes.OutputProposal\",\"components\":[{\"name\":\"outputRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"timestamp\",\"type\":\"uint128\",\"internalType\":\"uint128\"},{\"name\":\"l2BlockNumber\",\"type\":\"uint128\",\"internalType\":\"uint128\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getL2OutputIndexAfter\",\"inputs\":[{\"name\":\"_l2BlockNumber\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"historicBlockHashes\",\"inputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"_initParams\",\"type\":\"tuple\",\"internalType\":\"structOPSuccinctL2OutputOracle.InitParams\",\"components\":[{\"name\":\"challenger\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"proposer\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"finalizationPeriodSeconds\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"l2BlockTime\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"aggregationVkey\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"rangeVkeyCommitment\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"rollupConfigHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"startingOutputRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"startingBlockNumber\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"startingTimestamp\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"submissionInterval\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"verifier\",\"type\":\"address\",\"internalType\":\"address\"}]}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"l2BlockTime\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"latestBlockNumber\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"latestOutputIndex\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"nextBlockNumber\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"nextOutputIndex\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"owner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"proposeL2Output\",\"inputs\":[{\"name\":\"_outputRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"_l2BlockNumber\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_l1BlockNumber\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"proposer\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"rangeVkeyCommitment\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"removeProposer\",\"inputs\":[{\"name\":\"_proposer\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"rollupConfigHash\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"startingBlockNumber\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"startingTimestamp\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"submissionInterval\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"_owner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"updateAggregationVkey\",\"inputs\":[{\"name\":\"_aggregationVkey\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"updateRangeVkeyCommitment\",\"inputs\":[{\"name\":\"_rangeVkeyCommitment\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"updateRollupConfigHash\",\"inputs\":[{\"name\":\"_rollupConfigHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"updateSubmissionInterval\",\"inputs\":[{\"name\":\"_submissionInterval\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"updateVerifier\",\"inputs\":[{\"name\":\"_verifier\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"verifier\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"AggregationVkeyUpdated\",\"inputs\":[{\"name\":\"oldAggregationVkey\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"newAggregationVkey\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OutputProposed\",\"inputs\":[{\"name\":\"outputRoot\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"l2OutputIndex\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"l2BlockNumber\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"l1Timestamp\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OutputsDeleted\",\"inputs\":[{\"name\":\"prevNextOutputIndex\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"newNextOutputIndex\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferred\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ProposerUpdated\",\"inputs\":[{\"name\":\"proposer\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"added\",\"type\":\"bool\",\"indexed\":false,\"internalType\":\"bool\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RangeVkeyCommitmentUpdated\",\"inputs\":[{\"name\":\"oldRangeVkeyCommitment\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"newRangeVkeyCommitment\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RollupConfigHashUpdated\",\"inputs\":[{\"name\":\"oldRollupConfigHash\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"newRollupConfigHash\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"SubmissionIntervalUpdated\",\"inputs\":[{\"name\":\"oldSubmissionInterval\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"newSubmissionInterval\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"VerifierUpdated\",\"inputs\":[{\"name\":\"oldVerifier\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newVerifier\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"L1BlockHashNotAvailable\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1BlockHashNotCheckpointed\",\"inputs\":[]}]", - Bin: "0x608060405234801561001057600080fd5b5061001961001e565b6100de565b600054610100900460ff161561008a5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff90811610156100dc576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b611c57806100ed6000396000f3fe60806040526004361061023a5760003560e01c806393991af31161012e578063c4cb03ec116100ab578063db1470f51161006f578063db1470f5146106be578063dcec3348146106de578063e1a41bcf146106f3578063f2fde38b14610709578063f4daa2911461072957600080fd5b8063c4cb03ec14610608578063ce5db8d614610628578063cf8e5cf01461063e578063d1de856c1461065e578063d46512761461067e57600080fd5b8063a8e4fb90116100f2578063a8e4fb9014610574578063b03cd41814610594578063bc91ce33146105b4578063bffa7f0f146105d4578063c32e4e3e146105f257600080fd5b806393991af3146104ab57806397fc007c146104c15780639ad84880146104e1578063a196b525146104f4578063a25ae5571461052157600080fd5b806354fd4d50116101bc57806370872aa51161018057806370872aa51461041f5780637f00642014610435578063887862721461045557806389c44cbb1461046b5780638da5cb5b1461048b57600080fd5b806354fd4d501461037d57806369f16eec146103c15780636abcf563146103d65780636b4d98dd146103eb5780636d9a1c8b1461040957600080fd5b80632b7ac3f3116102035780632b7ac3f3146102db578063336c9e81146103135780634599c78814610333578063529933df14610348578063534db0e21461035d57600080fd5b80622134cc1461023f57806309d632d3146102635780631bdd450c146102855780631e856800146102a55780632b31841e146102c5575b600080fd5b34801561024b57600080fd5b506005545b6040519081526020015b60405180910390f35b34801561026f57600080fd5b5061028361027e366004611888565b61073e565b005b34801561029157600080fd5b506102836102a03660046118aa565b6107c7565b3480156102b157600080fd5b506102836102c03660046118aa565b610825565b3480156102d157600080fd5b50610250600a5481565b3480156102e757600080fd5b50600b546102fb906001600160a01b031681565b6040516001600160a01b03909116815260200161025a565b34801561031f57600080fd5b5061028361032e3660046118aa565b610857565b34801561033f57600080fd5b506102506108c2565b34801561035457600080fd5b50600454610250565b34801561036957600080fd5b506006546102fb906001600160a01b031681565b34801561038957600080fd5b506103b46040518060400160405280600b81526020016a0626574612d76302e342e360ac1b81525081565b60405161025a9190611910565b3480156103cd57600080fd5b5061025061091f565b3480156103e257600080fd5b50600354610250565b3480156103f757600080fd5b506006546001600160a01b03166102fb565b34801561041557600080fd5b50610250600c5481565b34801561042b57600080fd5b5061025060015481565b34801561044157600080fd5b506102506104503660046118aa565b610931565b34801561046157600080fd5b5061025060025481565b34801561047757600080fd5b506102836104863660046118aa565b610acf565b34801561049757600080fd5b50600d546102fb906001600160a01b031681565b3480156104b757600080fd5b5061025060055481565b3480156104cd57600080fd5b506102836104dc366004611888565b610cd4565b6102836104ef366004611994565b610d5a565b34801561050057600080fd5b5061025061050f3660046118aa565b600f6020526000908152604090205481565b34801561052d57600080fd5b5061054161053c3660046118aa565b6111cc565b60408051825181526020808401516001600160801b0390811691830191909152928201519092169082015260600161025a565b34801561058057600080fd5b506007546102fb906001600160a01b031681565b3480156105a057600080fd5b506102836105af366004611888565b61124a565b3480156105c057600080fd5b506102836105cf3660046118aa565b6112cb565b3480156105e057600080fd5b506007546001600160a01b03166102fb565b3480156105fe57600080fd5b5061025060095481565b34801561061457600080fd5b506102836106233660046118aa565b611329565b34801561063457600080fd5b5061025060085481565b34801561064a57600080fd5b506105416106593660046118aa565b611387565b34801561066a57600080fd5b506102506106793660046118aa565b6113bf565b34801561068a57600080fd5b506106ae610699366004611888565b600e6020526000908152604090205460ff1681565b604051901515815260200161025a565b3480156106ca57600080fd5b506102836106d9366004611a46565b6113ef565b3480156106ea57600080fd5b506102506117cf565b3480156106ff57600080fd5b5061025060045481565b34801561071557600080fd5b50610283610724366004611888565b6117e6565b34801561073557600080fd5b50600854610250565b600d546001600160a01b031633146107715760405162461bcd60e51b815260040161076890611b09565b60405180910390fd5b6001600160a01b0381166000818152600e60209081526040808320805460ff19169055519182527f5df38d395edc15b669d646569bd015513395070b5b4deb8a16300abb060d1b5a91015b60405180910390a250565b600d546001600160a01b031633146107f15760405162461bcd60e51b815260040161076890611b09565b600c546040518291907f5d9ebe9f09b0810b3546b30781ba9a51092b37dd6abada4b830ce54a41ac6a4b90600090a3600c55565b804080610845576040516321301a1960e21b815260040160405180910390fd5b6000918252600f602052604090912055565b600d546001600160a01b031633146108815760405162461bcd60e51b815260040161076890611b09565b60045460408051918252602082018390527fc1bf9abfb57ea01ed9ecb4f45e9cefa7ba44b2e6778c3ce7281409999f1af1b2910160405180910390a1600455565b6003546000901561091657600380546108dd90600190611b66565b815481106108ed576108ed611b7d565b6000918252602090912060029091020160010154600160801b90046001600160801b0316919050565b6001545b905090565b60035460009061091a90600190611b66565b600061093b6108c2565b8211156109c15760405162461bcd60e51b815260206004820152604860248201527f4c324f75747075744f7261636c653a2063616e6e6f7420676574206f7574707560448201527f7420666f72206120626c6f636b207468617420686173206e6f74206265656e206064820152671c1c9bdc1bdcd95960c21b608482015260a401610768565b600354610a455760405162461bcd60e51b815260206004820152604660248201527f4c324f75747075744f7261636c653a2063616e6e6f7420676574206f7574707560448201527f74206173206e6f206f7574707574732068617665206265656e2070726f706f736064820152651959081e595d60d21b608482015260a401610768565b6003546000905b80821015610ac85760006002610a628385611b93565b610a6c9190611bab565b90508460038281548110610a8257610a82611b7d565b6000918252602090912060029091020160010154600160801b90046001600160801b03161015610abe57610ab7816001611b93565b9250610ac2565b8091505b50610a4c565b5092915050565b6006546001600160a01b03163314610b4f5760405162461bcd60e51b815260206004820152603e60248201527f4c324f75747075744f7261636c653a206f6e6c7920746865206368616c6c656e60448201527f67657220616464726573732063616e2064656c657465206f75747075747300006064820152608401610768565b6003548110610bd25760405162461bcd60e51b815260206004820152604360248201527f4c324f75747075744f7261636c653a2063616e6e6f742064656c657465206f7560448201527f747075747320616674657220746865206c6174657374206f757470757420696e6064820152620c8caf60eb1b608482015260a401610768565b60085460038281548110610be857610be8611b7d565b6000918252602090912060016002909202010154610c0f906001600160801b031642611b66565b10610c915760405162461bcd60e51b815260206004820152604660248201527f4c324f75747075744f7261636c653a2063616e6e6f742064656c657465206f7560448201527f74707574732074686174206861766520616c7265616479206265656e2066696e606482015265185b1a5e995960d21b608482015260a401610768565b6000610c9c60035490565b90508160035581817f4ee37ac2c786ec85e87592d3c5c8a1dd66f8496dda3f125d9ea8ca5f657629b660405160405180910390a35050565b600d546001600160a01b03163314610cfe5760405162461bcd60e51b815260040161076890611b09565b600b546040516001600160a01b038084169216907f0243549a92b2412f7a3caf7a2e56d65b8821b91345363faa5f57195384065fcc90600090a3600b80546001600160a01b0319166001600160a01b0392909216919091179055565b336000908152600e602052604090205460ff1680610da2575060008052600e6020527fe710864318d4a32f37d6ce54cb3fadbef648dd12d8dbdf53973564d56b7f881c5460ff165b610e145760405162461bcd60e51b815260206004820152603f60248201527f4c324f75747075744f7261636c653a206f6e6c7920617070726f76656420707260448201527f6f706f736572732063616e2070726f706f7365206e6577206f757470757473006064820152608401610768565b610e1c6117cf565b831015610eb75760405162461bcd60e51b815260206004820152605860248201527f4c324f75747075744f7261636c653a20626c6f636b206e756d626572206d757360448201527f742062652067726561746572207468616e206f7220657175616c20746f206e6560648201527f787420657870656374656420626c6f636b206e756d6265720000000000000000608482015260a401610768565b42610ec1846113bf565b10610f2d5760405162461bcd60e51b815260206004820152603660248201527f4c324f75747075744f7261636c653a2063616e6e6f742070726f706f7365204c60448201527532206f757470757420696e207468652066757475726560501b6064820152608401610768565b83610fa05760405162461bcd60e51b815260206004820152603a60248201527f4c324f75747075744f7261636c653a204c32206f75747075742070726f706f7360448201527f616c2063616e6e6f7420626520746865207a65726f20686173680000000000006064820152608401610768565b6000828152600f602052604090205480610fcd57604051630455475360e31b815260040160405180910390fd5b60006040518060c001604052808381526020016003610fea61091f565b81548110610ffa57610ffa611b7d565b60009182526020918290206002909102015482528181018990526040808301899052600c54606080850191909152600a54608094850152600b5460095483518751818701529487015185850152928601518483015290850151838501529284015160a08084019190915284015160c08301529293506001600160a01b03909116916341493c609160e001604051602081830303815290604052866040518463ffffffff1660e01b81526004016110b293929190611bcd565b60006040518083038186803b1580156110ca57600080fd5b505afa1580156110de573d6000803e3d6000fd5b50505050846110ec60035490565b877fa7aaf2512769da4e444e3de247be2564225c2e7a8f74cfe528e46e17d24868e24260405161111e91815260200190565b60405180910390a45050604080516060810182529485526001600160801b034281166020870190815294811691860191825260038054600181018255600091909152955160029096027fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b810196909655935190518416600160801b029316929092177fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85c909301929092555050565b6040805160608101825260008082526020820181905291810191909152600382815481106111fc576111fc611b7d565b600091825260209182902060408051606081018252600290930290910180548352600101546001600160801b0380821694840194909452600160801b90049092169181019190915292915050565b600d546001600160a01b031633146112745760405162461bcd60e51b815260040161076890611b09565b6001600160a01b0381166000818152600e6020908152604091829020805460ff1916600190811790915591519182527f5df38d395edc15b669d646569bd015513395070b5b4deb8a16300abb060d1b5a91016107bc565b600d546001600160a01b031633146112f55760405162461bcd60e51b815260040161076890611b09565b600a546040518291907fbf8cab6317796bfa97fea82b6d27c9542a08fa0821813cf2a57e7cff7fdc815690600090a3600a55565b600d546001600160a01b031633146113535760405162461bcd60e51b815260040161076890611b09565b6009546040518291907f390b73b2b067afcef04d30b573e4590c6e565519e370927dd777ca0ce8a55db090600090a3600955565b604080516060810182526000808252602082018190529181019190915260036113af83610931565b815481106111fc576111fc611b7d565b6000600554600154836113d29190611b66565b6113dc9190611c02565b6002546113e99190611b93565b92915050565b600054610100900460ff161580801561140f5750600054600160ff909116105b806114295750303b158015611429575060005460ff166001145b61148c5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610768565b6000805460ff1916600117905580156114af576000805461ff0019166101001790555b60008261016001511161152a5760405162461bcd60e51b815260206004820152603a60248201527f4c324f75747075744f7261636c653a207375626d697373696f6e20696e74657260448201527f76616c206d7573742062652067726561746572207468616e20300000000000006064820152608401610768565b600082608001511161159b5760405162461bcd60e51b815260206004820152603460248201527f4c324f75747075744f7261636c653a204c3220626c6f636b2074696d65206d75604482015273073742062652067726561746572207468616e20360641b6064820152608401610768565b4282610140015111156116245760405162461bcd60e51b8152602060048201526044602482018190527f4c324f75747075744f7261636c653a207374617274696e67204c322074696d65908201527f7374616d70206d757374206265206c657373207468616e2063757272656e742060648201526374696d6560e01b608482015260a401610768565b61016082015160045560808201516005556003546000036116fb57604080516060810182526101008401518152610140840180516001600160801b03908116602084019081526101208701805183169585019586526003805460018181018355600092909252955160029687027fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b810191909155925196518416600160801b0296909316959095177fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85c909101559251909255905190555b8151600680546001600160a01b039283166001600160a01b031991821617909155606084015160085560208085015183166000908152600e909152604090819020805460ff1916600117905560a085015160095560c0850151600a55610180850151600b805491851691841691909117905560e0850151600c55840151600d805491909316911617905580156117cb576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b60006004546117dc6108c2565b61091a9190611b93565b600d546001600160a01b031633146118105760405162461bcd60e51b815260040161076890611b09565b600d546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600d80546001600160a01b0319166001600160a01b0392909216919091179055565b80356001600160a01b038116811461188357600080fd5b919050565b60006020828403121561189a57600080fd5b6118a38261186c565b9392505050565b6000602082840312156118bc57600080fd5b5035919050565b6000815180845260005b818110156118e9576020818501810151868301820152016118cd565b818111156118fb576000602083870101525b50601f01601f19169290920160200192915050565b6020815260006118a360208301846118c3565b634e487b7160e01b600052604160045260246000fd5b6040516101a0810167ffffffffffffffff8111828210171561195d5761195d611923565b60405290565b604051601f8201601f1916810167ffffffffffffffff8111828210171561198c5761198c611923565b604052919050565b600080600080608085870312156119aa57600080fd5b84359350602080860135935060408601359250606086013567ffffffffffffffff808211156119d857600080fd5b818801915088601f8301126119ec57600080fd5b8135818111156119fe576119fe611923565b611a10601f8201601f19168501611963565b91508082528984828501011115611a2657600080fd5b808484018584013760008482840101525080935050505092959194509250565b60006101a08284031215611a5957600080fd5b611a61611939565b611a6a8361186c565b8152611a786020840161186c565b6020820152611a896040840161186c565b6040820152606083013560608201526080830135608082015260a083013560a082015260c083013560c082015260e083013560e0820152610100808401358183015250610120808401358183015250610140808401358183015250610160808401358183015250610180611afe81850161186c565b908201529392505050565b60208082526027908201527f4c324f75747075744f7261636c653a2063616c6c6572206973206e6f74207468604082015266329037bbb732b960c91b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b600082821015611b7857611b78611b50565b500390565b634e487b7160e01b600052603260045260246000fd5b60008219821115611ba657611ba6611b50565b500190565b600082611bc857634e487b7160e01b600052601260045260246000fd5b500490565b838152606060208201526000611be660608301856118c3565b8281036040840152611bf881856118c3565b9695505050505050565b6000816000190483118215151615611c1c57611c1c611b50565b50029056fea264697066735822122017b7a0f745d54c124937ede48b12c01b01c1385bea76e9816bd47dbb830539d464736f6c634300080f0033", + ABI: "[{\"type\":\"constructor\",\"inputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"CHALLENGER\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"FINALIZATION_PERIOD_SECONDS\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"L2_BLOCK_TIME\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"PROPOSER\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"SUBMISSION_INTERVAL\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"addProposer\",\"inputs\":[{\"name\":\"_proposer\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"aggregationVkey\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"approvedProposers\",\"inputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"challenger\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"checkpointBlockHash\",\"inputs\":[{\"name\":\"_blockNumber\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"computeL2Timestamp\",\"inputs\":[{\"name\":\"_l2BlockNumber\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"deleteL2Outputs\",\"inputs\":[{\"name\":\"_l2OutputIndex\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"finalizationPeriodSeconds\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getL2Output\",\"inputs\":[{\"name\":\"_l2OutputIndex\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structTypes.OutputProposal\",\"components\":[{\"name\":\"outputRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"timestamp\",\"type\":\"uint128\",\"internalType\":\"uint128\"},{\"name\":\"l2BlockNumber\",\"type\":\"uint128\",\"internalType\":\"uint128\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getL2OutputAfter\",\"inputs\":[{\"name\":\"_l2BlockNumber\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structTypes.OutputProposal\",\"components\":[{\"name\":\"outputRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"timestamp\",\"type\":\"uint128\",\"internalType\":\"uint128\"},{\"name\":\"l2BlockNumber\",\"type\":\"uint128\",\"internalType\":\"uint128\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getL2OutputIndexAfter\",\"inputs\":[{\"name\":\"_l2BlockNumber\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"historicBlockHashes\",\"inputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"_initParams\",\"type\":\"tuple\",\"internalType\":\"structOPSuccinctL2OutputOracle.InitParams\",\"components\":[{\"name\":\"challenger\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"proposer\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"finalizationPeriodSeconds\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"l2BlockTime\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"aggregationVkey\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"rangeVkeyCommitment\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"rollupConfigHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"startingOutputRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"startingBlockNumber\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"startingTimestamp\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"submissionInterval\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"verifier\",\"type\":\"address\",\"internalType\":\"address\"}]}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"initializerVersion\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint8\",\"internalType\":\"uint8\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"l2BlockTime\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"latestBlockNumber\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"latestOutputIndex\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"nextBlockNumber\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"nextOutputIndex\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"owner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"proposeL2Output\",\"inputs\":[{\"name\":\"_outputRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"_l2BlockNumber\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_l1BlockNumber\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"_proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"proposer\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"rangeVkeyCommitment\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"removeProposer\",\"inputs\":[{\"name\":\"_proposer\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"rollupConfigHash\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"startingBlockNumber\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"startingTimestamp\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"submissionInterval\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"_owner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"updateAggregationVkey\",\"inputs\":[{\"name\":\"_aggregationVkey\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"updateRangeVkeyCommitment\",\"inputs\":[{\"name\":\"_rangeVkeyCommitment\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"updateRollupConfigHash\",\"inputs\":[{\"name\":\"_rollupConfigHash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"updateSubmissionInterval\",\"inputs\":[{\"name\":\"_submissionInterval\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"updateVerifier\",\"inputs\":[{\"name\":\"_verifier\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"verifier\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"AggregationVkeyUpdated\",\"inputs\":[{\"name\":\"oldAggregationVkey\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"newAggregationVkey\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OutputProposed\",\"inputs\":[{\"name\":\"outputRoot\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"l2OutputIndex\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"l2BlockNumber\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"l1Timestamp\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OutputsDeleted\",\"inputs\":[{\"name\":\"prevNextOutputIndex\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"},{\"name\":\"newNextOutputIndex\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferred\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ProposerUpdated\",\"inputs\":[{\"name\":\"proposer\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"added\",\"type\":\"bool\",\"indexed\":false,\"internalType\":\"bool\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RangeVkeyCommitmentUpdated\",\"inputs\":[{\"name\":\"oldRangeVkeyCommitment\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"newRangeVkeyCommitment\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"RollupConfigHashUpdated\",\"inputs\":[{\"name\":\"oldRollupConfigHash\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"newRollupConfigHash\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"SubmissionIntervalUpdated\",\"inputs\":[{\"name\":\"oldSubmissionInterval\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"newSubmissionInterval\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"VerifierUpdated\",\"inputs\":[{\"name\":\"oldVerifier\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newVerifier\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"L1BlockHashNotAvailable\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"L1BlockHashNotCheckpointed\",\"inputs\":[]}]", + Bin: "0x608060405234801561001057600080fd5b5061001961001e565b6100de565b600054610100900460ff161561008a5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff90811610156100dc576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b611c57806100ed6000396000f3fe6080604052600436106102455760003560e01c80638da5cb5b11610139578063c32e4e3e116100b6578063d46512761161007a578063d4651276146106b0578063db1470f5146106f0578063dcec334814610710578063e1a41bcf14610725578063f2fde38b1461073b578063f4daa2911461075b57600080fd5b8063c32e4e3e14610624578063c4cb03ec1461063a578063ce5db8d61461065a578063cf8e5cf014610670578063d1de856c1461069057600080fd5b8063a25ae557116100fd578063a25ae55714610553578063a8e4fb90146105a6578063b03cd418146105c6578063bc91ce33146105e6578063bffa7f0f1461060657600080fd5b80638da5cb5b146104bd57806393991af3146104dd57806397fc007c146104f35780639ad8488014610513578063a196b5251461052657600080fd5b806354fd4d50116101c757806370872aa51161018b57806370872aa51461042a5780637f006420146104405780637f01ea6814610460578063887862721461048757806389c44cbb1461049d57600080fd5b806354fd4d501461038857806369f16eec146103cc5780636abcf563146103e15780636b4d98dd146103f65780636d9a1c8b1461041457600080fd5b80632b7ac3f31161020e5780632b7ac3f3146102e6578063336c9e811461031e5780634599c7881461033e578063529933df14610353578063534db0e21461036857600080fd5b80622134cc1461024a57806309d632d31461026e5780631bdd450c146102905780631e856800146102b05780632b31841e146102d0575b600080fd5b34801561025657600080fd5b506005545b6040519081526020015b60405180910390f35b34801561027a57600080fd5b5061028e610289366004611888565b610770565b005b34801561029c57600080fd5b5061028e6102ab3660046118aa565b6107f9565b3480156102bc57600080fd5b5061028e6102cb3660046118aa565b610857565b3480156102dc57600080fd5b5061025b600a5481565b3480156102f257600080fd5b50600b54610306906001600160a01b031681565b6040516001600160a01b039091168152602001610265565b34801561032a57600080fd5b5061028e6103393660046118aa565b610889565b34801561034a57600080fd5b5061025b6108f4565b34801561035f57600080fd5b5060045461025b565b34801561037457600080fd5b50600654610306906001600160a01b031681565b34801561039457600080fd5b506103bf6040518060400160405280600b81526020016a0626574612d76312e302e360ac1b81525081565b6040516102659190611910565b3480156103d857600080fd5b5061025b610951565b3480156103ed57600080fd5b5060035461025b565b34801561040257600080fd5b506006546001600160a01b0316610306565b34801561042057600080fd5b5061025b600c5481565b34801561043657600080fd5b5061025b60015481565b34801561044c57600080fd5b5061025b61045b3660046118aa565b610963565b34801561046c57600080fd5b50610475600181565b60405160ff9091168152602001610265565b34801561049357600080fd5b5061025b60025481565b3480156104a957600080fd5b5061028e6104b83660046118aa565b610b01565b3480156104c957600080fd5b50600d54610306906001600160a01b031681565b3480156104e957600080fd5b5061025b60055481565b3480156104ff57600080fd5b5061028e61050e366004611888565b610d06565b61028e610521366004611994565b610d8c565b34801561053257600080fd5b5061025b6105413660046118aa565b600f6020526000908152604090205481565b34801561055f57600080fd5b5061057361056e3660046118aa565b6111fe565b60408051825181526020808401516001600160801b03908116918301919091529282015190921690820152606001610265565b3480156105b257600080fd5b50600754610306906001600160a01b031681565b3480156105d257600080fd5b5061028e6105e1366004611888565b61127c565b3480156105f257600080fd5b5061028e6106013660046118aa565b6112fd565b34801561061257600080fd5b506007546001600160a01b0316610306565b34801561063057600080fd5b5061025b60095481565b34801561064657600080fd5b5061028e6106553660046118aa565b61135b565b34801561066657600080fd5b5061025b60085481565b34801561067c57600080fd5b5061057361068b3660046118aa565b6113b9565b34801561069c57600080fd5b5061025b6106ab3660046118aa565b6113f1565b3480156106bc57600080fd5b506106e06106cb366004611888565b600e6020526000908152604090205460ff1681565b6040519015158152602001610265565b3480156106fc57600080fd5b5061028e61070b366004611a46565b611421565b34801561071c57600080fd5b5061025b6117cf565b34801561073157600080fd5b5061025b60045481565b34801561074757600080fd5b5061028e610756366004611888565b6117e6565b34801561076757600080fd5b5060085461025b565b600d546001600160a01b031633146107a35760405162461bcd60e51b815260040161079a90611b09565b60405180910390fd5b6001600160a01b0381166000818152600e60209081526040808320805460ff19169055519182527f5df38d395edc15b669d646569bd015513395070b5b4deb8a16300abb060d1b5a91015b60405180910390a250565b600d546001600160a01b031633146108235760405162461bcd60e51b815260040161079a90611b09565b600c546040518291907f5d9ebe9f09b0810b3546b30781ba9a51092b37dd6abada4b830ce54a41ac6a4b90600090a3600c55565b804080610877576040516321301a1960e21b815260040160405180910390fd5b6000918252600f602052604090912055565b600d546001600160a01b031633146108b35760405162461bcd60e51b815260040161079a90611b09565b60045460408051918252602082018390527fc1bf9abfb57ea01ed9ecb4f45e9cefa7ba44b2e6778c3ce7281409999f1af1b2910160405180910390a1600455565b60035460009015610948576003805461090f90600190611b66565b8154811061091f5761091f611b7d565b6000918252602090912060029091020160010154600160801b90046001600160801b0316919050565b6001545b905090565b60035460009061094c90600190611b66565b600061096d6108f4565b8211156109f35760405162461bcd60e51b815260206004820152604860248201527f4c324f75747075744f7261636c653a2063616e6e6f7420676574206f7574707560448201527f7420666f72206120626c6f636b207468617420686173206e6f74206265656e206064820152671c1c9bdc1bdcd95960c21b608482015260a40161079a565b600354610a775760405162461bcd60e51b815260206004820152604660248201527f4c324f75747075744f7261636c653a2063616e6e6f7420676574206f7574707560448201527f74206173206e6f206f7574707574732068617665206265656e2070726f706f736064820152651959081e595d60d21b608482015260a40161079a565b6003546000905b80821015610afa5760006002610a948385611b93565b610a9e9190611bab565b90508460038281548110610ab457610ab4611b7d565b6000918252602090912060029091020160010154600160801b90046001600160801b03161015610af057610ae9816001611b93565b9250610af4565b8091505b50610a7e565b5092915050565b6006546001600160a01b03163314610b815760405162461bcd60e51b815260206004820152603e60248201527f4c324f75747075744f7261636c653a206f6e6c7920746865206368616c6c656e60448201527f67657220616464726573732063616e2064656c657465206f7574707574730000606482015260840161079a565b6003548110610c045760405162461bcd60e51b815260206004820152604360248201527f4c324f75747075744f7261636c653a2063616e6e6f742064656c657465206f7560448201527f747075747320616674657220746865206c6174657374206f757470757420696e6064820152620c8caf60eb1b608482015260a40161079a565b60085460038281548110610c1a57610c1a611b7d565b6000918252602090912060016002909202010154610c41906001600160801b031642611b66565b10610cc35760405162461bcd60e51b815260206004820152604660248201527f4c324f75747075744f7261636c653a2063616e6e6f742064656c657465206f7560448201527f74707574732074686174206861766520616c7265616479206265656e2066696e606482015265185b1a5e995960d21b608482015260a40161079a565b6000610cce60035490565b90508160035581817f4ee37ac2c786ec85e87592d3c5c8a1dd66f8496dda3f125d9ea8ca5f657629b660405160405180910390a35050565b600d546001600160a01b03163314610d305760405162461bcd60e51b815260040161079a90611b09565b600b546040516001600160a01b038084169216907f0243549a92b2412f7a3caf7a2e56d65b8821b91345363faa5f57195384065fcc90600090a3600b80546001600160a01b0319166001600160a01b0392909216919091179055565b336000908152600e602052604090205460ff1680610dd4575060008052600e6020527fe710864318d4a32f37d6ce54cb3fadbef648dd12d8dbdf53973564d56b7f881c5460ff165b610e465760405162461bcd60e51b815260206004820152603f60248201527f4c324f75747075744f7261636c653a206f6e6c7920617070726f76656420707260448201527f6f706f736572732063616e2070726f706f7365206e6577206f75747075747300606482015260840161079a565b610e4e6117cf565b831015610ee95760405162461bcd60e51b815260206004820152605860248201527f4c324f75747075744f7261636c653a20626c6f636b206e756d626572206d757360448201527f742062652067726561746572207468616e206f7220657175616c20746f206e6560648201527f787420657870656374656420626c6f636b206e756d6265720000000000000000608482015260a40161079a565b42610ef3846113f1565b10610f5f5760405162461bcd60e51b815260206004820152603660248201527f4c324f75747075744f7261636c653a2063616e6e6f742070726f706f7365204c60448201527532206f757470757420696e207468652066757475726560501b606482015260840161079a565b83610fd25760405162461bcd60e51b815260206004820152603a60248201527f4c324f75747075744f7261636c653a204c32206f75747075742070726f706f7360448201527f616c2063616e6e6f7420626520746865207a65726f2068617368000000000000606482015260840161079a565b6000828152600f602052604090205480610fff57604051630455475360e31b815260040160405180910390fd5b60006040518060c00160405280838152602001600361101c610951565b8154811061102c5761102c611b7d565b60009182526020918290206002909102015482528181018990526040808301899052600c54606080850191909152600a54608094850152600b5460095483518751818701529487015185850152928601518483015290850151838501529284015160a08084019190915284015160c08301529293506001600160a01b03909116916341493c609160e001604051602081830303815290604052866040518463ffffffff1660e01b81526004016110e493929190611bcd565b60006040518083038186803b1580156110fc57600080fd5b505afa158015611110573d6000803e3d6000fd5b505050508461111e60035490565b877fa7aaf2512769da4e444e3de247be2564225c2e7a8f74cfe528e46e17d24868e24260405161115091815260200190565b60405180910390a45050604080516060810182529485526001600160801b034281166020870190815294811691860191825260038054600181018255600091909152955160029096027fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b810196909655935190518416600160801b029316929092177fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85c909301929092555050565b60408051606081018252600080825260208201819052918101919091526003828154811061122e5761122e611b7d565b600091825260209182902060408051606081018252600290930290910180548352600101546001600160801b0380821694840194909452600160801b90049092169181019190915292915050565b600d546001600160a01b031633146112a65760405162461bcd60e51b815260040161079a90611b09565b6001600160a01b0381166000818152600e6020908152604091829020805460ff1916600190811790915591519182527f5df38d395edc15b669d646569bd015513395070b5b4deb8a16300abb060d1b5a91016107ee565b600d546001600160a01b031633146113275760405162461bcd60e51b815260040161079a90611b09565b600a546040518291907fbf8cab6317796bfa97fea82b6d27c9542a08fa0821813cf2a57e7cff7fdc815690600090a3600a55565b600d546001600160a01b031633146113855760405162461bcd60e51b815260040161079a90611b09565b6009546040518291907f390b73b2b067afcef04d30b573e4590c6e565519e370927dd777ca0ce8a55db090600090a3600955565b604080516060810182526000808252602082018190529181019190915260036113e183610963565b8154811061122e5761122e611b7d565b6000600554600154836114049190611b66565b61140e9190611c02565b60025461141b9190611b93565b92915050565b600054600190610100900460ff16158015611443575060005460ff8083169116105b6114a65760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840161079a565b6000805461ffff191660ff8316176101001790556101608201516115325760405162461bcd60e51b815260206004820152603a60248201527f4c324f75747075744f7261636c653a207375626d697373696f6e20696e74657260448201527f76616c206d7573742062652067726561746572207468616e2030000000000000606482015260840161079a565b60008260800151116115a35760405162461bcd60e51b815260206004820152603460248201527f4c324f75747075744f7261636c653a204c3220626c6f636b2074696d65206d75604482015273073742062652067726561746572207468616e20360641b606482015260840161079a565b42826101400151111561162c5760405162461bcd60e51b8152602060048201526044602482018190527f4c324f75747075744f7261636c653a207374617274696e67204c322074696d65908201527f7374616d70206d757374206265206c657373207468616e2063757272656e742060648201526374696d6560e01b608482015260a40161079a565b610160820151600455608082015160055560035460000361170357604080516060810182526101008401518152610140840180516001600160801b03908116602084019081526101208701805183169585019586526003805460018181018355600092909252955160029687027fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b810191909155925196518416600160801b0296909316959095177fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85c909101559251909255905190555b8151600680546001600160a01b03199081166001600160a01b0393841617909155606084015160085560208085015183166000908152600e82526040808220805460ff1916600117905560a087015160095560c0870151600a55610180870151600b8054861691871691909117905560e0870151600c5580870151600d8054909516951694909417909255815461ff001916909155905160ff831681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498910160405180910390a15050565b60006004546117dc6108f4565b61094c9190611b93565b600d546001600160a01b031633146118105760405162461bcd60e51b815260040161079a90611b09565b600d546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600d80546001600160a01b0319166001600160a01b0392909216919091179055565b80356001600160a01b038116811461188357600080fd5b919050565b60006020828403121561189a57600080fd5b6118a38261186c565b9392505050565b6000602082840312156118bc57600080fd5b5035919050565b6000815180845260005b818110156118e9576020818501810151868301820152016118cd565b818111156118fb576000602083870101525b50601f01601f19169290920160200192915050565b6020815260006118a360208301846118c3565b634e487b7160e01b600052604160045260246000fd5b6040516101a0810167ffffffffffffffff8111828210171561195d5761195d611923565b60405290565b604051601f8201601f1916810167ffffffffffffffff8111828210171561198c5761198c611923565b604052919050565b600080600080608085870312156119aa57600080fd5b84359350602080860135935060408601359250606086013567ffffffffffffffff808211156119d857600080fd5b818801915088601f8301126119ec57600080fd5b8135818111156119fe576119fe611923565b611a10601f8201601f19168501611963565b91508082528984828501011115611a2657600080fd5b808484018584013760008482840101525080935050505092959194509250565b60006101a08284031215611a5957600080fd5b611a61611939565b611a6a8361186c565b8152611a786020840161186c565b6020820152611a896040840161186c565b6040820152606083013560608201526080830135608082015260a083013560a082015260c083013560c082015260e083013560e0820152610100808401358183015250610120808401358183015250610140808401358183015250610160808401358183015250610180611afe81850161186c565b908201529392505050565b60208082526027908201527f4c324f75747075744f7261636c653a2063616c6c6572206973206e6f74207468604082015266329037bbb732b960c91b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b600082821015611b7857611b78611b50565b500390565b634e487b7160e01b600052603260045260246000fd5b60008219821115611ba657611ba6611b50565b500190565b600082611bc857634e487b7160e01b600052601260045260246000fd5b500490565b838152606060208201526000611be660608301856118c3565b8281036040840152611bf881856118c3565b9695505050505050565b6000816000190483118215151615611c1c57611c1c611b50565b50029056fea2646970667358221220960a86e7fc8731a6278de5d7bf30cbec12bba95789c30f9d10a7cbc950c3179364736f6c634300080f0033", } // OPSuccinctL2OutputOracleABI is the input ABI used to generate the binding from. @@ -660,6 +660,37 @@ func (_OPSuccinctL2OutputOracle *OPSuccinctL2OutputOracleCallerSession) Historic return _OPSuccinctL2OutputOracle.Contract.HistoricBlockHashes(&_OPSuccinctL2OutputOracle.CallOpts, arg0) } +// InitializerVersion is a free data retrieval call binding the contract method 0x7f01ea68. +// +// Solidity: function initializerVersion() view returns(uint8) +func (_OPSuccinctL2OutputOracle *OPSuccinctL2OutputOracleCaller) InitializerVersion(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _OPSuccinctL2OutputOracle.contract.Call(opts, &out, "initializerVersion") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +// InitializerVersion is a free data retrieval call binding the contract method 0x7f01ea68. +// +// Solidity: function initializerVersion() view returns(uint8) +func (_OPSuccinctL2OutputOracle *OPSuccinctL2OutputOracleSession) InitializerVersion() (uint8, error) { + return _OPSuccinctL2OutputOracle.Contract.InitializerVersion(&_OPSuccinctL2OutputOracle.CallOpts) +} + +// InitializerVersion is a free data retrieval call binding the contract method 0x7f01ea68. +// +// Solidity: function initializerVersion() view returns(uint8) +func (_OPSuccinctL2OutputOracle *OPSuccinctL2OutputOracleCallerSession) InitializerVersion() (uint8, error) { + return _OPSuccinctL2OutputOracle.Contract.InitializerVersion(&_OPSuccinctL2OutputOracle.CallOpts) +} + // L2BlockTime is a free data retrieval call binding the contract method 0x93991af3. // // Solidity: function l2BlockTime() view returns(uint256) diff --git a/proposer/op/op_proposer.sh b/proposer/op/op_proposer.sh index 78be0a01..e560f90c 100644 --- a/proposer/op/op_proposer.sh +++ b/proposer/op/op_proposer.sh @@ -9,6 +9,7 @@ --poll-interval=${POLL_INTERVAL:-20s} \ --rollup-rpc=${L2_NODE_RPC} \ --l2oo-address=${L2OO_ADDRESS} \ + --dgf-address=${DGF_ADDRESS} \ --private-key=${PRIVATE_KEY} \ --l1-eth-rpc=${L1_RPC} \ --beacon-rpc=${L1_BEACON_RPC} \ diff --git a/proposer/op/proposer/config.go b/proposer/op/proposer/config.go index fac48485..ebe0abac 100644 --- a/proposer/op/proposer/config.go +++ b/proposer/op/proposer/config.go @@ -33,6 +33,9 @@ type CLIConfig struct { // L2OOAddress is the L2OutputOracle contract address. L2OOAddress string + // DGFAddress is the DisputeGameFactory contract address. + DGFAddress string + // PollInterval is the delay between querying L2 for more transaction // and creating a new batch. PollInterval time.Duration @@ -114,8 +117,8 @@ func (c *CLIConfig) Check() error { return err } - if c.L2OOAddress == "" { - return errors.New("the `L2OutputOracle` address was not provided") + if c.L2OOAddress == "" && c.DGFAddress == "" { + return errors.New("one of the `DisputeGameFactory` or `L2OutputOracle` address must be provided") } return nil @@ -142,6 +145,7 @@ func NewConfig(ctx *cli.Context) *CLIConfig { L1EthRpc: ctx.String(flags.L1EthRpcFlag.Name), RollupRpc: ctx.String(flags.RollupRpcFlag.Name), L2OOAddress: ctx.String(flags.L2OOAddressFlag.Name), + DGFAddress: ctx.String(flags.DGFAddressFlag.Name), PollInterval: ctx.Duration(flags.PollIntervalFlag.Name), TxMgrConfig: txmgr.ReadCLIConfig(ctx), BeaconRpc: ctx.String(flags.BeaconRpcFlag.Name), diff --git a/proposer/op/proposer/driver.go b/proposer/op/proposer/driver.go index e2757064..0fb1be53 100644 --- a/proposer/op/proposer/driver.go +++ b/proposer/op/proposer/driver.go @@ -91,6 +91,8 @@ type L2OutputSubmitter struct { l2ooContract L2OOContract l2ooABI *abi.ABI + dgfABI *abi.ABI + db db.ProofDB } @@ -129,7 +131,13 @@ func newL2OOSubmitter(ctx context.Context, cancel context.CancelFunc, setup Driv } log.Info("Connected to L2OutputOracle", "address", setup.Cfg.L2OutputOracleAddr, "version", version) - parsed, err := opsuccinctbindings.OPSuccinctL2OutputOracleMetaData.GetAbi() + l2ooAbiParsed, err := opsuccinctbindings.OPSuccinctL2OutputOracleMetaData.GetAbi() + if err != nil { + cancel() + return nil, err + } + + dfgAbiParsed, err := opsuccinctbindings.OPSuccinctDisputeGameFactoryMetaData.GetAbi() if err != nil { cancel() return nil, err @@ -148,8 +156,10 @@ func newL2OOSubmitter(ctx context.Context, cancel context.CancelFunc, setup Driv cancel: cancel, l2ooContract: l2ooContract, - l2ooABI: parsed, - db: *db, + l2ooABI: l2ooAbiParsed, + dgfABI: dfgAbiParsed, + + db: *db, }, nil } @@ -486,6 +496,15 @@ func proposeL2OutputTxData(abi *abi.ABI, output *eth.OutputResponse, proof []byt proof) } +func (l *L2OutputSubmitter) ProposeL2OutputDGFTxData(output *eth.OutputResponse, proof []byte, l1BlockNum uint64) ([]byte, error) { + return l.dgfABI.Pack( + "create", + output.OutputRoot, + new(big.Int).SetUint64(output.BlockRef.Number), + new(big.Int).SetUint64(l1BlockNum), + proof) +} + func (l *L2OutputSubmitter) CheckpointBlockHashTxData(blockNumber *big.Int) ([]byte, error) { return l.l2ooABI.Pack("checkpointBlockHash", blockNumber) } @@ -526,7 +545,19 @@ func (l *L2OutputSubmitter) sendTransaction(ctx context.Context, output *eth.Out l.Log.Info("Proposing output root", "output", output.OutputRoot, "block", output.BlockRef) var receipt *types.Receipt if l.Cfg.DisputeGameFactoryAddr != nil { - return errors.New("not implemented") + data, err := l.ProposeL2OutputDGFTxData(output, proof, l1BlockNum) + if err != nil { + return err + } + // TODO: This currently blocks the loop while it waits for the transaction to be confirmed. Up to 3 minutes. + receipt, err = l.Txmgr.Send(ctx, txmgr.TxCandidate{ + TxData: data, + To: l.Cfg.DisputeGameFactoryAddr, + GasLimit: 0, + }) + if err != nil { + return err + } } else { data, err := l.ProposeL2OutputTxData(output, proof, l1BlockNum) if err != nil { diff --git a/proposer/op/proposer/flags/flags.go b/proposer/op/proposer/flags/flags.go index f3223444..ea591acd 100644 --- a/proposer/op/proposer/flags/flags.go +++ b/proposer/op/proposer/flags/flags.go @@ -44,6 +44,11 @@ var ( Usage: "Address of the L2OutputOracle contract", EnvVars: prefixEnvVars("L2OO_ADDRESS"), } + DGFAddressFlag = &cli.StringFlag{ + Name: "dgf-address", + Usage: "Address of the DisputeGameFactory contract", + EnvVars: prefixEnvVars("DGF_ADDRESS"), + } PollIntervalFlag = &cli.DurationFlag{ Name: "poll-interval", Usage: "How frequently to poll L2 for new blocks (legacy L2OO)", @@ -159,6 +164,7 @@ var requiredFlags = []cli.Flag{ var optionalFlags = []cli.Flag{ L2OOAddressFlag, + DGFAddressFlag, PollIntervalFlag, AllowNonFinalizedFlag, L2OutputHDPathFlag, diff --git a/proposer/op/proposer/service.go b/proposer/op/proposer/service.go index 837cd784..1aea3ea8 100644 --- a/proposer/op/proposer/service.go +++ b/proposer/op/proposer/service.go @@ -135,6 +135,7 @@ func (ps *ProposerService) initFromCLIConfig(ctx context.Context, version string ps.Mock = cfg.Mock ps.initL2ooAddress(cfg) + ps.initDGF(cfg) if err := ps.initRPCClients(ctx, cfg); err != nil { return err @@ -252,6 +253,15 @@ func (ps *ProposerService) initL2ooAddress(cfg *CLIConfig) { ps.L2OutputOracleAddr = &l2ooAddress } +func (ps *ProposerService) initDGF(cfg *CLIConfig) { + dgfAddress, err := opservice.ParseAddress(cfg.DGFAddress) + if err != nil { + // Return no error & set no DGF related configuration fields. + return + } + ps.DisputeGameFactoryAddr = &dgfAddress +} + func (ps *ProposerService) initDriver() error { driver, err := NewL2OutputSubmitter(DriverSetup{ Log: ps.Log,