use crate::{
deprecated_state::{AuctionManagerV1, ParticipationStateV1},
error::MetaplexError,
state::{AuctionManagerStatus, Store},
utils::{
assert_at_least_one_creator_matches_or_store_public_and_all_verified,
assert_authority_correct, assert_derivation, assert_initialized, assert_owned_by,
assert_rent_exempt, assert_store_safety_vault_manager_match,
},
};
use borsh::BorshSerialize;
use mpl_token_metadata::state::{MasterEditionV1, Metadata, TokenMetadataAccount};
use mpl_token_vault::state::{SafetyDepositBox, Vault};
use solana_program::{
account_info::{next_account_info, AccountInfo},
entrypoint::ProgramResult,
program_option::COption,
pubkey::Pubkey,
rent::Rent,
sysvar::Sysvar,
};
use spl_token::state::Account;
pub fn process_deprecated_validate_participation(
program_id: &Pubkey,
accounts: &[AccountInfo],
) -> ProgramResult {
let account_info_iter = &mut accounts.iter();
let auction_manager_info = next_account_info(account_info_iter)?;
let open_edition_metadata_info = next_account_info(account_info_iter)?;
let open_master_edition_info = next_account_info(account_info_iter)?;
let printing_authorization_token_account_info = next_account_info(account_info_iter)?;
let authority_info = next_account_info(account_info_iter)?;
let whitelisted_creator_info = next_account_info(account_info_iter)?;
let store_info = next_account_info(account_info_iter)?;
let safety_deposit_box_info = next_account_info(account_info_iter)?;
let safety_deposit_box_token_store_info = next_account_info(account_info_iter)?;
let vault_info = next_account_info(account_info_iter)?;
let rent_info = next_account_info(account_info_iter)?;
let rent = &Rent::from_account_info(&rent_info)?;
let mut auction_manager = AuctionManagerV1::from_account_info(auction_manager_info)?;
let store = Store::from_account_info(store_info)?;
let vault = Vault::from_account_info(vault_info)?;
let safety_deposit_token_store: Account =
assert_initialized(safety_deposit_box_token_store_info)?;
let safety_deposit = SafetyDepositBox::from_account_info(safety_deposit_box_info)?;
let printing_token_account: Account =
assert_initialized(printing_authorization_token_account_info)?;
let open_edition_metadata = Metadata::from_account_info(open_edition_metadata_info)?;
let master_edition = MasterEditionV1::from_account_info(open_master_edition_info)?;
if vault.authority != *auction_manager_info.key {
return Err(MetaplexError::VaultAuthorityMismatch.into());
}
assert_authority_correct(&auction_manager.authority, authority_info)?;
assert_owned_by(auction_manager_info, program_id)?;
assert_owned_by(open_edition_metadata_info, &store.token_metadata_program)?;
assert_owned_by(open_master_edition_info, &store.token_metadata_program)?;
assert_owned_by(
printing_authorization_token_account_info,
&store.token_program,
)?;
if *whitelisted_creator_info.key != solana_program::system_program::id() {
if whitelisted_creator_info.data_is_empty() {
return Err(MetaplexError::Uninitialized.into());
}
assert_owned_by(whitelisted_creator_info, program_id)?;
}
assert_owned_by(store_info, program_id)?;
assert_owned_by(safety_deposit_box_info, &store.token_vault_program)?;
assert_owned_by(safety_deposit_box_token_store_info, &store.token_program)?;
assert_owned_by(vault_info, &store.token_vault_program)?;
assert_store_safety_vault_manager_match(
&auction_manager.vault,
&safety_deposit_box_info,
vault_info,
&store.token_vault_program,
)?;
if auction_manager.store != *store_info.key {
return Err(MetaplexError::AuctionManagerStoreMismatch.into());
}
if auction_manager.vault != *vault_info.key {
return Err(MetaplexError::AuctionManagerVaultMismatch.into());
}
assert_at_least_one_creator_matches_or_store_public_and_all_verified(
program_id,
&auction_manager,
&open_edition_metadata,
whitelisted_creator_info,
store_info,
)?;
assert_derivation(
&store.token_metadata_program,
open_master_edition_info,
&[
mpl_token_metadata::state::PREFIX.as_bytes(),
store.token_metadata_program.as_ref(),
&open_edition_metadata.mint.as_ref(),
mpl_token_metadata::state::EDITION.as_bytes(),
],
)?;
assert_owned_by(
printing_authorization_token_account_info,
&store.token_program,
)?;
assert_rent_exempt(rent, printing_authorization_token_account_info)?;
if printing_token_account.owner != *auction_manager_info.key {
return Err(MetaplexError::IncorrectOwner.into());
}
if printing_token_account.mint != master_edition.printing_mint {
return Err(MetaplexError::PrintingTokenAccountMintMismatch.into());
}
if printing_token_account.delegate != COption::None {
return Err(MetaplexError::DelegateShouldBeNone.into());
}
if printing_token_account.close_authority != COption::None {
return Err(MetaplexError::CloseAuthorityShouldBeNone.into());
}
if master_edition.max_supply.is_some() {
return Err(MetaplexError::CantUseLimitedSupplyEditionsWithOpenEditionAuction.into());
}
if master_edition.one_time_printing_authorization_mint != safety_deposit_token_store.mint {
return Err(MetaplexError::MasterEditionOneTimeAuthorizationMintMismatch.into());
}
if let Some(participation_config) = &auction_manager.settings.participation_config {
if participation_config.safety_deposit_box_index > vault.token_type_count {
return Err(MetaplexError::InvalidSafetyDepositBox.into());
}
if participation_config.safety_deposit_box_index != safety_deposit.order {
return Err(MetaplexError::SafetyDepositIndexMismatch.into());
}
if let Some(state) = auction_manager.state.participation_state {
if state.validated {
return Err(MetaplexError::AlreadyValidated.into());
}
auction_manager.state.participation_state = Some(ParticipationStateV1 {
collected_to_accept_payment: state.collected_to_accept_payment,
primary_sale_happened: open_edition_metadata.primary_sale_happened,
validated: true,
printing_authorization_token_account: Some(
*printing_authorization_token_account_info.key,
),
});
}
if auction_manager.settings.winning_configs.is_empty() {
auction_manager.state.status = AuctionManagerStatus::Validated;
}
auction_manager.serialize(&mut *auction_manager_info.data.borrow_mut())?;
}
Ok(())
}