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