Skip to content

Commit

Permalink
feat: EigenDA v2.1.0 migration action
Browse files Browse the repository at this point in the history
  • Loading branch information
epociask committed Oct 21, 2024
1 parent 9e3c1c3 commit 933e9ba
Show file tree
Hide file tree
Showing 7 changed files with 521 additions and 2 deletions.
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"
);
}
}
2 changes: 1 addition & 1 deletion foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ test = 'test'
cache_path = 'cache_forge'
solc_version = '0.8.16'
optimizer_runs = 2000
fs_permissions = [{ access = "read", path = "node_modules/@arbitrum/"}, { access = "read", path = "node_modules/@openzeppelin/"},{ access = "read-write", path = "./scripts/foundry"}]
fs_permissions = [{ access = "read", path = "node_modules/@arbitrum/"}, { access = "read", path = "node_modules/@eigenda/"}, { access = "read", path = "node_modules/@openzeppelin/"},{ access = "read-write", path = "./scripts/foundry"}]
script = 'scripts'
7 changes: 6 additions & 1 deletion package.json
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",
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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"
}
}
9 changes: 9 additions & 0 deletions scripts/foundry/contract-upgrades/eigenda-2.1.0/.env.sample
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
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();
}
}
Loading

0 comments on commit 933e9ba

Please sign in to comment.