|
| 1 | +pub mod pyth; |
| 2 | +pub mod switchboard; |
| 3 | + |
| 4 | +use crate::pyth::get_pyth_price_unchecked; |
| 5 | +use crate::pyth::get_pyth_pull_price; |
| 6 | +use crate::pyth::get_pyth_pull_price_unchecked; |
| 7 | +use crate::switchboard::get_switchboard_price; |
| 8 | +use crate::switchboard::get_switchboard_price_on_demand; |
| 9 | +use crate::switchboard::get_switchboard_price_v2; |
| 10 | +use solana_program::{ |
| 11 | + account_info::AccountInfo, msg, program_error::ProgramError, sysvar::clock::Clock, |
| 12 | +}; |
| 13 | +use solend_sdk::error::LendingError; |
| 14 | +use solend_sdk::math::Decimal; |
| 15 | + |
| 16 | +pub enum OracleType { |
| 17 | + Pyth, |
| 18 | + Switchboard, |
| 19 | + PythPull, |
| 20 | + SbOnDemand, |
| 21 | +} |
| 22 | + |
| 23 | +pub fn get_oracle_type(oracle_info: &AccountInfo) -> Result<OracleType, ProgramError> { |
| 24 | + if *oracle_info.owner == pyth_mainnet::id() { |
| 25 | + return Ok(OracleType::Pyth); |
| 26 | + } else if *oracle_info.owner == pyth_pull_mainnet::id() { |
| 27 | + return Ok(OracleType::PythPull); |
| 28 | + } else if *oracle_info.owner == switchboard_v2_mainnet::id() { |
| 29 | + return Ok(OracleType::Switchboard); |
| 30 | + } else if *oracle_info.owner == switchboard_on_demand_mainnet::id() { |
| 31 | + return Ok(OracleType::SbOnDemand); |
| 32 | + } |
| 33 | + |
| 34 | + msg!( |
| 35 | + "Could not find oracle type for {:?} with owner {:?}", |
| 36 | + oracle_info.key, |
| 37 | + oracle_info.owner |
| 38 | + ); |
| 39 | + Err(LendingError::InvalidOracleConfig.into()) |
| 40 | +} |
| 41 | + |
| 42 | +pub fn get_single_price( |
| 43 | + oracle_account_info: &AccountInfo, |
| 44 | + clock: &Clock, |
| 45 | +) -> Result<(Decimal, Option<Decimal>), ProgramError> { |
| 46 | + match get_oracle_type(oracle_account_info)? { |
| 47 | + OracleType::Pyth => { |
| 48 | + let price = pyth::get_pyth_price(oracle_account_info, clock)?; |
| 49 | + Ok((price.0, Some(price.1))) |
| 50 | + } |
| 51 | + OracleType::PythPull => { |
| 52 | + let price = get_pyth_pull_price(oracle_account_info, clock)?; |
| 53 | + Ok((price.0, Some(price.1))) |
| 54 | + } |
| 55 | + OracleType::Switchboard => { |
| 56 | + let price = get_switchboard_price(oracle_account_info, clock)?; |
| 57 | + Ok((price, None)) |
| 58 | + } |
| 59 | + OracleType::SbOnDemand => { |
| 60 | + let price = get_switchboard_price(oracle_account_info, clock)?; |
| 61 | + Ok((price, None)) |
| 62 | + } |
| 63 | + } |
| 64 | +} |
| 65 | + |
| 66 | +pub fn get_single_price_unchecked( |
| 67 | + oracle_account_info: &AccountInfo, |
| 68 | + clock: &Clock, |
| 69 | +) -> Result<Decimal, ProgramError> { |
| 70 | + match get_oracle_type(oracle_account_info)? { |
| 71 | + OracleType::Pyth => get_pyth_price_unchecked(oracle_account_info), |
| 72 | + OracleType::PythPull => get_pyth_pull_price_unchecked(oracle_account_info), |
| 73 | + OracleType::Switchboard => get_switchboard_price_v2(oracle_account_info, clock, false), |
| 74 | + OracleType::SbOnDemand => get_switchboard_price_on_demand(oracle_account_info, clock, true), |
| 75 | + } |
| 76 | +} |
| 77 | + |
| 78 | +/// Mainnet program id for Switchboard v2. |
| 79 | +pub mod switchboard_v2_mainnet { |
| 80 | + solana_program::declare_id!("SW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64f"); |
| 81 | +} |
| 82 | + |
| 83 | +/// Devnet program id for Switchboard v2. |
| 84 | +pub mod switchboard_v2_devnet { |
| 85 | + solana_program::declare_id!("2TfB33aLaneQb5TNVwyDz3jSZXS6jdW2ARw1Dgf84XCG"); |
| 86 | +} |
| 87 | + |
| 88 | +/// Mainnet program id for Switchboard On-Demand Oracle. |
| 89 | +pub mod switchboard_on_demand_mainnet { |
| 90 | + solana_program::declare_id!("SBondMDrcV3K4kxZR1HNVT7osZxAHVHgYXL5Ze1oMUv"); |
| 91 | +} |
| 92 | + |
| 93 | +/// Devnet program id for Switchboard On-Demand Oracle. |
| 94 | +pub mod switchboard_on_demand_devnet { |
| 95 | + solana_program::declare_id!("SBondMDrcV3K4kxZR1HNVT7osZxAHVHgYXL5Ze1oMUv"); |
| 96 | +} |
| 97 | + |
| 98 | +/// Mainnet program id for pyth |
| 99 | +pub mod pyth_mainnet { |
| 100 | + solana_program::declare_id!("FsJ3A3u2vn5cTVofAjvy6y5kwABJAqYWpe4975bi2epH"); |
| 101 | +} |
| 102 | + |
| 103 | +/// Mainnet program id for pyth |
| 104 | +pub mod pyth_pull_mainnet { |
| 105 | + solana_program::declare_id!("rec5EKMGg6MxZYaMdyBfgwp4d5rB9T1VQH5pJv5LtFJ"); |
| 106 | +} |
0 commit comments