Files
smom-dbis-138/services/token-aggregation/scripts/verify-dodo-v3-planner-visibility.ts
defiQUG 76aa419320 feat: bridges, PMM, flash workflow, token-aggregation, and deployment docs
- CCIP/trustless bridge contracts, GRU tokens, DEX/PMM tests, reserve vault.
- Token-aggregation service routes, planner, chain config, relay env templates.
- Config snapshots and multi-chain deployment markdown updates.
- gitignore services/btc-intake/dist/ (tsc output); do not track dist.

Run forge build && forge test before deploy (large solc graph).

Made-with: Cursor
2026-04-07 23:40:52 -07:00

143 lines
5.9 KiB
TypeScript

import fs from 'fs';
import path from 'path';
import { getProviderCapabilities } from '../src/config/provider-capabilities';
import { InternalExecutionPlanV2Builder } from '../src/services/internal-execution-plan-v2';
import { BestExecutionPlanner } from '../src/services/best-execution-planner';
const CHAIN_ID = 138;
const WETH10 = '0xf4BB2e28688e89fCcE3c0580D37d36A7672E8A9f';
const USDT = '0x004b63A7B5b0E06f6bB6adb4a5F9f590BF3182D1';
const D3_PROXY = '0xc9a11abB7C63d88546Be24D58a6d95e3762cB843';
const D3_POOL = '0x6550A3a59070061a262a893A1D6F3F490afFDBDA';
const ROUTER_V2 = '0xF1c93F54A5C2fc0d7766Ccb0Ad8f157DFB4C99Ce';
const AMOUNT_IN = '100000000000000000';
class MockPlannerMetricsRepository {
async getCachedPlan(): Promise<null> {
return null;
}
async recordProviderSnapshots(): Promise<void> {}
async cachePlan(): Promise<void> {}
async recordPlannedRouteMetrics(): Promise<void> {}
}
function assert(condition: unknown, message: string): asserts condition {
if (!condition) {
throw new Error(message);
}
}
function loadMatrix(): Record<string, unknown> {
const root = path.resolve(__dirname, '../../../../');
const matrixPath = path.resolve(root, 'config/aggregator-route-matrix.json');
const raw = fs.readFileSync(matrixPath, 'utf8');
return JSON.parse(raw) as Record<string, unknown>;
}
async function main(): Promise<void> {
const capabilities = getProviderCapabilities(CHAIN_ID);
const dodoV3 = capabilities.find((capability) => capability.provider === 'dodo_v3');
assert(dodoV3, 'Missing dodo_v3 provider capability for Chain 138.');
assert(dodoV3.live === true, 'Expected dodo_v3 capability to be live.');
assert(dodoV3.quoteLive === true, 'Expected dodo_v3 quoteLive=true.');
assert(dodoV3.executionLive === true, 'Expected dodo_v3 executionLive=true with the live router-v2 D3 adapter.');
const pair = dodoV3.pairs.find(
(entry) =>
entry.status === 'live' &&
entry.tokenInAddress === WETH10.toLowerCase() &&
entry.tokenOutAddress === USDT.toLowerCase()
);
assert(pair, 'Missing live WETH10 -> USDT dodo_v3 capability.');
assert(pair.target === D3_PROXY.toLowerCase(), `Expected D3 proxy target ${D3_PROXY}, got ${pair.target}.`);
const planner = new BestExecutionPlanner(undefined, new MockPlannerMetricsRepository() as never);
const request = {
sourceChainId: CHAIN_ID,
destinationChainId: CHAIN_ID,
tokenIn: WETH10,
tokenOut: USDT,
amountIn: AMOUNT_IN,
};
const plan = await planner.plan(request);
assert(plan.decision === 'direct-pool', `Expected direct-pool decision, got ${plan.decision}.`);
assert(plan.legs.length === 1, `Expected 1 planner leg, got ${plan.legs.length}.`);
assert(plan.legs[0].provider === 'dodo_v3', `Expected dodo_v3 provider, got ${plan.legs[0].provider}.`);
assert(plan.routePlan !== undefined, 'Expected executable routePlan for dodo_v3 pilot routes.');
assert(
plan.riskFlags.includes('pilot-venue') && !plan.riskFlags.includes('manual-execution-only'),
`Expected pilot-only risk flag set, got ${plan.riskFlags.join(', ')}.`
);
assert(BigInt(plan.estimatedAmountOut) > 0n, 'Expected positive DODO v3 quote output.');
const executionBuilder = new InternalExecutionPlanV2Builder(planner);
const internalExecution = await executionBuilder.build(request);
assert(!internalExecution.error, `Expected executable internal plan, got ${internalExecution.error || 'none'}.`);
assert(internalExecution.execution?.kind === 'route', `Expected route execution plan, got ${internalExecution.execution?.kind || 'none'}.`);
assert(
internalExecution.execution?.contractAddress === ROUTER_V2.toLowerCase(),
`Expected router-v2 contract ${ROUTER_V2}, got ${internalExecution.execution?.contractAddress || 'none'}.`
);
assert(
internalExecution.execution?.encodedCalldata?.startsWith('0x434180a2'),
'Expected executeRoute calldata for dodo_v3 pilot route.'
);
const matrix = loadMatrix();
const liveSwapRoutes = Array.isArray(matrix.liveSwapRoutes) ? matrix.liveSwapRoutes : [];
const dodoV3Routes = liveSwapRoutes.filter((route) => {
if (!route || typeof route !== 'object') return false;
const legs = Array.isArray((route as { legs?: unknown[] }).legs) ? (route as { legs: unknown[] }).legs : [];
return legs.some((leg) => leg && typeof leg === 'object' && (leg as { protocol?: string }).protocol === 'dodo_v3');
}) as Array<Record<string, unknown>>;
assert(dodoV3Routes.length === 2, `Expected 2 dodo_v3 routes in route matrix, got ${dodoV3Routes.length}.`);
for (const route of dodoV3Routes) {
const legs = Array.isArray(route.legs) ? route.legs : [];
const leg = legs[0] as Record<string, unknown>;
assert(leg.poolAddress === D3_POOL.toLowerCase(), `Expected canonical D3 pool ${D3_POOL}, got ${String(leg.poolAddress || '')}.`);
assert(leg.executorAddress === D3_PROXY.toLowerCase(), `Expected canonical D3 proxy ${D3_PROXY}, got ${String(leg.executorAddress || '')}.`);
}
console.log(
JSON.stringify(
{
verifiedAt: new Date().toISOString(),
chainId: CHAIN_ID,
capability: {
provider: dodoV3.provider,
live: dodoV3.live,
quoteLive: dodoV3.quoteLive,
executionLive: dodoV3.executionLive,
},
planner: {
decision: plan.decision,
provider: plan.legs[0].provider,
estimatedAmountOut: plan.estimatedAmountOut,
riskFlags: plan.riskFlags,
routePlanPresent: plan.routePlan !== undefined,
},
internalExecutionPlan: {
kind: internalExecution.execution?.kind,
contractAddress: internalExecution.execution?.contractAddress,
error: internalExecution.error,
},
routeMatrix: {
dodoV3RouteIds: dodoV3Routes.map((route) => String(route.routeId || '')),
},
},
null,
2
)
);
}
main().catch((error) => {
console.error(`[fail] ${error instanceof Error ? error.message : String(error)}`);
process.exit(1);
});