@@ -9,8 +9,8 @@ use solana_program::{instruction::Instruction, program::invoke_signed_unchecked}
9
9
10
10
use crate :: {
11
11
error:: MatchingEngineError ,
12
+ processor:: { get_user_amount_and_new_status_and_penalized, ActiveAuctionAccountInfos } ,
12
13
state:: { Auction , AuctionStatus , Custodian , MessageProtocol } ,
13
- utils:: { self , auction:: DepositPenalty } ,
14
14
ID ,
15
15
} ;
16
16
@@ -340,193 +340,28 @@ pub(super) fn process(accounts: &[AccountInfo]) -> Result<()> {
340
340
// TODO: Do we have to verify the CCTP message transmitter program is passed
341
341
// in?
342
342
343
- ////////////////////////////////////////////////////////////////////////////
344
- //
345
- // TODO: This execute order logic has been taken from the original execute
346
- // order instructions. We plan on using a helper method instead of copy-
347
- // pasting the same logic here.
348
- //
349
- ////////////////////////////////////////////////////////////////////////////
350
-
351
343
// Prepare the execute order (get the user amount, fill, and order executed event)
352
- let current_slot = Clock :: get ( ) . unwrap ( ) . slot ;
353
-
354
- // We extend the grace period for locally executed orders. Reserving a sequence number for
355
- // the fast fill will most likely require an additional transaction, so this buffer allows
356
- // the best offer participant to perform his duty without the risk of getting slashed by
357
- // another executor.
358
- let additional_grace_period = match active_auction. target_protocol {
359
- MessageProtocol :: Local { .. } => {
360
- crate :: EXECUTE_FAST_ORDER_LOCAL_ADDITIONAL_GRACE_PERIOD . into ( )
361
- }
362
- _ => None ,
344
+ let active_auction_accounts = ActiveAuctionAccountInfos {
345
+ auction_best_offer_token : auction_best_offer_token_info. to_account_info ( ) ,
346
+ auction_executor_token : executor_token_info. to_account_info ( ) ,
347
+ auction_initial_offer_token : auction_initial_offer_token_info. to_account_info ( ) ,
348
+ auction_custody_token : auction_custody_info. to_account_info ( ) ,
349
+ active_auction : active_auction_info. to_account_info ( ) ,
350
+ auction_custodian : custodian_info. to_account_info ( ) ,
363
351
} ;
364
-
365
- let DepositPenalty {
366
- penalty,
367
- user_reward,
368
- } = utils:: auction:: compute_deposit_penalty (
369
- & auction_config,
370
- active_auction_inner_info,
371
- current_slot,
372
- additional_grace_period,
373
- ) ;
374
-
375
- let init_auction_fee = fast_market_order. init_auction_fee ;
376
-
377
- let user_amount = active_auction_inner_info
378
- . amount_in
379
- . saturating_sub ( active_auction_inner_info. offer_price )
380
- . saturating_sub ( init_auction_fee)
381
- . saturating_add ( user_reward) ;
382
-
383
- // Keep track of the remaining amount in the custody token account. Whatever remains will go
384
- // to the executor.
385
-
386
352
let custody_token =
387
353
TokenAccount :: try_deserialize ( & mut & auction_custody_info. data . borrow ( ) [ ..] ) ?;
388
- let mut remaining_custodied_amount = custody_token. amount . saturating_sub ( user_amount) ;
389
-
390
- // Offer price + security deposit was checked in placing the initial offer.
391
- let mut deposit_and_fee = active_auction_inner_info
392
- . offer_price
393
- . saturating_add ( active_auction_inner_info. security_deposit )
394
- . saturating_sub ( user_reward) ;
395
-
396
- let penalized = penalty > 0 ;
397
-
398
- if penalized && auction_best_offer_token_info. key != executor_token_info. key {
399
- deposit_and_fee = deposit_and_fee. saturating_sub ( penalty) ;
400
- }
401
-
402
- // Need these seeds in order to transfer tokens and then set authority of auction custody token account to the custodian
403
- let auction_signer_seeds = & [
404
- Auction :: SEED_PREFIX ,
405
- active_auction. vaa_hash . as_ref ( ) ,
406
- & [ active_auction. bump ] ,
407
- ] ;
408
-
409
- // If the initial offer token account doesn't exist anymore, we have nowhere to send the
410
- // init auction fee. The executor will get these funds instead.
411
- //
412
- // We check that this is a legitimate token account.
413
- if utils:: checked_deserialize_token_account (
414
- auction_initial_offer_token_info,
415
- & common:: USDC_MINT ,
416
- )
417
- . is_some ( )
418
- {
419
- if auction_best_offer_token_info. key ( ) != auction_initial_offer_token_info. key ( ) {
420
- // Pay the auction initiator their fee.
421
- let transfer_ix = spl_token:: instruction:: transfer (
422
- & spl_token:: ID ,
423
- & auction_custody_info. key ( ) ,
424
- & auction_initial_offer_token_info. key ( ) ,
425
- & active_auction_info. key ( ) ,
426
- & [ ] ,
427
- init_auction_fee,
428
- )
429
- . unwrap ( ) ;
430
-
431
- invoke_signed_unchecked ( & transfer_ix, accounts, & [ auction_signer_seeds] ) ?;
432
- // Because the initial offer token was paid this fee, we account for it here.
433
- remaining_custodied_amount =
434
- remaining_custodied_amount. saturating_sub ( init_auction_fee) ;
435
- } else {
436
- // Add it to the reimbursement.
437
- deposit_and_fee = deposit_and_fee
438
- . checked_add ( init_auction_fee)
439
- . ok_or_else ( || MatchingEngineError :: U64Overflow ) ?;
440
- }
441
- }
442
-
443
- // Return the security deposit and the fee to the highest bidder.
444
- if auction_best_offer_token_info. key == executor_token_info. key {
445
- // If the best offer token is equal to the executor token, just send whatever remains in
446
- // the custody token account.
447
- //
448
- // NOTE: This will revert if the best offer token does not exist. But this will present
449
- // an opportunity for another executor to execute this order and take what the best
450
- // offer token would have received.
451
- let transfer_ix = spl_token:: instruction:: transfer (
452
- & spl_token:: ID ,
453
- & auction_custody_info. key ( ) ,
454
- & auction_best_offer_token_info. key ( ) ,
455
- & active_auction_info. key ( ) ,
456
- & [ ] ,
457
- deposit_and_fee,
458
- )
459
- . unwrap ( ) ;
460
- msg ! (
461
- "Sending deposit and fee amount {} to best offer token account" ,
462
- deposit_and_fee
463
- ) ;
464
- invoke_signed_unchecked ( & transfer_ix, accounts, & [ auction_signer_seeds] ) ?;
465
- } else {
466
- // Otherwise, send the deposit and fee to the best offer token. If the best offer token
467
- // doesn't exist at this point (which would be unusual), we will reserve these funds
468
- // for the executor token.
469
- if utils:: checked_deserialize_token_account (
470
- auction_best_offer_token_info,
471
- & common:: USDC_MINT ,
472
- )
473
- . is_some ( )
474
- {
475
- let transfer_ix = spl_token:: instruction:: transfer (
476
- & spl_token:: ID ,
477
- & auction_custody_info. key ( ) ,
478
- & auction_best_offer_token_info. key ( ) ,
479
- & active_auction_info. key ( ) ,
480
- & [ ] ,
481
- deposit_and_fee,
482
- )
483
- . unwrap ( ) ;
484
- msg ! (
485
- "Sending deposit and fee {} to best offer token account" ,
486
- deposit_and_fee
487
- ) ;
488
- invoke_signed_unchecked ( & transfer_ix, accounts, & [ auction_signer_seeds] ) ?;
489
- remaining_custodied_amount = remaining_custodied_amount. saturating_sub ( deposit_and_fee) ;
490
- }
491
-
492
- // And pay the executor whatever remains in the auction custody token account.
493
- if remaining_custodied_amount > 0 {
494
- let instruction = spl_token:: instruction:: transfer (
495
- & spl_token:: ID ,
496
- auction_custody_info. key ,
497
- executor_token_info. key ,
498
- & active_auction_info. key ( ) ,
499
- & [ ] ,
500
- remaining_custodied_amount,
501
- )
502
- . unwrap ( ) ;
503
- msg ! (
504
- "Sending remaining custodied amount {} to executor token account" ,
505
- remaining_custodied_amount
506
- ) ;
507
- invoke_signed_unchecked ( & instruction, accounts, & [ auction_signer_seeds] ) ?;
508
- }
509
- }
510
-
511
- // Set the authority of the custody token account to the custodian. He will take over from
512
- // here.
513
- let set_authority_ix = spl_token:: instruction:: set_authority (
514
- & spl_token:: ID ,
515
- auction_custody_info. key ,
516
- Some ( custodian_info. key ) ,
517
- spl_token:: instruction:: AuthorityType :: AccountOwner ,
518
- active_auction_info. key ,
519
- & [ ] ,
520
- )
521
- . unwrap ( ) ;
522
-
523
- invoke_signed_unchecked ( & set_authority_ix, accounts, & [ auction_signer_seeds] ) ?;
354
+ let ( user_amount, new_status, _penalized) = get_user_amount_and_new_status_and_penalized (
355
+ & active_auction,
356
+ & custody_token,
357
+ & auction_config,
358
+ fast_market_order. init_auction_fee ,
359
+ active_auction_accounts,
360
+ accounts,
361
+ ) ?;
524
362
525
363
// Set the active auction status
526
- active_auction. status = AuctionStatus :: Completed {
527
- slot : current_slot,
528
- execute_penalty : if penalized { penalty. into ( ) } else { None } ,
529
- } ;
364
+ active_auction. status = new_status;
530
365
531
366
let active_auction_info_data: & mut [ u8 ] = & mut active_auction_info. data . borrow_mut ( ) ;
532
367
let mut active_auction_cursor = std:: io:: Cursor :: new ( active_auction_info_data) ;
@@ -543,12 +378,6 @@ pub(super) fn process(accounts: &[AccountInfo]) -> Result<()> {
543
378
. unwrap ( ) ,
544
379
} ;
545
380
546
- ////////////////////////////////////////////////////////////////////////////
547
- //
548
- // TODO: See above TODO. This is the end of the copy-pasted logic.
549
- //
550
- ////////////////////////////////////////////////////////////////////////////
551
-
552
381
// TODO: Write test that passes in random keypair for CCTP message account
553
382
// to show that not having to check the PDA address is safe.
554
383
let ( _, new_cctp_message_bump) = Pubkey :: find_program_address (
0 commit comments