1- // Note: The `svm-spoke` does not support `speedUpV3Deposit ` and `fillV3RelayWithUpdatedDeposit ` due to cryptographic
1+ // Note: The `svm-spoke` does not support `speedUpDeposit ` and `fillRelayWithUpdatedDeposit ` due to cryptographic
22// incompatibilities between Solana (Ed25519) and Ethereum (ECDSA secp256k1). Specifically, Solana wallets cannot
33// generate ECDSA signatures required for Ethereum verification. As a result, speed-up functionality on Solana is not
44// implemented. For more details, refer to the documentation: https://docs.across.to
55
66use anchor_lang:: prelude:: * ;
7- use anchor_spl:: token_interface:: { Mint , TokenAccount , TokenInterface } ;
7+ use anchor_spl:: {
8+ associated_token:: AssociatedToken ,
9+ token_interface:: { Mint , TokenAccount , TokenInterface } ,
10+ } ;
811
912use crate :: {
1013 constants:: { MAX_EXCLUSIVITY_PERIOD_SECONDS , ZERO_DEPOSIT_ID } ,
1114 error:: { CommonError , SvmError } ,
1215 event:: FundsDeposited ,
13- state:: { Route , State } ,
14- utils:: { get_current_time, get_unsafe_deposit_id, transfer_from} ,
16+ state:: State ,
17+ utils:: {
18+ derive_seed_hash, get_current_time, get_unsafe_deposit_id, transfer_from, DepositNowSeedData , DepositSeedData ,
19+ } ,
1520} ;
1621
1722#[ event_cpi]
@@ -23,11 +28,12 @@ use crate::{
2328 output_token: Pubkey ,
2429 input_amount: u64 ,
2530 output_amount: u64 ,
26- destination_chain_id: u64 ,
31+ destination_chain_id: u64
2732) ]
2833pub struct Deposit < ' info > {
2934 #[ account( mut ) ]
3035 pub signer : Signer < ' info > ,
36+
3137 #[ account(
3238 mut ,
3339 seeds = [ b"state" , state. seed. to_le_bytes( ) . as_ref( ) ] ,
@@ -36,12 +42,8 @@ pub struct Deposit<'info> {
3642 ) ]
3743 pub state : Account < ' info , State > ,
3844
39- #[ account(
40- seeds = [ b"route" , input_token. as_ref( ) , state. seed. to_le_bytes( ) . as_ref( ) , destination_chain_id. to_le_bytes( ) . as_ref( ) ] ,
41- bump,
42- constraint = route. enabled @ CommonError :: DisabledRoute
43- ) ]
44- pub route : Account < ' info , Route > ,
45+ /// CHECK: PDA derived with seeds ["delegate", seed_hash]; used as a CPI signer.
46+ pub delegate : UncheckedAccount < ' info > ,
4547
4648 #[ account(
4749 mut ,
@@ -52,7 +54,8 @@ pub struct Deposit<'info> {
5254 pub depositor_token_account : InterfaceAccount < ' info , TokenAccount > ,
5355
5456 #[ account(
55- mut ,
57+ init_if_needed,
58+ payer = signer,
5659 associated_token:: mint = mint,
5760 associated_token:: authority = state, // Ensure owner is the state as tokens are sent here on deposit.
5861 associated_token:: token_program = token_program
@@ -66,6 +69,10 @@ pub struct Deposit<'info> {
6669 pub mint : InterfaceAccount < ' info , Mint > ,
6770
6871 pub token_program : Interface < ' info , TokenInterface > ,
72+
73+ pub associated_token_program : Program < ' info , AssociatedToken > ,
74+
75+ pub system_program : Program < ' info , System > ,
6976}
7077
7178pub fn _deposit (
@@ -83,15 +90,14 @@ pub fn _deposit(
8390 fill_deadline : u32 ,
8491 exclusivity_parameter : u32 ,
8592 message : Vec < u8 > ,
93+ delegate_seed_hash : [ u8 ; 32 ] ,
8694) -> Result < ( ) > {
8795 let state = & mut ctx. accounts . state ;
88-
8996 let current_time = get_current_time ( state) ?;
9097
9198 if current_time. checked_sub ( quote_timestamp) . unwrap_or ( u32:: MAX ) > state. deposit_quote_time_buffer {
9299 return err ! ( CommonError :: InvalidQuoteTimestamp ) ;
93100 }
94-
95101 if fill_deadline > current_time + state. fill_deadline_buffer {
96102 return err ! ( CommonError :: InvalidFillDeadline ) ;
97103 }
@@ -101,21 +107,20 @@ pub fn _deposit(
101107 if exclusivity_deadline <= MAX_EXCLUSIVITY_PERIOD_SECONDS {
102108 exclusivity_deadline += current_time;
103109 }
104-
105110 if exclusive_relayer == Pubkey :: default ( ) {
106111 return err ! ( CommonError :: InvalidExclusiveRelayer ) ;
107112 }
108113 }
109114
110- // Depositor must have delegated input_amount to the state PDA.
115+ // Depositor must have delegated input_amount to the delegate PDA
111116 transfer_from (
112117 & ctx. accounts . depositor_token_account ,
113118 & ctx. accounts . vault ,
114119 input_amount,
115- state,
116- ctx. bumps . state ,
120+ & ctx. accounts . delegate ,
117121 & ctx. accounts . mint ,
118122 & ctx. accounts . token_program ,
123+ delegate_seed_hash,
119124 ) ?;
120125
121126 let mut applied_deposit_id = deposit_id;
@@ -159,6 +164,22 @@ pub fn deposit(
159164 exclusivity_parameter : u32 ,
160165 message : Vec < u8 > ,
161166) -> Result < ( ) > {
167+ let seed_hash = derive_seed_hash (
168+ & ( DepositSeedData {
169+ depositor,
170+ recipient,
171+ input_token,
172+ output_token,
173+ input_amount,
174+ output_amount,
175+ destination_chain_id,
176+ exclusive_relayer,
177+ quote_timestamp,
178+ fill_deadline,
179+ exclusivity_parameter,
180+ message : & message,
181+ } ) ,
182+ ) ;
162183 _deposit (
163184 ctx,
164185 depositor,
@@ -174,6 +195,7 @@ pub fn deposit(
174195 fill_deadline,
175196 exclusivity_parameter,
176197 message,
198+ seed_hash,
177199 ) ?;
178200
179201 Ok ( ( ) )
@@ -195,7 +217,22 @@ pub fn deposit_now(
195217) -> Result < ( ) > {
196218 let state = & mut ctx. accounts . state ;
197219 let current_time = get_current_time ( state) ?;
198- deposit (
220+ let seed_hash = derive_seed_hash (
221+ & ( DepositNowSeedData {
222+ depositor,
223+ recipient,
224+ input_token,
225+ output_token,
226+ input_amount,
227+ output_amount,
228+ destination_chain_id,
229+ exclusive_relayer,
230+ fill_deadline_offset,
231+ exclusivity_period,
232+ message : & message,
233+ } ) ,
234+ ) ;
235+ _deposit (
199236 ctx,
200237 depositor,
201238 recipient,
@@ -205,10 +242,12 @@ pub fn deposit_now(
205242 output_amount,
206243 destination_chain_id,
207244 exclusive_relayer,
245+ ZERO_DEPOSIT_ID , // ZERO_DEPOSIT_ID informs internal function to use state.number_of_deposits as id.
208246 current_time,
209247 current_time + fill_deadline_offset,
210248 exclusivity_period,
211249 message,
250+ seed_hash,
212251 ) ?;
213252
214253 Ok ( ( ) )
@@ -232,6 +271,22 @@ pub fn unsafe_deposit(
232271) -> Result < ( ) > {
233272 // Calculate the unsafe deposit ID as a [u8; 32]
234273 let deposit_id = get_unsafe_deposit_id ( ctx. accounts . signer . key ( ) , depositor, deposit_nonce) ;
274+ let seed_hash = derive_seed_hash (
275+ & ( DepositSeedData {
276+ depositor,
277+ recipient,
278+ input_token,
279+ output_token,
280+ input_amount,
281+ output_amount,
282+ destination_chain_id,
283+ exclusive_relayer,
284+ quote_timestamp,
285+ fill_deadline,
286+ exclusivity_parameter,
287+ message : & message,
288+ } ) ,
289+ ) ;
235290 _deposit (
236291 ctx,
237292 depositor,
@@ -247,6 +302,7 @@ pub fn unsafe_deposit(
247302 fill_deadline,
248303 exclusivity_parameter,
249304 message,
305+ seed_hash,
250306 ) ?;
251307
252308 Ok ( ( ) )
0 commit comments