recon-generate 0.0.6 → 0.0.8

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.
package/dist/utils.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { ASTNode, ContractDefinition, Assignment, FunctionCall, FunctionDefinition, VariableDeclaration } from 'solc-typed-ast';
1
+ import { ASTNode, ContractDefinition, Assignment, FunctionCall, FunctionDefinition, VariableDeclaration, EventDefinition, ErrorDefinition } from 'solc-typed-ast';
2
2
  import { CallType } from './types';
3
3
  export declare function fileExists(p: string): Promise<boolean>;
4
4
  export declare function getFoundryConfigPath(workspaceRoot: string, override?: string): string;
@@ -29,3 +29,13 @@ export declare function toSource(node: ASTNode, version?: string): string;
29
29
  export declare function getCallType(fnCall: FunctionCall): CallType;
30
30
  export declare const getFunctionName: (fnDef: FunctionDefinition) => string;
31
31
  export declare const signatureEquals: (a: FunctionDefinition, b: FunctionDefinition) => boolean;
32
+ export declare function getSignature(definition: FunctionDefinition | EventDefinition | ErrorDefinition): string;
33
+ export declare function getEnclosingContract(node: ASTNode): ContractDefinition | undefined;
34
+ export declare function resolveOverride(root: ContractDefinition, signature: string): FunctionDefinition | undefined;
35
+ export declare function idToContract(root: ContractDefinition, id: number): ContractDefinition | undefined;
36
+ export declare function forwardLinearization(root: ContractDefinition): ContractDefinition[];
37
+ /**
38
+ * Resolve the `super` call according to Solidity's C3 linearisation of the root
39
+ * contract. `current` is the contract whose code contains the `super` call.
40
+ */
41
+ export declare function resolveSuper(root: ContractDefinition, current: ContractDefinition, signature: string): FunctionDefinition | undefined;
package/dist/utils.js CHANGED
@@ -58,6 +58,12 @@ exports.getDeepRef = getDeepRef;
58
58
  exports.getDefinitions = getDefinitions;
59
59
  exports.toSource = toSource;
60
60
  exports.getCallType = getCallType;
61
+ exports.getSignature = getSignature;
62
+ exports.getEnclosingContract = getEnclosingContract;
63
+ exports.resolveOverride = resolveOverride;
64
+ exports.idToContract = idToContract;
65
+ exports.forwardLinearization = forwardLinearization;
66
+ exports.resolveSuper = resolveSuper;
61
67
  const fs = __importStar(require("fs/promises"));
62
68
  const path = __importStar(require("path"));
63
69
  const solc_typed_ast_1 = require("solc-typed-ast");
@@ -284,11 +290,27 @@ function getDeepRef(node) {
284
290
  }
285
291
  }
286
292
  function getDefinitions(contract, kind, inclusion = true) {
287
- let defs = inclusion ? contract[kind] : [];
288
- for (const child of contract.vLinearizedBaseContracts.filter((x) => x !== contract)) {
289
- defs = getDefinitions(child, kind).concat(defs.filter((x) => !getDefinitions(child, kind).includes(x)));
290
- }
291
- return defs;
293
+ const visited = new Set();
294
+ const gather = (c) => {
295
+ if (visited.has(c)) {
296
+ return [];
297
+ }
298
+ visited.add(c);
299
+ const own = inclusion ? c[kind] : [];
300
+ const defs = [...(own || [])];
301
+ for (const base of c.vLinearizedBaseContracts) {
302
+ if (base === c) {
303
+ continue;
304
+ }
305
+ for (const def of gather(base)) {
306
+ if (!defs.includes(def)) {
307
+ defs.push(def);
308
+ }
309
+ }
310
+ }
311
+ return defs;
312
+ };
313
+ return gather(contract);
292
314
  }
293
315
  function toSource(node, version) {
294
316
  const formatter = new solc_typed_ast_1.PrettyFormatter(4, 0);
@@ -333,3 +355,84 @@ const signatureEquals = (a, b) => {
333
355
  return a.stateMutability === b.stateMutability;
334
356
  };
335
357
  exports.signatureEquals = signatureEquals;
358
+ function getSignature(definition) {
359
+ let name;
360
+ if (definition instanceof solc_typed_ast_1.FunctionDefinition) {
361
+ if (definition.kind === solc_typed_ast_1.FunctionKind.Constructor) {
362
+ name = 'constructor';
363
+ }
364
+ else if (definition.kind === solc_typed_ast_1.FunctionKind.Fallback) {
365
+ name = 'fallback';
366
+ }
367
+ else if (definition.kind === solc_typed_ast_1.FunctionKind.Receive) {
368
+ name = 'receive';
369
+ }
370
+ else {
371
+ name = definition.name;
372
+ }
373
+ }
374
+ else {
375
+ name = definition.name;
376
+ }
377
+ const paramTypes = definition.vParameters.vParameters.map(param => param.typeString).join(',');
378
+ return `${name}(${paramTypes})`;
379
+ }
380
+ function getEnclosingContract(node) {
381
+ let cur = node;
382
+ while (cur) {
383
+ if (cur instanceof solc_typed_ast_1.FunctionDefinition && cur.vScope instanceof solc_typed_ast_1.ContractDefinition) {
384
+ return cur.vScope;
385
+ }
386
+ cur = cur.parent;
387
+ }
388
+ return undefined;
389
+ }
390
+ function resolveOverride(root, signature) {
391
+ for (const ctr of forwardLinearization(root)) {
392
+ const match = ctr.vFunctions.find(fn => getSignature(fn) === signature);
393
+ if (match)
394
+ return match;
395
+ }
396
+ return undefined;
397
+ }
398
+ function idToContract(root, id) {
399
+ try {
400
+ return root.requiredContext.locate(id);
401
+ }
402
+ catch {
403
+ return undefined;
404
+ }
405
+ }
406
+ // Build forward (source-order) linearized list: root, then direct bases left->right, then their bases recursively without duplicates.
407
+ function forwardLinearization(root) {
408
+ // Solidity compiler provides the C3 linearized order in `linearizedBaseContracts`.
409
+ // We rely on that order directly; it already starts with `root` and follows the
410
+ // resolution order used for `super`.
411
+ const ids = root.linearizedBaseContracts;
412
+ const contracts = [];
413
+ for (const id of ids) {
414
+ const ctr = idToContract(root, id);
415
+ if (ctr)
416
+ contracts.push(ctr);
417
+ }
418
+ return contracts;
419
+ }
420
+ /**
421
+ * Resolve the `super` call according to Solidity's C3 linearisation of the root
422
+ * contract. `current` is the contract whose code contains the `super` call.
423
+ */
424
+ function resolveSuper(root, current, signature) {
425
+ // Linearised list of contract IDs for `root` (e.g. [D, B, C, A])
426
+ const linearContracts = forwardLinearization(root);
427
+ // Find index of the current contract
428
+ const idx = linearContracts.findIndex(c => c.id === current.id);
429
+ if (idx === -1)
430
+ return undefined;
431
+ // Search forward for first contract implementing the function
432
+ for (let i = idx + 1; i < linearContracts.length; i++) {
433
+ const cand = linearContracts[i].vFunctions.find(fn => getSignature(fn) === signature);
434
+ if (cand)
435
+ return cand;
436
+ }
437
+ return undefined;
438
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "recon-generate",
3
- "version": "0.0.6",
3
+ "version": "0.0.8",
4
4
  "description": "CLI to scaffold Recon fuzzing suite inside Foundry projects",
5
5
  "main": "dist/index.js",
6
6
  "bin": {