Skip to content

Update example sol-anchor-contract #107 #108

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions examples/sol-anchor-contract/.gitignore
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
yarn.lock
Cargo.lock
.anchor
.DS_Store
target
**/*.rs.bk
node_modules
test-ledger
program_address.json
27 changes: 21 additions & 6 deletions examples/sol-anchor-contract/Anchor.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,25 @@
[programs.devnet]
example_sol_anchor_contract = "BZh3CP454Ca1C9yBp2tpGAkXoKFti9x8ShJLSxNDpoxa"

[provider]
cluster = "devnet"
cluster = "localnet"
wallet = "~/.config/solana/id.json"

[programs.localnet]
sol_anchor_contract = "GFPM2LncpbWiLkePLs3QjcLVPw31B2h23FwFfhig79fh"

[scripts]
install = "npm install"
test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 scripts/test.ts"
test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts"

[test]
startup_wait = 20000

[[test.genesis]]
address = "GFPM2LncpbWiLkePLs3QjcLVPw31B2h23FwFfhig79fh"
program = "./target/deploy/sol_anchor_contract.so"

[test.validator]
url = "https://api.devnet.solana.com"

[[test.validator.clone]]
address = "EdVCmQ9FSPcVe5YySXDPCRmc8aDQLKJ9xvYBMZPie1Vw"

[[test.validator.clone]]
address = "38xoQ4oeJCBrcVvca2cGk7iV1dAfrmTR1kmhSCJQ8Jto"
2,998 changes: 0 additions & 2,998 deletions examples/sol-anchor-contract/package-lock.json

This file was deleted.

16 changes: 9 additions & 7 deletions examples/sol-anchor-contract/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@
"lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check"
},
"dependencies": {
"@project-serum/anchor": "^0.25.0",
"@coral-xyz/anchor": "^0.27.0"
},
"devDependencies": {
"chai": "^4.3.7",
"mocha": "^9.2.2",
"ts-mocha": "^10.0.0",
"@types/bn.js": "^5.1.1",
"@types/chai": "^4.3.3",
"@types/chai": "^4.3.5",
"@types/mocha": "^9.1.1",
"chai": "^4.3.6",
"mocha": "^10.1.0",
"prettier": "^2.7.1",
"ts-mocha": "^10.0.0",
"typescript": "^4.8.4"
"typescript": "^4.9.5",
"prettier": "^2.8.8"
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
[package]
name = "example-sol-anchor-contract"
name = "sol-anchor-contract"
version = "0.1.0"
description = "Created with Anchor"
rust-version = "1.60"
edition = "2021"

[lib]
crate-type = ["cdylib", "lib"]
name = "example_sol_anchor_contract"
name = "sol_anchor_contract"

[features]
no-entrypoint = []
Expand All @@ -16,7 +17,6 @@ cpi = ["no-entrypoint"]
default = []

[dependencies]
anchor-lang = "0.25.0"
anchor-lang = "0.27.0"
pyth-sdk = { path = "../../../../pyth-sdk", version = "0.7.0" }
pyth-sdk-solana = { path = "../../../../pyth-sdk-solana", version = "0.7.0" }
solana-program = ">= 1.10, < 1.15"
pyth-sdk-solana = { path = "../../../../pyth-sdk-solana", version = "0.7.2" }
Original file line number Diff line number Diff line change
@@ -1,50 +1,33 @@
use std::mem::size_of;
use anchor_lang::prelude::*;
use solana_program::account_info::AccountInfo;

pub mod state;
use state::PriceFeed;
use state::AdminConfig;
use state::PriceFeed;

mod error;
use error::ErrorCode;

declare_id!("BZh3CP454Ca1C9yBp2tpGAkXoKFti9x8ShJLSxNDpoxa");

#[derive(Accounts)]
pub struct InitRequest<'info> {
#[account(address = *program_id @ ErrorCode::Unauthorized)]
pub program: Signer<'info>,
#[account(mut)]
pub payer: Signer<'info>,
#[account(init, payer = payer, space = 8 + size_of::<AdminConfig>())]
pub config: Account<'info, AdminConfig>,
pub system_program: Program<'info, System>,
}
declare_id!("GFPM2LncpbWiLkePLs3QjcLVPw31B2h23FwFfhig79fh");

#[derive(Accounts)]
pub struct QueryRequest<'info> {
pub config: Account<'info, AdminConfig>,
#[account(address = config.loan_price_feed_id @ ErrorCode::InvalidArgument)]
pub pyth_loan_account: Account<'info, PriceFeed>,
#[account(address = config.collateral_price_feed_id @ ErrorCode::InvalidArgument)]
pub pyth_collateral_account: Account<'info, PriceFeed>,
}
const BASE : f64 = 10.0;

#[program]
pub mod example_sol_anchor_contract {
pub mod sol_anchor_contract {
use super::*;

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

pub fn loan_to_value(ctx: Context<QueryRequest>, loan_qty: i64, collateral_qty: i64) -> Result<()> {
pub fn loan_to_value(
ctx: Context<QueryRequest>,
loan_qty: i64,
collateral_qty: i64,
) -> Result<()> {
msg!("Loan quantity is {}.", loan_qty);
msg!("Collateral quantity is {}.", collateral_qty);


let loan_feed = &ctx.accounts.pyth_loan_account;
let collateral_feed = &ctx.accounts.pyth_collateral_account;
// With high confidence, the maximum value of the loan is
Expand All @@ -62,10 +45,21 @@ pub mod example_sol_anchor_contract {
let mut loan_max_value = loan_max_price
.checked_mul(loan_qty)
.ok_or(ErrorCode::Overflow)?;

// WARNING : f64 SHOULD NOT BE USED IN SMART CONTRACTS, IT IS USED HERE ONLY FOR LOGGING PURPOSES
// lets get the maximum loan value based on computation
// i.e {} * 10^({})
// loan_max_value * 10^(loan_price.expo)
let exponent: i32 = loan_price.expo;
let result = BASE.powi(exponent.abs());
let result = if exponent < 0 { 1.0 / result } else { result };
let result_loan_value = loan_max_value as f64 * result;

msg!(
"The maximum loan value is {} * 10^({}).",
"The maximum loan value is {} * 10^({}) = {}.",
loan_max_value,
loan_price.expo
loan_price.expo,
result_loan_value
);

// With high confidence, the minimum value of the collateral is
Expand All @@ -83,10 +77,21 @@ pub mod example_sol_anchor_contract {
let mut collateral_min_value = collateral_min_price
.checked_mul(collateral_qty)
.ok_or(ErrorCode::Overflow)?;

// WARNING : f64 SHOULD NOT BE USED IN SMART CONTRACTS, IT IS USED HERE ONLY FOR LOGGING PURPOSES
// lets get the minimum collateral value based on computation
// i.e {} * 10^({})
// i.e collateral_min_value * 10^(collateral_price.expo)
let exponent: i32 = collateral_price.expo;
let result = BASE.powi(exponent.abs());
let result: f64 = if exponent < 0 { 1.0 / result } else { result };
let result_collateral_value = collateral_min_value as f64 * result;

msg!(
"The minimum collateral value is {} * 10^({}).",
"The minimum collateral value is {} * 10^({}) = {}.",
collateral_min_value,
collateral_price.expo
collateral_price.expo,
result_collateral_value
);

// If the loan and collateral prices use different exponent,
Expand Down Expand Up @@ -116,3 +121,29 @@ pub mod example_sol_anchor_contract {
}
}
}

#[derive(Accounts)]
pub struct InitRequest<'info> {
#[account(mut)]
pub payer: Signer<'info>,
#[account(
init,
payer = payer,
space = 8 + AdminConfig::INIT_SPACE
)]
pub config: Account<'info, AdminConfig>,
pub system_program: Program<'info, System>,
}

#[derive(Accounts)]
pub struct QueryRequest<'info> {
pub config: Account<'info, AdminConfig>,
#[account(
address = config.loan_price_feed_id @ ErrorCode::InvalidArgument
)]
pub pyth_loan_account: Account<'info, PriceFeed>,
#[account(
address = config.collateral_price_feed_id @ ErrorCode::InvalidArgument
)]
pub pyth_collateral_account: Account<'info, PriceFeed>,
}
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
use std::ops::Deref;
use std::str::FromStr;
use anchor_lang::prelude::*;
use pyth_sdk_solana::state::load_price_account;
use std::ops::Deref;
use std::str::FromStr;

use crate::ErrorCode;

#[account]
#[derive(InitSpace)]
pub struct AdminConfig {
pub loan_price_feed_id: Pubkey,
pub loan_price_feed_id: Pubkey,
pub collateral_price_feed_id: Pubkey,
}

#[derive(Clone)]
pub struct PriceFeed (pyth_sdk::PriceFeed);
pub struct PriceFeed(pyth_sdk::PriceFeed);

impl anchor_lang::Owner for PriceFeed {
fn owner() -> Pubkey {
// Make sure the owner is the pyth oracle account on solana devnet
let oracle_addr = "gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s";
return Pubkey::from_str(&oracle_addr).unwrap();
return Pubkey::from_str(&oracle_addr).unwrap();
}
}

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

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

impl anchor_lang::AccountSerialize for PriceFeed {
fn try_serialize<W: std::io::Write>(&self, _writer: &mut W,) -> std::result::Result<(), Error> {
fn try_serialize<W: std::io::Write>(&self, _writer: &mut W) -> std::result::Result<(), Error> {
Err(error!(ErrorCode::TryToSerializePriceAccount))
}
}
Expand Down
93 changes: 0 additions & 93 deletions examples/sol-anchor-contract/scripts/test.ts

This file was deleted.

Loading