feat(pegs): shared peg-monitoring foundation (#299)#305
Open
spalen0 wants to merge 4 commits into
Open
Conversation
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>
This was referenced Jun 29, 2026
- 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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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
protocols/ustb/abi/ChainlinkAggregator.json→common-abi/ChainlinkAggregator.json(viagit mv); repoint the lone reference inprotocols/ustb/main.py.utils/chainlink.py:read_feeds(client, addresses)— batchedlatestRoundData+decimalsreader returning typedFeedReadings.scale_price(answer, decimals),is_stale(updated_at, heartbeat, now, buffer),round_issues/is_round_healthy(positive answer, completed round,answeredInRound >= roundId).RoundData/FeedReadingdataclasses.utils/pegged_assets.py:PegTargetenum —USD= constant1,BTC= live BTC/USD via DeFiLlama (coingecko:bitcoin).PeggedAssetdataclass —name,defillama_key,channel,peg,depeg_pct(deviation, not floor), optionalchainlink_feed(+heartbeat), optionalrate_oracle(withmonotonicflag).PEGGED_ASSETSsingle registry +PEGGED_ASSETS_BY_NAME, plusprice_deviation/resolve_peg_prices/get_assethelpers.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.
cast)TODO, not yet verified on-chainValidation
ruff format+ruff checkclean on all new/changed files.mypyclean on the new modules (remaining errors are pre-existing inutils/abi.py/utils/web3_wrapper.py, unrelated to this PR; repo has no CI mypy gate).42 passed— new tests +test_apyusd.py.protocols/ustb/main.pystill loads the moved ABI.Notes / follow-ups
siUSDaddress needs verification before L1/L2 wire-up.heartbeats use the mainnet 24h default; confirm per feed before tightening L2 staleness thresholds.rate_oraclemonotonicity path in L2/L3.🤖 Generated with Claude Code