recon-generate 0.0.20 → 0.0.22

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.
@@ -36,6 +36,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.TemplateManager = void 0;
37
37
  const path = __importStar(require("path"));
38
38
  const fs = __importStar(require("fs/promises"));
39
+ const case_1 = require("case");
39
40
  const templates = __importStar(require("./templates"));
40
41
  const types_1 = require("./types");
41
42
  class TemplateManager {
@@ -209,7 +210,7 @@ class TemplateManager {
209
210
  [path.join(suiteTargetsDir, 'ManagersTargets.sol')]: templates.managersTargetsTemplate({}),
210
211
  };
211
212
  for (const [contractName, functions] of Object.entries(separatedByContract)) {
212
- const targetPath = path.join(suiteTargetsDir, `${contractName}Targets.sol`);
213
+ const targetPath = path.join(suiteTargetsDir, `${(0, case_1.pascal)(contractName)}Targets.sol`);
213
214
  files[targetPath] = templates.targetsTemplate({
214
215
  contractName,
215
216
  path: functions.length > 0 ? functions[0].contractPath : '',
@@ -9,6 +9,18 @@ function capitalizeFirstLetter(string) {
9
9
  }
10
10
  return string.charAt(0).toUpperCase() + string.slice(1);
11
11
  }
12
+ /**
13
+ * Returns a safe instance name for a contract.
14
+ * If camelCase(name) equals the original name (e.g., "fB" -> "fB"),
15
+ * prefix with "_" to avoid type/variable name collision.
16
+ */
17
+ function safeInstanceName(name) {
18
+ const camelName = (0, case_1.camel)(name);
19
+ if (camelName === name) {
20
+ return `_${camelName}`;
21
+ }
22
+ return camelName;
23
+ }
12
24
  function getUsableInternalType(internalType) {
13
25
  if (internalType.split(" ").length > 1) {
14
26
  return internalType.split(" ")[1];
@@ -52,8 +64,12 @@ function registerHelpers(handlebars) {
52
64
  handlebars.registerHelper('pascal', function (str) {
53
65
  return (0, case_1.pascal)(str);
54
66
  });
67
+ handlebars.registerHelper('instanceName', function (str) {
68
+ return safeInstanceName(str);
69
+ });
55
70
  handlebars.registerHelper('functionDefinition', function ({ contractName, abi, actor, mode }) {
56
- contractName = (0, case_1.camel)(contractName);
71
+ const funcPrefix = (0, case_1.camel)(contractName); // For function names: fB_method
72
+ const instanceVar = safeInstanceName(contractName); // For instance access: _fB.method
57
73
  let modifiers = [];
58
74
  if (abi.stateMutability === 'payable') {
59
75
  modifiers.push('payable');
@@ -97,32 +113,32 @@ function registerHelpers(handlebars) {
97
113
  });
98
114
  if (mode === types_1.Mode.NORMAL || mode === types_1.Mode.FAIL) {
99
115
  return `
100
- function ${contractName}_${abi.name}(${abi.inputs
116
+ function ${funcPrefix}_${abi.name}(${abi.inputs
101
117
  .map((input) => `${conditionallyAddMemoryLocation(input.type, extractType(input))} ${inputNames[abi.inputs.indexOf(input)]}`)
102
118
  .join(", ")}) public ${modifiersStr}{
103
- ${contractName}.${abi.name}${valueStr}(${abi.inputs
119
+ ${instanceVar}.${abi.name}${valueStr}(${abi.inputs
104
120
  .map((input, index) => inputNames[index] || getDefaultValue(input.type))
105
121
  .join(", ")});${mode === 'fail'
106
122
  ? `
107
- t(false, "${contractName}_${abi.name}");`
123
+ t(false, "${funcPrefix}_${abi.name}");`
108
124
  : ""}
109
125
  }`;
110
126
  }
111
127
  else {
112
128
  return `
113
- function ${contractName}_${abi.name}(${abi.inputs
129
+ function ${funcPrefix}_${abi.name}(${abi.inputs
114
130
  .map((input) => `${conditionallyAddMemoryLocation(input.type, extractType(input))} ${inputNames[abi.inputs.indexOf(input)]}`)
115
131
  .join(", ")}) public ${modifiersStr}{
116
132
  ${hasOutputs ? `${outputs}
117
- try ${contractName}.${abi.name}${valueStr}(${abi.inputs
133
+ try ${instanceVar}.${abi.name}${valueStr}(${abi.inputs
118
134
  .map((input, index) => inputNames[index] || getDefaultValue(input.type))
119
135
  .join(", ")}) returns (${returnTypes}) {
120
136
  ${assignValues}
121
137
  }`
122
- : `try ${contractName}.${abi.name}(${abi.inputs
138
+ : `try ${instanceVar}.${abi.name}(${abi.inputs
123
139
  .map((input, index) => inputNames[index] || getDefaultValue(input.type))
124
140
  .join(", ")}) {}`} catch {
125
- ${hasOutputs ? " " : " "}t(false, "${contractName}_${abi.name}");
141
+ ${hasOutputs ? " " : " "}t(false, "${funcPrefix}_${abi.name}");
126
142
  ${hasOutputs ? " " : " "}}
127
143
  }`;
128
144
  }
@@ -28,9 +28,9 @@ import "{{this.path}}";
28
28
 
29
29
  abstract contract Setup is BaseSetup, ActorManager, AssetManager, Utils {
30
30
  {{#each contracts}}
31
- {{this.name}} {{camel this.name}};
31
+ {{this.name}} {{instanceName this.name}};
32
32
  {{#if this.isDynamic}}
33
- address[] {{camel this.name}}_s;
33
+ address[] {{instanceName this.name}}_s;
34
34
  {{/if}}
35
35
  {{/each}}
36
36
 
@@ -38,9 +38,9 @@ abstract contract Setup is BaseSetup, ActorManager, AssetManager, Utils {
38
38
  /// This contains all calls to be performed in the tester constructor, both for Echidna and Foundry
39
39
  function setup() internal virtual override {
40
40
  {{#each contracts}}
41
- {{camel this.name}} = new {{this.name}}(); // TODO: Add parameters here
41
+ {{instanceName this.name}} = new {{this.name}}(); // TODO: Add parameters here
42
42
  {{#if this.isDynamic}}
43
- {{camel this.name}}_s.push(address({{camel this.name}}));
43
+ {{instanceName this.name}}_s.push(address({{instanceName this.name}}));
44
44
  {{/if}}
45
45
  {{/each}}
46
46
  }
@@ -49,7 +49,7 @@ abstract contract Setup is BaseSetup, ActorManager, AssetManager, Utils {
49
49
  {{#each contracts}}
50
50
  {{#if this.isDynamic}}
51
51
  function _getRandom{{pascal this.name}}(uint8 index) internal view returns (address) {
52
- return {{camel this.name}}_s[index % {{camel this.name}}_s.length];
52
+ return {{instanceName this.name}}_s[index % {{instanceName this.name}}_s.length];
53
53
  }
54
54
 
55
55
  {{/if}}
@@ -42,7 +42,7 @@ abstract contract TargetFunctions is
42
42
  /// AUTO GENERATED DYNAMIC DEPLOY SWITCHES ///
43
43
  {{#each dynamicContracts}}
44
44
  function switch{{pascal this.name}}(uint8 entropy) public {
45
- {{camel this.name}} = {{this.name}}(_getRandom{{pascal this.name}}(entropy));
45
+ {{instanceName this.name}} = {{this.name}}(_getRandom{{pascal this.name}}(entropy));
46
46
  }
47
47
 
48
48
  {{/each}}
@@ -3,6 +3,18 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.registerWakeHelpers = registerWakeHelpers;
4
4
  const case_1 = require("case");
5
5
  const types_1 = require("../../types"); // Keeping types for Actor/Mode
6
+ /**
7
+ * Returns a safe instance name for a contract.
8
+ * If camelCase(name) equals the original name (e.g., "fB" -> "fB"),
9
+ * prefix with "_" to avoid type/variable name collision.
10
+ */
11
+ function safeInstanceName(name) {
12
+ const camelName = (0, case_1.camel)(name);
13
+ if (camelName === name) {
14
+ return `_${camelName}`;
15
+ }
16
+ return camelName;
17
+ }
6
18
  function registerWakeHelpers(handlebars) {
7
19
  handlebars.registerHelper('snake', function (str) {
8
20
  return (0, case_1.snake)(str);
@@ -13,6 +25,9 @@ function registerWakeHelpers(handlebars) {
13
25
  handlebars.registerHelper('pascal', function (str) {
14
26
  return (0, case_1.pascal)(str);
15
27
  });
28
+ handlebars.registerHelper('instanceName', function (str) {
29
+ return safeInstanceName(str);
30
+ });
16
31
  /**
17
32
  * Python default value based on type string.
18
33
  */
@@ -35,7 +50,7 @@ function registerWakeHelpers(handlebars) {
35
50
  * Expects: { contractName, method: { name, args: [{name, type}] }, actor, mode }
36
51
  */
37
52
  handlebars.registerHelper('flowDefinition', function ({ contractName, method, actor, mode }) {
38
- const contractVar = (0, case_1.camel)(contractName);
53
+ const instanceVar = safeInstanceName(contractName); // For instance access: self._fB.method
39
54
  const funcName = method.name;
40
55
  // Build parameter list
41
56
  const params = method.args.map((arg) => {
@@ -59,13 +74,13 @@ function registerWakeHelpers(handlebars) {
59
74
  const callArgsStr = callArgs.length > 0 ? `${callArgs.join(', ')}, ` : '';
60
75
  // Handle different modes (using existing logic, though pytypes inspection doesn't perfectly enable this yet)
61
76
  let methodBody = `${senderLine}
62
- # self.${contractVar}.${funcName}(${callArgsStr}from_=sender)`;
77
+ # self.${instanceVar}.${funcName}(${callArgsStr}from_=sender)`;
63
78
  // We wrap in try-except by default per "identical suite" robustness usually found in these tools
64
79
  // But user said "user only need to fix the setup and add invariants" implies flows should work or fail?
65
80
  // Let's assume standard basic call.
66
81
  methodBody = `${senderLine}
67
82
  try:
68
- self.${contractVar}.${funcName}(${callArgsStr}from_=sender)
83
+ self.${instanceVar}.${funcName}(${callArgsStr}from_=sender)
69
84
  except Exception:
70
85
  pass`;
71
86
  return `
@@ -23,7 +23,7 @@ class Setup(FuzzTest, ActorManager, AssetManager, Utils):
23
23
  admin: Account
24
24
  # Contracts
25
25
  {{#each contracts}}
26
- {{camel name}}: {{name}}
26
+ {{instanceName name}}: {{name}}
27
27
  {{/each}}
28
28
 
29
29
  def setup(self):
@@ -40,7 +40,7 @@ class Setup(FuzzTest, ActorManager, AssetManager, Utils):
40
40
  {{#each contracts}}
41
41
  # Deploy {{name}}
42
42
  # Args: {{#each deploy_args}}{{name}}: {{type}}, {{/each}}
43
- self.{{camel name}} = {{name}}.deploy(
43
+ self.{{instanceName name}} = {{name}}.deploy(
44
44
  {{#each deploy_args}}{{name}}={{pythonDefault type}}, {{/each}}
45
45
  from_=self.admin
46
46
  )
@@ -15,7 +15,7 @@ from {{contract.module}} import {{contract.name}}
15
15
  from ..properties import Properties
16
16
 
17
17
  class {{pascal contract.name}}Targets(Properties):
18
- # Assumes self.{{camel contract.name}} is available from Setup
18
+ # Assumes self.{{instanceName contract.name}} is available from Setup
19
19
 
20
20
  {{#each flows}}
21
21
  {{flowDefinition this}}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "recon-generate",
3
- "version": "0.0.20",
3
+ "version": "0.0.22",
4
4
  "description": "CLI to scaffold Recon fuzzing suite inside Foundry projects",
5
5
  "main": "dist/index.js",
6
6
  "bin": {