Skip to content

oracle_lib

Internal Vyper library for redundant Chainlink price reads. Initialized by TareEngine; not deployed standalone.

Source: TARE-Stablecoin/src/oracle_lib.vy (Vyper 0.4.3)

Concept guide: Collateral & oracles

Consumer: TareEngineoracle_lib._get_price on every collateral valuation.

Implementation overview

Redundant feed reader used per collateral asset:

  1. Defensive readsraw_call on latestRoundData(); bad feeds return (False, 0) instead of reverting.
  2. Staleness — 3h TIMEOUT; round completeness; positive answer; future updated_at guard (TARE-3).
  3. Circuit-breaker bands — reject prices pinned at minAnswer/maxAnswer when exposed (TARE-4).
  4. Dual-feed agreement — when primary + fallback healthy, must agree within max_deviation_bps.
  5. Fallback — single surviving feed used when other dead.
  6. L2 sequencer — optional uptime feed (skipped on Sepolia/mainnet with empty address).
flowchart TD
    GP[_get_price] --> Seq{sequencer up?}
    Seq --> P[_try_get_price primary]
    Seq --> F[_try_get_price fallback]
    P --> Both{both OK?}
    F --> Both
    Both -->|yes| Dev[_within_deviation]
    Both -->|one| Return[return surviving]
    Both -->|none| Revert[revert]

Constants

Name Value Role
TIMEOUT 3 hours Max feed staleness
BPS 10_000 Deviation math denominator

Internal functions

_try_get_price

oracle_lib._try_get_price(feed) -> (bool, uint256)

Soft-read one Chainlink feed via raw_call on latestRoundData(). Never reverts — returns (False, 0) on any failure.

Param Type Description
feed address Chainlink aggregator; empty(address)(False, 0)

Returns: (healthy, price) — price in feed's native decimals (typically 8 for USD pairs).

Checks when healthy: round complete, updated_at fresh (≤3h, not future), answer > 0, not at min/max circuit-breaker band.

Access: @internal @view — called by _get_price.

Source (TARE-Stablecoin/src/oracle_lib.vy:51-111):

@internal
@view
def _try_get_price(feed: address) -> (bool, uint256):
    success, response = raw_call(feed, method_id("latestRoundData()"), ...)
    # staleness, future updated_at, answer > 0, _within_answer_band
    return (True, convert(answer, uint256))

Example:

# Inside _get_price — never call externally
ok, price = self._try_get_price(primary_feed)

Cross-links: _within_answer_band · _get_price · TareEngine get_usd_value

_try_read_int

oracle_lib._try_read_int(feed, selector) -> (bool, int256)

Soft static read of a zero-arg getter returning int256 (e.g. minAnswer(), maxAnswer()).

Param Type Description
feed address Chainlink aggregator
selector Bytes[4] Method id (e.g. method_id("minAnswer()"))

Returns: (ok, value)(False, 0) if call fails or response < 32 bytes.

Access: @internal @view — helper for _within_answer_band.

Source (TARE-Stablecoin/src/oracle_lib.vy:114-129):

@internal
@view
def _try_read_int(feed: address, selector: Bytes[4]) -> (bool, int256):
    success, response = raw_call(feed, selector, max_outsize=32, is_static_call=True, revert_on_failure=False)
    if (not success) or (len(response) < 32):
        return (False, 0)
    return (True, abi_decode(response, int256))

Cross-links: _within_answer_band · _try_get_price

_within_answer_band

oracle_lib._within_answer_band(feed, answer) -> bool

Returns False if Chainlink answer is pinned at minAnswer/maxAnswer circuit-breaker bounds (stale floor/ceiling, not real price).

Param Type Description
feed address Chainlink aggregator
answer int256 Price from latestRoundData

Returns: boolTrue if OK to use price; True also when feed doesn't expose bounds (common proxy case).

Access: @internal @view — called from _try_get_price.

Source (TARE-Stablecoin/src/oracle_lib.vy:132-157):

@internal
@view
def _within_answer_band(feed: address, answer: int256) -> bool:
    min_ok, min_answer = self._try_read_int(feed, method_id("minAnswer()"))
    max_ok, max_answer = self._try_read_int(feed, method_id("maxAnswer()"))
    if not (min_ok and max_ok):
        return True  # no band exposed — skip check
    if answer <= min_answer or answer >= max_answer:
        return False
    return True

Cross-links: _try_read_int · _try_get_price

_within_deviation

oracle_lib._within_deviation(a, b, max_deviation_bps) -> bool

Pure math: true if two prices agree within max_deviation_bps basis points.

Param Type Description
a uint256 First price (feed native decimals)
b uint256 Second price
max_deviation_bps uint256 Max allowed disagreement in bps (10_000 = 100%)

Returns: boolTrue if |a - b| / max(a, b) <= max_deviation_bps / BPS.

Access: @internal @pure — dual-feed agreement check in _get_price.

Source (TARE-Stablecoin/src/oracle_lib.vy:160-172):

@internal
@pure
def _within_deviation(a: uint256, b: uint256, max_deviation_bps: uint256) -> bool:
    if a == b:
        return True
    high: uint256 = a if a > b else b
    low: uint256 = b if a > b else a
    return (high - low) * BPS <= max_deviation_bps * high

Cross-links: _get_price · TareEngine add_collateral

_sequencer_is_up

oracle_lib._sequencer_is_up(feed, grace_period) -> bool

L2 Chainlink sequencer uptime check. Skipped on Sepolia/mainnet when engine passes empty(address) feed.

Param Type Description
feed address L2 sequencer uptime aggregator
grace_period uint256 Seconds after restart before trusting prices

Returns: boolTrue if sequencer up past grace window. answer == 0 means up; 1 means down.

Access: @internal @view — asserted in _get_price when feed non-empty.

Source (TARE-Stablecoin/src/oracle_lib.vy:175-215):

@internal
@view
def _sequencer_is_up(feed: address, grace_period: uint256) -> bool:
    # latestRoundData: answer != 0 => down
    if block.timestamp - started_at <= grace_period:
        return False
    return True

Cross-links: _get_price · TareEngine pricing

_get_price

oracle_lib._get_price(primary, fallback, max_deviation_bps, sequencer_uptime_feed, sequencer_grace_period) -> uint256

Main entry: resolve redundant Chainlink price for one collateral asset.

Param Type Description
primary address Primary Chainlink feed (required)
fallback address Secondary feed or empty(address)
max_deviation_bps uint256 Max disagreement when both feeds live
sequencer_uptime_feed address L2 sequencer feed or empty(address) to skip
sequencer_grace_period uint256 Post-restart grace (ignored if sequencer feed empty)

Returns: uint256 — price in feeds' native decimals.

Resolution order:

  1. If sequencer feed set → must pass _sequencer_is_up or revert.
  2. Both feeds healthy → require _within_deviation; return primary.
  3. One healthy → return that price.
  4. None → revert "OracleLib: no healthy feed".

Access: @internal @view — called by TareEngine _get_usd_value / _get_token_amount_from_usd.

Source (TARE-Stablecoin/src/oracle_lib.vy:218-274):

@internal
@view
def _get_price(primary, fallback, max_deviation_bps, sequencer_uptime_feed, sequencer_grace_period) -> uint256:
    if sequencer_uptime_feed != empty(address):
        assert self._sequencer_is_up(...), "OracleLib: sequencer down"
    primary_ok, primary_price = self._try_get_price(primary)
    if fallback == empty(address):
        assert primary_ok, "OracleLib: primary feed unavailable"
        return primary_price
    # dual-feed: deviation check or fallback to surviving feed
    raise "OracleLib: no healthy feed"

Cross-links: _try_get_price · _within_deviation · _sequencer_is_up · TareEngine add_collateral