siphon-library 1.1.0 → 1.2.0
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/out/code_reference.d.ts +11 -0
- package/out/code_reference.js +56 -0
- package/out/code_reference.js.map +1 -0
- package/out/pattern.d.ts +17 -0
- package/out/pattern.js +41 -0
- package/out/pattern.js.map +1 -0
- package/out/siphon_client.d.ts +38 -0
- package/out/siphon_client.js +61 -0
- package/out/siphon_client.js.map +1 -0
- package/out/test.d.ts +1 -0
- package/out/test.js +166 -0
- package/out/test.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
interface CodeReference {
|
|
2
|
+
fileName: string;
|
|
3
|
+
contractName: string;
|
|
4
|
+
functionName: string;
|
|
5
|
+
lines?: {
|
|
6
|
+
start: number;
|
|
7
|
+
end: number;
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
declare function createCodeReference(code: string, fileName: string, contractName: string, functionName: string): CodeReference;
|
|
11
|
+
export { createCodeReference, CodeReference };
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createCodeReference = createCodeReference;
|
|
4
|
+
function createCodeReference(code, fileName, contractName, functionName) {
|
|
5
|
+
const linesArray = code.split("\n");
|
|
6
|
+
let contractLine = -1;
|
|
7
|
+
for (let i = 0; i < linesArray.length; i++) {
|
|
8
|
+
if (linesArray[i].includes(`contract ${contractName}`)) {
|
|
9
|
+
contractLine = i + 1;
|
|
10
|
+
break;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
if (contractLine === -1) {
|
|
14
|
+
console.log(`Contract "${contractName}" not found in the code.`);
|
|
15
|
+
return { fileName, contractName, functionName };
|
|
16
|
+
}
|
|
17
|
+
let functionStartLine = -1;
|
|
18
|
+
let functionEndLine = -1;
|
|
19
|
+
for (let i = contractLine; i < linesArray.length; i++) {
|
|
20
|
+
if (linesArray[i].includes(`function ${functionName}(`)) {
|
|
21
|
+
functionStartLine = i + 1;
|
|
22
|
+
let openBraces = 0;
|
|
23
|
+
let foundOpening = false;
|
|
24
|
+
for (let j = i; j < linesArray.length; j++) {
|
|
25
|
+
const line = linesArray[j];
|
|
26
|
+
for (const char of line) {
|
|
27
|
+
if (char === "{") {
|
|
28
|
+
openBraces++;
|
|
29
|
+
foundOpening = true;
|
|
30
|
+
}
|
|
31
|
+
else if (char === "}") {
|
|
32
|
+
openBraces--;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
if (foundOpening && openBraces === 0) {
|
|
36
|
+
functionEndLine = j + 1;
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
const codeReference = {
|
|
44
|
+
fileName,
|
|
45
|
+
contractName,
|
|
46
|
+
functionName,
|
|
47
|
+
};
|
|
48
|
+
if (functionEndLine !== -1) {
|
|
49
|
+
codeReference.lines = {
|
|
50
|
+
start: functionStartLine,
|
|
51
|
+
end: functionEndLine,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
return codeReference;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=code_reference.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code_reference.js","sourceRoot":"","sources":["../src/code_reference.ts"],"names":[],"mappings":";;AA2ES,kDAAmB;AAjE5B,SAAS,mBAAmB,CAC1B,IAAY,EACZ,QAAgB,EAChB,YAAoB,EACpB,YAAoB;IAEpB,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAEpC,IAAI,YAAY,GAAG,CAAC,CAAC,CAAC;IACtB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3C,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,YAAY,YAAY,EAAE,CAAC,EAAE,CAAC;YACvD,YAAY,GAAG,CAAC,GAAG,CAAC,CAAC;YACrB,MAAM;QACR,CAAC;IACH,CAAC;IAED,IAAI,YAAY,KAAK,CAAC,CAAC,EAAE,CAAC;QACxB,OAAO,CAAC,GAAG,CAAC,aAAa,YAAY,0BAA0B,CAAC,CAAC;QACjE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,YAAY,EAAE,CAAC;IAClD,CAAC;IAED,IAAI,iBAAiB,GAAG,CAAC,CAAC,CAAC;IAC3B,IAAI,eAAe,GAAG,CAAC,CAAC,CAAC;IAEzB,KAAK,IAAI,CAAC,GAAG,YAAY,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtD,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,YAAY,YAAY,GAAG,CAAC,EAAE,CAAC;YACxD,iBAAiB,GAAG,CAAC,GAAG,CAAC,CAAC;YAC1B,IAAI,UAAU,GAAG,CAAC,CAAC;YACnB,IAAI,YAAY,GAAG,KAAK,CAAC;YACzB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC3C,MAAM,IAAI,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;gBAE3B,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC;oBACxB,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;wBACjB,UAAU,EAAE,CAAC;wBACb,YAAY,GAAG,IAAI,CAAC;oBACtB,CAAC;yBAAM,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;wBACxB,UAAU,EAAE,CAAC;oBACf,CAAC;gBACH,CAAC;gBAED,IAAI,YAAY,IAAI,UAAU,KAAK,CAAC,EAAE,CAAC;oBACrC,eAAe,GAAG,CAAC,GAAG,CAAC,CAAC;oBACxB,MAAM;gBACR,CAAC;YACH,CAAC;YACD,MAAM;QACR,CAAC;IACH,CAAC;IAED,MAAM,aAAa,GAAkB;QACnC,QAAQ;QACR,YAAY;QACZ,YAAY;KACb,CAAC;IAEF,IAAI,eAAe,KAAK,CAAC,CAAC,EAAE,CAAC;QAC3B,aAAa,CAAC,KAAK,GAAG;YACpB,KAAK,EAAE,iBAAiB;YACxB,GAAG,EAAE,eAAe;SACrB,CAAC;IACJ,CAAC;IACD,OAAO,aAAa,CAAC;AACvB,CAAC"}
|
package/out/pattern.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare enum PatternType {
|
|
2
|
+
RedundantCode = "REDUNDANT_CODE",
|
|
3
|
+
OpaquePredicates = "OPAQUE_PREDICATES",
|
|
4
|
+
ExpensiveOperationsInsideLoop = "EXPENSIVE_OPERATIONS_INSIDE_LOOP",
|
|
5
|
+
LoopInvariantOperations = "LOOP_INVARIANT_OPERATIONS",
|
|
6
|
+
LoopInvariantConditions = "LOOP_INVARIANT_CONDITIONS"
|
|
7
|
+
}
|
|
8
|
+
export type Severity = "low" | "medium" | "high" | "critical";
|
|
9
|
+
export interface PatternInfo {
|
|
10
|
+
name: string;
|
|
11
|
+
description: string;
|
|
12
|
+
severity: Severity;
|
|
13
|
+
}
|
|
14
|
+
export declare const PatternDefinitions: Record<PatternType, PatternInfo>;
|
|
15
|
+
export interface DetectedPattern extends PatternInfo {
|
|
16
|
+
type: PatternType;
|
|
17
|
+
}
|
package/out/pattern.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PatternDefinitions = exports.PatternType = void 0;
|
|
4
|
+
// Define an enum for pattern types.
|
|
5
|
+
var PatternType;
|
|
6
|
+
(function (PatternType) {
|
|
7
|
+
PatternType["RedundantCode"] = "REDUNDANT_CODE";
|
|
8
|
+
PatternType["OpaquePredicates"] = "OPAQUE_PREDICATES";
|
|
9
|
+
PatternType["ExpensiveOperationsInsideLoop"] = "EXPENSIVE_OPERATIONS_INSIDE_LOOP";
|
|
10
|
+
PatternType["LoopInvariantOperations"] = "LOOP_INVARIANT_OPERATIONS";
|
|
11
|
+
PatternType["LoopInvariantConditions"] = "LOOP_INVARIANT_CONDITIONS";
|
|
12
|
+
})(PatternType || (exports.PatternType = PatternType = {}));
|
|
13
|
+
// This constant maps each PatternType to its corresponding info.
|
|
14
|
+
exports.PatternDefinitions = {
|
|
15
|
+
[PatternType.RedundantCode]: {
|
|
16
|
+
name: "Redundant Code",
|
|
17
|
+
description: "Identifies unreachable code branches that can be eliminated to reduce bytecode size.",
|
|
18
|
+
severity: "low",
|
|
19
|
+
},
|
|
20
|
+
[PatternType.OpaquePredicates]: {
|
|
21
|
+
name: "Opaque Predicates",
|
|
22
|
+
description: "Detects conditions that always evaluate to the same value regardless of input.",
|
|
23
|
+
severity: "low",
|
|
24
|
+
},
|
|
25
|
+
[PatternType.ExpensiveOperationsInsideLoop]: {
|
|
26
|
+
name: "Expensive Operations Inside Loop",
|
|
27
|
+
description: "Flags high-cost operations (e.g., storage accesses) performed inside loops.",
|
|
28
|
+
severity: "high",
|
|
29
|
+
},
|
|
30
|
+
[PatternType.LoopInvariantOperations]: {
|
|
31
|
+
name: "Loop Invariant Operations",
|
|
32
|
+
description: "Identifies operations inside loops that yield the same result on every iteration.",
|
|
33
|
+
severity: "medium",
|
|
34
|
+
},
|
|
35
|
+
[PatternType.LoopInvariantConditions]: {
|
|
36
|
+
name: "Loop Invariant Conditions",
|
|
37
|
+
description: "Recognizes condition checks in loops that remain constant across iterations.",
|
|
38
|
+
severity: "medium",
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
//# sourceMappingURL=pattern.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pattern.js","sourceRoot":"","sources":["../src/pattern.ts"],"names":[],"mappings":";;;AAAA,oCAAoC;AACpC,IAAY,WAMX;AAND,WAAY,WAAW;IACrB,+CAAgC,CAAA;IAChC,qDAAsC,CAAA;IACtC,iFAAkE,CAAA;IAClE,oEAAqD,CAAA;IACrD,oEAAqD,CAAA;AACvD,CAAC,EANW,WAAW,2BAAX,WAAW,QAMtB;AAYD,iEAAiE;AACpD,QAAA,kBAAkB,GAAqC;IAClE,CAAC,WAAW,CAAC,aAAa,CAAC,EAAE;QAC3B,IAAI,EAAE,gBAAgB;QACtB,WAAW,EACT,sFAAsF;QACxF,QAAQ,EAAE,KAAK;KAChB;IACD,CAAC,WAAW,CAAC,gBAAgB,CAAC,EAAE;QAC9B,IAAI,EAAE,mBAAmB;QACzB,WAAW,EACT,gFAAgF;QAClF,QAAQ,EAAE,KAAK;KAChB;IACD,CAAC,WAAW,CAAC,6BAA6B,CAAC,EAAE;QAC3C,IAAI,EAAE,kCAAkC;QACxC,WAAW,EACT,6EAA6E;QAC/E,QAAQ,EAAE,MAAM;KACjB;IACD,CAAC,WAAW,CAAC,uBAAuB,CAAC,EAAE;QACrC,IAAI,EAAE,2BAA2B;QACjC,WAAW,EACT,mFAAmF;QACrF,QAAQ,EAAE,QAAQ;KACnB;IACD,CAAC,WAAW,CAAC,uBAAuB,CAAC,EAAE;QACrC,IAAI,EAAE,2BAA2B;QACjC,WAAW,EACT,8EAA8E;QAChF,QAAQ,EAAE,QAAQ;KACnB;CACF,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export interface PatternDiagnostic {
|
|
2
|
+
contract: string;
|
|
3
|
+
function: string;
|
|
4
|
+
pattern_name: string;
|
|
5
|
+
pattern_id: number;
|
|
6
|
+
block_id: number;
|
|
7
|
+
contract_start_line: number | null;
|
|
8
|
+
contract_end_line: number | null;
|
|
9
|
+
function_start_line: number | null;
|
|
10
|
+
function_end_line: number | null;
|
|
11
|
+
pattern_start_line: number | null;
|
|
12
|
+
pattern_end_line: number | null;
|
|
13
|
+
source: string | null;
|
|
14
|
+
message: string | null;
|
|
15
|
+
suggestion: string | null;
|
|
16
|
+
}
|
|
17
|
+
export declare class SiphonWS {
|
|
18
|
+
private ws;
|
|
19
|
+
private pending;
|
|
20
|
+
constructor(url: string);
|
|
21
|
+
private _onMessage;
|
|
22
|
+
private _rpc;
|
|
23
|
+
/** One-off pattern analysis */
|
|
24
|
+
analyze(code: string): Promise<PatternDiagnostic[]>;
|
|
25
|
+
/** One-off optimize from scratch (does its own analysis under the hood) */
|
|
26
|
+
optimize(code: string): Promise<{
|
|
27
|
+
patches: any[];
|
|
28
|
+
newCode: string;
|
|
29
|
+
}>;
|
|
30
|
+
/**
|
|
31
|
+
* Analyze once, store patterns server-side, then optimize re-using those patterns.
|
|
32
|
+
* Falls back to server's internal analyzeOptimize if nothing stored.
|
|
33
|
+
*/
|
|
34
|
+
analyzeThenOptimize(code: string): Promise<{
|
|
35
|
+
patches: any[];
|
|
36
|
+
newCode: string;
|
|
37
|
+
}>;
|
|
38
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SiphonWS = void 0;
|
|
4
|
+
class SiphonWS {
|
|
5
|
+
ws;
|
|
6
|
+
pending = new Map();
|
|
7
|
+
constructor(url) {
|
|
8
|
+
this.ws = new WebSocket(url);
|
|
9
|
+
this.ws.onmessage = evt => this._onMessage(evt.data);
|
|
10
|
+
}
|
|
11
|
+
_onMessage(raw) {
|
|
12
|
+
let msg;
|
|
13
|
+
try {
|
|
14
|
+
msg = JSON.parse(raw);
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
if (msg.id) {
|
|
20
|
+
const p = this.pending.get(msg.id);
|
|
21
|
+
if (!p)
|
|
22
|
+
return;
|
|
23
|
+
if (msg.error)
|
|
24
|
+
p.reject(msg.error);
|
|
25
|
+
else
|
|
26
|
+
p.resolve(msg.result);
|
|
27
|
+
this.pending.delete(msg.id);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
_rpc(method, params = {}) {
|
|
31
|
+
const id = Math.random().toString(36).slice(2, 10);
|
|
32
|
+
const payload = { id, method, params };
|
|
33
|
+
return new Promise((resolve, reject) => {
|
|
34
|
+
this.pending.set(id, { resolve, reject });
|
|
35
|
+
this.ws.send(JSON.stringify(payload));
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
/** One-off pattern analysis */
|
|
39
|
+
analyze(code) {
|
|
40
|
+
return this._rpc('analyze', { code })
|
|
41
|
+
.then(r => r.patterns);
|
|
42
|
+
}
|
|
43
|
+
/** One-off optimize from scratch (does its own analysis under the hood) */
|
|
44
|
+
optimize(code) {
|
|
45
|
+
return this._rpc('optimize', { code });
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Analyze once, store patterns server-side, then optimize re-using those patterns.
|
|
49
|
+
* Falls back to server's internal analyzeOptimize if nothing stored.
|
|
50
|
+
*/
|
|
51
|
+
analyzeThenOptimize(code) {
|
|
52
|
+
// first do analyze
|
|
53
|
+
return this._rpc('analyze', { code })
|
|
54
|
+
.then(r => {
|
|
55
|
+
// now optimize with stored patterns (server will detect msg_id and reuse)
|
|
56
|
+
return this._rpc('optimize', { code });
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
exports.SiphonWS = SiphonWS;
|
|
61
|
+
//# sourceMappingURL=siphon_client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"siphon_client.js","sourceRoot":"","sources":["../src/siphon_client.ts"],"names":[],"mappings":";;;AAqBA,MAAa,QAAQ;IACX,EAAE,CAAY;IACd,OAAO,GAAG,IAAI,GAAG,EAAmB,CAAC;IAE7C,YAAY,GAAW;QACrB,IAAI,CAAC,EAAE,GAAG,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC;QAC7B,IAAI,CAAC,EAAE,CAAC,SAAS,GAAG,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAc,CAAC,CAAC;IACjE,CAAC;IAEO,UAAU,CAAC,GAAW;QAC5B,IAAI,GAAqB,CAAC;QAC1B,IAAI,CAAC;YACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACxB,CAAC;QAAC,MAAM,CAAC;YAAC,OAAO;QAAC,CAAC;QACnB,IAAI,GAAG,CAAC,EAAE,EAAE,CAAC;YACX,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACnC,IAAI,CAAC,CAAC;gBAAE,OAAO;YACf,IAAI,GAAG,CAAC,KAAK;gBAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;;gBAC9B,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAC3B,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;IAEO,IAAI,CAAI,MAAc,EAAE,SAAc,EAAE;QAC9C,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACnD,MAAM,OAAO,GAAG,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QACvC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;YAC1C,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;IACL,CAAC;IAED,+BAA+B;IAC/B,OAAO,CAAC,IAAY;QAClB,OAAO,IAAI,CAAC,IAAI,CAAoC,SAAS,EAAE,EAAE,IAAI,EAAE,CAAC;aACrE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IAC3B,CAAC;IAED,2EAA2E;IAC3E,QAAQ,CAAC,IAAY;QACnB,OAAO,IAAI,CAAC,IAAI,CAAsC,UAAU,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9E,CAAC;IAED;;;OAGG;IACH,mBAAmB,CAAC,IAAY;QAC9B,mBAAmB;QACnB,OAAO,IAAI,CAAC,IAAI,CAAoC,SAAS,EAAE,EAAE,IAAI,EAAE,CAAC;aACrE,IAAI,CAAC,CAAC,CAAC,EAAE;YACR,0EAA0E;YAC1E,OAAO,IAAI,CAAC,IAAI,CAAsC,UAAU,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9E,CAAC,CAAC,CAAC;IACP,CAAC;CACF;AAvDD,4BAuDC"}
|
package/out/test.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/out/test.js
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
// test.ts
|
|
4
|
+
const siphon_client_1 = require("./siphon_client");
|
|
5
|
+
async function runTests() {
|
|
6
|
+
const client = new siphon_client_1.SiphonWS('ws://localhost:8000/ws');
|
|
7
|
+
await new Promise(res => setTimeout(res, 100)); // give WS a moment
|
|
8
|
+
console.log('✅ Connected to Siphon WS');
|
|
9
|
+
const codeSample = `
|
|
10
|
+
// SPDX-License-Identifier: GPL-3.0
|
|
11
|
+
|
|
12
|
+
pragma solidity >=0.8.0;
|
|
13
|
+
|
|
14
|
+
contract EvaluationPattern1 {
|
|
15
|
+
uint256 minThreshold;
|
|
16
|
+
uint256 maxThreshold;
|
|
17
|
+
uint256 scalingFactor;
|
|
18
|
+
uint256 offset;
|
|
19
|
+
bool public Error;
|
|
20
|
+
|
|
21
|
+
function pattern1(uint256 x) public {
|
|
22
|
+
minThreshold = 5;
|
|
23
|
+
maxThreshold = 10;
|
|
24
|
+
scalingFactor = maxThreshold / minThreshold;
|
|
25
|
+
offset = 2;
|
|
26
|
+
|
|
27
|
+
uint256 y;
|
|
28
|
+
uint256 z;
|
|
29
|
+
if (minThreshold < x && x < maxThreshold) {
|
|
30
|
+
y = x * scalingFactor;
|
|
31
|
+
|
|
32
|
+
if (y < maxThreshold) {
|
|
33
|
+
Error = true;
|
|
34
|
+
}
|
|
35
|
+
} else {
|
|
36
|
+
y = 2 * maxThreshold;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
z = y - offset;
|
|
40
|
+
|
|
41
|
+
if (z < maxThreshold) {
|
|
42
|
+
Error = true;
|
|
43
|
+
} else {
|
|
44
|
+
Error = false;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
contract EvaluationPattern2 {
|
|
50
|
+
uint256 amount = 15;
|
|
51
|
+
uint256 interest = 2;
|
|
52
|
+
uint256 balance;
|
|
53
|
+
bool public Error;
|
|
54
|
+
|
|
55
|
+
function pattern2() public {
|
|
56
|
+
amount = 15;
|
|
57
|
+
interest = 2;
|
|
58
|
+
|
|
59
|
+
uint256 tentativeBalance = balance;
|
|
60
|
+
if (tentativeBalance > amount * interest) {
|
|
61
|
+
tentativeBalance -= amount * interest;
|
|
62
|
+
|
|
63
|
+
if (tentativeBalance > 0) {
|
|
64
|
+
Error = false;
|
|
65
|
+
} else {
|
|
66
|
+
Error = true;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
balance = tentativeBalance;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
contract EvaluationPattern4 {
|
|
75
|
+
uint256 numberOfTransactions;
|
|
76
|
+
address[] userList;
|
|
77
|
+
mapping(address => uint256) usersBalance;
|
|
78
|
+
address smallestBalanceIndex;
|
|
79
|
+
|
|
80
|
+
function pattern4(uint256 transactionAmount) public {
|
|
81
|
+
for(uint256 i = 0; i < userList.length; i++) {
|
|
82
|
+
numberOfTransactions++;
|
|
83
|
+
address userAddress = userList[i];
|
|
84
|
+
|
|
85
|
+
usersBalance[userAddress] += transactionAmount;
|
|
86
|
+
|
|
87
|
+
if (usersBalance[userAddress] < usersBalance[smallestBalanceIndex]) {
|
|
88
|
+
smallestBalanceIndex = userAddress;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
for(uint256 i = 0; i < userList.length; i++) {
|
|
95
|
+
usersBalance[smallestBalanceIndex] += transactionAmount * 2;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
contract EvaluationPattern5 {
|
|
101
|
+
address[] userList;
|
|
102
|
+
mapping(address => uint256) usersBalance;
|
|
103
|
+
|
|
104
|
+
function validAddress(address userAddress) public pure returns (bool) {
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function interest(uint256 amount) public pure returns (uint256) {
|
|
109
|
+
return amount * 2;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function pattern5(uint256 amount) public {
|
|
113
|
+
for(uint256 i = 0; i < userList.length; i++) {
|
|
114
|
+
address userAddress = userList[i];
|
|
115
|
+
if (validAddress(userAddress)) {
|
|
116
|
+
usersBalance[userAddress] += interest(amount);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
contract EvaluationPattern6 {
|
|
123
|
+
address[] userList;
|
|
124
|
+
mapping(address => uint256) usersBalance;
|
|
125
|
+
|
|
126
|
+
function adjustedMinThreshold(uint256 amount) public pure returns (uint256) {
|
|
127
|
+
return (amount) / (amount + 100);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function pattern6(uint256 amount) public {
|
|
131
|
+
for(uint256 i = 0; i < userList.length; i++) {
|
|
132
|
+
address userAddress = userList[i];
|
|
133
|
+
uint256 value;
|
|
134
|
+
if (amount < adjustedMinThreshold(amount)) {
|
|
135
|
+
value = amount;
|
|
136
|
+
} else {
|
|
137
|
+
value = 100;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
usersBalance[userAddress] += value;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
`;
|
|
145
|
+
// 1) analyze
|
|
146
|
+
const patterns = await client.analyze(codeSample);
|
|
147
|
+
console.log('📝 analyze result:', patterns);
|
|
148
|
+
if (patterns.length === 0) {
|
|
149
|
+
throw new Error('Expected at least one pattern diagnostic');
|
|
150
|
+
}
|
|
151
|
+
// 2) optimize from scratch
|
|
152
|
+
const { patches, newCode } = await client.optimize(codeSample);
|
|
153
|
+
console.log('🛠 optimize result:', { patches, newCode });
|
|
154
|
+
if (typeof newCode !== 'string') {
|
|
155
|
+
throw new Error('Expected optimized code string');
|
|
156
|
+
}
|
|
157
|
+
// 3) analyzeThenOptimize
|
|
158
|
+
const result2 = await client.analyzeThenOptimize(codeSample);
|
|
159
|
+
console.log('🔄 analyzeThenOptimize result:', result2);
|
|
160
|
+
console.log('✅ All tests passed');
|
|
161
|
+
}
|
|
162
|
+
runTests().catch(err => {
|
|
163
|
+
console.error('❌ Test suite failed:', err);
|
|
164
|
+
process.exit(1);
|
|
165
|
+
});
|
|
166
|
+
//# sourceMappingURL=test.js.map
|
package/out/test.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test.js","sourceRoot":"","sources":["../src/test.ts"],"names":[],"mappings":";;AAAA,UAAU;AACV,mDAA8D;AAE9D,KAAK,UAAU,QAAQ;IACrB,MAAM,MAAM,GAAG,IAAI,wBAAQ,CAAC,wBAAwB,CAAC,CAAC;IACtD,MAAM,IAAI,OAAO,CAAO,GAAG,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAE,mBAAmB;IAC1E,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;IAE1C,MAAM,UAAU,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuIlB,CAAC;IAEA,aAAa;IACb,MAAM,QAAQ,GAAwB,MAAM,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACvE,OAAO,CAAC,GAAG,CAAC,oBAAoB,EAAE,QAAQ,CAAC,CAAC;IAC5C,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAC9D,CAAC;IAED,2BAA2B;IAC3B,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;IAC/D,OAAO,CAAC,GAAG,CAAC,qBAAqB,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;IACzD,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACpD,CAAC;IAED,yBAAyB;IACzB,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,mBAAmB,CAAC,UAAU,CAAC,CAAC;IAC7D,OAAO,CAAC,GAAG,CAAC,gCAAgC,EAAE,OAAO,CAAC,CAAC;IAEvD,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;AACpC,CAAC;AAED,QAAQ,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,sBAAsB,EAAE,GAAG,CAAC,CAAC;IAC3C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|