- Expand token-aggregation API (report routes), canonical tokens, pools - Add flash vault contracts + tests (indexed, DODO cwUSDC, XAUT borrow) - PMM pools JSON, deploy/export scripts, metamask verified list Co-authored-by: Cursor <cursoragent@cursor.com>
164 lines
5.2 KiB
TypeScript
164 lines
5.2 KiB
TypeScript
import fs from 'fs';
|
|
import path from 'path';
|
|
|
|
type DiscoveryPayload = {
|
|
generated_at?: string;
|
|
entries?: Array<{
|
|
chain_id: number;
|
|
network?: string;
|
|
factoryAddress?: string;
|
|
routerAddress?: string;
|
|
pairsChecked?: Array<{
|
|
base: string;
|
|
quote: string;
|
|
poolAddress: string;
|
|
live: boolean;
|
|
health?: {
|
|
baseReserveRaw?: string;
|
|
quoteReserveRaw?: string;
|
|
baseReserveUnits?: string;
|
|
quoteReserveUnits?: string;
|
|
priceQuotePerBase?: string;
|
|
deviationBps?: string;
|
|
healthy?: boolean;
|
|
depthOk?: boolean;
|
|
parityOk?: boolean;
|
|
};
|
|
}>;
|
|
}>;
|
|
};
|
|
|
|
type DeploymentStatusChain = {
|
|
name?: string;
|
|
cwTokens?: Record<string, string>;
|
|
anchorAddresses?: Record<string, string>;
|
|
gasMirrors?: Record<string, string>;
|
|
gasQuoteAddresses?: Record<string, string>;
|
|
};
|
|
|
|
type DeploymentStatus = {
|
|
chains?: Record<string, DeploymentStatusChain>;
|
|
};
|
|
|
|
const PRICE_USD: Record<string, number> = {
|
|
USDC: 1,
|
|
USDT: 1,
|
|
cUSDC: 1,
|
|
cUSDT: 1,
|
|
cWUSDC: 1,
|
|
cWUSDT: 1,
|
|
cWAUSDT: 1,
|
|
};
|
|
|
|
function findRepoRoot(): string {
|
|
const candidates = [
|
|
process.env.PROXMOX_REPO_ROOT,
|
|
process.env.PROJECT_ROOT,
|
|
path.resolve(process.cwd(), '..', '..', '..'),
|
|
path.resolve(process.cwd(), '..'),
|
|
process.cwd(),
|
|
].filter(Boolean) as string[];
|
|
|
|
for (const candidate of candidates) {
|
|
if (fs.existsSync(path.join(candidate, 'reports/extraction/promod-uniswap-v2-live-pair-discovery-latest.json'))) {
|
|
return candidate;
|
|
}
|
|
}
|
|
return path.resolve(process.cwd(), '..', '..', '..');
|
|
}
|
|
|
|
function readJson<T>(filePath: string): T {
|
|
return JSON.parse(fs.readFileSync(filePath, 'utf8')) as T;
|
|
}
|
|
|
|
function resolveTokenAddress(chain: DeploymentStatusChain, symbol: string): string | undefined {
|
|
return (
|
|
chain.cwTokens?.[symbol] ||
|
|
chain.anchorAddresses?.[symbol] ||
|
|
chain.gasMirrors?.[symbol] ||
|
|
chain.gasQuoteAddresses?.[symbol]
|
|
);
|
|
}
|
|
|
|
function parsePositiveNumber(value?: string): number {
|
|
const parsed = Number(value);
|
|
return Number.isFinite(parsed) && parsed > 0 ? parsed : 0;
|
|
}
|
|
|
|
function main(): void {
|
|
const repoRoot = findRepoRoot();
|
|
const discoveryPath = path.join(repoRoot, 'reports/extraction/promod-uniswap-v2-live-pair-discovery-latest.json');
|
|
const deploymentStatusPath = path.join(repoRoot, 'cross-chain-pmm-lps/config/deployment-status.json');
|
|
const outPath = path.join(process.cwd(), 'config/live-uniswap-v2-pool-catalog.json');
|
|
|
|
const discovery = readJson<DiscoveryPayload>(discoveryPath);
|
|
const deploymentStatus = readJson<DeploymentStatus>(deploymentStatusPath);
|
|
const pools = [];
|
|
|
|
for (const entry of discovery.entries ?? []) {
|
|
const chainId = Number(entry.chain_id);
|
|
const chain = deploymentStatus.chains?.[String(chainId)];
|
|
if (!chain) continue;
|
|
|
|
for (const pair of entry.pairsChecked ?? []) {
|
|
if (!pair.live || !pair.poolAddress?.startsWith('0x') || !pair.health) continue;
|
|
const baseAddress = resolveTokenAddress(chain, pair.base);
|
|
const quoteAddress = resolveTokenAddress(chain, pair.quote);
|
|
if (!baseAddress || !quoteAddress) continue;
|
|
|
|
const baseReserveUnits = parsePositiveNumber(pair.health.baseReserveUnits);
|
|
const quoteReserveUnits = parsePositiveNumber(pair.health.quoteReserveUnits);
|
|
const basePriceUsd = PRICE_USD[pair.base] ?? 0;
|
|
const quotePriceUsd = PRICE_USD[pair.quote] ?? 0;
|
|
const reserve0Usd = baseReserveUnits * basePriceUsd;
|
|
const reserve1Usd = quoteReserveUnits * quotePriceUsd;
|
|
const totalLiquidityUsd = reserve0Usd + reserve1Usd;
|
|
if (totalLiquidityUsd <= 0) continue;
|
|
|
|
pools.push({
|
|
chainId,
|
|
chainName: entry.network ?? chain.name ?? `Chain ${chainId}`,
|
|
poolAddress: pair.poolAddress.toLowerCase(),
|
|
dex: 'uniswap_v2',
|
|
factoryAddress: entry.factoryAddress,
|
|
routerAddress: entry.routerAddress,
|
|
baseSymbol: pair.base,
|
|
quoteSymbol: pair.quote,
|
|
baseAddress: baseAddress.toLowerCase(),
|
|
quoteAddress: quoteAddress.toLowerCase(),
|
|
baseReserveRaw: pair.health.baseReserveRaw,
|
|
quoteReserveRaw: pair.health.quoteReserveRaw,
|
|
baseReserveUnits: pair.health.baseReserveUnits,
|
|
quoteReserveUnits: pair.health.quoteReserveUnits,
|
|
priceQuotePerBase: pair.health.priceQuotePerBase,
|
|
deviationBps: pair.health.deviationBps,
|
|
depthOk: pair.health.depthOk,
|
|
parityOk: pair.health.parityOk,
|
|
healthy: pair.health.healthy,
|
|
reserve0Usd,
|
|
reserve1Usd,
|
|
totalLiquidityUsd,
|
|
});
|
|
}
|
|
}
|
|
|
|
pools.sort((a, b) => a.chainId - b.chainId || a.poolAddress.localeCompare(b.poolAddress));
|
|
const payload = {
|
|
schema: 'token-aggregation-live-uniswap-v2-pool-catalog/v1',
|
|
generatedAt: new Date().toISOString(),
|
|
sourceArtifacts: [
|
|
'reports/extraction/promod-uniswap-v2-live-pair-discovery-latest.json',
|
|
'cross-chain-pmm-lps/config/deployment-status.json',
|
|
],
|
|
poolCount: pools.length,
|
|
positiveLiquidityPoolCount: pools.filter((pool) => pool.totalLiquidityUsd > 0).length,
|
|
pools,
|
|
};
|
|
|
|
fs.mkdirSync(path.dirname(outPath), { recursive: true });
|
|
fs.writeFileSync(outPath, `${JSON.stringify(payload, null, 2)}\n`);
|
|
console.log(outPath);
|
|
}
|
|
|
|
main();
|