Skip to content

[PR #35] oracle.rs: single global DEFAULT_MAX_AGE=600s; per-feed heartbeat not respected #110

@obchain

Description

@obchain

PR: #35 (feat/10-chainlink-pricecache)
Commit: 5c36873
Files: crates/charon-scanner/src/oracle.rs (DEFAULT_MAX_AGE), config/default.toml ([chainlink.bnb])

Problem: DEFAULT_MAX_AGE fixed at Duration::from_secs(600), applied uniformly to every feed via PriceCache.max_age. Config exposes no per-symbol staleness window.

BSC Chainlink heartbeat intervals (docs.chain.link):

  • BNB/USD: 27s deviation / 86400s fallback
  • BTC/USD: 30s deviation / 86400s fallback
  • USDT/USD: 0.5% deviation / 86400s fallback
  • USDC/USD: 0.5% deviation / 86400s fallback

Two failure modes from single global threshold:

  1. False staleness on stablecoins: USDT / USDC legitimately skip updates during low-vol periods. 600s rejects valid price → unnecessary fallback or skipped liquidation.
  2. Excessive leniency on volatile assets: if BNB/USD stops updating, bot serves price up to 600s old — 22× normal 27s heartbeat — to size liquidation.

Fix: Extend config schema:

[chainlink.bnb.BNB]
address   = "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE"
max_age_s = 120

[chainlink.bnb.USDT]
address   = "0xB97Ad0E74fa7d920791E90258A6E2085088b4320"
max_age_s = 90000

Or flat map + separate [chainlink.max_age_s] sub-table keyed by symbol with DEFAULT_MAX_AGE fallback.

PriceCache::new must accept per-symbol durations (HashMap<String, Duration>) and select correct window in refresh().

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