Skip to content

[PR #34] HealthScanner has no remove() — repaid borrowers accumulate forever, poison liquidatable() #106

@obchain

Description

@obchain

PR: #34 (feat/09-health-scanner)
File: crates/charon-scanner/src/scanner.rs — HealthScanner impl block

Problem: PRD review focus item 7 — borrowers that fully repay must be removed from all buckets; otherwise stale entries accumulate.

PR provides upsert(), bucket_counts(), liquidatable(), near_liquidation() but no remove() or prune(). Once borrower inserted, stays in DashMap for process lifetime regardless of repayment.

Two failure modes:

  1. Borrower repays debt. Position no longer returned by get_positions(). Stale entry remains in DashMap as Liquidatable. Every call to liquidatable() returns that position. Flash-loan router attempts liquidation, on-chain call reverts (no debt to liquidate), gas wasted and profitable bundle reverted.
  2. On BSC mainnet with thousands of Venus borrowers over multi-day run, DashMap grows unbounded. Combined with sentinel HF issue, liquidatable() Vec grows monotonically.

Fix: Add remove(address: Address) and prune(current_positions: &[Position]). prune() diffs current fetched set against DashMap keys, removes any address not present in latest snapshot. Call inside block loop before upsert().

Metadata

Metadata

Assignees

No one assigned

    Labels

    layer:rustRust crates (core / scanner / protocols / executor / cli)pr-reviewFindings from PR review processpriority:p1-coreCore MVP scopetype:featureNew capability or deliverable

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions