Skip to content

Commit

Permalink
feat: switch to use Pragma Cairo 1 contract (#66)
Browse files Browse the repository at this point in the history
  • Loading branch information
xJonathanLEI authored Jan 25, 2024
1 parent 10dfb3d commit bad002b
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 33 deletions.
20 changes: 14 additions & 6 deletions src/interfaces.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ trait IInterestRateModel<TContractState> {

#[starknet::interface]
trait IPragmaOracle<TContractState> {
fn get_spot_median(self: @TContractState, pair_id: felt252) -> PragmaOracleSpotMedian;
fn get_data_median(self: @TContractState, data_type: PragmaDataType) -> PragmaPricesResponse;
}

#[starknet::interface]
Expand Down Expand Up @@ -308,9 +308,17 @@ struct PriceWithUpdateTime {
}

#[derive(Drop, Serde)]
struct PragmaOracleSpotMedian {
price: felt252,
decimals: felt252,
last_updated_timestamp: felt252,
num_sources_aggregated: felt252
enum PragmaDataType {
SpotEntry: felt252,
FutureEntry: (felt252, u64),
GenericEntry: felt252,
}

#[derive(Drop, Serde)]
struct PragmaPricesResponse {
price: u128,
decimals: u32,
last_updated_timestamp: u64,
num_sources_aggregated: u32,
expiration_timestamp: Option<u64>,
}
19 changes: 8 additions & 11 deletions src/oracles/pragma_oracle_adapter.cairo
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
mod errors {
const INVALID_TIMESTAMP: felt252 = 'PRAGMA_INVALID_TIMESTAMP';
const STALED_PRICE: felt252 = 'PRAGMA_STALED_PRICE';
const ZERO_PRICE: felt252 = 'PRAGMA_ZERO_PRICE';
}
Expand All @@ -16,8 +15,8 @@ mod PragmaOracleAdapter {
use super::super::super as crate;

use crate::interfaces::{
IPragmaOracleDispatcher, IPragmaOracleDispatcherTrait, IPriceOracleSource,
PragmaOracleSpotMedian, PriceWithUpdateTime
IPragmaOracleDispatcher, IPragmaOracleDispatcherTrait, IPriceOracleSource, PragmaDataType,
PragmaPricesResponse, PriceWithUpdateTime
};
use crate::libraries::{pow, safe_math};

Expand Down Expand Up @@ -58,26 +57,24 @@ mod PragmaOracleAdapter {

let median = IPragmaOracleDispatcher {
contract_address: oracle_addr
}.get_spot_median(pair_key);
}.get_data_median(PragmaDataType::SpotEntry(pair_key));
assert(median.price != 0, errors::ZERO_PRICE);

// Block times are usually behind real world time by a bit. It's possible that the reported
// last updated timestamp is in the (very near) future.
let block_time: u64 = get_block_timestamp();
let last_updated_timestamp: u64 = median
.last_updated_timestamp
.try_into()
.expect(errors::INVALID_TIMESTAMP);

let time_elasped: u64 = match u64_checked_sub(block_time, last_updated_timestamp) {
let time_elasped: u64 = match u64_checked_sub(block_time, median.last_updated_timestamp) {
Option::Some(value) => value,
Option::None => 0,
};
let timeout = self.timeout.read();
assert(time_elasped <= timeout, errors::STALED_PRICE);

let scaled_price = scale_price(median.price, median.decimals);
PriceWithUpdateTime { price: scaled_price, update_time: median.last_updated_timestamp }
let scaled_price = scale_price(median.price.into(), median.decimals.into());
PriceWithUpdateTime {
price: scaled_price, update_time: median.last_updated_timestamp.into()
}
}

fn scale_price(price: felt252, decimals: felt252) -> felt252 {
Expand Down
8 changes: 4 additions & 4 deletions tests/mock.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -196,10 +196,10 @@ trait IMockPragmaOracle<TContractState> {
fn set_price(
ref self: TContractState,
pair_id: felt252,
price: felt252,
decimals: felt252,
last_updated_timestamp: felt252,
num_sources_aggregated: felt252
price: u128,
decimals: u32,
last_updated_timestamp: u64,
num_sources_aggregated: u32
);
}

Expand Down
27 changes: 15 additions & 12 deletions tests/mock/mock_pragma_oracle.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,30 @@
mod MockPragmaOracle {
use starknet::ContractAddress;

use zklend::interfaces::{IPragmaOracle, PragmaOracleSpotMedian};
use zklend::interfaces::{IPragmaOracle, PragmaDataType, PragmaPricesResponse};

use super::super::IMockPragmaOracle;

#[storage]
struct Storage {
pair_id: felt252,
price: felt252,
decimals: felt252,
last_updated_timestamp: felt252,
num_sources_aggregated: felt252
price: u128,
decimals: u32,
last_updated_timestamp: u64,
num_sources_aggregated: u32
}

#[external(v0)]
impl IPragmaOracleImpl of IPragmaOracle<ContractState> {
fn get_spot_median(self: @ContractState, pair_id: felt252) -> PragmaOracleSpotMedian {
PragmaOracleSpotMedian {
fn get_data_median(
self: @ContractState, data_type: PragmaDataType
) -> PragmaPricesResponse {
PragmaPricesResponse {
price: self.price.read(),
decimals: self.decimals.read(),
last_updated_timestamp: self.last_updated_timestamp.read(),
num_sources_aggregated: self.num_sources_aggregated.read()
num_sources_aggregated: self.num_sources_aggregated.read(),
expiration_timestamp: Option::None,
}
}
}
Expand All @@ -32,10 +35,10 @@ mod MockPragmaOracle {
fn set_price(
ref self: ContractState,
pair_id: felt252,
price: felt252,
decimals: felt252,
last_updated_timestamp: felt252,
num_sources_aggregated: felt252
price: u128,
decimals: u32,
last_updated_timestamp: u64,
num_sources_aggregated: u32
) {
self.pair_id.write(pair_id);
self.price.write(price);
Expand Down

0 comments on commit bad002b

Please sign in to comment.