Skip to content

Commit 05fe19b

Browse files
0xripleysnope-financemgild
authored
Pull oracle support for pyth, switchboard (#187)
* upgrade * add receiver sdk dependency * impementing pyth pull oracle * rustfmt * clippy * added some account state * test example * test doesn't break for stupid reasons * fix tests * making get price function more generic * feat: switchboard on-demand, init deps * add body for parsing switchboard feeds * add body for parsing switchboard feeds * update to sdk 0.1.12 * fixing up sb on demand * adding range check for switchboard * pull oracle tests * switchboard test failing * fixing tests * fmt * update solana version * rust version * fixing other warnings * create oracle crate * minor cleanup * forgot to add fixtures * clip * oops * remove oracle ids from sdk * fmt --------- Co-authored-by: Nope X <[email protected]> Co-authored-by: Mitch Gildenberg <[email protected]>
1 parent 25e3985 commit 05fe19b

31 files changed

+3838
-1159
lines changed

Cargo.lock

Lines changed: 2539 additions & 783 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ members = [
44
"token-lending/program",
55
"token-lending/sdk",
66
"token-lending/brick"
7-
]
7+
, "token-lending/oracles"]
88

99
[profile.dev]
1010
split-debuginfo = "unpacked"
11+
12+
[profile.release]
13+
overflow-checks = true

ci/rust-version.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
if [[ -n $RUST_STABLE_VERSION ]]; then
1919
stable_version="$RUST_STABLE_VERSION"
2020
else
21-
stable_version=1.65.0
21+
stable_version=1.76.0
2222
fi
2323

2424
if [[ -n $RUST_NIGHTLY_VERSION ]]; then

ci/solana-version.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
if [[ -n $SOLANA_VERSION ]]; then
1515
solana_version="$SOLANA_VERSION"
1616
else
17-
solana_version=v1.14.10
17+
solana_version=v1.16.20
1818
fi
1919

2020
export solana_version="$solana_version"

token-lending/brick/Cargo.toml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,21 @@ no-entrypoint = []
1212
test-bpf = []
1313

1414
[dependencies]
15-
solana-program = "=1.14.10"
15+
solana-program = "=1.16.20"
1616

1717
[dev-dependencies]
1818
assert_matches = "1.5.0"
1919
bytemuck = "1.5.1"
2020
base64 = "0.13"
2121
log = "0.4.14"
2222
proptest = "1.0"
23-
solana-program-test = "=1.14.10"
24-
solana-sdk = "=1.14.10"
25-
serde = "=1.0.140"
23+
solana-program-test = "=1.16.20"
24+
solana-sdk = "=1.16.20"
25+
serde = "1.0.140"
2626
serde_yaml = "0.8"
2727
thiserror = "1.0"
2828
bincode = "1.3.3"
29-
borsh = "0.9.3"
29+
borsh = "0.10.3"
3030

3131
[lib]
3232
crate-type = ["cdylib", "lib"]

token-lending/oracles/Cargo.toml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
[package]
2+
name = "oracles"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7+
8+
[dependencies]
9+
pyth-sdk-solana = "0.8.0"
10+
pyth-solana-receiver-sdk = "0.3.0"
11+
solana-program = ">=1.9"
12+
anchor-lang = "0.28.0"
13+
solend-sdk = { path = "../sdk" }
14+
switchboard-on-demand = "0.1.12"
15+
switchboard-program = "0.2.0"
16+
switchboard-v2 = "0.1.3"
17+
18+
[dev-dependencies]
19+
bytemuck = "1.5.1"
20+
assert_matches = "1.5.0"
21+
base64 = "0.13"
22+
log = "0.4.14"
23+
proptest = "1.0"
24+
solana-sdk = ">=1.9"
25+
serde = "1.0.140"
26+
serde_yaml = "0.8"
27+
rand = "0.8.5"
Binary file not shown.
Binary file not shown.

token-lending/oracles/src/lib.rs

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
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

Comments
 (0)