Skip to content

Commit

Permalink
Simplify stuff
Browse files Browse the repository at this point in the history
t# Please enter the commit message for your changes. Lines starting
  • Loading branch information
DaSichuan committed Feb 26, 2022
1 parent 7b4be89 commit a62dead
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 53 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions token-lending/program/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ spl-token = { version = "3.2.0", features=["no-entrypoint"] }
switchboard-program = "0.2.0"
thiserror = "1.0"
uint = "=0.9.0"
serde = "1.0"
serde_derive = "1.0"
serde_json = "1.0"

[dev-dependencies]
assert_matches = "1.5.0"
Expand Down
3 changes: 3 additions & 0 deletions token-lending/program/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ pub mod state;
// Export current sdk types for downstream users building with a different sdk version
pub use solana_program;

#[macro_use]
extern crate serde_derive;

solana_program::declare_id!("So1endDq2YkqhipRh3WViPa8hdiSpxWy6z3Z6tMCpAo");

/// Canonical null pubkey. Prints out as "nu11111111111111111111111111111111111111111"
Expand Down
61 changes: 29 additions & 32 deletions token-lending/program/src/logs.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
#![allow(missing_docs)]
use crate::math::Decimal;
use solana_program::{msg, pubkey::Pubkey};
use solana_program::pubkey::Pubkey;
use std::fmt;

#[derive(Debug)]
enum LogEventType {
extern crate serde;
extern crate serde_json;

#[derive(Debug, Serialize)]
pub enum LogEventType {
PythOraclePriceUpdateType,
PythErrorType,
SwitchboardV1OraclePriceUpdateType,
SwitchboardErrorType,
}

impl fmt::Display for LogEventType {
Expand All @@ -15,49 +20,41 @@ impl fmt::Display for LogEventType {
}
}

pub fn emit_log_event(e: &dyn LogEvent) {
msg!("Solend Log Event");
msg!(&e.to_string());
}

pub trait LogEvent {
fn to_string(&self) -> String;
#[macro_export]
macro_rules! emit_log_event {
($e:expr) => {
msg!("solend-event-log");
msg!(&serde_json::to_string($e).unwrap());
};
}

#[derive(Serialize)]
pub struct PythOraclePriceUpdate {
pub event_type: LogEventType,
pub oracle_pubkey: Pubkey,
pub price: Decimal,
pub conf: u64,
pub confidence: u64,
pub published_slot: u64,
}

impl LogEvent for PythOraclePriceUpdate {
fn to_string(&self) -> String {
return format!(
"{},{},{},{},{}",
LogEventType::PythOraclePriceUpdateType.to_string(),
self.oracle_pubkey.to_string(),
self.price.to_string(),
self.conf.to_string(),
self.published_slot,
);
}
#[derive(Serialize)]
pub struct PythError {
pub event_type: LogEventType,
pub oracle_pubkey: Pubkey,
pub error_message: String,
}

#[derive(Serialize)]
pub struct SwitchboardV1OraclePriceUpdate {
pub event_type: LogEventType,
pub oracle_pubkey: Pubkey,
pub price: Decimal,
pub published_slot: u64,
}

impl LogEvent for SwitchboardV1OraclePriceUpdate {
fn to_string(&self) -> String {
return format!(
"{},{},{},{}",
LogEventType::SwitchboardV1OraclePriceUpdateType.to_string(),
self.oracle_pubkey.to_string(),
self.price.to_string(),
self.published_slot,
);
}
#[derive(Serialize)]
pub struct SwitchboardError {
pub event_type: LogEventType,
pub oracle_pubkey: Pubkey,
pub error_message: String,
}
3 changes: 2 additions & 1 deletion token-lending/program/src/math/decimal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,12 @@ use uint::construct_uint;

// U192 with 192 bits consisting of 3 x 64-bit words
construct_uint! {
#[derive(Serialize)]
pub struct U192(3);
}

/// Large decimal values, precise to 18 digits
#[derive(Clone, Copy, Debug, Default, PartialEq, PartialOrd, Eq, Ord)]
#[derive(Clone, Copy, Debug, Default, PartialEq, PartialOrd, Eq, Ord, Serialize)]
pub struct Decimal(pub U192);

impl Decimal {
Expand Down
72 changes: 53 additions & 19 deletions token-lending/program/src/processor.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
//! Program state processor

use crate::{
self as spl_token_lending,
self as spl_token_lending, emit_log_event,
error::LendingError,
instruction::LendingInstruction,
logs::{emit_log_event, PythOraclePriceUpdate, SwitchboardV1OraclePriceUpdate},
logs::{
LogEventType, PythError, PythOraclePriceUpdate, SwitchboardError,
SwitchboardV1OraclePriceUpdate,
},
math::{Decimal, Rate, TryAdd, TryDiv, TryMul, TrySub, WAD},
pyth,
state::{
Expand Down Expand Up @@ -2153,15 +2156,24 @@ fn get_pyth_price(pyth_price_info: &AccountInfo, clock: &Clock) -> Result<Decima
.map_err(|_| ProgramError::InvalidAccountData)?;

if pyth_price.ptype != pyth::PriceType::Price {
msg!("Oracle price type is invalid {}", pyth_price.ptype as u8);
emit_log_event!(&PythError {
event_type: LogEventType::PythOraclePriceUpdateType,
oracle_pubkey: *pyth_price_info.key,
error_message: format!("Oracle price type is invalid: {}", pyth_price.ptype as u8),
});

return Err(LendingError::InvalidOracleConfig.into());
}

if pyth_price.agg.status != pyth::PriceStatus::Trading {
msg!(
"Oracle price status is invalid: {}",
pyth_price.agg.status as u8
);
emit_log_event!(&PythError {
event_type: LogEventType::PythOraclePriceUpdateType,
oracle_pubkey: *pyth_price_info.key,
error_message: format!(
"Oracle price status is invalid: {}",
pyth_price.agg.status as u8
),
});
return Err(LendingError::InvalidOracleConfig.into());
}

Expand All @@ -2170,12 +2182,20 @@ fn get_pyth_price(pyth_price_info: &AccountInfo, clock: &Clock) -> Result<Decima
.checked_sub(pyth_price.valid_slot)
.ok_or(LendingError::MathOverflow)?;
if slots_elapsed >= STALE_AFTER_SLOTS_ELAPSED {
msg!("Pyth oracle price is stale");
emit_log_event!(&PythError {
event_type: LogEventType::PythOraclePriceUpdateType,
oracle_pubkey: *pyth_price_info.key,
error_message: format!("Pyth oracle price is stale: {} slots old.", slots_elapsed),
});
return Err(LendingError::InvalidOracleConfig.into());
}

let price: u64 = pyth_price.agg.price.try_into().map_err(|_| {
msg!("Oracle price cannot be negative");
emit_log_event!(&PythError {
event_type: LogEventType::PythOraclePriceUpdateType,
oracle_pubkey: *pyth_price_info.key,
error_message: "Oracle price cannot be negative".to_string(),
});
LendingError::InvalidOracleConfig
})?;

Expand All @@ -2186,11 +2206,15 @@ fn get_pyth_price(pyth_price_info: &AccountInfo, clock: &Clock) -> Result<Decima
// 100/confidence_ratio = maximum size of confidence range as a percent of price
// confidence_ratio of 10 filters out pyth prices with conf > 10% of price
if conf.checked_mul(confidence_ratio).unwrap() > price {
msg!(
"Oracle price confidence is too wide. price: {}, conf: {}",
price,
conf,
);
emit_log_event!(&PythError {
event_type: LogEventType::PythOraclePriceUpdateType,
oracle_pubkey: *pyth_price_info.key,
error_message: format!(
"Oracle price confidence is too wide. price: {}, conf: {}",
price, conf
),
});

return Err(LendingError::InvalidOracleConfig.into());
}

Expand All @@ -2215,10 +2239,11 @@ fn get_pyth_price(pyth_price_info: &AccountInfo, clock: &Clock) -> Result<Decima
.ok_or(LendingError::MathOverflow)?;
Decimal::from(price).try_div(decimals)?
};
emit_log_event(&PythOraclePriceUpdate {
emit_log_event!(&PythOraclePriceUpdate {
event_type: LogEventType::PythOraclePriceUpdateType,
oracle_pubkey: *pyth_price_info.key,
price: market_price,
conf: conf,
confidence: conf,
published_slot: pyth_price.valid_slot,
});

Expand All @@ -2238,7 +2263,11 @@ fn get_switchboard_price(
let account_buf = switchboard_feed_info.try_borrow_data()?;
// first byte type discriminator
if account_buf[0] != SwitchboardAccountType::TYPE_AGGREGATOR as u8 {
msg!("switchboard address not of type aggregator");
emit_log_event!(&SwitchboardError {
event_type: LogEventType::SwitchboardErrorType,
oracle_pubkey: *switchboard_feed_info.key,
error_message: "Switchboard feed is not of type aggregator".to_string(),
});
return Err(LendingError::InvalidAccountInput.into());
}

Expand All @@ -2254,7 +2283,11 @@ fn get_switchboard_price(
.checked_sub(open_slot)
.ok_or(LendingError::MathOverflow)?;
if slots_elapsed >= STALE_AFTER_SLOTS_ELAPSED {
msg!("Switchboard oracle price is stale");
emit_log_event!(&SwitchboardError {
event_type: LogEventType::SwitchboardErrorType,
oracle_pubkey: *switchboard_feed_info.key,
error_message: format!("Oracle price is stale by {} slots", slots_elapsed),
});
return Err(LendingError::InvalidOracleConfig.into());
}

Expand All @@ -2266,7 +2299,8 @@ fn get_switchboard_price(
let price = ((price_quotient as f64) * price_float) as u128;

let market_price = Decimal::from(price).try_div(price_quotient)?;
emit_log_event(&SwitchboardV1OraclePriceUpdate {
emit_log_event!(&SwitchboardV1OraclePriceUpdate {
event_type: LogEventType::SwitchboardV1OraclePriceUpdateType,
oracle_pubkey: *switchboard_feed_info.key,
price: market_price,
published_slot: open_slot,
Expand Down
2 changes: 1 addition & 1 deletion token-lending/program/tests/refresh_reserve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ async fn test_success() {
);

// limit to track compute unit increase
test.set_bpf_compute_max_units(16_000);
test.set_bpf_compute_max_units(24_000);

const SOL_RESERVE_LIQUIDITY_LAMPORTS: u64 = 100 * LAMPORTS_TO_SOL;
const USDC_RESERVE_LIQUIDITY_FRACTIONAL: u64 = 100 * FRACTIONAL_TO_USDC;
Expand Down

0 comments on commit a62dead

Please sign in to comment.