Oracle contract
The Oracle
contract serves as an adapter between a Pool
instance and a third-party oracle provider such as Pragma or ChainLink. The oracle fetches the raw price for an asset from the oracle provider and validates this price according to the following criteria:
- number of price sources used to compute the price
- price staleness
- non-zero price
These criteria are based on the Pragma oracle provider feeds and may change as other providers are supported in the future.
The oracle then returns the raw price with a price validity flag (true, false) to the Pool
contract which then either consumes the price or pauses the pool.
Data Types
Vesu V2 defines a number of data types, called struct
in Cairo, that are reused across the different components. We here discuss the main types related to the Pool
contract.
OracleConfig
The OracleConfig
type contains all parameters relevant to the configuration of a specific asset's price feed.
pub struct OracleConfig {
pub pragma_key: felt252,
pub timeout: u64, // [seconds]
pub number_of_sources: u32, // [0, 255]
pub start_time_offset: u64, // [seconds]
pub time_window: u64, // [seconds]
pub aggregation_mode: AggregationMode,
}
AssetPrice
Note that the AssetPrice
is always returned in 18-decimals precision irrespective of the decimals used for the feed by the oracle provider.
The AssetPrice
type expresses a specific asset price, as returned by the respective oracle provider, and its validity flag, which is derived by the Oracle
itself based on the price's metadata.
pub struct AssetPrice {
pub value: u256,
pub is_valid: bool,
}
Storage
We here show the full storage of the Oracle
contract with inline docs.
struct Storage {
#[substorage(v0)]
ownable: OwnableComponent::Storage,
// The address of the pragma oracle contract
pragma_oracle: ContractAddress,
// The address of the pragma summary contract
pragma_summary: ContractAddress,
// asset -> oracle configuration
oracle_configs: Map<ContractAddress, OracleConfig>,
// The owner of the pool
curator: ContractAddress,
// The pending curator
pending_curator: ContractAddress,
}
Price Function
Make sure that all configured price feeds return an AssetPrice
that is denominated in the same base asset, e.g. USD, or you risk inconsistent valuation of Vesu positions and unintended liquidations or bad debt as a result.
The price
function is called by the Pool
contract upon every user interaction with a pool to compute the value of a position's collateral and debt.
/// Returns the current price for an asset and the validity status of the price.
/// The price can be invalid if price is too old (stale) or if the number of price sources is too low.
/// # Arguments
/// * `asset` - address of the asset
/// # Returns
/// * `AssetPrice` - latest price of the asset and its validity
fn price(self: @ContractState, asset: ContractAddress) -> AssetPrice
Owner Functions
Note that only the owner of the Oracle
has permission to use the below functions.
Add a new Asset Feed
To add a new asset price feed, use the add_asset
function:
/// Sets oracle config for an asset
/// # Arguments
/// * `asset` - address of the asset
/// * `oracle_config` - oracle configuration
fn add_asset(ref self: ContractState, asset: ContractAddress, oracle_config: OracleConfig)
Change Oracle Parameter
To change a specific parameter for an asset's price feed, use the set_oracle_parameter
function:
/// Sets a parameter for a given oracle configuration of an asset
/// # Arguments
/// * `asset` - address of the asset
/// * `parameter` - parameter name
/// * `value` - value of the parameter
fn set_oracle_parameter(ref self: ContractState, asset: ContractAddress, parameter: felt252, value: felt252)
Note, the following parameters can be changed:
pragma_key
timeout
number_of_sources
start_time_offset
time_window
- `aggregation_mode``