use {
super::validate_safety_deposit_box_v2::{
assert_common_checks, assert_supply_logic_check, CommonCheckArgs, SupplyLogicCheckArgs,
},
crate::{
deprecated_state::{
AuctionManagerV1, ParticipationStateV1, SafetyDepositValidationTicket,
MAX_VALIDATION_TICKET_SIZE,
},
error::MetaplexError,
state::{AuctionManagerStatus, Key, Store, WinningConfigType, PREFIX},
utils::{assert_derivation, assert_initialized, create_or_allocate_account_raw},
},
borsh::BorshSerialize,
metaplex_token_metadata::state::Metadata,
metaplex_token_vault::state::{SafetyDepositBox, Vault},
solana_program::{
account_info::{next_account_info, AccountInfo},
entrypoint::ProgramResult,
pubkey::Pubkey,
},
spl_token::state::Account,
};
pub fn make_safety_deposit_validation<'a>(
program_id: &Pubkey,
auction_manager_info: &AccountInfo<'a>,
safety_deposit_info: &AccountInfo<'a>,
safety_deposit_validation_ticket_info: &AccountInfo<'a>,
payer_info: &AccountInfo<'a>,
rent_info: &AccountInfo<'a>,
system_info: &AccountInfo<'a>,
) -> ProgramResult {
let bump = assert_derivation(
program_id,
safety_deposit_validation_ticket_info,
&[
PREFIX.as_bytes(),
program_id.as_ref(),
auction_manager_info.key.as_ref(),
safety_deposit_info.key.as_ref(),
],
)?;
create_or_allocate_account_raw(
*program_id,
safety_deposit_validation_ticket_info,
rent_info,
system_info,
payer_info,
MAX_VALIDATION_TICKET_SIZE,
&[
PREFIX.as_bytes(),
program_id.as_ref(),
auction_manager_info.key.as_ref(),
safety_deposit_info.key.as_ref(),
&[bump],
],
)?;
let mut validation =
SafetyDepositValidationTicket::from_account_info(safety_deposit_validation_ticket_info)?;
validation.key = Key::SafetyDepositValidationTicketV1;
validation.address = *safety_deposit_info.key;
validation.serialize(&mut *safety_deposit_validation_ticket_info.data.borrow_mut())?;
Ok(())
}
pub fn process_deprecated_validate_safety_deposit_box_v1<'a>(
program_id: &'a Pubkey,
accounts: &'a [AccountInfo<'a>],
) -> ProgramResult {
let account_info_iter = &mut accounts.iter();
let safety_deposit_validation_ticket_info = next_account_info(account_info_iter)?;
let auction_manager_info = next_account_info(account_info_iter)?;
let metadata_info = next_account_info(account_info_iter)?;
let original_authority_lookup_info = next_account_info(account_info_iter)?;
let whitelisted_creator_info = next_account_info(account_info_iter)?;
let auction_manager_store_info = next_account_info(account_info_iter)?;
let safety_deposit_info = next_account_info(account_info_iter)?;
let safety_deposit_token_store_info = next_account_info(account_info_iter)?;
let mint_info = next_account_info(account_info_iter)?;
let edition_info = next_account_info(account_info_iter)?;
let vault_info = next_account_info(account_info_iter)?;
let authority_info = next_account_info(account_info_iter)?;
let metadata_authority_info = next_account_info(account_info_iter)?;
let payer_info = next_account_info(account_info_iter)?;
let token_metadata_program_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)?;
if !safety_deposit_validation_ticket_info.data_is_empty() {
return Err(MetaplexError::AlreadyValidated.into());
}
let mut auction_manager = AuctionManagerV1::from_account_info(auction_manager_info)?;
let safety_deposit = SafetyDepositBox::from_account_info(safety_deposit_info)?;
let _safety_deposit_token_store: Account = assert_initialized(safety_deposit_token_store_info)?;
let metadata = Metadata::from_account_info(metadata_info)?;
let store = Store::from_account_info(auction_manager_store_info)?;
let vault = Vault::from_account_info(vault_info)?;
let mut total_amount_requested: u64 = 0;
let mut winning_config_type: WinningConfigType = WinningConfigType::TokenOnlyTransfer;
let mut winning_config_items_validated: u8 = 0;
let mut all_winning_config_items: u8 = 0;
for i in 0..auction_manager.settings.winning_configs.len() {
let possible_config = &auction_manager.settings.winning_configs[i];
for j in 0..possible_config.items.len() {
let possible_item = &possible_config.items[j];
all_winning_config_items = all_winning_config_items
.checked_add(1)
.ok_or(MetaplexError::NumericalOverflowError)?;
if possible_item.safety_deposit_box_index == safety_deposit.order {
winning_config_type = possible_item.winning_config_type;
winning_config_items_validated = winning_config_items_validated
.checked_add(1)
.ok_or(MetaplexError::NumericalOverflowError)?;
total_amount_requested = total_amount_requested
.checked_add(possible_item.amount.into())
.ok_or(MetaplexError::NumericalOverflowError)?;
auction_manager.state.winning_config_states[i].items[j].primary_sale_happened =
metadata.primary_sale_happened;
}
}
}
if let Some(participation_config) = &auction_manager.settings.participation_config {
if participation_config.safety_deposit_box_index == safety_deposit.order {
total_amount_requested = total_amount_requested
.checked_add(1)
.ok_or(MetaplexError::NumericalOverflowError)?;
if let Some(state) = &auction_manager.state.participation_state {
auction_manager.state.participation_state = Some(ParticipationStateV1 {
collected_to_accept_payment: state.collected_to_accept_payment,
primary_sale_happened: state.primary_sale_happened,
validated: true,
printing_authorization_token_account: state
.printing_authorization_token_account,
})
}
}
}
if total_amount_requested == 0 {
return Err(MetaplexError::SafetyDepositBoxNotUsedInAuction.into());
}
assert_common_checks(CommonCheckArgs {
program_id,
auction_manager_info,
metadata_info,
original_authority_lookup_info,
whitelisted_creator_info,
safety_deposit_info,
safety_deposit_token_store_info,
edition_info,
vault_info,
mint_info,
token_metadata_program_info,
auction_manager_store_info,
authority_info,
store: &store,
auction_manager: &auction_manager,
metadata: &metadata,
safety_deposit: &safety_deposit,
vault: &vault,
winning_config_type: &winning_config_type,
})?;
assert_supply_logic_check(SupplyLogicCheckArgs {
program_id,
auction_manager_info,
metadata_info,
edition_info,
metadata_authority_info,
original_authority_lookup_info,
rent_info,
system_info,
payer_info,
token_metadata_program_info,
auction_manager: &auction_manager,
winning_config_type: &winning_config_type,
metadata: &metadata,
safety_deposit: &safety_deposit,
store: &store,
safety_deposit_token_store_info,
total_amount_requested,
})?;
auction_manager.state.winning_config_items_validated = match auction_manager
.state
.winning_config_items_validated
.checked_add(winning_config_items_validated)
{
Some(val) => val,
None => return Err(MetaplexError::NumericalOverflowError.into()),
};
if auction_manager.state.winning_config_items_validated == all_winning_config_items {
let mut participation_okay = true;
if let Some(state) = &auction_manager.state.participation_state {
participation_okay = state.validated
}
if participation_okay {
auction_manager.state.status = AuctionManagerStatus::Validated
}
}
auction_manager.serialize(&mut *auction_manager_info.data.borrow_mut())?;
make_safety_deposit_validation(
program_id,
auction_manager_info,
safety_deposit_info,
safety_deposit_validation_ticket_info,
payer_info,
rent_info,
system_info,
)?;
Ok(())
}