@aztec/ethereum 0.74.0 → 0.75.0-commit.c03ba01a2a4122e43e90d5133ba017e54b90e9d2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/dest/chain.js +17 -18
  2. package/dest/client.js +5 -9
  3. package/dest/config.js +13 -14
  4. package/dest/constants.js +0 -1
  5. package/dest/contracts/empire_base.js +3 -2
  6. package/dest/contracts/forwarder.js +46 -26
  7. package/dest/contracts/governance.js +11 -6
  8. package/dest/contracts/governance_proposer.js +78 -67
  9. package/dest/contracts/index.js +0 -1
  10. package/dest/contracts/rollup.js +270 -243
  11. package/dest/contracts/slashing_proposer.js +18 -8
  12. package/dest/deploy_l1_contracts.js +201 -126
  13. package/dest/eth_cheat_codes.js +144 -127
  14. package/dest/index.js +0 -1
  15. package/dest/l1_contract_addresses.js +17 -19
  16. package/dest/l1_reader.js +6 -7
  17. package/dest/l1_tx_utils.js +227 -186
  18. package/dest/l1_tx_utils_with_blobs.js +25 -22
  19. package/dest/queries.js +6 -9
  20. package/dest/test/delayed_tx_utils.js +3 -3
  21. package/dest/test/eth_cheat_codes_with_state.js +10 -12
  22. package/dest/test/index.js +0 -1
  23. package/dest/test/start_anvil.js +17 -9
  24. package/dest/test/tx_delayer.js +77 -74
  25. package/dest/types.js +1 -2
  26. package/dest/utils.js +35 -36
  27. package/package.json +5 -4
  28. package/src/contracts/rollup.ts +1 -1
  29. package/src/l1_tx_utils_with_blobs.ts +1 -1
  30. package/dest/chain.d.ts +0 -25
  31. package/dest/chain.d.ts.map +0 -1
  32. package/dest/client.d.ts +0 -16
  33. package/dest/client.d.ts.map +0 -1
  34. package/dest/config.d.ts +0 -38
  35. package/dest/config.d.ts.map +0 -1
  36. package/dest/constants.d.ts +0 -4
  37. package/dest/constants.d.ts.map +0 -1
  38. package/dest/contracts/empire_base.d.ts +0 -13
  39. package/dest/contracts/empire_base.d.ts.map +0 -1
  40. package/dest/contracts/forwarder.d.ts +0 -24
  41. package/dest/contracts/forwarder.d.ts.map +0 -1
  42. package/dest/contracts/governance.d.ts +0 -14
  43. package/dest/contracts/governance.d.ts.map +0 -1
  44. package/dest/contracts/governance_proposer.d.ts +0 -28
  45. package/dest/contracts/governance_proposer.d.ts.map +0 -1
  46. package/dest/contracts/index.d.ts +0 -7
  47. package/dest/contracts/index.d.ts.map +0 -1
  48. package/dest/contracts/rollup.d.ts +0 -115
  49. package/dest/contracts/rollup.d.ts.map +0 -1
  50. package/dest/contracts/slashing_proposer.d.ts +0 -21
  51. package/dest/contracts/slashing_proposer.d.ts.map +0 -1
  52. package/dest/deploy_l1_contracts.d.ts +0 -21118
  53. package/dest/deploy_l1_contracts.d.ts.map +0 -1
  54. package/dest/eth_cheat_codes.d.ts +0 -146
  55. package/dest/eth_cheat_codes.d.ts.map +0 -1
  56. package/dest/index.d.ts +0 -15
  57. package/dest/index.d.ts.map +0 -1
  58. package/dest/l1_contract_addresses.d.ts +0 -55
  59. package/dest/l1_contract_addresses.d.ts.map +0 -1
  60. package/dest/l1_reader.d.ts +0 -16
  61. package/dest/l1_reader.d.ts.map +0 -1
  62. package/dest/l1_tx_utils.d.ts +0 -194
  63. package/dest/l1_tx_utils.d.ts.map +0 -1
  64. package/dest/l1_tx_utils_with_blobs.d.ts +0 -12
  65. package/dest/l1_tx_utils_with_blobs.d.ts.map +0 -1
  66. package/dest/queries.d.ts +0 -15
  67. package/dest/queries.d.ts.map +0 -1
  68. package/dest/test/delayed_tx_utils.d.ts +0 -8
  69. package/dest/test/delayed_tx_utils.d.ts.map +0 -1
  70. package/dest/test/eth_cheat_codes_with_state.d.ts +0 -18
  71. package/dest/test/eth_cheat_codes_with_state.d.ts.map +0 -1
  72. package/dest/test/index.d.ts +0 -5
  73. package/dest/test/index.d.ts.map +0 -1
  74. package/dest/test/start_anvil.d.ts +0 -9
  75. package/dest/test/start_anvil.d.ts.map +0 -1
  76. package/dest/test/tx_delayer.d.ts +0 -24
  77. package/dest/test/tx_delayer.d.ts.map +0 -1
  78. package/dest/types.d.ts +0 -12
  79. package/dest/types.d.ts.map +0 -1
  80. package/dest/utils.d.ts +0 -24
  81. package/dest/utils.d.ts.map +0 -1
@@ -1,6 +1,6 @@
1
1
  import { EthAddress } from '@aztec/foundation/eth-address';
2
- import { CoinIssuerAbi, CoinIssuerBytecode, ExtRollupLibAbi, ExtRollupLibBytecode, FeeJuicePortalAbi, FeeJuicePortalBytecode, ForwarderAbi, ForwarderBytecode, GovernanceAbi, GovernanceBytecode, GovernanceProposerAbi, GovernanceProposerBytecode, InboxAbi, InboxBytecode, OutboxAbi, OutboxBytecode, RegistryAbi, RegistryBytecode, RewardDistributorAbi, RewardDistributorBytecode, RollupAbi, RollupBytecode, RollupLinkReferences, SlashFactoryAbi, SlashFactoryBytecode, StakingLibAbi, StakingLibBytecode, TestERC20Abi, TestERC20Bytecode, ValidatorSelectionLibAbi, ValidatorSelectionLibBytecode, } from '@aztec/l1-artifacts';
3
- import { concatHex, createPublicClient, createWalletClient, encodeDeployData, getAddress, getContract, getContractAddress, http, numberToHex, padHex, publicActions, } from 'viem';
2
+ import { CoinIssuerAbi, CoinIssuerBytecode, ExtRollupLibAbi, ExtRollupLibBytecode, FeeJuicePortalAbi, FeeJuicePortalBytecode, ForwarderAbi, ForwarderBytecode, GovernanceAbi, GovernanceBytecode, GovernanceProposerAbi, GovernanceProposerBytecode, InboxAbi, InboxBytecode, OutboxAbi, OutboxBytecode, RegistryAbi, RegistryBytecode, RewardDistributorAbi, RewardDistributorBytecode, RollupAbi, RollupBytecode, RollupLinkReferences, SlashFactoryAbi, SlashFactoryBytecode, StakingLibAbi, StakingLibBytecode, TestERC20Abi, TestERC20Bytecode, ValidatorSelectionLibAbi, ValidatorSelectionLibBytecode } from '@aztec/l1-artifacts';
3
+ import { concatHex, createPublicClient, createWalletClient, encodeDeployData, getAddress, getContract, getContractAddress, http, numberToHex, padHex, publicActions } from 'viem';
4
4
  import { mnemonicToAccount, privateKeyToAccount } from 'viem/accounts';
5
5
  import { foundry } from 'viem/chains';
6
6
  import { isAnvilTestChain } from './chain.js';
@@ -9,15 +9,15 @@ export const DEPLOYER_ADDRESS = '0x4e59b44847b379578588920cA78FbF26c0B4956C';
9
9
  export const l1Artifacts = {
10
10
  registry: {
11
11
  contractAbi: RegistryAbi,
12
- contractBytecode: RegistryBytecode,
12
+ contractBytecode: RegistryBytecode
13
13
  },
14
14
  inbox: {
15
15
  contractAbi: InboxAbi,
16
- contractBytecode: InboxBytecode,
16
+ contractBytecode: InboxBytecode
17
17
  },
18
18
  outbox: {
19
19
  contractAbi: OutboxAbi,
20
- contractBytecode: OutboxBytecode,
20
+ contractBytecode: OutboxBytecode
21
21
  },
22
22
  rollup: {
23
23
  contractAbi: RollupAbi,
@@ -27,51 +27,51 @@ export const l1Artifacts = {
27
27
  libraryCode: {
28
28
  ValidatorSelectionLib: {
29
29
  contractAbi: ValidatorSelectionLibAbi,
30
- contractBytecode: ValidatorSelectionLibBytecode,
30
+ contractBytecode: ValidatorSelectionLibBytecode
31
31
  },
32
32
  ExtRollupLib: {
33
33
  contractAbi: ExtRollupLibAbi,
34
- contractBytecode: ExtRollupLibBytecode,
34
+ contractBytecode: ExtRollupLibBytecode
35
35
  },
36
36
  StakingLib: {
37
37
  contractAbi: StakingLibAbi,
38
- contractBytecode: StakingLibBytecode,
39
- },
40
- },
41
- },
38
+ contractBytecode: StakingLibBytecode
39
+ }
40
+ }
41
+ }
42
42
  },
43
43
  stakingAsset: {
44
44
  contractAbi: TestERC20Abi,
45
- contractBytecode: TestERC20Bytecode,
45
+ contractBytecode: TestERC20Bytecode
46
46
  },
47
47
  feeAsset: {
48
48
  contractAbi: TestERC20Abi,
49
- contractBytecode: TestERC20Bytecode,
49
+ contractBytecode: TestERC20Bytecode
50
50
  },
51
51
  feeJuicePortal: {
52
52
  contractAbi: FeeJuicePortalAbi,
53
- contractBytecode: FeeJuicePortalBytecode,
53
+ contractBytecode: FeeJuicePortalBytecode
54
54
  },
55
55
  rewardDistributor: {
56
56
  contractAbi: RewardDistributorAbi,
57
- contractBytecode: RewardDistributorBytecode,
57
+ contractBytecode: RewardDistributorBytecode
58
58
  },
59
59
  coinIssuer: {
60
60
  contractAbi: CoinIssuerAbi,
61
- contractBytecode: CoinIssuerBytecode,
61
+ contractBytecode: CoinIssuerBytecode
62
62
  },
63
63
  governanceProposer: {
64
64
  contractAbi: GovernanceProposerAbi,
65
- contractBytecode: GovernanceProposerBytecode,
65
+ contractBytecode: GovernanceProposerBytecode
66
66
  },
67
67
  governance: {
68
68
  contractAbi: GovernanceAbi,
69
- contractBytecode: GovernanceBytecode,
69
+ contractBytecode: GovernanceBytecode
70
70
  },
71
71
  slashFactory: {
72
72
  contractAbi: SlashFactoryAbi,
73
- contractBytecode: SlashFactoryBytecode,
74
- },
73
+ contractBytecode: SlashFactoryBytecode
74
+ }
75
75
  };
76
76
  /**
77
77
  * Creates a wallet and a public viem client for interacting with L1.
@@ -79,30 +79,28 @@ export const l1Artifacts = {
79
79
  * @param mnemonicOrPrivateKeyOrHdAccount - Mnemonic or account for the wallet client.
80
80
  * @param chain - Optional chain spec (defaults to local foundry).
81
81
  * @returns - A wallet and a public client.
82
- */
83
- export function createL1Clients(rpcUrl, mnemonicOrPrivateKeyOrHdAccount, chain = foundry) {
84
- const hdAccount = typeof mnemonicOrPrivateKeyOrHdAccount === 'string'
85
- ? mnemonicOrPrivateKeyOrHdAccount.startsWith('0x')
86
- ? privateKeyToAccount(mnemonicOrPrivateKeyOrHdAccount)
87
- : mnemonicToAccount(mnemonicOrPrivateKeyOrHdAccount)
88
- : mnemonicOrPrivateKeyOrHdAccount;
82
+ */ export function createL1Clients(rpcUrl, mnemonicOrPrivateKeyOrHdAccount, chain = foundry) {
83
+ const hdAccount = typeof mnemonicOrPrivateKeyOrHdAccount === 'string' ? mnemonicOrPrivateKeyOrHdAccount.startsWith('0x') ? privateKeyToAccount(mnemonicOrPrivateKeyOrHdAccount) : mnemonicToAccount(mnemonicOrPrivateKeyOrHdAccount) : mnemonicOrPrivateKeyOrHdAccount;
89
84
  // From what I can see, this is the difference between the HDAccount and the PrivateKeyAccount
90
85
  // and we don't need it for anything. This lets us use the same type for both.
91
86
  // eslint-disable-next-line camelcase
92
- hdAccount.experimental_signAuthorization ?? (hdAccount.experimental_signAuthorization = () => {
87
+ hdAccount.experimental_signAuthorization ??= ()=>{
93
88
  throw new Error('experimental_signAuthorization not implemented for HDAccount');
94
- });
89
+ };
95
90
  const walletClient = createWalletClient({
96
91
  account: hdAccount,
97
92
  chain,
98
- transport: http(rpcUrl),
93
+ transport: http(rpcUrl)
99
94
  }).extend(publicActions);
100
95
  const publicClient = createPublicClient({
101
96
  chain,
102
97
  transport: http(rpcUrl),
103
- pollingInterval: 100,
98
+ pollingInterval: 100
104
99
  });
105
- return { walletClient, publicClient };
100
+ return {
101
+ walletClient,
102
+ publicClient
103
+ };
106
104
  }
107
105
  /**
108
106
  * Deploys the aztec L1 contracts; Rollup & (optionally) Decoder Helper.
@@ -112,69 +110,81 @@ export function createL1Clients(rpcUrl, mnemonicOrPrivateKeyOrHdAccount, chain =
112
110
  * @param logger - A logger object.
113
111
  * @param args - Arguments for initialization of L1 contracts
114
112
  * @returns A list of ETH addresses of the deployed contracts.
115
- */
116
- export const deployL1Contracts = async (rpcUrl, account, chain, logger, args) => {
113
+ */ export const deployL1Contracts = async (rpcUrl, account, chain, logger, args)=>{
117
114
  // We are assuming that you are running this on a local anvil node which have 1s block times
118
115
  // To align better with actual deployment, we update the block interval to 12s
119
116
  // The code is same as `setBlockInterval` in `cheat_codes.ts`
120
- const rpcCall = async (method, params) => {
117
+ const rpcCall = async (method, params)=>{
121
118
  const paramsString = JSON.stringify(params);
122
119
  const content = {
123
120
  body: `{"jsonrpc":"2.0", "method": "${method}", "params": ${paramsString}, "id": 1}`,
124
121
  method: 'POST',
125
- headers: { 'Content-Type': 'application/json' },
122
+ headers: {
123
+ 'Content-Type': 'application/json'
124
+ }
126
125
  };
127
126
  return await (await fetch(rpcUrl, content)).json();
128
127
  };
129
128
  if (isAnvilTestChain(chain.id)) {
130
- const res = await rpcCall('anvil_setBlockTimestampInterval', [args.ethereumSlotDuration]);
129
+ const res = await rpcCall('anvil_setBlockTimestampInterval', [
130
+ args.ethereumSlotDuration
131
+ ]);
131
132
  if (res.error) {
132
133
  throw new Error(`Error setting block interval: ${res.error.message}`);
133
134
  }
134
135
  logger.warn(`Set block interval to ${args.ethereumSlotDuration}`);
135
136
  }
136
137
  logger.verbose(`Deploying contracts from ${account.address.toString()}`);
137
- const walletClient = createWalletClient({ account, chain, transport: http(rpcUrl) });
138
- const publicClient = createPublicClient({ chain, transport: http(rpcUrl) });
138
+ const walletClient = createWalletClient({
139
+ account,
140
+ chain,
141
+ transport: http(rpcUrl)
142
+ });
143
+ const publicClient = createPublicClient({
144
+ chain,
145
+ transport: http(rpcUrl)
146
+ });
139
147
  // Governance stuff
140
148
  const govDeployer = new L1Deployer(walletClient, publicClient, args.salt, logger);
141
- const registryAddress = await govDeployer.deploy(l1Artifacts.registry, [account.address.toString()]);
149
+ const registryAddress = await govDeployer.deploy(l1Artifacts.registry, [
150
+ account.address.toString()
151
+ ]);
142
152
  logger.verbose(`Deployed Registry at ${registryAddress}`);
143
153
  const feeAssetAddress = await govDeployer.deploy(l1Artifacts.feeAsset, [
144
154
  'FeeJuice',
145
155
  'FEE',
146
- account.address.toString(),
156
+ account.address.toString()
147
157
  ]);
148
158
  logger.verbose(`Deployed Fee Juice at ${feeAssetAddress}`);
149
159
  const stakingAssetAddress = await govDeployer.deploy(l1Artifacts.stakingAsset, [
150
160
  'Staking',
151
161
  'STK',
152
- account.address.toString(),
162
+ account.address.toString()
153
163
  ]);
154
164
  logger.verbose(`Deployed Staking Asset at ${stakingAssetAddress}`);
155
165
  const governanceProposerAddress = await govDeployer.deploy(l1Artifacts.governanceProposer, [
156
166
  registryAddress.toString(),
157
167
  args.governanceProposerQuorum,
158
- args.governanceProposerRoundSize,
168
+ args.governanceProposerRoundSize
159
169
  ]);
160
170
  logger.verbose(`Deployed GovernanceProposer at ${governanceProposerAddress}`);
161
171
  // @note @LHerskind the assets are expected to be the same at some point, but for better
162
172
  // configurability they are different for now.
163
173
  const governanceAddress = await govDeployer.deploy(l1Artifacts.governance, [
164
174
  feeAssetAddress.toString(),
165
- governanceProposerAddress.toString(),
175
+ governanceProposerAddress.toString()
166
176
  ]);
167
177
  logger.verbose(`Deployed Governance at ${governanceAddress}`);
168
178
  const coinIssuerAddress = await govDeployer.deploy(l1Artifacts.coinIssuer, [
169
179
  feeAssetAddress.toString(),
170
- 1n * 10n ** 18n, // @todo #8084
171
- governanceAddress.toString(),
180
+ 1n * 10n ** 18n,
181
+ governanceAddress.toString()
172
182
  ]);
173
183
  logger.verbose(`Deployed CoinIssuer at ${coinIssuerAddress}`);
174
184
  const rewardDistributorAddress = await govDeployer.deploy(l1Artifacts.rewardDistributor, [
175
185
  feeAssetAddress.toString(),
176
186
  registryAddress.toString(),
177
- governanceAddress.toString(),
187
+ governanceAddress.toString()
178
188
  ]);
179
189
  logger.verbose(`Deployed RewardDistributor at ${rewardDistributorAddress}`);
180
190
  logger.verbose(`Waiting for governance contracts to be deployed`);
@@ -184,7 +194,7 @@ export const deployL1Contracts = async (rpcUrl, account, chain, logger, args) =>
184
194
  const feeJuicePortalAddress = await deployer.deploy(l1Artifacts.feeJuicePortal, [
185
195
  registryAddress.toString(),
186
196
  feeAssetAddress.toString(),
187
- args.l2FeeJuiceAddress.toString(),
197
+ args.l2FeeJuiceAddress.toString()
188
198
  ]);
189
199
  logger.verbose(`Deployed Fee Juice Portal at ${feeJuicePortalAddress}`);
190
200
  const rollupConfigArgs = {
@@ -194,7 +204,7 @@ export const deployL1Contracts = async (rpcUrl, account, chain, logger, args) =>
194
204
  aztecEpochProofClaimWindowInL2Slots: args.aztecEpochProofClaimWindowInL2Slots,
195
205
  minimumStake: args.minimumStake,
196
206
  slashingQuorum: args.slashingQuorum,
197
- slashingRoundSize: args.slashingRoundSize,
207
+ slashingRoundSize: args.slashingRoundSize
198
208
  };
199
209
  const rollupArgs = [
200
210
  feeJuicePortalAddress.toString(),
@@ -203,68 +213,89 @@ export const deployL1Contracts = async (rpcUrl, account, chain, logger, args) =>
203
213
  args.vkTreeRoot.toString(),
204
214
  args.protocolContractTreeRoot.toString(),
205
215
  account.address.toString(),
206
- rollupConfigArgs,
216
+ rollupConfigArgs
207
217
  ];
208
218
  await deployer.waitForDeployments();
209
219
  const rollupAddress = await deployer.deploy(l1Artifacts.rollup, rollupArgs);
210
220
  logger.verbose(`Deployed Rollup at ${rollupAddress}`, rollupConfigArgs);
211
- const slashFactoryAddress = await deployer.deploy(l1Artifacts.slashFactory, [rollupAddress.toString()]);
221
+ const slashFactoryAddress = await deployer.deploy(l1Artifacts.slashFactory, [
222
+ rollupAddress.toString()
223
+ ]);
212
224
  logger.verbose(`Deployed SlashFactory at ${slashFactoryAddress}`);
213
225
  await deployer.waitForDeployments();
214
226
  logger.verbose(`All core contracts have been deployed`);
215
227
  const feeJuicePortal = getContract({
216
228
  address: feeJuicePortalAddress.toString(),
217
229
  abi: l1Artifacts.feeJuicePortal.contractAbi,
218
- client: walletClient,
230
+ client: walletClient
219
231
  });
220
232
  const feeAsset = getContract({
221
233
  address: feeAssetAddress.toString(),
222
234
  abi: l1Artifacts.feeAsset.contractAbi,
223
- client: walletClient,
235
+ client: walletClient
224
236
  });
225
237
  const stakingAsset = getContract({
226
238
  address: stakingAssetAddress.toString(),
227
239
  abi: l1Artifacts.stakingAsset.contractAbi,
228
- client: walletClient,
240
+ client: walletClient
229
241
  });
230
242
  const rollup = getContract({
231
243
  address: getAddress(rollupAddress.toString()),
232
244
  abi: l1Artifacts.rollup.contractAbi,
233
- client: walletClient,
245
+ client: walletClient
234
246
  });
235
247
  // Transaction hashes to await
236
248
  const txHashes = [];
237
249
  {
238
- const txHash = await feeAsset.write.setFreeForAll([true], {});
250
+ const txHash = await feeAsset.write.setFreeForAll([
251
+ true
252
+ ], {});
239
253
  logger.verbose(`Fee asset set to free for all in ${txHash}`);
240
254
  txHashes.push(txHash);
241
255
  }
242
256
  if (args.initialValidators && args.initialValidators.length > 0) {
243
257
  // Check if some of the initial validators are already registered, so we support idempotent deployments
244
- const validatorsInfo = await Promise.all(args.initialValidators.map(async (address) => ({ address, ...(await rollup.read.getInfo([address.toString()])) })));
245
- const existingValidators = validatorsInfo.filter(v => v.status !== 0);
258
+ const validatorsInfo = await Promise.all(args.initialValidators.map(async (address)=>({
259
+ address,
260
+ ...await rollup.read.getInfo([
261
+ address.toString()
262
+ ])
263
+ })));
264
+ const existingValidators = validatorsInfo.filter((v)=>v.status !== 0);
246
265
  if (existingValidators.length > 0) {
247
- logger.warn(`Validators ${existingValidators.map(v => v.address).join(', ')} already exist. Skipping from initialization.`);
266
+ logger.warn(`Validators ${existingValidators.map((v)=>v.address).join(', ')} already exist. Skipping from initialization.`);
248
267
  }
249
- const newValidatorsAddresses = validatorsInfo.filter(v => v.status === 0).map(v => v.address.toString());
268
+ const newValidatorsAddresses = validatorsInfo.filter((v)=>v.status === 0).map((v)=>v.address.toString());
250
269
  if (newValidatorsAddresses.length > 0) {
251
270
  // Mint tokens, approve them, use cheat code to initialise validator set without setting up the epoch.
252
271
  const stakeNeeded = args.minimumStake * BigInt(newValidatorsAddresses.length);
253
272
  await Promise.all([
254
- await stakingAsset.write.mint([walletClient.account.address, stakeNeeded], {}),
255
- await stakingAsset.write.approve([rollupAddress.toString(), stakeNeeded], {}),
256
- ].map(txHash => publicClient.waitForTransactionReceipt({ hash: txHash })));
257
- const validators = newValidatorsAddresses.map(v => ({
258
- attester: v,
259
- proposer: getExpectedAddress(ForwarderAbi, ForwarderBytecode, [v], v).address,
260
- withdrawer: v,
261
- amount: args.minimumStake,
262
- }));
263
- const initiateValidatorSetTxHash = await rollup.write.cheat__InitialiseValidatorSet([validators]);
273
+ await stakingAsset.write.mint([
274
+ walletClient.account.address,
275
+ stakeNeeded
276
+ ], {}),
277
+ await stakingAsset.write.approve([
278
+ rollupAddress.toString(),
279
+ stakeNeeded
280
+ ], {})
281
+ ].map((txHash)=>publicClient.waitForTransactionReceipt({
282
+ hash: txHash
283
+ })));
284
+ const validators = newValidatorsAddresses.map((v)=>({
285
+ attester: v,
286
+ proposer: getExpectedAddress(ForwarderAbi, ForwarderBytecode, [
287
+ v
288
+ ], v).address,
289
+ withdrawer: v,
290
+ amount: args.minimumStake
291
+ }));
292
+ const initiateValidatorSetTxHash = await rollup.write.cheat__InitialiseValidatorSet([
293
+ validators
294
+ ]);
264
295
  txHashes.push(initiateValidatorSetTxHash);
265
296
  logger.info(`Initialized validator set`, {
266
297
  validators,
267
- txHash: initiateValidatorSetTxHash,
298
+ txHash: initiateValidatorSetTxHash
268
299
  });
269
300
  }
270
301
  }
@@ -273,17 +304,21 @@ export const deployL1Contracts = async (rpcUrl, account, chain, logger, args) =>
273
304
  // @todo #8084
274
305
  // fund the portal contract with Fee Juice
275
306
  const FEE_JUICE_INITIAL_MINT = 200000000000000000000000n;
276
- const mintTxHash = await feeAsset.write.mint([feeJuicePortalAddress.toString(), FEE_JUICE_INITIAL_MINT], {});
307
+ const mintTxHash = await feeAsset.write.mint([
308
+ feeJuicePortalAddress.toString(),
309
+ FEE_JUICE_INITIAL_MINT
310
+ ], {});
277
311
  // @note This is used to ensure we fully wait for the transaction when running against a real chain
278
312
  // otherwise we execute subsequent transactions too soon
279
- await publicClient.waitForTransactionReceipt({ hash: mintTxHash });
313
+ await publicClient.waitForTransactionReceipt({
314
+ hash: mintTxHash
315
+ });
280
316
  logger.verbose(`Funding fee juice portal contract with fee juice in ${mintTxHash}`);
281
- if (!(await feeJuicePortal.read.initialized())) {
317
+ if (!await feeJuicePortal.read.initialized()) {
282
318
  const initPortalTxHash = await feeJuicePortal.write.initialize();
283
319
  txHashes.push(initPortalTxHash);
284
320
  logger.verbose(`Fee juice portal initializing in tx ${initPortalTxHash}`);
285
- }
286
- else {
321
+ } else {
287
322
  logger.verbose(`Fee juice portal is already initialized`);
288
323
  }
289
324
  logger.verbose(`Initialized Fee Juice Portal at ${feeJuicePortalAddress} to bridge between L1 ${feeAssetAddress} to L2 ${args.l2FeeJuiceAddress}`);
@@ -292,56 +327,74 @@ export const deployL1Contracts = async (rpcUrl, account, chain, logger, args) =>
292
327
  // The edge case being that the genesis block is already occupying slot 0, so we cannot have another block.
293
328
  try {
294
329
  // Need to get the time
295
- const currentSlot = (await rollup.read.getCurrentSlot());
330
+ const currentSlot = await rollup.read.getCurrentSlot();
296
331
  if (BigInt(currentSlot) === 0n) {
297
- const ts = Number(await rollup.read.getTimestampForSlot([1n]));
298
- await rpcCall('evm_setNextBlockTimestamp', [ts]);
299
- await rpcCall('hardhat_mine', [1]);
300
- const currentSlot = (await rollup.read.getCurrentSlot());
332
+ const ts = Number(await rollup.read.getTimestampForSlot([
333
+ 1n
334
+ ]));
335
+ await rpcCall('evm_setNextBlockTimestamp', [
336
+ ts
337
+ ]);
338
+ await rpcCall('hardhat_mine', [
339
+ 1
340
+ ]);
341
+ const currentSlot = await rollup.read.getCurrentSlot();
301
342
  if (BigInt(currentSlot) !== 1n) {
302
343
  throw new Error(`Error jumping time: current slot is ${currentSlot}`);
303
344
  }
304
345
  logger.info(`Jumped to slot 1`);
305
346
  }
306
- }
307
- catch (e) {
347
+ } catch (e) {
308
348
  throw new Error(`Error jumping time: ${e}`);
309
349
  }
310
350
  }
311
351
  // Set initial blocks as proven if requested
312
352
  if (args.assumeProvenThrough && args.assumeProvenThrough > 0) {
313
- await rollup.write.setAssumeProvenThroughBlockNumber([BigInt(args.assumeProvenThrough)], { account });
353
+ await rollup.write.setAssumeProvenThroughBlockNumber([
354
+ BigInt(args.assumeProvenThrough)
355
+ ], {
356
+ account
357
+ });
314
358
  logger.warn(`Rollup set to assumedProvenUntil to ${args.assumeProvenThrough}`);
315
359
  }
316
360
  // Inbox and Outbox are immutable and are deployed from Rollup's constructor so we just fetch them from the contract.
317
- const inboxAddress = EthAddress.fromString((await rollup.read.INBOX()));
361
+ const inboxAddress = EthAddress.fromString(await rollup.read.INBOX());
318
362
  logger.verbose(`Inbox available at ${inboxAddress}`);
319
- const outboxAddress = EthAddress.fromString((await rollup.read.OUTBOX()));
363
+ const outboxAddress = EthAddress.fromString(await rollup.read.OUTBOX());
320
364
  logger.verbose(`Outbox available at ${outboxAddress}`);
321
365
  // We need to call a function on the registry to set the various contract addresses.
322
366
  const registryContract = getContract({
323
367
  address: getAddress(registryAddress.toString()),
324
368
  abi: l1Artifacts.registry.contractAbi,
325
- client: walletClient,
369
+ client: walletClient
326
370
  });
327
- if (!(await registryContract.read.isRollupRegistered([getAddress(rollupAddress.toString())]))) {
328
- const upgradeTxHash = await registryContract.write.upgrade([getAddress(rollupAddress.toString())], { account });
371
+ if (!await registryContract.read.isRollupRegistered([
372
+ getAddress(rollupAddress.toString())
373
+ ])) {
374
+ const upgradeTxHash = await registryContract.write.upgrade([
375
+ getAddress(rollupAddress.toString())
376
+ ], {
377
+ account
378
+ });
329
379
  logger.verbose(`Upgrading registry contract at ${registryAddress} to rollup ${rollupAddress} in tx ${upgradeTxHash}`);
330
380
  txHashes.push(upgradeTxHash);
331
- }
332
- else {
381
+ } else {
333
382
  logger.verbose(`Registry ${registryAddress} has already registered rollup ${rollupAddress}`);
334
383
  }
335
384
  // If the owner is not the Governance contract, transfer ownership to the Governance contract
336
- if ((await registryContract.read.owner()) !== getAddress(governanceAddress.toString())) {
337
- const transferOwnershipTxHash = await registryContract.write.transferOwnership([getAddress(governanceAddress.toString())], {
338
- account,
385
+ if (await registryContract.read.owner() !== getAddress(governanceAddress.toString())) {
386
+ const transferOwnershipTxHash = await registryContract.write.transferOwnership([
387
+ getAddress(governanceAddress.toString())
388
+ ], {
389
+ account
339
390
  });
340
391
  logger.verbose(`Transferring the ownership of the registry contract at ${registryAddress} to the Governance ${governanceAddress} in tx ${transferOwnershipTxHash}`);
341
392
  txHashes.push(transferOwnershipTxHash);
342
393
  }
343
394
  // Wait for all actions to be mined
344
- await Promise.all(txHashes.map(txHash => publicClient.waitForTransactionReceipt({ hash: txHash })));
395
+ await Promise.all(txHashes.map((txHash)=>publicClient.waitForTransactionReceipt({
396
+ hash: txHash
397
+ })));
345
398
  logger.verbose(`All transactions for L1 deployment have been mined`);
346
399
  const l1Contracts = {
347
400
  rollupAddress,
@@ -355,22 +408,29 @@ export const deployL1Contracts = async (rpcUrl, account, chain, logger, args) =>
355
408
  rewardDistributorAddress,
356
409
  governanceProposerAddress,
357
410
  governanceAddress,
358
- slashFactoryAddress,
411
+ slashFactoryAddress
359
412
  };
360
413
  logger.info(`Aztec L1 contracts initialized`, l1Contracts);
361
414
  return {
362
415
  walletClient,
363
416
  publicClient,
364
- l1ContractAddresses: l1Contracts,
417
+ l1ContractAddresses: l1Contracts
365
418
  };
366
419
  };
367
420
  class L1Deployer {
368
- constructor(walletClient, publicClient, maybeSalt, logger) {
421
+ walletClient;
422
+ publicClient;
423
+ logger;
424
+ salt;
425
+ txHashes;
426
+ constructor(walletClient, publicClient, maybeSalt, logger){
369
427
  this.walletClient = walletClient;
370
428
  this.publicClient = publicClient;
371
429
  this.logger = logger;
372
430
  this.txHashes = [];
373
- this.salt = maybeSalt ? padHex(numberToHex(maybeSalt), { size: 32 }) : undefined;
431
+ this.salt = maybeSalt ? padHex(numberToHex(maybeSalt), {
432
+ size: 32
433
+ }) : undefined;
374
434
  }
375
435
  async deploy(params, args = []) {
376
436
  const { txHash, address } = await deployL1Contract(this.walletClient, this.publicClient, params.contractAbi, params.contractBytecode, args, this.salt, params.libraries, this.logger);
@@ -380,7 +440,9 @@ class L1Deployer {
380
440
  return address;
381
441
  }
382
442
  async waitForDeployments() {
383
- await Promise.all(this.txHashes.map(txHash => this.publicClient.waitForTransactionReceipt({ hash: txHash })));
443
+ await Promise.all(this.txHashes.map((txHash)=>this.publicClient.waitForTransactionReceipt({
444
+ hash: txHash
445
+ })));
384
446
  }
385
447
  }
386
448
  // docs:start:deployL1Contract
@@ -393,27 +455,26 @@ class L1Deployer {
393
455
  * @param args - Constructor arguments for the contract.
394
456
  * @param maybeSalt - Optional salt for CREATE2 deployment (does not wait for deployment tx to be mined if set, does not send tx if contract already exists).
395
457
  * @returns The ETH address the contract was deployed to.
396
- */
397
- export async function deployL1Contract(walletClient, publicClient, abi, bytecode, args = [], maybeSalt, libraries, logger) {
458
+ */ export async function deployL1Contract(walletClient, publicClient, abi, bytecode, args = [], maybeSalt, libraries, logger) {
398
459
  let txHash = undefined;
399
460
  let resultingAddress = undefined;
400
461
  const l1TxUtils = new L1TxUtils(publicClient, walletClient, logger);
401
462
  if (libraries) {
402
463
  // Note that this does NOT work well for linked libraries having linked libraries.
403
464
  // Verify that all link references have corresponding code
404
- for (const linkRef in libraries.linkReferences) {
405
- for (const contractName in libraries.linkReferences[linkRef]) {
465
+ for(const linkRef in libraries.linkReferences){
466
+ for(const contractName in libraries.linkReferences[linkRef]){
406
467
  if (!libraries.libraryCode[contractName]) {
407
468
  throw new Error(`Missing library code for ${contractName}`);
408
469
  }
409
470
  }
410
471
  }
411
472
  const replacements = {};
412
- for (const libraryName in libraries?.libraryCode) {
473
+ for(const libraryName in libraries?.libraryCode){
413
474
  const lib = libraries.libraryCode[libraryName];
414
475
  const { address } = await deployL1Contract(walletClient, publicClient, lib.contractAbi, lib.contractBytecode, [], maybeSalt, undefined, logger);
415
- for (const linkRef in libraries.linkReferences) {
416
- for (const contractName in libraries.linkReferences[linkRef]) {
476
+ for(const linkRef in libraries.linkReferences){
477
+ for(const contractName in libraries.linkReferences[linkRef]){
417
478
  // If the library name matches the one we just deployed, we replace it.
418
479
  if (contractName !== libraryName) {
419
480
  continue;
@@ -426,10 +487,10 @@ export async function deployL1Contract(walletClient, publicClient, abi, bytecode
426
487
  }
427
488
  }
428
489
  }
429
- const escapeRegExp = (s) => {
490
+ const escapeRegExp = (s)=>{
430
491
  return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // Escape special characters
431
492
  };
432
- for (const toReplace in replacements) {
493
+ for(const toReplace in replacements){
433
494
  const replacement = replacements[toReplace].toString().slice(2);
434
495
  bytecode = bytecode.replace(new RegExp(escapeRegExp(toReplace), 'g'), replacement);
435
496
  }
@@ -437,48 +498,62 @@ export async function deployL1Contract(walletClient, publicClient, abi, bytecode
437
498
  if (maybeSalt) {
438
499
  const { address, paddedSalt: salt, calldata } = getExpectedAddress(abi, bytecode, args, maybeSalt);
439
500
  resultingAddress = address;
440
- const existing = await publicClient.getBytecode({ address: resultingAddress });
501
+ const existing = await publicClient.getBytecode({
502
+ address: resultingAddress
503
+ });
441
504
  if (existing === undefined || existing === '0x') {
442
505
  const res = await l1TxUtils.sendTransaction({
443
506
  to: DEPLOYER_ADDRESS,
444
- data: concatHex([salt, calldata]),
507
+ data: concatHex([
508
+ salt,
509
+ calldata
510
+ ])
445
511
  });
446
512
  txHash = res.txHash;
447
513
  logger?.verbose(`Deployed contract with salt ${salt} to address ${resultingAddress} in tx ${txHash}.`);
448
- }
449
- else {
514
+ } else {
450
515
  logger?.verbose(`Skipping existing deployment of contract with salt ${salt} to address ${resultingAddress}`);
451
516
  }
452
- }
453
- else {
517
+ } else {
454
518
  // Regular deployment path
455
- const deployData = encodeDeployData({ abi, bytecode, args });
519
+ const deployData = encodeDeployData({
520
+ abi,
521
+ bytecode,
522
+ args
523
+ });
456
524
  const { receipt } = await l1TxUtils.sendAndMonitorTransaction({
457
525
  to: null,
458
- data: deployData,
526
+ data: deployData
459
527
  });
460
528
  txHash = receipt.transactionHash;
461
529
  resultingAddress = receipt.contractAddress;
462
530
  if (!resultingAddress) {
463
- throw new Error(`No contract address found in receipt: ${JSON.stringify(receipt, (_, val) => typeof val === 'bigint' ? String(val) : val)}`);
531
+ throw new Error(`No contract address found in receipt: ${JSON.stringify(receipt, (_, val)=>typeof val === 'bigint' ? String(val) : val)}`);
464
532
  }
465
533
  }
466
- return { address: EthAddress.fromString(resultingAddress), txHash };
534
+ return {
535
+ address: EthAddress.fromString(resultingAddress),
536
+ txHash
537
+ };
467
538
  }
468
539
  export function getExpectedAddress(abi, bytecode, args, salt) {
469
- const paddedSalt = padHex(salt, { size: 32 });
470
- const calldata = encodeDeployData({ abi, bytecode, args });
540
+ const paddedSalt = padHex(salt, {
541
+ size: 32
542
+ });
543
+ const calldata = encodeDeployData({
544
+ abi,
545
+ bytecode,
546
+ args
547
+ });
471
548
  const address = getContractAddress({
472
549
  from: DEPLOYER_ADDRESS,
473
550
  salt: paddedSalt,
474
551
  bytecode: calldata,
475
- opcode: 'CREATE2',
552
+ opcode: 'CREATE2'
476
553
  });
477
554
  return {
478
555
  address,
479
556
  paddedSalt,
480
- calldata,
557
+ calldata
481
558
  };
482
- }
483
- // docs:end:deployL1Contract
484
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVwbG95X2wxX2NvbnRyYWN0cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9kZXBsb3lfbDFfY29udHJhY3RzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUczRCxPQUFPLEVBQ0wsYUFBYSxFQUNiLGtCQUFrQixFQUNsQixlQUFlLEVBQ2Ysb0JBQW9CLEVBQ3BCLGlCQUFpQixFQUNqQixzQkFBc0IsRUFDdEIsWUFBWSxFQUNaLGlCQUFpQixFQUNqQixhQUFhLEVBQ2Isa0JBQWtCLEVBQ2xCLHFCQUFxQixFQUNyQiwwQkFBMEIsRUFDMUIsUUFBUSxFQUNSLGFBQWEsRUFDYixTQUFTLEVBQ1QsY0FBYyxFQUNkLFdBQVcsRUFDWCxnQkFBZ0IsRUFDaEIsb0JBQW9CLEVBQ3BCLHlCQUF5QixFQUN6QixTQUFTLEVBQ1QsY0FBYyxFQUNkLG9CQUFvQixFQUNwQixlQUFlLEVBQ2Ysb0JBQW9CLEVBQ3BCLGFBQWEsRUFDYixrQkFBa0IsRUFDbEIsWUFBWSxFQUNaLGlCQUFpQixFQUNqQix3QkFBd0IsRUFDeEIsNkJBQTZCLEdBQzlCLE1BQU0scUJBQXFCLENBQUM7QUFHN0IsT0FBTyxFQVlMLFNBQVMsRUFDVCxrQkFBa0IsRUFDbEIsa0JBQWtCLEVBQ2xCLGdCQUFnQixFQUNoQixVQUFVLEVBQ1YsV0FBVyxFQUNYLGtCQUFrQixFQUNsQixJQUFJLEVBQ0osV0FBVyxFQUNYLE1BQU0sRUFDTixhQUFhLEdBQ2QsTUFBTSxNQUFNLENBQUM7QUFDZCxPQUFPLEVBQTBDLGlCQUFpQixFQUFFLG1CQUFtQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQy9HLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFFdEMsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sWUFBWSxDQUFDO0FBRzlDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztB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
559
+ } // docs:end:deployL1Contract