Skip to content

Commit 9e73bef

Browse files
authored
Merge pull request #16 from OffchainLabs/upg-2.0.0
Orbit upgrade action for contracts v2.1.0
2 parents dc54bae + 1746e9e commit 9e73bef

39 files changed

+1838
-40
lines changed

.gas-snapshot

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
UpgradeArbOSVersionAtTimestampActionTest:test_1() (gas: 165)

README.md

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,14 @@ A set of contracts that are similar to Arbitrum [gov-action-contracts](https://g
77
[yarn](https://classic.yarnpkg.com/lang/en/docs/install/) and [foundry](https://book.getfoundry.sh/getting-started/installation) are required to run the scripts
88

99
Most of the action contracts only support the following ownership setup:
10+
1011
- Rollup Contract on Parent Chain owned by a `ParentUpgradeExecutor`
1112
- Rollup ProxyAdmin on Parent Chain owned by a `ParentUpgradeExecutor`
1213
- Arb Owner on the Child Orbit Chain is granted to alias of `ParentUpgradeExecutor`
1314
- Arb Owner on the Child Orbit Chain is granted to `ChildUpgradeExecutor`
1415

1516
For token bridge related operations, these are the additional requirements:
17+
1618
- Token Bridge ProxyAdmin on Parent Chain owned by `ParentUpgradeExecutor`
1719
- Token Bridge ProxyAdmin on Child Orbit Chain owned by `ChildUpgradeExecutor`
1820
- Parent Chain Gateway Router and Custom Gateway owned by `ParentUpgradeExecutor`
@@ -26,6 +28,7 @@ yarn install
2628
## Check Version and Upgrade Path
2729

2830
Run the follow command to check the version of Nitro contracts deployed on the parent chain of your Orbit chain.
31+
2932
```
3033
$ INBOX_ADDRESS=0xaE21fDA3de92dE2FDAF606233b2863782Ba046F9 yarn orbit:contracts:version --network arb1
3134
Get the version of Orbit chain's nitro contracts (inbox 0xaE21fDA3de92dE2FDAF606233b2863782Ba046F9), hosted on chain 42161
@@ -38,28 +41,53 @@ Version of deployed RollupAdminLogic: v1.1.1
3841
Version of deployed RollupUserLogic: v1.1.1
3942
This deployment can be upgraded to v1.2.1 using NitroContracts1Point2Point1UpgradeAction
4043
```
41-
For other networks, replace `arb1` with the network name and configure INFURA_KEY or the rpc in hardhat.config.ts
4244

45+
For other networks, replace `arb1` with the network name and configure INFURA_KEY or the rpc in hardhat.config.ts
4346

4447
## Nitro Contracts Upgrades
45-
*This section is also referenced in the documentation on ["How to upgrade ArbOS on your Orbit chain"](https://docs.arbitrum.io/launch-orbit-chain/how-tos/arbos-upgrade)*
4648

47-
For ArbOS upgrades, a pre-requisite is to deploy new Nitro contracts to the parent chain of your Orbit chain before scheduling the ArbOS upgrade. These contracts include the rollup logic, fraud proof contracts, and interfaces for interacting with Nitro precompiles.
49+
_This section is also referenced in the documentation on ["How to upgrade ArbOS on your Orbit chain"](https://docs.arbitrum.io/launch-orbit-chain/how-tos/arbos-upgrade)_
50+
51+
For ArbOS upgrades, a pre-requisite is to deploy new Nitro contracts to the parent chain of your Orbit chain before scheduling the ArbOS upgrade. These contracts include the rollup logic, fraud proof contracts, and interfaces for interacting with Nitro precompiles.
52+
53+
### Nitro contracts 2.1.0 (for ArbOS 31 Bianca)
54+
55+
The [`nitro-contracts 2.1.0` upgrade action](scripts/foundry/contract-upgrades/2.1.0) will deploy `nitro-contracts v2.1.0` contracts to your Orbit's parent chain. Note that this action will only work for chains with `nitro-contracts v1.2.1` or `nitro-contracts v1.3.0`.
56+
57+
Note: nitro contracts upgrade brings support for AnyTrust fast confirmations and Stylus. However, Stylus will be enabled only when `ArbOS 31 Bianca` upgrade takes place, once it will be officially supported for Orbit chains.
4858

4959
### Nitro contracts 1.2.1 (for ArbOS 20 Atlas)
60+
5061
The [`nitro-contracts 1.2.1` upgrade action](scripts/foundry/contract-upgrades/1.2.1) will deploy `nitro-contracts v1.2.1` contracts to your Orbit's parent chain. Note that this action will only work for chains with `nitro-contracts v1.1.0` or `nitro-contracts v.1.1.1`. ArbOS 20 Atlas, shipped via [Nitro v2.3.0](https://github.com/OffchainLabs/nitro/releases/tag/v2.3.0), requires [**`nitro-contracts v1.2.1`**](https://github.com/OffchainLabs/nitro-contracts/releases/tag/v1.2.1) or higher.
5162

5263
## Scheduling the ArbOS upgrade
53-
*This section is also referenced in the documentation on ["How to upgrade ArbOS on your Orbit chain"](https://docs.arbitrum.io/launch-orbit-chain/how-tos/arbos-upgrade)*
5464

55-
Next, you will need to schedule the actual upgrade using the [ArbOS upgrade at timestamp action](scripts/foundry/arbos-upgrades/at-timestamp).
65+
_This section is also referenced in the documentation on ["How to upgrade ArbOS on your Orbit chain"](https://docs.arbitrum.io/launch-orbit-chain/how-tos/arbos-upgrade)_
66+
67+
Next, you will need to schedule the actual upgrade using the [ArbOS upgrade at timestamp action](scripts/foundry/arbos-upgrades/at-timestamp).
5668

5769
This action schedule an upgrade of the ArbOS to a specific version at a specific timestamp.
5870

5971
## Common upgrade paths
72+
6073
Here is a list of common upgrade paths that can be used to upgrade the Orbit chains.
6174

75+
### ArbOS 31 Bianca
76+
77+
1. TBD
78+
6279
### ArbOS 20 Atlas
80+
6381
1. Upgrade your Nitro node(s) to [Nitro v2.3.1](https://github.com/OffchainLabs/nitro/releases/tag/v2.3.1)
6482
1. Upgrade `nitro-contracts` to `v1.2.1` using [nitro-contract 1.2.1 upgrade action](scripts/foundry/contract-upgrades/1.2.1)
65-
2. Schedule the ArbOS 20 Atlas upgrade using [ArbOS upgrade at timestamp action](scripts/foundry/arbos-upgrades/at-timestamp)
83+
1. Schedule the ArbOS 20 Atlas upgrade using [ArbOS upgrade at timestamp action](scripts/foundry/arbos-upgrades/at-timestamp)
84+
85+
# Other Actions
86+
87+
## Enable Fast Confirmation
88+
89+
See [EnableFastConfirmAction](scripts/foundry/fast-confirm)
90+
91+
## Enable Stylus Cache Manager
92+
93+
See [setCacheManager](scripts/foundry/stylus/setCacheManager]
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
pragma solidity 0.8.16;
3+
4+
import "@arbitrum/nitro-contracts-2.1.0/src/precompiles/ArbSys.sol";
5+
6+
// ArbOwner interface will include addWasmCacheManager as of stylus upgrade
7+
interface IUpdatedArbOwner {
8+
function addWasmCacheManager(address manager) external;
9+
}
10+
11+
// ArbWasmCache precompile interface
12+
interface IArbWasmCache {
13+
/// @notice See if the user is a cache manager.
14+
function isCacheManager(address manager) external view returns (bool);
15+
}
16+
17+
// @notice For deployment on an Orbit chain;
18+
// adds wasm cache manager only when the stylus ArbOS upgrade activates.
19+
contract AddWasmCacheManagerAction {
20+
// wasm cache manager to add
21+
address public immutable wasmCachemanager;
22+
23+
// ArbOS version; use value as it's set and commonly used, NOT the value returned by
24+
// ArbSys, which adds 55. E.g., the value here should be 31, not 85
25+
uint256 public immutable targetArbOSVersion;
26+
27+
constructor(address _wasmCachemanager, uint256 _targetArbOSVersion) {
28+
wasmCachemanager = _wasmCachemanager;
29+
targetArbOSVersion = _targetArbOSVersion;
30+
}
31+
32+
function perform() external {
33+
// getter returns a value offset by 55: https://github.com/OffchainLabs/nitro/blob/a20a1c70cc11ac52c7cfe6a20f00c880c2009a8f/precompiles/ArbSys.go#L64
34+
uint256 currentArbOsVersion = ArbSys(0x0000000000000000000000000000000000000064).arbOSVersion() - 55;
35+
// revert if target arbos version not reached; since this is executed by a retryable, can be re-executed until target version is reached
36+
require(targetArbOSVersion == currentArbOsVersion, "AddWasmCacheManagerAction: ArbOS version");
37+
38+
IUpdatedArbOwner(0x0000000000000000000000000000000000000070).addWasmCacheManager(wasmCachemanager);
39+
40+
// verify:
41+
require(
42+
IArbWasmCache(0x0000000000000000000000000000000000000072).isCacheManager(wasmCachemanager),
43+
"AddWasmCacheManagerAction: is cache manager"
44+
);
45+
}
46+
}
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
pragma solidity 0.8.16;
3+
4+
import "@arbitrum/nitro-contracts-2.1.0/src/osp/IOneStepProofEntry.sol";
5+
import "@arbitrum/nitro-contracts-2.1.0/src/rollup/IRollupAdmin.sol";
6+
import "@openzeppelin/contracts/utils/Address.sol";
7+
import "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol";
8+
9+
interface IChallengeManagerUpgradeInit {
10+
function postUpgradeInit(IOneStepProofEntry osp_, bytes32 condRoot, IOneStepProofEntry condOsp) external;
11+
function osp() external returns (address);
12+
}
13+
14+
interface IRollupUpgrade {
15+
function upgradeTo(address newImplementation) external;
16+
function upgradeSecondaryTo(address newImplementation) external;
17+
function anyTrustFastConfirmer() external returns (address);
18+
}
19+
20+
interface ISequencerInbox_v1_2_1 {
21+
function isUsingFeeToken() external returns (bool);
22+
}
23+
24+
/**
25+
* @title DeployNitroContracts2Point1Point0UpgradeActionScript
26+
* @notice Set wasm module root and upgrade challenge manager for stylus ArbOS upgrade.
27+
* Also upgrade Rollup logic contracts to include fast confirmations feature.
28+
*/
29+
contract NitroContracts2Point1Point0UpgradeAction {
30+
bytes32 public immutable newWasmModuleRoot;
31+
address public immutable newChallengeManagerImpl;
32+
IOneStepProofEntry public immutable osp;
33+
bytes32 public immutable condRoot;
34+
IOneStepProofEntry public immutable condOsp;
35+
36+
address public immutable newRollupAdminLogic;
37+
address public immutable newRollupUserLogic;
38+
39+
constructor(
40+
bytes32 _newWasmModuleRoot,
41+
address _newChallengeManagerImpl,
42+
IOneStepProofEntry _osp,
43+
bytes32 _condRoot,
44+
IOneStepProofEntry _condOsp,
45+
address _newRollupAdminLogic,
46+
address _newRollupUserLogic
47+
) {
48+
require(
49+
_newWasmModuleRoot != bytes32(0), "NitroContracts2Point1Point0UpgradeAction: _newWasmModuleRoot is empty"
50+
);
51+
require(
52+
Address.isContract(_newChallengeManagerImpl),
53+
"NitroContracts2Point1Point0UpgradeAction: _newChallengeManagerImpl is not a contract"
54+
);
55+
require(Address.isContract(address(_osp)), "NitroContracts2Point1Point0UpgradeAction: _osp is not a contract");
56+
require(
57+
Address.isContract(address(_condOsp)),
58+
"NitroContracts2Point1Point0UpgradeAction: _condOsp is not a contract"
59+
);
60+
require(
61+
Address.isContract(_newRollupAdminLogic),
62+
"NitroContracts2Point1Point0UpgradeAction: _newRollupAdminLogic is not a contract"
63+
);
64+
require(
65+
Address.isContract(_newRollupUserLogic),
66+
"NitroContracts2Point1Point0UpgradeAction: _newRollupUserLogic is not a contract"
67+
);
68+
69+
newWasmModuleRoot = _newWasmModuleRoot;
70+
newChallengeManagerImpl = _newChallengeManagerImpl;
71+
osp = _osp;
72+
condRoot = _condRoot;
73+
condOsp = _condOsp;
74+
newRollupAdminLogic = _newRollupAdminLogic;
75+
newRollupUserLogic = _newRollupUserLogic;
76+
}
77+
78+
function perform(IRollupCore rollup, ProxyAdmin proxyAdmin) external {
79+
/// check if previous upgrade v1.2.1 was performed by polling function which was introduced in that version
80+
ISequencerInbox_v1_2_1 sequencerInbox = ISequencerInbox_v1_2_1(address(rollup.sequencerInbox()));
81+
try sequencerInbox.isUsingFeeToken() returns (bool) {}
82+
catch {
83+
revert("NitroContracts2Point1Point0UpgradeAction: sequencer inbox needs to be at version >= 1.2.1");
84+
}
85+
86+
/// check that condRoot is being used
87+
require(rollup.wasmModuleRoot() == condRoot, "NitroContracts2Point1Point0UpgradeAction: wasm root mismatch");
88+
89+
/// do the upgrade
90+
_upgradeChallengerManager(rollup, proxyAdmin);
91+
_upgradeRollup(address(rollup));
92+
}
93+
94+
function _upgradeChallengerManager(IRollupCore rollup, ProxyAdmin proxyAdmin) internal {
95+
// set the new challenge manager impl
96+
TransparentUpgradeableProxy challengeManager =
97+
TransparentUpgradeableProxy(payable(address(rollup.challengeManager())));
98+
proxyAdmin.upgradeAndCall(
99+
challengeManager,
100+
newChallengeManagerImpl,
101+
abi.encodeCall(IChallengeManagerUpgradeInit.postUpgradeInit, (osp, condRoot, condOsp))
102+
);
103+
104+
// verify
105+
require(
106+
proxyAdmin.getProxyImplementation(challengeManager) == newChallengeManagerImpl,
107+
"NitroContracts2Point1Point0UpgradeAction: new challenge manager implementation set"
108+
);
109+
require(
110+
IChallengeManagerUpgradeInit(address(challengeManager)).osp() == address(osp),
111+
"NitroContracts2Point1Point0UpgradeAction: new OSP not set"
112+
);
113+
114+
// set new wasm module root
115+
IRollupAdmin(address(rollup)).setWasmModuleRoot(newWasmModuleRoot);
116+
117+
// verify:
118+
require(
119+
rollup.wasmModuleRoot() == newWasmModuleRoot,
120+
"NitroContracts2Point1Point0UpgradeAction: wasm module root not set"
121+
);
122+
}
123+
124+
function _upgradeRollup(address rollupProxy) internal {
125+
IRollupUpgrade rollup = IRollupUpgrade(rollupProxy);
126+
127+
// set new logic contracts
128+
rollup.upgradeTo(newRollupAdminLogic);
129+
rollup.upgradeSecondaryTo(newRollupUserLogic);
130+
131+
// verify
132+
require(
133+
rollup.anyTrustFastConfirmer() == address(0),
134+
"NitroContracts2Point1Point0UpgradeAction: unexpected fast confirmer address"
135+
);
136+
}
137+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
pragma solidity 0.8.16;
3+
4+
interface IRollupAdmin {
5+
function anyTrustFastConfirmer() external view returns (address);
6+
function isValidator(address) external view returns (bool);
7+
function setAnyTrustFastConfirmer(address _anyTrustFastConfirmer) external;
8+
function setMinimumAssertionPeriod(uint256 _minimumAssertionPeriod) external;
9+
function setValidator(address[] memory _validator, bool[] memory _val) external;
10+
}
11+
12+
interface IGnosisSafeProxyFactory {
13+
function createProxyWithNonce(address _singleton, bytes memory initializer, uint256 saltNonce)
14+
external
15+
returns (address proxy);
16+
}
17+
18+
contract EnableFastConfirmAction {
19+
address public immutable GNOSIS_SAFE_PROXY_FACTORY;
20+
address public immutable GNOSIS_SAFE_1_3_0;
21+
address public immutable GNOSIS_COMPATIBILITY_FALLBACK_HANDLER;
22+
23+
constructor(address gnosisSafeProxyFactory, address gnosisSafe1_3_0, address gnosisCompatibilityFallbackHandler) {
24+
require(gnosisSafeProxyFactory.code.length > 0, "gnosisSafeProxyFactory doesn't exist on this chain");
25+
require(gnosisSafe1_3_0.code.length > 0, "gnosisSafe1_3_0 doesn't exist on this chain");
26+
require(
27+
gnosisCompatibilityFallbackHandler.code.length > 0,
28+
"gnosisCompatibilityFallbackHandler doesn't exist on this chain"
29+
);
30+
GNOSIS_SAFE_PROXY_FACTORY = gnosisSafeProxyFactory;
31+
GNOSIS_SAFE_1_3_0 = gnosisSafe1_3_0;
32+
GNOSIS_COMPATIBILITY_FALLBACK_HANDLER = gnosisCompatibilityFallbackHandler;
33+
}
34+
35+
function perform(IRollupAdmin rollup, address[] calldata fastConfirmCommittee, uint256 threshold, uint256 salt)
36+
external
37+
{
38+
require(rollup.anyTrustFastConfirmer() == address(0), "Fast confirm already enabled");
39+
require(threshold > 0 && threshold <= fastConfirmCommittee.length, "Invalid threshold");
40+
for (uint256 i = 0; i < fastConfirmCommittee.length; i++) {
41+
require(fastConfirmCommittee[i] != address(0), "Invalid address");
42+
require(rollup.isValidator(fastConfirmCommittee[i]), "fastConfirmCommittee members must be validator");
43+
}
44+
address fastConfirmer = IGnosisSafeProxyFactory(GNOSIS_SAFE_PROXY_FACTORY).createProxyWithNonce(
45+
GNOSIS_SAFE_1_3_0,
46+
abi.encodeWithSignature(
47+
"setup(address[],uint256,address,bytes,address,address,uint256,address)",
48+
fastConfirmCommittee,
49+
threshold,
50+
address(0),
51+
"",
52+
GNOSIS_COMPATIBILITY_FALLBACK_HANDLER,
53+
address(0),
54+
0,
55+
address(0)
56+
),
57+
salt
58+
);
59+
rollup.setAnyTrustFastConfirmer(fastConfirmer);
60+
address[] memory validators = new address[](1);
61+
validators[0] = fastConfirmer;
62+
bool[] memory val = new bool[](1);
63+
val[0] = true;
64+
rollup.setValidator(validators, val);
65+
rollup.setMinimumAssertionPeriod(1);
66+
}
67+
}

foundry.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@ test = 'test'
66
cache_path = 'cache_forge'
77
solc_version = '0.8.16'
88
optimizer_runs = 2000
9-
fs_permissions = [{ access = "read", path = "node_modules/@arbitrum/nitro-contracts-1.2.1"}, { access = "read-write", path = "./scripts/foundry"}]
9+
fs_permissions = [{ access = "read", path = "node_modules/@arbitrum/"}, { access = "read", path = "node_modules/@openzeppelin/"},{ access = "read-write", path = "./scripts/foundry"}]
1010
script = 'scripts'

package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,16 @@
2626
},
2727
"devDependencies": {
2828
"@arbitrum/nitro-contracts-1.2.1": "npm:@arbitrum/[email protected]",
29-
"@offchainlabs/upgrade-executor": "1.1.0-beta.0",
29+
"@arbitrum/nitro-contracts-1.3.0": "npm:@arbitrum/[email protected]",
30+
"@arbitrum/nitro-contracts-2.1.0": "npm:@arbitrum/[email protected]",
31+
"@arbitrum/token-bridge-1.2.2": "npm:@arbitrum/[email protected]",
3032
"@nomicfoundation/hardhat-chai-matchers": "^2.0.0",
3133
"@nomicfoundation/hardhat-ethers": "^3.0.0",
3234
"@nomicfoundation/hardhat-foundry": "^1.1.1",
3335
"@nomicfoundation/hardhat-network-helpers": "^1.0.0",
3436
"@nomicfoundation/hardhat-toolbox": "^4.0.0",
3537
"@nomicfoundation/hardhat-verify": "^2.0.0",
38+
"@offchainlabs/upgrade-executor": "1.1.0-beta.0",
3639
"@typechain/ethers-v6": "^0.5.0",
3740
"@typechain/hardhat": "^9.0.0",
3841
"@types/chai": "^4.2.0",
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
## These env vars are used for ExecuteNitroContracts2Point1Point0UpgradeScript
2+
3+
UPGRADE_ACTION_ADDRESS=
4+
ROLLUP_ADDRESS=
5+
PROXY_ADMIN_ADDRESS=
6+
PARENT_UPGRADE_EXECUTOR_ADDRESS=
7+
WASM_MODULE_ROOT=0x260f5fa5c3176a856893642e149cf128b5a8de9f828afec8d11184415dd8dc69
8+
PARENT_CHAIN_IS_ARBITRUM=true

0 commit comments

Comments
 (0)