Skip to main content

percli_program/instructions/
update_oracle.rs

1use anchor_lang::prelude::*;
2
3use crate::error::PercolatorError;
4use crate::instructions::events;
5use crate::state::{header_from_account_data, write_header, MARKET_ACCOUNT_SIZE};
6
7const PYTH_PROGRAM_ID: Pubkey = pubkey!("FsJ3A3u2vn5cTVofAjvy6y5kwABJAqYWpe4975bi2epH");
8
9#[derive(Accounts)]
10pub struct UpdateOracle<'info> {
11    pub authority: Signer<'info>,
12
13    /// CHECK: Validated via owner, discriminator, and size.
14    #[account(
15        mut,
16        owner = crate::ID @ PercolatorError::AccountNotFound,
17        constraint = market.data_len() >= MARKET_ACCOUNT_SIZE @ PercolatorError::AccountNotFound,
18    )]
19    pub market: UncheckedAccount<'info>,
20
21    /// CHECK: Validated by Pyth program owner check.
22    #[account(
23        owner = PYTH_PROGRAM_ID @ PercolatorError::InvalidOraclePrice,
24    )]
25    pub new_oracle: UncheckedAccount<'info>,
26}
27
28pub fn handler(ctx: Context<UpdateOracle>) -> Result<()> {
29    let market = &ctx.accounts.market;
30    let mut data = market.try_borrow_mut_data()?;
31
32    require!(
33        &data[0..8] == b"percmrkt",
34        PercolatorError::AccountNotFound
35    );
36
37    let mut header = header_from_account_data(&data)?;
38    require!(
39        header.authority == ctx.accounts.authority.key(),
40        PercolatorError::Unauthorized
41    );
42
43    let old_oracle = header.oracle;
44    header.oracle = ctx.accounts.new_oracle.key();
45    write_header(&mut data, &header);
46
47    emit!(events::OracleUpdated {
48        authority: ctx.accounts.authority.key(),
49        old_oracle,
50        new_oracle: ctx.accounts.new_oracle.key(),
51    });
52
53    Ok(())
54}