Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add action contracts for migrating live orbit chains to espresso #1

Merged
merged 28 commits into from
Sep 12, 2024
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
4ebee9a
Add migration contract and test.
zacshowa Aug 14, 2024
7b31c80
add espresso ArbOS upgrade contract
zacshowa Aug 14, 2024
38ec00d
commit example .env files for upgrades.
zacshowa Aug 14, 2024
944af15
commit yarn.lock and package.json for new dependencies.
zacshowa Aug 14, 2024
5f1a716
add nitro-contracts submodule.
zacshowa Aug 19, 2024
a79bb05
Add license identifier to contracts
zacshowa Aug 19, 2024
7098927
Update the EspressoArbOSUpgrade.sol contract to import the UpgradeArb…
zacshowa Aug 19, 2024
3c35709
address PR feedback
zacshowa Aug 19, 2024
3440e75
add nitro-contracts submodule to .gitmodules
zacshowa Aug 21, 2024
9004894
remove unused nitro-contracts submodule
zacshowa Aug 21, 2024
637f8ef
forge install: nitro-contracts.git
zacshowa Aug 21, 2024
0ef9057
forge install: nitro-contracts
zacshowa Aug 21, 2024
8e72997
Deployment scripts and foundry remappings
zacshowa Aug 22, 2024
261b147
fix broken submodule from forge install
zacshowa Aug 22, 2024
15b00f0
Updates to action upgrade contracts.
zacshowa Aug 23, 2024
3a798bd
Commit with current progress: updates to contracts
zacshowa Aug 23, 2024
853faad
Update the rollup address
ImJeremyHe Aug 26, 2024
c9a1eeb
Set adresses and module roots via env vars
sveitser Aug 26, 2024
1123bb5
move migration scripts to their own folder
zacshowa Aug 30, 2024
0677dca
Add WIP README.md for the migration
zacshowa Aug 30, 2024
313d834
Update ArbOS action upgrade to take a timestamp parameter.
zacshowa Sep 3, 2024
fb31130
update .example-env for reference in the README.md
zacshowa Sep 3, 2024
1fe92a4
Update README.md to explain the full migration process.
zacshowa Sep 3, 2024
5df09a9
update Migration solidity test to point to relocated migration action…
zacshowa Sep 4, 2024
fcb0ff9
Update migration/README.md
zacshowa Sep 5, 2024
dc57c2c
run forge fmt
zacshowa Sep 5, 2024
c993b69
Update README.md to reflect PR feedback
zacshowa Sep 6, 2024
b914e97
Merge branch 'espresso-migration' of github.com:EspressoSystems/orbit…
zacshowa Sep 6, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@
[submodule "lib/arbitrum-sdk"]
path = lib/arbitrum-sdk
url = https://github.com/OffchainLabs/arbitrum-sdk
[submodule "lib/nitro-contracts.git"]
path = lib/nitro-contracts
url = https://github.com/EspressoSystems/nitro-contracts
17 changes: 17 additions & 0 deletions contracts/child-chain/arbos-upgrade/DeployArbOSUpgradeAction.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.9;

import "forge-std/Script.sol";
import "./EspressoArbOSUpgrade.sol";

contract DeployArbOSUpgradeAction is Script{
function run() external{
uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");
uint64 upgradeTimestamp = uint64(vm.envUint("UPGRADE_TIMESTAMP"));
vm.startBroadcast(deployerPrivateKey);
EspressoArbOSUpgrade arbOSUpgrade = new EspressoArbOSUpgrade(
upgradeTimestamp
);
vm.stopBroadcast();
}
}
16 changes: 16 additions & 0 deletions contracts/child-chain/arbos-upgrade/EspressoArbOSUpgrade.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.16;

import "forge-std/Script.sol";
import "./UpgradeArbOSVersionAtTimestampAction.sol";

contract EspressoArbOSUpgrade is UpgradeArbOSVersionAtTimestampAction, Script {
constructor(
uint64 upgradeTimestamp
)
UpgradeArbOSVersionAtTimestampAction(
35,
upgradeTimestamp
)
{}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export NEW_OSP_ENTRY="0x7B5F0B437EE68A22992DdD629AA22525Fc5dfa9A"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: I dont think you need export in front of the environment variables ( example here)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might just be from my lack of familiarity with forge and foundry. I couldn't get the env vars to be visible to the tests unless I exported them. Sourcing the file without exporting them doesn't propagate the vars to any child processes, e.g. forge test.
If there is a different way I'm supposed to supply forge with the env vars I would love to know about it!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the file is called .env exactly it is special and automatically picked up by foundry and many other tools. Unfortunately it has to be exactly .env in the case of foundry.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can do source .env-espresso-osp-migration && forge test <> to be able to have a foundry script pick up env variables that's not in the expected .env file.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's true but then breaks the ability of being able to override with env vars. So this can get messy when used in scripts if one expects environment variable that are already set to take precedence.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's true. we aren't using the .env file for secrets anymore but only for config (since that's how it's been set up historically). So should this go into the .env file?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems to be how existing orbit upgrades are configured in the orbit-actions repo. I think it's a good idea to stick to how things are done in that repo unless it really gets in our way.

export NEW_WASM_MODULE_ROOT="0x43683fe4e619e9ee7c0d959259d10ff2a38f4325a2b8936c47d9162704fe072a"
export CURRENT_OSP_ENTRY="0x4838B106FCe9647Bdf1E7877BF73cE8B0BAD5f97"
export CURRENT_WASM_MODULE_ROOT="0xbc1026ff45c20ea97e9e6057224a5668ea78d8f885c9b14fc849238e8ef5c5dc"
export ROLLUP_ADDRESS="0xF2099c4783921f44Ac988B67e743DAeFd4A00efd"
export PROXY_ADMIN="0x94e2090Fb86906C799A67263e6beAe528b81B3D6"
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export UPGRADE_TIMESTAMP = "1723664126"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

25 changes: 25 additions & 0 deletions contracts/parent-chain/espresso-migration/DeployEspressoOsp.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.9;

import "forge-std/Script.sol";
import "nitro-contracts/osp/OneStepProverMemory.sol";
import "nitro-contracts/osp/OneStepProverMath.sol";
import "nitro-contracts/osp/OneStepProverHostIo.sol";
import "nitro-contracts/osp/OneStepProver0.sol";
import "nitro-contracts/osp/OneStepProofEntry.sol";


contract DeployEspressoOsp is Script{
function run() external{
address hotshotAddr = vm.envAddress("HOTSHOT_ADDRESS");
uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");
vm.startBroadcast(deployerPrivateKey);
OneStepProofEntry newOSP = new OneStepProofEntry(
new OneStepProver0(),
new OneStepProverMemory(),
new OneStepProverMath(),
new OneStepProverHostIo(hotshotAddr)
);
vm.stopBroadcast();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.9;

import "forge-std/Script.sol";
import "./EspressoOspMigrationAction.sol";

contract DeployEspressoOspMigrationAction is Script{
function run() external{
uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");
address newOspEntry = vm.envAddress("NEW_OSP_ENTRY");
bytes32 newWasmModuleRoot = vm.envBytes32("NEW_WASM_MODULE_ROOT");
address currentOspEntry = vm.envAddress("CURRENT_OSP_ENTRY");
bytes32 currentWasmModuleRoot = vm.envBytes32("CURRENT_WASM_MODULE_ROOT");
address rollup = vm.envAddress("ROLLUP_ADDRESS");
address proxyAdmin = vm.envAddress("PROXY_ADMIN");

vm.startBroadcast(deployerPrivateKey);
OspMigrationAction migrationAction = new OspMigrationAction(
newOspEntry,
newWasmModuleRoot,
currentOspEntry,
currentWasmModuleRoot,
rollup,
proxyAdmin
);
vm.stopBroadcast();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.9;

import "forge-std/Script.sol";
import "@arbitrum/nitro-contracts/src/challenge/IChallengeManager.sol";
import "@arbitrum/nitro-contracts/src/rollup/IRollupCore.sol";
import "@arbitrum/nitro-contracts/src/rollup/IRollupAdmin.sol";

import "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol";
import "@openzeppelin/contracts/utils/Address.sol";

contract OspMigrationAction{

error IncorrectWasmModuleRoot(bytes32 incorrectAddr);

error AddressIsNotContract(address incorrectAddr);

error ChallengeManagerUpdated(address newChallengeManagerAddr);

error OspNotUpgraded(address oldOspAddress);

error WasmModuleRootNotUpdated(bytes32 oldWasmModuleRoot);

address public immutable newOspEntry;
bytes32 public immutable newWasmModuleRoot;
bytes32 public immutable currentWasmModuleRoot;
address public immutable currentOspEntry;
address public immutable rollup;
address public immutable proxyAdmin;


constructor(
address _newOspEntry,
bytes32 _newWasmModuleRoot,
address _currentOspEntry,
bytes32 _currentWasmModuleRoot,
address _rollup,
address _proxyAdmin
){
if(_newWasmModuleRoot == bytes32(0)){
revert IncorrectWasmModuleRoot(_newWasmModuleRoot);
}

if(_currentWasmModuleRoot == bytes32(0)){
revert IncorrectWasmModuleRoot(_currentWasmModuleRoot);
}

if(!Address.isContract(_newOspEntry)){
revert AddressIsNotContract(_newOspEntry);
}

if(!Address.isContract(_currentOspEntry)){
revert AddressIsNotContract(_currentOspEntry);
}

if(!Address.isContract(_proxyAdmin)){
revert AddressIsNotContract(_proxyAdmin);
}

if(!Address.isContract(_rollup)){
revert AddressIsNotContract(_rollup);
}
newOspEntry = _newOspEntry;
newWasmModuleRoot = _newWasmModuleRoot;
currentOspEntry = _currentOspEntry;
currentWasmModuleRoot = _currentWasmModuleRoot;
rollup = _rollup;
proxyAdmin = _proxyAdmin;
}

function perform() external{
//Handle assertions in the perform function as we shouldn't be storing local state for delegated calls.

// set the new challenge manager impl
TransparentUpgradeableProxy challengeManager =
TransparentUpgradeableProxy(payable(address(IRollupCore(rollup).challengeManager())));
address chalManImpl = ProxyAdmin(proxyAdmin).getProxyImplementation(challengeManager);
ProxyAdmin(proxyAdmin).upgradeAndCall(
challengeManager,
chalManImpl, // Use the rollups current challenge manager as we only need to upgrade the OSP
abi.encodeWithSelector(IChallengeManager.postUpgradeInit.selector, IOneStepProofEntry(newOspEntry), currentWasmModuleRoot, IOneStepProofEntry(currentOspEntry))
);
address postUpgradeChalManAddr = ProxyAdmin(proxyAdmin).getProxyImplementation(challengeManager);

if(postUpgradeChalManAddr != chalManImpl){
revert ChallengeManagerUpdated(postUpgradeChalManAddr);
}
IOneStepProofEntry newOsp = IChallengeManager(address(challengeManager)).osp();

if(newOsp != IOneStepProofEntry(newOspEntry) ){
Sneh1999 marked this conversation as resolved.
Show resolved Hide resolved
revert OspNotUpgraded(address(newOsp));
}

IRollupAdmin(rollup).setWasmModuleRoot(newWasmModuleRoot);

bytes32 postUpgradeWasmModuleRoot = IRollupCore(rollup).wasmModuleRoot();

if(postUpgradeWasmModuleRoot != newWasmModuleRoot){
revert WasmModuleRootNotUpdated(postUpgradeWasmModuleRoot);
}
}
}
Loading