use crate::{
error::MetaplexError,
state::{get_auction_manager, AuctionManagerStatus, Store, PREFIX},
utils::{
assert_authority_correct, assert_derivation, assert_owned_by, assert_signer, end_auction,
},
};
use mpl_auction::processor::AuctionData;
use mpl_token_vault::{instruction::create_set_authority_instruction, state::Vault};
use solana_program::{
account_info::{next_account_info, AccountInfo},
entrypoint::ProgramResult,
program::invoke_signed,
pubkey::Pubkey,
};
fn set_vault_authority_to_auction_manager_authority<'a>(
auction_manager_info: &AccountInfo<'a>,
authority_info: &AccountInfo<'a>,
vault_info: &AccountInfo<'a>,
vault_program_info: &AccountInfo<'a>,
signer_seeds: &[&[u8]],
) -> ProgramResult {
invoke_signed(
&create_set_authority_instruction(
*vault_program_info.key,
*vault_info.key,
*auction_manager_info.key,
*authority_info.key,
),
&[
auction_manager_info.clone(),
authority_info.clone(),
vault_info.clone(),
vault_program_info.clone(),
],
&[&signer_seeds],
)?;
Ok(())
}
pub fn process_decommission_auction_manager<'a>(
program_id: &'a Pubkey,
accounts: &'a [AccountInfo<'a>],
) -> ProgramResult {
let account_info_iter = &mut accounts.iter();
let mut auction_manager_info = next_account_info(account_info_iter)?;
let auction_info = next_account_info(account_info_iter)?;
let authority_info = next_account_info(account_info_iter)?;
let vault_info = next_account_info(account_info_iter)?;
let store_info = next_account_info(account_info_iter)?;
let auction_program_info = next_account_info(account_info_iter)?;
let clock_info = next_account_info(account_info_iter)?;
let vault_program_info = next_account_info(account_info_iter).ok();
assert_owned_by(auction_manager_info, program_id)?;
assert_owned_by(store_info, program_id)?;
assert_signer(authority_info)?;
let mut auction_manager = get_auction_manager(auction_manager_info)?;
let vault = Vault::from_account_info(vault_info)?;
let auction = AuctionData::from_account_info(auction_info)?;
let store = Store::from_account_info(store_info)?;
assert_authority_correct(&auction_manager.authority(), authority_info)?;
if auction.authority != *auction_manager_info.key {
return Err(MetaplexError::AuctionAuthorityMismatch.into());
}
if vault.authority != *auction_manager_info.key {
return Err(MetaplexError::VaultAuthorityMismatch.into());
}
if auction_manager.status() != AuctionManagerStatus::Initialized {
return Err(MetaplexError::InvalidStatus.into());
}
if auction_manager.store() != *store_info.key {
return Err(MetaplexError::AuctionManagerStoreMismatch.into());
}
if *auction_program_info.key != store.auction_program {
return Err(MetaplexError::AuctionManagerAuctionProgramMismatch.into());
}
if auction_manager.auction() != *auction_info.key {
return Err(MetaplexError::AuctionManagerAuctionMismatch.into());
}
let bump_seed = assert_derivation(
program_id,
auction_manager_info,
&[PREFIX.as_bytes(), &auction_info.key.as_ref()],
)?;
let authority_seeds = &[PREFIX.as_bytes(), &auction_info.key.as_ref(), &[bump_seed]];
end_auction(
auction_manager.vault(),
auction_info.clone(),
auction_manager_info.clone(),
auction_program_info.clone(),
clock_info.clone(),
authority_seeds,
)?;
if let Some(vault_program) = vault_program_info {
set_vault_authority_to_auction_manager_authority(
auction_manager_info,
authority_info,
vault_info,
vault_program,
authority_seeds,
)?;
}
auction_manager.set_status(AuctionManagerStatus::Disbursing);
auction_manager.save(&mut auction_manager_info)?;
Ok(())
}