1use solana_program::{
2 instruction::{AccountMeta, Instruction},
3 pubkey::Pubkey,
4 system_program,
5};
6use spl_token;
7
8use crate::consts;
9
10#[repr(packed)]
11pub struct UpdateUserAssetConfigParam {
12 pub use_as_collateral: u8,
13 pub pool_id: u8,
14}
15
16#[repr(packed)]
17pub struct AddUserAndDepositParam {
18 pub page_id: u16,
19 pub amount: u64,
20 pub pool_id: u8,
21}
22
23#[repr(packed)]
24pub struct DepositParam {
25 pub amount: u64,
26 pub pool_id: u8,
27}
28
29#[repr(packed)]
30pub struct WithdrawParam {
31 pub withdraw_all: u8,
32 pub amount: u64,
33 pub pool_id: u8,
34}
35
36#[repr(packed)]
37pub struct BorrowParam {
38 pub amount: u64,
39 pub pool_id: u8,
40}
41
42#[repr(packed)]
43pub struct RepayParam {
44 pub repay_all: u8,
45 pub amount: u64,
46 pub pool_id: u8,
47}
48
49#[repr(packed)]
50pub struct ExternLiquidateParam {
51 pub min_collateral_amount: u64,
53 pub repaid_borrow_amount: u64,
55 pub collateral_pool_id: u8,
56 pub borrowed_pool_id: u8,
57}
58
59#[inline(always)]
60pub fn mut_cast<T>(data: &mut [u8]) -> &mut T {
61 assert!(data.len() >= std::mem::size_of::<T>());
62 return unsafe { std::mem::transmute(data.as_ptr()) };
63}
64
65pub fn deposit(
66 user_wallet: &Pubkey, user_spl: &Pubkey, amount: u64,
69 pool_id: u8,
70) -> Instruction {
71 deposit_full(
72 user_wallet,
73 user_spl,
74 &consts::get_user_info_k(user_wallet),
75 &consts::get_asset_pool_k(pool_id),
76 &consts::get_asset_pool_spl_k(&spl_token::ID, pool_id),
77 &consts::get_pool_summaries_k(),
78 &consts::get_price_summaries_k(),
79 &spl_token::ID,
80 &consts::program::ID,
81 amount,
82 pool_id,
83 )
84}
85
86pub fn deposit_full(
87 user_wallet: &Pubkey, user_spl: &Pubkey, user_info: &Pubkey, asset_pool: &Pubkey, asset_pool_spl: &Pubkey, pool_summaries: &Pubkey, price_summaries: &Pubkey, token_program: &Pubkey,
95 program_id: &Pubkey, amount: u64,
98 pool_id: u8,
99) -> Instruction {
100 let data_size = 1 + std::mem::size_of::<DepositParam>();
101 let mut buffer = vec![0; data_size];
102
103 buffer[0] = consts::CMD_DEPOSIT;
104 let mut param = mut_cast::<DepositParam>(&mut buffer[1..]);
105 param.amount = amount;
106 param.pool_id = pool_id;
107
108 Instruction {
109 program_id: *program_id,
110 accounts: vec![
111 AccountMeta::new_readonly(*user_wallet, true),
112 AccountMeta::new(*user_spl, false),
113 AccountMeta::new(*user_info, false),
114 AccountMeta::new(*asset_pool, false),
115 AccountMeta::new(*asset_pool_spl, false),
116 AccountMeta::new(*pool_summaries, false),
117 AccountMeta::new(*price_summaries, false),
118 AccountMeta::new_readonly(*token_program, false),
119 ],
120 data: buffer,
121 }
122}
123
124pub fn add_user_and_deposit(
125 user_wallet: &Pubkey, user_spl: &Pubkey, amount: u64,
128 pool_id: u8,
129 page_id: u16,
130) -> Instruction {
131 add_user_and_deposit_full(
132 user_wallet,
133 user_spl,
134 &consts::get_user_pages_stats_k(),
135 &consts::get_users_page_k(page_id),
136 &consts::get_user_info_k(user_wallet),
137 &consts::get_asset_pool_k(pool_id),
138 &consts::get_asset_pool_spl_k(&spl_token::ID, pool_id),
139 &consts::get_pool_summaries_k(),
140 &consts::get_price_summaries_k(),
141 &system_program::ID,
142 &spl_token::ID,
143 &consts::program::ID,
144 amount,
145 pool_id,
146 page_id,
147 )
148}
149
150pub fn add_user_and_deposit_full(
151 user_wallet: &Pubkey, user_spl: &Pubkey, user_pages_stats: &Pubkey, users_page: &Pubkey, user_info: &Pubkey, asset_pool: &Pubkey, asset_pool_spl: &Pubkey, pool_summaries: &Pubkey, price_summaries: &Pubkey, system_program: &Pubkey,
161 token_program: &Pubkey,
162 program_id: &Pubkey, amount: u64,
165 pool_id: u8,
166 page_id: u16,
167) -> Instruction {
168 let data_size = 1 + std::mem::size_of::<AddUserAndDepositParam>();
169 let mut buffer = vec![0; data_size];
170
171 buffer[0] = consts::CMD_ADD_USER_AND_DEPOSIT;
172 let mut param = mut_cast::<AddUserAndDepositParam>(&mut buffer[1..]);
173 param.amount = amount;
174 param.pool_id = pool_id;
175 param.page_id = page_id;
176
177 Instruction {
178 program_id: *program_id,
179 accounts: vec![
180 AccountMeta::new(*user_wallet, true),
181 AccountMeta::new(*user_spl, false),
182 AccountMeta::new(*user_pages_stats, false),
183 AccountMeta::new(*users_page, false),
184 AccountMeta::new(*user_info, false),
185 AccountMeta::new(*asset_pool, false),
186 AccountMeta::new(*asset_pool_spl, false),
187 AccountMeta::new(*pool_summaries, false),
188 AccountMeta::new(*price_summaries, false),
189 AccountMeta::new_readonly(*system_program, false),
190 AccountMeta::new_readonly(*token_program, false),
191 ],
192 data: buffer,
193 }
194}
195
196pub fn withdraw(
197 user_wallet: &Pubkey, user_spl: &Pubkey, withdraw_all: bool,
200 amount: u64,
201 pool_id: u8,
202 page_id: u16,
203) -> Instruction {
204 withdraw_full(
205 user_wallet,
206 user_spl,
207 &consts::get_user_info_k(user_wallet),
208 &consts::get_asset_pool_k(pool_id),
209 &consts::get_asset_pool_spl_k(&spl_token::ID, pool_id),
210 &consts::get_pool_summaries_k(),
211 &consts::get_price_summaries_k(),
212 &consts::get_base_pda(),
213 &spl_token::ID,
214 &consts::program::ID,
215 withdraw_all,
216 amount,
217 pool_id,
218 page_id,
219 )
220}
221
222pub fn withdraw_full(
223 user_wallet: &Pubkey, user_spl: &Pubkey, user_info: &Pubkey, asset_pool: &Pubkey, asset_pool_spl: &Pubkey, pool_summaries: &Pubkey, price_summaries: &Pubkey, base_pda: &Pubkey, token_program: &Pubkey,
232 program_id: &Pubkey, withdraw_all: bool,
235 amount: u64,
236 pool_id: u8,
237 page_id: u16,
238) -> Instruction {
239 let data_size = 1 + std::mem::size_of::<WithdrawParam>();
240 let mut buffer = vec![0; data_size];
241
242 buffer[0] = if withdraw_all {
243 consts::CMD_WITHDRAW_AND_REMOVE_USER
244 } else {
245 consts::CMD_WITHDRAW
246 };
247 let mut param = mut_cast::<WithdrawParam>(&mut buffer[1..]);
248 param.withdraw_all = if withdraw_all { 1 } else { 0 };
249 param.amount = amount;
250 param.pool_id = pool_id;
251
252 let mut accounts = vec![
253 AccountMeta::new_readonly(*user_wallet, true),
254 AccountMeta::new(*user_spl, false),
255 ];
256 if withdraw_all {
257 accounts.push(AccountMeta::new(consts::get_user_pages_stats_k(), false));
258 accounts.push(AccountMeta::new(consts::get_users_page_k(page_id), false));
259 }
260 accounts.push(AccountMeta::new(*user_info, false));
261 accounts.push(AccountMeta::new(*asset_pool, false));
262 accounts.push(AccountMeta::new(*asset_pool_spl, false));
263 accounts.push(AccountMeta::new(*pool_summaries, false));
264 accounts.push(AccountMeta::new_readonly(*price_summaries, false));
265 accounts.push(AccountMeta::new_readonly(*base_pda, false));
266 accounts.push(AccountMeta::new_readonly(*token_program, false));
267 Instruction {
268 program_id: *program_id,
269 accounts: accounts,
270 data: buffer,
271 }
272}
273
274pub fn borrow(
275 user_wallet: &Pubkey, user_spl: &Pubkey, amount: u64,
278 pool_id: u8,
279) -> Instruction {
280 borrow_full(
281 user_wallet,
282 user_spl,
283 &consts::get_user_info_k(user_wallet),
284 &consts::get_asset_pool_k(pool_id),
285 &consts::get_asset_pool_spl_k(&spl_token::ID, pool_id),
286 &consts::get_pool_summaries_k(),
287 &consts::get_price_summaries_k(),
288 &consts::get_base_pda(),
289 &spl_token::ID,
290 &consts::program::ID,
291 amount,
292 pool_id,
293 )
294}
295
296pub fn borrow_full(
297 user_wallet: &Pubkey, user_spl: &Pubkey, user_info: &Pubkey, asset_pool: &Pubkey, asset_pool_spl: &Pubkey, pool_summaries: &Pubkey, price_summaries: &Pubkey, base_pda: &Pubkey, token_program: &Pubkey,
306 program_id: &Pubkey, amount: u64,
309 pool_id: u8,
310) -> Instruction {
311 let data_size = 1 + std::mem::size_of::<BorrowParam>();
312 let mut buffer = vec![0; data_size];
313
314 buffer[0] = consts::CMD_BORROW;
315 let mut param = mut_cast::<BorrowParam>(&mut buffer[1..]);
316 param.amount = amount;
317 param.pool_id = pool_id;
318
319 Instruction {
320 program_id: *program_id,
321 accounts: vec![
322 AccountMeta::new_readonly(*user_wallet, true),
323 AccountMeta::new(*user_spl, false),
324 AccountMeta::new(*user_info, false),
325 AccountMeta::new(*asset_pool, false),
326 AccountMeta::new(*asset_pool_spl, false),
327 AccountMeta::new(*pool_summaries, false),
328 AccountMeta::new_readonly(*price_summaries, false),
329 AccountMeta::new_readonly(*base_pda, false),
330 AccountMeta::new_readonly(*token_program, false),
331 ],
332 data: buffer,
333 }
334}
335
336pub fn repay(
337 user_wallet: &Pubkey, user_spl: &Pubkey, repay_all: bool,
340 amount: u64,
341 pool_id: u8,
342) -> Instruction {
343 repay_full(
344 user_wallet,
345 user_spl,
346 &consts::get_user_info_k(user_wallet),
347 &consts::get_asset_pool_k(pool_id),
348 &consts::get_asset_pool_spl_k(&spl_token::ID, pool_id),
349 &consts::get_pool_summaries_k(),
350 &spl_token::ID,
351 &consts::program::ID,
352 repay_all,
353 amount,
354 pool_id,
355 )
356}
357
358pub fn repay_full(
359 user_wallet: &Pubkey, user_spl: &Pubkey, user_info: &Pubkey, asset_pool: &Pubkey, asset_pool_spl: &Pubkey, pool_summaries: &Pubkey, token_program: &Pubkey,
366 program_id: &Pubkey, repay_all: bool,
369 amount: u64,
370 pool_id: u8,
371) -> Instruction {
372 let data_size = 1 + std::mem::size_of::<RepayParam>();
373 let mut buffer = vec![0; data_size];
374
375 buffer[0] = consts::CMD_REPAY;
376 let mut param = mut_cast::<RepayParam>(&mut buffer[1..]);
377 param.repay_all = if repay_all { 1 } else { 0 };
378 param.amount = amount;
379 param.pool_id = pool_id;
380
381 Instruction {
382 program_id: *program_id,
383 accounts: vec![
384 AccountMeta::new_readonly(*user_wallet, true),
385 AccountMeta::new(*user_spl, false),
386 AccountMeta::new(*user_info, false),
387 AccountMeta::new(*asset_pool, false),
388 AccountMeta::new(*asset_pool_spl, false),
389 AccountMeta::new(*pool_summaries, false),
390 AccountMeta::new_readonly(*token_program, false),
391 ],
392 data: buffer,
393 }
394}
395
396pub fn refresh_user(user_wallet: &Pubkey, ) -> Instruction {
398 let data_size = 1 + 0; let mut buffer = vec![0; data_size];
400
401 let program_id = consts::program::ID;
402 let user_info = consts::get_user_info_k(user_wallet);
403 let pool_summaries = consts::get_pool_summaries_k();
404
405 buffer[0] = consts::CMD_REFRESH_USER;
406
407 Instruction {
408 program_id: program_id,
409 accounts: vec![
410 AccountMeta::new_readonly(*user_wallet, false),
411 AccountMeta::new(user_info, false),
412 AccountMeta::new_readonly(pool_summaries, false),
413 ],
414 data: buffer,
415 }
416}
417
418pub fn extern_liquidate(
419 liquidated_wallet: &Pubkey, liquidator_wallet: &Pubkey, liquidator_collateral_spl: &Pubkey, liquidator_borrowed_spl: &Pubkey, repaid_borrow_amount: u64,
424 min_collateral_amount: u64,
425 borrowed_pool_id: u8,
426 collateral_pool_id: u8,
427) -> Instruction {
428 extern_liquidate_full(
429 liquidated_wallet,
430 liquidator_wallet,
431 &consts::get_user_info_k(liquidated_wallet),
432 &consts::get_base_pda(),
433 liquidator_collateral_spl,
434 liquidator_borrowed_spl,
435 &consts::get_asset_pool_k(collateral_pool_id),
436 &consts::get_asset_pool_spl_k(&spl_token::ID, collateral_pool_id),
437 &consts::get_asset_pool_k(borrowed_pool_id),
438 &consts::get_asset_pool_spl_k(&spl_token::ID, borrowed_pool_id),
439 &consts::get_pool_summaries_k(),
440 &spl_token::ID,
441 &consts::program::ID,
442 repaid_borrow_amount,
443 min_collateral_amount,
444 borrowed_pool_id,
445 collateral_pool_id,
446 )
447}
448
449pub fn extern_liquidate_full(
451 liquidated_wallet: &Pubkey, liquidator_wallet: &Pubkey, user_info: &Pubkey, base_pda: &Pubkey, liquidator_collateral_spl: &Pubkey, liquidator_borrowed_spl: &Pubkey, collateral_asset_pool: &Pubkey, collateral_asset_pool_spl: &Pubkey, borrowed_asset_pool: &Pubkey, borrowed_asset_pool_spl: &Pubkey, pool_summaries: &Pubkey, token_program: &Pubkey,
468 program_id: &Pubkey, repaid_borrow_amount: u64,
471 min_collateral_amount: u64,
472 borrowed_pool_id: u8,
473 collateral_pool_id: u8,
474) -> Instruction {
475 let data_size = 1 + std::mem::size_of::<ExternLiquidateParam>();
476 let mut buffer = vec![0; data_size];
477 buffer[0] = consts::CMD_EXTERN_LIQUIDATE;
478
479 let mut param = mut_cast::<ExternLiquidateParam>(&mut buffer[1..]);
480 param.repaid_borrow_amount = repaid_borrow_amount;
481 param.min_collateral_amount = min_collateral_amount;
482 param.borrowed_pool_id = borrowed_pool_id;
483 param.collateral_pool_id = collateral_pool_id;
484
485 Instruction {
486 program_id: *program_id,
487 accounts: vec![
488 AccountMeta::new_readonly(*liquidated_wallet, false),
489 AccountMeta::new_readonly(*liquidator_wallet, true),
490 AccountMeta::new(*user_info, false),
491 AccountMeta::new_readonly(*base_pda, false),
492 AccountMeta::new(*liquidator_collateral_spl, false),
493 AccountMeta::new(*liquidator_borrowed_spl, false),
494 AccountMeta::new(*collateral_asset_pool, false),
495 AccountMeta::new(*collateral_asset_pool_spl, false),
496 AccountMeta::new(*borrowed_asset_pool, false),
497 AccountMeta::new(*borrowed_asset_pool_spl, false),
498 AccountMeta::new(*pool_summaries, false),
499 AccountMeta::new_readonly(*token_program, false),
500 ],
501 data: buffer,
502 }
503}
504
505pub fn make_lm_reward_claimable(user_wallet: &Pubkey) -> Instruction {
509 let user_info = consts::get_user_info_k(user_wallet);
510 let pool_summaries = consts::get_pool_summaries_k();
511
512 let mut buffer = vec![0; 1];
513 buffer[0] = consts::CMD_MAKE_LM_REWARD_AVAILABLE;
514
515 Instruction {
516 program_id: consts::program::ID,
517 accounts: vec![
518 AccountMeta::new_readonly(*user_wallet, true),
519 AccountMeta::new_readonly(*user_wallet, false),
520 AccountMeta::new(user_info, false),
521 AccountMeta::new(pool_summaries, false),
522 ],
523 data: buffer,
524 }
525}
526
527pub fn claim_apt_lm_reward(user_wallet: &Pubkey, user_apt_spl: &Pubkey) -> Instruction {
528 let base_pda = consts::get_base_pda();
529 let user_info = consts::get_user_info_k(user_wallet);
530 let lm_apt_vault = consts::lm_apt_vault::ID;
531 let pool_summaries = consts::get_pool_summaries_k();
532 let price_summaries = consts::get_price_summaries_k();
533
534 let mut buffer = vec![0; 1];
535 buffer[0] = consts::CMD_CLAIM_APT_LM_REWARD;
536 Instruction {
537 program_id: consts::program::ID,
538 accounts: vec![
539 AccountMeta::new_readonly(base_pda, false),
540 AccountMeta::new_readonly(*user_wallet, true),
541 AccountMeta::new(user_info, false),
542 AccountMeta::new(*user_apt_spl, false),
543 AccountMeta::new(lm_apt_vault, false),
544 AccountMeta::new(pool_summaries, false),
545 AccountMeta::new_readonly(price_summaries, false),
546 AccountMeta::new_readonly(spl_token::ID, false),
547 ],
548 data: buffer,
549 }
550}