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