percli_program/instructions/
transfer_authority.rs1use 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
7#[derive(Accounts)]
24pub struct TransferAuthority<'info> {
25 pub authority: Signer<'info>,
26
27 #[account(
29 mut,
30 owner = crate::ID @ PercolatorError::AccountNotFound,
31 constraint = market.data_len() >= MARKET_ACCOUNT_SIZE @ PercolatorError::AccountNotFound,
32 )]
33 pub market: UncheckedAccount<'info>,
34}
35
36pub fn handler(ctx: Context<TransferAuthority>, new_authority: Pubkey) -> Result<()> {
37 let market = &ctx.accounts.market;
38 let mut data = market.try_borrow_mut_data()?;
39
40 require!(
41 crate::state::is_v1_market(&data),
42 PercolatorError::AccountNotFound
43 );
44
45 let mut header = header_from_account_data(&data)?;
46 require!(
47 header.authority == ctx.accounts.authority.key(),
48 PercolatorError::Unauthorized
49 );
50 require!(
52 new_authority != header.authority,
53 PercolatorError::Unauthorized
54 );
55
56 let previous_pending = header.pending_authority;
57 header.pending_authority = new_authority;
58 write_header(&mut data, &header);
59
60 if new_authority == Pubkey::default() {
61 emit!(events::AuthorityTransferCancelled {
62 market: market.key(),
63 authority: header.authority,
64 previous_pending,
65 });
66 } else {
67 emit!(events::AuthorityTransferInitiated {
68 market: market.key(),
69 old_authority: header.authority,
70 pending_authority: new_authority,
71 });
72 }
73
74 Ok(())
75}