recon-generate 0.0.10 → 0.0.11

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 (45) hide show
  1. package/dist/generator.d.ts +2 -0
  2. package/dist/generator.js +71 -0
  3. package/dist/index.js +55 -1
  4. package/dist/pathsGenerator.d.ts +5 -1
  5. package/dist/pathsGenerator.js +62 -11
  6. package/dist/templates/setup.js +4 -3
  7. package/dist/templates/wake/before_after.d.ts +1 -0
  8. package/dist/templates/wake/before_after.js +33 -0
  9. package/dist/templates/wake/conftest.d.ts +1 -0
  10. package/dist/templates/wake/conftest.js +18 -0
  11. package/dist/templates/wake/crytic_tester.d.ts +1 -0
  12. package/dist/templates/wake/crytic_tester.js +20 -0
  13. package/dist/templates/wake/flows.d.ts +1 -0
  14. package/dist/templates/wake/flows.js +18 -0
  15. package/dist/templates/wake/fuzz-test.d.ts +1 -0
  16. package/dist/templates/wake/fuzz-test.js +62 -0
  17. package/dist/templates/wake/handlebars_helpers.d.ts +2 -0
  18. package/dist/templates/wake/handlebars_helpers.js +84 -0
  19. package/dist/templates/wake/helpers/actor_manager.d.ts +1 -0
  20. package/dist/templates/wake/helpers/actor_manager.js +44 -0
  21. package/dist/templates/wake/helpers/asset_manager.d.ts +1 -0
  22. package/dist/templates/wake/helpers/asset_manager.js +44 -0
  23. package/dist/templates/wake/helpers/utils.d.ts +1 -0
  24. package/dist/templates/wake/helpers/utils.js +11 -0
  25. package/dist/templates/wake/helpers.d.ts +2 -0
  26. package/dist/templates/wake/helpers.js +81 -0
  27. package/dist/templates/wake/index.d.ts +10 -0
  28. package/dist/templates/wake/index.js +26 -0
  29. package/dist/templates/wake/invariants.d.ts +1 -0
  30. package/dist/templates/wake/invariants.js +21 -0
  31. package/dist/templates/wake/properties.d.ts +1 -0
  32. package/dist/templates/wake/properties.js +19 -0
  33. package/dist/templates/wake/setup.d.ts +1 -0
  34. package/dist/templates/wake/setup.js +48 -0
  35. package/dist/templates/wake/target_functions.d.ts +1 -0
  36. package/dist/templates/wake/target_functions.js +24 -0
  37. package/dist/templates/wake/targets/contract_targets.d.ts +1 -0
  38. package/dist/templates/wake/targets/contract_targets.js +23 -0
  39. package/dist/templates/wake/targets/managers_targets.d.ts +1 -0
  40. package/dist/templates/wake/targets/managers_targets.js +26 -0
  41. package/dist/templates/wake/test_fuzz.d.ts +1 -0
  42. package/dist/templates/wake/test_fuzz.js +27 -0
  43. package/dist/wakeGenerator.d.ts +32 -0
  44. package/dist/wakeGenerator.js +447 -0
  45. package/package.json +1 -1
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.actorManagerTemplate = void 0;
7
+ const handlebars_1 = __importDefault(require("handlebars"));
8
+ exports.actorManagerTemplate = handlebars_1.default.compile(`
9
+ from typing import List, Optional
10
+ from wake.testing import *
11
+
12
+ class ActorManager:
13
+ _actors: List[Account]
14
+ _actor: Optional[Account]
15
+
16
+ # Expected to be mixed in with a class having 'admin'
17
+
18
+ def __init_actors__(self):
19
+ self._actors = []
20
+ self._actor = None
21
+
22
+ @property
23
+ def current_actor(self) -> Account:
24
+ return self._get_actor()
25
+
26
+ def _get_actor(self) -> Account:
27
+ if not self._actor:
28
+ # Fallback to admin if available in self (Setup/FuzzTest)
29
+ if hasattr(self, 'admin') and self.admin:
30
+ return self.admin
31
+ from wake.testing import default_chain
32
+ return default_chain.accounts[0]
33
+ return self._actor
34
+
35
+ def _add_actor(self, actor: Account) -> None:
36
+ if actor not in self._actors:
37
+ self._actors.append(actor)
38
+ if not self._actor:
39
+ self._actor = actor
40
+
41
+ def _switch_actor(self, entropy: int) -> None:
42
+ if self._actors:
43
+ self._actor = self._actors[entropy % len(self._actors)]
44
+ `);
@@ -0,0 +1 @@
1
+ export declare const assetManagerTemplate: HandlebarsTemplateDelegate<any>;
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.assetManagerTemplate = void 0;
7
+ const handlebars_1 = __importDefault(require("handlebars"));
8
+ exports.assetManagerTemplate = handlebars_1.default.compile(`
9
+ from typing import List, Optional
10
+ from wake.testing import *
11
+ from pytypes.recon.MockERC20 import MockERC20
12
+
13
+ class AssetManager:
14
+ _assets: List[Address]
15
+ _asset: Optional[Address]
16
+
17
+ def __init_assets__(self):
18
+ self._assets = []
19
+ self._asset = None
20
+
21
+ def _get_asset(self) -> Address:
22
+ if self._asset:
23
+ return self._asset
24
+ if self._assets:
25
+ return self._assets[0]
26
+ return Address(0)
27
+
28
+ def _new_asset(self, decimals: int) -> Address:
29
+ # Assuming admin is available via self.admin
30
+ if not hasattr(self, 'admin'):
31
+ from wake.testing import default_chain
32
+ admin = default_chain.accounts[0]
33
+ else:
34
+ admin = self.admin
35
+
36
+ token = MockERC20.deploy("Test Token", "TST", decimals, from_=admin)
37
+ self._assets.append(token.address)
38
+ self._asset = token.address
39
+ return token.address
40
+
41
+ def _switch_asset(self, entropy: int) -> None:
42
+ if self._assets:
43
+ self._asset = self._assets[entropy % len(self._assets)]
44
+ `);
@@ -0,0 +1 @@
1
+ export declare const utilsTemplate: HandlebarsTemplateDelegate<any>;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.utilsTemplate = void 0;
7
+ const handlebars_1 = __importDefault(require("handlebars"));
8
+ exports.utilsTemplate = handlebars_1.default.compile(`
9
+ class Utils:
10
+ pass
11
+ `);
@@ -0,0 +1,2 @@
1
+ import Handlebars from "handlebars";
2
+ export declare function registerWakeHelpers(handlebars: typeof Handlebars): void;
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registerWakeHelpers = registerWakeHelpers;
4
+ const case_1 = require("case");
5
+ const types_1 = require("../../types"); // Keeping types for Actor/Mode
6
+ function registerWakeHelpers(handlebars) {
7
+ handlebars.registerHelper('snake', function (str) {
8
+ return (0, case_1.snake)(str);
9
+ });
10
+ handlebars.registerHelper('camel', function (str) {
11
+ return (0, case_1.camel)(str);
12
+ });
13
+ handlebars.registerHelper('pascal', function (str) {
14
+ return (0, case_1.pascal)(str);
15
+ });
16
+ /**
17
+ * Python default value based on type string.
18
+ */
19
+ function pythonDefault(type) {
20
+ if (type.includes("Address"))
21
+ return "Address(0)";
22
+ if (type.includes("int"))
23
+ return "0";
24
+ if (type === "bool")
25
+ return "False";
26
+ if (type.includes("bytes"))
27
+ return 'b""';
28
+ if (type.includes("list") || type.includes("List"))
29
+ return "[]";
30
+ return "None";
31
+ }
32
+ handlebars.registerHelper('pythonDefault', pythonDefault);
33
+ /**
34
+ * Generate a @flow decorated method definition for Wake FuzzTest.
35
+ * Expects: { contractName, method: { name, args: [{name, type}] }, actor, mode }
36
+ */
37
+ handlebars.registerHelper('flowDefinition', function ({ contractName, method, actor, mode }) {
38
+ const contractVar = (0, case_1.camel)(contractName);
39
+ const funcName = method.name;
40
+ // Build parameter list
41
+ const params = method.args.map((arg) => {
42
+ let typeStr = arg.type;
43
+ // Fix imported types if needed? Usually they are unqualified if imported, or fully qualified.
44
+ // Pytypes usually gives "ComplexVault.Status" or "Address".
45
+ return `${arg.name}: ${typeStr}`;
46
+ });
47
+ // Add self as first parameter
48
+ const paramStr = params.length > 0 ? `self, ${params.join(', ')}` : 'self';
49
+ // Determine sender based on actor type
50
+ let senderLine;
51
+ if (actor === types_1.Actor.ADMIN) {
52
+ senderLine = ' sender = default_chain.accounts[0] # Admin';
53
+ }
54
+ else {
55
+ senderLine = ' sender = self._get_actor()';
56
+ }
57
+ // Build argument list for the contract call
58
+ const callArgs = method.args.map((arg) => arg.name);
59
+ const callArgsStr = callArgs.length > 0 ? `${callArgs.join(', ')}, ` : '';
60
+ // Handle different modes (using existing logic, though pytypes inspection doesn't perfectly enable this yet)
61
+ let methodBody = `${senderLine}
62
+ # self.${contractVar}.${funcName}(${callArgsStr}from_=sender)`;
63
+ // We wrap in try-except by default per "identical suite" robustness usually found in these tools
64
+ // But user said "user only need to fix the setup and add invariants" implies flows should work or fail?
65
+ // Let's assume standard basic call.
66
+ methodBody = `${senderLine}
67
+ self.${contractVar}.${funcName}(${callArgsStr}from_=sender)`;
68
+ return `
69
+ @flow()
70
+ def flow_${(0, case_1.snake)(contractName)}_${(0, case_1.snake)(funcName)}(${paramStr}) -> None:
71
+ """Call ${contractName}.${funcName}"""
72
+ ${methodBody}
73
+ `;
74
+ });
75
+ handlebars.registerHelper('hasItems', function (arr, options) {
76
+ if (arr && arr.length > 0) {
77
+ return options.fn(this);
78
+ }
79
+ return options.inverse(this);
80
+ });
81
+ }
@@ -0,0 +1,10 @@
1
+ export * from './crytic_tester';
2
+ export * from './setup';
3
+ export * from './target_functions';
4
+ export * from './properties';
5
+ export * from './before_after';
6
+ export * from './helpers/actor_manager';
7
+ export * from './helpers/asset_manager';
8
+ export * from './helpers/utils';
9
+ export * from './targets/managers_targets';
10
+ export * from './targets/contract_targets';
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./crytic_tester"), exports);
18
+ __exportStar(require("./setup"), exports);
19
+ __exportStar(require("./target_functions"), exports);
20
+ __exportStar(require("./properties"), exports);
21
+ __exportStar(require("./before_after"), exports);
22
+ __exportStar(require("./helpers/actor_manager"), exports);
23
+ __exportStar(require("./helpers/asset_manager"), exports);
24
+ __exportStar(require("./helpers/utils"), exports);
25
+ __exportStar(require("./targets/managers_targets"), exports);
26
+ __exportStar(require("./targets/contract_targets"), exports);
@@ -0,0 +1 @@
1
+ export declare const invariantsTemplate: HandlebarsTemplateDelegate<any>;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.invariantsTemplate = void 0;
7
+ const handlebars_1 = __importDefault(require("handlebars"));
8
+ const helpers_1 = require("./helpers");
9
+ (0, helpers_1.registerWakeHelpers)(handlebars_1.default);
10
+ exports.invariantsTemplate = handlebars_1.default.compile(`
11
+ from wake.testing import *
12
+ from wake.testing.fuzzing import *
13
+
14
+ class Invariants:
15
+ @invariant()
16
+ def invariant_placeholder(self) -> None:
17
+ """
18
+ Placeholder invariant - replace with your actual property checks.
19
+ """
20
+ pass
21
+ `, { noEscape: true });
@@ -0,0 +1 @@
1
+ export declare const propertiesTemplate: HandlebarsTemplateDelegate<any>;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.propertiesTemplate = void 0;
7
+ const handlebars_1 = __importDefault(require("handlebars"));
8
+ exports.propertiesTemplate = handlebars_1.default.compile(`
9
+ from wake.testing import *
10
+ from wake.testing.fuzzing import *
11
+ from .setup import Setup
12
+
13
+ class Properties(Setup):
14
+ @invariant()
15
+ def check_invariants(self):
16
+ # Example invariant:
17
+ # assert self.complexVault.totalAssets() >= 0
18
+ pass
19
+ `, { noEscape: true });
@@ -0,0 +1 @@
1
+ export declare const setupTemplate: HandlebarsTemplateDelegate<any>;
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.setupTemplate = void 0;
7
+ const handlebars_1 = __importDefault(require("handlebars"));
8
+ const handlebars_helpers_1 = require("./handlebars_helpers");
9
+ (0, handlebars_helpers_1.registerWakeHelpers)(handlebars_1.default);
10
+ exports.setupTemplate = handlebars_1.default.compile(`
11
+ from typing import List, Optional, Union
12
+ from .helpers.actor_manager import ActorManager
13
+ from .helpers.asset_manager import AssetManager
14
+ from .helpers.utils import Utils
15
+ from wake.testing import *
16
+ from wake.testing.fuzzing import FuzzTest
17
+ # Import contracts for setup
18
+ {{#each contracts}}
19
+ from {{module}} import {{name}}
20
+ {{/each}}
21
+
22
+ class Setup(FuzzTest, ActorManager, AssetManager, Utils):
23
+ admin: Account
24
+ # Contracts
25
+ {{#each contracts}}
26
+ {{camel name}}: {{name}}
27
+ {{/each}}
28
+
29
+ def setup(self):
30
+ self.admin = default_chain.accounts[0]
31
+ self.__init_actors__()
32
+ self.__init_assets__()
33
+
34
+ self._add_actor(self.admin)
35
+ # Add a few more actors for better fuzzing coverage
36
+ for i in range(1, 5):
37
+ self._add_actor(default_chain.accounts[i])
38
+
39
+ # Deploy contracts
40
+ {{#each contracts}}
41
+ # Deploy {{name}}
42
+ # Args: {{#each deploy_args}}{{name}}: {{type}}, {{/each}}
43
+ self.{{camel name}} = {{name}}.deploy(
44
+ {{#each deploy_args}}{{name}}={{pythonDefault type}}, {{/each}}
45
+ from_=self.admin
46
+ )
47
+ {{/each}}
48
+ `, { noEscape: true });
@@ -0,0 +1 @@
1
+ export declare const targetFunctionsTemplate: HandlebarsTemplateDelegate<any>;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.targetFunctionsTemplate = void 0;
7
+ const handlebars_1 = __importDefault(require("handlebars"));
8
+ const handlebars_helpers_1 = require("./handlebars_helpers");
9
+ (0, handlebars_helpers_1.registerWakeHelpers)(handlebars_1.default);
10
+ exports.targetFunctionsTemplate = handlebars_1.default.compile(`
11
+ # imports
12
+ {{#each contracts}}
13
+ from .targets.{{snake name}}_targets import {{pascal name}}Targets
14
+ {{/each}}
15
+ from .targets.managers_targets import ManagersTargets
16
+
17
+ class TargetFunctions(
18
+ ManagersTargets,
19
+ {{#each contracts}}
20
+ {{pascal name}}Targets,
21
+ {{/each}}
22
+ ):
23
+ pass
24
+ `);
@@ -0,0 +1 @@
1
+ export declare const contractTargetsTemplate: HandlebarsTemplateDelegate<any>;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.contractTargetsTemplate = void 0;
7
+ const handlebars_1 = __importDefault(require("handlebars"));
8
+ const handlebars_helpers_1 = require("../handlebars_helpers");
9
+ (0, handlebars_helpers_1.registerWakeHelpers)(handlebars_1.default);
10
+ exports.contractTargetsTemplate = handlebars_1.default.compile(`
11
+ from typing import List, Optional, Union
12
+ from wake.testing import *
13
+ from wake.testing.fuzzing import *
14
+ from {{contract.module}} import {{contract.name}}
15
+ from ..properties import Properties
16
+
17
+ class {{pascal contract.name}}Targets(Properties):
18
+ # Assumes self.{{camel contract.name}} is available from Setup
19
+
20
+ {{#each flows}}
21
+ {{flowDefinition this}}
22
+ {{/each}}
23
+ `, { noEscape: true });
@@ -0,0 +1 @@
1
+ export declare const managersTargetsTemplate: HandlebarsTemplateDelegate<any>;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.managersTargetsTemplate = void 0;
7
+ const handlebars_1 = __importDefault(require("handlebars"));
8
+ exports.managersTargetsTemplate = handlebars_1.default.compile(`
9
+ from typing import List, Optional, Union
10
+ from wake.testing import *
11
+ from wake.testing.fuzzing import *
12
+ from ..properties import Properties
13
+
14
+ class ManagersTargets(Properties):
15
+ @flow()
16
+ def flow_switch_actor(self, entropy: uint256) -> None:
17
+ self._switch_actor(entropy)
18
+
19
+ @flow()
20
+ def flow_switch_asset(self, entropy: uint256) -> None:
21
+ self._switch_asset(entropy)
22
+
23
+ @flow()
24
+ def flow_add_new_asset(self, decimals: uint8) -> None:
25
+ self._new_asset(decimals)
26
+ `);
@@ -0,0 +1 @@
1
+ export declare const fuzzTestTemplate: HandlebarsTemplateDelegate<any>;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.fuzzTestTemplate = void 0;
7
+ const handlebars_1 = __importDefault(require("handlebars"));
8
+ const handlebars_helpers_1 = require("./handlebars_helpers");
9
+ (0, handlebars_helpers_1.registerWakeHelpers)(handlebars_1.default);
10
+ exports.fuzzTestTemplate = handlebars_1.default.compile(`"""
11
+ {{pascal suiteName}} Fuzz Test
12
+ """
13
+ from wake.testing import *
14
+ from wake.testing.fuzzing import *
15
+
16
+ from .setup import Setup
17
+ from .target_functions import TargetFunctions
18
+ from .properties import Properties
19
+ from .before_after import BeforeAfter
20
+
21
+ class {{pascal suiteName}}FuzzTest(FuzzTest, Setup, TargetFunctions, Properties, BeforeAfter):
22
+ def pre_sequence(self) -> None:
23
+ self.setup()
24
+
25
+ def test_{{snake suiteName}}_fuzz():
26
+ {{pascal suiteName}}FuzzTest().run(sequences_count=10, flows_count=100)
27
+ `);
@@ -0,0 +1,32 @@
1
+ export type FilterSpec = {
2
+ contractOnly: Set<string>;
3
+ functions: Map<string, Set<string>>;
4
+ };
5
+ export interface WakeGeneratorOptions {
6
+ suiteDir: string;
7
+ foundryConfigPath: string;
8
+ include?: FilterSpec;
9
+ exclude?: FilterSpec;
10
+ debug?: boolean;
11
+ force?: boolean;
12
+ forceBuild?: boolean;
13
+ admin?: Map<string, Set<string>>;
14
+ suiteNameSnake: string;
15
+ suiteNamePascal: string;
16
+ }
17
+ export declare class WakeGenerator {
18
+ private foundryRoot;
19
+ private options;
20
+ constructor(foundryRoot: string, options: WakeGeneratorOptions);
21
+ private logDebug;
22
+ private runCmd;
23
+ private ensureBuild;
24
+ private runWakeUp;
25
+ private copyBuiltins;
26
+ private inspectPytypes;
27
+ private matchesSignatureOrName;
28
+ private isContractAllowed;
29
+ private isFunctionIncluded;
30
+ run(): Promise<void>;
31
+ listAvailable(): Promise<void>;
32
+ }