Skip to main content

ChainlinkOracleCloneable

Git Source

Inherits: IChainlinkOracle, IOraclePriceCache, Clone

Title: ChainlinkOracleCloneable

Author: OlympusDAO

forge-lint: disable-start(mixed-case-function,mixed-case-variable)

Oracle adapter that implements Chainlink's AggregatorV2V3Interface from cached base/quote pair snapshots

State Variables

_VERSION

uint8 internal constant _VERSION = 1

Functions

factory

The factory address

Does not revert.

function factory() public pure returns (IOracleFactory);

Returns

NameTypeDescription
<none>IOracleFactoryThe factory address stored in immutable args

baseToken

The base token address

Does not revert.

function baseToken() public pure override returns (address);

Returns

NameTypeDescription
<none>addressaddress The base token address stored in immutable args

quoteToken

The quote token address

Does not revert.

function quoteToken() public pure override returns (address);

Returns

NameTypeDescription
<none>addressaddress The quote token address stored in immutable args

_priceDecimals

The cache decimal scale captured at creation time

This value is intentionally immutable per oracle instance.

function _priceDecimals() internal pure returns (uint8);

Returns

NameTypeDescription
<none>uint8uint8 The cache decimal scale stored in immutable args

maxAge

The maximum allowed age for cached prices

Does not revert.

function maxAge() public pure override returns (uint48);

Returns

NameTypeDescription
<none>uint48uint48 The max age stored in immutable args

name

The name of the oracle

Does not revert.

function name() public pure override returns (string memory);

Returns

NameTypeDescription
<none>stringstring The name stored in immutable args

_getEnabledPriceCache

Returns the enabled price cache policy for this oracle.

Calls factory().getOracleContext(address(this)) to read the oracle liveness context and configured cache policy from the factory. Reverts with ChainlinkOracle_NotEnabled() if the returned context is disabled or if the factory does not provide a valid price cache address. Reverts from getOracleContext bubble up, including when the factory policy is inactive or this oracle was not created by the factory.

function _getEnabledPriceCache() internal view returns (IPriceCache priceCache_);

Returns

NameTypeDescription
priceCache_IPriceCacheThe configured price cache policy, expected to be a non-zero address.

decimals

Does not revert.

function decimals() external pure override returns (uint8);

Returns

NameTypeDescription
<none>uint8uint8 The number of decimals

description

Does not revert.

function description() external pure override returns (string memory);

Returns

NameTypeDescription
<none>stringstring The oracle name

version

Does not revert.

function version() external pure override returns (uint256);

Returns

NameTypeDescription
<none>uint256uint256 The version number

_latestRoundDataInternal

This function uses cached pair snapshots only (round-style semantics). It does not fallback to live pricing when caches are stale and does not enforce maxAge(). This function will revert if:

  • The oracle is not enabled in the factory context
  • The factory policy is deactivated in Kernel (checked via factory.getOracleContext())
  • The IPriceCache.getCachedPrice() call reverts because the cache policy is deactivated in Kernel or the cache contract is disabled
  • The base/quote pair is invalid for the configured cache policy
  • Either cached USD leg is zero
  • No cached pair observation is present (updatedAt == 0)
  • The computed pair price rounds down to zero (price == 0 after FullMath.mulDiv(...))
  • The computed pair price cannot be cast to int256 (answer = SafeCast.toInt256(price)) If callers encounter a revert due to feed state, they should cache prices then retry.
function _latestRoundDataInternal()
internal
view
returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);

Returns

NameTypeDescription
roundIduint80The cached pair round ID
answerint256The price of 1 base token in quote tokens, scaled by 10^decimals()
startedAtuint256The timestamp when the round started (same as updatedAt)
updatedAtuint256The timestamp when the round was updated (from the cached pair snapshot)
answeredInRounduint80The round ID (same as roundId)

_isStaleFromTimestamp

Checks whether a timestamp is stale for the configured freshness window.

Returns true when timestamp_ is zero or when it is older than maxAge_.

function _isStaleFromTimestamp(uint256 timestamp_, uint48 maxAge_) internal view returns (bool);

Parameters

NameTypeDescription
timestamp_uint256Timestamp to evaluate.
maxAge_uint48Maximum acceptable age, in seconds.

Returns

NameTypeDescription
<none>boolisStale_ Whether the timestamp is zero or too old.

_latestPermissibleTimestamp

Computes the oldest timestamp that is still acceptable for fresh round data.

Returns 0 when block.timestamp <= maxAge_; otherwise returns block.timestamp - uint256(maxAge_).

function _latestPermissibleTimestamp(uint48 maxAge_) internal view returns (uint256);

Parameters

NameTypeDescription
maxAge_uint48Maximum acceptable age, in seconds.

Returns

NameTypeDescription
<none>uint256latestPermissible_ Oldest acceptable timestamp, or 0 if no positive lower bound exists.

_latestRoundDataFreshInternal

Returns latest round data after enforcing maxAge() freshness.

Reverts with ChainlinkOracle_Stale(updatedAt, latestPermissibleTimestamp) when the returned updatedAt is stale according to _isStaleFromTimestamp(updatedAt, maxAge()).

function _latestRoundDataFreshInternal()
internal
view
returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);

Returns

NameTypeDescription
roundIduint80Latest round identifier.
answerint256Latest answer.
startedAtuint256Timestamp when the latest round started.
updatedAtuint256Timestamp when the latest round answer was updated.
answeredInRounduint80Round identifier in which the answer was computed.

latestRoundData

Reverts if:

  • The oracle is not enabled in the factory context
  • The factory policy is deactivated in Kernel (checked via factory.getOracleContext())
  • The cache policy is deactivated in Kernel or the cache contract is disabled
  • The base/quote pair is invalid for the configured cache policy
  • Either cached USD leg is zero
  • No cached pair observation is present (updatedAt == 0)
  • The cached pair observation is stale (updatedAt + maxAge() < block.timestamp)
  • The computed pair price rounds down to zero (price == 0 after FullMath.mulDiv(...))
  • The computed pair price cannot be cast to int256 (answer = SafeCast.toInt256(price))
function latestRoundData()
external
view
override
returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);

isStale

Returns whether the cached pair round should be considered stale.

Chainlink-style round readers may consume stale rounds. This flag allows consumers to detect stale or missing cached state before reading. Reverts if:

  • The oracle is not enabled in the factory context
  • The factory policy is deactivated in Kernel (checked via factory.getOracleContext())
  • The IPriceCache.isStale() call reverts because the cache policy is deactivated in Kernel or the cache contract is disabled
  • The configured pair is invalid for the active cache policy
function isStale() external view override returns (bool);

Returns

NameTypeDescription
<none>boolisStale_ true if the direct pair cache is unset or older than maxAge()

getRoundData

Only supports the latest round. For any other round ID, reverts with ChainlinkOracle_NoDataPresent(). This function will revert if:

  • The oracle is not enabled in the factory context
  • The factory policy is deactivated in Kernel (checked via factory.getOracleContext())
  • The cache policy is deactivated in Kernel or the cache contract is disabled
  • The base/quote pair is invalid for the configured cache policy
  • Either cached USD leg is zero
  • No cached pair observation is present (updatedAt == 0)
  • The computed pair price rounds down to zero (price == 0 after FullMath.mulDiv(...))
  • The computed pair price cannot be cast to int256 (answer = SafeCast.toInt256(price)) This function does not revert when the latest cached round is stale.
function getRoundData(uint80 roundId_)
external
view
override
returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);

Parameters

NameTypeDescription
roundId_uint80The round ID to query

Returns

NameTypeDescription
roundIduint80The round ID
answerint256The price of 1 base token in quote tokens, scaled by 10^decimals()
startedAtuint256The timestamp when the round started
updatedAtuint256The timestamp when the round was updated
answeredInRounduint80The round ID

latestAnswer

Reverts if:

  • The oracle is not enabled in the factory context
  • The factory policy is deactivated in Kernel (checked via factory.getOracleContext())
  • The cache policy is deactivated in Kernel or the cache contract is disabled
  • The base/quote pair is invalid for the configured cache policy
  • Either cached USD leg is zero
  • No cached pair observation is present (updatedAt == 0)
  • The cached pair observation is stale (updatedAt + maxAge() < block.timestamp)
  • The computed pair price rounds down to zero (price == 0 after FullMath.mulDiv(...))
  • The computed pair price cannot be cast to int256 (answer = SafeCast.toInt256(price))
function latestAnswer() external view override returns (int256);

Returns

NameTypeDescription
<none>int256int256 The latest price

latestTimestamp

Reverts if:

  • The oracle is not enabled in the factory context
  • The factory policy is deactivated in Kernel (checked via factory.getOracleContext())
  • The cache policy is deactivated in Kernel or the cache contract is disabled
  • The base/quote pair is invalid for the configured cache policy
  • Either cached USD leg is zero
  • No cached pair observation is present (updatedAt == 0)
  • The computed pair price rounds down to zero (price == 0 after FullMath.mulDiv(...))
  • The computed pair price cannot be cast to int256 (answer = SafeCast.toInt256(price)) This function does not revert when the latest cached round is stale.
function latestTimestamp() external view override returns (uint256);

Returns

NameTypeDescription
<none>uint256uint256 The latest timestamp

latestRound

Reverts if:

  • The oracle is not enabled in the factory context
  • The factory policy is deactivated in Kernel (checked via factory.getOracleContext())
  • The cache policy is deactivated in Kernel or the cache contract is disabled
  • The base/quote pair is invalid for the configured cache policy
  • Either cached USD leg is zero
  • No cached pair observation is present (updatedAt == 0)
  • The computed pair price rounds down to zero (price == 0 after FullMath.mulDiv(...))
  • The computed pair price cannot be cast to int256 (answer = SafeCast.toInt256(price)) This function does not revert when the latest cached round is stale.
function latestRound() external view override returns (uint256);

Returns

NameTypeDescription
<none>uint256uint256 The latest round ID

getAnswer

Reverts if:

  • The oracle is not enabled in the factory context
  • The factory policy is deactivated in Kernel (checked via factory.getOracleContext())
  • The cache policy is deactivated in Kernel or the cache contract is disabled
  • The base/quote pair is invalid for the configured cache policy
  • Either cached USD leg is zero
  • No cached pair observation is present (updatedAt == 0)
  • The computed pair price rounds down to zero (price == 0 after FullMath.mulDiv(...))
  • The computed pair price cannot be cast to int256 (answer = SafeCast.toInt256(price))
  • roundId_ is not the latest round ID This function does not revert when the latest cached round is stale.
function getAnswer(uint256 roundId_) external view override returns (int256);

Parameters

NameTypeDescription
roundId_uint256The round ID to query

Returns

NameTypeDescription
<none>int256int256 The answer for the given round ID

getTimestamp

Reverts if:

  • The oracle is not enabled in the factory context
  • The factory policy is deactivated in Kernel (checked via factory.getOracleContext())
  • The cache policy is deactivated in Kernel or the cache contract is disabled
  • The base/quote pair is invalid for the configured cache policy
  • Either cached USD leg is zero
  • No cached pair observation is present (updatedAt == 0)
  • The computed pair price rounds down to zero (price == 0 after FullMath.mulDiv(...))
  • The computed pair price cannot be cast to int256 (answer = SafeCast.toInt256(price))
  • roundId_ is not the latest round ID This function does not revert when the latest cached round is stale.
function getTimestamp(uint256 roundId_) external view override returns (uint256);

Parameters

NameTypeDescription
roundId_uint256The round ID to query

Returns

NameTypeDescription
<none>uint256uint256 The timestamp for the given round ID

cachePrice

Triggers a cache update for the oracle's configured pair

Unconditionally asks the factory to cache the configured pair. Reverts if:

  • The factory policy is deactivated in Kernel
  • The factory is disabled
  • This contract is not a deployed oracle from the factory
  • This contract is not enabled in the factory
  • The configured pair is invalid in the active cache policy
function cachePrice() external override;

cachePriceIfNecessary

Triggers a cache update only when the oracle's configured pair cache is stale

Defers staleness checks to the factory using this oracle's configured maxAge. Reverts if:

  • The factory policy is deactivated in Kernel
  • The factory is disabled
  • This contract is not a deployed oracle from the factory
  • This contract is not enabled in the factory
  • The configured pair is invalid in the active cache policy
function cachePriceIfNecessary() external override;

supportsInterface

Query if a contract implements an interface

Does not revert.

function supportsInterface(bytes4 interfaceId_) public pure returns (bool);

Parameters

NameTypeDescription
interfaceId_bytes4The interface identifier, as specified in ERC-165

Returns

NameTypeDescription
<none>boolbool true if the contract implements interfaceId_ and false otherwise