Embed cUSDC per-token sample and triple-state in ho-liquidity snapshot.
Some checks failed
CI/CD Pipeline / Solidity Contracts (push) Failing after 1m22s
CI/CD Pipeline / Security Scanning (push) Successful in 2m36s
CI/CD Pipeline / Lint and Format (push) Failing after 52s
CI/CD Pipeline / Terraform Validation (push) Failing after 30s
CI/CD Pipeline / Kubernetes Validation (push) Successful in 27s
HYBX OMNL TypeScript & anchor / token-aggregation build + reconcile artifact (push) Failing after 31s
Validation / validate-genesis (push) Successful in 35s
Validation / validate-terraform (push) Has been cancelled
Validation / validate-kubernetes (push) Has been cancelled
Validation / validate-smart-contracts (push) Has been cancelled
Validation / validate-documentation (push) Has been cancelled
Validation / validate-security (push) Has been cancelled

Public ho-liquidity-snapshot now includes perTokenSamples.cUSDC (Blockscout supply vs 1.2× nostro) and tripleState reconcile summary for the explorer dashboard.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
defiQUG
2026-06-26 01:59:11 -07:00
parent 1158c616d8
commit aa5790bb8b
2 changed files with 126 additions and 0 deletions

View File

@@ -0,0 +1,106 @@
import { existsSync, readFileSync } from 'fs';
import { resolve } from 'path';
import { fetchBlockscoutTokenMeta } from './blockscout-token-meta';
import { evaluateSupplyNostroMatch, type SupplyNostroMatchInfo } from './omnl-cash-in-bank-audit';
import { runTripleStateReconcile, type TripleReconcileReport } from './omnl-triple-reconcile';
import { resolveCanonicalPriceUsd } from './canonical-price-oracle';
const CHAIN_138 = 138;
const DEFAULT_CUSDC_ADDRESS = '0xf22258f57794CC8E06237084b353Ab30fFfa640b';
export interface HoLiquidityTripleStateSummary {
aligned?: boolean;
breaksCount?: number;
generatedAt?: string;
}
export interface HoLiquidityPerTokenSample {
address: string;
totalSupplyUsd?: number;
cashInBankUsd?: number;
supplyNostroMatch?: SupplyNostroMatchInfo;
}
function decimalStringToNumber(value?: string, decimals?: number): number | null {
if (value == null || value === '') return null;
const dec = Number.isInteger(decimals) ? Number(decimals) : 18;
try {
const raw = BigInt(value);
const base = 10n ** BigInt(dec);
const whole = raw / base;
const frac = raw % base;
return Number(whole) + Number(frac) / Number(base);
} catch {
return null;
}
}
function readOptionalTripleStateFile(): TripleReconcileReport | null {
const candidates = [
process.env.OMNL_TRIPLE_RECONCILE_FILE?.trim(),
resolve(process.cwd(), 'reports/status/omnl-triple-reconcile-latest.json'),
process.env.PROXMOX_ROOT
? resolve(process.env.PROXMOX_ROOT, 'reports/status/omnl-triple-reconcile-latest.json')
: '',
].filter(Boolean) as string[];
for (const file of candidates) {
if (!existsSync(file)) continue;
try {
return JSON.parse(readFileSync(file, 'utf8')) as TripleReconcileReport;
} catch {
continue;
}
}
return null;
}
export async function loadHoLiquidityTripleStateSummary(): Promise<HoLiquidityTripleStateSummary | undefined> {
let triple: TripleReconcileReport | null = null;
try {
triple = await runTripleStateReconcile(process.env.OMNL_HEALTH_LINE_ID?.trim() || undefined);
} catch {
triple = null;
}
const fileTriple = readOptionalTripleStateFile();
if ((!triple || (triple.breaks?.length ?? 0) > 0) && fileTriple) {
triple = fileTriple;
} else if (!triple && fileTriple) {
triple = fileTriple;
}
if (!triple) return undefined;
return {
aligned: triple.aligned,
breaksCount: (triple.breaks || []).length,
generatedAt: triple.generatedAt,
};
}
export async function loadCusdcPerTokenSample(input: {
cashInBankUsd: number;
officeId: number;
}): Promise<HoLiquidityPerTokenSample | undefined> {
const address = (process.env.CUSDC_ADDRESS_138 || DEFAULT_CUSDC_ADDRESS).toLowerCase();
const meta = await fetchBlockscoutTokenMeta(CHAIN_138, address);
const decimals = meta?.decimals ?? 6;
const supplyUnits = decimalStringToNumber(meta?.totalSupply, decimals);
const { priceUsd } = resolveCanonicalPriceUsd(CHAIN_138, address);
const pegPriceUsd = priceUsd != null && priceUsd > 0 ? priceUsd : 1;
const totalSupplyUsd = supplyUnits != null && supplyUnits > 0 ? supplyUnits * pegPriceUsd : undefined;
const supplyNostroMatch = evaluateSupplyNostroMatch({
totalSupplyUsd,
externalNostroCashUsd: input.cashInBankUsd,
headOfficeId: input.officeId,
});
return {
address,
totalSupplyUsd,
cashInBankUsd: input.cashInBankUsd > 0 ? input.cashInBankUsd : undefined,
supplyNostroMatch,
};
}

View File

@@ -7,6 +7,12 @@ import {
type SupplyNostroMatchInfo,
} from './omnl-cash-in-bank-audit';
import { fineractConfigured } from './omnl-fineract-office-gl';
import {
loadCusdcPerTokenSample,
loadHoLiquidityTripleStateSummary,
type HoLiquidityPerTokenSample,
type HoLiquidityTripleStateSummary,
} from './omnl-ho-liquidity-enrichment';
export type HoLiquidityAlertSeverity = 'critical' | 'warning' | 'info';
@@ -25,6 +31,10 @@ export interface HoLiquiditySnapshot {
cashInBank: CashInBankAuditSnapshot;
reserveCoverage: HoReserveCoverageInfo;
aggregateSupplyNostroMatch?: SupplyNostroMatchInfo;
perTokenSamples?: {
cUSDC?: HoLiquidityPerTokenSample;
};
tripleState?: HoLiquidityTripleStateSummary;
alerts: HoLiquidityAlert[];
auditMaxAgeMinutes: number;
}
@@ -149,6 +159,14 @@ export async function buildHoLiquiditySnapshot(options?: {
),
).toISOString();
const [tripleState, cusdcSample] = await Promise.all([
loadHoLiquidityTripleStateSummary().catch(() => undefined),
loadCusdcPerTokenSample({
cashInBankUsd: cashInBankEnriched.cashInBankUsd,
officeId,
}).catch(() => undefined),
]);
return {
generatedAt,
officeId,
@@ -158,6 +176,8 @@ export async function buildHoLiquiditySnapshot(options?: {
cashInBank: cashInBankEnriched,
reserveCoverage,
aggregateSupplyNostroMatch,
perTokenSamples: cusdcSample ? { cUSDC: cusdcSample } : undefined,
tripleState,
alerts: evaluateHoLiquidityAlerts({ cashInBank: cashInBankEnriched, reserveCoverage, generatedAt }),
auditMaxAgeMinutes: auditMaxAgeMinutes(),
};