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