import { describe, it, expect } from "vitest"; import { StrategyCompiler } from "../../src/planner/compiler.js"; import { executeStrategy } from "../../src/engine.js"; import { loadStrategy, substituteBlinds } from "../../src/strategy.js"; import { readFileSync } from "fs"; import { join } from "path"; describe("Full Strategy Execution", () => { it("should compile and execute recursive leverage strategy", async () => { const strategyPath = join( process.cwd(), "strategies", "sample.recursive.json" ); if (!require("fs").existsSync(strategyPath)) { // Skip if strategy file doesn't exist return; } const strategy = loadStrategy(strategyPath); // Substitute blind values for testing const blindValues = { collateralAmount: "1000000", // 1 USDC (6 decimals) leverageFactor: "500000", // 0.5 USDC }; const resolvedStrategy = substituteBlinds(strategy, blindValues); const compiler = new StrategyCompiler(resolvedStrategy.chain); const plan = await compiler.compile(resolvedStrategy); expect(plan.calls.length).toBeGreaterThan(0); }); it("should compile liquidation helper strategy", async () => { const strategyPath = join( process.cwd(), "strategies", "sample.liquidation.json" ); if (!require("fs").existsSync(strategyPath)) { return; } const strategy = loadStrategy(strategyPath); const compiler = new StrategyCompiler(strategy.chain); const plan = await compiler.compile(strategy); expect(plan.requiresFlashLoan).toBe(true); }); it("should compile stablecoin hedge strategy", async () => { const strategyPath = join( process.cwd(), "strategies", "sample.stablecoin-hedge.json" ); if (!require("fs").existsSync(strategyPath)) { return; } const strategy = loadStrategy(strategyPath); const compiler = new StrategyCompiler(strategy.chain); const plan = await compiler.compile(strategy); expect(plan.calls.length).toBeGreaterThan(0); }); it("should compile multi-protocol strategy", async () => { const strategy = { name: "Multi-Protocol", chain: "mainnet", steps: [ { id: "supply", action: { type: "aaveV3.supply", asset: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", amount: "1000000", }, }, { id: "swap", action: { type: "uniswapV3.swap", tokenIn: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", tokenOut: "0xdAC17F958D2ee523a2206206994597C13D831ec7", fee: 3000, amountIn: "500000", exactInput: true, }, }, ], }; const compiler = new StrategyCompiler("mainnet"); const plan = await compiler.compile(strategy as any); expect(plan.calls.length).toBe(2); }); it("should compile strategy with all guard types", async () => { const strategy = { name: "All Guards", chain: "mainnet", guards: [ { type: "maxGas", params: { maxGasLimit: "5000000" }, }, { type: "slippage", params: { maxBps: 50 }, }, ], steps: [ { id: "step1", guards: [ { type: "oracleSanity", params: { token: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", maxDeviationBps: 500, }, }, ], action: { type: "aaveV3.supply", asset: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", amount: "1000000", }, }, ], }; const compiler = new StrategyCompiler("mainnet"); const plan = await compiler.compile(strategy as any); expect(plan.calls.length).toBeGreaterThan(0); }); });