Skip to content

Commit 2654643

Browse files
committed
solana: clean up close fast market order
1 parent da9b5ff commit 2654643

File tree

1 file changed

+46
-59
lines changed

1 file changed

+46
-59
lines changed
Lines changed: 46 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,94 +1,81 @@
1-
use crate::error::MatchingEngineError;
2-
use crate::state::FastMarketOrder;
31
use anchor_lang::prelude::*;
42
use solana_program::instruction::Instruction;
5-
use solana_program::program_error::ProgramError;
63

7-
use super::helpers::require_min_account_infos_len;
8-
use super::FallbackMatchingEngineInstruction;
4+
use crate::{error::MatchingEngineError, state::FastMarketOrder};
95

106
pub struct CloseFastMarketOrderAccounts<'ix> {
11-
/// The fast market order account created from the initialize fast market order instruction
7+
/// The fast market order account to be closed.
128
pub fast_market_order: &'ix Pubkey,
13-
/// The account that will receive the refund. CHECK: Must be a signer.
14-
/// CHECK: Must match the close account refund recipient in the fast market order account
9+
/// The account that will receive rent from the fast market order account.
10+
/// This account is the only authority that can close the fast market order.
11+
/// TODO: Rename to "refund_recipient".
1512
pub close_account_refund_recipient: &'ix Pubkey,
1613
}
1714

18-
impl<'ix> CloseFastMarketOrderAccounts<'ix> {
19-
pub fn to_account_metas(&self) -> Vec<AccountMeta> {
20-
vec![
21-
AccountMeta::new(*self.fast_market_order, false),
22-
AccountMeta::new(*self.close_account_refund_recipient, true),
23-
]
24-
}
25-
}
26-
15+
/// Closes the fast market order and transfers the lamports from the fast market
16+
/// order to its refund recipient.
2717
pub struct CloseFastMarketOrder<'ix> {
2818
pub program_id: &'ix Pubkey,
2919
pub accounts: CloseFastMarketOrderAccounts<'ix>,
3020
}
3121

3222
impl CloseFastMarketOrder<'_> {
3323
pub fn instruction(&self) -> Instruction {
24+
let CloseFastMarketOrderAccounts {
25+
fast_market_order,
26+
close_account_refund_recipient: refund_recipient,
27+
} = self.accounts;
28+
3429
Instruction {
3530
program_id: *self.program_id,
36-
accounts: self.accounts.to_account_metas(),
37-
data: FallbackMatchingEngineInstruction::CloseFastMarketOrder.to_vec(),
31+
accounts: vec![
32+
AccountMeta::new(*fast_market_order, false),
33+
AccountMeta::new(*refund_recipient, true),
34+
],
35+
data: super::FallbackMatchingEngineInstruction::CloseFastMarketOrder.to_vec(),
3836
}
3937
}
4038
}
4139

42-
/// Closes the fast market order and transfers the lamports from the fast market order to the close account refund recipient
43-
///
44-
/// # Arguments
45-
///
46-
/// * `accounts` - The accounts of the fast market order and the close account refund recipient
47-
///
48-
/// # Returns
49-
///
50-
/// Result<()>
5140
pub fn close_fast_market_order(accounts: &[AccountInfo]) -> Result<()> {
52-
require_min_account_infos_len(accounts, 2)?;
41+
super::helpers::require_min_account_infos_len(accounts, 2)?;
5342

54-
let fast_market_order = &accounts[0];
55-
let close_account_refund_recipient = &accounts[1];
43+
// We need to check the refund recipient account against what we know as the
44+
// refund recipient encoded in the fast market order account.
45+
let fast_market_order_info = &accounts[0];
46+
let refund_recipient_info = &accounts[1];
5647

57-
// Check that the close_account_refund_recipient is a signer, otherwise someone might call this and steal the lamports
58-
if !close_account_refund_recipient.is_signer {
59-
msg!("Refund recipient (account #2) is not a signer");
60-
return Err(ProgramError::InvalidAccountData.into());
61-
}
62-
let fast_market_order_data = &fast_market_order.data.borrow()[..];
63-
let fast_market_order_deserialized = FastMarketOrder::try_read(fast_market_order_data)?;
64-
// Check that the fast_market_order is owned by the close_account_refund_recipient
65-
if fast_market_order_deserialized.close_account_refund_recipient
66-
!= close_account_refund_recipient.key()
67-
{
48+
let fast_market_order_data = &fast_market_order_info.data.borrow()[..];
49+
50+
// NOTE: We do not need to verify that the owner of this account is this
51+
// program because the lamport transfer will fail otherwise.
52+
let fast_market_order = FastMarketOrder::try_read(fast_market_order_data)?;
53+
54+
// Check that the refund recipient provided in this instruction is the one
55+
// encoded in the fast market order account.
56+
let expected_refund_recipient_key = fast_market_order.close_account_refund_recipient;
57+
if refund_recipient_info.key != &expected_refund_recipient_key {
6858
return Err(MatchingEngineError::MismatchingCloseAccountRefundRecipient.into()).map_err(
69-
|e: Error| {
70-
e.with_pubkeys((
71-
fast_market_order_deserialized.close_account_refund_recipient,
72-
close_account_refund_recipient.key(),
73-
))
74-
},
59+
|e: Error| e.with_pubkeys((*refund_recipient_info.key, expected_refund_recipient_key)),
7560
);
7661
}
7762

78-
// First, get the current lamports value
79-
let current_recipient_lamports = **close_account_refund_recipient.lamports.borrow();
80-
81-
// Then, get the fast market order lamports
82-
let mut fast_market_order_lamports = fast_market_order.lamports.borrow_mut();
63+
// This refund recipient must sign to invoke this instruction. He is the
64+
// only authority allowed to perform this action.
65+
if !refund_recipient_info.is_signer {
66+
return Err(ErrorCode::AccountNotSigner.into())
67+
.map_err(|e: Error| e.with_account_name("refund_recipient"));
68+
}
8369

84-
// Calculate the new amount
85-
let new_amount = current_recipient_lamports.saturating_add(**fast_market_order_lamports);
70+
let mut fast_market_order_info_lamports = fast_market_order_info.lamports.borrow_mut();
8671

87-
// Now update the recipient's lamports
88-
**close_account_refund_recipient.lamports.borrow_mut() = new_amount;
72+
// Move lamports to the refund recipient.
73+
let mut recipient_info_lamports = refund_recipient_info.lamports.borrow_mut();
74+
**recipient_info_lamports =
75+
recipient_info_lamports.saturating_add(**fast_market_order_info_lamports);
8976

90-
// Zero out the fast market order lamports
91-
**fast_market_order_lamports = 0;
77+
// Zero out the fast market order lamports.
78+
**fast_market_order_info_lamports = 0;
9279

9380
Ok(())
9481
}

0 commit comments

Comments
 (0)