Add mainnet cWBTC token-aggregation indexing, supply proof, and Etherscan verify scripts.
Some checks failed
CI/CD Pipeline / Solidity Contracts (push) Failing after 1m25s
CI/CD Pipeline / Security Scanning (push) Successful in 3m28s
CI/CD Pipeline / Lint and Format (push) Failing after 43s
CI/CD Pipeline / Terraform Validation (push) Failing after 25s
CI/CD Pipeline / Kubernetes Validation (push) Successful in 28s
Deploy ChainID 138 / Deploy ChainID 138 (push) Failing after 45s
HYBX OMNL TypeScript & anchor / token-aggregation build + reconcile artifact (push) Failing after 29s
Validation / validate-genesis (push) Successful in 32s
Validation / validate-terraform (push) Failing after 30s
Validation / validate-kubernetes (push) Failing after 10s
Validation / validate-smart-contracts (push) Failing after 10s
Validation / validate-security (push) Failing after 1m36s
Validation / validate-documentation (push) Failing after 17s
Verify Deployment / Verify Deployment (push) Failing after 48s
Some checks failed
CI/CD Pipeline / Solidity Contracts (push) Failing after 1m25s
CI/CD Pipeline / Security Scanning (push) Successful in 3m28s
CI/CD Pipeline / Lint and Format (push) Failing after 43s
CI/CD Pipeline / Terraform Validation (push) Failing after 25s
CI/CD Pipeline / Kubernetes Validation (push) Successful in 28s
Deploy ChainID 138 / Deploy ChainID 138 (push) Failing after 45s
HYBX OMNL TypeScript & anchor / token-aggregation build + reconcile artifact (push) Failing after 29s
Validation / validate-genesis (push) Successful in 32s
Validation / validate-terraform (push) Failing after 30s
Validation / validate-kubernetes (push) Failing after 10s
Validation / validate-smart-contracts (push) Failing after 10s
Validation / validate-security (push) Failing after 1m36s
Validation / validate-documentation (push) Failing after 17s
Verify Deployment / Verify Deployment (push) Failing after 48s
Wire live 0x2BBe3c… address into canonical tokens, pool catalog merge from mesh health, and bridge/cWBTC explorer verification helpers. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -48,6 +48,8 @@ const PRICE_USD: Record<string, number> = {
|
||||
cWUSDC: 1,
|
||||
cWUSDT: 1,
|
||||
cWAUSDT: 1,
|
||||
BTC: Number(process.env.CANONICAL_PRICE_USD_BTC || process.env.BTC_PRICE_USD || 90000),
|
||||
cWBTC: Number(process.env.CANONICAL_PRICE_USD_BTC || process.env.BTC_PRICE_USD || 90000),
|
||||
};
|
||||
|
||||
function findRepoRoot(): string {
|
||||
@@ -85,73 +87,166 @@ function parsePositiveNumber(value?: string): number {
|
||||
return Number.isFinite(parsed) && parsed > 0 ? parsed : 0;
|
||||
}
|
||||
|
||||
type CwbtcPoolHealth = {
|
||||
id?: string;
|
||||
pair?: string;
|
||||
venue?: string;
|
||||
poolAddress?: string;
|
||||
live?: boolean;
|
||||
baseReserveRaw?: string;
|
||||
quoteReserveRaw?: string;
|
||||
errors?: string[];
|
||||
};
|
||||
|
||||
type CwbtcPoolsHealthPayload = {
|
||||
chainId?: number;
|
||||
tokenAddress?: string;
|
||||
token?: { symbol?: string; addressDefault?: string; decimals?: number };
|
||||
quoteTokens?: Record<string, string>;
|
||||
pools?: CwbtcPoolHealth[];
|
||||
};
|
||||
|
||||
function mergeCwbtcMeshPools(repoRoot: string, pools: Array<Record<string, unknown>>): void {
|
||||
const healthPath = path.join(repoRoot, 'reports/status/mainnet-cwbtc-pools-health-latest.json');
|
||||
const poolsConfigPath = path.join(repoRoot, 'config/engine/mainnet-cwbtc-pools.v1.json');
|
||||
if (!fs.existsSync(healthPath) || !fs.existsSync(poolsConfigPath)) return;
|
||||
|
||||
const health = readJson<CwbtcPoolsHealthPayload>(healthPath);
|
||||
const poolsConfig = readJson<{ quoteTokens?: Record<string, string> }>(poolsConfigPath);
|
||||
const chainId = Number(health.chainId ?? 1);
|
||||
const cwbtcAddress = String(health.tokenAddress ?? health.token?.addressDefault ?? '').toLowerCase();
|
||||
const quoteTokens = { ...(poolsConfig.quoteTokens ?? {}), ...(health.quoteTokens ?? {}) };
|
||||
const existing = new Set(pools.map((pool) => String(pool.poolAddress).toLowerCase()));
|
||||
|
||||
for (const row of health.pools ?? []) {
|
||||
if (!row.live || row.venue !== 'uniswap_v2') continue;
|
||||
const poolAddress = String(row.poolAddress ?? '').toLowerCase();
|
||||
if (!poolAddress.startsWith('0x') || existing.has(poolAddress)) continue;
|
||||
|
||||
const [baseSymbol, quoteSymbol] = String(row.pair ?? '/').split('/');
|
||||
const baseAddress =
|
||||
baseSymbol === 'cWBTC' ? cwbtcAddress : String(quoteTokens[baseSymbol] ?? '').toLowerCase();
|
||||
const quoteAddress =
|
||||
quoteSymbol === 'cWBTC' ? cwbtcAddress : String(quoteTokens[quoteSymbol] ?? '').toLowerCase();
|
||||
if (!baseAddress.startsWith('0x') || !quoteAddress.startsWith('0x')) continue;
|
||||
|
||||
const baseDecimals = baseSymbol === 'cWBTC' ? 8 : 6;
|
||||
const quoteDecimals = quoteSymbol === 'cWBTC' ? 8 : 6;
|
||||
const baseReserveRaw = parsePositiveNumber(row.baseReserveRaw);
|
||||
const quoteReserveRaw = parsePositiveNumber(row.quoteReserveRaw);
|
||||
if (baseReserveRaw <= 0 && quoteReserveRaw <= 0) continue;
|
||||
|
||||
const baseReserveUnits = baseReserveRaw / 10 ** baseDecimals;
|
||||
const quoteReserveUnits = quoteReserveRaw / 10 ** quoteDecimals;
|
||||
const basePriceUsd = PRICE_USD[baseSymbol] ?? 0;
|
||||
const quotePriceUsd = PRICE_USD[quoteSymbol] ?? 0;
|
||||
const reserve0Usd = baseReserveUnits * basePriceUsd;
|
||||
const reserve1Usd = quoteReserveUnits * quotePriceUsd;
|
||||
const totalLiquidityUsd = reserve0Usd + reserve1Usd;
|
||||
if (totalLiquidityUsd <= 0) continue;
|
||||
|
||||
pools.push({
|
||||
chainId,
|
||||
chainName: 'Ethereum Mainnet',
|
||||
poolAddress,
|
||||
dex: 'uniswap_v2',
|
||||
baseSymbol,
|
||||
quoteSymbol,
|
||||
baseAddress,
|
||||
quoteAddress,
|
||||
baseReserveRaw: String(row.baseReserveRaw ?? ''),
|
||||
quoteReserveRaw: String(row.quoteReserveRaw ?? ''),
|
||||
baseReserveUnits: String(baseReserveUnits),
|
||||
quoteReserveUnits: String(quoteReserveUnits),
|
||||
healthy: true,
|
||||
depthOk: true,
|
||||
parityOk: true,
|
||||
reserve0Usd,
|
||||
reserve1Usd,
|
||||
totalLiquidityUsd,
|
||||
sourceArtifact: 'reports/status/mainnet-cwbtc-pools-health-latest.json',
|
||||
});
|
||||
existing.add(poolAddress);
|
||||
}
|
||||
}
|
||||
|
||||
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 = [];
|
||||
const pools: Array<Record<string, unknown>> = [];
|
||||
|
||||
for (const entry of discovery.entries ?? []) {
|
||||
const chainId = Number(entry.chain_id);
|
||||
const chain = deploymentStatus.chains?.[String(chainId)];
|
||||
if (!chain) continue;
|
||||
if (fs.existsSync(discoveryPath) && fs.existsSync(deploymentStatusPath)) {
|
||||
const discovery = readJson<DiscoveryPayload>(discoveryPath);
|
||||
const deploymentStatus = readJson<DeploymentStatus>(deploymentStatusPath);
|
||||
|
||||
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;
|
||||
for (const entry of discovery.entries ?? []) {
|
||||
const chainId = Number(entry.chain_id);
|
||||
const chain = deploymentStatus.chains?.[String(chainId)];
|
||||
if (!chain) 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;
|
||||
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;
|
||||
|
||||
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,
|
||||
});
|
||||
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));
|
||||
mergeCwbtcMeshPools(repoRoot, pools);
|
||||
|
||||
pools.sort(
|
||||
(a, b) =>
|
||||
Number(a.chainId) - Number(b.chainId) ||
|
||||
String(a.poolAddress).localeCompare(String(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',
|
||||
'reports/status/mainnet-cwbtc-pools-health-latest.json',
|
||||
],
|
||||
poolCount: pools.length,
|
||||
positiveLiquidityPoolCount: pools.filter((pool) => pool.totalLiquidityUsd > 0).length,
|
||||
positiveLiquidityPoolCount: pools.filter((pool) => Number(pool.totalLiquidityUsd) > 0).length,
|
||||
pools,
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user