forked from OffchainLabs/orbit-actions
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: EigenDA v2.1.0 migration action
- Loading branch information
Showing
7 changed files
with
521 additions
and
2 deletions.
There are no files selected for viewing
193 changes: 193 additions & 0 deletions
193
contracts/parent-chain/contract-upgrades/NitroContractsEigenDA2Point1Point0UpgradeAction.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,193 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
pragma solidity 0.8.16; | ||
|
||
import "@eigenda/nitro-contracts-2.1.0/src/osp/IOneStepProofEntry.sol"; | ||
import "@eigenda/nitro-contracts-2.1.0/src/rollup/IRollupAdmin.sol"; | ||
import "@openzeppelin/contracts/utils/Address.sol"; | ||
import "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; | ||
|
||
/* | ||
EigendDA support: | ||
- modifies SequencerInbox and OneStepProverHostIO contracts | ||
- introduces a new RollupManager contract used for verification against the EigenDAServiceManager contract | ||
*/ | ||
|
||
interface IChallengeManagerUpgradeInit { | ||
function postUpgradeInit(IOneStepProofEntry osp_, bytes32 condRoot, IOneStepProofEntry condOsp) external; | ||
function osp() external returns (address); | ||
} | ||
interface ISeqInboxUpgradeInit { | ||
function executeUpgrade() external; | ||
} | ||
|
||
interface IChallengeManagerUpgradeHandler { | ||
function executeUpgrade(address _updatedOsp) external; | ||
function getOsp() external view returns (address); | ||
} | ||
|
||
interface IRollupUpgrade { | ||
function upgradeTo(address newImplementation) external; | ||
function upgradeSecondaryTo(address newImplementation) external; | ||
function anyTrustFastConfirmer() external returns (address); | ||
} | ||
|
||
/// @notice Upgrades an existing Arbitrum chain to using version 2.1.0 of EigenDA x Nitro contracts. | ||
contract NitroContractsEigenDA2Point1Point0UpgradeAction { | ||
address public immutable seqInboxImpl; | ||
address public immutable challengeMgrImpl; | ||
|
||
// Two OSP contracts are used to ensure cross compatibility | ||
// with previous bridge assertions using the PrevWASMRoot OSP contract | ||
// that haven't been finalized yet. | ||
|
||
// EigenDA v2.1.0 OSP contracts | ||
IOneStepProofEntry public immutable osp; | ||
bytes32 public immutable wasmModuleRoot; | ||
|
||
// Arbitrum v2.1.0 conditional OSP contracts | ||
IOneStepProofEntry public immutable condOsp; | ||
bytes32 public immutable condRoot; | ||
|
||
|
||
address public immutable rollupManager; | ||
address public immutable newRollupAdminLogic; | ||
address public immutable newRollupUserLogic; | ||
|
||
constructor( | ||
bytes32 _newWasmModuleRoot, | ||
address _newSequencerInboxImpl, | ||
address _newChallengeMangerImpl, | ||
IOneStepProofEntry _newOsp, | ||
IOneStepProofEntry _condOsp, | ||
bytes32 _condOspRoot, | ||
address _rollupManager, // eigenDA rollup manager contract | ||
address _newRollupAdminLogic, | ||
address _newRollupUserLogic | ||
) { | ||
|
||
require(_newWasmModuleRoot != bytes32(0), 'Invalid wasm root hash'); | ||
// wasmModuleRoot = _newWasmModuleRoot; | ||
|
||
require(Address.isContract(_newSequencerInboxImpl), 'Invalid Sequencer Inbox implementation'); | ||
seqInboxImpl = _newSequencerInboxImpl; | ||
|
||
require(Address.isContract(_newChallengeMangerImpl), 'Invalid Challenge Manager implementation'); | ||
challengeMgrImpl = _newChallengeMangerImpl; | ||
|
||
require(Address.isContract(address(_newOsp)), 'Invalid OSP contract'); | ||
osp = _newOsp; | ||
wasmModuleRoot = _newWasmModuleRoot; | ||
|
||
// require(Address.isContract(address(_condOsp)), 'Invalid conditional OSP contract'); | ||
condOsp = _condOsp; | ||
condRoot = _condOspRoot; | ||
|
||
|
||
require(Address.isContract(_rollupManager), 'Invalid EigenDA Rollup Manager contract'); | ||
rollupManager = _rollupManager; | ||
|
||
require( | ||
Address.isContract(_newRollupAdminLogic), | ||
"NitroContracts2Point1Point0UpgradeAction: _newRollupAdminLogic is not a contract" | ||
); | ||
|
||
newRollupAdminLogic = _newRollupAdminLogic; | ||
|
||
require( | ||
Address.isContract(_newRollupUserLogic), | ||
"NitroContracts2Point1Point0UpgradeAction: _newRollupUserLogic is not a contract" | ||
); | ||
|
||
newRollupUserLogic = _newRollupUserLogic; | ||
|
||
} | ||
|
||
function execute(IRollupCore rollup, ProxyAdmin adminProxy) public { | ||
|
||
IRollupAdmin(address(rollup)).setWasmModuleRoot(wasmModuleRoot); | ||
|
||
// Confirm the Wasm root updated successfully on the rollupAdmin contract | ||
require( | ||
rollup.wasmModuleRoot() == wasmModuleRoot, | ||
'Failed to update Wasm root' | ||
); | ||
|
||
// Upgrade the SequencerInbox and verify sufficient time variation: | ||
TransparentUpgradeableProxy sequencerInbox = TransparentUpgradeableProxy( | ||
payable(address(rollup.sequencerInbox())) | ||
); | ||
(, uint256 blocksBeforeUpgrade, , ) = ISequencerInbox( | ||
address(sequencerInbox) | ||
).maxTimeVariation(); | ||
adminProxy.upgrade(sequencerInbox, seqInboxImpl); | ||
|
||
// Validate the new Sequencer Inbox implementation: | ||
require( | ||
adminProxy.getProxyImplementation(sequencerInbox) == seqInboxImpl, | ||
'Sequencer Inbox upgrade failed' | ||
); | ||
|
||
(, uint256 blocksAfterUpgrade, , ) = ISequencerInbox(address(sequencerInbox)) | ||
.maxTimeVariation(); | ||
|
||
require( | ||
blocksBeforeUpgrade != 0 && blocksBeforeUpgrade == blocksAfterUpgrade, | ||
'Time variation mismatch' | ||
); | ||
|
||
// Ensure that rollup manager contract is a dependency of the rollup contract: | ||
ISequencerInbox(address(sequencerInbox)).setEigenDARollupManager(rollupManager); | ||
|
||
require( | ||
address(ISequencerInbox(address(sequencerInbox)).eigenDARollupManager()) == rollupManager, | ||
'Rollup Manager mismatch' | ||
); | ||
|
||
|
||
_upgradeChallengerManager(rollup, adminProxy); | ||
} | ||
|
||
function _upgradeChallengerManager(IRollupCore rollup, ProxyAdmin proxyAdmin) internal { | ||
// set the new challenge manager impl | ||
TransparentUpgradeableProxy challengeManager = | ||
TransparentUpgradeableProxy(payable(address(rollup.challengeManager()))); | ||
proxyAdmin.upgradeAndCall( | ||
challengeManager, | ||
challengeMgrImpl, | ||
abi.encodeCall(IChallengeManagerUpgradeInit.postUpgradeInit, (osp, condRoot, condOsp)) | ||
); | ||
|
||
// verify | ||
require( | ||
proxyAdmin.getProxyImplementation(challengeManager) == challengeMgrImpl, | ||
"NitroContracts2Point1Point0UpgradeAction: new challenge manager implementation set" | ||
); | ||
require( | ||
IChallengeManagerUpgradeInit(address(challengeManager)).osp() == address(osp), | ||
"NitroContracts2Point1Point0UpgradeAction: new OSP not set" | ||
); | ||
|
||
// set new wasm module root | ||
IRollupAdmin(address(rollup)).setWasmModuleRoot(wasmModuleRoot); | ||
|
||
// verify: | ||
require( | ||
rollup.wasmModuleRoot() == wasmModuleRoot, | ||
"NitroContracts2Point1Point0UpgradeAction: wasm module root not set" | ||
); | ||
} | ||
|
||
function _upgradeRollup(address rollupProxy) internal { | ||
IRollupUpgrade rollup = IRollupUpgrade(rollupProxy); | ||
|
||
// set new logic contracts | ||
rollup.upgradeTo(newRollupAdminLogic); | ||
rollup.upgradeSecondaryTo(newRollupUserLogic); | ||
|
||
// verify | ||
require( | ||
rollup.anyTrustFastConfirmer() == address(0), | ||
"NitroContracts2Point1Point0UpgradeAction: unexpected fast confirmer address" | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
{ | ||
"name": "orbit-actions", | ||
"version": "1.0.0", | ||
"repository": "https://github.com/OffchainLabs/blockchain-eng-template.git", | ||
"repository": "https://github.com/layr-labs/orbit-actions.git", | ||
"license": "Apache 2.0", | ||
"scripts": { | ||
"prepare": "forge install && cd lib/arbitrum-sdk && yarn", | ||
|
@@ -29,6 +29,7 @@ | |
"@arbitrum/nitro-contracts-1.3.0": "npm:@arbitrum/[email protected]", | ||
"@arbitrum/nitro-contracts-2.1.0": "npm:@arbitrum/[email protected]", | ||
"@arbitrum/token-bridge-1.2.2": "npm:@arbitrum/[email protected]", | ||
"@eigenda/nitro-contracts-2.1.0": "npm:@eigenda/[email protected]", | ||
"@nomicfoundation/hardhat-chai-matchers": "^2.0.0", | ||
"@nomicfoundation/hardhat-ethers": "^3.0.0", | ||
"@nomicfoundation/hardhat-foundry": "^1.1.1", | ||
|
@@ -59,5 +60,9 @@ | |
"ts-node": ">=8.0.0", | ||
"typechain": "^8.3.0", | ||
"typescript": ">=4.5.0" | ||
}, | ||
"dependencies": { | ||
"@eigenda/eigenda-utils": "^2.0.0", | ||
"@eigenda/nitro-contracts": "2.1.0-rc" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
## These env vars are used for ExecuteNitroContracts2Point1Point0UpgradeScript | ||
|
||
UPGRADE_ACTION_ADDRESS= | ||
INBOX_ADDRESS=0x229AA64b2C1cF171E45E2419D0756a9BAd1717c8 | ||
PROXY_ADMIN_ADDRESS=0xC1da2a856e08a05B15CB42C3e4d9DcCBe022C256 | ||
PARENT_UPGRADE_EXECUTOR_ADDRESS=0x6E6485413811F40DC9b5689CCB559FD1789e93D2 | ||
TARGET_WASM_MODULE_ROOT=0xf91c7c13d65ff0cc2970fdbe2e086acf2bff1828fd70095d5dc6d224730c42de | ||
PREVIOUS_OSP_ENTRY_ADDRESS= | ||
PARENT_CHAIN_IS_ARBITRUM=true |
157 changes: 157 additions & 0 deletions
157
...ntract-upgrades/eigenda-2.1.0/DeployNitroContractsEigenDA2Point1Point0UpgradeAction.s.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
pragma solidity 0.8.16; | ||
|
||
import {DeploymentHelpersScript} from "../../helper/DeploymentHelpers.s.sol"; | ||
import { | ||
NitroContractsEigenDA2Point1Point0UpgradeAction, | ||
IOneStepProofEntry | ||
} from "../../../../contracts/parent-chain/contract-upgrades/NitroContractsEigenDA2Point1Point0UpgradeAction.sol"; | ||
import {MockArbSys} from "../../helper/MockArbSys.sol"; | ||
import {console} from "forge-std/console.sol"; | ||
|
||
/** | ||
* @title DeployEigenDANitroContracts2Point1Point0UpgradeActionScript | ||
* @notice This script deploys OSPs, ChallengeManager and Rollup templates, and the upgrade action. | ||
*/ | ||
contract DeployNitroContractsEigenDA2Point1Point0UpgradeActionScript is DeploymentHelpersScript { | ||
// ArbOS x EigenDA v32 {LINK OFFICIAL RELEASE HERE WHEN READY} | ||
bytes32 public constant WASM_MODULE_ROOT = 0xddc237b76a502661518781d4fcf4b42461439cb7fc670b40f7689efcd27b9113; | ||
// ArbOS v32 https://github.com/OffchainLabs/nitro/releases/tag/consensus-v32 | ||
bytes32 public constant COND_WASM_MODULE_ROOT = 0x184884e1eb9fefdc158f6c8ac912bb183bf3cf83f0090317e0bc4ac5860baa39; | ||
|
||
function run() public { | ||
bool isArbitrum = vm.envBool("PARENT_CHAIN_IS_ARBITRUM"); | ||
if (isArbitrum) { | ||
// etch a mock ArbSys contract so that foundry simulate it nicely | ||
bytes memory mockArbSysCode = address(new MockArbSys()).code; | ||
vm.etch(address(100), mockArbSysCode); | ||
} | ||
|
||
address reader4844Address; | ||
if (!isArbitrum) { | ||
// deploy blob reader from arbitrum v2.1.0 | ||
reader4844Address = deployBytecodeFromJSON( | ||
"/node_modules/@arbitrum/nitro-contracts-1.2.1/out/yul/Reader4844.yul/Reader4844.json" | ||
); | ||
} | ||
|
||
vm.startBroadcast(); | ||
|
||
// deploy old osp from arbitrum v2.1.0 | ||
address oldOsp; | ||
{ | ||
address osp0 = deployBytecodeFromJSON( | ||
"/node_modules/@arbitrum/nitro-contracts-2.1.0/build/contracts/src/osp/OneStepProver0.sol/OneStepProver0.json" | ||
); | ||
address ospMemory = deployBytecodeFromJSON( | ||
"/node_modules/@arbitrum/nitro-contracts-2.1.0/build/contracts/src/osp/OneStepProverMemory.sol/OneStepProverMemory.json" | ||
); | ||
address ospMath = deployBytecodeFromJSON( | ||
"/node_modules/@arbitrum/nitro-contracts-2.1.0/build/contracts/src/osp/OneStepProverMath.sol/OneStepProverMath.json" | ||
); | ||
address ospHostIo = deployBytecodeFromJSON( | ||
"/node_modules/@arbitrum/nitro-contracts-2.1.0/build/contracts/src/osp/OneStepProverHostIo.sol/OneStepProverHostIo.json" | ||
); | ||
oldOsp = deployBytecodeWithConstructorFromJSON( | ||
"/node_modules/@arbitrum/nitro-contracts-2.1.0/build/contracts/src/osp/OneStepProofEntry.sol/OneStepProofEntry.json", | ||
abi.encode(osp0, ospMemory, ospMath, ospHostIo) | ||
); | ||
} | ||
|
||
// deploy new osp from v2.1.0 | ||
address newOsp; | ||
{ | ||
address osp0 = deployBytecodeFromJSON( | ||
"/node_modules/@eigenda/nitro-contracts-2.1.0/build/contracts/src/osp/OneStepProver0.sol/OneStepProver0.json" | ||
); | ||
address ospMemory = deployBytecodeFromJSON( | ||
"/node_modules/@eigenda/nitro-contracts-2.1.0/build/contracts/src/osp/OneStepProverMemory.sol/OneStepProverMemory.json" | ||
); | ||
address ospMath = deployBytecodeFromJSON( | ||
"/node_modules/@eigenda/nitro-contracts-2.1.0/build/contracts/src/osp/OneStepProverMath.sol/OneStepProverMath.json" | ||
); | ||
address ospHostIo = deployBytecodeFromJSON( | ||
"/node_modules/@eigenda/nitro-contracts-2.1.0/build/contracts/src/osp/OneStepProverHostIo.sol/OneStepProverHostIo.json" | ||
); | ||
newOsp = deployBytecodeWithConstructorFromJSON( | ||
"/node_modules/@eigenda/nitro-contracts-2.1.0/build/contracts/src/osp/OneStepProofEntry.sol/OneStepProofEntry.json", | ||
abi.encode(osp0, ospMemory, ospMath, ospHostIo) | ||
); | ||
} | ||
|
||
|
||
// inheritance chain for the new one step prover entry: | ||
// OneStepProverHostIO --immutably_held_by--> OneStepProofEntry --immutably_held_by--> ChallengeManager | ||
// | | | ||
// | immutably | | ||
// v held by v | ||
// RollupAdmin <-- --> RollupUser | ||
// deploying new one step prover requires upgrading | ||
// caller contracts to maintain a new storage | ||
// mapping for the new one step prover entry. | ||
// this immutable field pattern goes up to the core RollupAdmin | ||
// and RollupUser contracts. | ||
|
||
|
||
// understand which rollup manager to deploy based on parent chain context. | ||
address rollupManager; | ||
uint256 parentChainID = block.chainid; | ||
|
||
if (parentChainID == 17000 || parentChainID == 1) { // holesky or ETH | ||
console.log("(SAFE) Deploying EigenDA x Orbit L1 Blob Verifier contract"); | ||
rollupManager = deployBytecodeFromJSON( | ||
"/node_modules/@eigenda/nitro-contracts-2.1.0/build/contracts/src/bridge/EigenDABlobVerifierL1.sol/EigenDABlobVerifierL1.json" | ||
); | ||
} else { | ||
console.log("(DANGEROUS) Deploying EigenDA x Orbit L2 Blob Verifier contract"); | ||
rollupManager = deployBytecodeFromJSON( // non ETH or L3 deployment - this contract performs no verifications | ||
"/node_modules/@eigenda/nitro-contracts-2.1.0/build/contracts/src/bridge/EigenDABlobVerifierL2.sol/EigenDABlobVerifierL2.json" | ||
); | ||
} | ||
|
||
// deploy new challenge manager from v2.1.0 | ||
address challengeManager = deployBytecodeFromJSON( | ||
"/node_modules/@eigenda/nitro-contracts-2.1.0/build/contracts/src/challenge/ChallengeManager.sol/ChallengeManager.json" | ||
); | ||
|
||
console.log("Successfully deployed EigenDA x Orbit ChallengeManager"); | ||
|
||
// deploy new RollupAdminLogic contract from v2.1.0 | ||
address newRollupAdminLogic = deployBytecodeFromJSON( | ||
"/node_modules/@eigenda/nitro-contracts-2.1.0/build/contracts/src/rollup/RollupAdminLogic.sol/RollupAdminLogic.json" | ||
); | ||
|
||
console.log("Successfully deployed EigenDA x Orbit RollupAdminLogic"); | ||
|
||
|
||
// deploy new RollupUserLogic contract from v2.1.0 | ||
address newRollupUserLogic = deployBytecodeFromJSON( | ||
"/node_modules/@eigenda/nitro-contracts-2.1.0/build/contracts/src/rollup/RollupUserLogic.sol/RollupUserLogic.json" | ||
); | ||
console.log("Successfully deployed EigenDA x Orbit RollupUserLogic"); | ||
|
||
|
||
// deploy new new sequencer inbox from eigenda v2.1.0 | ||
address sequencerInbox = deployBytecodeWithConstructorFromJSON( | ||
"/node_modules/@eigenda/nitro-contracts-2.1.0/build/contracts/src/bridge/SequencerInbox.sol/SequencerInbox.json", | ||
abi.encode(vm.envUint("MAX_DATA_SIZE"), reader4844Address, !vm.envBool("IS_FEE_TOKEN_CHAIN")) | ||
); | ||
|
||
// finally deploy upgrade action | ||
new NitroContractsEigenDA2Point1Point0UpgradeAction({ | ||
_newWasmModuleRoot: WASM_MODULE_ROOT, | ||
_newSequencerInboxImpl: sequencerInbox, | ||
_newChallengeMangerImpl: challengeManager, | ||
_newOsp: IOneStepProofEntry(newOsp), | ||
_condOsp: IOneStepProofEntry(oldOsp), | ||
_condOspRoot: COND_WASM_MODULE_ROOT, | ||
_rollupManager: rollupManager, | ||
_newRollupAdminLogic: newRollupAdminLogic, | ||
_newRollupUserLogic: newRollupUserLogic | ||
}); | ||
|
||
console.log("Successfully deployed EigenDA x Orbit 2.1.0 upgrade/migration action"); | ||
|
||
vm.stopBroadcast(); | ||
} | ||
} |
Oops, something went wrong.