Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
bcebb18
chore: update v3.0.0 meta
gzeoneth Jan 8, 2025
0e9f4db
feat: add any
gzeoneth Jan 8, 2025
42d28de
docs: comments
gzeoneth Jan 8, 2025
fcedcf5
chore: add rei hashes
gzeoneth Jan 8, 2025
b5858f5
fix: type
gzeoneth Jan 8, 2025
a3887a4
feat: check fee token
gzeoneth Jan 8, 2025
3a33b97
feat: v3 upgrade check
gzeoneth Jan 8, 2025
71e2bf1
docs: bold upgrade draft
gzeoneth Jan 8, 2025
2466ef6
add version path
godzillaba Jan 14, 2025
318b4ba
fmt
godzillaba Jan 14, 2025
dd6ccdd
add action
godzillaba Jan 14, 2025
7104ba6
fix
godzillaba Jan 14, 2025
3c99af2
snapshot
godzillaba Jan 14, 2025
65cbb33
add tests
godzillaba Jan 14, 2025
5f0831c
readme
godzillaba Jan 15, 2025
5b0f67b
deployment script
godzillaba Jan 15, 2025
002c898
execution script
godzillaba Jan 15, 2025
6fc72a0
format
godzillaba Jan 15, 2025
ee12699
Revert "format"
godzillaba Jan 15, 2025
ce4d8f6
reformat
godzillaba Jan 15, 2025
5d85634
tight broadcast
godzillaba Jan 15, 2025
24159ec
Update README.md
godzillaba Jan 15, 2025
8257ee5
misc
godzillaba Jan 15, 2025
31287a2
fix
godzillaba Jan 15, 2025
89aad88
postUpgradeInit
godzillaba Jan 15, 2025
f91ef8a
main readme
godzillaba Jan 17, 2025
88f14c0
Update scripts/foundry/contract-upgrades/3.0.0/README.md
godzillaba Jan 17, 2025
44a6177
readme tweak
godzillaba Jan 17, 2025
e09a00b
note
godzillaba Jan 17, 2025
3c80dd3
Update scripts/foundry/contract-upgrades/3.0.0/README.md
godzillaba Jan 17, 2025
d549ae1
Merge branch 'bold-upgrade-guide' into custom-fee-patch
godzillaba Jan 17, 2025
d7a8f01
add 2.1.2 to 3.0.0 allowed versions
godzillaba Jan 17, 2025
6656dcb
typo
godzillaba Jan 24, 2025
be1c247
fix: disable custom fee token chain support for v3 for now
gzeoneth Feb 3, 2025
a87dfb2
replace npm package
godzillaba Feb 11, 2025
feaff55
metadata hashes
godzillaba Feb 19, 2025
0120917
Merge branch 'bold-upgrade-guide' into custom-fee-patch
godzillaba Feb 19, 2025
12f8088
chore: no bold upgrade
gzeoneth Feb 24, 2025
cf136f5
chore: also remove v3 hashes
gzeoneth Feb 24, 2025
df1b037
ci: use foundry stable
gzeoneth Feb 24, 2025
98893af
fix: lint
gzeoneth Feb 24, 2025
2641402
test: remove pretty flag from inspect
gzeoneth Feb 24, 2025
d744a65
test: commit new format
gzeoneth Feb 24, 2025
8df4175
chore: deployments
gzeoneth Feb 24, 2025
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 .gas-snapshot
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
NitroContracts2Point1Point2UpgradeActionTest:testShouldRevertOnEth() (gas: 61684)
NitroContracts2Point1Point2UpgradeActionTest:testShouldRevertOnV2() (gas: 65683)
NitroContracts2Point1Point2UpgradeActionTest:testShouldUpgradeAndSetDecimals() (gas: 91928)
UpgradeArbOSVersionAtTimestampActionTest:test_1() (gas: 165)
2 changes: 1 addition & 1 deletion .github/workflows/audit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
version: nightly
version: stable

- run: yarn minimal-install
- run: yarn audit:ci
2 changes: 1 addition & 1 deletion .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
version: nightly
version: stable

- run: yarn && yarn build
- run: yarn lint
6 changes: 3 additions & 3 deletions .github/workflows/test-e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
version: nightly
version: stable

- run: yarn
- run: cp .env.example .env && yarn test:e2e
Expand All @@ -52,7 +52,7 @@ jobs:
# - name: Install Foundry
# uses: foundry-rs/foundry-toolchain@v1
# with:
# version: nightly
# version: stable

# - run: yarn
# - run: cp .env.example .env && yarn test:e2e
Expand Down Expand Up @@ -80,7 +80,7 @@ jobs:
# - name: Install Foundry
# uses: foundry-rs/foundry-toolchain@v1
# with:
# version: nightly
# version: stable

# - run: yarn
# - run: cp .env.example .env && yarn test:e2e
2 changes: 1 addition & 1 deletion .github/workflows/test-fork.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
version: nightly
version: stable

- run: yarn minimal-install
- run: ETH_FORK_URL=${{ secrets.ETH_FORK_URL }} ARB_FORK_URL=${{ secrets.ARB_FORK_URL }} yarn test:fork
10 changes: 5 additions & 5 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
version: nightly
version: stable

- run: yarn minimal-install
- run: yarn test:unit
Expand All @@ -35,7 +35,7 @@ jobs:
- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
version: nightly
version: stable

- run: yarn minimal-install
- run: yarn test:sizes
Expand All @@ -50,7 +50,7 @@ jobs:
- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
version: nightly
version: stable

- run: yarn minimal-install
- run: yarn test:gas-check
Expand All @@ -65,7 +65,7 @@ jobs:
- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
version: nightly
version: stable

- run: yarn minimal-install
- run: yarn test:sigs
Expand All @@ -80,7 +80,7 @@ jobs:
- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
version: nightly
version: stable

- run: yarn minimal-install
- run: yarn test:storage
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,18 @@ _This section is also referenced in the documentation on ["How to upgrade ArbOS

For ArbOS upgrades, a common 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. The scripts and instructions in this repository are meant for Orbit chain owners to upgrade the aforementioned contracts, set the new WASM module root, and then schedule the ArbOS upgrade.

### Nitro contracts 2.1.2

The [`nitro-contracts 2.1.2` upgrade guide](scripts/foundry/contract-upgrades/2.1.2) will patch the `ERC20Bridge` with a storage layout fix.

This upgrade is only required if:

1. The chain has a custom native token; AND
1. The chain was originally deployed before `v2.0.0`; AND
1. The chain wishes to upgrade to `v3.0.0`

Do not perform this upgrade if the above requirements aren't met.

### Nitro contracts 2.1.0 (for [ArbOS 32 Bianca](https://docs.arbitrum.io/run-arbitrum-node/arbos-releases/arbos32))

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`.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.8.16;

import {ProxyAdmin} from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol";
import {TransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";
import {Address} from "@openzeppelin/contracts/utils/Address.sol";

interface IERC20Bridge {
function nativeToken() external view returns (address);
}

interface IERC20Bridge_v2 {
function nativeTokenDecimals() external view returns (uint8);
}

interface IERC20Bridge_v2_patch {
function postUpgradeInit() external;
}

/**
* @title NitroContracts2Point1Point2UpgradeAction
* @notice Upgrade the bridge to ERC20Bridge v2.1.2 and force it to set nativeTokenDecimals to 18.
* Will revert if the bridge is not an ERC20Bridge.
* Will revert if ERC20Bridge is not v1.x.x
*/
contract NitroContracts2Point1Point2UpgradeAction {
address public immutable newBridgeImpl;

constructor(address _newBridgeImpl) {
require(
Address.isContract(_newBridgeImpl),
"NitroContracts2Point1Point2UpgradeAction: _newBridgeImpl is not a contract"
);

newBridgeImpl = _newBridgeImpl;
}

function perform(address bridge, ProxyAdmin proxyAdmin) external {
// ensure the bridge is an ERC20Bridge
try IERC20Bridge(bridge).nativeToken() returns (address) {}
catch {
// nativeToken() reverted, so it's not an ERC20Bridge
revert("NitroContracts2Point1Point2UpgradeAction: bridge is not an ERC20Bridge");
}

// ensure the bridge is v1.x.x
try IERC20Bridge_v2(address(bridge)).nativeTokenDecimals() returns (uint8) {
// nativeTokenDecimals() didn't revert, so it must be v2.x.x
revert("NitroContracts2Point1Point2UpgradeAction: bridge is not v1.x.x");
} catch {}

// upgrade to the new implementation and call forceEighteenDecimalsPatch
proxyAdmin.upgradeAndCall({
proxy: TransparentUpgradeableProxy(payable((bridge))),
implementation: newBridgeImpl,
data: abi.encodeCall(IERC20Bridge_v2_patch.postUpgradeInit, ())
});

// ensure decimals were set to 18
require(IERC20Bridge_v2((bridge)).nativeTokenDecimals() == 18, "decimals not set to 18");
}
}
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/@offchainlabs/"},{ access = "read", path = "node_modules/@arbitrum/"}, { access = "read", path = "node_modules/@openzeppelin/"},{ access = "read-write", path = "./scripts/foundry"}]
script = 'scripts'
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"@arbitrum/nitro-contracts-1.2.1": "npm:@arbitrum/nitro-contracts@1.2.1",
"@arbitrum/nitro-contracts-1.3.0": "npm:@arbitrum/nitro-contracts@1.3.0",
"@arbitrum/nitro-contracts-2.1.0": "npm:@arbitrum/nitro-contracts@2.1.0",
"@arbitrum/nitro-contracts-2.1.2": "npm:@arbitrum/nitro-contracts@2.1.2",
"@arbitrum/token-bridge-1.2.2": "npm:@arbitrum/token-bridge-contracts@1.2.2",
"@nomicfoundation/hardhat-chai-matchers": "^2.0.0",
"@nomicfoundation/hardhat-ethers": "^3.0.0",
Expand Down
2 changes: 1 addition & 1 deletion scripts/foundry/contract-upgrades/2.1.0/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ Also, expectation is that rollup being upgraded currently uses official ArbOS20

## How to use it

1. Setup .env according to the example files, make sure you have everything correctly defined. The script will do some sanity checks but not everything can be checked. The .env file must be in project root for recent foundary versions.
1. Setup .env according to the example files, make sure you have everything correctly defined. The script will do some sanity checks but not everything can be checked. The .env file must be in project root for recent foundry versions.

> [!CAUTION]
> The .env file must be in project root.
Expand Down
6 changes: 6 additions & 0 deletions scripts/foundry/contract-upgrades/2.1.2/.env.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
## These env vars are used for ExecuteNitroContracts2Point1Point2UpgradeScript

UPGRADE_ACTION_ADDRESS=
INBOX_ADDRESS=
PROXY_ADMIN_ADDRESS=
PARENT_UPGRADE_EXECUTOR_ADDRESS=
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.8.16;

import {DeploymentHelpersScript} from "../../helper/DeploymentHelpers.s.sol";
import {NitroContracts2Point1Point2UpgradeAction} from
"../../../../contracts/parent-chain/contract-upgrades/NitroContracts2Point1Point2UpgradeAction.sol";

/**
* @title DeployNitroContracts2Point1Point2UpgradeActionScript
* @notice This script deploys the ERC20Bridge contract and NitroContracts2Point1Point2UpgradeAction contract.
*/
contract DeployNitroContracts2Point1Point2UpgradeActionScript is DeploymentHelpersScript {
function run() public {
vm.startBroadcast();

// deploy new ERC20Bridge contract from v2.1.2
address newBridgeImpl = deployBytecodeFromJSON(
"/node_modules/@arbitrum/nitro-contracts-2.1.2/build/contracts/src/bridge/ERC20Bridge.sol/ERC20Bridge.json"
);

// deploy upgrade action
new NitroContracts2Point1Point2UpgradeAction(newBridgeImpl);

vm.stopBroadcast();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.8.16;

import "forge-std/Script.sol";
import {
NitroContracts2Point1Point2UpgradeAction,
ProxyAdmin
} from "../../../../contracts/parent-chain/contract-upgrades/NitroContracts2Point1Point2UpgradeAction.sol";
import {IInboxBase} from "@arbitrum/nitro-contracts-1.2.1/src/bridge/IInboxBase.sol";
import {IERC20Bridge} from "@arbitrum/nitro-contracts-2.1.2/src/bridge/IERC20Bridge.sol";
import {IUpgradeExecutor} from "@offchainlabs/upgrade-executor/src/IUpgradeExecutor.sol";

/**
* @title ExecuteNitroContracts1Point2Point1UpgradeScript
* @notice This script executes nitro contracts 2.1.2 upgrade through UpgradeExecutor
*/
contract ExecuteNitroContracts2Point1Point2UpgradeScript is Script {
function run() public {
NitroContracts2Point1Point2UpgradeAction upgradeAction =
NitroContracts2Point1Point2UpgradeAction(vm.envAddress("UPGRADE_ACTION_ADDRESS"));

IInboxBase inbox = IInboxBase(vm.envAddress("INBOX_ADDRESS"));

address bridge = address(inbox.bridge());

// prepare upgrade calldata
ProxyAdmin proxyAdmin = ProxyAdmin(vm.envAddress("PROXY_ADMIN_ADDRESS"));
bytes memory upgradeCalldata =
abi.encodeCall(NitroContracts2Point1Point2UpgradeAction.perform, (bridge, proxyAdmin));

// execute the upgrade
// action checks prerequisites, and script will fail if the action reverts
IUpgradeExecutor executor = IUpgradeExecutor(vm.envAddress("PARENT_UPGRADE_EXECUTOR_ADDRESS"));
vm.startBroadcast();
executor.execute(address(upgradeAction), upgradeCalldata);
vm.stopBroadcast();

// sanity check, full checks are done on-chain by the upgrade action
require(IERC20Bridge(bridge).nativeTokenDecimals() == 18, "Unexpected native token decimals");
}
}
87 changes: 87 additions & 0 deletions scripts/foundry/contract-upgrades/2.1.2/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# Nitro contracts 2.1.2 upgrade

> [!CAUTION]
> This is a patch version and is only necessary for custom fee token chains with an `ERC20Bridge` contract below version `< v2.0.0`.
>
> If your chain uses the parent chain's native asset for fees, or your `ERC20Bridge` is already at `v2.0.0` or above, do not perform this upgrade.
>
> The rest of this document assumes the chain satisfies the above.

These scripts deploy and execute the `NitroContracts2Point1Point2UpgradeAction` contract which allows Orbit chains to upgrade to [2.1.2 release](https://github.com/OffchainLabs/nitro-contracts/releases/tag/v2.1.2). Predeployed instances of the upgrade action exist on the chains listed in the following section.

Upgrading to `v2.1.2` is REQUIRED before upgrading to `v3.0.0`. Upgrading to `v2.1.0` is REQUIRED before upgrading to `v2.1.2`.

`NitroContracts2Point1Point2UpgradeAction` will perform the following action:

1. Upgrade the `ERC20Bridge` contract to `v2.1.2`
1. Force `nativeTokenDecimals` to 18

It is assumed that the native token has 18 decimals, since this was a requirement for deploying a custom fee token chain prior to `v2.0.0`.

## Requirements

This upgrade only support upgrading from the following [nitro-contract release](https://github.com/OffchainLabs/nitro-contracts/releases):

- Inbox: v1.1.0 - v1.3.0 inclusive
- Outbox: v1.1.0 - v1.3.0 inclusive
- SequencerInbox: v1.2.1 - v2.1.0 inclusive
- Bridge: v1.1.0 - v1.3.0 inclusive
- RollupProxy: v1.1.0 - v2.1.0 inclusive
- RollupAdminLogic: v2.1.0
- RollupUserLogic: v2.1.0
- ChallengeManager: v2.1.0

Please refer to the top [README](/README.md#check-version-and-upgrade-path) `Check Version and Upgrade Path` on how to determine your current nitro contracts version.

## Deployed instances

### Mainnets
- L1 Mainnet: 0x78Ee30C74B3Ce1aeB38163Db3E7d769d9735542F
- L2 Arb1: 0x7D42F098e79DE006CFAB475cFD50BdF2310d7ae8
- L2 Nova: 0xEb35A5E1B0FdBa925880A539Eac661907d43Ee07
- L2 Base: 0x9d924ffE6D66ca0727657734a615CC9730925c49

### Testnets
- L1 Sepolia: 0xA8a3869A55Baf88f20B81bdbf54eDaC532b98369
- L1 Holesky: 0x619a0B831d61b90a8585CE9B25077021f1fFa925
- L2 ArbSepolia: 0x76A35A0c721A6bf53982f5a00ccb3AaDb184aD8E
- L2 BaseSepolia: 0xA5b663B60502ef6bFFe3e003A43d3E79AFB1aC1c

## How to use it

1. Setup .env according to the example files, make sure you have everything correctly defined. The .env file must be in project root for recent foundry versions.

> [!CAUTION]
> The .env file must be in project root.

2. (Skip this step if you can use the deployed instances of action contract)
`DeployNitroContracts2Point1Point2UpgradeActionScript.s.sol` script deploys templates, and upgrade action itself. It can be executed in this directory like this:

```bash
forge script --sender $DEPLOYER --rpc-url $PARENT_CHAIN_RPC --broadcast --slow DeployNitroContracts2Point1Point2UpgradeActionScript -vvv --verify --skip-simulation
# use --account XXX / --private-key XXX / --interactive / --ledger to set the account to send the transaction from
```

As a result, all templates and upgrade action are deployed. Note the last deployed address - that's the upgrade action.

3. `ExecuteNitroContracts2Point1Point2Upgrade.s.sol` script uses previously deployed upgrade action to execute the upgrade. It makes following assumptions - L1UpgradeExecutor is the rollup owner, and there is an EOA which has executor rights on the L1UpgradeExecutor. Proceed with upgrade using the owner account (the one with executor rights on L1UpgradeExecutor):

```bash
forge script --sender $EXECUTOR --rpc-url $PARENT_CHAIN_RPC --broadcast ExecuteNitroContracts2Point1Point2UpgradeScript -vvv
# use --account XXX / --private-key XXX / --interactive / --ledger to set the account to send the transaction from
```

If you have a multisig as executor, you can still run the above command without broadcasting to get the payload for the multisig transaction.

4. That's it, upgrade has been performed. You can make sure it has successfully executed by checking the native token decimals.

```bash
# should return 18
cast call --rpc-url $PARENT_CHAIN_RPC $BRIDGE "nativeTokenDecimals()(uint8)"
```

## FAQ

### Q: intrinsic gas too low when running foundry script

A: try to add -g 1000 to the command
Loading
Loading