ERC7726OracleFactory
Inherits: Policy, PolicyEnabler, IERC7726OracleFactory, IVersioned, ReentrancyGuard
Title: ERC7726OracleFactory
Author: OlympusDAO
Factory for deploying generic ERC7726 clone oracles keyed by maxAge
Constants
_ROLES_KEYCODE
bytes5 internal constant _ROLES_KEYCODE = "ROLES";
ORACLE_IMPLEMENTATION
Reference implementation for cloning
ERC7726OracleCloneable public immutable ORACLE_IMPLEMENTATION;
_DEFAULT_ORACLE_NAME
bytes32 internal constant _DEFAULT_ORACLE_NAME = "ERC7726 Oracle";
State Variables
priceCache
The pair cache policy
IPriceCache public priceCache;
isCreationEnabled
Whether new oracle creation is enabled
bool public isCreationEnabled;
_oracles
Internal array of all deployed oracles
address[] internal _oracles;
_enabledOracleCount
Number of deployed oracles that are currently enabled
Updated when oracles are created, enabled, or disabled. Factory-level re-enable recaching skips all requested pairs when this count is zero.
uint256 internal _enabledOracleCount;
_maxAgeToOracle
Mapping from maxAge to oracle
mapping(uint48 maxAge => address oracle) internal _maxAgeToOracle;
_oracleToMaxAge
Mapping from oracle to maxAge
mapping(address oracle => uint48 maxAge) internal _oracleToMaxAge;
isOracle
Mapping to validate deployed oracles
mapping(address oracle => bool) public isOracle;
_isOracleEnabled
Mapping to track if an oracle is enabled
mapping(address oracle => bool) internal _isOracleEnabled;
Functions
constructor
Constructs a new ERC7726OracleFactory
Reverts if priceCache_ is not a valid IPriceCache policy for this Kernel.
constructor(Kernel kernel_, address priceCache_) Policy(kernel_);
Parameters
| Name | Type | Description |
|---|---|---|
| kernel_ | Kernel | The Kernel address |
| priceCache_ | address | The 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
| Name | Type | Description |
|---|---|---|
| dependencies | Keycode[] | - 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
| Name | Type | Description |
|---|---|---|
| requests | Permissions[] | - Array of keycodes and function selectors for requested permissions. |
VERSION
Returns the version of the contract
Does not revert.
function VERSION() external pure override returns (uint8 major, uint8 minor);
Returns
| Name | Type | Description |
|---|---|---|
| major | uint8 | - Major version upgrade indicates breaking change to the interface. |
| minor | uint8 | - 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
function _onlyOracleManagerOrAdminRole() internal view;
_onlyOracleManagerOrAdminOrEmergencyRole
function _onlyOracleManagerOrAdminOrEmergencyRole() internal view;
onlyOracleManagerOrAdminRole
modifier onlyOracleManagerOrAdminRole();
onlyOracleManagerOrAdminOrEmergencyRole
modifier onlyOracleManagerOrAdminOrEmergencyRole();
createOracle
Creates a new oracle for a specific maxAge
Creates an enabled oracle and adds it to the factory-level re-enable recache count.
Reverts if:
- The factory is disabled
- The caller is not admin or oracle manager
- Oracle creation is disabled
- An oracle for
maxAge_already exists customParams_is non-empty and not exactly 32 bytes
function createOracle(
uint48 maxAge_,
bytes calldata customParams_
)
external
override
onlyEnabled
onlyOracleManagerOrAdminRole
nonReentrant
returns (address oracle);
Parameters
| Name | Type | Description |
|---|---|---|
| maxAge_ | uint48 | The maximum age (in seconds) of cached prices used by the oracle |
| customParams_ | bytes | Optional params for factory-specific customization |
Returns
| Name | Type | Description |
|---|---|---|
| oracle | address | The address of the created oracle |
getOracle
Gets the oracle address for a maxAge
Does not revert.
function getOracle(uint48 maxAge_) external view override returns (address oracle);
Parameters
| Name | Type | Description |
|---|---|---|
| maxAge_ | uint48 | The maximum age used by the oracle |
Returns
| Name | Type | Description |
|---|---|---|
| oracle | address | The oracle address, or address(0) if not found |
getOracles
Gets all deployed oracle addresses
Does not revert.
function getOracles() external view override returns (address[] memory oracles);
Returns
| Name | Type | Description |
|---|---|---|
| oracles | address[] | Array of all oracle addresses |
getPriceCache
Gets the configured price cache policy
Does not revert.
function getPriceCache() external view override returns (address policy);
Returns
| Name | Type | Description |
|---|---|---|
| policy | address | The price cache policy address |
enableCreation
Enables oracle creation
enableCreation() sets isCreationEnabled to true. It does not update the
enabled-oracle counter or perform recaching logic.
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
disableCreation() sets isCreationEnabled to false. It does not update the
enabled-oracle counter or perform recaching logic.
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
| Name | Type | Description |
|---|---|---|
| policy_ | address | The price cache policy address |
enableOracle
Enables a specific oracle
Reverts if:
- The factory is disabled
- The caller is not admin or oracle manager
oracle_is not a factory-created oracleoracle_is already enabled
function enableOracle(
address oracle_
) external override onlyEnabled onlyOracleManagerOrAdminRole nonReentrant;
Parameters
| Name | Type | Description |
|---|---|---|
| oracle_ | address | The oracle address to enable |
disableOracle
Disables a specific oracle
Reverts if:
- The factory is disabled
- The caller is not admin, oracle manager, or emergency
oracle_is not a factory-created oracleoracle_is already disabled
function disableOracle(
address oracle_
) external override onlyEnabled onlyOracleManagerOrAdminOrEmergencyRole nonReentrant;
Parameters
| Name | Type | Description |
|---|---|---|
| oracle_ | address | The oracle address to disable |
isOracleEnabled
Checks if a specific oracle is enabled
Reverts if the policy is deactivated in Kernel.
function isOracleEnabled(
address oracle_
) external view override onlyPolicyActive returns (bool enabled);
Parameters
| Name | Type | Description |
|---|---|---|
| oracle_ | address | The oracle address to check |
Returns
| Name | Type | Description |
|---|---|---|
| enabled | bool | 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
| Name | Type | Description |
|---|---|---|
| oracle_ | address | The oracle address to check |
Returns
| Name | Type | Description |
|---|---|---|
| enabled | bool | True if the oracle is enabled, false otherwise |
| policy | address | The configured price cache policy address |
cachePrice
Cache the direct pair unconditionally for the calling oracle
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
- Underlying cache write fails
function cachePrice(
address base_,
address quote_
) external override onlyPolicyActive onlyEnabled nonReentrant;
Parameters
| Name | Type | Description |
|---|---|---|
| base_ | address | The base asset to cache |
| quote_ | address | The quote asset to cache |
cachePriceIfNecessary
Cache the direct pair only when stale for the calling oracle's configured max age
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
- Underlying cache evaluation/write fails
function cachePriceIfNecessary(
address base_,
address quote_
) external override onlyPolicyActive onlyEnabled nonReentrant;
Parameters
| Name | Type | Description |
|---|---|---|
| base_ | address | The base asset to conditionally cache |
| quote_ | address | The quote asset to conditionally cache |
_enable
_enable optionally re-caches caller-specified pairs from enableData_ before
the factory-level isEnabled flag flips to true. enableData_ can be empty for
a no-op. Requested pairs are only recached when at least one ERC-7726 oracle
variant is enabled; otherwise all requested pairs are skipped because disabled
clones cannot request fresh cache writes until they are 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
- The price cache rejects a requested pair during recaching
function _enable(bytes calldata enableData_) internal override;
Parameters
| Name | Type | Description |
|---|---|---|
| enableData_ | bytes | Custom data that can be used by the implementation. The format of this data is left to the discretion of the implementation. |
_decodeOracleName
function _decodeOracleName(
bytes calldata customParams_
) internal pure returns (bytes32 oracleName);
Parameters
| Name | Type | Description |
|---|---|---|
| customParams_ | bytes |
Returns
| Name | Type | Description |
|---|---|---|
| oracleName | bytes32 |
_validateCachingCaller
function _validateCachingCaller(address caller_) internal view;
Parameters
| Name | Type | Description |
|---|---|---|
| caller_ | address |
_hasEnabledOracleVariant
function _hasEnabledOracleVariant() internal view returns (bool);
Returns
| Name | Type | Description |
|---|---|---|
| <none> | bool |
_setPriceCache
function _setPriceCache(address policy_) internal;
Parameters
| Name | Type | Description |
|---|---|---|
| policy_ | address |
_implementsIPriceCache
function _implementsIPriceCache(address policy_) internal view returns (bool);
Parameters
| Name | Type | Description |
|---|---|---|
| policy_ | address |
Returns
| Name | Type | Description |
|---|---|---|
| <none> | bool |
_hasSameKernel
function _hasSameKernel(address policy_) internal view returns (bool);
Parameters
| Name | Type | Description |
|---|---|---|
| policy_ | address |
Returns
| Name | Type | Description |
|---|---|---|
| <none> | bool |
supportsInterface
Query if a contract implements an interface
Does not revert.
function supportsInterface(bytes4 interfaceId_) public view override returns (bool);
Parameters
| Name | Type | Description |
|---|---|---|
| interfaceId_ | bytes4 | The interface identifier, as specified in ERC-165 |
Returns
| Name | Type | Description |
|---|---|---|
| <none> | bool | bool True if the contract implements interfaceId_ |