Initial commit: add .gitignore and README
This commit is contained in:
222
tests/unit/planner/compiler.test.ts
Normal file
222
tests/unit/planner/compiler.test.ts
Normal file
@@ -0,0 +1,222 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import { StrategyCompiler } from "../../../src/planner/compiler.js";
|
||||
import { Strategy } from "../../../src/strategy.schema.js";
|
||||
|
||||
describe("Strategy Compiler", () => {
|
||||
const executorAddr = "0x1234567890123456789012345678901234567890";
|
||||
|
||||
it("should compile aaveV3.supply", async () => {
|
||||
const compiler = new StrategyCompiler("mainnet");
|
||||
const strategy: Strategy = {
|
||||
name: "Test",
|
||||
chain: "mainnet",
|
||||
steps: [{
|
||||
id: "supply",
|
||||
action: {
|
||||
type: "aaveV3.supply",
|
||||
asset: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
||||
amount: "1000000",
|
||||
},
|
||||
}],
|
||||
};
|
||||
|
||||
const plan = await compiler.compile(strategy, executorAddr);
|
||||
expect(plan.calls.length).toBe(1);
|
||||
expect(plan.calls[0].description).toContain("Aave v3 supply");
|
||||
});
|
||||
|
||||
it("should compile aaveV3.setUserEMode", async () => {
|
||||
const compiler = new StrategyCompiler("mainnet");
|
||||
const strategy: Strategy = {
|
||||
name: "Test",
|
||||
chain: "mainnet",
|
||||
steps: [{
|
||||
id: "setEMode",
|
||||
action: {
|
||||
type: "aaveV3.setUserEMode",
|
||||
categoryId: 1,
|
||||
},
|
||||
}],
|
||||
};
|
||||
|
||||
const plan = await compiler.compile(strategy, executorAddr);
|
||||
expect(plan.calls.length).toBe(1);
|
||||
});
|
||||
|
||||
it("should compile maker.openVault", async () => {
|
||||
const compiler = new StrategyCompiler("mainnet");
|
||||
const strategy: Strategy = {
|
||||
name: "Test",
|
||||
chain: "mainnet",
|
||||
steps: [{
|
||||
id: "openVault",
|
||||
action: {
|
||||
type: "maker.openVault",
|
||||
ilk: "ETH-A",
|
||||
},
|
||||
}],
|
||||
};
|
||||
|
||||
const plan = await compiler.compile(strategy, executorAddr);
|
||||
expect(plan.calls.length).toBe(1);
|
||||
});
|
||||
|
||||
it("should compile balancer.batchSwap", async () => {
|
||||
const compiler = new StrategyCompiler("mainnet");
|
||||
const strategy: Strategy = {
|
||||
name: "Test",
|
||||
chain: "mainnet",
|
||||
steps: [{
|
||||
id: "batchSwap",
|
||||
action: {
|
||||
type: "balancer.batchSwap",
|
||||
kind: "givenIn",
|
||||
swaps: [{
|
||||
poolId: "0x...",
|
||||
assetInIndex: 0,
|
||||
assetOutIndex: 1,
|
||||
amount: "1000000",
|
||||
}],
|
||||
assets: [
|
||||
"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
||||
"0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
||||
],
|
||||
},
|
||||
}],
|
||||
};
|
||||
|
||||
const plan = await compiler.compile(strategy, executorAddr);
|
||||
expect(plan.calls.length).toBe(1);
|
||||
});
|
||||
|
||||
it("should compile curve.exchange_underlying", async () => {
|
||||
const compiler = new StrategyCompiler("mainnet");
|
||||
const strategy: Strategy = {
|
||||
name: "Test",
|
||||
chain: "mainnet",
|
||||
steps: [{
|
||||
id: "exchange",
|
||||
action: {
|
||||
type: "curve.exchange_underlying",
|
||||
pool: "0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7",
|
||||
i: 0,
|
||||
j: 1,
|
||||
dx: "1000000",
|
||||
},
|
||||
}],
|
||||
};
|
||||
|
||||
const plan = await compiler.compile(strategy, executorAddr);
|
||||
expect(plan.calls.length).toBe(1);
|
||||
});
|
||||
|
||||
it("should compile aggregators.swap1Inch", async () => {
|
||||
const compiler = new StrategyCompiler("mainnet");
|
||||
const strategy: Strategy = {
|
||||
name: "Test",
|
||||
chain: "mainnet",
|
||||
steps: [{
|
||||
id: "swap",
|
||||
action: {
|
||||
type: "aggregators.swap1Inch",
|
||||
tokenIn: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
||||
tokenOut: "0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
||||
amountIn: "1000000",
|
||||
},
|
||||
}],
|
||||
};
|
||||
|
||||
// Mock 1inch API
|
||||
global.fetch = vi.fn().mockResolvedValue({
|
||||
ok: true,
|
||||
json: async () => ({
|
||||
toAmount: "1000000",
|
||||
tx: { data: "0x1234" },
|
||||
}),
|
||||
});
|
||||
|
||||
const plan = await compiler.compile(strategy, executorAddr);
|
||||
expect(plan.calls.length).toBe(1);
|
||||
});
|
||||
|
||||
it("should compile perps.increasePosition", async () => {
|
||||
const compiler = new StrategyCompiler("mainnet");
|
||||
const strategy: Strategy = {
|
||||
name: "Test",
|
||||
chain: "mainnet",
|
||||
steps: [{
|
||||
id: "increase",
|
||||
action: {
|
||||
type: "perps.increasePosition",
|
||||
path: ["0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"],
|
||||
indexToken: "0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
||||
amountIn: "1000000",
|
||||
sizeDelta: "2000000",
|
||||
isLong: true,
|
||||
},
|
||||
}],
|
||||
};
|
||||
|
||||
const plan = await compiler.compile(strategy, executorAddr);
|
||||
expect(plan.calls.length).toBe(1);
|
||||
});
|
||||
|
||||
it("should wrap flash loan with subsequent operations", async () => {
|
||||
const compiler = new StrategyCompiler("mainnet");
|
||||
const strategy: Strategy = {
|
||||
name: "Flash Loan",
|
||||
chain: "mainnet",
|
||||
steps: [
|
||||
{
|
||||
id: "flashLoan",
|
||||
action: {
|
||||
type: "aaveV3.flashLoan",
|
||||
assets: ["0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"],
|
||||
amounts: ["1000000"],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "swap",
|
||||
action: {
|
||||
type: "uniswapV3.swap",
|
||||
tokenIn: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
||||
tokenOut: "0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
||||
fee: 3000,
|
||||
amountIn: "1000000",
|
||||
exactInput: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const plan = await compiler.compile(strategy, executorAddr);
|
||||
expect(plan.requiresFlashLoan).toBe(true);
|
||||
expect(plan.flashLoanAsset).toBe("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48");
|
||||
// Should have executeFlashLoan call
|
||||
expect(plan.calls.some(c => c.description.includes("flash loan"))).toBe(true);
|
||||
});
|
||||
|
||||
it("should substitute executor address in swaps", async () => {
|
||||
const compiler = new StrategyCompiler("mainnet");
|
||||
const strategy: Strategy = {
|
||||
name: "Test",
|
||||
chain: "mainnet",
|
||||
steps: [{
|
||||
id: "swap",
|
||||
action: {
|
||||
type: "uniswapV3.swap",
|
||||
tokenIn: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
||||
tokenOut: "0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
||||
fee: 3000,
|
||||
amountIn: "1000000",
|
||||
exactInput: true,
|
||||
},
|
||||
}],
|
||||
};
|
||||
|
||||
const plan = await compiler.compile(strategy, executorAddr);
|
||||
// Recipient should be executor address, not zero
|
||||
expect(plan.calls.length).toBe(1);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user