Skip to content

Commit bac6e6a

Browse files
authored
Merge pull request #108 from lastemp/update-example-sol-anchor-contract
Update example sol-anchor-contract #107
2 parents ecbe342 + 4585659 commit bac6e6a

File tree

12 files changed

+166
-3153
lines changed

12 files changed

+166
-3153
lines changed
-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
yarn.lock
2-
Cargo.lock
32
.anchor
43
.DS_Store
54
target
65
**/*.rs.bk
76
node_modules
87
test-ledger
9-
program_address.json
+21-6
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,25 @@
1-
[programs.devnet]
2-
example_sol_anchor_contract = "BZh3CP454Ca1C9yBp2tpGAkXoKFti9x8ShJLSxNDpoxa"
3-
41
[provider]
5-
cluster = "devnet"
2+
cluster = "localnet"
63
wallet = "~/.config/solana/id.json"
74

5+
[programs.localnet]
6+
sol_anchor_contract = "GFPM2LncpbWiLkePLs3QjcLVPw31B2h23FwFfhig79fh"
7+
88
[scripts]
9-
install = "npm install"
10-
test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 scripts/test.ts"
9+
test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts"
10+
11+
[test]
12+
startup_wait = 20000
13+
14+
[[test.genesis]]
15+
address = "GFPM2LncpbWiLkePLs3QjcLVPw31B2h23FwFfhig79fh"
16+
program = "./target/deploy/sol_anchor_contract.so"
17+
18+
[test.validator]
19+
url = "https://api.devnet.solana.com"
20+
21+
[[test.validator.clone]]
22+
address = "EdVCmQ9FSPcVe5YySXDPCRmc8aDQLKJ9xvYBMZPie1Vw"
23+
24+
[[test.validator.clone]]
25+
address = "38xoQ4oeJCBrcVvca2cGk7iV1dAfrmTR1kmhSCJQ8Jto"

examples/sol-anchor-contract/package-lock.json

-2,998
This file was deleted.

examples/sol-anchor-contract/package.json

+9-7
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,16 @@
44
"lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check"
55
},
66
"dependencies": {
7-
"@project-serum/anchor": "^0.25.0",
7+
"@coral-xyz/anchor": "^0.27.0"
8+
},
9+
"devDependencies": {
10+
"chai": "^4.3.7",
11+
"mocha": "^9.2.2",
12+
"ts-mocha": "^10.0.0",
813
"@types/bn.js": "^5.1.1",
9-
"@types/chai": "^4.3.3",
14+
"@types/chai": "^4.3.5",
1015
"@types/mocha": "^9.1.1",
11-
"chai": "^4.3.6",
12-
"mocha": "^10.1.0",
13-
"prettier": "^2.7.1",
14-
"ts-mocha": "^10.0.0",
15-
"typescript": "^4.8.4"
16+
"typescript": "^4.9.5",
17+
"prettier": "^2.8.8"
1618
}
1719
}
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
[package]
2-
name = "example-sol-anchor-contract"
2+
name = "sol-anchor-contract"
33
version = "0.1.0"
44
description = "Created with Anchor"
5+
rust-version = "1.60"
56
edition = "2021"
67

78
[lib]
89
crate-type = ["cdylib", "lib"]
9-
name = "example_sol_anchor_contract"
10+
name = "sol_anchor_contract"
1011

1112
[features]
1213
no-entrypoint = []
@@ -16,7 +17,6 @@ cpi = ["no-entrypoint"]
1617
default = []
1718

1819
[dependencies]
19-
anchor-lang = "0.25.0"
20+
anchor-lang = "0.27.0"
2021
pyth-sdk = { path = "../../../../pyth-sdk", version = "0.7.0" }
21-
pyth-sdk-solana = { path = "../../../../pyth-sdk-solana", version = "0.7.0" }
22-
solana-program = ">= 1.10, < 1.15"
22+
pyth-sdk-solana = { path = "../../../../pyth-sdk-solana", version = "0.7.2" }

examples/sol-anchor-contract/programs/example-sol-anchor-contract/src/lib.rs examples/sol-anchor-contract/programs/sol-anchor-contract/src/lib.rs

+61-30
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,33 @@
1-
use std::mem::size_of;
21
use anchor_lang::prelude::*;
3-
use solana_program::account_info::AccountInfo;
42

53
pub mod state;
6-
use state::PriceFeed;
74
use state::AdminConfig;
5+
use state::PriceFeed;
86

97
mod error;
108
use error::ErrorCode;
119

12-
declare_id!("BZh3CP454Ca1C9yBp2tpGAkXoKFti9x8ShJLSxNDpoxa");
13-
14-
#[derive(Accounts)]
15-
pub struct InitRequest<'info> {
16-
#[account(address = *program_id @ ErrorCode::Unauthorized)]
17-
pub program: Signer<'info>,
18-
#[account(mut)]
19-
pub payer: Signer<'info>,
20-
#[account(init, payer = payer, space = 8 + size_of::<AdminConfig>())]
21-
pub config: Account<'info, AdminConfig>,
22-
pub system_program: Program<'info, System>,
23-
}
10+
declare_id!("GFPM2LncpbWiLkePLs3QjcLVPw31B2h23FwFfhig79fh");
2411

25-
#[derive(Accounts)]
26-
pub struct QueryRequest<'info> {
27-
pub config: Account<'info, AdminConfig>,
28-
#[account(address = config.loan_price_feed_id @ ErrorCode::InvalidArgument)]
29-
pub pyth_loan_account: Account<'info, PriceFeed>,
30-
#[account(address = config.collateral_price_feed_id @ ErrorCode::InvalidArgument)]
31-
pub pyth_collateral_account: Account<'info, PriceFeed>,
32-
}
12+
const BASE : f64 = 10.0;
3313

3414
#[program]
35-
pub mod example_sol_anchor_contract {
15+
pub mod sol_anchor_contract {
3616
use super::*;
3717

3818
pub fn init(ctx: Context<InitRequest>, config: AdminConfig) -> Result<()> {
3919
ctx.accounts.config.set_inner(config);
4020
Ok(())
4121
}
4222

43-
pub fn loan_to_value(ctx: Context<QueryRequest>, loan_qty: i64, collateral_qty: i64) -> Result<()> {
23+
pub fn loan_to_value(
24+
ctx: Context<QueryRequest>,
25+
loan_qty: i64,
26+
collateral_qty: i64,
27+
) -> Result<()> {
4428
msg!("Loan quantity is {}.", loan_qty);
4529
msg!("Collateral quantity is {}.", collateral_qty);
4630

47-
4831
let loan_feed = &ctx.accounts.pyth_loan_account;
4932
let collateral_feed = &ctx.accounts.pyth_collateral_account;
5033
// With high confidence, the maximum value of the loan is
@@ -62,10 +45,21 @@ pub mod example_sol_anchor_contract {
6245
let mut loan_max_value = loan_max_price
6346
.checked_mul(loan_qty)
6447
.ok_or(ErrorCode::Overflow)?;
48+
49+
// WARNING : f64 SHOULD NOT BE USED IN SMART CONTRACTS, IT IS USED HERE ONLY FOR LOGGING PURPOSES
50+
// lets get the maximum loan value based on computation
51+
// i.e {} * 10^({})
52+
// loan_max_value * 10^(loan_price.expo)
53+
let exponent: i32 = loan_price.expo;
54+
let result = BASE.powi(exponent.abs());
55+
let result = if exponent < 0 { 1.0 / result } else { result };
56+
let result_loan_value = loan_max_value as f64 * result;
57+
6558
msg!(
66-
"The maximum loan value is {} * 10^({}).",
59+
"The maximum loan value is {} * 10^({}) = {}.",
6760
loan_max_value,
68-
loan_price.expo
61+
loan_price.expo,
62+
result_loan_value
6963
);
7064

7165
// With high confidence, the minimum value of the collateral is
@@ -83,10 +77,21 @@ pub mod example_sol_anchor_contract {
8377
let mut collateral_min_value = collateral_min_price
8478
.checked_mul(collateral_qty)
8579
.ok_or(ErrorCode::Overflow)?;
80+
81+
// WARNING : f64 SHOULD NOT BE USED IN SMART CONTRACTS, IT IS USED HERE ONLY FOR LOGGING PURPOSES
82+
// lets get the minimum collateral value based on computation
83+
// i.e {} * 10^({})
84+
// i.e collateral_min_value * 10^(collateral_price.expo)
85+
let exponent: i32 = collateral_price.expo;
86+
let result = BASE.powi(exponent.abs());
87+
let result: f64 = if exponent < 0 { 1.0 / result } else { result };
88+
let result_collateral_value = collateral_min_value as f64 * result;
89+
8690
msg!(
87-
"The minimum collateral value is {} * 10^({}).",
91+
"The minimum collateral value is {} * 10^({}) = {}.",
8892
collateral_min_value,
89-
collateral_price.expo
93+
collateral_price.expo,
94+
result_collateral_value
9095
);
9196

9297
// If the loan and collateral prices use different exponent,
@@ -116,3 +121,29 @@ pub mod example_sol_anchor_contract {
116121
}
117122
}
118123
}
124+
125+
#[derive(Accounts)]
126+
pub struct InitRequest<'info> {
127+
#[account(mut)]
128+
pub payer: Signer<'info>,
129+
#[account(
130+
init,
131+
payer = payer,
132+
space = 8 + AdminConfig::INIT_SPACE
133+
)]
134+
pub config: Account<'info, AdminConfig>,
135+
pub system_program: Program<'info, System>,
136+
}
137+
138+
#[derive(Accounts)]
139+
pub struct QueryRequest<'info> {
140+
pub config: Account<'info, AdminConfig>,
141+
#[account(
142+
address = config.loan_price_feed_id @ ErrorCode::InvalidArgument
143+
)]
144+
pub pyth_loan_account: Account<'info, PriceFeed>,
145+
#[account(
146+
address = config.collateral_price_feed_id @ ErrorCode::InvalidArgument
147+
)]
148+
pub pyth_collateral_account: Account<'info, PriceFeed>,
149+
}

examples/sol-anchor-contract/programs/example-sol-anchor-contract/src/state.rs examples/sol-anchor-contract/programs/sol-anchor-contract/src/state.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,31 @@
1-
use std::ops::Deref;
2-
use std::str::FromStr;
31
use anchor_lang::prelude::*;
42
use pyth_sdk_solana::state::load_price_account;
3+
use std::ops::Deref;
4+
use std::str::FromStr;
55

66
use crate::ErrorCode;
77

88
#[account]
9+
#[derive(InitSpace)]
910
pub struct AdminConfig {
10-
pub loan_price_feed_id: Pubkey,
11+
pub loan_price_feed_id: Pubkey,
1112
pub collateral_price_feed_id: Pubkey,
1213
}
1314

1415
#[derive(Clone)]
15-
pub struct PriceFeed (pyth_sdk::PriceFeed);
16+
pub struct PriceFeed(pyth_sdk::PriceFeed);
1617

1718
impl anchor_lang::Owner for PriceFeed {
1819
fn owner() -> Pubkey {
1920
// Make sure the owner is the pyth oracle account on solana devnet
2021
let oracle_addr = "gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s";
21-
return Pubkey::from_str(&oracle_addr).unwrap();
22+
return Pubkey::from_str(&oracle_addr).unwrap();
2223
}
2324
}
2425

2526
impl anchor_lang::AccountDeserialize for PriceFeed {
26-
fn try_deserialize_unchecked(data: &mut &[u8]) -> Result<Self>{
27-
let account = load_price_account(data)
28-
.map_err(|_x| error!(ErrorCode::PythError))?;
27+
fn try_deserialize_unchecked(data: &mut &[u8]) -> Result<Self> {
28+
let account = load_price_account(data).map_err(|_x| error!(ErrorCode::PythError))?;
2929

3030
// Use a dummy key since the key field will be removed from the SDK
3131
let zeros: [u8; 32] = [0; 32];
@@ -36,7 +36,7 @@ impl anchor_lang::AccountDeserialize for PriceFeed {
3636
}
3737

3838
impl anchor_lang::AccountSerialize for PriceFeed {
39-
fn try_serialize<W: std::io::Write>(&self, _writer: &mut W,) -> std::result::Result<(), Error> {
39+
fn try_serialize<W: std::io::Write>(&self, _writer: &mut W) -> std::result::Result<(), Error> {
4040
Err(error!(ErrorCode::TryToSerializePriceAccount))
4141
}
4242
}

examples/sol-anchor-contract/scripts/test.ts

-93
This file was deleted.

0 commit comments

Comments
 (0)