Skip to content
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

refactor lazer for updated idl #1393

Merged
merged 1 commit into from
Dec 18, 2024
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
21 changes: 6 additions & 15 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion programs/drift/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ anchor-lang = "0.29.0"
solana-program = "1.16"
anchor-spl = "0.29.0"
pyth-client = "0.2.2"
pyth-lazer-sdk = { git = "https://github.com/drift-labs/pyth-crosschain", rev = "776b6f772ba8ae49f26d16d04649073c3d6f77cf"}
pyth-lazer-solana-contract = { git = "https://github.com/drift-labs/pyth-crosschain", rev = "1f8d9d4f5322fa96c51420e3252c3e9a995d5df0"}
pythnet-sdk = { git = "https://github.com/drift-labs/pyth-crosschain", rev = "3e8a24ecd0bcf22b787313e2020f4186bb22c729"}
pyth-solana-receiver-sdk = { git = "https://github.com/drift-labs/pyth-crosschain", rev = "3e8a24ecd0bcf22b787313e2020f4186bb22c729"}
bytemuck = { version = "1.4.0" }
Expand Down
57 changes: 40 additions & 17 deletions programs/drift/src/instructions/pyth_lazer_oracle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,13 @@ use crate::state::pyth_lazer_oracle::{
};
use crate::validate;
use anchor_lang::prelude::*;
use pyth_lazer_sdk::protocol::payload::{PayloadData, PayloadPropertyValue};
use pyth_lazer_sdk::protocol::router::Price;
use anchor_lang::InstructionData;
use pyth_lazer_solana_contract::instruction::VerifyMessage;
use pyth_lazer_solana_contract::protocol::message::SolanaMessage;
use pyth_lazer_solana_contract::protocol::payload::{PayloadData, PayloadPropertyValue};
use pyth_lazer_solana_contract::protocol::router::Price;
use solana_program::sysvar::instructions::load_current_index_checked;
use solana_program::{instruction::Instruction as ProgramInstruction, program::invoke};

pub fn handle_update_pyth_lazer_oracle<'c: 'info, 'info>(
ctx: Context<'_, '_, 'c, 'info, UpdatePythLazerOracle>,
Expand All @@ -22,19 +26,32 @@ pub fn handle_update_pyth_lazer_oracle<'c: 'info, 'info>(
"instruction index must be greater than 0 to include the sig verify ix"
)?;

let verified = pyth_lazer_sdk::verify_message(
&ctx.accounts.pyth_lazer_storage,
&ctx.accounts.ix_sysvar.to_account_info(),
&pyth_message,
ix_idx - 1,
0,
12, // 8 bytes for anchor ix discriminator, 4 bytes for borsh vec len encoding
);

if verified.is_err() {
msg!("{:?}", verified);
return Err(ErrorCode::UnverifiedPythLazerMessage.into());
}
invoke(
&ProgramInstruction::new_with_bytes(
pyth_lazer_solana_contract::ID,
&VerifyMessage {
message_data: pyth_message.to_vec(),
ed25519_instruction_index: ix_idx - 1,
signature_index: 0,
message_offset: 12,
}
.data(),
vec![
AccountMeta::new(*ctx.accounts.keeper.key, true),
AccountMeta::new_readonly(*ctx.accounts.pyth_lazer_storage.key, false),
AccountMeta::new(*ctx.accounts.pyth_lazer_treasury.key, false),
AccountMeta::new_readonly(*ctx.accounts.pyth_lazer_treasury.key, false),
AccountMeta::new_readonly(*ctx.accounts.ix_sysvar.key, false),
],
),
&[
ctx.accounts.keeper.to_account_info(),
ctx.accounts.pyth_lazer_storage.clone(),
ctx.accounts.pyth_lazer_treasury.clone(),
ctx.accounts.system_program.to_account_info(),
ctx.accounts.ix_sysvar.to_account_info(),
],
)?;

// Load oracle accounts from remaining accounts
let remaining_accounts = ctx.remaining_accounts;
Expand All @@ -43,7 +60,10 @@ pub fn handle_update_pyth_lazer_oracle<'c: 'info, 'info>(
ErrorCode::OracleTooManyPriceAccountUpdates
)?;

let data = PayloadData::deserialize_slice_le(verified.unwrap().payload)
let deserialized_pyth_message = SolanaMessage::deserialize_slice(&pyth_message)
.map_err(|_| ProgramError::InvalidInstructionData)?;

let data = PayloadData::deserialize_slice_le(&deserialized_pyth_message.payload)
.map_err(|_| ProgramError::InvalidInstructionData)?;
let next_timestamp = data.timestamp_us.0;

Expand Down Expand Up @@ -127,10 +147,13 @@ pub struct UpdatePythLazerOracle<'info> {
pub keeper: Signer<'info>,
/// CHECK: Pyth lazer storage account not available to us
#[account(
address = PYTH_LAZER_STORAGE_ID @ ErrorCode::InvalidPythLazerStorageOwner
address = PYTH_LAZER_STORAGE_ID @ ErrorCode::InvalidPythLazerStorageOwner,
)]
pub pyth_lazer_storage: AccountInfo<'info>,
/// CHECK: this account doesn't need additional constraints.
pub pyth_lazer_treasury: AccountInfo<'info>,
/// CHECK: checked by ed25519 verify
#[account(address = solana_program::sysvar::instructions::ID)]
pub ix_sysvar: AccountInfo<'info>,
pub system_program: Program<'info, System>,
}
20 changes: 17 additions & 3 deletions sdk/src/driftClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ export class DriftClient {
txHandler: TxHandler;

receiverProgram?: Program<PythSolanaReceiver>;
pythLazerTreausryPubkey?: PublicKey;
wormholeProgram?: Program<WormholeCoreBridgeSolana>;
sbOnDemandProgramdId: PublicKey;
sbOnDemandProgram?: Program30<Idl30>;
Expand Down Expand Up @@ -8518,6 +8519,13 @@ export class DriftClient {
return txSig;
}

public async loadPythLazerTreasuryPubkey(): Promise<PublicKey> {
const accountInfo = await this.connection.getAccountInfo(
PYTH_LAZER_STORAGE_ACCOUNT_KEY
);
return new PublicKey(accountInfo!.data.slice(40, 72));
}

public async getUpdatePythPullOracleIxs(
params: {
merklePriceUpdate: {
Expand Down Expand Up @@ -8557,7 +8565,7 @@ export class DriftClient {
feedIds: number[],
pythMessageHex: string
): Promise<string> {
const postIxs = this.getPostPythLazerOracleUpdateIxs(
const postIxs = await this.getPostPythLazerOracleUpdateIxs(
feedIds,
pythMessageHex,
undefined,
Expand All @@ -8568,12 +8576,16 @@ export class DriftClient {
return txSig;
}

public getPostPythLazerOracleUpdateIxs(
public async getPostPythLazerOracleUpdateIxs(
feedIds: number[],
pythMessageHex: string,
precedingIxs: TransactionInstruction[] = [],
overrideIxCount?: number
): TransactionInstruction[] {
): Promise<TransactionInstruction[]> {
if (!this.pythLazerTreausryPubkey) {
this.pythLazerTreausryPubkey = await this.loadPythLazerTreasuryPubkey();
}

const pythMessageBytes = Buffer.from(pythMessageHex, 'hex');

const verifyIx = createMinimalEd25519VerifyIx(
Expand All @@ -8597,6 +8609,8 @@ export class DriftClient {
keeper: this.wallet.publicKey,
pythLazerStorage: PYTH_LAZER_STORAGE_ACCOUNT_KEY,
ixSysvar: SYSVAR_INSTRUCTIONS_PUBKEY,
systemProgram: anchor.web3.SystemProgram.programId,
pythLazerTreasury: this.pythLazerTreausryPubkey,
},
remainingAccounts: remainingAccountsMeta,
}
Expand Down
6 changes: 3 additions & 3 deletions tests/pythLazer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ describe('pyth lazer oracles', () => {
});

it('crank', async () => {
const ixs = driftClient.getPostPythLazerOracleUpdateIxs(
const ixs = await driftClient.getPostPythLazerOracleUpdateIxs(
[1],
PYTH_LAZER_HEX_STRING_BTC,
[]
Expand All @@ -118,7 +118,7 @@ describe('pyth lazer oracles', () => {
});

it('crank multi', async () => {
const ixs = driftClient.getPostPythLazerOracleUpdateIxs(
const ixs = await driftClient.getPostPythLazerOracleUpdateIxs(
[1, 2, 6],
PYTH_LAZER_HEX_STRING_MULTI
);
Expand All @@ -135,7 +135,7 @@ describe('pyth lazer oracles', () => {
});

it('fails on wrong message passed', async () => {
const ixs = driftClient.getPostPythLazerOracleUpdateIxs(
const ixs = await driftClient.getPostPythLazerOracleUpdateIxs(
[1],
PYTH_LAZER_HEX_STRING_SOL
);
Expand Down
Loading