1
+ use crate :: ID ;
1
2
use anchor_lang:: { prelude:: * , Discriminator } ;
2
3
use anchor_spl:: token:: { spl_token, TokenAccount } ;
3
4
use common:: wormhole_io:: TypePrefixedPayload ;
@@ -12,7 +13,7 @@ use crate::{
12
13
13
14
use super :: {
14
15
burn_and_post:: { burn_and_post, PostMessageAccounts , PostMessageDerivedAccounts } ,
15
- helpers:: { require_min_account_infos_len , create_account_reliably } ,
16
+ helpers:: { create_account_reliably , require_min_account_infos_len } ,
16
17
} ;
17
18
18
19
#[ derive( Copy , Clone ) ]
@@ -38,81 +39,81 @@ impl SettleAuctionNoneCctpShimData {
38
39
39
40
pub struct SettleAuctionNoneCctpShimAccounts < ' ix > {
40
41
/// Payer of the account
41
- pub payer : & ' ix Pubkey , // 0
42
+ pub payer : & ' ix Pubkey , // 0
42
43
/// Post shim message account
43
- pub post_shim_message : & ' ix Pubkey , // 1
44
+ pub post_shim_message : & ' ix Pubkey , // 1
44
45
/// Core bridge emitter sequence account
45
- pub core_bridge_emitter_sequence : & ' ix Pubkey , // 2
46
- /// Post message shim event authority CHECK: Mutable. Seeds must be \["core-msg", payer, payer_sequence.value\].
47
- pub post_message_shim_event_authority : & ' ix Pubkey , // 3
46
+ pub core_bridge_emitter_sequence : & ' ix Pubkey , // 2
47
+ /// Post message shim event authority
48
+ pub post_message_shim_event_authority : & ' ix Pubkey , // 3
48
49
/// Post message shim program
49
- pub post_message_shim_program : & ' ix Pubkey , // 4
50
- /// Cctp message
51
- pub cctp_message : & ' ix Pubkey , // 5
50
+ pub post_message_shim_program : & ' ix Pubkey , // 4
51
+ /// Cctp message CHECK: Seeds must be \["cctp-msg", auction.key().as_ref()\].
52
+ pub cctp_message : & ' ix Pubkey , // 5
52
53
/// Custodian account
53
- pub custodian : & ' ix Pubkey , // 6
54
+ pub custodian : & ' ix Pubkey , // 6
54
55
/// Fee recipient token
55
- pub fee_recipient_token : & ' ix Pubkey , // 7
56
+ pub fee_recipient_token : & ' ix Pubkey , // 7
56
57
/// Closed prepared order response actor (closed_by)
57
- pub closed_prepared_order_response_actor : & ' ix Pubkey , // 8
58
+ pub closed_prepared_order_response_actor : & ' ix Pubkey , // 8
58
59
/// Closed prepared order response
59
- pub closed_prepared_order_response : & ' ix Pubkey , // 9
60
+ pub closed_prepared_order_response : & ' ix Pubkey , // 9
60
61
/// Closed prepared order response custody token
61
62
pub closed_prepared_order_response_custody_token : & ' ix Pubkey , // 10
62
- /// Auction account
63
- pub auction : & ' ix Pubkey , // 11
63
+ /// Auction account CHECK: Init if needed, Seeds must be \["auction", prepared.order_response.seeds.fast_vaa_hash.as_ref()\].
64
+ pub auction : & ' ix Pubkey , // 11
64
65
/// Cctp mint (must be USDC mint)
65
- pub cctp_mint : & ' ix Pubkey , // 12
66
+ pub cctp_mint : & ' ix Pubkey , // 12
66
67
/// Cctp token messenger minter sender authority
67
68
pub cctp_token_messenger_minter_sender_authority : & ' ix Pubkey , // 13
68
69
/// Cctp message transmitter config
69
- pub cctp_message_transmitter_config : & ' ix Pubkey , // 14
70
+ pub cctp_message_transmitter_config : & ' ix Pubkey , // 14
70
71
/// Cctp token messenger
71
- pub cctp_token_messenger : & ' ix Pubkey , // 15
72
+ pub cctp_token_messenger : & ' ix Pubkey , // 15
72
73
/// Cctp remote token messenger
73
- pub cctp_remote_token_messenger : & ' ix Pubkey , // 16
74
+ pub cctp_remote_token_messenger : & ' ix Pubkey , // 16
74
75
/// Cctp token minter
75
- pub cctp_token_minter : & ' ix Pubkey , // 17
76
+ pub cctp_token_minter : & ' ix Pubkey , // 17
76
77
/// Cctp local token
77
- pub cctp_local_token : & ' ix Pubkey , // 18
78
+ pub cctp_local_token : & ' ix Pubkey , // 18
78
79
/// Cctp token messenger minter event authority
79
- pub cctp_token_messenger_minter_event_authority : & ' ix Pubkey , // 19
80
+ pub cctp_token_messenger_minter_event_authority : & ' ix Pubkey , // 19
80
81
/// Cctp token messenger minter program
81
- pub cctp_token_messenger_minter_program : & ' ix Pubkey , // 20
82
+ pub cctp_token_messenger_minter_program : & ' ix Pubkey , // 20
82
83
/// Cctp message transmitter program
83
- pub cctp_message_transmitter_program : & ' ix Pubkey , // 21
84
+ pub cctp_message_transmitter_program : & ' ix Pubkey , // 21
84
85
/// Core bridge program
85
- pub core_bridge_program : & ' ix Pubkey , // 22
86
+ pub core_bridge_program : & ' ix Pubkey , // 22
86
87
/// Core bridge fee collector
87
- pub core_bridge_fee_collector : & ' ix Pubkey , // 23
88
+ pub core_bridge_fee_collector : & ' ix Pubkey , // 23
88
89
/// Core bridge config
89
- pub core_bridge_config : & ' ix Pubkey , // 24
90
+ pub core_bridge_config : & ' ix Pubkey , // 24
90
91
/// Token program
91
- pub token_program : & ' ix Pubkey , // 25
92
+ pub token_program : & ' ix Pubkey , // 25
92
93
/// System program
93
- pub system_program : & ' ix Pubkey , // 26
94
+ pub system_program : & ' ix Pubkey , // 26
94
95
/// Clock
95
- pub clock : & ' ix Pubkey , // 27
96
+ pub clock : & ' ix Pubkey , // 27
96
97
/// Rent
97
- pub rent : & ' ix Pubkey , // 28
98
+ pub rent : & ' ix Pubkey , // 28
98
99
}
99
100
100
101
impl < ' ix > SettleAuctionNoneCctpShimAccounts < ' ix > {
101
102
pub fn to_account_metas ( & self ) -> Vec < AccountMeta > {
102
103
vec ! [
103
- AccountMeta :: new_readonly( * self . payer, true ) , // 0
104
+ AccountMeta :: new_readonly( * self . payer, true ) , // 0
104
105
AccountMeta :: new( * self . post_shim_message, false ) , // 1
105
106
AccountMeta :: new( * self . core_bridge_emitter_sequence, false ) , // 2
106
107
AccountMeta :: new_readonly( * self . post_message_shim_event_authority, false ) , // 3
107
108
AccountMeta :: new_readonly( * self . post_message_shim_program, false ) , // 4
108
- AccountMeta :: new( * self . cctp_message, false ) , // 5
109
- AccountMeta :: new( * self . custodian, false ) , // 6
110
- AccountMeta :: new( * self . fee_recipient_token, false ) , // 7
109
+ AccountMeta :: new( * self . cctp_message, false ) , // 5
110
+ AccountMeta :: new( * self . custodian, false ) , // 6
111
+ AccountMeta :: new( * self . fee_recipient_token, false ) , // 7
111
112
AccountMeta :: new( * self . closed_prepared_order_response_actor, false ) , // 8
112
113
AccountMeta :: new_readonly( * self . closed_prepared_order_response, false ) , // 9
113
114
AccountMeta :: new( * self . closed_prepared_order_response_custody_token, false ) , // 10
114
- AccountMeta :: new( * self . auction, false ) , // 11
115
- AccountMeta :: new( * self . cctp_mint, false ) , // 12
115
+ AccountMeta :: new( * self . auction, false ) , // 11
116
+ AccountMeta :: new( * self . cctp_mint, false ) , // 12
116
117
AccountMeta :: new_readonly( * self . cctp_token_messenger_minter_sender_authority, false ) , // 13
117
118
AccountMeta :: new( * self . cctp_message_transmitter_config, false ) , // 14
118
119
AccountMeta :: new_readonly( * self . cctp_token_messenger, false ) , // 15
@@ -186,20 +187,83 @@ pub fn settle_auction_none_cctp_shim(
186
187
_ => return Err ( MatchingEngineError :: InvalidCctpEndpoint . into ( ) ) ,
187
188
} ;
188
189
189
- // TODO: Make more checks
190
- // Do checks
190
+ // Start of checks
191
191
// ------------------------------------------------------------------------------------------------
192
+
193
+ // Check cctp message is writable
192
194
if !cctp_message. is_writable {
193
195
msg ! ( "Cctp message is not writable" ) ;
194
196
return Err ( MatchingEngineError :: AccountNotWritable . into ( ) )
195
197
. map_err ( |e : Error | e. with_account_name ( "cctp_message" ) ) ;
196
198
}
197
- // End of checks
198
- // ------------------------------------------------------------------------------------------------
199
+ let auction_key = auction. key ( ) ;
199
200
200
- // Begin of initialisation of auction account
201
- // ------------------------------------------------------------------------------------------------
202
- let auction_space = 8 + Auction :: INIT_SPACE_NO_AUCTION ;
201
+ // Check cctp message seeds are valid
202
+ let cctp_message_seeds = [
203
+ common:: CCTP_MESSAGE_SEED_PREFIX ,
204
+ auction_key. as_ref ( ) ,
205
+ & [ data. cctp_message_bump ] ,
206
+ ] ;
207
+
208
+ let cctp_message_pda = Pubkey :: create_program_address ( & cctp_message_seeds, & ID )
209
+ . map_err ( |_| MatchingEngineError :: InvalidPda ) ?;
210
+ if cctp_message_pda != cctp_message. key ( ) {
211
+ msg ! ( "Cctp message seeds are invalid" ) ;
212
+ return Err ( ErrorCode :: ConstraintSeeds . into ( ) )
213
+ . map_err ( |e : Error | e. with_pubkeys ( ( cctp_message_pda, cctp_message. key ( ) ) ) ) ;
214
+ } ;
215
+ // Check custodian owner is the matching engine program and that it deserializes into a checked custodian
216
+ require_eq ! ( custodian. owner, & ID ) ;
217
+ let _checked_custodian = Custodian :: try_deserialize ( & mut & custodian. data . borrow_mut ( ) [ ..] ) ?;
218
+ // Check that fee recipient token is a token account
219
+ let _checked_fee_recipient_token = Box :: new ( TokenAccount :: try_deserialize (
220
+ & mut & fee_recipient_token. data . borrow_mut ( ) [ ..] ,
221
+ ) ?) ;
222
+ // Check seeds of prepared order response are valid
223
+ let prepared_order_response_pda = Pubkey :: create_program_address (
224
+ & [
225
+ PreparedOrderResponse :: SEED_PREFIX ,
226
+ prepared_order_response_account. seeds . fast_vaa_hash . as_ref ( ) ,
227
+ & [ prepared_order_response_account. seeds . bump ] ,
228
+ ] ,
229
+ program_id,
230
+ )
231
+ . map_err ( |_| MatchingEngineError :: InvalidPda ) ?;
232
+ if prepared_order_response_pda != closed_prepared_order_response. key ( ) {
233
+ msg ! ( "Prepared order response seeds are invalid" ) ;
234
+ return Err ( ErrorCode :: ConstraintSeeds . into ( ) ) . map_err ( |e : Error | {
235
+ e. with_pubkeys ( (
236
+ prepared_order_response_pda,
237
+ closed_prepared_order_response. key ( ) ,
238
+ ) )
239
+ } ) ;
240
+ } ;
241
+ // Check seeds of prepared custody token are valid
242
+ {
243
+ let ( prepared_custody_token_pda, _) = Pubkey :: find_program_address (
244
+ & [
245
+ crate :: PREPARED_CUSTODY_TOKEN_SEED_PREFIX ,
246
+ closed_prepared_order_response. key ( ) . as_ref ( ) ,
247
+ ] ,
248
+ program_id,
249
+ ) ;
250
+ if prepared_custody_token_pda != closed_prepared_order_response_custody_token. key ( ) {
251
+ msg ! ( "Prepared custody token seeds are invalid" ) ;
252
+ return Err ( ErrorCode :: ConstraintSeeds . into ( ) ) . map_err ( |e : Error | {
253
+ e. with_pubkeys ( (
254
+ prepared_custody_token_pda,
255
+ closed_prepared_order_response_custody_token. key ( ) ,
256
+ ) )
257
+ } ) ;
258
+ } ;
259
+ }
260
+ // Check that custody token is a token account
261
+ let _checked_prepared_custody_token = Box :: new ( TokenAccount :: try_deserialize (
262
+ & mut & closed_prepared_order_response_custody_token
263
+ . data
264
+ . borrow_mut ( ) [ ..] ,
265
+ ) ?) ;
266
+ // Check seeds of auction are valid
203
267
let auction_seeds = [
204
268
Auction :: SEED_PREFIX ,
205
269
prepared_order_response_account. seeds . fast_vaa_hash . as_ref ( ) ,
@@ -210,6 +274,14 @@ pub fn settle_auction_none_cctp_shim(
210
274
if auction_pda != auction. key ( ) {
211
275
return Err ( MatchingEngineError :: InvalidPda . into ( ) ) ;
212
276
}
277
+
278
+ // End of checks
279
+ // ------------------------------------------------------------------------------------------------
280
+
281
+ // Begin of initialisation of auction account
282
+ // ------------------------------------------------------------------------------------------------
283
+ let auction_space = 8 + Auction :: INIT_SPACE_NO_AUCTION ;
284
+
213
285
let auction_signer_seeds = & [ & auction_seeds[ ..] ] ;
214
286
create_account_reliably (
215
287
& payer. key ( ) ,
@@ -251,6 +323,11 @@ pub fn settle_auction_none_cctp_shim(
251
323
. try_to_vec ( )
252
324
. map_err ( |_| MatchingEngineError :: BorshDeserializationError ) ?;
253
325
auction_data[ 8 ..8_usize . saturating_add ( auction_bytes. len ( ) ) ] . copy_from_slice ( & auction_bytes) ;
326
+ // ------------------------------------------------------------------------------------------------
327
+ // End of initialisation of auction account
328
+
329
+ // Begin of burning and posting the message
330
+ // ------------------------------------------------------------------------------------------------
254
331
let post_message_accounts = PostMessageAccounts {
255
332
emitter : custodian. key ( ) ,
256
333
payer : payer. key ( ) ,
@@ -303,7 +380,11 @@ pub fn settle_auction_none_cctp_shim(
303
380
post_message_accounts,
304
381
accounts,
305
382
) ?;
306
- // TODO: Emit event?
383
+ // ------------------------------------------------------------------------------------------------
384
+ // End of burning and posting the message
385
+
386
+ // Begin of closing the prepared order response
387
+ // ------------------------------------------------------------------------------------------------
307
388
let close_token_account_ix = spl_token:: instruction:: close_account (
308
389
& spl_token:: ID ,
309
390
& closed_prepared_order_response_custody_token. key ( ) ,
@@ -316,6 +397,9 @@ pub fn settle_auction_none_cctp_shim(
316
397
accounts,
317
398
& [ & Custodian :: SIGNER_SEEDS ] ,
318
399
) ?;
400
+ // ------------------------------------------------------------------------------------------------
401
+ // End of closing the prepared order response
402
+
319
403
Ok ( ( ) )
320
404
}
321
405
0 commit comments