From 7d0fca1ac6cbaac144132216827bf26576177286 Mon Sep 17 00:00:00 2001 From: Goran Vladika Date: Fri, 12 Jul 2024 15:07:49 +0200 Subject: [PATCH 01/11] Add script that gets metadata hashses for selected contracts --- scripts/printMetadataHashes.ts | 65 ++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 scripts/printMetadataHashes.ts diff --git a/scripts/printMetadataHashes.ts b/scripts/printMetadataHashes.ts new file mode 100644 index 00000000..ae9e3aa0 --- /dev/null +++ b/scripts/printMetadataHashes.ts @@ -0,0 +1,65 @@ +import path from 'path' +import fs from 'fs-extra' +import hre from 'hardhat' + +main() + .then(() => process.exit(0)) + .catch((error: Error) => { + console.error(error) + process.exit(1) + }) + +async function main() { + const contracts: string[] = [ + 'Inbox', + 'Outbox', + 'SequencerInbox', + 'Bridge', + 'ERC20Inbox', + 'ERC20Outbox', + 'SequencerInbox', + 'ERC20Bridge', + 'RollupProxy', + 'RollupAdminLogic', + 'RollupUserLogic', + 'ChallengeManager', + ] + + console.log('HARDHAT:') + for (const contract of contracts) { + const hash = await _getHardhatMetadataHash(contract) + console.log(`${contract}: ${hash}`) + } + + console.log('\nFOUNDRY:') + for (const contract of contracts) { + const hash = await _getFoundryMetadataHash(contract) + console.log(`${contract}: ${hash}`) + } +} + +async function _getHardhatMetadataHash(contractName: string): Promise { + const artifact = await hre.artifacts.readArtifact(contractName) + return _extractMetadataHash(artifact.bytecode) +} + +async function _getFoundryMetadataHash(contractName: string): Promise { + const artifactPath = path.join( + 'out', + `${contractName}.sol`, + `${contractName}.json` + ) + const artifact = await fs.readJson(artifactPath) + return _extractMetadataHash(artifact.bytecode.object) +} + +function _extractMetadataHash(bytecode: string): string { + const metadataPattern = /a264697066735822([a-fA-F0-9]{64})/ + const matches = bytecode.match(metadataPattern) + + if (matches && matches.length > 1) { + return matches[1] + } else { + throw new Error('No metadata hash found in bytecode') + } +} From aa37d524a8c7804bc4f12a78e56aacb3b6dc76ce Mon Sep 17 00:00:00 2001 From: gzeon Date: Tue, 6 Aug 2024 21:11:02 +0900 Subject: [PATCH 02/11] chore: verification improvements --- hardhat.config.ts | 10 +++++----- package.json | 2 +- scripts/createEthRollup.ts | 2 +- scripts/deploymentUtils.ts | 26 +++++++++++++++++++++++-- scripts/rollupCreation.ts | 24 ++++++++--------------- src/mocks/BridgeUnproxied.sol | 2 ++ yarn.lock | 36 +++++++++++++++++++---------------- 7 files changed, 61 insertions(+), 41 deletions(-) diff --git a/hardhat.config.ts b/hardhat.config.ts index 35c7adc8..ff6034d4 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -1,7 +1,7 @@ import '@nomiclabs/hardhat-waffle' import 'hardhat-deploy' import '@nomiclabs/hardhat-ethers' -import '@nomiclabs/hardhat-etherscan' +import '@nomicfoundation/hardhat-verify' import '@typechain/hardhat' import 'solidity-coverage' import 'hardhat-gas-reporter' @@ -183,8 +183,8 @@ module.exports = { network: 'arbSepolia', chainId: 421614, urls: { - apiURL: 'https://sepolia-explorer.arbitrum.io/api', - browserURL: 'https://sepolia-explorer.arbitrum.io/', + apiURL: 'https://api-sepolia.arbiscan.io/api', + browserURL: 'https://sepolia.arbiscan.io/', }, }, ], @@ -200,6 +200,6 @@ module.exports = { target: 'ethers-v5', }, contractSizer: { - strict: true - } + strict: true, + }, } diff --git a/package.json b/package.json index ef489de8..10d0b4d6 100644 --- a/package.json +++ b/package.json @@ -57,8 +57,8 @@ "devDependencies": { "@arbitrum/sdk": "^3.4.1", "@ethersproject/providers": "^5.7.2", + "@nomicfoundation/hardhat-verify": "^2.0.9", "@nomiclabs/hardhat-ethers": "npm:hardhat-deploy-ethers@^0.3.0-beta.13", - "@nomiclabs/hardhat-etherscan": "^3.1.0", "@nomiclabs/hardhat-waffle": "^2.0.1", "@tovarishfin/hardhat-yul": "^3.0.5", "@typechain/ethers-v5": "^10.0.0", diff --git a/scripts/createEthRollup.ts b/scripts/createEthRollup.ts index 4248ac21..c76af5dd 100644 --- a/scripts/createEthRollup.ts +++ b/scripts/createEthRollup.ts @@ -3,7 +3,7 @@ import '@nomiclabs/hardhat-ethers' import { createRollup } from './rollupCreation' async function main() { - const feeToken = undefined + const feeToken = ethers.constants.AddressZero const rollupCreatorAddress = process.env.ROLLUP_CREATOR_ADDRESS if (!rollupCreatorAddress) { throw new Error('ROLLUP_CREATOR_ADDRESS not set') diff --git a/scripts/deploymentUtils.ts b/scripts/deploymentUtils.ts index 582ae67d..5c4ca3e5 100644 --- a/scripts/deploymentUtils.ts +++ b/scripts/deploymentUtils.ts @@ -32,9 +32,11 @@ export async function verifyContract( contract?: string address: string constructorArguments: any[] + force: boolean } = { address: contractAddress, constructorArguments: constructorArguments, + force: true, } // if contractPathAndName is provided, add it to the verification options @@ -45,8 +47,15 @@ export async function verifyContract( await run('verify:verify', verificationOptions) console.log(`Verified contract ${contractName} successfully.`) } catch (error: any) { - if (error.message.includes('Already Verified')) { + if (error.message.toLowerCase().includes('already verified')) { console.log(`Contract ${contractName} is already verified.`) + } else if (error.message.includes('does not have bytecode')) { + await verifyContract( + contractName, + contractAddress, + constructorArguments, + contractPathAndName + ) } else { console.error( `Verification for ${contractName} failed with the following error: ${error.message}` @@ -73,7 +82,11 @@ export async function deployContract( const contract: Contract = await connectedFactory.deploy(...deploymentArgs) await contract.deployTransaction.wait() - console.log(`New ${contractName} created at address:`, contract.address) + console.log( + `* New ${contractName} created at address: ${ + contract.address + } ${constructorArgs.join(' ')}` + ) if (verify) await verifyContract(contractName, contract.address, constructorArgs) @@ -226,6 +239,15 @@ export async function deployAllContracts( verify ) const deployHelper = await deployContract('DeployHelper', signer, [], verify) + if (verify && !process.env.DISABLE_VERIFICATION) { + // Deploy RollupProxy contract only for verification, should not be used anywhere else + await deployContract( + 'RollupProxy', + signer, + [], + verify + ) + } return { bridgeCreator, prover0, diff --git a/scripts/rollupCreation.ts b/scripts/rollupCreation.ts index e70b82dc..ce16290f 100644 --- a/scripts/rollupCreation.ts +++ b/scripts/rollupCreation.ts @@ -7,7 +7,7 @@ import { BigNumber, Signer } from 'ethers' import { ERC20, ERC20__factory, IERC20__factory } from '../build/types' import { sleep } from './testSetup' import { promises as fs } from 'fs' -import { _isRunningOnArbitrum } from './deploymentUtils' +import { _isRunningOnArbitrum, verifyContract } from './deploymentUtils' // 1 gwei const MAX_FER_PER_GAS = BigNumber.from('1000000000') @@ -149,21 +149,13 @@ export async function createRollup( console.log( `Attempting to verify Rollup contract at address ${rollupAddress}...` ) - try { - await run('verify:verify', { - contract: 'src/rollup/RollupProxy.sol:RollupProxy', - address: rollupAddress, - constructorArguments: [], - }) - } catch (error: any) { - if (error.message.includes('Already Verified')) { - console.log(`Contract RollupProxy is already verified.`) - } else { - console.error( - `Verification for RollupProxy failed with the following error: ${error.message}` - ) - } - } + + await verifyContract( + 'RollupProxy', + rollupAddress, + [], + 'src/rollup/RollupProxy.sol:RollupProxy' + ) } console.log('Inbox (proxy) Contract created at address:', inboxAddress) diff --git a/src/mocks/BridgeUnproxied.sol b/src/mocks/BridgeUnproxied.sol index 75aecfe1..fbdb13fc 100644 --- a/src/mocks/BridgeUnproxied.sol +++ b/src/mocks/BridgeUnproxied.sol @@ -10,6 +10,8 @@ import {BadSequencerMessageNumber} from "../libraries/Error.sol"; import "../bridge/Bridge.sol"; contract BridgeUnproxied is Bridge { + uint256 public DUMMYVAR = 0; // This is a dummy variable to disambiguous with the Bridge contract + constructor() { _activeOutbox = EMPTY_ACTIVEOUTBOX; rollup = IOwnable(msg.sender); diff --git a/yarn.lock b/yarn.lock index 00d8467d..06a9ee89 100644 --- a/yarn.lock +++ b/yarn.lock @@ -802,6 +802,21 @@ "@nomicfoundation/ethereumjs-rlp" "5.0.4" ethereum-cryptography "0.1.3" +"@nomicfoundation/hardhat-verify@^2.0.9": + version "2.0.9" + resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-verify/-/hardhat-verify-2.0.9.tgz#98a1c9a3742b008be71a709d074f10dec23bc5f0" + integrity sha512-7kD8hu1+zlnX87gC+UN4S0HTKBnIsDfXZ/pproq1gYsK94hgCk+exvzXbwR0X2giiY/RZPkqY9oKRi0Uev91hQ== + dependencies: + "@ethersproject/abi" "^5.1.2" + "@ethersproject/address" "^5.0.2" + cbor "^8.1.0" + chalk "^2.4.2" + debug "^4.1.1" + lodash.clonedeep "^4.5.0" + semver "^6.3.0" + table "^6.8.0" + undici "^5.14.0" + "@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.2": version "0.1.2" resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.2.tgz#3a9c3b20d51360b20affb8f753e756d553d49557" @@ -864,22 +879,6 @@ resolved "https://registry.yarnpkg.com/hardhat-deploy-ethers/-/hardhat-deploy-ethers-0.3.0-beta.13.tgz#b96086ff768ddf69928984d5eb0a8d78cfca9366" integrity sha512-PdWVcKB9coqWV1L7JTpfXRCI91Cgwsm7KLmBcwZ8f0COSm1xtABHZTyz3fvF6p42cTnz1VM0QnfDvMFlIRkSNw== -"@nomiclabs/hardhat-etherscan@^3.1.0": - version "3.1.8" - resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-3.1.8.tgz#3c12ee90b3733e0775e05111146ef9418d4f5a38" - integrity sha512-v5F6IzQhrsjHh6kQz4uNrym49brK9K5bYCq2zQZ729RYRaifI9hHbtmK+KkIVevfhut7huQFEQ77JLRMAzWYjQ== - dependencies: - "@ethersproject/abi" "^5.1.2" - "@ethersproject/address" "^5.0.2" - cbor "^8.1.0" - chalk "^2.4.2" - debug "^4.1.1" - fs-extra "^7.0.1" - lodash "^4.17.11" - semver "^6.3.0" - table "^6.8.0" - undici "^5.14.0" - "@nomiclabs/hardhat-waffle@^2.0.1": version "2.0.6" resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-waffle/-/hardhat-waffle-2.0.6.tgz#d11cb063a5f61a77806053e54009c40ddee49a54" @@ -4771,6 +4770,11 @@ lodash.camelcase@^4.3.0: resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY= +lodash.clonedeep@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" + integrity sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ== + lodash.merge@^4.6.2: version "4.6.2" resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" From af7ef125b342985ab3b26299affc1260dfae0828 Mon Sep 17 00:00:00 2001 From: gzeon Date: Wed, 7 Aug 2024 17:58:15 +0900 Subject: [PATCH 03/11] chore: change rinkeby to holesky --- hardhat.config.ts | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/hardhat.config.ts b/hardhat.config.ts index ff6034d4..3599427d 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -110,8 +110,8 @@ module.exports = { ? [process.env['DEVNET_PRIVKEY']] : [], }, - rinkeby: { - url: 'https://rinkeby.infura.io/v3/' + process.env['INFURA_KEY'], + holesky: { + url: 'https://holesky.infura.io/v3/' + process.env['INFURA_KEY'], accounts: process.env['DEVNET_PRIVKEY'] ? [process.env['DEVNET_PRIVKEY']] : [], @@ -146,6 +146,18 @@ module.exports = { ? [process.env['MAINNET_PRIVKEY']] : [], }, + base: { + url: 'https://mainnet.base.org', + accounts: process.env['MAINNET_PRIVKEY'] + ? [process.env['MAINNET_PRIVKEY']] + : [], + }, + baseSepolia: { + url: 'https://sepolia.base.org', + accounts: process.env['DEVNET_PRIVKEY'] + ? [process.env['DEVNET_PRIVKEY']] + : [], + }, geth: { url: 'http://localhost:8545', }, @@ -155,12 +167,14 @@ module.exports = { mainnet: process.env['ETHERSCAN_API_KEY'], goerli: process.env['ETHERSCAN_API_KEY'], sepolia: process.env['ETHERSCAN_API_KEY'], - rinkeby: process.env['ETHERSCAN_API_KEY'], + holesky: process.env['ETHERSCAN_API_KEY'], arbitrumOne: process.env['ARBISCAN_API_KEY'], arbitrumTestnet: process.env['ARBISCAN_API_KEY'], nova: process.env['NOVA_ARBISCAN_API_KEY'], arbGoerliRollup: process.env['ARBISCAN_API_KEY'], arbSepolia: process.env['ARBISCAN_API_KEY'], + base: process.env['BASESCAN_API_KEY'], + baseSepolia: process.env['BASESCAN_API_KEY'], }, customChains: [ { From 28047135ec5c47f68cff5790aa60a1bab428ef5f Mon Sep 17 00:00:00 2001 From: gzeon Date: Wed, 7 Aug 2024 17:58:33 +0900 Subject: [PATCH 04/11] chore: max data size warning --- scripts/deployment.ts | 20 ++++++++++++++++++++ scripts/deploymentUtils.ts | 6 ++++++ 2 files changed, 26 insertions(+) diff --git a/scripts/deployment.ts b/scripts/deployment.ts index 8da3acc2..76918567 100644 --- a/scripts/deployment.ts +++ b/scripts/deployment.ts @@ -3,8 +3,28 @@ import '@nomiclabs/hardhat-ethers' import { deployAllContracts } from './deploymentUtils' import { maxDataSize } from './config' +import { + ArbSys__factory +} from '../build/types' + async function main() { const [signer] = await ethers.getSigners() + + if (process.env['IGNORE_MAX_DATA_SIZE_WARNING'] !== 'true') { + let isArbitrum = false + try { + await ArbSys__factory.connect('0x0000000000000000000000000000000000000064', signer).arbOSVersion() + // on arbitrum chain + isArbitrum = true + } catch (error) { + isArbitrum = false + } + if (isArbitrum && maxDataSize as any !== 104857) { + throw new Error('maxDataSize should be 104857 when the parent chain is Arbitrum (set IGNORE_MAX_DATA_SIZE_WARNING to ignore)') + } else if (!isArbitrum && maxDataSize as any !== 117964) { + throw new Error('maxDataSize should be 117964 when the parent chain is not Arbitrum (set IGNORE_MAX_DATA_SIZE_WARNING to ignore)') + } + } try { // Deploying all contracts diff --git a/scripts/deploymentUtils.ts b/scripts/deploymentUtils.ts index 5c4ca3e5..4a63e744 100644 --- a/scripts/deploymentUtils.ts +++ b/scripts/deploymentUtils.ts @@ -78,6 +78,12 @@ export async function deployContract( let deploymentArgs = [...constructorArgs] if (overrides) { deploymentArgs.push(overrides) + } else { + // overrides = { + // maxFeePerGas: ethers.utils.parseUnits('5.0', 'gwei'), + // maxPriorityFeePerGas: ethers.utils.parseUnits('0.01', 'gwei') + // } + // deploymentArgs.push(overrides) } const contract: Contract = await connectedFactory.deploy(...deploymentArgs) From 4716d660e1e0c8ae4c853746c66715b27b075b5b Mon Sep 17 00:00:00 2001 From: gzeon Date: Wed, 7 Aug 2024 17:59:58 +0900 Subject: [PATCH 05/11] refactor: use _isRunningOnArbitrum --- scripts/deployment.ts | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/scripts/deployment.ts b/scripts/deployment.ts index 76918567..5578a7b2 100644 --- a/scripts/deployment.ts +++ b/scripts/deployment.ts @@ -1,6 +1,6 @@ import { ethers } from 'hardhat' import '@nomiclabs/hardhat-ethers' -import { deployAllContracts } from './deploymentUtils' +import { deployAllContracts, _isRunningOnArbitrum } from './deploymentUtils' import { maxDataSize } from './config' import { @@ -11,14 +11,7 @@ async function main() { const [signer] = await ethers.getSigners() if (process.env['IGNORE_MAX_DATA_SIZE_WARNING'] !== 'true') { - let isArbitrum = false - try { - await ArbSys__factory.connect('0x0000000000000000000000000000000000000064', signer).arbOSVersion() - // on arbitrum chain - isArbitrum = true - } catch (error) { - isArbitrum = false - } + let isArbitrum = await _isRunningOnArbitrum(signer) if (isArbitrum && maxDataSize as any !== 104857) { throw new Error('maxDataSize should be 104857 when the parent chain is Arbitrum (set IGNORE_MAX_DATA_SIZE_WARNING to ignore)') } else if (!isArbitrum && maxDataSize as any !== 117964) { From ba1ef169f8bb0e3fe86f0625f979aac20c0d6c5a Mon Sep 17 00:00:00 2001 From: gzeon Date: Wed, 7 Aug 2024 18:00:28 +0900 Subject: [PATCH 06/11] chore: additional logging --- scripts/deployment.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/deployment.ts b/scripts/deployment.ts index 5578a7b2..5ec530fe 100644 --- a/scripts/deployment.ts +++ b/scripts/deployment.ts @@ -10,6 +10,7 @@ import { async function main() { const [signer] = await ethers.getSigners() + console.log('Deploying contracts with maxDataSize:', maxDataSize) if (process.env['IGNORE_MAX_DATA_SIZE_WARNING'] !== 'true') { let isArbitrum = await _isRunningOnArbitrum(signer) if (isArbitrum && maxDataSize as any !== 104857) { @@ -17,6 +18,8 @@ async function main() { } else if (!isArbitrum && maxDataSize as any !== 117964) { throw new Error('maxDataSize should be 117964 when the parent chain is not Arbitrum (set IGNORE_MAX_DATA_SIZE_WARNING to ignore)') } + } else { + console.log('Ignoring maxDataSize warning') } try { From 47989be933f4720a80d39c7da42a97b0cfdf7311 Mon Sep 17 00:00:00 2001 From: Goran Vladika Date: Mon, 12 Aug 2024 10:40:04 +0200 Subject: [PATCH 07/11] Add option to enable CacheManager through UpgradeExecutor --- scripts/deploymentUtils.ts | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/scripts/deploymentUtils.ts b/scripts/deploymentUtils.ts index 582ae67d..b8748d81 100644 --- a/scripts/deploymentUtils.ts +++ b/scripts/deploymentUtils.ts @@ -1,5 +1,5 @@ import { ethers } from 'hardhat' -import { ContractFactory, Contract, Overrides, BigNumber } from 'ethers' +import { ContractFactory, Contract, Overrides, BigNumber, Wallet } from 'ethers' import '@nomiclabs/hardhat-ethers' import { run } from 'hardhat' import { @@ -245,7 +245,7 @@ export async function deployAllContracts( } export async function deployAndSetCacheManager( - chainOwnerWallet: any, + chainOwnerWallet: Wallet, verify: boolean = true ) { const cacheManagerLogic = await deployContract( @@ -280,7 +280,23 @@ export async function deployAndSetCacheManager( ARB_OWNER_ADDRESS, chainOwnerWallet ) - await (await arbOwner.addWasmCacheManager(cacheManagerProxy.address)).wait() + + const arbOwnerAccount = (await arbOwner.getAllChainOwners())[0] + if ((await chainOwnerWallet.provider.getCode(arbOwnerAccount)) === '0x') { + // arb owner is EOA, add cache manager directly + await (await arbOwner.addWasmCacheManager(cacheManagerProxy.address)).wait() + } else { + // assume upgrade executor is arb owner + const upgradeExecutor = new ethers.Contract( + arbOwnerAccount, + UpgradeExecutorABI, + chainOwnerWallet + ) + const data = arbOwner.interface.encodeFunctionData('addWasmCacheManager', [ + cacheManagerProxy.address, + ]) + await (await upgradeExecutor.executeCall(ARB_OWNER_ADDRESS, data)).wait() + } return cacheManagerProxy } From 99c07a7db2fcce75b751c5a2bd4936e898cda065 Mon Sep 17 00:00:00 2001 From: Goran Vladika Date: Mon, 12 Aug 2024 13:27:12 +0200 Subject: [PATCH 08/11] Use arb owner public to poll for chain owners --- scripts/deploymentUtils.ts | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/scripts/deploymentUtils.ts b/scripts/deploymentUtils.ts index b8748d81..4f1198e4 100644 --- a/scripts/deploymentUtils.ts +++ b/scripts/deploymentUtils.ts @@ -9,6 +9,7 @@ import { import { Toolkit4844 } from '../test/contract/toolkit4844' import { ArbOwner__factory, + ArbOwnerPublic__factory, ArbSys__factory, CacheManager__factory, } from '../build/types' @@ -16,6 +17,7 @@ import { const INIT_CACHE_SIZE = 536870912 const INIT_DECAY = 10322197911 const ARB_OWNER_ADDRESS = '0x0000000000000000000000000000000000000070' +const ARB_OWNER_PUBLIC_ADDRESS = '0x000000000000000000000000000000000000006b' const ARB_SYS_ADDRESS = '0x0000000000000000000000000000000000000064' // Define a verification function @@ -248,20 +250,19 @@ export async function deployAndSetCacheManager( chainOwnerWallet: Wallet, verify: boolean = true ) { + // deploy CacheManager const cacheManagerLogic = await deployContract( 'CacheManager', chainOwnerWallet, [], verify ) - const proxyAdmin = await deployContract( 'ProxyAdmin', chainOwnerWallet, [], verify ) - const cacheManagerProxy = await deployContract( 'TransparentUpgradeableProxy', chainOwnerWallet, @@ -269,22 +270,30 @@ export async function deployAndSetCacheManager( verify ) + // initialize CacheManager const cacheManager = CacheManager__factory.connect( cacheManagerProxy.address, chainOwnerWallet ) - await (await cacheManager.initialize(INIT_CACHE_SIZE, INIT_DECAY)).wait() - const arbOwner = ArbOwner__factory.connect( + /// add CacheManager to ArbOwner + const arbOwnerAccount = ( + await ArbOwnerPublic__factory.connect( + ARB_OWNER_PUBLIC_ADDRESS, + chainOwnerWallet + ).getAllChainOwners() + )[0] + + const arbOwnerPrecompile = ArbOwner__factory.connect( ARB_OWNER_ADDRESS, chainOwnerWallet ) - - const arbOwnerAccount = (await arbOwner.getAllChainOwners())[0] if ((await chainOwnerWallet.provider.getCode(arbOwnerAccount)) === '0x') { // arb owner is EOA, add cache manager directly - await (await arbOwner.addWasmCacheManager(cacheManagerProxy.address)).wait() + await ( + await arbOwnerPrecompile.addWasmCacheManager(cacheManagerProxy.address) + ).wait() } else { // assume upgrade executor is arb owner const upgradeExecutor = new ethers.Contract( @@ -292,9 +301,10 @@ export async function deployAndSetCacheManager( UpgradeExecutorABI, chainOwnerWallet ) - const data = arbOwner.interface.encodeFunctionData('addWasmCacheManager', [ - cacheManagerProxy.address, - ]) + const data = arbOwnerPrecompile.interface.encodeFunctionData( + 'addWasmCacheManager', + [cacheManagerProxy.address] + ) await (await upgradeExecutor.executeCall(ARB_OWNER_ADDRESS, data)).wait() } From 811a4b2e574fbed034552647fc8bc287f2556f95 Mon Sep 17 00:00:00 2001 From: Goran Vladika Date: Tue, 13 Aug 2024 14:06:09 +0200 Subject: [PATCH 09/11] Update natspec --- src/rollup/RollupCreator.sol | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/rollup/RollupCreator.sol b/src/rollup/RollupCreator.sol index 61351cfe..fca3f245 100644 --- a/src/rollup/RollupCreator.sol +++ b/src/rollup/RollupCreator.sol @@ -40,7 +40,6 @@ contract RollupCreator is Ownable { address nativeToken; bool deployFactoriesToL2; uint256 maxFeePerGasForRetryables; - //// @dev The address of the batch poster, not used when set to zero address address[] batchPosters; address batchPosterManager; } @@ -92,11 +91,11 @@ contract RollupCreator is Ownable { * @dev - UpgradeExecutor should be the owner of proxyAdmin which manages bridge contracts * @dev - config.rollupOwner should have executor role on upgradeExecutor * @dev - Bridge should have a single inbox and outbox - * @dev - Validators and batch poster should be set if provided + * @dev - Validators, batch posters and batch poster manager should be set if provided * @param deployParams The parameters for the rollup deployment. It consists of: * - config The configuration for the rollup - * - batchPoster The address of the batch poster, not used when set to zero address * - validators The list of validator addresses, not used when set to empty list + * - maxDataSize Max size of the calldata that can be posted * - nativeToken Address of the custom fee token used by rollup. If rollup is ETH-based address(0) should be provided * - deployFactoriesToL2 Whether to deploy L2 factories using retryable tickets. If true, retryables need to be paid for in native currency. * Deploying factories via retryable tickets at rollup creation time is the most reliable method to do it since it @@ -104,7 +103,8 @@ contract RollupCreator is Ownable { * anyone can try to deploy factories and potentially burn the nonce 0 (ie. due to gas price spike when doing direct * L2 TX). That would mean we permanently lost capability to deploy deterministic factory at expected address. * - maxFeePerGasForRetryables price bid for L2 execution. - * - dataHashReader The address of the data hash reader used to read blob hashes + * - batchPosters The list of batch poster addresses, not used when set to empty list + * - batchPosterManager The address which has the ability to rotate batch poster keys * @return The address of the newly created rollup */ function createRollup(RollupDeploymentParams memory deployParams) From 0cfe59281aaa2a4cb41475947d8cc3945b543a25 Mon Sep 17 00:00:00 2001 From: Goran Vladika Date: Tue, 13 Aug 2024 14:31:31 +0200 Subject: [PATCH 10/11] Update audit-ci.json --- audit-ci.jsonc | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/audit-ci.jsonc b/audit-ci.jsonc index f7240916..3b7a12b3 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 + "GHSA-49q7-c7j4-3p7m", + // Elliptic's ECDSA missing check for whether leading bit of r and s is zero + "GHSA-977x-g7h5-7qgw", + // Elliptic's EDDSA missing signature length check + "GHSA-f7q4-pwc6-w24p", + // Server-Side Request Forgery in axios + "GHSA-8hc4-vh64-cxmj" ] } From 3411f9326316e69a46e2573727c2bac2675a8fb9 Mon Sep 17 00:00:00 2001 From: gzeon Date: Fri, 16 Aug 2024 20:36:26 +0900 Subject: [PATCH 11/11] feat: check integrity before outputing metadata hashes --- package.json | 1 + scripts/printMetadataHashes.ts | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/package.json b/package.json index 3f36aeb7..fc03e23c 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "test:signatures": "./test/signatures/test-sigs.bash", "test:e2e": "hardhat test test/e2e/*.ts", "test:update": "yarn run test:signatures || yarn run test:storage", + "metadatahash": "yarn build:all && hardhat run scripts/printMetadataHashes.ts", "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", diff --git a/scripts/printMetadataHashes.ts b/scripts/printMetadataHashes.ts index ae9e3aa0..b1e1b876 100644 --- a/scripts/printMetadataHashes.ts +++ b/scripts/printMetadataHashes.ts @@ -1,6 +1,7 @@ import path from 'path' import fs from 'fs-extra' import hre from 'hardhat' +import { execSync } from 'child_process' main() .then(() => process.exit(0)) @@ -25,6 +26,30 @@ async function main() { 'ChallengeManager', ] + // Print the current git tag + const gitTag = execSync('git describe --tags').toString().trim() + console.log(`Current tag: ${gitTag}`) + + // Check if yarn packages match yarn.lock + try { + execSync('yarn install --check-files', { stdio: 'ignore' }) + } catch (e) { + console.error('Yarn packages does not match yarn.lock') + process.exit(1) + } + + // Check if the current working directory is clean + try { + execSync('git update-index --really-refresh', { stdio: 'ignore' }) + if (execSync('git status --porcelain').toString().trim()) { + console.error('The current working directory have staged changes.') + process.exit(1) + } + } catch (e) { + console.error('The current working directory is not clean.') + process.exit(1) + } + console.log('HARDHAT:') for (const contract of contracts) { const hash = await _getHardhatMetadataHash(contract)