diff --git a/.github/workflows/audit-ci.yml b/.github/workflows/audit-ci.yml index 661d4e37..495d99b1 100644 --- a/.github/workflows/audit-ci.yml +++ b/.github/workflows/audit-ci.yml @@ -10,39 +10,25 @@ on: - develop jobs: - install: - name: 'Install' + yarn-audit: + name: Audit runs-on: ubuntu-latest strategy: matrix: node-version: [18, 20] steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up Node.js - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} - name: Install node_modules uses: OffchainLabs/actions/node-modules/install@main - - yarn-audit: - name: Audit - runs-on: ubuntu-latest - needs: install - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Set up Node.js - uses: actions/setup-node@v3 with: - node-version: ${{ matrix.node-version }} - - - name: Restore node_modules - uses: OffchainLabs/actions/node-modules/restore@main + cache-key: ${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }}-${{ matrix.node-version }} - name: Run audit run: yarn audit:ci diff --git a/.github/workflows/contract-tests.yml b/.github/workflows/contract-tests.yml index 7264a53c..8eba7024 100644 --- a/.github/workflows/contract-tests.yml +++ b/.github/workflows/contract-tests.yml @@ -97,6 +97,12 @@ jobs: - name: Test function signatures run: yarn run test:signatures + - name: Run unused Solidity errors checker + uses: OffchainLabs/actions/check-unused-errors@main + with: + directory: './src' + exceptions_file: './test/unused-errors/exceptions.txt' + - name: Run coverage run: yarn hardhat coverage --testfiles "test/contract/*.spec.ts" @@ -107,6 +113,10 @@ jobs: files: ./contracts/coverage.json verbose: false token: ${{ secrets.CODECOV_TOKEN }} + + - name: Upload 4bytes + run: yarn upload-4bytes + test-4844: name: 4844 tests runs-on: ubuntu-latest @@ -120,7 +130,7 @@ jobs: with: version: nightly - - uses: OffchainLabs/actions/run-nitro-test-node@test-node-args + - uses: OffchainLabs/actions/run-nitro-test-node@main with: nitro-testnode-ref: deneb-integration args: --pos diff --git a/audit-ci.jsonc b/audit-ci.jsonc index f7240916..0e2ab97a 100644 --- a/audit-ci.jsonc +++ b/audit-ci.jsonc @@ -55,6 +55,14 @@ // Prototype Pollution in async "GHSA-fwr7-v2mv-hh25", // ws affected by a DoS when handling a request with many HTTP headers - "GHSA-3h5v-q93c-6h6q" + "GHSA-3h5v-q93c-6h6q", + // Elliptic allows BER-encoded signatures - only used in dev + "GHSA-49q7-c7j4-3p7m", + // Elliptic's EDDSA missing signature length check - only used in dev + "GHSA-f7q4-pwc6-w24p", + // Elliptic's ECDSA missing check for whether leading bit of r and s is zero - only used in dev + "GHSA-977x-g7h5-7qgw", + // Server-Side Request Forgery in axios + "GHSA-8hc4-vh64-cxmj" ] } diff --git a/hardhat.config.ts b/hardhat.config.ts index 8ea9070d..e56c5c1f 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -176,6 +176,6 @@ module.exports = { target: 'ethers-v5', }, contractSizer: { - strict: process.env.STRICT ? true : false, - }, + strict: true + } } diff --git a/package.json b/package.json index b053725f..82fbdb5a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@arbitrum/nitro-contracts", - "version": "1.2.1", + "version": "2.1.0", "description": "Layer 2 precompiles and rollup for Arbitrum Nitro", "author": "Offchain Labs, Inc.", "license": "BUSL-1.1", @@ -27,7 +27,7 @@ "build:forge:sol": "forge build --skip *.yul", "build:forge:yul": "FOUNDRY_PROFILE=yul forge build --skip *.sol", "build:forge": "yarn build:forge:sol && yarn build:forge:yul", - "contract:size": "STRICT=true hardhat size-contracts", + "contract:size": "hardhat size-contracts", "lint:test": "eslint ./test", "solhint": "solhint -f table src/**/*.sol", "prettier:solidity": "prettier --write src/**/*.sol", @@ -42,6 +42,8 @@ "test:e2e": "hardhat test test/e2e/*.ts", "test:upgrade": "./scripts/testUpgrade.bash", "test:foundry": "forge test --gas-limit 10000000000", + "test:update": "yarn run test:signatures || yarn run test:storage", + "upload-4bytes": "forge build && find ./out -type f -name \"*.json\" -exec cast upload-signature {} + | grep -v Duplicated:", "postinstall": "patch-package", "deploy-factory": "hardhat run scripts/deployment.ts", "deploy-eth-rollup": "hardhat run scripts/createEthRollup.ts", diff --git a/scripts/boldUpgradeCommon.ts b/scripts/boldUpgradeCommon.ts index ae9ab9f0..193c5fe0 100644 --- a/scripts/boldUpgradeCommon.ts +++ b/scripts/boldUpgradeCommon.ts @@ -66,7 +66,6 @@ export interface Config { stakeAmt: BigNumber miniStakeAmounts: BigNumber[] chainId: number - anyTrustFastConfirmer: string disableValidatorWhitelist: boolean maxDataSize: number blockLeafSize: number diff --git a/scripts/files/configs/arb1.ts b/scripts/files/configs/arb1.ts index e978769f..b7e5be54 100644 --- a/scripts/files/configs/arb1.ts +++ b/scripts/files/configs/arb1.ts @@ -1,5 +1,5 @@ import { parseEther } from 'ethers/lib/utils' -import { Config } from '../../common' +import { Config } from '../../boldUpgradeCommon' export const arb1: Config = { contracts: { @@ -29,7 +29,6 @@ export const arb1: Config = { stakeAmt: parseEther('3600'), miniStakeAmounts: [parseEther('0'), parseEther('555'), parseEther('79')], chainId: 42161, - anyTrustFastConfirmer: '0x0000000000000000000000000000000000000000', disableValidatorWhitelist: true, blockLeafSize: 1048576, // todo below bigStepLeafSize: 512, diff --git a/scripts/files/configs/local.ts b/scripts/files/configs/local.ts index 80b59cd5..7d09ec61 100644 --- a/scripts/files/configs/local.ts +++ b/scripts/files/configs/local.ts @@ -1,5 +1,5 @@ import { parseEther } from 'ethers/lib/utils' -import { Config } from '../../common' +import { Config } from '../../boldUpgradeCommon' export const local: Config = { contracts: { @@ -34,7 +34,6 @@ export const local: Config = { parseEther('1'), ], chainId: 412346, - anyTrustFastConfirmer: '0x6d903f6003cca6255D85CcA4D3B5E5146dC33925', disableValidatorWhitelist: true, blockLeafSize: 1048576, bigStepLeafSize: 512, diff --git a/scripts/files/configs/nova.ts b/scripts/files/configs/nova.ts index 99a0ddac..6f5c4f22 100644 --- a/scripts/files/configs/nova.ts +++ b/scripts/files/configs/nova.ts @@ -1,5 +1,5 @@ import { parseEther } from 'ethers/lib/utils' -import { Config } from '../../common' +import { Config } from '../../boldUpgradeCommon' export const nova: Config = { contracts: { @@ -34,7 +34,6 @@ export const nova: Config = { parseEther('1'), ], chainId: 42161, - anyTrustFastConfirmer: '0x0000000000000000000000000000000000000000', disableValidatorWhitelist: false, blockLeafSize: 1048576, bigStepLeafSize: 512, diff --git a/scripts/files/configs/sepolia.ts b/scripts/files/configs/sepolia.ts index 5144f4be..6525a9b7 100644 --- a/scripts/files/configs/sepolia.ts +++ b/scripts/files/configs/sepolia.ts @@ -1,5 +1,5 @@ import { parseEther } from 'ethers/lib/utils' -import { Config } from '../../common' +import { Config } from '../../boldUpgradeCommon' export const sepolia: Config = { contracts: { @@ -27,7 +27,6 @@ export const sepolia: Config = { stakeAmt: parseEther('36'), // 1/100th of arb1, same for mini stakes miniStakeAmounts: [parseEther('0'), parseEther('5.5'), parseEther('0.79')], chainId: 421614, - anyTrustFastConfirmer: '0x0000000000000000000000000000000000000000', disableValidatorWhitelist: false, blockLeafSize: 2 ** 26, // leaf sizes same as arb1 bigStepLeafSize: 2 ** 19, diff --git a/scripts/rollupCreation.ts b/scripts/rollupCreation.ts index dabc7816..b737d626 100644 --- a/scripts/rollupCreation.ts +++ b/scripts/rollupCreation.ts @@ -321,7 +321,6 @@ async function _getDevRollupConfig( layerZeroBlockEdgeHeight: 2 ** 5, layerZeroBigStepEdgeHeight: 2 ** 5, layerZeroSmallStepEdgeHeight: 2 ** 5, - anyTrustFastConfirmer: ethers.constants.AddressZero, numBigStepLevel: 1, challengeGracePeriodBlocks: 10, bufferConfig: { threshold: 600, max: 14400, replenishRateInBasis: 500 }, diff --git a/scripts/testLocalExecuteBoldUpgrade.ts b/scripts/testLocalExecuteBoldUpgrade.ts index e102b894..58510e96 100644 --- a/scripts/testLocalExecuteBoldUpgrade.ts +++ b/scripts/testLocalExecuteBoldUpgrade.ts @@ -448,14 +448,12 @@ async function checkNewRollup( throw new Error('Base stake does not match') } - // check fast confirmer - if (config.settings.anyTrustFastConfirmer.length != 0) { - if ( - getAddress(await newRollup.anyTrustFastConfirmer()) !== - getAddress(config.settings.anyTrustFastConfirmer) - ) { - throw new Error('Any trust fast confirmer does not match') - } + // check fast confirmer (must be 0 for the local chain) + if ( + getAddress(await newRollup.anyTrustFastConfirmer()) !== + ethers.constants.AddressZero + ) { + throw new Error('Any trust fast confirmer does not match') } } diff --git a/src/rollup/BOLDUpgradeAction.sol b/src/rollup/BOLDUpgradeAction.sol index 879282ae..c43cb277 100644 --- a/src/rollup/BOLDUpgradeAction.sol +++ b/src/rollup/BOLDUpgradeAction.sol @@ -72,6 +72,7 @@ interface IOldRollup { function getStaker(address staker) external view returns (OldStaker memory); function isValidator(address validator) external view returns (bool); function validatorWalletCreator() external view returns (address); + function anyTrustFastConfirmer() external view returns (address); } interface IOldRollupAdmin { @@ -168,6 +169,10 @@ contract RollupReader is IOldRollup { function validatorWalletCreator() external view returns (address) { return rollup.validatorWalletCreator(); } + + function anyTrustFastConfirmer() external view returns (address) { + return rollup.anyTrustFastConfirmer(); + } } /// @notice Stores an array specified during construction. @@ -210,7 +215,6 @@ contract BOLDUpgradeAction { address public immutable STAKE_TOKEN; uint256 public immutable STAKE_AMOUNT; uint256 public immutable CHAIN_ID; - address public immutable ANY_TRUST_FAST_CONFIRMER; bool public immutable DISABLE_VALIDATOR_WHITELIST; uint64 public immutable CHALLENGE_GRACE_PERIOD_BLOCKS; address public immutable MINI_STAKE_AMOUNTS_STORAGE; @@ -252,7 +256,6 @@ contract BOLDUpgradeAction { uint256 stakeAmt; uint256[] miniStakeAmounts; uint256 chainId; - address anyTrustFastConfirmer; bool disableValidatorWhitelist; uint256 blockLeafSize; uint256 bigStepLeafSize; @@ -334,7 +337,6 @@ contract BOLDUpgradeAction { STAKE_TOKEN = settings.stakeToken; STAKE_AMOUNT = settings.stakeAmt; MINI_STAKE_AMOUNTS_STORAGE = address(new ConstantArrayStorage(settings.miniStakeAmounts)); - ANY_TRUST_FAST_CONFIRMER = settings.anyTrustFastConfirmer; DISABLE_VALIDATOR_WHITELIST = settings.disableValidatorWhitelist; BLOCK_LEAF_SIZE = settings.blockLeafSize; BIGSTEP_LEAF_SIZE = settings.bigStepLeafSize; @@ -419,7 +421,7 @@ contract BOLDUpgradeAction { layerZeroSmallStepEdgeHeight: SMALLSTEP_LEAF_SIZE, genesisAssertionState: genesisAssertionState, genesisInboxCount: inboxMaxCount, - anyTrustFastConfirmer: ANY_TRUST_FAST_CONFIRMER, + anyTrustFastConfirmer: address(0), // fast confirmer would be migrated from the old rollup if existed numBigStepLevel: NUM_BIGSTEP_LEVEL, challengeGracePeriodBlocks: CHALLENGE_GRACE_PERIOD_BLOCKS, bufferConfig: bufferConfig @@ -587,6 +589,15 @@ contract BOLDUpgradeAction { IRollupAdmin(address(rollup)).setValidatorWhitelistDisabled(DISABLE_VALIDATOR_WHITELIST); } + // anyTrustFastConfirmer only exists since v2.0.0, but the old rollup can be on an older version + try ROLLUP_READER.anyTrustFastConfirmer() returns (address anyTrustFastConfirmer) { + if(anyTrustFastConfirmer != address(0)) { + IRollupAdmin(address(rollup)).setAnyTrustFastConfirmer(anyTrustFastConfirmer); + } + } catch { + // do nothing if anyTrustFastConfirmer doesnt exist + } + IRollupAdmin(address(rollup)).setOwner(actualOwner); emit RollupMigrated(expectedRollupAddress, address(challengeManager)); diff --git a/src/rollup/IRollupAdmin.sol b/src/rollup/IRollupAdmin.sol index eb8faa91..2a2cced4 100644 --- a/src/rollup/IRollupAdmin.sol +++ b/src/rollup/IRollupAdmin.sol @@ -178,6 +178,12 @@ interface IRollupAdmin { */ function setValidatorWhitelistDisabled(bool _validatorWhitelistDisabled) external; + /** + * @notice set the anyTrustFastConfirmer address + * @param _anyTrustFastConfirmer new value of anyTrustFastConfirmer + */ + function setAnyTrustFastConfirmer(address _anyTrustFastConfirmer) external; + /** * @notice set a new challengeManager contract * @param _challengeManager new value of challengeManager diff --git a/test/unused-errors/exceptions.txt b/test/unused-errors/exceptions.txt new file mode 100644 index 00000000..49748d79 --- /dev/null +++ b/test/unused-errors/exceptions.txt @@ -0,0 +1,13 @@ +Custom +Unused +NoTicketWithID +NotCallable +InvalidBlockNumber +ProgramExpired +ProgramInsufficientValue +ProgramKeepaliveTooSoon +ProgramNeedsUpgrade +ProgramNotActivated +ProgramNotWasm +ProgramUpToDate +CallerNotArbOS