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.
- package/dist/templateManager.js +2 -1
- package/dist/templates/handlebars-helpers.js +24 -8
- package/dist/templates/setup.js +5 -5
- package/dist/templates/target-functions.js +1 -1
- package/dist/templates/wake/handlebars_helpers.js +18 -3
- package/dist/templates/wake/setup.js +2 -2
- package/dist/templates/wake/targets/contract_targets.js +1 -1
- package/package.json +1 -1
package/dist/templateManager.js
CHANGED
|
@@ -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
|
-
|
|
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 ${
|
|
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
|
-
${
|
|
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, "${
|
|
123
|
+
t(false, "${funcPrefix}_${abi.name}");`
|
|
108
124
|
: ""}
|
|
109
125
|
}`;
|
|
110
126
|
}
|
|
111
127
|
else {
|
|
112
128
|
return `
|
|
113
|
-
function ${
|
|
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 ${
|
|
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 ${
|
|
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, "${
|
|
141
|
+
${hasOutputs ? " " : " "}t(false, "${funcPrefix}_${abi.name}");
|
|
126
142
|
${hasOutputs ? " " : " "}}
|
|
127
143
|
}`;
|
|
128
144
|
}
|
package/dist/templates/setup.js
CHANGED
|
@@ -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}} {{
|
|
31
|
+
{{this.name}} {{instanceName this.name}};
|
|
32
32
|
{{#if this.isDynamic}}
|
|
33
|
-
address[] {{
|
|
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
|
-
{{
|
|
41
|
+
{{instanceName this.name}} = new {{this.name}}(); // TODO: Add parameters here
|
|
42
42
|
{{#if this.isDynamic}}
|
|
43
|
-
{{
|
|
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 {{
|
|
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
|
-
{{
|
|
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
|
|
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.${
|
|
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.${
|
|
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
|
-
{{
|
|
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.{{
|
|
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.{{
|
|
18
|
+
# Assumes self.{{instanceName contract.name}} is available from Setup
|
|
19
19
|
|
|
20
20
|
{{#each flows}}
|
|
21
21
|
{{flowDefinition this}}
|