ywpl_plex/processor/
deprecated_validate_participation.rs

1use crate::{
2    deprecated_state::{AuctionManagerV1, ParticipationStateV1},
3    error::MetaplexError,
4    state::{AuctionManagerStatus, Store},
5    utils::{
6        assert_at_least_one_creator_matches_or_store_public_and_all_verified,
7        assert_authority_correct, assert_derivation, assert_initialized, assert_owned_by,
8        assert_rent_exempt, assert_store_safety_vault_manager_match,
9    },
10};
11use borsh::BorshSerialize;
12use mpl_token_metadata::state::{MasterEditionV1, Metadata};
13use ywpl_token_vault::state::{SafetyDepositBox, Vault};
14use solana_program::{
15    account_info::{next_account_info, AccountInfo},
16    entrypoint::ProgramResult,
17    program_option::COption,
18    pubkey::Pubkey,
19    rent::Rent,
20    sysvar::Sysvar,
21};
22use spl_token::state::Account;
23
24pub fn process_deprecated_validate_participation(
25    program_id: &Pubkey,
26    accounts: &[AccountInfo],
27) -> ProgramResult {
28    let account_info_iter = &mut accounts.iter();
29
30    let auction_manager_info = next_account_info(account_info_iter)?;
31    let open_edition_metadata_info = next_account_info(account_info_iter)?;
32    let open_master_edition_info = next_account_info(account_info_iter)?;
33    let printing_authorization_token_account_info = next_account_info(account_info_iter)?;
34    let authority_info = next_account_info(account_info_iter)?;
35    let whitelisted_creator_info = next_account_info(account_info_iter)?;
36    let store_info = next_account_info(account_info_iter)?;
37    let safety_deposit_box_info = next_account_info(account_info_iter)?;
38    let safety_deposit_box_token_store_info = next_account_info(account_info_iter)?;
39    let vault_info = next_account_info(account_info_iter)?;
40    let rent_info = next_account_info(account_info_iter)?;
41    let rent = &Rent::from_account_info(&rent_info)?;
42
43    let mut auction_manager = AuctionManagerV1::from_account_info(auction_manager_info)?;
44    let store = Store::from_account_info(store_info)?;
45    let vault = Vault::from_account_info(vault_info)?;
46    let safety_deposit_token_store: Account =
47        assert_initialized(safety_deposit_box_token_store_info)?;
48    let safety_deposit = SafetyDepositBox::from_account_info(safety_deposit_box_info)?;
49    let printing_token_account: Account =
50        assert_initialized(printing_authorization_token_account_info)?;
51    let open_edition_metadata = Metadata::from_account_info(open_edition_metadata_info)?;
52    let master_edition = MasterEditionV1::from_account_info(open_master_edition_info)?;
53
54    if vault.authority != *auction_manager_info.key {
55        return Err(MetaplexError::VaultAuthorityMismatch.into());
56    }
57
58    // top level authority and ownership check
59    assert_authority_correct(&auction_manager.authority, authority_info)?;
60    assert_owned_by(auction_manager_info, program_id)?;
61    assert_owned_by(open_edition_metadata_info, &store.token_metadata_program)?;
62    assert_owned_by(open_master_edition_info, &store.token_metadata_program)?;
63    assert_owned_by(
64        printing_authorization_token_account_info,
65        &store.token_program,
66    )?;
67    if *whitelisted_creator_info.key != solana_program::system_program::id() {
68        if whitelisted_creator_info.data_is_empty() {
69            return Err(MetaplexError::Uninitialized.into());
70        }
71        assert_owned_by(whitelisted_creator_info, program_id)?;
72    }
73    assert_owned_by(store_info, program_id)?;
74    assert_owned_by(safety_deposit_box_info, &store.token_vault_program)?;
75    assert_owned_by(safety_deposit_box_token_store_info, &store.token_program)?;
76    assert_owned_by(vault_info, &store.token_vault_program)?;
77    // is it the right vault, safety deposit, and token store?
78    assert_store_safety_vault_manager_match(
79        &auction_manager.vault,
80        &safety_deposit_box_info,
81        vault_info,
82        &store.token_vault_program,
83    )?;
84
85    // do the vault and store belong to this AM?
86    if auction_manager.store != *store_info.key {
87        return Err(MetaplexError::AuctionManagerStoreMismatch.into());
88    }
89
90    if auction_manager.vault != *vault_info.key {
91        return Err(MetaplexError::AuctionManagerVaultMismatch.into());
92    }
93    // Check creators
94    assert_at_least_one_creator_matches_or_store_public_and_all_verified(
95        program_id,
96        &auction_manager,
97        &open_edition_metadata,
98        whitelisted_creator_info,
99        store_info,
100    )?;
101
102    // Make sure master edition is the right master edition for this metadata given
103    assert_derivation(
104        &store.token_metadata_program,
105        open_master_edition_info,
106        &[
107            mpl_token_metadata::state::PREFIX.as_bytes(),
108            store.token_metadata_program.as_ref(),
109            &open_edition_metadata.mint.as_ref(),
110            mpl_token_metadata::state::EDITION.as_bytes(),
111        ],
112    )?;
113
114    // Assert the holding account for authorization tokens is rent filled, owned correctly, and ours
115    assert_owned_by(
116        printing_authorization_token_account_info,
117        &store.token_program,
118    )?;
119    assert_rent_exempt(rent, printing_authorization_token_account_info)?;
120
121    if printing_token_account.owner != *auction_manager_info.key {
122        return Err(MetaplexError::IncorrectOwner.into());
123    }
124
125    if printing_token_account.mint != master_edition.printing_mint {
126        return Err(MetaplexError::PrintingTokenAccountMintMismatch.into());
127    }
128
129    if printing_token_account.delegate != COption::None {
130        return Err(MetaplexError::DelegateShouldBeNone.into());
131    }
132
133    if printing_token_account.close_authority != COption::None {
134        return Err(MetaplexError::CloseAuthorityShouldBeNone.into());
135    }
136
137    if master_edition.max_supply.is_some() {
138        return Err(MetaplexError::CantUseLimitedSupplyEditionsWithOpenEditionAuction.into());
139    }
140
141    if master_edition.one_time_printing_authorization_mint != safety_deposit_token_store.mint {
142        return Err(MetaplexError::MasterEditionOneTimeAuthorizationMintMismatch.into());
143    }
144
145    if let Some(participation_config) = &auction_manager.settings.participation_config {
146        if participation_config.safety_deposit_box_index > vault.token_type_count {
147            return Err(MetaplexError::InvalidSafetyDepositBox.into());
148        }
149
150        if participation_config.safety_deposit_box_index != safety_deposit.order {
151            return Err(MetaplexError::SafetyDepositIndexMismatch.into());
152        }
153
154        if let Some(state) = auction_manager.state.participation_state {
155            if state.validated {
156                return Err(MetaplexError::AlreadyValidated.into());
157            }
158
159            auction_manager.state.participation_state = Some(ParticipationStateV1 {
160                collected_to_accept_payment: state.collected_to_accept_payment,
161                primary_sale_happened: open_edition_metadata.primary_sale_happened,
162                validated: true,
163                printing_authorization_token_account: Some(
164                    *printing_authorization_token_account_info.key,
165                ),
166            });
167        }
168
169        if auction_manager.settings.winning_configs.is_empty() {
170            auction_manager.state.status = AuctionManagerStatus::Validated;
171        }
172        auction_manager.serialize(&mut *auction_manager_info.data.borrow_mut())?;
173    }
174
175    Ok(())
176}