Skip to content

Commit 8939621

Browse files
author
Bengt Lofgren
committed
place initial offer comments
1 parent cc8039f commit 8939621

File tree

4 files changed

+104
-53
lines changed

4 files changed

+104
-53
lines changed

solana/programs/matching-engine/src/fallback/processor/execute_order.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,8 +197,8 @@ pub fn handle_execute_order_shim(accounts: &[AccountInfo]) -> Result<()> {
197197
// Do checks
198198
// ------------------------------------------------------------------------------------------------
199199

200-
let fast_market_order_zero_copy =
201-
FastMarketOrderState::try_deserialize(&mut &fast_market_order_account.data.borrow()[..])?;
200+
let fast_market_order_data = &fast_market_order_account.data.borrow()[..];
201+
let fast_market_order_zero_copy = FastMarketOrderState::try_read(fast_market_order_data)?;
202202
// Bind value for compiler (needed for pda seeds)
203203
let active_auction_key = active_auction_account.key();
204204

solana/programs/matching-engine/src/fallback/processor/helpers.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use anchor_lang::prelude::*;
22

3+
use anchor_spl::token::spl_token;
34
use solana_program::{
45
entrypoint::ProgramResult,
56
instruction::{AccountMeta, Instruction},
@@ -129,3 +130,51 @@ pub fn create_account_reliably(
129130

130131
Ok(())
131132
}
133+
134+
/// Create a token account reliably
135+
///
136+
/// This function creates a token account and initializes it with the given mint and owner.
137+
///
138+
/// # Arguments
139+
///
140+
/// * `payer_pubkey` - The pubkey of the account that will pay for the token account.
141+
/// * `account_pubkey_to_create` - The pubkey of the account to create.
142+
/// * `owner_account_info` - The account info of the owner of the token account.
143+
/// * `mint_pubkey` - The pubkey of the mint.
144+
/// * `data_len` - The length of the data to be written to the token account.
145+
/// * `accounts` - The accounts to be used in the CPI.
146+
/// * `signer_seeds` - The signer seeds to be used in the CPI.
147+
#[allow(clippy::too_many_arguments)]
148+
pub fn create_token_account_reliably(
149+
payer_pubkey: &Pubkey,
150+
account_pubkey_to_create: &Pubkey,
151+
owner_account_pubkey: &Pubkey,
152+
mint_pubkey: &Pubkey,
153+
data_len: usize,
154+
token_account_lamports: u64,
155+
accounts: &[AccountInfo],
156+
signer_seeds: &[&[&[u8]]],
157+
) -> ProgramResult {
158+
// Create the owner account
159+
create_account_reliably(
160+
payer_pubkey,
161+
account_pubkey_to_create,
162+
token_account_lamports,
163+
data_len,
164+
accounts,
165+
&spl_token::ID,
166+
signer_seeds,
167+
)?;
168+
169+
// Create the token account
170+
let init_token_account_ix = spl_token::instruction::initialize_account3(
171+
&spl_token::ID,
172+
account_pubkey_to_create,
173+
mint_pubkey,
174+
owner_account_pubkey,
175+
)?;
176+
177+
solana_program::program::invoke_signed_unchecked(&init_token_account_ix, accounts, &[])?;
178+
179+
Ok(())
180+
}

solana/programs/matching-engine/src/fallback/processor/place_initial_offer.rs

Lines changed: 51 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
use super::helpers::check_account_length;
22
use super::helpers::create_account_reliably;
3+
use super::helpers::create_token_account_reliably;
4+
use crate::state::MessageProtocol;
35
use crate::state::{
46
Auction, AuctionConfig, AuctionInfo, AuctionStatus, Custodian,
5-
FastMarketOrder as FastMarketOrderState, MessageProtocol, RouterEndpoint,
7+
FastMarketOrder as FastMarketOrderState, RouterEndpoint,
68
};
79
use crate::ID as PROGRAM_ID;
810
use anchor_lang::prelude::*;
@@ -25,29 +27,38 @@ pub struct PlaceInitialOfferCctpShimData {
2527
}
2628

2729
impl PlaceInitialOfferCctpShimData {
28-
pub fn new(offer_price: u64) -> Self {
29-
Self { offer_price }
30-
}
31-
3230
pub fn from_bytes(data: &[u8]) -> Option<&Self> {
3331
bytemuck::try_from_bytes::<Self>(data).ok()
3432
}
3533
}
3634

3735
#[derive(Debug, Clone, PartialEq, Eq, Copy)]
3836
pub struct PlaceInitialOfferCctpShimAccounts<'ix> {
37+
/// The signer account
3938
pub signer: &'ix Pubkey,
39+
/// The transfer authority account
4040
pub transfer_authority: &'ix Pubkey,
41+
/// The custodian account
4142
pub custodian: &'ix Pubkey,
43+
/// The auction config account
4244
pub auction_config: &'ix Pubkey,
45+
/// The from endpoint account
4346
pub from_endpoint: &'ix Pubkey,
47+
/// The to endpoint account
4448
pub to_endpoint: &'ix Pubkey,
45-
pub fast_market_order: &'ix Pubkey, // Needs initalising. Seeds are [FastMarketOrderState::SEED_PREFIX, auction_address.as_ref()]
46-
pub auction: &'ix Pubkey, // Needs initalising
49+
/// The fast market order account, which will be initialised. Seeds are [FastMarketOrderState::SEED_PREFIX, auction_address.as_ref()]
50+
pub fast_market_order: &'ix Pubkey,
51+
/// The auction account, which will be initialised
52+
pub auction: &'ix Pubkey,
53+
/// The offer token account
4754
pub offer_token: &'ix Pubkey,
55+
/// The auction custody token account
4856
pub auction_custody_token: &'ix Pubkey,
57+
/// The usdc token account
4958
pub usdc: &'ix Pubkey,
59+
/// The system program account
5060
pub system_program: &'ix Pubkey,
61+
/// The token program account
5162
pub token_program: &'ix Pubkey,
5263
}
5364

@@ -119,8 +130,7 @@ impl VaaMessageBodyHeader {
119130
}
120131
}
121132

122-
/// This function creates both the message body and the payload.
123-
/// This is all done here just because it's (supposedly?) cheaper in the solana vm.
133+
/// This function creates both the message body for the fast market order, including the payload.
124134
pub fn message_body(&self, fast_market_order: &FastMarketOrderState) -> Vec<u8> {
125135
let mut message_body = vec![];
126136
message_body.extend_from_slice(&self.vaa_time.to_be_bytes());
@@ -129,44 +139,48 @@ impl VaaMessageBodyHeader {
129139
message_body.extend_from_slice(&self.emitter_address);
130140
message_body.extend_from_slice(&self.sequence.to_be_bytes());
131141
message_body.extend_from_slice(&[self.consistency_level]);
132-
let mut payload = vec![];
133-
payload.push(11_u8);
134-
payload.extend_from_slice(&fast_market_order.amount_in.to_be_bytes());
135-
payload.extend_from_slice(&fast_market_order.min_amount_out.to_be_bytes());
136-
payload.extend_from_slice(&fast_market_order.target_chain.to_be_bytes());
137-
payload.extend_from_slice(&fast_market_order.redeemer);
138-
payload.extend_from_slice(&fast_market_order.sender);
139-
payload.extend_from_slice(&fast_market_order.refund_address);
140-
payload.extend_from_slice(&fast_market_order.max_fee.to_be_bytes());
141-
payload.extend_from_slice(&fast_market_order.init_auction_fee.to_be_bytes());
142-
payload.extend_from_slice(&fast_market_order.deadline.to_be_bytes());
143-
payload.extend_from_slice(&fast_market_order.redeemer_message_length.to_be_bytes());
142+
message_body.push(11_u8);
143+
message_body.extend_from_slice(&fast_market_order.amount_in.to_be_bytes());
144+
message_body.extend_from_slice(&fast_market_order.min_amount_out.to_be_bytes());
145+
message_body.extend_from_slice(&fast_market_order.target_chain.to_be_bytes());
146+
message_body.extend_from_slice(&fast_market_order.redeemer);
147+
message_body.extend_from_slice(&fast_market_order.sender);
148+
message_body.extend_from_slice(&fast_market_order.refund_address);
149+
message_body.extend_from_slice(&fast_market_order.max_fee.to_be_bytes());
150+
message_body.extend_from_slice(&fast_market_order.init_auction_fee.to_be_bytes());
151+
message_body.extend_from_slice(&fast_market_order.deadline.to_be_bytes());
152+
message_body.extend_from_slice(&fast_market_order.redeemer_message_length.to_be_bytes());
144153
if fast_market_order.redeemer_message_length > 0 {
145-
payload.extend_from_slice(
154+
message_body.extend_from_slice(
146155
&fast_market_order.redeemer_message
147156
[..usize::from(fast_market_order.redeemer_message_length)],
148157
);
149158
}
150-
message_body.extend_from_slice(&payload);
151159
message_body
152160
}
153161

162+
/// This function creates the hash of the message body for the fast market order.
163+
/// This is used to create the digest.
154164
pub fn message_hash(&self, fast_market_order: &FastMarketOrderState) -> keccak::Hash {
155165
keccak::hashv(&[self.message_body(fast_market_order).as_ref()])
156166
}
157167

168+
/// The digest is the hash of the message hash.
158169
pub fn digest(&self, fast_market_order: &FastMarketOrderState) -> keccak::Hash {
159170
keccak::hashv(&[self.message_hash(fast_market_order).as_ref()])
160171
}
161172

173+
/// This function returns the vaa time.
162174
pub fn vaa_time(&self) -> u32 {
163175
self.vaa_time
164176
}
165177

178+
/// This function returns the sequence number of the fast market order.
166179
pub fn sequence(&self) -> u64 {
167180
self.sequence
168181
}
169182

183+
/// This function returns the emitter chain of the fast market order.
170184
pub fn emitter_chain(&self) -> u16 {
171185
self.emitter_chain
172186
}
@@ -176,8 +190,7 @@ pub fn place_initial_offer_cctp_shim(
176190
accounts: &[AccountInfo],
177191
data: &PlaceInitialOfferCctpShimData,
178192
) -> Result<()> {
179-
// Check account owners
180-
let program_id = &crate::ID; // Your program ID
193+
let program_id = &PROGRAM_ID; // Your program ID
181194

182195
// Check all accounts are valid
183196
check_account_length(accounts, 11)?;
@@ -204,8 +217,8 @@ pub fn place_initial_offer_cctp_shim(
204217
.map_err(|e: Error| e.with_account_name("fast_market_order_account"));
205218
}
206219

207-
let fast_market_order_zero_copy =
208-
FastMarketOrderState::try_deserialize(&mut &fast_market_order_account.data.borrow()[..])?;
220+
let fast_market_order_data = &fast_market_order_account.data.borrow()[..];
221+
let fast_market_order_zero_copy = FastMarketOrderState::try_read(fast_market_order_data)?;
209222

210223
let vaa_time = fast_market_order_zero_copy.vaa_timestamp;
211224
let sequence = fast_market_order_zero_copy.vaa_sequence;
@@ -303,16 +316,16 @@ pub fn place_initial_offer_cctp_shim(
303316
return Err(MatchingEngineError::SameEndpoint.into());
304317
}
305318

306-
// Check that the to endpoint protocol is cctp or local
319+
// Check that the to endpoint is a valid protocol
307320
match to_endpoint_account.protocol {
308321
MessageProtocol::Cctp { .. } | MessageProtocol::Local { .. } => (),
309322
_ => return Err(MatchingEngineError::InvalidEndpoint.into()),
310323
}
311324

312-
// Check that the from endpoint protocol is cctp or local
313-
match from_endpoint_account.protocol {
314-
MessageProtocol::Cctp { .. } | MessageProtocol::Local { .. } => (),
315-
_ => return Err(MatchingEngineError::InvalidEndpoint.into()),
325+
// Check that the vaa emitter address equals the from_endpoints encoded address
326+
if from_endpoint_account.address != fast_market_order_zero_copy.vaa_emitter_address {
327+
msg!("Vaa emitter address is not equal to the from_endpoints encoded address");
328+
return Err(MatchingEngineError::InvalidSourceRouter.into());
316329
}
317330

318331
// Check that to endpoint chain is equal to the fast_market_order target_chain
@@ -349,8 +362,6 @@ pub fn place_initial_offer_cctp_shim(
349362

350363
// Begin of initialisation of auction custody token account
351364
// ------------------------------------------------------------------------------------------------
352-
let auction_custody_token_space = spl_token::state::Account::LEN;
353-
354365
let (auction_custody_token_pda, auction_custody_token_bump) = Pubkey::find_program_address(
355366
&[
356367
crate::AUCTION_CUSTODY_TOKEN_SEED_PREFIX,
@@ -373,25 +384,17 @@ pub fn place_initial_offer_cctp_shim(
373384
&[auction_custody_token_bump],
374385
];
375386
let auction_custody_token_signer_seeds = &[&auction_custody_token_seeds[..]];
376-
create_account_reliably(
387+
388+
create_token_account_reliably(
377389
&signer.key(),
378390
&auction_custody_token_pda,
391+
&auction_account.key(),
392+
&usdc.key(),
393+
spl_token::state::Account::LEN,
379394
auction_custody_token.lamports(),
380-
auction_custody_token_space,
381395
accounts,
382-
&spl_token::ID,
383396
auction_custody_token_signer_seeds,
384397
)?;
385-
// Initialise the token account
386-
let init_token_account_ix = spl_token::instruction::initialize_account3(
387-
&spl_token::ID,
388-
&auction_custody_token_pda,
389-
&usdc.key(),
390-
&auction_account.key(),
391-
)
392-
.unwrap();
393-
394-
solana_program::program::invoke(&init_token_account_ix, accounts).unwrap();
395398

396399
// ------------------------------------------------------------------------------------------------
397400
// End of initialisation of auction custody token account
@@ -494,8 +497,7 @@ pub fn place_initial_offer_cctp_shim(
494497
&offer_price.to_be_bytes(),
495498
&[transfer_authority_bump],
496499
]],
497-
)
498-
.map_err(|_| MatchingEngineError::TokenTransferFailed)?;
500+
)?;
499501
// ------------------------------------------------------------------------------------------------
500502
// End of token transfer from offer token to auction custody token
501503
Ok(())

solana/programs/matching-engine/src/fallback/processor/prepare_order_response.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -226,9 +226,9 @@ pub fn prepare_order_response_cctp_shim(
226226
.map_err(|_| MatchingEngineError::InvalidCctpMessage)?;
227227

228228
// Load accounts
229-
let fast_market_order_account_data = fast_market_order.data.borrow();
229+
let fast_market_order_account_data = &fast_market_order.data.borrow()[..];
230230
let fast_market_order_zero_copy =
231-
FastMarketOrderState::try_read(&fast_market_order_account_data[..])?;
231+
FastMarketOrderState::try_read(fast_market_order_account_data)?;
232232
// Create pdas for addresses that need to be created
233233
// Check the prepared order response account is valid
234234
let fast_market_order_digest = fast_market_order_zero_copy.digest();

0 commit comments

Comments
 (0)