Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion dca/dca.ts
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,11 @@ async function executeDirectSwap(opts: {
network,
senderKey: opts.stxPrivateKey,
anchorMode: AnchorMode.Any,
fee: 5000n,
// 2026-07-15 field audit F-14: an underpriced hardcoded fee is a
// stuck-head-nonce seed (one stuck tx stalls every later tx from the
// signer). Configurable via DCA_FEE_USTX; default raised to match
// field-tested contract-call fees.
fee: BigInt(process.env.DCA_FEE_USTX ?? "50000"),
});

const broadcastRes = await broadcastTransaction({ transaction: tx, network });
Expand Down
15 changes: 13 additions & 2 deletions defi-portfolio-scanner/defi-portfolio-scanner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,17 @@ const SKILL_NAME = "defi-portfolio-scanner";
const REQUEST_TIMEOUT = 10_000; // 10 seconds per protocol
const HIRO_TIMEOUT = 15_000;

// Zest LTV liquidation-risk thresholds, as FRACTIONS in [0, 1] (display
// multiplies by 100). NOTE (2026-07-15 field audit F-13): no scanner code path
// currently populates ZestPosition.ltv with a number — both construction sites
// set null — so this risk block is DORMANT until the Zest reserve-data parser
// computes a real fractional LTV. The threshold scale below is corrected now so
// the flags work the moment ltv is populated; population is tracked separately
// (requires verifying the on-chain get-user-reserve-data value scale against a
// live position).
const ZEST_LTV_CRITICAL = 0.85;
const ZEST_LTV_WARNING = 0.70;

const ENDPOINTS = {
bitflowPools: "https://bff.bitflowapis.finance/api/app/v1/pools",
zestContract: {
Expand Down Expand Up @@ -731,14 +742,14 @@ function computeRiskScore(scanData: ScanData): {
// 3. Zest LTV risk
for (const pos of protocols.zest.positions) {
if (pos.ltv !== null) {
if (pos.ltv > 85) {
if (pos.ltv > ZEST_LTV_CRITICAL) {
score += 30;
factors.push({
factor: "zest-ltv-critical",
severity: "critical",
detail: `Zest position ${pos.asset} has LTV ${(pos.ltv * 100).toFixed(1)}% — liquidation risk imminent.`,
});
} else if (pos.ltv > 70) {
} else if (pos.ltv > ZEST_LTV_WARNING) {
score += 15;
factors.push({
factor: "zest-ltv-warning",
Expand Down
Loading