hardhat 2.22.11 → 2.22.13

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 (94) hide show
  1. package/internal/hardhat-network/provider/provider.d.ts +2 -3
  2. package/internal/hardhat-network/provider/provider.d.ts.map +1 -1
  3. package/internal/hardhat-network/provider/provider.js +5 -19
  4. package/internal/hardhat-network/provider/provider.js.map +1 -1
  5. package/internal/hardhat-network/provider/return-data.d.ts +2 -15
  6. package/internal/hardhat-network/provider/return-data.d.ts.map +1 -1
  7. package/internal/hardhat-network/provider/return-data.js +2 -50
  8. package/internal/hardhat-network/provider/return-data.js.map +1 -1
  9. package/internal/hardhat-network/provider/vm/exit.d.ts +2 -20
  10. package/internal/hardhat-network/provider/vm/exit.d.ts.map +1 -1
  11. package/internal/hardhat-network/provider/vm/exit.js +3 -78
  12. package/internal/hardhat-network/provider/vm/exit.js.map +1 -1
  13. package/internal/hardhat-network/stack-traces/compiler-to-model.d.ts +2 -3
  14. package/internal/hardhat-network/stack-traces/compiler-to-model.d.ts.map +1 -1
  15. package/internal/hardhat-network/stack-traces/compiler-to-model.js +2 -351
  16. package/internal/hardhat-network/stack-traces/compiler-to-model.js.map +1 -1
  17. package/internal/hardhat-network/stack-traces/debug.d.ts +2 -7
  18. package/internal/hardhat-network/stack-traces/debug.d.ts.map +1 -1
  19. package/internal/hardhat-network/stack-traces/debug.js +3 -143
  20. package/internal/hardhat-network/stack-traces/debug.js.map +1 -1
  21. package/internal/hardhat-network/stack-traces/library-utils.d.ts +2 -11
  22. package/internal/hardhat-network/stack-traces/library-utils.d.ts.map +1 -1
  23. package/internal/hardhat-network/stack-traces/library-utils.js +3 -61
  24. package/internal/hardhat-network/stack-traces/library-utils.js.map +1 -1
  25. package/internal/hardhat-network/stack-traces/logger.d.ts.map +1 -1
  26. package/internal/hardhat-network/stack-traces/logger.js +0 -221
  27. package/internal/hardhat-network/stack-traces/logger.js.map +1 -1
  28. package/internal/hardhat-network/stack-traces/message-trace.d.ts +2 -51
  29. package/internal/hardhat-network/stack-traces/message-trace.d.ts.map +1 -1
  30. package/internal/hardhat-network/stack-traces/message-trace.js +0 -46
  31. package/internal/hardhat-network/stack-traces/message-trace.js.map +1 -1
  32. package/internal/hardhat-network/stack-traces/solidity-errors.d.ts.map +1 -1
  33. package/internal/hardhat-network/stack-traces/solidity-errors.js +58 -53
  34. package/internal/hardhat-network/stack-traces/solidity-errors.js.map +1 -1
  35. package/internal/hardhat-network/stack-traces/solidity-stack-trace.d.ts +4 -155
  36. package/internal/hardhat-network/stack-traces/solidity-stack-trace.d.ts.map +1 -1
  37. package/internal/hardhat-network/stack-traces/solidity-stack-trace.js +12 -37
  38. package/internal/hardhat-network/stack-traces/solidity-stack-trace.js.map +1 -1
  39. package/internal/hardhat-network/stack-traces/solidityTracer.d.ts +2 -13
  40. package/internal/hardhat-network/stack-traces/solidityTracer.d.ts.map +1 -1
  41. package/internal/hardhat-network/stack-traces/solidityTracer.js +2 -162
  42. package/internal/hardhat-network/stack-traces/solidityTracer.js.map +1 -1
  43. package/internal/hardhat-network/stack-traces/vm-trace-decoder.d.ts +4 -15
  44. package/internal/hardhat-network/stack-traces/vm-trace-decoder.d.ts.map +1 -1
  45. package/internal/hardhat-network/stack-traces/vm-trace-decoder.js +6 -70
  46. package/internal/hardhat-network/stack-traces/vm-trace-decoder.js.map +1 -1
  47. package/internal/hardhat-network/stack-traces/vm-tracer.d.ts +2 -19
  48. package/internal/hardhat-network/stack-traces/vm-tracer.d.ts.map +1 -1
  49. package/internal/hardhat-network/stack-traces/vm-tracer.js +3 -150
  50. package/internal/hardhat-network/stack-traces/vm-tracer.js.map +1 -1
  51. package/package.json +2 -2
  52. package/src/internal/hardhat-network/provider/provider.ts +11 -24
  53. package/src/internal/hardhat-network/provider/return-data.ts +5 -73
  54. package/src/internal/hardhat-network/provider/vm/exit.ts +4 -92
  55. package/src/internal/hardhat-network/stack-traces/compiler-to-model.ts +5 -697
  56. package/src/internal/hardhat-network/stack-traces/debug.ts +5 -218
  57. package/src/internal/hardhat-network/stack-traces/library-utils.ts +5 -90
  58. package/src/internal/hardhat-network/stack-traces/logger.ts +0 -221
  59. package/src/internal/hardhat-network/stack-traces/message-trace.ts +5 -122
  60. package/src/internal/hardhat-network/stack-traces/solidity-errors.ts +16 -15
  61. package/src/internal/hardhat-network/stack-traces/solidity-stack-trace.ts +83 -186
  62. package/src/internal/hardhat-network/stack-traces/solidityTracer.ts +5 -253
  63. package/src/internal/hardhat-network/stack-traces/vm-trace-decoder.ts +15 -108
  64. package/src/internal/hardhat-network/stack-traces/vm-tracer.ts +5 -206
  65. package/internal/hardhat-network/stack-traces/contracts-identifier.d.ts +0 -15
  66. package/internal/hardhat-network/stack-traces/contracts-identifier.d.ts.map +0 -1
  67. package/internal/hardhat-network/stack-traces/contracts-identifier.js +0 -166
  68. package/internal/hardhat-network/stack-traces/contracts-identifier.js.map +0 -1
  69. package/internal/hardhat-network/stack-traces/error-inferrer.d.ts +0 -85
  70. package/internal/hardhat-network/stack-traces/error-inferrer.d.ts.map +0 -1
  71. package/internal/hardhat-network/stack-traces/error-inferrer.js +0 -1168
  72. package/internal/hardhat-network/stack-traces/error-inferrer.js.map +0 -1
  73. package/internal/hardhat-network/stack-traces/mapped-inlined-internal-functions-heuristics.d.ts +0 -24
  74. package/internal/hardhat-network/stack-traces/mapped-inlined-internal-functions-heuristics.d.ts.map +0 -1
  75. package/internal/hardhat-network/stack-traces/mapped-inlined-internal-functions-heuristics.js +0 -116
  76. package/internal/hardhat-network/stack-traces/mapped-inlined-internal-functions-heuristics.js.map +0 -1
  77. package/internal/hardhat-network/stack-traces/model.d.ts +0 -140
  78. package/internal/hardhat-network/stack-traces/model.d.ts.map +0 -1
  79. package/internal/hardhat-network/stack-traces/model.js +0 -328
  80. package/internal/hardhat-network/stack-traces/model.js.map +0 -1
  81. package/internal/hardhat-network/stack-traces/opcodes.d.ts +0 -266
  82. package/internal/hardhat-network/stack-traces/opcodes.d.ts.map +0 -1
  83. package/internal/hardhat-network/stack-traces/opcodes.js +0 -320
  84. package/internal/hardhat-network/stack-traces/opcodes.js.map +0 -1
  85. package/internal/hardhat-network/stack-traces/source-maps.d.ts +0 -13
  86. package/internal/hardhat-network/stack-traces/source-maps.d.ts.map +0 -1
  87. package/internal/hardhat-network/stack-traces/source-maps.js +0 -106
  88. package/internal/hardhat-network/stack-traces/source-maps.js.map +0 -1
  89. package/src/internal/hardhat-network/stack-traces/contracts-identifier.ts +0 -235
  90. package/src/internal/hardhat-network/stack-traces/error-inferrer.ts +0 -1845
  91. package/src/internal/hardhat-network/stack-traces/mapped-inlined-internal-functions-heuristics.ts +0 -163
  92. package/src/internal/hardhat-network/stack-traces/model.ts +0 -409
  93. package/src/internal/hardhat-network/stack-traces/opcodes.ts +0 -344
  94. package/src/internal/hardhat-network/stack-traces/source-maps.ts +0 -167
@@ -1,699 +1,7 @@
1
- import debug from "debug";
1
+ import { requireNapiRsModule } from "../../../common/napi-rs";
2
2
 
3
- import {
4
- CompilerInput,
5
- CompilerOutput,
6
- CompilerOutputBytecode,
7
- } from "../../../types";
3
+ const { createModelsAndDecodeBytecodes } = requireNapiRsModule(
4
+ "@nomicfoundation/edr"
5
+ ) as typeof import("@nomicfoundation/edr");
8
6
 
9
- import {
10
- getLibraryAddressPositions,
11
- normalizeCompilerOutputBytecode,
12
- } from "./library-utils";
13
- import {
14
- Bytecode,
15
- Contract,
16
- ContractFunction,
17
- ContractFunctionType,
18
- ContractFunctionVisibility,
19
- ContractType,
20
- CustomError,
21
- SourceFile,
22
- SourceLocation,
23
- } from "./model";
24
- import { decodeInstructions } from "./source-maps";
25
-
26
- const abi = require("ethereumjs-abi");
27
-
28
- const log = debug("hardhat:core:hardhat-network:compiler-to-model");
29
-
30
- interface ContractAbiEntry {
31
- name?: string;
32
- inputs?: Array<{
33
- type: string;
34
- }>;
35
- }
36
-
37
- type ContractAbi = ContractAbiEntry[];
38
-
39
- export function createModelsAndDecodeBytecodes(
40
- solcVersion: string,
41
- compilerInput: CompilerInput,
42
- compilerOutput: CompilerOutput
43
- ): Bytecode[] {
44
- const fileIdToSourceFile = new Map<number, SourceFile>();
45
- const contractIdToContract = new Map<number, Contract>();
46
-
47
- createSourcesModelFromAst(
48
- compilerOutput,
49
- compilerInput,
50
- fileIdToSourceFile,
51
- contractIdToContract
52
- );
53
-
54
- const bytecodes = decodeBytecodes(
55
- solcVersion,
56
- compilerOutput,
57
- fileIdToSourceFile,
58
- contractIdToContract
59
- );
60
-
61
- correctSelectors(bytecodes, compilerOutput);
62
-
63
- return bytecodes;
64
- }
65
-
66
- function createSourcesModelFromAst(
67
- compilerOutput: CompilerOutput,
68
- compilerInput: CompilerInput,
69
- fileIdToSourceFile: Map<number, SourceFile>,
70
- contractIdToContract: Map<number, Contract>
71
- ) {
72
- const contractIdToLinearizedBaseContractIds = new Map<number, number[]>();
73
-
74
- // Create a `sourceName => contract => abi` mapping
75
- const sourceNameToContractToAbi = new Map<string, Map<string, ContractAbi>>();
76
- for (const [sourceName, contracts] of Object.entries(
77
- compilerOutput.contracts
78
- )) {
79
- const contractToAbi = new Map<string, ContractAbi>();
80
- sourceNameToContractToAbi.set(sourceName, contractToAbi);
81
- for (const [contractName, contract] of Object.entries(contracts)) {
82
- contractToAbi.set(contractName, contract.abi);
83
- }
84
- }
85
-
86
- for (const [sourceName, source] of Object.entries(compilerOutput.sources)) {
87
- const contractToAbi = sourceNameToContractToAbi.get(sourceName);
88
- const file = new SourceFile(
89
- sourceName,
90
- compilerInput.sources[sourceName].content
91
- );
92
-
93
- fileIdToSourceFile.set(source.id, file);
94
-
95
- for (const node of source.ast.nodes) {
96
- if (node.nodeType === "ContractDefinition") {
97
- const contractType = contractKindToContractType(node.contractKind);
98
-
99
- if (contractType === undefined) {
100
- continue;
101
- }
102
-
103
- const contractAbi = contractToAbi?.get(node.name);
104
-
105
- processContractAstNode(
106
- file,
107
- node,
108
- fileIdToSourceFile,
109
- contractType,
110
- contractIdToContract,
111
- contractIdToLinearizedBaseContractIds,
112
- contractAbi
113
- );
114
- }
115
-
116
- // top-level functions
117
- if (node.nodeType === "FunctionDefinition") {
118
- processFunctionDefinitionAstNode(
119
- node,
120
- fileIdToSourceFile,
121
- undefined,
122
- file
123
- );
124
- }
125
- }
126
- }
127
-
128
- applyContractsInheritance(
129
- contractIdToContract,
130
- contractIdToLinearizedBaseContractIds
131
- );
132
- }
133
-
134
- function processContractAstNode(
135
- file: SourceFile,
136
- contractNode: any,
137
- fileIdToSourceFile: Map<number, SourceFile>,
138
- contractType: ContractType,
139
- contractIdToContract: Map<number, Contract>,
140
- contractIdToLinearizedBaseContractIds: Map<number, number[]>,
141
- contractAbi?: ContractAbi
142
- ) {
143
- const contractLocation = astSrcToSourceLocation(
144
- contractNode.src,
145
- fileIdToSourceFile
146
- )!;
147
-
148
- const contract = new Contract(
149
- contractNode.name,
150
- contractType,
151
- contractLocation
152
- );
153
-
154
- contractIdToContract.set(contractNode.id, contract);
155
- contractIdToLinearizedBaseContractIds.set(
156
- contractNode.id,
157
- contractNode.linearizedBaseContracts
158
- );
159
-
160
- file.addContract(contract);
161
-
162
- for (const node of contractNode.nodes) {
163
- if (node.nodeType === "FunctionDefinition") {
164
- const functionAbis = contractAbi?.filter(
165
- (abiEntry) => abiEntry.name === node.name
166
- );
167
-
168
- processFunctionDefinitionAstNode(
169
- node,
170
- fileIdToSourceFile,
171
- contract,
172
- file,
173
- functionAbis
174
- );
175
- } else if (node.nodeType === "ModifierDefinition") {
176
- processModifierDefinitionAstNode(
177
- node,
178
- fileIdToSourceFile,
179
- contract,
180
- file
181
- );
182
- } else if (node.nodeType === "VariableDeclaration") {
183
- const getterAbi = contractAbi?.find(
184
- (abiEntry) => abiEntry.name === node.name
185
- );
186
- processVariableDeclarationAstNode(
187
- node,
188
- fileIdToSourceFile,
189
- contract,
190
- file,
191
- getterAbi
192
- );
193
- }
194
- }
195
- }
196
-
197
- function processFunctionDefinitionAstNode(
198
- functionDefinitionNode: any,
199
- fileIdToSourceFile: Map<number, SourceFile>,
200
- contract: Contract | undefined,
201
- file: SourceFile,
202
- functionAbis?: ContractAbiEntry[]
203
- ) {
204
- if (functionDefinitionNode.implemented === false) {
205
- return;
206
- }
207
-
208
- const functionType = functionDefinitionKindToFunctionType(
209
- functionDefinitionNode.kind
210
- );
211
- const functionLocation = astSrcToSourceLocation(
212
- functionDefinitionNode.src,
213
- fileIdToSourceFile
214
- )!;
215
- const visibility = astVisibilityToVisibility(
216
- functionDefinitionNode.visibility
217
- );
218
-
219
- let selector: Buffer | undefined;
220
- if (
221
- functionType === ContractFunctionType.FUNCTION &&
222
- (visibility === ContractFunctionVisibility.EXTERNAL ||
223
- visibility === ContractFunctionVisibility.PUBLIC)
224
- ) {
225
- selector = astFunctionDefinitionToSelector(functionDefinitionNode);
226
- }
227
-
228
- // function can be overloaded, match the abi by the selector
229
- const matchingFunctionAbi = functionAbis?.find((functionAbi) => {
230
- if (functionAbi.name === undefined) {
231
- return false;
232
- }
233
-
234
- const functionAbiSelector = abi.methodID(
235
- functionAbi.name,
236
- functionAbi.inputs?.map((input) => input.type) ?? []
237
- );
238
-
239
- if (selector === undefined || functionAbiSelector === undefined) {
240
- return false;
241
- }
242
-
243
- return selector.equals(functionAbiSelector);
244
- });
245
-
246
- const paramTypes = matchingFunctionAbi?.inputs?.map((input) => input.type);
247
-
248
- const cf = new ContractFunction(
249
- functionDefinitionNode.name,
250
- functionType,
251
- functionLocation,
252
- contract,
253
- visibility,
254
- functionDefinitionNode.stateMutability === "payable",
255
- selector,
256
- paramTypes
257
- );
258
-
259
- if (contract !== undefined) {
260
- contract.addLocalFunction(cf);
261
- }
262
-
263
- file.addFunction(cf);
264
- }
265
-
266
- function processModifierDefinitionAstNode(
267
- modifierDefinitionNode: any,
268
- fileIdToSourceFile: Map<number, SourceFile>,
269
- contract: Contract,
270
- file: SourceFile
271
- ) {
272
- const functionLocation = astSrcToSourceLocation(
273
- modifierDefinitionNode.src,
274
- fileIdToSourceFile
275
- )!;
276
-
277
- const cf = new ContractFunction(
278
- modifierDefinitionNode.name,
279
- ContractFunctionType.MODIFIER,
280
- functionLocation,
281
- contract
282
- );
283
-
284
- contract.addLocalFunction(cf);
285
- file.addFunction(cf);
286
- }
287
-
288
- function canonicalAbiTypeForElementaryOrUserDefinedTypes(keyType: any): any {
289
- if (isElementaryType(keyType)) {
290
- return toCanonicalAbiType(keyType.name);
291
- }
292
-
293
- if (isEnumType(keyType)) {
294
- return "uint256";
295
- }
296
-
297
- if (isContractType(keyType)) {
298
- return "address";
299
- }
300
-
301
- return undefined;
302
- }
303
-
304
- function getPublicVariableSelectorFromDeclarationAstNode(
305
- variableDeclaration: any
306
- ) {
307
- if (variableDeclaration.functionSelector !== undefined) {
308
- return Buffer.from(variableDeclaration.functionSelector, "hex");
309
- }
310
-
311
- const paramTypes: string[] = [];
312
-
313
- // VariableDeclaration nodes for function parameters or state variables will always
314
- // have their typeName fields defined.
315
- let nextType = variableDeclaration.typeName;
316
- while (true) {
317
- if (nextType.nodeType === "Mapping") {
318
- const canonicalType = canonicalAbiTypeForElementaryOrUserDefinedTypes(
319
- nextType.keyType
320
- );
321
- paramTypes.push(canonicalType);
322
-
323
- nextType = nextType.valueType;
324
- } else {
325
- if (nextType.nodeType === "ArrayTypeName") {
326
- paramTypes.push("uint256");
327
- }
328
-
329
- break;
330
- }
331
- }
332
-
333
- return abi.methodID(variableDeclaration.name, paramTypes);
334
- }
335
-
336
- function processVariableDeclarationAstNode(
337
- variableDeclarationNode: any,
338
- fileIdToSourceFile: Map<number, SourceFile>,
339
- contract: Contract,
340
- file: SourceFile,
341
- getterAbi?: ContractAbiEntry
342
- ) {
343
- const visibility = astVisibilityToVisibility(
344
- variableDeclarationNode.visibility
345
- );
346
-
347
- // Variables can't be external
348
- if (visibility !== ContractFunctionVisibility.PUBLIC) {
349
- return;
350
- }
351
-
352
- const functionLocation = astSrcToSourceLocation(
353
- variableDeclarationNode.src,
354
- fileIdToSourceFile
355
- )!;
356
-
357
- const paramTypes = getterAbi?.inputs?.map((input) => input.type);
358
-
359
- const cf = new ContractFunction(
360
- variableDeclarationNode.name,
361
- ContractFunctionType.GETTER,
362
- functionLocation,
363
- contract,
364
- visibility,
365
- false, // Getters aren't payable
366
- getPublicVariableSelectorFromDeclarationAstNode(variableDeclarationNode),
367
- paramTypes
368
- );
369
-
370
- contract.addLocalFunction(cf);
371
- file.addFunction(cf);
372
- }
373
-
374
- function applyContractsInheritance(
375
- contractIdToContract: Map<number, Contract>,
376
- contractIdToLinearizedBaseContractIds: Map<number, number[]>
377
- ) {
378
- for (const [cid, contract] of contractIdToContract.entries()) {
379
- const inheritanceIds = contractIdToLinearizedBaseContractIds.get(cid)!;
380
-
381
- for (const baseId of inheritanceIds) {
382
- const baseContract = contractIdToContract.get(baseId);
383
-
384
- if (baseContract === undefined) {
385
- // This list includes interface, which we don't model
386
- continue;
387
- }
388
-
389
- contract.addNextLinearizedBaseContract(baseContract);
390
- }
391
- }
392
- }
393
-
394
- function decodeBytecodes(
395
- solcVersion: string,
396
- compilerOutput: CompilerOutput,
397
- fileIdToSourceFile: Map<number, SourceFile>,
398
- contractIdToContract: Map<number, Contract>
399
- ): Bytecode[] {
400
- const bytecodes: Bytecode[] = [];
401
-
402
- for (const contract of contractIdToContract.values()) {
403
- const contractFile = contract.location.file.sourceName;
404
- const contractEvmOutput =
405
- compilerOutput.contracts[contractFile][contract.name].evm;
406
- const contractAbiOutput =
407
- compilerOutput.contracts[contractFile][contract.name].abi;
408
-
409
- for (const abiItem of contractAbiOutput) {
410
- if (abiItem.type === "error") {
411
- const customError = CustomError.fromABI(abiItem.name, abiItem.inputs);
412
-
413
- if (customError !== undefined) {
414
- contract.addCustomError(customError);
415
- } else {
416
- log(`Couldn't build CustomError for error '${abiItem.name}'`);
417
- }
418
- }
419
- }
420
-
421
- // This is an abstract contract
422
- if (contractEvmOutput.bytecode.object === "") {
423
- continue;
424
- }
425
-
426
- const deploymentBytecode = decodeEvmBytecode(
427
- contract,
428
- solcVersion,
429
- true,
430
- contractEvmOutput.bytecode,
431
- fileIdToSourceFile
432
- );
433
-
434
- const runtimeBytecode = decodeEvmBytecode(
435
- contract,
436
- solcVersion,
437
- false,
438
- contractEvmOutput.deployedBytecode,
439
- fileIdToSourceFile
440
- );
441
-
442
- bytecodes.push(deploymentBytecode);
443
- bytecodes.push(runtimeBytecode);
444
- }
445
-
446
- return bytecodes;
447
- }
448
-
449
- function decodeEvmBytecode(
450
- contract: Contract,
451
- solcVersion: string,
452
- isDeployment: boolean,
453
- compilerBytecode: CompilerOutputBytecode,
454
- fileIdToSourceFile: Map<number, SourceFile>
455
- ): Bytecode {
456
- const libraryAddressPositions = getLibraryAddressPositions(compilerBytecode);
457
-
458
- const immutableReferences =
459
- compilerBytecode.immutableReferences !== undefined
460
- ? Object.values(compilerBytecode.immutableReferences).reduce(
461
- (previousValue, currentValue) => [...previousValue, ...currentValue],
462
- []
463
- )
464
- : [];
465
-
466
- const normalizedCode = normalizeCompilerOutputBytecode(
467
- compilerBytecode.object,
468
- libraryAddressPositions
469
- );
470
-
471
- const instructions = decodeInstructions(
472
- normalizedCode,
473
- compilerBytecode.sourceMap,
474
- fileIdToSourceFile,
475
- isDeployment
476
- );
477
-
478
- return new Bytecode(
479
- contract,
480
- isDeployment,
481
- normalizedCode,
482
- instructions,
483
- libraryAddressPositions,
484
- immutableReferences,
485
- solcVersion
486
- );
487
- }
488
-
489
- function astSrcToSourceLocation(
490
- src: string,
491
- fileIdToSourceFile: Map<number, SourceFile>
492
- ): SourceLocation | undefined {
493
- const [offset, length, fileId] = src.split(":").map((p) => +p);
494
- const file = fileIdToSourceFile.get(fileId);
495
-
496
- if (file === undefined) {
497
- return undefined;
498
- }
499
-
500
- return new SourceLocation(file, offset, length);
501
- }
502
-
503
- function contractKindToContractType(
504
- contractKind?: string
505
- ): ContractType | undefined {
506
- if (contractKind === "library") {
507
- return ContractType.LIBRARY;
508
- }
509
-
510
- if (contractKind === "contract") {
511
- return ContractType.CONTRACT;
512
- }
513
-
514
- return undefined;
515
- }
516
-
517
- function astVisibilityToVisibility(
518
- visibility: string
519
- ): ContractFunctionVisibility {
520
- if (visibility === "private") {
521
- return ContractFunctionVisibility.PRIVATE;
522
- }
523
-
524
- if (visibility === "internal") {
525
- return ContractFunctionVisibility.INTERNAL;
526
- }
527
-
528
- if (visibility === "public") {
529
- return ContractFunctionVisibility.PUBLIC;
530
- }
531
-
532
- return ContractFunctionVisibility.EXTERNAL;
533
- }
534
-
535
- function functionDefinitionKindToFunctionType(
536
- kind: string | undefined
537
- ): ContractFunctionType {
538
- if (kind === "constructor") {
539
- return ContractFunctionType.CONSTRUCTOR;
540
- }
541
-
542
- if (kind === "fallback") {
543
- return ContractFunctionType.FALLBACK;
544
- }
545
-
546
- if (kind === "receive") {
547
- return ContractFunctionType.RECEIVE;
548
- }
549
-
550
- if (kind === "freeFunction") {
551
- return ContractFunctionType.FREE_FUNCTION;
552
- }
553
-
554
- return ContractFunctionType.FUNCTION;
555
- }
556
-
557
- function astFunctionDefinitionToSelector(functionDefinition: any): Buffer {
558
- const paramTypes: string[] = [];
559
-
560
- // The function selector is available in solc versions >=0.6.0
561
- if (functionDefinition.functionSelector !== undefined) {
562
- return Buffer.from(functionDefinition.functionSelector, "hex");
563
- }
564
-
565
- for (const param of functionDefinition.parameters.parameters) {
566
- if (isContractType(param)) {
567
- paramTypes.push("address");
568
- continue;
569
- }
570
-
571
- // TODO: implement ABIv2 structs parsing
572
- // This might mean we need to parse struct definitions before
573
- // resolving types and trying to calculate function selectors.
574
- // if (isStructType(param)) {
575
- // paramTypes.push(something);
576
- // continue;
577
- // }
578
-
579
- if (isEnumType(param)) {
580
- // TODO: If the enum has >= 256 elements this will fail. It should be a uint16. This is
581
- // complicated, as enums can be inherited. Fortunately, if multiple parent contracts
582
- // define the same enum, solc fails to compile.
583
- paramTypes.push("uint8");
584
- continue;
585
- }
586
-
587
- // The rest of the function parameters always have their typeName node defined
588
- const typename = param.typeName;
589
- if (
590
- typename.nodeType === "ArrayTypeName" ||
591
- typename.nodeType === "FunctionTypeName" ||
592
- typename.nodeType === "Mapping"
593
- ) {
594
- paramTypes.push(typename.typeDescriptions.typeString);
595
- continue;
596
- }
597
-
598
- paramTypes.push(toCanonicalAbiType(typename.name));
599
- }
600
-
601
- return abi.methodID(functionDefinition.name, paramTypes);
602
- }
603
-
604
- function isContractType(param: any): boolean {
605
- return (
606
- (param.typeName?.nodeType === "UserDefinedTypeName" ||
607
- param?.nodeType === "UserDefinedTypeName") &&
608
- param.typeDescriptions?.typeString !== undefined &&
609
- param.typeDescriptions.typeString.startsWith("contract ")
610
- );
611
- }
612
-
613
- function isEnumType(param: any): boolean {
614
- return (
615
- (param.typeName?.nodeType === "UserDefinedTypeName" ||
616
- param?.nodeType === "UserDefinedTypeName") &&
617
- param.typeDescriptions?.typeString !== undefined &&
618
- param.typeDescriptions.typeString.startsWith("enum ")
619
- );
620
- }
621
-
622
- function isElementaryType(param: any) {
623
- return (
624
- param.type === "ElementaryTypeName" ||
625
- param.nodeType === "ElementaryTypeName"
626
- );
627
- }
628
-
629
- function toCanonicalAbiType(type: string): string {
630
- if (type.startsWith("int[")) {
631
- return `int256${type.slice(3)}`;
632
- }
633
-
634
- if (type === "int") {
635
- return "int256";
636
- }
637
-
638
- if (type.startsWith("uint[")) {
639
- return `uint256${type.slice(4)}`;
640
- }
641
-
642
- if (type === "uint") {
643
- return "uint256";
644
- }
645
-
646
- if (type.startsWith("fixed[")) {
647
- return `fixed128x128${type.slice(5)}`;
648
- }
649
-
650
- if (type === "fixed") {
651
- return "fixed128x128";
652
- }
653
-
654
- if (type.startsWith("ufixed[")) {
655
- return `ufixed128x128${type.slice(6)}`;
656
- }
657
-
658
- if (type === "ufixed") {
659
- return "ufixed128x128";
660
- }
661
-
662
- return type;
663
- }
664
-
665
- function correctSelectors(
666
- bytecodes: Bytecode[],
667
- compilerOutput: CompilerOutput
668
- ) {
669
- for (const bytecode of bytecodes) {
670
- if (bytecode.isDeployment) {
671
- continue;
672
- }
673
-
674
- const contract = bytecode.contract;
675
- const methodIdentifiers =
676
- compilerOutput.contracts[contract.location.file.sourceName][contract.name]
677
- .evm.methodIdentifiers;
678
-
679
- for (const [signature, hexSelector] of Object.entries(methodIdentifiers)) {
680
- const functionName = signature.slice(0, signature.indexOf("("));
681
- const selector = Buffer.from(hexSelector, "hex");
682
-
683
- const contractFunction = contract.getFunctionFromSelector(selector);
684
-
685
- if (contractFunction !== undefined) {
686
- continue;
687
- }
688
-
689
- const fixedSelector = contract.correctSelector(functionName, selector);
690
-
691
- if (!fixedSelector) {
692
- // eslint-disable-next-line @nomicfoundation/hardhat-internal-rules/only-hardhat-error
693
- throw new Error(
694
- `Failed to compute the selector one or more implementations of ${contract.name}#${functionName}. Hardhat Network can automatically fix this problem if you don't use function overloading.`
695
- );
696
- }
697
- }
698
- }
699
- }
7
+ export { createModelsAndDecodeBytecodes };