Skip to content

feat(pegs): shared peg-monitoring foundation (#299)#305

Open
spalen0 wants to merge 4 commits into
mainfrom
feat/peg-monitoring-foundation
Open

feat(pegs): shared peg-monitoring foundation (#299)#305
spalen0 wants to merge 4 commits into
mainfrom
feat/peg-monitoring-foundation

Conversation

@spalen0

@spalen0 spalen0 commented Jun 29, 2026

Copy link
Copy Markdown
Collaborator

Closes #299.

Establishes the shared building blocks consumed by all later peg/oracle monitoring layers (L1 market depeg, L2 oracle health, L3 event consumers). Generalizes the gold-standard pattern from protocols/ustb/main.py.

Changes

  • Promote ABI: protocols/ustb/abi/ChainlinkAggregator.jsoncommon-abi/ChainlinkAggregator.json (via git mv); repoint the lone reference in protocols/ustb/main.py.
  • utils/chainlink.py:
    • read_feeds(client, addresses) — batched latestRoundData + decimals reader returning typed FeedReadings.
    • Pure helpers: scale_price(answer, decimals), is_stale(updated_at, heartbeat, now, buffer), round_issues / is_round_healthy (positive answer, completed round, answeredInRound >= roundId).
    • RoundData / FeedReading dataclasses.
  • utils/pegged_assets.py:
    • PegTarget enum — USD = constant 1, BTC = live BTC/USD via DeFiLlama (coingecko:bitcoin).
    • PeggedAsset dataclass — name, defillama_key, channel, peg, depeg_pct (deviation, not floor), optional chainlink_feed (+heartbeat), optional rate_oracle (with monotonic flag).
    • PEGGED_ASSETS single registry + PEGGED_ASSETS_BY_NAME, plus price_deviation / resolve_peg_prices / get_asset helpers.
  • Tests: tests/test_chainlink.py, tests/test_pegged_assets.py — staleness, round sanity, deviation, registry helpers.

Registry coverage

Covers the required set: USDC, USDT, USDS, USDe, cUSD, iUSD, siUSD, cbBTC, LBTC.

Asset Peg Verified
USDC, USDT, USDS, USDe USD token + Chainlink USD feed verified on mainnet (cast)
cbBTC, LBTC BTC token + Chainlink (cbBTC/USD, LBTC/BTC) feed verified on mainnet
cUSD (cap), iUSD (infinifi) USD token verified; no Chainlink feed (DeFiLlama-priced)
siUSD USD ⚠️ placeholder address — TODO, not yet verified on-chain

Validation

  • ruff format + ruff check clean on all new/changed files.
  • mypy clean on the new modules (remaining errors are pre-existing in utils/abi.py / utils/web3_wrapper.py, unrelated to this PR; repo has no CI mypy gate).
  • 42 passed — new tests + test_apyusd.py.
  • Smoke-tested imports; protocols/ustb/main.py still loads the moved ABI.

Notes / follow-ups

  • siUSD address needs verification before L1/L2 wire-up.
  • Chainlink heartbeats use the mainnet 24h default; confirm per feed before tightening L2 staleness thresholds.
  • Yield-bearing tokens (sUSDe, syrup*, USTB) are intentionally not modeled as flat-peg deviations — they belong to the rate_oracle monotonicity path in L2/L3.

🤖 Generated with Claude Code

Establish the building blocks consumed by all peg/oracle monitoring layers
(L1 market depeg, L2 oracle health, L3 event consumers):

- Promote ChainlinkAggregator.json to common-abi/ and repoint protocols/ustb.
- Add utils/chainlink.py: batched latestRoundData reader (read_feeds) plus
  pure, unit-tested helpers — scale_price, is_stale(updated_at, heartbeat,
  buffer), and round/answeredInRound sanity checks. Generalizes the logic
  previously inline in protocols/ustb/main.py.
- Add utils/pegged_assets.py: PeggedAsset dataclass + PegTarget enum (USD=1,
  BTC=live BTC/USD via DeFiLlama) as the single registry consumed by L1/L2/L3,
  with optional chainlink_feed (+heartbeat) and rate_oracle (monotonic) refs.
  depeg_pct expresses peg deviation, not an absolute floor.
- Registry covers USDC, USDT, USDS, USDe, cUSD, iUSD, siUSD, cbBTC, LBTC.
  Token addresses and Chainlink feeds verified on mainnet; siUSD is a marked
  placeholder pending address verification.
- Unit tests for staleness, round sanity, deviation, and registry helpers.

ruff + mypy clean (new files); 42 tests pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
spalen0 and others added 3 commits June 30, 2026 12:54
- Remove is_stale and round_issues/is_round_healthy from utils/chainlink.py:
  no longer reliable oracle health indicators and unused by production code.
- Replace the unverified siUSD placeholder entry with the existing verified
  iUSD (infinifi) entry; siUSD is yield-bearing staked iUSD and shouldn't be
  modeled as a flat-peg deviation. Drop the now-unused PLACEHOLDER_ADDRESS.
- Update tests to match.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…nitor

- Add WBTC to the peg registry (BTC peg, verified WBTC/BTC Chainlink feed).
- ChainlinkFeed gains an explicit `quote: PegTarget` so consumers can interpret
  mixed feed denominations (WBTC/LBTC are BTC-quoted ~1.0; cbBTC is USD-quoted).
- PeggedAsset gains `downside_only`; is_depegged becomes asymmetric for BTC
  wrappers (WBTC/cbBTC/LBTC) so a legit move above peg (e.g. LBTC at ~1.004 BTC)
  no longer false-alerts — only a drop below peg triggers.
- lrt-pegs curve monitor: read pools via balances(i) (works for modern and
  legacy pools) and add the deep Lido stETH/ETH pool as the canonical
  wstETH-vs-ETH depeg gauge (wstETH deterministically wraps stETH).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@spalen0 spalen0 marked this pull request as ready for review June 30, 2026 11:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Peg monitoring: shared foundation — utils/chainlink.py, Chainlink ABI, PeggedAsset registry

1 participant