1use std::{convert::TryInto, mem::size_of};
4
5use solana_program::{
6 instruction::{AccountMeta, Instruction},
7 msg,
8 program_error::ProgramError,
9 pubkey::{Pubkey, PUBKEY_BYTES},
10 sysvar,
11};
12use solana_program::program_option::COption;
13
14use crate::error::LendingError;
15
16#[derive(Clone, Debug, PartialEq)]
18pub enum LendingInstruction {
19 RefreshReserve,
29
30 DepositReserveLiquidity {
48 liquidity_amount: u64,
50 },
51
52 RedeemReserveCollateral {
69 collateral_amount: u64,
71 },
72
73 InitObligation,
85
86 RefreshObligation,
98
99 DepositObligationCollateral {
120 collateral_amount: u64,
122 },
123
124 WithdrawObligationCollateral {
143 collateral_amount: u64,
145 },
146
147 BorrowObligationLiquidity {
166 liquidity_amount: u64,
168 },
170
171 RepayObligationLiquidity {
187 liquidity_amount: u64,
189 },
190
191 LiquidateObligation {
216 liquidity_amount: u64,
218 },
219
220 FlashLoan {
257 amount: u64,
259 },
260
261 DepositReserveLiquidityAndObligationCollateral {
284 liquidity_amount: u64,
286 },
287}
288
289impl LendingInstruction {
290 pub fn unpack(input: &[u8]) -> Result<Self, ProgramError> {
292 let (&tag, rest) = input
293 .split_first()
294 .ok_or(LendingError::InstructionUnpackError)?;
295 Ok(match tag {
296 3 => Self::RefreshReserve,
297 4 => {
298 let (liquidity_amount, _rest) = Self::unpack_u64(rest)?;
299 Self::DepositReserveLiquidity { liquidity_amount }
300 }
301 5 => {
302 let (collateral_amount, _rest) = Self::unpack_u64(rest)?;
303 Self::RedeemReserveCollateral { collateral_amount }
304 }
305 6 => Self::InitObligation,
306 7 => Self::RefreshObligation,
307 8 => {
308 let (collateral_amount, _rest) = Self::unpack_u64(rest)?;
309 Self::DepositObligationCollateral { collateral_amount }
310 }
311 9 => {
312 let (collateral_amount, _rest) = Self::unpack_u64(rest)?;
313 Self::WithdrawObligationCollateral { collateral_amount }
314 }
315 10 => {
316 let (liquidity_amount, _rest) = Self::unpack_u64(rest)?;
317 Self::BorrowObligationLiquidity { liquidity_amount }
318 }
319 11 => {
320 let (liquidity_amount, _rest) = Self::unpack_u64(rest)?;
321 Self::RepayObligationLiquidity { liquidity_amount }
322 }
323 12 => {
324 let (liquidity_amount, _rest) = Self::unpack_u64(rest)?;
325 Self::LiquidateObligation { liquidity_amount }
326 }
327 13 => {
328 let (amount, _rest) = Self::unpack_u64(rest)?;
329 Self::FlashLoan { amount }
330 }
331 14 => {
332 let (liquidity_amount, _rest) = Self::unpack_u64(rest)?;
333 Self::DepositReserveLiquidityAndObligationCollateral { liquidity_amount }
334 }
335
336 _ => {
337 msg!("Instruction cannot be unpacked");
338 return Err(LendingError::InstructionUnpackError.into());
339 }
340 })
341 }
342
343 fn unpack_u64(input: &[u8]) -> Result<(u64, &[u8]), ProgramError> {
344 if input.len() < 8 {
345 msg!("u64 cannot be unpacked");
346 return Err(LendingError::InstructionUnpackError.into());
347 }
348 let (bytes, rest) = input.split_at(8);
349 let value = bytes
350 .get(..8)
351 .and_then(|slice| slice.try_into().ok())
352 .map(u64::from_le_bytes)
353 .ok_or(LendingError::InstructionUnpackError)?;
354 Ok((value, rest))
355 }
356
357 pub fn pack(&self) -> Vec<u8> {
359 let mut buf = Vec::with_capacity(size_of::<Self>());
360 match *self {
361 Self::RefreshReserve => {
362 buf.push(3);
363 }
364 Self::DepositReserveLiquidity { liquidity_amount } => {
365 buf.push(4);
366 buf.extend_from_slice(&liquidity_amount.to_le_bytes());
367 }
368 Self::RedeemReserveCollateral { collateral_amount } => {
369 buf.push(5);
370 buf.extend_from_slice(&collateral_amount.to_le_bytes());
371 }
372 Self::InitObligation => {
373 buf.push(6);
374 }
375 Self::RefreshObligation => {
376 buf.push(7);
377 }
378 Self::DepositObligationCollateral { collateral_amount } => {
379 buf.push(8);
380 buf.extend_from_slice(&collateral_amount.to_le_bytes());
381 }
382 Self::WithdrawObligationCollateral { collateral_amount } => {
383 buf.push(9);
384 buf.extend_from_slice(&collateral_amount.to_le_bytes());
385 }
386 Self::BorrowObligationLiquidity { liquidity_amount } => {
387 buf.push(10);
388 buf.extend_from_slice(&liquidity_amount.to_le_bytes());
389 }
390 Self::RepayObligationLiquidity { liquidity_amount } => {
391 buf.push(11);
392 buf.extend_from_slice(&liquidity_amount.to_le_bytes());
393 }
394 Self::LiquidateObligation { liquidity_amount } => {
395 buf.push(12);
396 buf.extend_from_slice(&liquidity_amount.to_le_bytes());
397 }
398 Self::FlashLoan { amount } => {
399 buf.push(13);
400 buf.extend_from_slice(&amount.to_le_bytes());
401 }
402 Self::DepositReserveLiquidityAndObligationCollateral { liquidity_amount } => {
403 buf.push(14);
404 buf.extend_from_slice(&liquidity_amount.to_le_bytes());
405 }
406 }
407 buf
408 }
409}
410
411pub fn refresh_reserve(
413 program_id: Pubkey,
414 reserve_pubkey: Pubkey,
415 reserve_liquidity_oracle_pubkey: COption<Pubkey>,
416) -> Instruction {
417 let mut accounts = vec![
418 AccountMeta::new(reserve_pubkey, false),
419 AccountMeta::new_readonly(sysvar::clock::id(), false),
420 ];
421 if let COption::Some(reserve_liquidity_oracle_pubkey) = reserve_liquidity_oracle_pubkey {
422 accounts.push(AccountMeta::new_readonly(
423 reserve_liquidity_oracle_pubkey,
424 false,
425 ));
426 }
427 Instruction {
428 program_id,
429 accounts,
430 data: LendingInstruction::RefreshReserve.pack(),
431 }
432}
433
434#[allow(clippy::too_many_arguments)]
436pub fn deposit_reserve_liquidity(
437 program_id: Pubkey,
438 liquidity_amount: u64,
439 source_liquidity_pubkey: Pubkey,
440 destination_collateral_pubkey: Pubkey,
441 reserve_pubkey: Pubkey,
442 reserve_liquidity_supply_pubkey: Pubkey,
443 reserve_collateral_mint_pubkey: Pubkey,
444 lending_market_pubkey: Pubkey,
445 user_transfer_authority_pubkey: Pubkey,
446) -> Instruction {
447 let (lending_market_authority_pubkey, _bump_seed) = Pubkey::find_program_address(
448 &[&lending_market_pubkey.to_bytes()[..PUBKEY_BYTES]],
449 &program_id,
450 );
451 Instruction {
452 program_id,
453 accounts: vec![
454 AccountMeta::new(source_liquidity_pubkey, false),
455 AccountMeta::new(destination_collateral_pubkey, false),
456 AccountMeta::new(reserve_pubkey, false),
457 AccountMeta::new(reserve_liquidity_supply_pubkey, false),
458 AccountMeta::new(reserve_collateral_mint_pubkey, false),
459 AccountMeta::new_readonly(lending_market_pubkey, false),
460 AccountMeta::new_readonly(lending_market_authority_pubkey, false),
461 AccountMeta::new_readonly(user_transfer_authority_pubkey, true),
462 AccountMeta::new_readonly(sysvar::clock::id(), false),
463 AccountMeta::new_readonly(spl_token::id(), false),
464 ],
465 data: LendingInstruction::DepositReserveLiquidity { liquidity_amount }.pack(),
466 }
467}
468
469#[allow(clippy::too_many_arguments)]
471pub fn redeem_reserve_collateral(
472 program_id: Pubkey,
473 collateral_amount: u64,
474 source_collateral_pubkey: Pubkey,
475 destination_liquidity_pubkey: Pubkey,
476 reserve_pubkey: Pubkey,
477 reserve_collateral_mint_pubkey: Pubkey,
478 reserve_liquidity_supply_pubkey: Pubkey,
479 lending_market_pubkey: Pubkey,
480 user_transfer_authority_pubkey: Pubkey,
481) -> Instruction {
482 let (lending_market_authority_pubkey, _bump_seed) = Pubkey::find_program_address(
483 &[&lending_market_pubkey.to_bytes()[..PUBKEY_BYTES]],
484 &program_id,
485 );
486 Instruction {
487 program_id,
488 accounts: vec![
489 AccountMeta::new(source_collateral_pubkey, false),
490 AccountMeta::new(destination_liquidity_pubkey, false),
491 AccountMeta::new(reserve_pubkey, false),
492 AccountMeta::new(reserve_collateral_mint_pubkey, false),
493 AccountMeta::new(reserve_liquidity_supply_pubkey, false),
494 AccountMeta::new_readonly(lending_market_pubkey, false),
495 AccountMeta::new_readonly(lending_market_authority_pubkey, false),
496 AccountMeta::new_readonly(user_transfer_authority_pubkey, true),
497 AccountMeta::new_readonly(sysvar::clock::id(), false),
498 AccountMeta::new_readonly(spl_token::id(), false),
499 ],
500 data: LendingInstruction::RedeemReserveCollateral { collateral_amount }.pack(),
501 }
502}
503
504#[allow(clippy::too_many_arguments)]
506pub fn init_obligation(
507 program_id: Pubkey,
508 obligation_pubkey: Pubkey,
509 lending_market_pubkey: Pubkey,
510 obligation_owner_pubkey: Pubkey,
511) -> Instruction {
512 Instruction {
513 program_id,
514 accounts: vec![
515 AccountMeta::new(obligation_pubkey, false),
516 AccountMeta::new_readonly(lending_market_pubkey, false),
517 AccountMeta::new_readonly(obligation_owner_pubkey, true),
518 AccountMeta::new_readonly(sysvar::clock::id(), false),
519 AccountMeta::new_readonly(sysvar::rent::id(), false),
520 AccountMeta::new_readonly(spl_token::id(), false),
521 ],
522 data: LendingInstruction::InitObligation.pack(),
523 }
524}
525
526#[allow(clippy::too_many_arguments)]
528pub fn refresh_obligation(
529 program_id: Pubkey,
530 obligation_pubkey: Pubkey,
531 reserve_pubkeys: Vec<Pubkey>,
532) -> Instruction {
533 let mut accounts = vec![
534 AccountMeta::new(obligation_pubkey, false),
535 AccountMeta::new_readonly(sysvar::clock::id(), false),
536 ];
537 accounts.extend(
538 reserve_pubkeys
539 .into_iter()
540 .map(|pubkey| AccountMeta::new_readonly(pubkey, false)),
541 );
542 Instruction {
543 program_id,
544 accounts,
545 data: LendingInstruction::RefreshObligation.pack(),
546 }
547}
548
549#[allow(clippy::too_many_arguments)]
551pub fn deposit_obligation_collateral(
552 program_id: Pubkey,
553 collateral_amount: u64,
554 source_collateral_pubkey: Pubkey,
555 destination_collateral_pubkey: Pubkey,
556 deposit_reserve_pubkey: Pubkey,
557 obligation_pubkey: Pubkey,
558 lending_market_pubkey: Pubkey,
559 obligation_owner_pubkey: Pubkey,
560 user_transfer_authority_pubkey: Pubkey,
561 option_stake_account_pubkey: Option<Pubkey>,
562 option_staking_pool_pubkey: Option<Pubkey>,
563) -> Instruction {
564 let (lending_market_authority_pubkey, _bump_seed) = Pubkey::find_program_address(
565 &[&lending_market_pubkey.to_bytes()[..PUBKEY_BYTES]],
566 &program_id,
567 );
568 let mut accounts = vec![
569 AccountMeta::new(source_collateral_pubkey, false),
570 AccountMeta::new(destination_collateral_pubkey, false),
571 AccountMeta::new_readonly(deposit_reserve_pubkey, false),
572 AccountMeta::new(obligation_pubkey, false),
573 AccountMeta::new_readonly(lending_market_pubkey, false),
574 AccountMeta::new_readonly(lending_market_authority_pubkey, false),
575 AccountMeta::new_readonly(obligation_owner_pubkey, true),
576 AccountMeta::new_readonly(user_transfer_authority_pubkey, true),
577 AccountMeta::new_readonly(sysvar::clock::id(), false),
578 AccountMeta::new_readonly(spl_token::id(), false),
579 ];
580
581 if let [Some(staking_account_pubkey), Some(staking_pool_pubkey)] =
582 [option_stake_account_pubkey, option_staking_pool_pubkey]
583 {
584 accounts.push(AccountMeta::new(staking_account_pubkey, false));
585 accounts.push(AccountMeta::new(staking_pool_pubkey, false));
586 accounts.push(AccountMeta::new_readonly(port_finance_staking::id(), false));
587 }
588 Instruction {
589 program_id,
590 accounts,
591 data: LendingInstruction::DepositObligationCollateral { collateral_amount }.pack(),
592 }
593}
594
595#[allow(clippy::too_many_arguments)]
597pub fn withdraw_obligation_collateral(
598 program_id: Pubkey,
599 collateral_amount: u64,
600 source_collateral_pubkey: Pubkey,
601 destination_collateral_pubkey: Pubkey,
602 withdraw_reserve_pubkey: Pubkey,
603 obligation_pubkey: Pubkey,
604 lending_market_pubkey: Pubkey,
605 obligation_owner_pubkey: Pubkey,
606 option_stake_account_pubkey: Option<Pubkey>,
607 option_staking_pool_pubkey: Option<Pubkey>,
608) -> Instruction {
609 let (lending_market_authority_pubkey, _bump_seed) = Pubkey::find_program_address(
610 &[&lending_market_pubkey.to_bytes()[..PUBKEY_BYTES]],
611 &program_id,
612 );
613 let mut accounts = vec![
614 AccountMeta::new(source_collateral_pubkey, false),
615 AccountMeta::new(destination_collateral_pubkey, false),
616 AccountMeta::new_readonly(withdraw_reserve_pubkey, false),
617 AccountMeta::new(obligation_pubkey, false),
618 AccountMeta::new_readonly(lending_market_pubkey, false),
619 AccountMeta::new_readonly(lending_market_authority_pubkey, false),
620 AccountMeta::new_readonly(obligation_owner_pubkey, true),
621 AccountMeta::new_readonly(sysvar::clock::id(), false),
622 AccountMeta::new_readonly(spl_token::id(), false),
623 ];
624
625 if let [Some(staking_account_pubkey), Some(staking_pool_pubkey)] =
626 [option_stake_account_pubkey, option_staking_pool_pubkey]
627 {
628 accounts.push(AccountMeta::new(staking_account_pubkey, false));
629 accounts.push(AccountMeta::new(staking_pool_pubkey, false));
630 accounts.push(AccountMeta::new_readonly(port_finance_staking::id(), false));
631 }
632 Instruction {
633 program_id,
634 accounts,
635 data: LendingInstruction::WithdrawObligationCollateral { collateral_amount }.pack(),
636 }
637}
638
639#[allow(clippy::too_many_arguments)]
641pub fn borrow_obligation_liquidity(
642 program_id: Pubkey,
643 liquidity_amount: u64,
644 source_liquidity_pubkey: Pubkey,
645 destination_liquidity_pubkey: Pubkey,
646 borrow_reserve_pubkey: Pubkey,
647 borrow_reserve_liquidity_fee_receiver_pubkey: Pubkey,
648 obligation_pubkey: Pubkey,
649 lending_market_pubkey: Pubkey,
650 obligation_owner_pubkey: Pubkey,
651) -> Instruction {
652 let (lending_market_authority_pubkey, _bump_seed) = Pubkey::find_program_address(
653 &[&lending_market_pubkey.to_bytes()[..PUBKEY_BYTES]],
654 &program_id,
655 );
656 let accounts = vec![
657 AccountMeta::new(source_liquidity_pubkey, false),
658 AccountMeta::new(destination_liquidity_pubkey, false),
659 AccountMeta::new(borrow_reserve_pubkey, false),
660 AccountMeta::new(borrow_reserve_liquidity_fee_receiver_pubkey, false),
661 AccountMeta::new(obligation_pubkey, false),
662 AccountMeta::new_readonly(lending_market_pubkey, false),
663 AccountMeta::new_readonly(lending_market_authority_pubkey, false),
664 AccountMeta::new_readonly(obligation_owner_pubkey, true),
665 AccountMeta::new_readonly(sysvar::clock::id(), false),
666 AccountMeta::new_readonly(spl_token::id(), false),
667 ];
668
669 Instruction {
670 program_id,
671 accounts,
672 data: LendingInstruction::BorrowObligationLiquidity { liquidity_amount }.pack(),
673 }
674}
675
676#[allow(clippy::too_many_arguments)]
678pub fn repay_obligation_liquidity(
679 program_id: Pubkey,
680 liquidity_amount: u64,
681 source_liquidity_pubkey: Pubkey,
682 destination_liquidity_pubkey: Pubkey,
683 repay_reserve_pubkey: Pubkey,
684 obligation_pubkey: Pubkey,
685 lending_market_pubkey: Pubkey,
686 user_transfer_authority_pubkey: Pubkey,
687) -> Instruction {
688 let accounts = vec![
689 AccountMeta::new(source_liquidity_pubkey, false),
690 AccountMeta::new(destination_liquidity_pubkey, false),
691 AccountMeta::new(repay_reserve_pubkey, false),
692 AccountMeta::new(obligation_pubkey, false),
693 AccountMeta::new_readonly(lending_market_pubkey, false),
694 AccountMeta::new_readonly(user_transfer_authority_pubkey, true),
695 AccountMeta::new_readonly(sysvar::clock::id(), false),
696 AccountMeta::new_readonly(spl_token::id(), false),
697 ];
698 Instruction {
699 program_id,
700 accounts,
701 data: LendingInstruction::RepayObligationLiquidity { liquidity_amount }.pack(),
702 }
703}
704
705#[allow(clippy::too_many_arguments)]
707pub fn liquidate_obligation(
708 program_id: Pubkey,
709 liquidity_amount: u64,
710 source_liquidity_pubkey: Pubkey,
711 destination_collateral_pubkey: Pubkey,
712 repay_reserve_pubkey: Pubkey,
713 repay_reserve_liquidity_supply_pubkey: Pubkey,
714 withdraw_reserve_pubkey: Pubkey,
715 withdraw_reserve_collateral_supply_pubkey: Pubkey,
716 obligation_pubkey: Pubkey,
717 lending_market_pubkey: Pubkey,
718 user_transfer_authority_pubkey: Pubkey,
719 option_borrow_stake_account_pubkey: Option<Pubkey>,
720 option_borrow_staking_pool_pubkey: Option<Pubkey>,
721) -> Instruction {
722 let (lending_market_authority_pubkey, _bump_seed) = Pubkey::find_program_address(
723 &[&lending_market_pubkey.to_bytes()[..PUBKEY_BYTES]],
724 &program_id,
725 );
726 let mut accounts = vec![
727 AccountMeta::new(source_liquidity_pubkey, false),
728 AccountMeta::new(destination_collateral_pubkey, false),
729 AccountMeta::new(repay_reserve_pubkey, false),
730 AccountMeta::new(repay_reserve_liquidity_supply_pubkey, false),
731 AccountMeta::new_readonly(withdraw_reserve_pubkey, false),
732 AccountMeta::new(withdraw_reserve_collateral_supply_pubkey, false),
733 AccountMeta::new(obligation_pubkey, false),
734 AccountMeta::new_readonly(lending_market_pubkey, false),
735 AccountMeta::new_readonly(lending_market_authority_pubkey, false),
736 AccountMeta::new_readonly(user_transfer_authority_pubkey, true),
737 AccountMeta::new_readonly(sysvar::clock::id(), false),
738 AccountMeta::new_readonly(spl_token::id(), false),
739 ];
740 if let [Some(staking_account_pubkey), Some(staking_pool_pubkey)] = [
741 option_borrow_stake_account_pubkey,
742 option_borrow_staking_pool_pubkey,
743 ] {
744 accounts.push(AccountMeta::new(staking_account_pubkey, false));
745 accounts.push(AccountMeta::new(staking_pool_pubkey, false));
746 accounts.push(AccountMeta::new_readonly(port_finance_staking::id(), false));
747 }
748 Instruction {
749 program_id,
750 accounts,
751 data: LendingInstruction::LiquidateObligation { liquidity_amount }.pack(),
752 }
753}
754
755#[allow(clippy::too_many_arguments)]
757pub fn flash_loan(
758 program_id: Pubkey,
759 amount: u64,
760 source_liquidity_pubkey: Pubkey,
761 destination_liquidity_pubkey: Pubkey,
762 reserve_pubkey: Pubkey,
763 reserve_liquidity_fee_receiver_pubkey: Pubkey,
764 host_fee_receiver_pubkey: Pubkey,
765 lending_market_pubkey: Pubkey,
766 flash_loan_receiver_program_id: Pubkey,
767 flash_loan_receiver_program_accounts: Vec<AccountMeta>,
768) -> Instruction {
769 let (lending_market_authority_pubkey, _bump_seed) = Pubkey::find_program_address(
770 &[&lending_market_pubkey.to_bytes()[..PUBKEY_BYTES]],
771 &program_id,
772 );
773 let mut accounts = vec![
774 AccountMeta::new(source_liquidity_pubkey, false),
775 AccountMeta::new(destination_liquidity_pubkey, false),
776 AccountMeta::new(reserve_pubkey, false),
777 AccountMeta::new(reserve_liquidity_fee_receiver_pubkey, false),
778 AccountMeta::new(host_fee_receiver_pubkey, false),
779 AccountMeta::new_readonly(lending_market_pubkey, false),
780 AccountMeta::new_readonly(lending_market_authority_pubkey, false),
781 AccountMeta::new_readonly(spl_token::id(), false),
782 AccountMeta::new_readonly(flash_loan_receiver_program_id, false),
783 ];
784 accounts.extend(flash_loan_receiver_program_accounts);
785 Instruction {
786 program_id,
787 accounts,
788 data: LendingInstruction::FlashLoan { amount }.pack(),
789 }
790}
791
792#[allow(clippy::too_many_arguments)]
794pub fn deposit_reserve_liquidity_and_obligation_collateral(
795 program_id: Pubkey,
796 liquidity_amount: u64,
797 source_liquidity_pubkey: Pubkey,
798 user_collateral_pubkey: Pubkey,
799 reserve_pubkey: Pubkey,
800 reserve_liquidity_supply_pubkey: Pubkey,
801 reserve_collateral_mint_pubkey: Pubkey,
802 lending_market_pubkey: Pubkey,
803 destination_deposit_collateral_pubkey: Pubkey,
804 obligation_pubkey: Pubkey,
805 obligation_owner_pubkey: Pubkey,
806 user_transfer_authority_pubkey: Pubkey,
807 option_stake_account_pubkey: Option<Pubkey>,
808 option_staking_pool_pubkey: Option<Pubkey>,
809) -> Instruction {
810 let (lending_market_authority_pubkey, _bump_seed) = Pubkey::find_program_address(
811 &[&lending_market_pubkey.to_bytes()[..PUBKEY_BYTES]],
812 &program_id,
813 );
814 let mut accounts = vec![
815 AccountMeta::new(source_liquidity_pubkey, false),
816 AccountMeta::new(user_collateral_pubkey, false),
817 AccountMeta::new(reserve_pubkey, false),
818 AccountMeta::new(reserve_liquidity_supply_pubkey, false),
819 AccountMeta::new(reserve_collateral_mint_pubkey, false),
820 AccountMeta::new_readonly(lending_market_pubkey, false),
821 AccountMeta::new_readonly(lending_market_authority_pubkey, false),
822 AccountMeta::new(destination_deposit_collateral_pubkey, false),
823 AccountMeta::new(obligation_pubkey, false),
824 AccountMeta::new(obligation_owner_pubkey, true),
825 AccountMeta::new_readonly(user_transfer_authority_pubkey, true),
826 AccountMeta::new_readonly(sysvar::clock::id(), false),
827 AccountMeta::new_readonly(spl_token::id(), false),
828 ];
829 if let [Some(staking_account_pubkey), Some(staking_pool_pubkey)] =
830 [option_stake_account_pubkey, option_staking_pool_pubkey]
831 {
832 accounts.push(AccountMeta::new(staking_account_pubkey, false));
833 accounts.push(AccountMeta::new(staking_pool_pubkey, false));
834 accounts.push(AccountMeta::new_readonly(port_finance_staking::id(), false));
835 }
836 Instruction {
837 program_id,
838 accounts,
839 data: LendingInstruction::DepositReserveLiquidityAndObligationCollateral {
840 liquidity_amount,
841 }
842 .pack(),
843 }
844}