use crate::{
error::MetaplexError,
state::{CommonWinningIndexChecks, CommonWinningIndexReturn, WinningConfigType, PREFIX},
utils::{
assert_owned_by, common_redeem_checks, common_redeem_finish, transfer_metadata_ownership,
transfer_safety_deposit_box_items, CommonRedeemCheckArgs, CommonRedeemFinishArgs,
CommonRedeemReturn,
},
};
use mpl_token_metadata::state::{Metadata, TokenMetadataAccount};
use solana_program::{
account_info::{next_account_info, AccountInfo},
entrypoint::ProgramResult,
msg,
pubkey::Pubkey,
};
pub fn process_full_rights_transfer_bid<'a>(
program_id: &'a Pubkey,
accounts: &'a [AccountInfo<'a>],
overwrite_win_index: Option<usize>,
) -> ProgramResult {
let account_info_iter = &mut accounts.iter();
let auction_manager_info = next_account_info(account_info_iter)?;
let safety_deposit_token_store_info = next_account_info(account_info_iter)?;
let destination_info = next_account_info(account_info_iter)?;
let bid_redemption_info = next_account_info(account_info_iter)?;
let safety_deposit_info = next_account_info(account_info_iter)?;
let vault_info = next_account_info(account_info_iter)?;
let fraction_mint_info = next_account_info(account_info_iter)?;
let auction_info = next_account_info(account_info_iter)?;
let bidder_metadata_info = next_account_info(account_info_iter)?;
let bidder_info = next_account_info(account_info_iter)?;
let payer_info = next_account_info(account_info_iter)?;
let token_program_info = next_account_info(account_info_iter)?;
let token_vault_program_info = next_account_info(account_info_iter)?;
let token_metadata_program_info = next_account_info(account_info_iter)?;
let store_info = next_account_info(account_info_iter)?;
let system_info = next_account_info(account_info_iter)?;
let rent_info = next_account_info(account_info_iter)?;
let metadata_info = next_account_info(account_info_iter)?;
let new_metadata_authority_info = next_account_info(account_info_iter)?;
let transfer_authority_info = next_account_info(account_info_iter)?;
let safety_deposit_config_info = next_account_info(account_info_iter).ok();
let auction_extended_info = next_account_info(account_info_iter).ok();
let CommonRedeemReturn {
auction_manager,
redemption_bump_seed,
cancelled,
rent: _rent,
win_index,
token_metadata_program,
} = common_redeem_checks(CommonRedeemCheckArgs {
program_id,
auction_manager_info,
safety_deposit_token_store_info,
destination_info,
bid_redemption_info,
safety_deposit_info,
vault_info,
auction_info,
auction_extended_info,
bidder_metadata_info,
bidder_info,
token_program_info,
token_vault_program_info,
token_metadata_program_info,
store_info,
rent_info,
safety_deposit_config_info,
is_participation: false,
user_provided_win_index: None,
overwrite_win_index,
assert_bidder_signer: true,
ignore_bid_redeemed_item_check: false,
})?;
assert_owned_by(metadata_info, &token_metadata_program)?;
let mut winning_item_index = None;
if !cancelled {
if let Some(winning_index) = win_index {
let CommonWinningIndexReturn {
amount: _a,
winning_config_type,
winning_config_item_index,
} = auction_manager.common_winning_index_checks(CommonWinningIndexChecks {
safety_deposit_info,
winning_index,
auction_manager_v1_ignore_claim: false,
safety_deposit_config_info,
})?;
winning_item_index = winning_config_item_index;
if winning_config_type != WinningConfigType::FullRightsTransfer {
return Err(MetaplexError::WrongBidEndpointForPrize.into());
}
let auction_key = auction_manager.auction();
let auction_seeds = &[PREFIX.as_bytes(), auction_key.as_ref()];
let (_, auction_bump_seed) = Pubkey::find_program_address(auction_seeds, &program_id);
let auction_authority_seeds = &[
PREFIX.as_bytes(),
auction_key.as_ref(),
&[auction_bump_seed],
];
let metadata = Metadata::from_account_info(metadata_info)?;
if metadata.update_authority == *auction_manager_info.key {
msg!("Transferring metadata authority!");
transfer_metadata_ownership(
token_metadata_program_info.clone(),
metadata_info.clone(),
auction_manager_info.clone(),
new_metadata_authority_info.clone(),
auction_authority_seeds,
)?;
}
transfer_safety_deposit_box_items(
token_vault_program_info.clone(),
destination_info.clone(),
safety_deposit_info.clone(),
safety_deposit_token_store_info.clone(),
vault_info.clone(),
fraction_mint_info.clone(),
auction_manager_info.clone(),
transfer_authority_info.clone(),
rent_info.clone(),
1,
auction_authority_seeds,
)?;
}
};
common_redeem_finish(CommonRedeemFinishArgs {
program_id,
auction_manager,
auction_manager_info,
bidder_metadata_info,
rent_info,
system_info,
payer_info,
bid_redemption_info,
redemption_bump_seed,
vault_info,
safety_deposit_config_info,
winning_index: win_index,
bid_redeemed: true,
participation_redeemed: false,
winning_item_index,
overwrite_win_index,
})?;
Ok(())
}