CommonOracleMiddleware
Inherits: ICommonOracleMiddleware, AccessControlDefaultAdminRules, ChainlinkOracle, PythOracle
This contract serves as a common base that must be implemented by other middleware contracts.
State Variables
ADMIN_ROLE
Gets the admin role's signature.
bytes32 public constant ADMIN_ROLE = keccak256("ADMIN_ROLE");
MIDDLEWARE_DECIMALS
The number of decimals for the returned price.
uint8 internal constant MIDDLEWARE_DECIMALS = 18;
_validationDelay
The delay (in seconds) between the moment an action is initiated and the timestamp of the price data used to validate that action.
uint256 internal _validationDelay = 24 seconds;
_lowLatencyDelay
The amount of time during which a low latency oracle price validation is available.
This value should be greater than or equal to _lowLatencyValidatorDeadline
of the USDN protocol.
uint16 internal _lowLatencyDelay = 20 minutes;
Functions
constructor
constructor(address pythContract, bytes32 pythFeedId, address chainlinkPriceFeed, uint256 chainlinkTimeElapsedLimit)
PythOracle(pythContract, pythFeedId)
ChainlinkOracle(chainlinkPriceFeed, chainlinkTimeElapsedLimit)
AccessControlDefaultAdminRules(0, msg.sender);
Parameters
Name | Type | Description |
---|---|---|
pythContract | address | Address of the Pyth contract. |
pythFeedId | bytes32 | The Pyth price feed ID for the asset. |
chainlinkPriceFeed | address | Address of the Chainlink price feed. |
chainlinkTimeElapsedLimit | uint256 | The duration after which a Chainlink price is considered stale. |
getDecimals
Gets the number of decimals for the price.
function getDecimals() external pure returns (uint8 decimals_);
Returns
Name | Type | Description |
---|---|---|
decimals_ | uint8 | The number of decimals. |
getValidationDelay
Gets the required delay (in seconds) between the moment an action is initiated and the timestamp of the price data used to validate that action.
function getValidationDelay() external view returns (uint256 delay_);
Returns
Name | Type | Description |
---|---|---|
delay_ | uint256 | The validation delay. |
getLowLatencyDelay
Gets The maximum amount of time (in seconds) after initiation during which a low-latency price oracle can be used for validation.
function getLowLatencyDelay() external view returns (uint16 delay_);
Returns
Name | Type | Description |
---|---|---|
delay_ | uint16 | The maximum delay for low-latency validation. |
validationCost
Returns the cost of one price validation for the given action (in native token).
function validationCost(bytes calldata data, Types.ProtocolAction) public view virtual returns (uint256 result_);
Parameters
Name | Type | Description |
---|---|---|
data | bytes | Price data for which to get the fee. |
<none> | Types.ProtocolAction |
Returns
Name | Type | Description |
---|---|---|
result_ | uint256 | cost_ The cost of one price validation (in native token). |
parseAndValidatePrice
Parse and validate data
and returns the corresponding price data.
The data format is specific to the middleware and is simply forwarded from the user transaction's calldata.
A fee amounting to exactly validationCost (with the same data
and action
) must be sent or the transaction
will revert.
function parseAndValidatePrice(bytes32, uint128 targetTimestamp, Types.ProtocolAction action, bytes calldata data)
public
payable
virtual
returns (PriceInfo memory price_);
Parameters
Name | Type | Description |
---|---|---|
<none> | bytes32 | |
targetTimestamp | uint128 | The target timestamp for validating the price data. For validation actions, this is the timestamp of the initiation. |
action | Types.ProtocolAction | Type of action for which the price is requested. The middleware may use this to alter the validation of the price or the returned price. |
data | bytes | The data to be used to communicate with oracles, the format varies from middleware to middleware and can be different depending on the action. |
Returns
Name | Type | Description |
---|---|---|
price_ | PriceInfo | result_ The price and timestamp as PriceInfo. |
setValidationDelay
Sets the validation delay (in seconds) between an action timestamp and the price data timestamp used to validate that action.
function setValidationDelay(uint256 newValidationDelay) external onlyRole(ADMIN_ROLE);
Parameters
Name | Type | Description |
---|---|---|
newValidationDelay | uint256 | The new validation delay. |
setChainlinkTimeElapsedLimit
Sets the elapsed time tolerated before we consider the price from Chainlink invalid.
function setChainlinkTimeElapsedLimit(uint256 newTimeElapsedLimit) external onlyRole(ADMIN_ROLE);
Parameters
Name | Type | Description |
---|---|---|
newTimeElapsedLimit | uint256 | The new time elapsed limit. |
setPythRecentPriceDelay
Sets the amount of time after which we do not consider a price as recent.
function setPythRecentPriceDelay(uint64 newDelay) external onlyRole(ADMIN_ROLE);
Parameters
Name | Type | Description |
---|---|---|
newDelay | uint64 | The maximum age of a price to be considered recent. |
setLowLatencyDelay
Sets the new low latency delay.
function setLowLatencyDelay(uint16 newLowLatencyDelay, IUsdnProtocol usdnProtocol) external onlyRole(ADMIN_ROLE);
Parameters
Name | Type | Description |
---|---|---|
newLowLatencyDelay | uint16 | The new low latency delay. |
usdnProtocol | IUsdnProtocol | The address of the USDN protocol. |
withdrawEther
Withdraws the ether balance of this contract.
This contract can receive funds but is not designed to hold them. So this function can be used if there's an error and funds remain after a call.
function withdrawEther(address to) external onlyRole(ADMIN_ROLE);
Parameters
Name | Type | Description |
---|---|---|
to | address | The address to send the ether to. |
_getLowLatencyPrice
Gets the price from the low-latency oracle.
function _getLowLatencyPrice(bytes calldata data, uint128 actionTimestamp, PriceAdjustment dir, uint128 targetLimit)
internal
virtual
returns (PriceInfo memory price_);
Parameters
Name | Type | Description |
---|---|---|
data | bytes | The signed price update data. |
actionTimestamp | uint128 | The timestamp of the action corresponding to the price. If zero, then we must accept all prices younger than the recent price delay. |
dir | PriceAdjustment | The direction for the low latency price adjustment. |
targetLimit | uint128 | The most recent timestamp a price can have (can be zero if actionTimestamp is zero). |
Returns
Name | Type | Description |
---|---|---|
price_ | PriceInfo | The price from the low-latency oracle, adjusted according to the price adjustment direction. |
_getInitiateActionPrice
Gets the price for an initiate
action of the protocol.
function _getInitiateActionPrice(bytes calldata data, PriceAdjustment dir)
internal
virtual
returns (PriceInfo memory price_);
Parameters
Name | Type | Description |
---|---|---|
data | bytes | The low latency data. |
dir | PriceAdjustment | The direction to adjust the price (when using a low latency price). |
Returns
Name | Type | Description |
---|---|---|
price_ | PriceInfo | The price to use for the user action. |
_getValidateActionPrice
Gets the price for a validate action of the protocol.
If the low latency delay is not exceeded, validate the price with the low-latency oracle(s).
Else, get the specified roundId on-chain price from Chainlink. In case of chainlink price,
we don't have a price adjustment, so both neutralPrice
and price
are equal.
function _getValidateActionPrice(bytes calldata data, uint128 targetTimestamp, PriceAdjustment dir)
internal
virtual
returns (PriceInfo memory price_);
Parameters
Name | Type | Description |
---|---|---|
data | bytes | An optional low-latency price update or a chainlink roundId (abi-encoded uint80). |
targetTimestamp | uint128 | The timestamp of the initiate action. |
dir | PriceAdjustment | The direction to adjust the price (when using a low latency price). |
Returns
Name | Type | Description |
---|---|---|
price_ | PriceInfo | The price to use for the user action. |
_getLiquidationPrice
Gets the price from the low-latency oracle.
function _getLiquidationPrice(bytes calldata data) internal virtual returns (PriceInfo memory price_);
Parameters
Name | Type | Description |
---|---|---|
data | bytes | The signed price update data. |
Returns
Name | Type | Description |
---|---|---|
price_ | PriceInfo | The low-latency oracle price. |
_validateChainlinkRoundId
Checks that the given round ID is valid and returns its corresponding price data.
Round IDs are not necessarily consecutive, so additional computing can be necessary to find the previous round ID.
function _validateChainlinkRoundId(uint128 targetLimit, uint80 roundId)
internal
view
returns (ChainlinkPriceInfo memory providedRoundPrice_);
Parameters
Name | Type | Description |
---|---|---|
targetLimit | uint128 | The timestamp of the initiate action + _lowLatencyDelay. |
roundId | uint80 | The round ID to validate. |
Returns
Name | Type | Description |
---|---|---|
providedRoundPrice_ | ChainlinkPriceInfo | The price data of the provided round ID. |
_isPythData
Checks if the passed calldata corresponds to a Pyth message.
function _isPythData(bytes calldata data) internal pure returns (bool isPythData_);
Parameters
Name | Type | Description |
---|---|---|
data | bytes | The calldata pointer to the message. |
Returns
Name | Type | Description |
---|---|---|
isPythData_ | bool | Whether the data is a valid Pyth message or not. |