Skip to content

Commit 86b6439

Browse files
authored
feat: update wasm module root for consensus v51.1 (#644)
1 parent c85014b commit 86b6439

File tree

9 files changed

+315
-156
lines changed

9 files changed

+315
-156
lines changed

audit-ci.jsonc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,11 @@
7272
// https://github.com/cryptocoinjs/secp256k1-node/commit/dc37f41f2abfe87853b54bcd7d1b556db41b0c64#diff-7ae45ad102eab3b6d7e7896acd08c427a9b25b346470d7bc6507b6481575d519R35
7373
// from: @arbitrum/token-bridge-contracts > @openzeppelin/upgrades-core > ethereumjs-util > ethereum-cryptography
7474
"GHSA-584q-6j8j-r5pm",
75+
// https://github.com/advisories/GHSA-848j-6mx2-7j84
76+
// elliptic has no patched release yet (affected: <=6.6.1)
77+
// transitive via ethereumjs-util -> ethereum-cryptography -> secp256k1 -> elliptic
78+
// from: @safe-global/protocol-kit>ethereumjs-util>ethereum-cryptography>secp256k1>elliptic
79+
"GHSA-848j-6mx2-7j84",
7580
// https://github.com/advisories/GHSA-3xgq-45jj-v275
7681
// cross-spawn command injection vulnerability
7782
// Only used during development via audit-ci, nyc, and patch-package

src/createRollupPrepareDeploymentParamsConfig/__snapshots__/v2.1.unit.test.ts.snap

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ exports[`creates a config for a chain on top of a custom parent chain 1`] = `
1717
"futureSeconds": 5n,
1818
},
1919
"stakeToken": "0x0000000000000000000000000000000000000000",
20-
"wasmModuleRoot": "0x28b6ad83ed87b21a87c73f7a0296a135ebc7074e449efb289ececccad771ccd6",
20+
"wasmModuleRoot": "0xc2c02df561d4afaf9a1d6785f70098ec3874765c638e3cb6dbe8d3c83333e14c",
2121
}
2222
`;
2323

@@ -38,7 +38,7 @@ exports[`creates config for a chain on top of arbitrum one with defaults 1`] = `
3838
"futureSeconds": 3600n,
3939
},
4040
"stakeToken": "0x0000000000000000000000000000000000000000",
41-
"wasmModuleRoot": "0x28b6ad83ed87b21a87c73f7a0296a135ebc7074e449efb289ececccad771ccd6",
41+
"wasmModuleRoot": "0xc2c02df561d4afaf9a1d6785f70098ec3874765c638e3cb6dbe8d3c83333e14c",
4242
}
4343
`;
4444

@@ -80,7 +80,7 @@ exports[`creates config for a chain on top of arbitrum sepolia with defaults 1`]
8080
"futureSeconds": 3600n,
8181
},
8282
"stakeToken": "0x0000000000000000000000000000000000000000",
83-
"wasmModuleRoot": "0x28b6ad83ed87b21a87c73f7a0296a135ebc7074e449efb289ececccad771ccd6",
83+
"wasmModuleRoot": "0xc2c02df561d4afaf9a1d6785f70098ec3874765c638e3cb6dbe8d3c83333e14c",
8484
}
8585
`;
8686

@@ -122,7 +122,7 @@ exports[`creates config for a chain on top of base sepolia with defaults 1`] = `
122122
"futureSeconds": 3600n,
123123
},
124124
"stakeToken": "0x0000000000000000000000000000000000000000",
125-
"wasmModuleRoot": "0x28b6ad83ed87b21a87c73f7a0296a135ebc7074e449efb289ececccad771ccd6",
125+
"wasmModuleRoot": "0xc2c02df561d4afaf9a1d6785f70098ec3874765c638e3cb6dbe8d3c83333e14c",
126126
}
127127
`;
128128

@@ -143,6 +143,6 @@ exports[`creates config for a chain on top of base with defaults 1`] = `
143143
"futureSeconds": 3600n,
144144
},
145145
"stakeToken": "0x0000000000000000000000000000000000000000",
146-
"wasmModuleRoot": "0x28b6ad83ed87b21a87c73f7a0296a135ebc7074e449efb289ececccad771ccd6",
146+
"wasmModuleRoot": "0xc2c02df561d4afaf9a1d6785f70098ec3874765c638e3cb6dbe8d3c83333e14c",
147147
}
148148
`;

src/createRollupPrepareDeploymentParamsConfig/__snapshots__/v3.1.unit.test.ts.snap

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ exports[`creates a config for a chain on top of a custom parent chain 1`] = `
4848
},
4949
"stakeToken": "0xabaF3D9f5cbDcE54cDc43b429d8f7154A3E19Afa",
5050
"validatorAfkBlocks": 4n,
51-
"wasmModuleRoot": "0x28b6ad83ed87b21a87c73f7a0296a135ebc7074e449efb289ececccad771ccd6",
51+
"wasmModuleRoot": "0xc2c02df561d4afaf9a1d6785f70098ec3874765c638e3cb6dbe8d3c83333e14c",
5252
}
5353
`;
5454

@@ -100,7 +100,7 @@ exports[`creates config for a chain on top of arbitrum one with defaults 1`] = `
100100
},
101101
"stakeToken": "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",
102102
"validatorAfkBlocks": 201600n,
103-
"wasmModuleRoot": "0x28b6ad83ed87b21a87c73f7a0296a135ebc7074e449efb289ececccad771ccd6",
103+
"wasmModuleRoot": "0xc2c02df561d4afaf9a1d6785f70098ec3874765c638e3cb6dbe8d3c83333e14c",
104104
}
105105
`;
106106

@@ -204,7 +204,7 @@ exports[`creates config for a chain on top of arbitrum sepolia with defaults 1`]
204204
},
205205
"stakeToken": "0x980B62Da83eFf3D4576C647993b0c1D7faf17c73",
206206
"validatorAfkBlocks": 201600n,
207-
"wasmModuleRoot": "0x28b6ad83ed87b21a87c73f7a0296a135ebc7074e449efb289ececccad771ccd6",
207+
"wasmModuleRoot": "0xc2c02df561d4afaf9a1d6785f70098ec3874765c638e3cb6dbe8d3c83333e14c",
208208
}
209209
`;
210210

@@ -308,7 +308,7 @@ exports[`creates config for a chain on top of base sepolia with defaults 1`] = `
308308
},
309309
"stakeToken": "0x4200000000000000000000000000000000000006",
310310
"validatorAfkBlocks": 1209600n,
311-
"wasmModuleRoot": "0x28b6ad83ed87b21a87c73f7a0296a135ebc7074e449efb289ececccad771ccd6",
311+
"wasmModuleRoot": "0xc2c02df561d4afaf9a1d6785f70098ec3874765c638e3cb6dbe8d3c83333e14c",
312312
}
313313
`;
314314

@@ -360,6 +360,6 @@ exports[`creates config for a chain on top of base with defaults 1`] = `
360360
},
361361
"stakeToken": "0x4200000000000000000000000000000000000006",
362362
"validatorAfkBlocks": 1209600n,
363-
"wasmModuleRoot": "0x28b6ad83ed87b21a87c73f7a0296a135ebc7074e449efb289ececccad771ccd6",
363+
"wasmModuleRoot": "0xc2c02df561d4afaf9a1d6785f70098ec3874765c638e3cb6dbe8d3c83333e14c",
364364
}
365365
`;

src/createRollupPrepareTransactionRequest-v2.1.unit.test.ts

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { it, expect } from 'vitest';
22
import { createPublicClient, http, zeroAddress } from 'viem';
3-
import { arbitrumSepolia } from 'viem/chains';
3+
import { arbitrum, arbitrumSepolia } from 'viem/chains';
44

55
import { generateChainId } from './utils';
66
import { prepareChainConfig } from './prepareChainConfig';
@@ -353,6 +353,45 @@ it(`fails to prepare transaction request if "params.maxDataSize" is not provided
353353
).rejects.toThrowError(`"params.maxDataSize" must be provided when using a custom parent chain.`);
354354
});
355355

356+
it(`fails to prepare transaction request if "params.wasmModuleRoot" is blacklisted`, async () => {
357+
const chainId = 123456;
358+
359+
// create the chain config
360+
const chainConfig = prepareChainConfig({
361+
chainId,
362+
arbitrum: { InitialChainOwner: deployer.address, DataAvailabilityCommittee: true },
363+
});
364+
365+
const wasmModuleRoot = '0x28b6ad83ed87b21a87c73f7a0296a135ebc7074e449efb289ececccad771ccd6';
366+
const arbOSVersion = chainConfig.arbitrum.InitialArbOSVersion;
367+
368+
await expect(
369+
createRollupPrepareTransactionRequest({
370+
params: {
371+
config: createRollupPrepareDeploymentParamsConfig(
372+
publicClient,
373+
{
374+
chainId: BigInt(chainId),
375+
owner: deployer.address,
376+
chainConfig,
377+
wasmModuleRoot,
378+
},
379+
'v2.1',
380+
),
381+
batchPosters: [deployer.address],
382+
validators: [deployer.address],
383+
},
384+
value: createRollupDefaultRetryablesFees,
385+
account: deployer.address,
386+
publicClient,
387+
gasOverrides: { gasLimit: { base: 1_000n } },
388+
rollupCreatorVersion: 'v2.1',
389+
}),
390+
).rejects.toThrowError(
391+
`Wasm module root ${wasmModuleRoot} is not supported. Please update your "wasmModuleRoot" to that of a Consensus version compatible with ArbOS ${arbOSVersion}.`,
392+
);
393+
});
394+
356395
it(`successfully prepares a transaction request with the default rollup creator and a gas limit override`, async () => {
357396
// generate a random chain id
358397
const chainId = generateChainId();

src/createRollupPrepareTransactionRequest-v3.1.unit.test.ts

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { it, expect } from 'vitest';
22
import { createPublicClient, http, zeroAddress } from 'viem';
3-
import { arbitrumSepolia } from 'viem/chains';
3+
import { arbitrum, arbitrumSepolia } from 'viem/chains';
44

55
import { generateChainId } from './utils';
66
import { prepareChainConfig } from './prepareChainConfig';
@@ -311,6 +311,40 @@ it(`fails to prepare transaction request if "params.maxDataSize" is not provided
311311
).rejects.toThrowError(`"params.maxDataSize" must be provided when using a custom parent chain.`);
312312
});
313313

314+
it(`fails to prepare transaction request if "params.wasmModuleRoot" is blacklisted`, async () => {
315+
const chainId = 123456;
316+
317+
// create the chain config
318+
const chainConfig = prepareChainConfig({
319+
chainId,
320+
arbitrum: { InitialChainOwner: deployer.address, DataAvailabilityCommittee: true },
321+
});
322+
323+
const wasmModuleRoot = '0x28b6ad83ed87b21a87c73f7a0296a135ebc7074e449efb289ececccad771ccd6';
324+
const arbOSVersion = chainConfig.arbitrum.InitialArbOSVersion;
325+
326+
await expect(
327+
createRollupPrepareTransactionRequest({
328+
params: {
329+
config: createRollupPrepareDeploymentParamsConfig(publicClient, {
330+
chainId: BigInt(chainId),
331+
owner: deployer.address,
332+
chainConfig,
333+
wasmModuleRoot,
334+
}),
335+
batchPosters: [deployer.address],
336+
validators: [deployer.address],
337+
},
338+
value: createRollupDefaultRetryablesFees,
339+
account: deployer.address,
340+
publicClient,
341+
gasOverrides: { gasLimit: { base: 1_000n } },
342+
}),
343+
).rejects.toThrowError(
344+
`Wasm module root ${wasmModuleRoot} is not supported. Please update your "wasmModuleRoot" to that of a Consensus version compatible with ArbOS ${arbOSVersion}.`,
345+
);
346+
});
347+
314348
it(`successfully prepares a transaction request with the default rollup creator and a gas limit override`, async () => {
315349
// generate a random chain id
316350
const chainId = generateChainId();

src/createRollupPrepareTransactionRequest.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { ChainConfig } from './types/ChainConfig';
1010
import { getRollupCreatorAddress } from './utils/getRollupCreatorAddress';
1111
import { fetchDecimals } from './utils/erc20';
1212
import { TransactionRequestGasOverrides, applyPercentIncrease } from './utils/gasOverrides';
13+
import { isDisabledWasmModuleRoot } from './wasmModuleRoot';
1314

1415
import {
1516
CreateRollupParams,
@@ -136,6 +137,12 @@ export async function createRollupPrepareTransactionRequest<TChain extends Chain
136137
}
137138
}
138139

140+
if (isDisabledWasmModuleRoot(wasmModuleRoot)) {
141+
throw new Error(
142+
`Wasm module root ${wasmModuleRoot} is not supported. Please update your "wasmModuleRoot" to that of a Consensus version compatible with ArbOS ${arbOSVersion}.`,
143+
);
144+
}
145+
139146
const paramsWithDefaults = { ...defaults, ...params, maxDataSize };
140147
const createRollupGetCallValueParams = { ...paramsWithDefaults, account };
141148

src/wasmModuleRoot.ts

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ type ConsensusRelease = {
44
version: number;
55
wasmModuleRoot: Hex;
66
maxArbOSVersion: number;
7+
isDisabled?: boolean;
78
};
89

910
const consensusReleases = [
@@ -78,12 +79,19 @@ const consensusReleases = [
7879
version: 51,
7980
wasmModuleRoot: '0x8a7513bf7bb3e3db04b0d982d0e973bcf57bf8b88aef7c6d03dba3a81a56a499',
8081
maxArbOSVersion: 51,
82+
isDisabled: true,
8183
},
8284
{
83-
// https://github.com/OffchainLabs/nitro/releases/tag/consensus-v51.1
8485
version: 51.1,
8586
wasmModuleRoot: '0x28b6ad83ed87b21a87c73f7a0296a135ebc7074e449efb289ececccad771ccd6',
86-
maxArbOSVersion: 51.1,
87+
maxArbOSVersion: 51,
88+
isDisabled: true,
89+
},
90+
{
91+
// https://github.com/OffchainLabs/nitro/releases/tag/consensus-v51.1
92+
version: 51.1,
93+
wasmModuleRoot: '0xc2c02df561d4afaf9a1d6785f70098ec3874765c638e3cb6dbe8d3c83333e14c',
94+
maxArbOSVersion: 51,
8795
},
8896
] as const satisfies readonly ConsensusRelease[];
8997

@@ -102,7 +110,10 @@ export function getConsensusReleaseByVersion<TConsensusVersion extends Consensus
102110
): GetConsensusReleaseByVersion<TConsensusVersion> {
103111
const consensusRelease = consensusReleases
104112
//
105-
.find((release) => release.version === consensusVersion);
113+
.find(
114+
(release) =>
115+
release.version === consensusVersion && !('isDisabled' in release && release.isDisabled),
116+
);
106117

107118
return consensusRelease as GetConsensusReleaseByVersion<TConsensusVersion>;
108119
}
@@ -129,3 +140,13 @@ export function isKnownWasmModuleRoot(wasmModuleRoot: Hex): wasmModuleRoot is Wa
129140
.includes(wasmModuleRoot)
130141
);
131142
}
143+
144+
export function isDisabledWasmModuleRoot(wasmModuleRoot: Hex): boolean {
145+
const lowerCaseWasmModuleRoot = wasmModuleRoot.toLowerCase();
146+
return consensusReleases.some(
147+
(release) =>
148+
'isDisabled' in release &&
149+
release.isDisabled &&
150+
release.wasmModuleRoot.toLowerCase() === lowerCaseWasmModuleRoot,
151+
);
152+
}

src/wasmModuleRoot.unit.test.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { describe, it, expect } from 'vitest';
22

3-
import { isKnownWasmModuleRoot } from './wasmModuleRoot';
3+
import { isDisabledWasmModuleRoot, isKnownWasmModuleRoot } from './wasmModuleRoot';
44

55
describe('isKnownWasmModuleRoot', () => {
66
it('returns true for a known wasm module root', () => {
@@ -28,3 +28,21 @@ describe('isKnownWasmModuleRoot', () => {
2828
).toEqual(false);
2929
});
3030
});
31+
32+
describe('isDisabledWasmModuleRoot', () => {
33+
it('returns true for a blacklisted wasm module root', () => {
34+
expect(
35+
isDisabledWasmModuleRoot(
36+
'0x8a7513bf7bb3e3db04b0d982d0e973bcf57bf8b88aef7c6d03dba3a81a56a499',
37+
),
38+
).toEqual(true);
39+
});
40+
41+
it('returns false for a non-blacklisted wasm module root', () => {
42+
expect(
43+
isDisabledWasmModuleRoot(
44+
'0xdb698a2576298f25448bc092e52cf13b1e24141c997135d70f217d674bbeb69a',
45+
),
46+
).toEqual(false);
47+
});
48+
});

0 commit comments

Comments
 (0)