IOracleGuard
Title: IOracleGuard
Authors: David Dada <daveproxy80@gmail.com> (https://github.com/dadadave80), Modified from Chainlink (https://docs.chain.link/data-feeds/l2-sequencer-feeds)
Interface for the OracleGuard Diamond facet: an opt-in guarded price read layered over any Lattice
price adapter that exposes the IPriceOracleReader latestAnswer(bytes32) read. It adds the two
checks the adapters leave to the integrator: the Chainlink L2 sequencer-uptime feed (with a grace
period after a restart) and per-key [min, max] sanity bounds on the WAD answer.
Integrators read prices through guardedAnswer instead of the adapter's latestAnswer. The guard
keeps its own storage and calls the configured oracle's latestAnswer, so the adapters' storage
and interfaceIds are untouched; every adapter check (staleness, round completeness, non-positive
answers) still runs, and its revert bubbles up unchanged. The oracle is either the guard's own
diamond (the guard cut next to the adapter, with OracleGuardInit run beside the adapter's init so
ERC-165 reports this interface) or another adapter diamond (the standalone DeployOracleGuard recipe).
Configuration is opt-in and fails closed once set:
- Sequencer check: skipped while the sequencer feed is
address(0)(L1 deployments). Once set, a read reverts unless the uptime feed answers0(up), itsstartedAtis non-zero (an Arbitrum uptime feed that was never initialized reports0), and more thangracePeriodseconds have passed sincestartedAt. - Keys: an unconfigured key reverts OracleGuardKeyNotConfigured rather than passing a price through unchecked.
- Bounds:
(0, 0)disables the bounds of a key. Otherwise the WAD answer must lie in[minAnswer, maxAnswer]. Bounds are never read from the aggregator, whoseminAnswer/maxAnswermost Chainlink feeds no longer use. A non-positive WAD answer always reverts, even with bounds disabled.
Functions
guardedAnswer
Returns the oracle's WAD answer for key after the sequencer and bounds checks.
Reverts with the oracle's own error when its checks fail, and with this interface's errors when the guard's checks fail.
function guardedAnswer(bytes32 key) external view returns (int256 answerWad);Parameters
| Name | Type | Description |
|---|---|---|
| key | bytes32 | The feed identifier. |
Returns
| Name | Type | Description |
|---|---|---|
| answerWad | int256 | The checked price scaled to 1e18. |
checkSequencerUptime
Reverts unless the sequencer is up and past its grace period. No-op while no feed is set.
For integrators that read something other than guardedAnswer (raw reads, TWAPs) on an L2.
function checkSequencerUptime() external view;getSequencerConfig
Returns the sequencer-uptime configuration.
function getSequencerConfig() external view returns (address sequencerFeed, uint48 gracePeriod);Returns
| Name | Type | Description |
|---|---|---|
| sequencerFeed | address | The uptime feed (address(0) when the check is disabled). |
| gracePeriod | uint48 | The grace period in seconds. |
getGuardedFeed
Returns the guard configuration of key.
function getGuardedFeed(bytes32 key) external view returns (address oracle, int256 minAnswer, int256 maxAnswer);Parameters
| Name | Type | Description |
|---|---|---|
| key | bytes32 | The feed identifier. |
Returns
| Name | Type | Description |
|---|---|---|
| oracle | address | The oracle read for key (address(0) when unconfigured). |
| minAnswer | int256 | Lowest accepted WAD answer. |
| maxAnswer | int256 | Highest accepted WAD answer. |
setSequencerConfig
Sets the Chainlink L2 sequencer-uptime feed and the grace period after a restart.
Caller must hold DEFAULT_ADMIN_ROLE. sequencerFeed == address(0) disables the check; a non-zero
feed requires a non-zero gracePeriod (Chainlink's example uses 3600 seconds).
function setSequencerConfig(address sequencerFeed, uint48 gracePeriod) external;Parameters
| Name | Type | Description |
|---|---|---|
| sequencerFeed | address | The uptime feed for this chain. |
| gracePeriod | uint48 | Seconds after a restart during which reads revert. |
setGuardedFeed
Configures key: the oracle to read and the accepted WAD range.
Caller must hold DEFAULT_ADMIN_ROLE. oracle must be non-zero. (0, 0) disables the bounds;
otherwise 0 <= minAnswer <= maxAnswer.
function setGuardedFeed(bytes32 key, address oracle, int256 minAnswer, int256 maxAnswer) external;Parameters
| Name | Type | Description |
|---|---|---|
| key | bytes32 | The feed identifier, passed through to the oracle's latestAnswer(key). |
| oracle | address | The adapter (or adapter diamond) to read; the guard's own diamond when co-cut. |
| minAnswer | int256 | Lowest accepted WAD answer. |
| maxAnswer | int256 | Highest accepted WAD answer. |
removeGuardedFeed
Removes the guard configuration of key; guardedAnswer then reverts for it.
Caller must hold DEFAULT_ADMIN_ROLE.
function removeGuardedFeed(bytes32 key) external;Parameters
| Name | Type | Description |
|---|---|---|
| key | bytes32 | The feed identifier. |
Events
SequencerConfigSet
Emitted when the sequencer-uptime configuration is set.
event SequencerConfigSet(address indexed sequencerFeed, uint48 gracePeriod);Parameters
| Name | Type | Description |
|---|---|---|
| sequencerFeed | address | The Chainlink L2 sequencer-uptime feed (address(0) disables the check). |
| gracePeriod | uint48 | Seconds after a sequencer restart during which reads revert. |
GuardedFeedSet
Emitted when a guarded key is configured or reconfigured.
event GuardedFeedSet(bytes32 indexed key, address oracle, int256 minAnswer, int256 maxAnswer);Parameters
| Name | Type | Description |
|---|---|---|
| key | bytes32 | The feed identifier, shared with the oracle's latestAnswer(key). |
| oracle | address | The adapter (or adapter diamond) read for key. |
| minAnswer | int256 | Lowest accepted WAD answer. |
| maxAnswer | int256 | Highest accepted WAD answer ((0, 0) disables the bounds). |
GuardedFeedRemoved
Emitted when a guarded key is removed.
event GuardedFeedRemoved(bytes32 indexed key);Parameters
| Name | Type | Description |
|---|---|---|
| key | bytes32 | The removed feed identifier. |
Errors
OracleGuardKeyNotConfigured
The key has no guard configuration.
error OracleGuardKeyNotConfigured(bytes32 key);Parameters
| Name | Type | Description |
|---|---|---|
| key | bytes32 | The feed identifier. |
OracleGuardSequencerDown
The uptime feed reports the sequencer down (status != 0) or uninitialized (startedAt == 0).
error OracleGuardSequencerDown(int256 status, uint256 startedAt);Parameters
| Name | Type | Description |
|---|---|---|
| status | int256 | The uptime feed's answer (0 = up, 1 = down). |
| startedAt | uint256 | The uptime feed's startedAt. |
OracleGuardGracePeriodNotOver
The sequencer came back up no more than gracePeriod seconds ago (or startedAt is in the future).
error OracleGuardGracePeriodNotOver(uint256 startedAt, uint256 gracePeriod);Parameters
| Name | Type | Description |
|---|---|---|
| startedAt | uint256 | When the sequencer's current status began. |
| gracePeriod | uint256 | The configured grace period in seconds. |
OracleGuardInvalidAnswer
The oracle returned a non-positive WAD answer.
error OracleGuardInvalidAnswer(bytes32 key, int256 answerWad);Parameters
| Name | Type | Description |
|---|---|---|
| key | bytes32 | The feed identifier. |
| answerWad | int256 | The rejected answer. |
OracleGuardAnswerOutOfBounds
The WAD answer is outside the key's configured bounds.
error OracleGuardAnswerOutOfBounds(bytes32 key, int256 answerWad, int256 minAnswer, int256 maxAnswer);Parameters
| Name | Type | Description |
|---|---|---|
| key | bytes32 | The feed identifier. |
| answerWad | int256 | The rejected answer. |
| minAnswer | int256 | The configured lower bound. |
| maxAnswer | int256 | The configured upper bound. |
OracleGuardInvalidConfig
A setter was called with an invalid parameter: a zero oracle, negative or inverted bounds, or a sequencer feed with a zero grace period.
error OracleGuardInvalidConfig();