ywpl_plex/processor/
deprecated_validate_safety_deposit_box_v1.rs

1use super::validate_safety_deposit_box_v2::{
2    assert_common_checks, assert_supply_logic_check, CommonCheckArgs, SupplyLogicCheckArgs,
3};
4use crate::{
5    deprecated_state::{
6        AuctionManagerV1, ParticipationStateV1, SafetyDepositValidationTicket,
7        MAX_VALIDATION_TICKET_SIZE,
8    },
9    error::MetaplexError,
10    state::{AuctionManagerStatus, Key, Store, WinningConfigType, PREFIX},
11    utils::{assert_derivation, assert_initialized, create_or_allocate_account_raw},
12};
13use borsh::BorshSerialize;
14use mpl_token_metadata::state::Metadata;
15use ywpl_token_vault::state::{SafetyDepositBox, Vault};
16use solana_program::{
17    account_info::{next_account_info, AccountInfo},
18    entrypoint::ProgramResult,
19    pubkey::Pubkey,
20};
21use spl_token::state::Account;
22pub fn make_safety_deposit_validation<'a>(
23    program_id: &Pubkey,
24    auction_manager_info: &AccountInfo<'a>,
25    safety_deposit_info: &AccountInfo<'a>,
26    safety_deposit_validation_ticket_info: &AccountInfo<'a>,
27    payer_info: &AccountInfo<'a>,
28    rent_info: &AccountInfo<'a>,
29    system_info: &AccountInfo<'a>,
30) -> ProgramResult {
31    let bump = assert_derivation(
32        program_id,
33        safety_deposit_validation_ticket_info,
34        &[
35            PREFIX.as_bytes(),
36            program_id.as_ref(),
37            auction_manager_info.key.as_ref(),
38            safety_deposit_info.key.as_ref(),
39        ],
40    )?;
41
42    create_or_allocate_account_raw(
43        *program_id,
44        safety_deposit_validation_ticket_info,
45        rent_info,
46        system_info,
47        payer_info,
48        MAX_VALIDATION_TICKET_SIZE,
49        &[
50            PREFIX.as_bytes(),
51            program_id.as_ref(),
52            auction_manager_info.key.as_ref(),
53            safety_deposit_info.key.as_ref(),
54            &[bump],
55        ],
56    )?;
57
58    let mut validation =
59        SafetyDepositValidationTicket::from_account_info(safety_deposit_validation_ticket_info)?;
60    validation.key = Key::SafetyDepositValidationTicketV1;
61    validation.address = *safety_deposit_info.key;
62    validation.serialize(&mut *safety_deposit_validation_ticket_info.data.borrow_mut())?;
63
64    Ok(())
65}
66
67pub fn process_deprecated_validate_safety_deposit_box_v1<'a>(
68    program_id: &'a Pubkey,
69    accounts: &'a [AccountInfo<'a>],
70) -> ProgramResult {
71    let account_info_iter = &mut accounts.iter();
72    let safety_deposit_validation_ticket_info = next_account_info(account_info_iter)?;
73    let auction_manager_info = next_account_info(account_info_iter)?;
74    let metadata_info = next_account_info(account_info_iter)?;
75    let original_authority_lookup_info = next_account_info(account_info_iter)?;
76    let whitelisted_creator_info = next_account_info(account_info_iter)?;
77    let auction_manager_store_info = next_account_info(account_info_iter)?;
78    let safety_deposit_info = next_account_info(account_info_iter)?;
79    let safety_deposit_token_store_info = next_account_info(account_info_iter)?;
80    let mint_info = next_account_info(account_info_iter)?;
81    let edition_info = next_account_info(account_info_iter)?;
82    let vault_info = next_account_info(account_info_iter)?;
83    let authority_info = next_account_info(account_info_iter)?;
84    let metadata_authority_info = next_account_info(account_info_iter)?;
85    let payer_info = next_account_info(account_info_iter)?;
86    let token_metadata_program_info = next_account_info(account_info_iter)?;
87    let system_info = next_account_info(account_info_iter)?;
88    let rent_info = next_account_info(account_info_iter)?;
89
90    if !safety_deposit_validation_ticket_info.data_is_empty() {
91        return Err(MetaplexError::AlreadyValidated.into());
92    }
93
94    let mut auction_manager = AuctionManagerV1::from_account_info(auction_manager_info)?;
95    let safety_deposit = SafetyDepositBox::from_account_info(safety_deposit_info)?;
96    let _safety_deposit_token_store: Account = assert_initialized(safety_deposit_token_store_info)?;
97    let metadata = Metadata::from_account_info(metadata_info)?;
98    let store = Store::from_account_info(auction_manager_store_info)?;
99    // Is it a real vault?
100    let vault = Vault::from_account_info(vault_info)?;
101
102    let mut total_amount_requested: u64 = 0;
103    // At this point we know we have at least one config and they may have different amounts but all
104    // point at the same safety deposit box and so have the same winning config type.
105    // We default to TokenOnlyTransfer but this will get set by the loop.
106    let mut winning_config_type: WinningConfigType = WinningConfigType::TokenOnlyTransfer;
107    let mut winning_config_items_validated: u8 = 0;
108    let mut all_winning_config_items: u8 = 0;
109
110    for i in 0..auction_manager.settings.winning_configs.len() {
111        let possible_config = &auction_manager.settings.winning_configs[i];
112
113        for j in 0..possible_config.items.len() {
114            let possible_item = &possible_config.items[j];
115            all_winning_config_items = all_winning_config_items
116                .checked_add(1)
117                .ok_or(MetaplexError::NumericalOverflowError)?;
118
119            if possible_item.safety_deposit_box_index == safety_deposit.order {
120                winning_config_type = possible_item.winning_config_type;
121
122                winning_config_items_validated = winning_config_items_validated
123                    .checked_add(1)
124                    .ok_or(MetaplexError::NumericalOverflowError)?;
125
126                // Build array to sum total amount
127                total_amount_requested = total_amount_requested
128                    .checked_add(possible_item.amount.into())
129                    .ok_or(MetaplexError::NumericalOverflowError)?;
130                // Record that primary sale happened at time of validation for later royalties reconcilation
131                auction_manager.state.winning_config_states[i].items[j].primary_sale_happened =
132                    metadata.primary_sale_happened;
133            }
134        }
135    }
136
137    if let Some(participation_config) = &auction_manager.settings.participation_config {
138        if participation_config.safety_deposit_box_index == safety_deposit.order {
139            // Really it's unknown how many prints will be made
140            // but we set it to 1 since that's how many master edition tokens are in there.
141            total_amount_requested = total_amount_requested
142                .checked_add(1)
143                .ok_or(MetaplexError::NumericalOverflowError)?;
144
145            // now that participation configs can be validated through normal safety deposit endpoints, need to flip this boolean
146            // here too, until we can deprecate it later.
147            if let Some(state) = &auction_manager.state.participation_state {
148                auction_manager.state.participation_state = Some(ParticipationStateV1 {
149                    collected_to_accept_payment: state.collected_to_accept_payment,
150                    primary_sale_happened: state.primary_sale_happened,
151                    validated: true,
152                    printing_authorization_token_account: state
153                        .printing_authorization_token_account,
154                })
155            }
156        }
157    }
158
159    if total_amount_requested == 0 {
160        return Err(MetaplexError::SafetyDepositBoxNotUsedInAuction.into());
161    }
162
163    assert_common_checks(CommonCheckArgs {
164        program_id,
165        auction_manager_info,
166        metadata_info,
167        original_authority_lookup_info,
168        whitelisted_creator_info,
169        safety_deposit_info,
170        safety_deposit_token_store_info,
171        edition_info,
172        vault_info,
173        mint_info,
174        token_metadata_program_info,
175        auction_manager_store_info,
176        authority_info,
177        store: &store,
178        auction_manager: &auction_manager,
179        metadata: &metadata,
180        safety_deposit: &safety_deposit,
181        vault: &vault,
182        winning_config_type: &winning_config_type,
183    })?;
184
185    assert_supply_logic_check(SupplyLogicCheckArgs {
186        program_id,
187        auction_manager_info,
188        metadata_info,
189        edition_info,
190        metadata_authority_info,
191        original_authority_lookup_info,
192        rent_info,
193        system_info,
194        payer_info,
195        token_metadata_program_info,
196        auction_manager: &auction_manager,
197        winning_config_type: &winning_config_type,
198        metadata: &metadata,
199        safety_deposit: &safety_deposit,
200        store: &store,
201        safety_deposit_token_store_info,
202        total_amount_requested,
203    })?;
204
205    auction_manager.state.winning_config_items_validated = match auction_manager
206        .state
207        .winning_config_items_validated
208        .checked_add(winning_config_items_validated)
209    {
210        Some(val) => val,
211        None => return Err(MetaplexError::NumericalOverflowError.into()),
212    };
213
214    if auction_manager.state.winning_config_items_validated == all_winning_config_items {
215        let mut participation_okay = true;
216        if let Some(state) = &auction_manager.state.participation_state {
217            participation_okay = state.validated
218        }
219        if participation_okay {
220            auction_manager.state.status = AuctionManagerStatus::Validated
221        }
222    }
223
224    auction_manager.serialize(&mut *auction_manager_info.data.borrow_mut())?;
225
226    make_safety_deposit_validation(
227        program_id,
228        auction_manager_info,
229        safety_deposit_info,
230        safety_deposit_validation_ticket_info,
231        payer_info,
232        rent_info,
233        system_info,
234    )?;
235
236    Ok(())
237}