Skip to main content

BaseOracleFactory

Git Source

Inherits: Policy, PolicyEnabler, IOracleFactory, IVersioned, ReentrancyGuard

Title: BaseOracleFactory

Author: OlympusDAO

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

Abstract base contract for oracle factories with common functionality

Uses ClonesWithImmutableArgs for gas-efficient oracle deployment

State Variables​

_ROLES_KEYCODE​

bytes5 internal constant _ROLES_KEYCODE = "ROLES"

priceCache​

The pair cache policy

IPriceCache public priceCache

_tokensToOracle​

Mapping from base token to quote token to maxAge to oracle address

mapping(address baseToken => mapping(address quoteToken => mapping(uint48 maxAge => address oracle))) internal
_tokensToOracle

_oraclePairVariantCounts​

Mapping from an ordered base/quote pair to the number of deployed oracle variants

Updated when oracles are created. Factory-level re-enable uses this count to reject unknown pairs before checking whether any deployed variant is enabled.

mapping(bytes32 pairKey => uint256 variantCount) internal _oraclePairVariantCounts

_enabledOraclePairVariantCounts​

Mapping from an ordered base/quote pair to the number of enabled oracle variants

Updated when oracles are created, enabled, or disabled. Factory-level re-enable recaching uses this count to skip pairs that currently have no enabled oracle.

mapping(bytes32 pairKey => uint256 variantCount) internal _enabledOraclePairVariantCounts

_oracles​

Internal array of all deployed oracles

address[] internal _oracles

isOracle​

Mapping to validate deployed oracles

mapping(address => bool) public isOracle

_oracleToBaseToken​

Mapping from oracle to base token

mapping(address oracle => address baseToken) internal _oracleToBaseToken

_oracleToQuoteToken​

Mapping from oracle to quote token

mapping(address oracle => address quoteToken) internal _oracleToQuoteToken

_oracleToMaxAge​

Mapping from oracle to maxAge

mapping(address oracle => uint48 maxAge) internal _oracleToMaxAge

_isOracleEnabled​

Mapping to track if an oracle is enabled

mapping(address => bool) internal _isOracleEnabled

isCreationEnabled​

Whether new oracle creation is enabled

bool public isCreationEnabled

Functions​

constructor​

Constructs a new BaseOracleFactory

Reverts if priceCache_ is not a valid IPriceCache policy for this Kernel.

constructor(Kernel kernel_, address priceCache_) Policy(kernel_);

Parameters

NameTypeDescription
kernel_KernelThe Kernel address
priceCache_addressThe price cache policy address

configureDependencies​

Define module dependencies for this policy.

Reverts if the configured ROLES module major version is unsupported.

function configureDependencies() external override returns (Keycode[] memory dependencies);

Returns

NameTypeDescription
dependenciesKeycode[]- Keycode array of module dependencies.

requestPermissions​

Function called by kernel to set module function permissions.

Does not revert.

function requestPermissions() external pure override returns (Permissions[] memory requests);

Returns

NameTypeDescription
requestsPermissions[]- Array of keycodes and function selectors for requested permissions.

VERSION​

Returns the version of the contract

Does not revert.

function VERSION() external pure virtual override returns (uint8 major, uint8 minor);

Returns

NameTypeDescription
majoruint8- Major version upgrade indicates breaking change to the interface.
minoruint8- Minor version change retains backward-compatible interface.

onlyPolicyActive​

Reverts if this policy is not active in the Kernel.

modifier onlyPolicyActive() ;

_onlyPolicyActive​

function _onlyPolicyActive() internal view;

_onlyOracleManagerOrAdminRole​

Checks if the caller has the oracle_manager or admin role

function _onlyOracleManagerOrAdminRole() internal view;

_onlyOracleManagerOrAdminOrEmergencyRole​

Checks if the caller has the oracle_manager, admin, or emergency role

function _onlyOracleManagerOrAdminOrEmergencyRole() internal view;

onlyOracleManagerOrAdminRole​

Modifier that reverts if the caller does not have the oracle_manager or admin role

modifier onlyOracleManagerOrAdminRole() ;

onlyOracleManagerOrAdminOrEmergencyRole​

Modifier that reverts if the caller does not have the oracle_manager, admin, or emergency role

modifier onlyOracleManagerOrAdminOrEmergencyRole() ;

_getOracleImplementation​

Returns the oracle implementation address for cloning

function _getOracleImplementation() internal view virtual returns (address);

Returns

NameTypeDescription
<none>addressaddress The address of the oracle implementation contract to be cloned

_encodeOracleData​

Encodes oracle-specific data for cloning

This function should perform service-specific validation, calculate parameters, and encode the immutable args for the clone

function _encodeOracleData(address baseToken_, address quoteToken_, uint48 maxAge_, bytes calldata customParams_)
internal
view
virtual
returns (bytes memory);

Parameters

NameTypeDescription
baseToken_addressThe base token address
quoteToken_addressThe quote token address
maxAge_uint48The maximum age (in seconds) of cached prices used by the oracle
customParams_bytesService-specific custom parameters (can be empty)

Returns

NameTypeDescription
<none>bytesbytes The encoded bytes for cloning

createOracle​

Creates a new oracle for a base/quote token pair

Creates an enabled oracle only after the initial cache write succeeds.

Reverts if:

  • The factory is disabled
  • The caller is not admin or oracle manager
  • Oracle creation is disabled
  • An oracle for (baseToken_, quoteToken_, maxAge_) already exists
  • Either token is the zero address or both tokens are the same
  • Service-specific validation in _encodeOracleData fails
  • Initial cache population fails in the configured price cache policy
function createOracle(address baseToken_, address quoteToken_, uint48 maxAge_, bytes calldata customParams_)
external
override
onlyEnabled
onlyOracleManagerOrAdminRole
nonReentrant
returns (address oracle);

Parameters

NameTypeDescription
baseToken_addressThe base token address
quoteToken_addressThe quote token address
maxAge_uint48The maximum age (in seconds) of cached prices used by the oracle
customParams_bytesService-specific custom parameters (can be empty)

Returns

NameTypeDescription
oracleaddressThe address of the created oracle

getOracle​

Gets the oracle address for a base/quote token pair

Does not revert.

function getOracle(address baseToken_, address quoteToken_, uint48 maxAge_)
external
view
override
returns (address oracle);

Parameters

NameTypeDescription
baseToken_addressThe base token address
quoteToken_addressThe quote token address
maxAge_uint48The maximum age (in seconds) of cached prices used by the oracle

Returns

NameTypeDescription
oracleaddressThe address of the oracle, or address(0) if not found

getPriceCache​

Gets the configured price cache policy

Does not revert.

function getPriceCache() external view override returns (address);

Returns

NameTypeDescription
<none>addresspolicy The price cache policy address

getOracles​

Gets all deployed oracle addresses

Does not revert.

function getOracles() external view override returns (address[] memory);

Returns

NameTypeDescription
<none>address[]oracles Array of all oracle addresses

enableCreation​

Enables oracle creation

Reverts if:

  • The factory is disabled
  • The caller is not admin or oracle manager
  • Creation is already enabled
function enableCreation() external override onlyEnabled onlyOracleManagerOrAdminRole nonReentrant;

disableCreation​

Disables oracle creation

Reverts if:

  • The factory is disabled
  • The caller is not admin, oracle manager, or emergency
  • Creation is already disabled
function disableCreation() external override onlyEnabled onlyOracleManagerOrAdminOrEmergencyRole nonReentrant;

setPriceCache​

Sets the configured price cache policy

Reverts if:

  • The factory is disabled
  • The caller is not admin
  • policy_ is zero, not IPriceCache-compatible, or bound to a different Kernel
function setPriceCache(address policy_) external override onlyEnabled onlyAdminRole nonReentrant;

Parameters

NameTypeDescription
policy_addressThe price cache policy address

enableOracle​

Enables a specific oracle

Refreshes the oracle pair cache if stale before marking the oracle enabled.

Reverts if:

  • The caller does not have the required role
  • The contract is disabled
  • The oracle is not created by the factory
  • The oracle is already enabled
function enableOracle(address oracle_) external override onlyEnabled onlyOracleManagerOrAdminRole nonReentrant;

Parameters

NameTypeDescription
oracle_addressThe oracle address to enable

disableOracle​

Disables a specific oracle

Decrements the enabled variant count for the oracle pair so factory-level re-enable skips the pair when no enabled variants remain.

Reverts if:

  • The caller does not have the required role
  • The contract is disabled
  • The oracle is not created by the factory
  • The oracle is already disabled
function disableOracle(address oracle_)
external
override
onlyEnabled
onlyOracleManagerOrAdminOrEmergencyRole
nonReentrant;

Parameters

NameTypeDescription
oracle_addressThe oracle address to disable

isOracleEnabled​

Checks if a specific oracle is enabled

Reverts if:

  • The policy is deactivated in Kernel Determines if a given oracle is enabled, using the following logic:
  • Factory must be enabled
  • Oracle must be created by the factory
  • Oracle must be enabled
function isOracleEnabled(address oracle_) external view override onlyPolicyActive returns (bool);

Parameters

NameTypeDescription
oracle_addressThe oracle address to check

Returns

NameTypeDescription
<none>boolenabled True if the oracle is enabled, false otherwise

getOracleContext​

Checks if a factory-created oracle is enabled and returns the configured price cache

Reverts if:

  • The policy is deactivated in Kernel
  • oracle_ was not created by this factory
function getOracleContext(address oracle_)
external
view
override
onlyPolicyActive
returns (bool enabled, address policy);

Parameters

NameTypeDescription
oracle_addressThe oracle address to check

Returns

NameTypeDescription
enabledboolTrue if the oracle is enabled, false otherwise
policyaddressThe configured price cache policy address

cachePrice​

Caches the provided base/quote pair

Reverts if:

  • The policy is deactivated in Kernel
  • The factory is disabled
  • The caller is not a factory-created oracle
  • The caller oracle is disabled
  • (baseToken_, quoteToken_) does not match the caller oracle pair
  • Underlying cache write fails
function cachePrice(address baseToken_, address quoteToken_)
external
override
onlyPolicyActive
onlyEnabled
nonReentrant;

Parameters

NameTypeDescription
baseToken_addressThe base token address
quoteToken_addressThe quote token address

cachePriceIfNecessary​

Caches the provided base/quote pair only when stale

Reverts if:

  • The policy is deactivated in Kernel
  • The factory is disabled
  • The caller is not a factory-created oracle
  • The caller oracle is disabled
  • (baseToken_, quoteToken_) does not match the caller oracle pair
  • Underlying cache evaluation/write fails
function cachePriceIfNecessary(address baseToken_, address quoteToken_)
external
override
onlyPolicyActive
onlyEnabled
nonReentrant;

Parameters

NameTypeDescription
baseToken_addressThe base token address
quoteToken_addressThe quote token address

_cacheOraclePrices​

Caches prices for the configured oracle token pair

function _cacheOraclePrices(address oracle_) internal;

Parameters

NameTypeDescription
oracle_addressThe oracle whose base/quote tokens should be cached

_cachePriceIfNecessary​

Conditionally caches prices for the token pair based on direct pair staleness

function _cachePriceIfNecessary(address oracle_, address baseToken_, address quoteToken_) internal;

_enable​

Implementation-specific enable function

_enable optionally re-caches caller-specified direct pairs from enableData_ before the factory-level isEnabled flag flips back to true. enableData_ can be empty for a no-op. Pairs with deployed variants are recached only when at least one variant is currently enabled; disabled oracles validate and refresh their own pair cache when individually re-enabled. When enableData_ is non-empty, it must encode: (address[] baseTokens, address[] quoteTokens). Reverts if enableData_ is non-empty and:

  • enableData_ cannot be decoded into (address[] baseTokens, address[] quoteTokens)
  • The decoded base and quote token arrays have different lengths
  • A requested pair has no deployed oracle variant for that exact ordering
  • The price cache rejects a requested pair that has an enabled oracle variant
function _enable(bytes calldata enableData_) internal virtual override;

Parameters

NameTypeDescription
enableData_bytesCustom data that can be used by the implementation. The format of this data is left to the discretion of the implementation.

_hasOracleVariant​

Returns whether the factory has a deployed oracle for the provided pair.

function _hasOracleVariant(bytes32 pairKey_) internal view returns (bool);

_hasEnabledOracleVariant​

Returns whether the factory has an enabled oracle for the provided pair.

function _hasEnabledOracleVariant(bytes32 pairKey_) internal view returns (bool);

_oraclePairKey​

Returns the storage key for an ordered oracle base/quote pair.

function _oraclePairKey(address baseToken_, address quoteToken_) internal pure returns (bytes32);

_setPriceCache​

function _setPriceCache(address policy_) internal;

_implementsIPriceCache​

function _implementsIPriceCache(address policy_) internal view returns (bool);

_hasSameKernel​

function _hasSameKernel(address policy_) internal view returns (bool);

_validateCachingCaller​

function _validateCachingCaller(address caller_) internal view;

_validateCachingPair​

function _validateCachingPair(address caller_, address baseToken_, address quoteToken_) internal view;

supportsInterface​

Query if a contract implements an interface

Does not revert.

function supportsInterface(bytes4 interfaceId_) public view virtual override 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