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,1845 +0,0 @@
1
- /* eslint "@typescript-eslint/no-non-null-assertion": "error" */
2
- import { defaultAbiCoder as abi } from "@ethersproject/abi";
3
- import { equalsBytes } from "@nomicfoundation/ethereumjs-util";
4
- import semver from "semver";
5
-
6
- import { assertHardhatInvariant } from "../../core/errors";
7
- import { AbiHelpers } from "../../util/abi-helpers";
8
- import { ReturnData } from "../provider/return-data";
9
- import { ExitCode } from "../provider/vm/exit";
10
-
11
- import {
12
- DecodedCallMessageTrace,
13
- DecodedCreateMessageTrace,
14
- DecodedEvmMessageTrace,
15
- EvmStep,
16
- isCreateTrace,
17
- isDecodedCallTrace,
18
- isDecodedCreateTrace,
19
- isEvmStep,
20
- isPrecompileTrace,
21
- MessageTrace,
22
- } from "./message-trace";
23
- import {
24
- Bytecode,
25
- ContractFunction,
26
- ContractFunctionType,
27
- ContractType,
28
- Instruction,
29
- JumpType,
30
- SourceLocation,
31
- } from "./model";
32
- import { isCall, isCreate, Opcode } from "./opcodes";
33
- import {
34
- CallFailedErrorStackTraceEntry,
35
- CallstackEntryStackTraceEntry,
36
- CONSTRUCTOR_FUNCTION_NAME,
37
- CustomErrorStackTraceEntry,
38
- FALLBACK_FUNCTION_NAME,
39
- InternalFunctionCallStackEntry,
40
- OtherExecutionErrorStackTraceEntry,
41
- PanicErrorStackTraceEntry,
42
- RECEIVE_FUNCTION_NAME,
43
- RevertErrorStackTraceEntry,
44
- SolidityStackTrace,
45
- SolidityStackTraceEntry,
46
- SourceReference,
47
- StackTraceEntryType,
48
- UnmappedSolc063RevertErrorStackTraceEntry,
49
- } from "./solidity-stack-trace";
50
-
51
- const FIRST_SOLC_VERSION_CREATE_PARAMS_VALIDATION = "0.5.9";
52
- const FIRST_SOLC_VERSION_RECEIVE_FUNCTION = "0.6.0";
53
- const FIRST_SOLC_VERSION_WITH_UNMAPPED_REVERTS = "0.6.3";
54
-
55
- export interface SubmessageData {
56
- messageTrace: MessageTrace;
57
- stacktrace: SolidityStackTrace;
58
- stepIndex: number;
59
- }
60
-
61
- /* eslint-disable @nomicfoundation/hardhat-internal-rules/only-hardhat-error */
62
-
63
- export class ErrorInferrer {
64
- public inferBeforeTracingCallMessage(
65
- trace: DecodedCallMessageTrace
66
- ): SolidityStackTrace | undefined {
67
- if (this._isDirectLibraryCall(trace)) {
68
- return this._getDirectLibraryCallErrorStackTrace(trace);
69
- }
70
-
71
- const calledFunction = trace.bytecode.contract.getFunctionFromSelector(
72
- trace.calldata.slice(0, 4)
73
- );
74
-
75
- if (
76
- calledFunction !== undefined &&
77
- this._isFunctionNotPayableError(trace, calledFunction)
78
- ) {
79
- return [
80
- {
81
- type: StackTraceEntryType.FUNCTION_NOT_PAYABLE_ERROR,
82
- sourceReference: this._getFunctionStartSourceReference(
83
- trace,
84
- calledFunction
85
- ),
86
- value: trace.value,
87
- },
88
- ];
89
- }
90
-
91
- if (this._isMissingFunctionAndFallbackError(trace, calledFunction)) {
92
- if (this._emptyCalldataAndNoReceive(trace)) {
93
- return [
94
- {
95
- type: StackTraceEntryType.MISSING_FALLBACK_OR_RECEIVE_ERROR,
96
- sourceReference:
97
- this._getContractStartWithoutFunctionSourceReference(trace),
98
- },
99
- ];
100
- }
101
-
102
- return [
103
- {
104
- type: StackTraceEntryType.UNRECOGNIZED_FUNCTION_WITHOUT_FALLBACK_ERROR,
105
- sourceReference:
106
- this._getContractStartWithoutFunctionSourceReference(trace),
107
- },
108
- ];
109
- }
110
-
111
- if (this._isFallbackNotPayableError(trace, calledFunction)) {
112
- if (this._emptyCalldataAndNoReceive(trace)) {
113
- return [
114
- {
115
- type: StackTraceEntryType.FALLBACK_NOT_PAYABLE_AND_NO_RECEIVE_ERROR,
116
- sourceReference: this._getFallbackStartSourceReference(trace),
117
- value: trace.value,
118
- },
119
- ];
120
- }
121
-
122
- return [
123
- {
124
- type: StackTraceEntryType.FALLBACK_NOT_PAYABLE_ERROR,
125
- sourceReference: this._getFallbackStartSourceReference(trace),
126
- value: trace.value,
127
- },
128
- ];
129
- }
130
- }
131
-
132
- public inferBeforeTracingCreateMessage(
133
- trace: DecodedCreateMessageTrace
134
- ): SolidityStackTrace | undefined {
135
- if (this._isConstructorNotPayableError(trace)) {
136
- return [
137
- {
138
- type: StackTraceEntryType.FUNCTION_NOT_PAYABLE_ERROR,
139
- sourceReference: this._getConstructorStartSourceReference(trace),
140
- value: trace.value,
141
- },
142
- ];
143
- }
144
-
145
- if (this._isConstructorInvalidArgumentsError(trace)) {
146
- return [
147
- {
148
- type: StackTraceEntryType.INVALID_PARAMS_ERROR,
149
- sourceReference: this._getConstructorStartSourceReference(trace),
150
- },
151
- ];
152
- }
153
- }
154
-
155
- public inferAfterTracing(
156
- trace: DecodedEvmMessageTrace,
157
- stacktrace: SolidityStackTrace,
158
- functionJumpdests: Instruction[],
159
- jumpedIntoFunction: boolean,
160
- lastSubmessageData: SubmessageData | undefined
161
- ): SolidityStackTrace {
162
- return (
163
- this._checkLastSubmessage(trace, stacktrace, lastSubmessageData) ??
164
- this._checkFailedLastCall(trace, stacktrace) ??
165
- this._checkLastInstruction(
166
- trace,
167
- stacktrace,
168
- functionJumpdests,
169
- jumpedIntoFunction
170
- ) ??
171
- this._checkNonContractCalled(trace, stacktrace) ??
172
- this._checkSolidity063UnmappedRevert(trace, stacktrace) ??
173
- this._checkContractTooLarge(trace) ??
174
- this._otherExecutionErrorStacktrace(trace, stacktrace)
175
- );
176
- }
177
-
178
- public filterRedundantFrames(
179
- stacktrace: SolidityStackTrace
180
- ): SolidityStackTrace {
181
- return stacktrace.filter((frame, i) => {
182
- if (i + 1 === stacktrace.length) {
183
- return true;
184
- }
185
-
186
- const nextFrame = stacktrace[i + 1];
187
-
188
- // we can only filter frames if we know their sourceReference
189
- // and the one from the next frame
190
- if (
191
- frame.sourceReference === undefined ||
192
- nextFrame.sourceReference === undefined
193
- ) {
194
- return true;
195
- }
196
-
197
- // look TWO frames ahead to determine if this is a specific occurrence of
198
- // a redundant CALLSTACK_ENTRY frame observed when using Solidity 0.8.5:
199
- if (
200
- frame.type === StackTraceEntryType.CALLSTACK_ENTRY &&
201
- i + 2 < stacktrace.length &&
202
- stacktrace[i + 2].sourceReference !== undefined &&
203
- stacktrace[i + 2].type === StackTraceEntryType.RETURNDATA_SIZE_ERROR
204
- ) {
205
- // ! below for tsc. we confirmed existence in the enclosing conditional.
206
- const thatSrcRef = stacktrace[i + 2].sourceReference;
207
- if (
208
- thatSrcRef !== undefined &&
209
- frame.sourceReference.range[0] === thatSrcRef.range[0] &&
210
- frame.sourceReference.range[1] === thatSrcRef.range[1] &&
211
- frame.sourceReference.line === thatSrcRef.line
212
- ) {
213
- return false;
214
- }
215
- }
216
-
217
- // constructors contain the whole contract, so we ignore them
218
- if (
219
- frame.sourceReference.function === "constructor" &&
220
- nextFrame.sourceReference.function !== "constructor"
221
- ) {
222
- return true;
223
- }
224
-
225
- // this is probably a recursive call
226
- if (
227
- i > 0 &&
228
- frame.type === nextFrame.type &&
229
- frame.sourceReference.range[0] === nextFrame.sourceReference.range[0] &&
230
- frame.sourceReference.range[1] === nextFrame.sourceReference.range[1] &&
231
- frame.sourceReference.line === nextFrame.sourceReference.line
232
- ) {
233
- return true;
234
- }
235
-
236
- if (
237
- frame.sourceReference.range[0] <= nextFrame.sourceReference.range[0] &&
238
- frame.sourceReference.range[1] >= nextFrame.sourceReference.range[1]
239
- ) {
240
- return false;
241
- }
242
-
243
- return true;
244
- });
245
- }
246
-
247
- // Heuristics
248
-
249
- /**
250
- * Check if the last submessage can be used to generate the stack trace.
251
- */
252
- private _checkLastSubmessage(
253
- trace: DecodedEvmMessageTrace,
254
- stacktrace: SolidityStackTrace,
255
- lastSubmessageData: SubmessageData | undefined
256
- ): SolidityStackTrace | undefined {
257
- if (lastSubmessageData === undefined) {
258
- return undefined;
259
- }
260
-
261
- const inferredStacktrace = [...stacktrace];
262
-
263
- // get the instruction before the submessage and add it to the stack trace
264
- const callStep = trace.steps[lastSubmessageData.stepIndex - 1];
265
-
266
- if (!isEvmStep(callStep)) {
267
- throw new Error(
268
- "This should not happen: MessageTrace should be preceded by a EVM step"
269
- );
270
- }
271
-
272
- const callInst = trace.bytecode.getInstruction(callStep.pc);
273
- const callStackFrame = instructionToCallstackStackTraceEntry(
274
- trace.bytecode,
275
- callInst
276
- );
277
-
278
- const lastMessageFailed = lastSubmessageData.messageTrace.exit.isError();
279
- if (lastMessageFailed) {
280
- // add the call/create that generated the message to the stack trace
281
- inferredStacktrace.push(callStackFrame);
282
-
283
- if (
284
- this._isSubtraceErrorPropagated(trace, lastSubmessageData.stepIndex) ||
285
- this._isProxyErrorPropagated(trace, lastSubmessageData.stepIndex)
286
- ) {
287
- inferredStacktrace.push(...lastSubmessageData.stacktrace);
288
-
289
- if (
290
- this._isContractCallRunOutOfGasError(
291
- trace,
292
- lastSubmessageData.stepIndex
293
- )
294
- ) {
295
- const lastFrame = inferredStacktrace.pop();
296
- assertHardhatInvariant(
297
- lastFrame !== undefined,
298
- "Expected inferred stack trace to have at least one frame"
299
- );
300
- inferredStacktrace.push({
301
- type: StackTraceEntryType.CONTRACT_CALL_RUN_OUT_OF_GAS_ERROR,
302
- sourceReference: lastFrame.sourceReference,
303
- });
304
- }
305
-
306
- return this._fixInitialModifier(trace, inferredStacktrace);
307
- }
308
- } else {
309
- const isReturnDataSizeError = this._failsRightAfterCall(
310
- trace,
311
- lastSubmessageData.stepIndex
312
- );
313
- if (isReturnDataSizeError) {
314
- inferredStacktrace.push({
315
- type: StackTraceEntryType.RETURNDATA_SIZE_ERROR,
316
- sourceReference: callStackFrame.sourceReference,
317
- });
318
-
319
- return this._fixInitialModifier(trace, inferredStacktrace);
320
- }
321
- }
322
- }
323
-
324
- /**
325
- * Check if the last call/create that was done failed.
326
- */
327
- private _checkFailedLastCall(
328
- trace: DecodedEvmMessageTrace,
329
- stacktrace: SolidityStackTrace
330
- ): SolidityStackTrace | undefined {
331
- for (let stepIndex = trace.steps.length - 2; stepIndex >= 0; stepIndex--) {
332
- const step = trace.steps[stepIndex];
333
- const nextStep = trace.steps[stepIndex + 1];
334
-
335
- if (!isEvmStep(step)) {
336
- return;
337
- }
338
-
339
- const inst = trace.bytecode.getInstruction(step.pc);
340
-
341
- const isCallOrCreate = isCall(inst.opcode) || isCreate(inst.opcode);
342
-
343
- if (isCallOrCreate && isEvmStep(nextStep)) {
344
- if (this._isCallFailedError(trace, stepIndex, inst)) {
345
- const inferredStacktrace = [
346
- ...stacktrace,
347
- this._callInstructionToCallFailedToExecuteStackTraceEntry(
348
- trace.bytecode,
349
- inst
350
- ),
351
- ];
352
-
353
- return this._fixInitialModifier(trace, inferredStacktrace);
354
- }
355
- }
356
- }
357
- }
358
-
359
- /**
360
- * Check if the execution stopped with a revert or an invalid opcode.
361
- */
362
- private _checkRevertOrInvalidOpcode(
363
- trace: DecodedEvmMessageTrace,
364
- stacktrace: SolidityStackTrace,
365
- lastInstruction: Instruction,
366
- functionJumpdests: Instruction[],
367
- jumpedIntoFunction: boolean
368
- ): SolidityStackTrace | undefined {
369
- if (
370
- lastInstruction.opcode !== Opcode.REVERT &&
371
- lastInstruction.opcode !== Opcode.INVALID
372
- ) {
373
- return;
374
- }
375
-
376
- const inferredStacktrace = [...stacktrace];
377
-
378
- if (
379
- lastInstruction.location !== undefined &&
380
- (!isDecodedCallTrace(trace) || jumpedIntoFunction)
381
- ) {
382
- // There should always be a function here, but that's not the case with optimizations.
383
- //
384
- // If this is a create trace, we already checked args and nonpayable failures before
385
- // calling this function.
386
- //
387
- // If it's a call trace, we already jumped into a function. But optimizations can happen.
388
- const failingFunction = lastInstruction.location.getContainingFunction();
389
-
390
- // If the failure is in a modifier we add an entry with the function/constructor
391
- if (
392
- failingFunction !== undefined &&
393
- failingFunction.type === ContractFunctionType.MODIFIER
394
- ) {
395
- inferredStacktrace.push(
396
- this._getEntryBeforeFailureInModifier(trace, functionJumpdests)
397
- );
398
- }
399
- }
400
-
401
- const panicStacktrace = this._checkPanic(
402
- trace,
403
- inferredStacktrace,
404
- lastInstruction
405
- );
406
- if (panicStacktrace !== undefined) {
407
- return panicStacktrace;
408
- }
409
-
410
- const customErrorStacktrace = this._checkCustomErrors(
411
- trace,
412
- inferredStacktrace,
413
- lastInstruction
414
- );
415
- if (customErrorStacktrace !== undefined) {
416
- return customErrorStacktrace;
417
- }
418
-
419
- if (
420
- lastInstruction.location !== undefined &&
421
- (!isDecodedCallTrace(trace) || jumpedIntoFunction)
422
- ) {
423
- const failingFunction = lastInstruction.location.getContainingFunction();
424
-
425
- if (failingFunction !== undefined) {
426
- inferredStacktrace.push(
427
- this._instructionWithinFunctionToRevertStackTraceEntry(
428
- trace,
429
- lastInstruction
430
- )
431
- );
432
- } else if (isDecodedCallTrace(trace)) {
433
- // This is here because of the optimizations
434
- const functionSelector =
435
- trace.bytecode.contract.getFunctionFromSelector(
436
- trace.calldata.slice(0, 4)
437
- );
438
-
439
- // in general this shouldn't happen, but it does when viaIR is enabled,
440
- // "optimizerSteps": "u" is used, and the called function is fallback or
441
- // receive
442
- if (functionSelector === undefined) {
443
- return;
444
- }
445
-
446
- inferredStacktrace.push({
447
- type: StackTraceEntryType.REVERT_ERROR,
448
- sourceReference: this._getFunctionStartSourceReference(
449
- trace,
450
- functionSelector
451
- ),
452
- message: new ReturnData(trace.returnData),
453
- isInvalidOpcodeError: lastInstruction.opcode === Opcode.INVALID,
454
- });
455
- } else {
456
- // This is here because of the optimizations
457
- inferredStacktrace.push({
458
- type: StackTraceEntryType.REVERT_ERROR,
459
- sourceReference: this._getConstructorStartSourceReference(trace),
460
- message: new ReturnData(trace.returnData),
461
- isInvalidOpcodeError: lastInstruction.opcode === Opcode.INVALID,
462
- });
463
- }
464
-
465
- return this._fixInitialModifier(trace, inferredStacktrace);
466
- }
467
-
468
- // If the revert instruction is not mapped but there is return data,
469
- // we add the frame anyway, sith the best sourceReference we can get
470
- if (lastInstruction.location === undefined && trace.returnData.length > 0) {
471
- const revertFrame: RevertErrorStackTraceEntry = {
472
- type: StackTraceEntryType.REVERT_ERROR,
473
- sourceReference:
474
- this._getLastSourceReference(trace) ??
475
- this._getContractStartWithoutFunctionSourceReference(trace),
476
- message: new ReturnData(trace.returnData),
477
- isInvalidOpcodeError: lastInstruction.opcode === Opcode.INVALID,
478
- };
479
- inferredStacktrace.push(revertFrame);
480
-
481
- return this._fixInitialModifier(trace, inferredStacktrace);
482
- }
483
- }
484
-
485
- /**
486
- * Check if the trace reverted with a panic error.
487
- */
488
- private _checkPanic(
489
- trace: DecodedEvmMessageTrace,
490
- stacktrace: SolidityStackTrace,
491
- lastInstruction: Instruction
492
- ): SolidityStackTrace | undefined {
493
- if (!this._isPanicReturnData(trace.returnData)) {
494
- return;
495
- }
496
-
497
- // If the last frame is an internal function, it means that the trace
498
- // jumped there to return the panic. If that's the case, we remove that
499
- // frame.
500
- const lastFrame = stacktrace[stacktrace.length - 1];
501
- if (
502
- lastFrame?.type === StackTraceEntryType.INTERNAL_FUNCTION_CALLSTACK_ENTRY
503
- ) {
504
- stacktrace.splice(-1);
505
- }
506
-
507
- const panicReturnData = new ReturnData(trace.returnData);
508
- const errorCode = panicReturnData.decodePanic();
509
-
510
- // if the error comes from a call to a zero-initialized function,
511
- // we remove the last frame, which represents the call, to avoid
512
- // having duplicated frames
513
- if (errorCode === 0x51n) {
514
- stacktrace.splice(-1);
515
- }
516
-
517
- const inferredStacktrace = [...stacktrace];
518
- inferredStacktrace.push(
519
- this._instructionWithinFunctionToPanicStackTraceEntry(
520
- trace,
521
- lastInstruction,
522
- errorCode
523
- )
524
- );
525
-
526
- return this._fixInitialModifier(trace, inferredStacktrace);
527
- }
528
-
529
- private _checkCustomErrors(
530
- trace: DecodedEvmMessageTrace,
531
- stacktrace: SolidityStackTrace,
532
- lastInstruction: Instruction
533
- ): SolidityStackTrace | undefined {
534
- const returnData = new ReturnData(trace.returnData);
535
-
536
- if (returnData.isEmpty() || returnData.isErrorReturnData()) {
537
- // if there is no return data, or if it's a Error(string),
538
- // then it can't be a custom error
539
- return;
540
- }
541
-
542
- const rawReturnData = Buffer.from(returnData.value).toString("hex");
543
- let errorMessage = `reverted with an unrecognized custom error (return data: 0x${rawReturnData})`;
544
-
545
- for (const customError of trace.bytecode.contract.customErrors) {
546
- if (returnData.matchesSelector(customError.selector)) {
547
- // if the return data matches a custom error in the called contract,
548
- // we format the message using the returnData and the custom error instance
549
- const decodedValues = abi.decode(
550
- customError.paramTypes,
551
- returnData.value.slice(4)
552
- );
553
-
554
- const params = AbiHelpers.formatValues([...decodedValues]);
555
- errorMessage = `reverted with custom error '${customError.name}(${params})'`;
556
- break;
557
- }
558
- }
559
-
560
- const inferredStacktrace = [...stacktrace];
561
- inferredStacktrace.push(
562
- this._instructionWithinFunctionToCustomErrorStackTraceEntry(
563
- trace,
564
- lastInstruction,
565
- errorMessage
566
- )
567
- );
568
-
569
- return this._fixInitialModifier(trace, inferredStacktrace);
570
- }
571
-
572
- /**
573
- * Check last instruction to try to infer the error.
574
- */
575
- private _checkLastInstruction(
576
- trace: DecodedEvmMessageTrace,
577
- stacktrace: SolidityStackTrace,
578
- functionJumpdests: Instruction[],
579
- jumpedIntoFunction: boolean
580
- ): SolidityStackTrace | undefined {
581
- if (trace.steps.length === 0) {
582
- return;
583
- }
584
-
585
- const lastStep = trace.steps[trace.steps.length - 1];
586
-
587
- if (!isEvmStep(lastStep)) {
588
- throw new Error(
589
- "This should not happen: MessageTrace ends with a subtrace"
590
- );
591
- }
592
-
593
- const lastInstruction = trace.bytecode.getInstruction(lastStep.pc);
594
-
595
- const revertOrInvalidStacktrace = this._checkRevertOrInvalidOpcode(
596
- trace,
597
- stacktrace,
598
- lastInstruction,
599
- functionJumpdests,
600
- jumpedIntoFunction
601
- );
602
-
603
- if (revertOrInvalidStacktrace !== undefined) {
604
- return revertOrInvalidStacktrace;
605
- }
606
-
607
- if (isDecodedCallTrace(trace) && !jumpedIntoFunction) {
608
- if (
609
- this._hasFailedInsideTheFallbackFunction(trace) ||
610
- this._hasFailedInsideTheReceiveFunction(trace)
611
- ) {
612
- return [
613
- this._instructionWithinFunctionToRevertStackTraceEntry(
614
- trace,
615
- lastInstruction
616
- ),
617
- ];
618
- }
619
-
620
- // Sometimes we do fail inside of a function but there's no jump into
621
- if (lastInstruction.location !== undefined) {
622
- const failingFunction =
623
- lastInstruction.location.getContainingFunction();
624
- if (failingFunction !== undefined) {
625
- return [
626
- {
627
- type: StackTraceEntryType.REVERT_ERROR,
628
- sourceReference: this._getFunctionStartSourceReference(
629
- trace,
630
- failingFunction
631
- ),
632
- message: new ReturnData(trace.returnData),
633
- isInvalidOpcodeError: lastInstruction.opcode === Opcode.INVALID,
634
- },
635
- ];
636
- }
637
- }
638
-
639
- const calledFunction = trace.bytecode.contract.getFunctionFromSelector(
640
- trace.calldata.slice(0, 4)
641
- );
642
-
643
- if (calledFunction !== undefined) {
644
- const isValidCalldata = calledFunction.isValidCalldata(
645
- trace.calldata.slice(4)
646
- );
647
-
648
- if (!isValidCalldata) {
649
- return [
650
- {
651
- type: StackTraceEntryType.INVALID_PARAMS_ERROR,
652
- sourceReference: this._getFunctionStartSourceReference(
653
- trace,
654
- calledFunction
655
- ),
656
- },
657
- ];
658
- }
659
- }
660
-
661
- if (this._solidity063MaybeUnmappedRevert(trace)) {
662
- const revertFrame =
663
- this._solidity063GetFrameForUnmappedRevertBeforeFunction(trace);
664
-
665
- if (revertFrame !== undefined) {
666
- return [revertFrame];
667
- }
668
- }
669
-
670
- return [this._getOtherErrorBeforeCalledFunctionStackTraceEntry(trace)];
671
- }
672
- }
673
-
674
- private _checkNonContractCalled(
675
- trace: DecodedEvmMessageTrace,
676
- stacktrace: SolidityStackTrace
677
- ): SolidityStackTrace | undefined {
678
- if (this._isCalledNonContractAccountError(trace)) {
679
- const sourceReference = this._getLastSourceReference(trace);
680
-
681
- // We are sure this is not undefined because there was at least a call instruction
682
- assertHardhatInvariant(
683
- sourceReference !== undefined,
684
- "Expected source reference to be defined"
685
- );
686
-
687
- const nonContractCalledFrame: SolidityStackTraceEntry = {
688
- type: StackTraceEntryType.NONCONTRACT_ACCOUNT_CALLED_ERROR,
689
- sourceReference,
690
- };
691
-
692
- return [...stacktrace, nonContractCalledFrame];
693
- }
694
- }
695
-
696
- private _checkSolidity063UnmappedRevert(
697
- trace: DecodedEvmMessageTrace,
698
- stacktrace: SolidityStackTrace
699
- ): SolidityStackTrace | undefined {
700
- if (this._solidity063MaybeUnmappedRevert(trace)) {
701
- const revertFrame =
702
- this._solidity063GetFrameForUnmappedRevertWithinFunction(trace);
703
-
704
- if (revertFrame !== undefined) {
705
- return [...stacktrace, revertFrame];
706
- }
707
- }
708
- }
709
-
710
- private _checkContractTooLarge(
711
- trace: DecodedEvmMessageTrace
712
- ): SolidityStackTrace | undefined {
713
- if (isCreateTrace(trace) && this._isContractTooLargeError(trace)) {
714
- return [
715
- {
716
- type: StackTraceEntryType.CONTRACT_TOO_LARGE_ERROR,
717
- sourceReference: this._getConstructorStartSourceReference(trace),
718
- },
719
- ];
720
- }
721
- }
722
-
723
- private _otherExecutionErrorStacktrace(
724
- trace: DecodedEvmMessageTrace,
725
- stacktrace: SolidityStackTrace
726
- ): SolidityStackTrace {
727
- const otherExecutionErrorFrame: SolidityStackTraceEntry = {
728
- type: StackTraceEntryType.OTHER_EXECUTION_ERROR,
729
- sourceReference: this._getLastSourceReference(trace),
730
- };
731
-
732
- return [...stacktrace, otherExecutionErrorFrame];
733
- }
734
-
735
- // Helpers
736
-
737
- private _fixInitialModifier(
738
- trace: DecodedEvmMessageTrace,
739
- stacktrace: SolidityStackTrace
740
- ): SolidityStackTrace {
741
- const firstEntry = stacktrace[0];
742
- if (
743
- firstEntry !== undefined &&
744
- firstEntry.type === StackTraceEntryType.CALLSTACK_ENTRY &&
745
- firstEntry.functionType === ContractFunctionType.MODIFIER
746
- ) {
747
- return [
748
- this._getEntryBeforeInitialModifierCallstackEntry(trace),
749
- ...stacktrace,
750
- ];
751
- }
752
-
753
- return stacktrace;
754
- }
755
-
756
- private _isDirectLibraryCall(trace: DecodedCallMessageTrace): boolean {
757
- return (
758
- trace.depth === 0 && trace.bytecode.contract.type === ContractType.LIBRARY
759
- );
760
- }
761
-
762
- private _getDirectLibraryCallErrorStackTrace(
763
- trace: DecodedCallMessageTrace
764
- ): SolidityStackTrace {
765
- const func = trace.bytecode.contract.getFunctionFromSelector(
766
- trace.calldata.slice(0, 4)
767
- );
768
-
769
- if (func !== undefined) {
770
- return [
771
- {
772
- type: StackTraceEntryType.DIRECT_LIBRARY_CALL_ERROR,
773
- sourceReference: this._getFunctionStartSourceReference(trace, func),
774
- },
775
- ];
776
- }
777
-
778
- return [
779
- {
780
- type: StackTraceEntryType.DIRECT_LIBRARY_CALL_ERROR,
781
- sourceReference:
782
- this._getContractStartWithoutFunctionSourceReference(trace),
783
- },
784
- ];
785
- }
786
-
787
- private _isFunctionNotPayableError(
788
- trace: DecodedCallMessageTrace,
789
- calledFunction: ContractFunction
790
- ): boolean {
791
- // This error doesn't return data
792
- if (trace.returnData.length > 0) {
793
- return false;
794
- }
795
-
796
- if (trace.value <= 0n) {
797
- return false;
798
- }
799
-
800
- // Libraries don't have a nonpayable check
801
- if (trace.bytecode.contract.type === ContractType.LIBRARY) {
802
- return false;
803
- }
804
-
805
- return calledFunction.isPayable === undefined || !calledFunction.isPayable;
806
- }
807
-
808
- private _getFunctionStartSourceReference(
809
- trace: DecodedEvmMessageTrace,
810
- func: ContractFunction
811
- ): SourceReference {
812
- return {
813
- sourceName: func.location.file.sourceName,
814
- sourceContent: func.location.file.content,
815
- contract: trace.bytecode.contract.name,
816
- function: func.name,
817
- line: func.location.getStartingLineNumber(),
818
- range: [
819
- func.location.offset,
820
- func.location.offset + func.location.length,
821
- ],
822
- };
823
- }
824
-
825
- private _isMissingFunctionAndFallbackError(
826
- trace: DecodedCallMessageTrace,
827
- calledFunction: ContractFunction | undefined
828
- ): boolean {
829
- // This error doesn't return data
830
- if (trace.returnData.length > 0) {
831
- return false;
832
- }
833
-
834
- // the called function exists in the contract
835
- if (calledFunction !== undefined) {
836
- return false;
837
- }
838
-
839
- // there's a receive function and no calldata
840
- if (
841
- trace.calldata.length === 0 &&
842
- trace.bytecode.contract.receive !== undefined
843
- ) {
844
- return false;
845
- }
846
-
847
- return trace.bytecode.contract.fallback === undefined;
848
- }
849
-
850
- private _emptyCalldataAndNoReceive(trace: DecodedCallMessageTrace): boolean {
851
- // this only makes sense when receive functions are available
852
- if (
853
- semver.lt(
854
- trace.bytecode.compilerVersion,
855
- FIRST_SOLC_VERSION_RECEIVE_FUNCTION
856
- )
857
- ) {
858
- return false;
859
- }
860
-
861
- return (
862
- trace.calldata.length === 0 &&
863
- trace.bytecode.contract.receive === undefined
864
- );
865
- }
866
-
867
- private _getContractStartWithoutFunctionSourceReference(
868
- trace: DecodedEvmMessageTrace
869
- ): SourceReference {
870
- const location = trace.bytecode.contract.location;
871
- return {
872
- sourceName: location.file.sourceName,
873
- sourceContent: location.file.content,
874
- contract: trace.bytecode.contract.name,
875
- line: location.getStartingLineNumber(),
876
- range: [location.offset, location.offset + location.length],
877
- };
878
- }
879
-
880
- private _isFallbackNotPayableError(
881
- trace: DecodedCallMessageTrace,
882
- calledFunction: ContractFunction | undefined
883
- ): boolean {
884
- if (calledFunction !== undefined) {
885
- return false;
886
- }
887
-
888
- // This error doesn't return data
889
- if (trace.returnData.length > 0) {
890
- return false;
891
- }
892
-
893
- if (trace.value <= 0n) {
894
- return false;
895
- }
896
-
897
- if (trace.bytecode.contract.fallback === undefined) {
898
- return false;
899
- }
900
-
901
- const isPayable = trace.bytecode.contract.fallback.isPayable;
902
-
903
- return isPayable === undefined || !isPayable;
904
- }
905
-
906
- private _getFallbackStartSourceReference(
907
- trace: DecodedCallMessageTrace
908
- ): SourceReference {
909
- const func = trace.bytecode.contract.fallback;
910
-
911
- if (func === undefined) {
912
- throw new Error(
913
- "This shouldn't happen: trying to get fallback source reference from a contract without fallback"
914
- );
915
- }
916
-
917
- return {
918
- sourceName: func.location.file.sourceName,
919
- sourceContent: func.location.file.content,
920
- contract: trace.bytecode.contract.name,
921
- function: FALLBACK_FUNCTION_NAME,
922
- line: func.location.getStartingLineNumber(),
923
- range: [
924
- func.location.offset,
925
- func.location.offset + func.location.length,
926
- ],
927
- };
928
- }
929
-
930
- private _isConstructorNotPayableError(
931
- trace: DecodedCreateMessageTrace
932
- ): boolean {
933
- // This error doesn't return data
934
- if (trace.returnData.length > 0) {
935
- return false;
936
- }
937
-
938
- const constructor = trace.bytecode.contract.constructorFunction;
939
-
940
- // This function is only matters with contracts that have constructors defined. The ones that
941
- // don't are abstract contracts, or their constructor doesn't take any argument.
942
- if (constructor === undefined) {
943
- return false;
944
- }
945
-
946
- return (
947
- trace.value > 0n &&
948
- (constructor.isPayable === undefined || !constructor.isPayable)
949
- );
950
- }
951
-
952
- /**
953
- * Returns a source reference pointing to the constructor if it exists, or to the contract
954
- * otherwise.
955
- */
956
- private _getConstructorStartSourceReference(
957
- trace: DecodedCreateMessageTrace
958
- ): SourceReference {
959
- const contract = trace.bytecode.contract;
960
- const constructor = contract.constructorFunction;
961
-
962
- const line =
963
- constructor !== undefined
964
- ? constructor.location.getStartingLineNumber()
965
- : contract.location.getStartingLineNumber();
966
-
967
- return {
968
- sourceName: contract.location.file.sourceName,
969
- sourceContent: contract.location.file.content,
970
- contract: contract.name,
971
- function: CONSTRUCTOR_FUNCTION_NAME,
972
- line,
973
- range: [
974
- contract.location.offset,
975
- contract.location.offset + contract.location.length,
976
- ],
977
- };
978
- }
979
-
980
- private _isConstructorInvalidArgumentsError(
981
- trace: DecodedCreateMessageTrace
982
- ): boolean {
983
- // This error doesn't return data
984
- if (trace.returnData.length > 0) {
985
- return false;
986
- }
987
-
988
- const contract = trace.bytecode.contract;
989
- const constructor = contract.constructorFunction;
990
-
991
- // This function is only matters with contracts that have constructors defined. The ones that
992
- // don't are abstract contracts, or their constructor doesn't take any argument.
993
- if (constructor === undefined) {
994
- return false;
995
- }
996
-
997
- if (
998
- semver.lt(
999
- trace.bytecode.compilerVersion,
1000
- FIRST_SOLC_VERSION_CREATE_PARAMS_VALIDATION
1001
- )
1002
- ) {
1003
- return false;
1004
- }
1005
-
1006
- const lastStep = trace.steps[trace.steps.length - 1];
1007
- if (!isEvmStep(lastStep)) {
1008
- return false;
1009
- }
1010
-
1011
- const lastInst = trace.bytecode.getInstruction(lastStep.pc);
1012
- if (lastInst.opcode !== Opcode.REVERT || lastInst.location !== undefined) {
1013
- return false;
1014
- }
1015
-
1016
- let hasReadDeploymentCodeSize = false;
1017
-
1018
- // eslint-disable-next-line @typescript-eslint/prefer-for-of
1019
- for (let stepIndex = 0; stepIndex < trace.steps.length; stepIndex++) {
1020
- const step = trace.steps[stepIndex];
1021
- if (!isEvmStep(step)) {
1022
- return false;
1023
- }
1024
-
1025
- const inst = trace.bytecode.getInstruction(step.pc);
1026
-
1027
- if (
1028
- inst.location !== undefined &&
1029
- !contract.location.equals(inst.location) &&
1030
- !constructor.location.equals(inst.location)
1031
- ) {
1032
- return false;
1033
- }
1034
-
1035
- if (inst.opcode === Opcode.CODESIZE && isCreateTrace(trace)) {
1036
- hasReadDeploymentCodeSize = true;
1037
- }
1038
- }
1039
-
1040
- return hasReadDeploymentCodeSize;
1041
- }
1042
-
1043
- private _getEntryBeforeInitialModifierCallstackEntry(
1044
- trace: DecodedEvmMessageTrace
1045
- ): SolidityStackTraceEntry {
1046
- if (isDecodedCreateTrace(trace)) {
1047
- return {
1048
- type: StackTraceEntryType.CALLSTACK_ENTRY,
1049
- sourceReference: this._getConstructorStartSourceReference(trace),
1050
- functionType: ContractFunctionType.CONSTRUCTOR,
1051
- };
1052
- }
1053
-
1054
- const calledFunction = trace.bytecode.contract.getFunctionFromSelector(
1055
- trace.calldata.slice(0, 4)
1056
- );
1057
-
1058
- if (calledFunction !== undefined) {
1059
- return {
1060
- type: StackTraceEntryType.CALLSTACK_ENTRY,
1061
- sourceReference: this._getFunctionStartSourceReference(
1062
- trace,
1063
- calledFunction
1064
- ),
1065
- functionType: ContractFunctionType.FUNCTION,
1066
- };
1067
- }
1068
-
1069
- // If it failed or made a call from within a modifier, and the selector doesn't match
1070
- // any function, it must have a fallback.
1071
- return {
1072
- type: StackTraceEntryType.CALLSTACK_ENTRY,
1073
- sourceReference: this._getFallbackStartSourceReference(trace),
1074
- functionType: ContractFunctionType.FALLBACK,
1075
- };
1076
- }
1077
-
1078
- private _getLastSourceReference(
1079
- trace: DecodedEvmMessageTrace
1080
- ): SourceReference | undefined {
1081
- for (let i = trace.steps.length - 1; i >= 0; i--) {
1082
- const step = trace.steps[i];
1083
- if (!isEvmStep(step)) {
1084
- continue;
1085
- }
1086
-
1087
- const inst = trace.bytecode.getInstruction(step.pc);
1088
-
1089
- if (inst.location === undefined) {
1090
- continue;
1091
- }
1092
-
1093
- const sourceReference = sourceLocationToSourceReference(
1094
- trace.bytecode,
1095
- inst.location
1096
- );
1097
-
1098
- if (sourceReference !== undefined) {
1099
- return sourceReference;
1100
- }
1101
- }
1102
-
1103
- return undefined;
1104
- }
1105
-
1106
- private _hasFailedInsideTheFallbackFunction(
1107
- trace: DecodedCallMessageTrace
1108
- ): boolean {
1109
- const contract = trace.bytecode.contract;
1110
-
1111
- if (contract.fallback === undefined) {
1112
- return false;
1113
- }
1114
-
1115
- return this._hasFailedInsideFunction(trace, contract.fallback);
1116
- }
1117
-
1118
- private _hasFailedInsideTheReceiveFunction(
1119
- trace: DecodedCallMessageTrace
1120
- ): boolean {
1121
- const contract = trace.bytecode.contract;
1122
-
1123
- if (contract.receive === undefined) {
1124
- return false;
1125
- }
1126
-
1127
- return this._hasFailedInsideFunction(trace, contract.receive);
1128
- }
1129
-
1130
- private _hasFailedInsideFunction(
1131
- trace: DecodedCallMessageTrace,
1132
- func: ContractFunction
1133
- ) {
1134
- const lastStep = trace.steps[trace.steps.length - 1] as EvmStep;
1135
- const lastInstruction = trace.bytecode.getInstruction(lastStep.pc);
1136
-
1137
- return (
1138
- lastInstruction.location !== undefined &&
1139
- lastInstruction.opcode === Opcode.REVERT &&
1140
- func.location.contains(lastInstruction.location)
1141
- );
1142
- }
1143
-
1144
- private _instructionWithinFunctionToRevertStackTraceEntry(
1145
- trace: DecodedEvmMessageTrace,
1146
- inst: Instruction
1147
- ): RevertErrorStackTraceEntry {
1148
- const sourceReference = sourceLocationToSourceReference(
1149
- trace.bytecode,
1150
- inst.location
1151
- );
1152
- assertHardhatInvariant(
1153
- sourceReference !== undefined,
1154
- "Expected source reference to be defined"
1155
- );
1156
-
1157
- return {
1158
- type: StackTraceEntryType.REVERT_ERROR,
1159
- sourceReference,
1160
- message: new ReturnData(trace.returnData),
1161
- isInvalidOpcodeError: inst.opcode === Opcode.INVALID,
1162
- };
1163
- }
1164
-
1165
- private _instructionWithinFunctionToUnmappedSolc063RevertErrorStackTraceEntry(
1166
- trace: DecodedEvmMessageTrace,
1167
- inst: Instruction
1168
- ): UnmappedSolc063RevertErrorStackTraceEntry {
1169
- const sourceReference = sourceLocationToSourceReference(
1170
- trace.bytecode,
1171
- inst.location
1172
- );
1173
-
1174
- return {
1175
- type: StackTraceEntryType.UNMAPPED_SOLC_0_6_3_REVERT_ERROR,
1176
- sourceReference,
1177
- };
1178
- }
1179
-
1180
- private _instructionWithinFunctionToPanicStackTraceEntry(
1181
- trace: DecodedEvmMessageTrace,
1182
- inst: Instruction,
1183
- errorCode: bigint
1184
- ): PanicErrorStackTraceEntry {
1185
- const lastSourceReference = this._getLastSourceReference(trace);
1186
- return {
1187
- type: StackTraceEntryType.PANIC_ERROR,
1188
- sourceReference:
1189
- sourceLocationToSourceReference(trace.bytecode, inst.location) ??
1190
- lastSourceReference,
1191
- errorCode,
1192
- };
1193
- }
1194
-
1195
- private _instructionWithinFunctionToCustomErrorStackTraceEntry(
1196
- trace: DecodedEvmMessageTrace,
1197
- inst: Instruction,
1198
- message: string
1199
- ): CustomErrorStackTraceEntry {
1200
- const lastSourceReference = this._getLastSourceReference(trace);
1201
-
1202
- assertHardhatInvariant(
1203
- lastSourceReference !== undefined,
1204
- "Expected last source reference to be defined"
1205
- );
1206
-
1207
- return {
1208
- type: StackTraceEntryType.CUSTOM_ERROR,
1209
- sourceReference:
1210
- sourceLocationToSourceReference(trace.bytecode, inst.location) ??
1211
- lastSourceReference,
1212
- message,
1213
- };
1214
- }
1215
-
1216
- private _solidity063MaybeUnmappedRevert(trace: DecodedEvmMessageTrace) {
1217
- if (trace.steps.length === 0) {
1218
- return false;
1219
- }
1220
-
1221
- const lastStep = trace.steps[trace.steps.length - 1];
1222
- if (!isEvmStep(lastStep)) {
1223
- return false;
1224
- }
1225
-
1226
- const lastInst = trace.bytecode.getInstruction(lastStep.pc);
1227
-
1228
- return (
1229
- semver.satisfies(
1230
- trace.bytecode.compilerVersion,
1231
- `^${FIRST_SOLC_VERSION_WITH_UNMAPPED_REVERTS}`
1232
- ) && lastInst.opcode === Opcode.REVERT
1233
- );
1234
- }
1235
-
1236
- // Solidity 0.6.3 unmapped reverts special handling
1237
- // For more info: https://github.com/ethereum/solidity/issues/9006
1238
- private _solidity063GetFrameForUnmappedRevertBeforeFunction(
1239
- trace: DecodedCallMessageTrace
1240
- ) {
1241
- let revertFrame =
1242
- this._solidity063GetFrameForUnmappedRevertWithinFunction(trace);
1243
-
1244
- if (
1245
- revertFrame === undefined ||
1246
- revertFrame.sourceReference === undefined
1247
- ) {
1248
- if (
1249
- trace.bytecode.contract.receive === undefined ||
1250
- trace.calldata.length > 0
1251
- ) {
1252
- if (trace.bytecode.contract.fallback !== undefined) {
1253
- // Failed within the fallback
1254
- const location = trace.bytecode.contract.fallback.location;
1255
- revertFrame = {
1256
- type: StackTraceEntryType.UNMAPPED_SOLC_0_6_3_REVERT_ERROR,
1257
- sourceReference: {
1258
- contract: trace.bytecode.contract.name,
1259
- function: FALLBACK_FUNCTION_NAME,
1260
- sourceName: location.file.sourceName,
1261
- sourceContent: location.file.content,
1262
- line: location.getStartingLineNumber(),
1263
- range: [location.offset, location.offset + location.length],
1264
- },
1265
- };
1266
-
1267
- this._solidity063CorrectLineNumber(revertFrame);
1268
- }
1269
- } else {
1270
- // Failed within the receive function
1271
- const location = trace.bytecode.contract.receive.location;
1272
- revertFrame = {
1273
- type: StackTraceEntryType.UNMAPPED_SOLC_0_6_3_REVERT_ERROR,
1274
- sourceReference: {
1275
- contract: trace.bytecode.contract.name,
1276
- function: RECEIVE_FUNCTION_NAME,
1277
- sourceName: location.file.sourceName,
1278
- sourceContent: location.file.content,
1279
- line: location.getStartingLineNumber(),
1280
- range: [location.offset, location.offset + location.length],
1281
- },
1282
- };
1283
-
1284
- this._solidity063CorrectLineNumber(revertFrame);
1285
- }
1286
- }
1287
- return revertFrame;
1288
- }
1289
-
1290
- private _getOtherErrorBeforeCalledFunctionStackTraceEntry(
1291
- trace: DecodedCallMessageTrace
1292
- ): OtherExecutionErrorStackTraceEntry {
1293
- return {
1294
- type: StackTraceEntryType.OTHER_EXECUTION_ERROR,
1295
- sourceReference:
1296
- this._getContractStartWithoutFunctionSourceReference(trace),
1297
- };
1298
- }
1299
-
1300
- private _isCalledNonContractAccountError(
1301
- trace: DecodedEvmMessageTrace
1302
- ): boolean {
1303
- // We could change this to checking that the last valid location maps to a call, but
1304
- // it's way more complex as we need to get the ast node from that location.
1305
-
1306
- const lastIndex = this._getLastInstructionWithValidLocationStepIndex(trace);
1307
- if (lastIndex === undefined || lastIndex === 0) {
1308
- return false;
1309
- }
1310
-
1311
- const lastStep = trace.steps[lastIndex] as EvmStep; // We know this is an EVM step
1312
- const lastInst = trace.bytecode.getInstruction(lastStep.pc);
1313
- if (lastInst.opcode !== Opcode.ISZERO) {
1314
- return false;
1315
- }
1316
-
1317
- const prevStep = trace.steps[lastIndex - 1] as EvmStep; // We know this is an EVM step
1318
- const prevInst = trace.bytecode.getInstruction(prevStep.pc);
1319
- return prevInst.opcode === Opcode.EXTCODESIZE;
1320
- }
1321
-
1322
- private _solidity063GetFrameForUnmappedRevertWithinFunction(
1323
- trace: DecodedEvmMessageTrace
1324
- ): UnmappedSolc063RevertErrorStackTraceEntry | undefined {
1325
- // If we are within a function there's a last valid location. It may
1326
- // be the entire contract.
1327
- const prevInst = this._getLastInstructionWithValidLocation(trace);
1328
- const lastStep = trace.steps[trace.steps.length - 1] as EvmStep;
1329
- const nextInstPc = lastStep.pc + 1;
1330
- const hasNextInst = trace.bytecode.hasInstruction(nextInstPc);
1331
-
1332
- if (hasNextInst) {
1333
- const nextInst = trace.bytecode.getInstruction(nextInstPc);
1334
- const prevLoc = prevInst?.location;
1335
- const nextLoc = nextInst.location;
1336
- const prevFunc = prevLoc?.getContainingFunction();
1337
- const nextFunc = nextLoc?.getContainingFunction();
1338
-
1339
- // This is probably a require. This means that we have the exact
1340
- // line, but the stack trace may be degraded (e.g. missing our
1341
- // synthetic call frames when failing in a modifier) so we still
1342
- // add this frame as UNMAPPED_SOLC_0_6_3_REVERT_ERROR
1343
- if (
1344
- prevFunc !== undefined &&
1345
- nextLoc !== undefined &&
1346
- prevLoc !== undefined &&
1347
- prevLoc.equals(nextLoc)
1348
- ) {
1349
- return this._instructionWithinFunctionToUnmappedSolc063RevertErrorStackTraceEntry(
1350
- trace,
1351
- nextInst
1352
- );
1353
- }
1354
-
1355
- let revertFrame: UnmappedSolc063RevertErrorStackTraceEntry | undefined;
1356
-
1357
- // If the previous and next location don't match, we try to use the
1358
- // previous one if it's inside a function, otherwise we use the next one
1359
- if (prevFunc !== undefined && prevInst !== undefined) {
1360
- revertFrame =
1361
- this._instructionWithinFunctionToUnmappedSolc063RevertErrorStackTraceEntry(
1362
- trace,
1363
- prevInst
1364
- );
1365
- } else if (nextFunc !== undefined) {
1366
- revertFrame =
1367
- this._instructionWithinFunctionToUnmappedSolc063RevertErrorStackTraceEntry(
1368
- trace,
1369
- nextInst
1370
- );
1371
- }
1372
-
1373
- if (revertFrame !== undefined) {
1374
- this._solidity063CorrectLineNumber(revertFrame);
1375
- }
1376
-
1377
- return revertFrame;
1378
- }
1379
-
1380
- if (isCreateTrace(trace) && prevInst !== undefined) {
1381
- // Solidity is smart enough to stop emitting extra instructions after
1382
- // an unconditional revert happens in a constructor. If this is the case
1383
- // we just return a special error.
1384
- const constructorRevertFrame: UnmappedSolc063RevertErrorStackTraceEntry =
1385
- this._instructionWithinFunctionToUnmappedSolc063RevertErrorStackTraceEntry(
1386
- trace,
1387
- prevInst
1388
- );
1389
-
1390
- // When the latest instruction is not within a function we need
1391
- // some default sourceReference to show to the user
1392
- if (constructorRevertFrame.sourceReference === undefined) {
1393
- const location = trace.bytecode.contract.location;
1394
- const defaultSourceReference: SourceReference = {
1395
- function: CONSTRUCTOR_FUNCTION_NAME,
1396
- contract: trace.bytecode.contract.name,
1397
- sourceName: location.file.sourceName,
1398
- sourceContent: location.file.content,
1399
- line: location.getStartingLineNumber(),
1400
- range: [location.offset, location.offset + location.length],
1401
- };
1402
-
1403
- if (trace.bytecode.contract.constructorFunction !== undefined) {
1404
- defaultSourceReference.line =
1405
- trace.bytecode.contract.constructorFunction.location.getStartingLineNumber();
1406
- }
1407
-
1408
- constructorRevertFrame.sourceReference = defaultSourceReference;
1409
- } else {
1410
- this._solidity063CorrectLineNumber(constructorRevertFrame);
1411
- }
1412
-
1413
- return constructorRevertFrame;
1414
- }
1415
-
1416
- if (prevInst !== undefined) {
1417
- // We may as well just be in a function or modifier and just happen
1418
- // to be at the last instruction of the runtime bytecode.
1419
- // In this case we just return whatever the last mapped intruction
1420
- // points to.
1421
- const latestInstructionRevertFrame: UnmappedSolc063RevertErrorStackTraceEntry =
1422
- this._instructionWithinFunctionToUnmappedSolc063RevertErrorStackTraceEntry(
1423
- trace,
1424
- prevInst
1425
- );
1426
-
1427
- if (latestInstructionRevertFrame.sourceReference !== undefined) {
1428
- this._solidity063CorrectLineNumber(latestInstructionRevertFrame);
1429
- }
1430
- return latestInstructionRevertFrame;
1431
- }
1432
- }
1433
-
1434
- private _isContractTooLargeError(trace: DecodedCreateMessageTrace) {
1435
- return trace.exit.kind === ExitCode.CODESIZE_EXCEEDS_MAXIMUM;
1436
- }
1437
-
1438
- private _solidity063CorrectLineNumber(
1439
- revertFrame: UnmappedSolc063RevertErrorStackTraceEntry
1440
- ) {
1441
- if (revertFrame.sourceReference === undefined) {
1442
- return;
1443
- }
1444
-
1445
- const lines = revertFrame.sourceReference.sourceContent.split("\n");
1446
-
1447
- const currentLine = lines[revertFrame.sourceReference.line - 1];
1448
-
1449
- if (currentLine.includes("require") || currentLine.includes("revert")) {
1450
- return;
1451
- }
1452
-
1453
- const nextLines = lines.slice(revertFrame.sourceReference.line);
1454
- const firstNonEmptyLine = nextLines.findIndex((l) => l.trim() !== "");
1455
-
1456
- if (firstNonEmptyLine === -1) {
1457
- return;
1458
- }
1459
-
1460
- const nextLine = nextLines[firstNonEmptyLine];
1461
-
1462
- if (nextLine.includes("require") || nextLine.includes("revert")) {
1463
- revertFrame.sourceReference.line += 1 + firstNonEmptyLine;
1464
- }
1465
- }
1466
-
1467
- private _getLastInstructionWithValidLocationStepIndex(
1468
- trace: DecodedEvmMessageTrace
1469
- ): number | undefined {
1470
- for (let i = trace.steps.length - 1; i >= 0; i--) {
1471
- const step = trace.steps[i];
1472
-
1473
- if (!isEvmStep(step)) {
1474
- return undefined;
1475
- }
1476
-
1477
- const inst = trace.bytecode.getInstruction(step.pc);
1478
-
1479
- if (inst.location !== undefined) {
1480
- return i;
1481
- }
1482
- }
1483
-
1484
- return undefined;
1485
- }
1486
-
1487
- private _getLastInstructionWithValidLocation(
1488
- trace: DecodedEvmMessageTrace
1489
- ): Instruction | undefined {
1490
- const lastLocationIndex =
1491
- this._getLastInstructionWithValidLocationStepIndex(trace);
1492
-
1493
- if (lastLocationIndex === undefined) {
1494
- return undefined;
1495
- }
1496
-
1497
- const lastLocationStep = trace.steps[lastLocationIndex];
1498
- if (isEvmStep(lastLocationStep)) {
1499
- const lastInstructionWithLocation = trace.bytecode.getInstruction(
1500
- lastLocationStep.pc
1501
- );
1502
- return lastInstructionWithLocation;
1503
- }
1504
-
1505
- return undefined;
1506
- }
1507
-
1508
- private _callInstructionToCallFailedToExecuteStackTraceEntry(
1509
- bytecode: Bytecode,
1510
- callInst: Instruction
1511
- ): CallFailedErrorStackTraceEntry {
1512
- const sourceReference = sourceLocationToSourceReference(
1513
- bytecode,
1514
- callInst.location
1515
- );
1516
- assertHardhatInvariant(
1517
- sourceReference !== undefined,
1518
- "Expected source reference to be defined"
1519
- );
1520
-
1521
- // Calls only happen within functions
1522
- return {
1523
- type: StackTraceEntryType.CALL_FAILED_ERROR,
1524
- sourceReference,
1525
- };
1526
- }
1527
-
1528
- private _getEntryBeforeFailureInModifier(
1529
- trace: DecodedEvmMessageTrace,
1530
- functionJumpdests: Instruction[]
1531
- ): CallstackEntryStackTraceEntry | InternalFunctionCallStackEntry {
1532
- // If there's a jumpdest, this modifier belongs to the last function that it represents
1533
- if (functionJumpdests.length > 0) {
1534
- return instructionToCallstackStackTraceEntry(
1535
- trace.bytecode,
1536
- functionJumpdests[functionJumpdests.length - 1]
1537
- );
1538
- }
1539
-
1540
- // This function is only called after we jumped into the initial function in call traces, so
1541
- // there should always be at least a function jumpdest.
1542
- if (!isDecodedCreateTrace(trace)) {
1543
- throw new Error(
1544
- "This shouldn't happen: a call trace has no functionJumpdest but has already jumped into a function"
1545
- );
1546
- }
1547
-
1548
- // If there's no jump dest, we point to the constructor.
1549
- return {
1550
- type: StackTraceEntryType.CALLSTACK_ENTRY,
1551
- sourceReference: this._getConstructorStartSourceReference(trace),
1552
- functionType: ContractFunctionType.CONSTRUCTOR,
1553
- };
1554
- }
1555
-
1556
- private _failsRightAfterCall(
1557
- trace: DecodedEvmMessageTrace,
1558
- callSubtraceStepIndex: number
1559
- ): boolean {
1560
- const lastStep = trace.steps[trace.steps.length - 1];
1561
- if (!isEvmStep(lastStep)) {
1562
- return false;
1563
- }
1564
-
1565
- const lastInst = trace.bytecode.getInstruction(lastStep.pc);
1566
- if (lastInst.opcode !== Opcode.REVERT) {
1567
- return false;
1568
- }
1569
-
1570
- const callOpcodeStep = trace.steps[callSubtraceStepIndex - 1] as EvmStep;
1571
- const callInst = trace.bytecode.getInstruction(callOpcodeStep.pc);
1572
-
1573
- // Calls are always made from within functions
1574
- assertHardhatInvariant(
1575
- callInst.location !== undefined,
1576
- "Expected call instruction location to be defined"
1577
- );
1578
-
1579
- return this._isLastLocation(
1580
- trace,
1581
- callSubtraceStepIndex + 1,
1582
- callInst.location
1583
- );
1584
- }
1585
-
1586
- private _isCallFailedError(
1587
- trace: DecodedEvmMessageTrace,
1588
- instIndex: number,
1589
- callInstruction: Instruction
1590
- ): boolean {
1591
- const callLocation = callInstruction.location;
1592
-
1593
- // Calls are always made from within functions
1594
- assertHardhatInvariant(
1595
- callLocation !== undefined,
1596
- "Expected call location to be defined"
1597
- );
1598
-
1599
- return this._isLastLocation(trace, instIndex, callLocation);
1600
- }
1601
-
1602
- private _isLastLocation(
1603
- trace: DecodedEvmMessageTrace,
1604
- fromStep: number,
1605
- location: SourceLocation
1606
- ): boolean {
1607
- for (let i = fromStep; i < trace.steps.length; i++) {
1608
- const step = trace.steps[i];
1609
-
1610
- if (!isEvmStep(step)) {
1611
- return false;
1612
- }
1613
-
1614
- const stepInst = trace.bytecode.getInstruction(step.pc);
1615
-
1616
- if (stepInst.location === undefined) {
1617
- continue;
1618
- }
1619
-
1620
- if (!location.equals(stepInst.location)) {
1621
- return false;
1622
- }
1623
- }
1624
-
1625
- return true;
1626
- }
1627
-
1628
- private _isSubtraceErrorPropagated(
1629
- trace: DecodedEvmMessageTrace,
1630
- callSubtraceStepIndex: number
1631
- ): boolean {
1632
- const call = trace.steps[callSubtraceStepIndex] as MessageTrace;
1633
-
1634
- if (!equalsBytes(trace.returnData, call.returnData)) {
1635
- return false;
1636
- }
1637
-
1638
- if (
1639
- trace.exit.kind === ExitCode.OUT_OF_GAS &&
1640
- call.exit.kind === ExitCode.OUT_OF_GAS
1641
- ) {
1642
- return true;
1643
- }
1644
-
1645
- // If the return data is not empty, and it's still the same, we assume it
1646
- // is being propagated
1647
- if (trace.returnData.length > 0) {
1648
- return true;
1649
- }
1650
-
1651
- return this._failsRightAfterCall(trace, callSubtraceStepIndex);
1652
- }
1653
-
1654
- private _isProxyErrorPropagated(
1655
- trace: DecodedEvmMessageTrace,
1656
- callSubtraceStepIndex: number
1657
- ): boolean {
1658
- if (!isDecodedCallTrace(trace)) {
1659
- return false;
1660
- }
1661
-
1662
- const callStep = trace.steps[callSubtraceStepIndex - 1];
1663
- if (!isEvmStep(callStep)) {
1664
- return false;
1665
- }
1666
-
1667
- const callInst = trace.bytecode.getInstruction(callStep.pc);
1668
- if (callInst.opcode !== Opcode.DELEGATECALL) {
1669
- return false;
1670
- }
1671
-
1672
- const subtrace = trace.steps[callSubtraceStepIndex];
1673
- if (isEvmStep(subtrace)) {
1674
- return false;
1675
- }
1676
-
1677
- if (isPrecompileTrace(subtrace)) {
1678
- return false;
1679
- }
1680
-
1681
- // If we can't recognize the implementation we'd better don't consider it as such
1682
- if (subtrace.bytecode === undefined) {
1683
- return false;
1684
- }
1685
-
1686
- if (subtrace.bytecode.contract.type === ContractType.LIBRARY) {
1687
- return false;
1688
- }
1689
-
1690
- if (!equalsBytes(trace.returnData, subtrace.returnData)) {
1691
- return false;
1692
- }
1693
-
1694
- for (let i = callSubtraceStepIndex + 1; i < trace.steps.length; i++) {
1695
- const step = trace.steps[i];
1696
- if (!isEvmStep(step)) {
1697
- return false;
1698
- }
1699
-
1700
- const inst = trace.bytecode.getInstruction(step.pc);
1701
-
1702
- // All the remaining locations should be valid, as they are part of the inline asm
1703
- if (inst.location === undefined) {
1704
- return false;
1705
- }
1706
-
1707
- if (
1708
- inst.jumpType === JumpType.INTO_FUNCTION ||
1709
- inst.jumpType === JumpType.OUTOF_FUNCTION
1710
- ) {
1711
- return false;
1712
- }
1713
- }
1714
-
1715
- const lastStep = trace.steps[trace.steps.length - 1] as EvmStep;
1716
- const lastInst = trace.bytecode.getInstruction(lastStep.pc);
1717
-
1718
- return lastInst.opcode === Opcode.REVERT;
1719
- }
1720
-
1721
- private _isContractCallRunOutOfGasError(
1722
- trace: DecodedEvmMessageTrace,
1723
- callStepIndex: number
1724
- ): boolean {
1725
- if (trace.returnData.length > 0) {
1726
- return false;
1727
- }
1728
-
1729
- if (trace.exit.kind !== ExitCode.REVERT) {
1730
- return false;
1731
- }
1732
-
1733
- const call = trace.steps[callStepIndex] as MessageTrace;
1734
- if (call.exit.kind !== ExitCode.OUT_OF_GAS) {
1735
- return false;
1736
- }
1737
-
1738
- return this._failsRightAfterCall(trace, callStepIndex);
1739
- }
1740
-
1741
- private _isPanicReturnData(returnData: Uint8Array): boolean {
1742
- return new ReturnData(returnData).isPanicReturnData();
1743
- }
1744
- }
1745
-
1746
- export function instructionToCallstackStackTraceEntry(
1747
- bytecode: Bytecode,
1748
- inst: Instruction
1749
- ): CallstackEntryStackTraceEntry | InternalFunctionCallStackEntry {
1750
- // This means that a jump is made from within an internal solc function.
1751
- // These are normally made from yul code, so they don't map to any Solidity
1752
- // function
1753
- if (inst.location === undefined) {
1754
- const location = bytecode.contract.location;
1755
- return {
1756
- type: StackTraceEntryType.INTERNAL_FUNCTION_CALLSTACK_ENTRY,
1757
- pc: inst.pc,
1758
- sourceReference: {
1759
- sourceName: bytecode.contract.location.file.sourceName,
1760
- sourceContent: bytecode.contract.location.file.content,
1761
- contract: bytecode.contract.name,
1762
- function: undefined,
1763
- line: bytecode.contract.location.getStartingLineNumber(),
1764
- range: [location.offset, location.offset + location.length],
1765
- },
1766
- };
1767
- }
1768
-
1769
- const func = inst.location?.getContainingFunction();
1770
-
1771
- if (func !== undefined) {
1772
- const sourceReference = sourceLocationToSourceReference(
1773
- bytecode,
1774
- inst.location
1775
- );
1776
- assertHardhatInvariant(
1777
- sourceReference !== undefined,
1778
- "Expected source reference to be defined"
1779
- );
1780
-
1781
- return {
1782
- type: StackTraceEntryType.CALLSTACK_ENTRY,
1783
- sourceReference,
1784
- functionType: func.type,
1785
- };
1786
- }
1787
-
1788
- assertHardhatInvariant(
1789
- inst.location !== undefined,
1790
- "Expected instruction location to be defined"
1791
- );
1792
-
1793
- return {
1794
- type: StackTraceEntryType.CALLSTACK_ENTRY,
1795
- sourceReference: {
1796
- function: undefined,
1797
- contract: bytecode.contract.name,
1798
- sourceName: inst.location.file.sourceName,
1799
- sourceContent: inst.location.file.content,
1800
- line: inst.location.getStartingLineNumber(),
1801
- range: [
1802
- inst.location.offset,
1803
- inst.location.offset + inst.location.length,
1804
- ],
1805
- },
1806
- functionType: ContractFunctionType.FUNCTION,
1807
- };
1808
- }
1809
-
1810
- function sourceLocationToSourceReference(
1811
- bytecode: Bytecode,
1812
- location?: SourceLocation
1813
- ): SourceReference | undefined {
1814
- if (location === undefined) {
1815
- return undefined;
1816
- }
1817
-
1818
- const func = location.getContainingFunction();
1819
-
1820
- if (func === undefined) {
1821
- return undefined;
1822
- }
1823
-
1824
- let funcName = func.name;
1825
-
1826
- if (func.type === ContractFunctionType.CONSTRUCTOR) {
1827
- funcName = CONSTRUCTOR_FUNCTION_NAME;
1828
- } else if (func.type === ContractFunctionType.FALLBACK) {
1829
- funcName = FALLBACK_FUNCTION_NAME;
1830
- } else if (func.type === ContractFunctionType.RECEIVE) {
1831
- funcName = RECEIVE_FUNCTION_NAME;
1832
- }
1833
-
1834
- return {
1835
- function: funcName,
1836
- contract:
1837
- func.type === ContractFunctionType.FREE_FUNCTION
1838
- ? undefined
1839
- : bytecode.contract.name,
1840
- sourceName: func.location.file.sourceName,
1841
- sourceContent: func.location.file.content,
1842
- line: location.getStartingLineNumber(),
1843
- range: [location.offset, location.offset + location.length],
1844
- };
1845
- }