diff --git a/controller/program/src/instructions/admin/add_lst.rs b/controller/program/src/instructions/admin/add_lst.rs index 11d59185..5b9d2f9b 100644 --- a/controller/program/src/instructions/admin/add_lst.rs +++ b/controller/program/src/instructions/admin/add_lst.rs @@ -1,14 +1,13 @@ use crate::{ - utils::extend_lst_state_list, + utils::{accs_split_first_chunk, extend_lst_state_list}, verify::{ - verify_not_rebalancing_and_not_disabled, verify_pks, verify_signers, - verify_sol_value_calculator_is_program, verify_tokenkeg_or_22_mint, + verify_lst_state_list_no_dup, verify_not_rebalancing_and_not_disabled, verify_pks, + verify_signers, verify_sol_value_calculator_is_program, verify_tokenkeg_or_22_mint, }, Cpi, }; use inf1_ctl_jiminy::{ - account_utils::{lst_state_list_checked_mut, pool_state_v2_checked}, - accounts::lst_state_list::LstStatePackedList, + account_utils::{lst_state_list_checked, lst_state_list_checked_mut, pool_state_v2_checked}, err::Inf1CtlErr, instructions::admin::add_lst::{AddLstIxAccs, NewAddLstIxAccsBuilder, ADD_LST_IX_IS_SIGNER}, keys::{ATOKEN_ID, LST_STATE_LIST_ID, POOL_STATE_ID, PROTOCOL_FEE_ID, SYS_PROG_ID}, @@ -18,9 +17,9 @@ use inf1_ctl_jiminy::{ }; use jiminy_cpi::{ account::{Abr, AccountHandle}, - program_error::{ProgramError, INVALID_SEEDS, NOT_ENOUGH_ACCOUNT_KEYS}, + program_error::{ProgramError, INVALID_SEEDS}, }; -use jiminy_sysvar_rent::{sysvar::SimpleSysvar, Rent}; +use jiminy_sysvar_rent::Rent; use sanctum_ata_jiminy::sanctum_ata_core::instructions::create::{ CreateIdempotentIxData, NewCreateIxAccsBuilder, }; @@ -29,10 +28,11 @@ use sanctum_system_jiminy::sanctum_system_core::instructions::transfer::NewTrans #[inline] pub fn process_add_lst( abr: &mut Abr, - accounts: &[AccountHandle], cpi: &mut Cpi, + accs: &[AccountHandle], + rent: &Rent, ) -> Result<(), ProgramError> { - let accs = accounts.first_chunk().ok_or(NOT_ENOUGH_ACCOUNT_KEYS)?; + let (accs, _) = accs_split_first_chunk(accs)?; let accs = AddLstIxAccs(*accs); let pool = pool_state_v2_checked(abr.get(*accs.pool_state()))?; @@ -72,17 +72,13 @@ pub fn process_add_lst( verify_tokenkeg_or_22_mint(lst_mint_acc)?; verify_sol_value_calculator_is_program(abr.get(*accs.sol_value_calculator()))?; - // Verify no duplicate in lst state list - let lst_state_list_acc = abr.get(*accs.lst_state_list()); - let list = LstStatePackedList::of_acc_data(lst_state_list_acc.data()) - .ok_or(Inf1CtlCustomProgErr(Inf1CtlErr::InvalidLstStateListData))?; - - if list.find_by_mint(lst_mint_acc.key()).is_some() { - return Err(Inf1CtlCustomProgErr(Inf1CtlErr::DuplicateLst).into()); - } + let list = lst_state_list_checked(abr.get(*accs.lst_state_list()))?.0; + verify_lst_state_list_no_dup(list, lst_mint_acc.key())?; // idx=u32::MAX is reserved for LP mint - if list.0.len() >= u32::MAX as usize { + // cant even test this because at this number, the size of list + // exceeds max account size of 10MB lul + if list.len() >= u32::MAX as usize { return Err(Inf1CtlCustomProgErr(Inf1CtlErr::IndexTooLarge).into()); } @@ -124,7 +120,7 @@ pub fn process_add_lst( .with_from(*accs.payer()) .with_to(*accs.lst_state_list()) .build(), - &Rent::get()?, + rent, )?; // Add lst state to lst state list diff --git a/controller/program/src/instructions/admin/lst_input/common.rs b/controller/program/src/instructions/admin/lst_input/common.rs index 900b84ee..33e6c49e 100644 --- a/controller/program/src/instructions/admin/lst_input/common.rs +++ b/controller/program/src/instructions/admin/lst_input/common.rs @@ -12,11 +12,11 @@ use inf1_ctl_jiminy::{ }; use jiminy_cpi::{ account::{Abr, AccountHandle}, - program_error::{ProgramError, NOT_ENOUGH_ACCOUNT_KEYS}, + program_error::ProgramError, }; use crate::{ - utils::ix_data_as_arr, + utils::{accs_split_first_chunk, ix_data_as_arr}, verify::{verify_not_rebalancing_and_not_disabled, verify_pks, verify_signers}, }; @@ -26,7 +26,7 @@ pub fn set_lst_input_checked<'acc>( accs: &[AccountHandle<'acc>], data_no_discm: &[u8], ) -> Result<(SetLstInputIxAccs>, usize), ProgramError> { - let accs = accs.first_chunk().ok_or(NOT_ENOUGH_ACCOUNT_KEYS)?; + let (accs, _) = accs_split_first_chunk(accs)?; let accs = SetLstInputIxAccs(*accs); let idx = u32_ix_data_parse_no_discm(ix_data_as_arr(data_no_discm)?) as usize; diff --git a/controller/program/src/instructions/admin/remove_lst.rs b/controller/program/src/instructions/admin/remove_lst.rs index 83e3cae3..54625407 100644 --- a/controller/program/src/instructions/admin/remove_lst.rs +++ b/controller/program/src/instructions/admin/remove_lst.rs @@ -13,9 +13,9 @@ use inf1_ctl_jiminy::{ }; use jiminy_cpi::{ account::{Abr, AccountHandle}, - program_error::{ProgramError, NOT_ENOUGH_ACCOUNT_KEYS}, + program_error::ProgramError, }; -use jiminy_sysvar_rent::{sysvar::SimpleSysvar, Rent}; +use jiminy_sysvar_rent::Rent; use sanctum_spl_token_jiminy::{ instructions::close_account::close_account_ix_account_handle_perms, sanctum_spl_token_core::instructions::close_account::{ @@ -26,7 +26,7 @@ use sanctum_system_jiminy::sanctum_system_core::instructions::transfer::NewTrans use crate::{ token::get_token_account_amount, - utils::shrink_lst_state_list, + utils::{accs_split_first_chunk, shrink_lst_state_list}, verify::{verify_not_rebalancing_and_not_disabled, verify_pks, verify_signers}, Cpi, }; @@ -35,10 +35,11 @@ use crate::{ pub fn process_remove_lst( abr: &mut Abr, cpi: &mut Cpi, - accounts: &[AccountHandle], + accs: &[AccountHandle], lst_idx: usize, + rent: &Rent, ) -> Result<(), ProgramError> { - let accs = accounts.first_chunk().ok_or(NOT_ENOUGH_ACCOUNT_KEYS)?; + let (accs, _) = accs_split_first_chunk(accs)?; let accs = RemoveLstIxAccs(*accs); let list = lst_state_list_checked(abr.get(*accs.lst_state_list()))?; @@ -120,7 +121,7 @@ pub fn process_remove_lst( .with_from(*accs.lst_state_list()) .with_to(*accs.refund_rent_to()) .build(), - &Rent::get()?, + rent, lst_idx, )?; diff --git a/controller/program/src/instructions/admin/set_admin.rs b/controller/program/src/instructions/admin/set_admin.rs index 084041e6..eb7cd1c5 100644 --- a/controller/program/src/instructions/admin/set_admin.rs +++ b/controller/program/src/instructions/admin/set_admin.rs @@ -7,10 +7,13 @@ use inf1_ctl_jiminy::{ }; use jiminy_cpi::{ account::{Abr, AccountHandle}, - program_error::{ProgramError, NOT_ENOUGH_ACCOUNT_KEYS}, + program_error::ProgramError, }; -use crate::verify::{verify_pks, verify_signers}; +use crate::{ + utils::accs_split_first_chunk, + verify::{verify_pks, verify_signers}, +}; type SetAdminIxAccounts<'acc> = SetAdminIxAccs>; @@ -19,7 +22,7 @@ pub fn set_admin_accs_checked<'acc>( abr: &mut Abr, accs: &[AccountHandle<'acc>], ) -> Result, ProgramError> { - let accs = accs.first_chunk().ok_or(NOT_ENOUGH_ACCOUNT_KEYS)?; + let (accs, _) = accs_split_first_chunk(accs)?; let accs = SetAdminIxAccs(*accs); let pool = pool_state_v2_checked(abr.get(*accs.pool_state()))?; @@ -38,7 +41,7 @@ pub fn set_admin_accs_checked<'acc>( } #[inline] -pub fn process_set_admin(abr: &mut Abr, accs: SetAdminIxAccounts) -> Result<(), ProgramError> { +pub fn process_set_admin(abr: &mut Abr, accs: &SetAdminIxAccounts) -> Result<(), ProgramError> { let new_admin = *abr.get(*accs.new()).key(); let pool = pool_state_v2_checked_mut(abr.get_mut(*accs.pool_state()))?; pool.admin = new_admin; diff --git a/controller/program/src/instructions/admin/set_pricing_prog.rs b/controller/program/src/instructions/admin/set_pricing_prog.rs index 20e959d7..8cc57262 100644 --- a/controller/program/src/instructions/admin/set_pricing_prog.rs +++ b/controller/program/src/instructions/admin/set_pricing_prog.rs @@ -7,12 +7,15 @@ use inf1_ctl_jiminy::{ }; use jiminy_cpi::{ account::{Abr, AccountHandle}, - program_error::{ProgramError, NOT_ENOUGH_ACCOUNT_KEYS}, + program_error::ProgramError, }; -use crate::verify::{ - verify_not_rebalancing_and_not_disabled, verify_pks, verify_pricing_program_is_program, - verify_signers, +use crate::{ + utils::accs_split_first_chunk, + verify::{ + verify_not_rebalancing_and_not_disabled, verify_pks, verify_pricing_program_is_program, + verify_signers, + }, }; type SetPricingProgIxAccounts<'acc> = SetPricingProgIxAccs>; @@ -22,7 +25,7 @@ pub fn set_pricing_prog_accs_checked<'acc>( abr: &mut Abr, accs: &[AccountHandle<'acc>], ) -> Result, ProgramError> { - let accs = accs.first_chunk().ok_or(NOT_ENOUGH_ACCOUNT_KEYS)?; + let (accs, _) = accs_split_first_chunk(accs)?; let accs = SetPricingProgIxAccs(*accs); let pool = pool_state_v2_checked(abr.get(*accs.pool_state()))?; @@ -48,7 +51,7 @@ pub fn set_pricing_prog_accs_checked<'acc>( #[inline] pub fn process_set_pricing_prog( abr: &mut Abr, - accs: SetPricingProgIxAccounts, + accs: &SetPricingProgIxAccounts, ) -> Result<(), ProgramError> { let new_pp = *abr.get(*accs.new()).key(); let pool = pool_state_v2_checked_mut(abr.get_mut(*accs.pool_state()))?; diff --git a/controller/program/src/instructions/admin/set_sol_value_calculator.rs b/controller/program/src/instructions/admin/set_sol_value_calculator.rs index 543511da..93510915 100644 --- a/controller/program/src/instructions/admin/set_sol_value_calculator.rs +++ b/controller/program/src/instructions/admin/set_sol_value_calculator.rs @@ -18,7 +18,7 @@ use inf1_ctl_jiminy::{ }; use jiminy_cpi::{ account::{Abr, AccountHandle}, - program_error::{ProgramError, NOT_ENOUGH_ACCOUNT_KEYS}, + program_error::ProgramError, }; use inf1_core::instructions::admin::set_sol_value_calculator::SetSolValueCalculatorIxAccs; @@ -27,7 +27,7 @@ use jiminy_sysvar_clock::Clock; use crate::{ svc::lst_ssv_uy, - utils::split_suf_accs, + utils::{accs_split_first_chunk, split_suf_accs}, verify::{ verify_not_rebalancing_and_not_disabled, verify_pks, verify_signers, verify_sol_value_calculator_is_program, @@ -48,7 +48,7 @@ pub fn set_sol_value_calculator_accs_checked<'a, 'acc>( accs: &'a [AccountHandle<'acc>], lst_idx: usize, ) -> Result, ProgramError> { - let (ix_prefix, suf) = accs.split_first_chunk().ok_or(NOT_ENOUGH_ACCOUNT_KEYS)?; + let (ix_prefix, suf) = accs_split_first_chunk(accs)?; let ix_prefix = SetSolValueCalculatorIxPreAccs(*ix_prefix); let list = lst_state_list_checked(abr.get(*ix_prefix.lst_state_list()))?; diff --git a/controller/program/src/instructions/disable_pool/add_disable_pool_auth.rs b/controller/program/src/instructions/disable_pool/add_disable_pool_auth.rs index fb51a72f..93f3d4ab 100644 --- a/controller/program/src/instructions/disable_pool/add_disable_pool_auth.rs +++ b/controller/program/src/instructions/disable_pool/add_disable_pool_auth.rs @@ -12,14 +12,14 @@ use inf1_ctl_jiminy::{ }; use jiminy_cpi::{ account::{Abr, AccountHandle}, - program_error::{ProgramError, NOT_ENOUGH_ACCOUNT_KEYS}, + program_error::ProgramError, Cpi, }; -use jiminy_sysvar_rent::{sysvar::SimpleSysvar, Rent}; +use jiminy_sysvar_rent::Rent; use sanctum_system_jiminy::sanctum_system_core::instructions::transfer::NewTransferIxAccsBuilder; use crate::{ - utils::extend_disable_pool_auth_list, + utils::{accs_split_first_chunk, extend_disable_pool_auth_list}, verify::{verify_disable_pool_auth_list_no_dup, verify_pks, verify_signers}, }; @@ -30,7 +30,7 @@ pub fn add_disable_pool_auth_accs_checked<'acc>( abr: &Abr, accs: &[AccountHandle<'acc>], ) -> Result, ProgramError> { - let accs = accs.first_chunk().ok_or(NOT_ENOUGH_ACCOUNT_KEYS)?; + let (accs, _) = accs_split_first_chunk(accs)?; let accs = AddDisablePoolAuthIxAccs(*accs); let pool = pool_state_v2_checked(abr.get(*accs.pool_state()))?; @@ -61,6 +61,7 @@ pub fn process_add_disable_pool_auth( abr: &mut Abr, cpi: &mut Cpi, accs: &AddDisablePoolAuthAccounts, + rent: &Rent, ) -> Result<(), ProgramError> { extend_disable_pool_auth_list( abr, @@ -69,7 +70,7 @@ pub fn process_add_disable_pool_auth( .with_from(*accs.payer()) .with_to(*accs.disable_pool_auth_list()) .build(), - &Rent::get()?, + rent, )?; let new_auth = *abr.get(*accs.new()).key(); let list = disable_pool_auth_list_checked_mut(abr.get_mut(*accs.disable_pool_auth_list()))?; diff --git a/controller/program/src/instructions/disable_pool/disable.rs b/controller/program/src/instructions/disable_pool/disable.rs index ca03b57b..506909e8 100644 --- a/controller/program/src/instructions/disable_pool/disable.rs +++ b/controller/program/src/instructions/disable_pool/disable.rs @@ -13,10 +13,13 @@ use inf1_ctl_jiminy::{ }; use jiminy_cpi::{ account::{Abr, AccountHandle}, - program_error::{ProgramError, NOT_ENOUGH_ACCOUNT_KEYS}, + program_error::ProgramError, }; -use crate::verify::{verify_not_rebalancing_and_not_disabled, verify_pks, verify_signers}; +use crate::{ + utils::accs_split_first_chunk, + verify::{verify_not_rebalancing_and_not_disabled, verify_pks, verify_signers}, +}; type DisablePoolIxAccounts<'acc> = DisablePoolIxAccs>; @@ -25,7 +28,7 @@ pub fn disable_pool_accs_checked<'acc>( abr: &mut Abr, accs: &[AccountHandle<'acc>], ) -> Result, ProgramError> { - let accs = accs.first_chunk().ok_or(NOT_ENOUGH_ACCOUNT_KEYS)?; + let (accs, _) = accs_split_first_chunk(accs)?; let accs = DisablePoolIxAccs(*accs); let signer_pk = abr.get(*accs.signer()).key(); diff --git a/controller/program/src/instructions/disable_pool/enable.rs b/controller/program/src/instructions/disable_pool/enable.rs index a7f69e3e..1efa0be5 100644 --- a/controller/program/src/instructions/disable_pool/enable.rs +++ b/controller/program/src/instructions/disable_pool/enable.rs @@ -11,10 +11,13 @@ use inf1_ctl_jiminy::{ }; use jiminy_cpi::{ account::{Abr, AccountHandle}, - program_error::{ProgramError, NOT_ENOUGH_ACCOUNT_KEYS}, + program_error::ProgramError, }; -use crate::verify::{verify_pks, verify_signers}; +use crate::{ + utils::accs_split_first_chunk, + verify::{verify_pks, verify_signers}, +}; type EnablePoolIxAccounts<'acc> = EnablePoolIxAccs>; @@ -23,7 +26,7 @@ pub fn enable_pool_accs_checked<'acc>( abr: &Abr, accs: &[AccountHandle<'acc>], ) -> Result, ProgramError> { - let accs = accs.first_chunk().ok_or(NOT_ENOUGH_ACCOUNT_KEYS)?; + let (accs, _) = accs_split_first_chunk(accs)?; let accs = EnablePoolIxAccs(*accs); let PoolStateV2 { diff --git a/controller/program/src/instructions/disable_pool/remove_disable_pool_auth.rs b/controller/program/src/instructions/disable_pool/remove_disable_pool_auth.rs index 7b92be30..cf7cbfb1 100644 --- a/controller/program/src/instructions/disable_pool/remove_disable_pool_auth.rs +++ b/controller/program/src/instructions/disable_pool/remove_disable_pool_auth.rs @@ -13,13 +13,13 @@ use inf1_ctl_jiminy::{ }; use jiminy_cpi::{ account::{Abr, AccountHandle}, - program_error::{ProgramError, INVALID_INSTRUCTION_DATA, NOT_ENOUGH_ACCOUNT_KEYS}, + program_error::{ProgramError, INVALID_INSTRUCTION_DATA}, }; -use jiminy_sysvar_rent::{sysvar::SimpleSysvar, Rent}; +use jiminy_sysvar_rent::Rent; use sanctum_system_jiminy::sanctum_system_core::instructions::transfer::NewTransferIxAccsBuilder; use crate::{ - utils::shrink_disable_pool_auth_list, + utils::{accs_split_first_chunk, shrink_disable_pool_auth_list}, verify::{verify_pks, verify_signers}, }; @@ -31,7 +31,7 @@ pub fn remove_disable_pool_auth_checked<'acc>( accs: &[AccountHandle<'acc>], data_no_discm: &[u8], ) -> Result<(RemoveDisablePoolAuthAccounts<'acc>, usize), ProgramError> { - let accs = accs.first_chunk().ok_or(NOT_ENOUGH_ACCOUNT_KEYS)?; + let (accs, _) = accs_split_first_chunk(accs)?; let accs = RemoveDisablePoolAuthIxAccs(*accs); let idx = RemoveDisablePoolAuthIxData::parse_no_discm( @@ -72,6 +72,7 @@ pub fn process_remove_disable_pool_auth( abr: &mut Abr, accs: &RemoveDisablePoolAuthAccounts, idx: usize, + rent: &Rent, ) -> Result<(), ProgramError> { shrink_disable_pool_auth_list( abr, @@ -79,7 +80,7 @@ pub fn process_remove_disable_pool_auth( .with_from(*accs.disable_pool_auth_list()) .with_to(*accs.refund_rent_to()) .build(), - &Rent::get()?, + rent, idx, ) } diff --git a/controller/program/src/instructions/protocol_fee/set_protocol_fee.rs b/controller/program/src/instructions/protocol_fee/set_protocol_fee.rs index 857a6a97..781c2bcb 100644 --- a/controller/program/src/instructions/protocol_fee/set_protocol_fee.rs +++ b/controller/program/src/instructions/protocol_fee/set_protocol_fee.rs @@ -12,10 +12,13 @@ use inf1_ctl_jiminy::{ }; use jiminy_cpi::{ account::{Abr, AccountHandle}, - program_error::{ProgramError, INVALID_INSTRUCTION_DATA, NOT_ENOUGH_ACCOUNT_KEYS}, + program_error::{ProgramError, INVALID_INSTRUCTION_DATA}, }; -use crate::verify::{verify_not_rebalancing_and_not_disabled, verify_pks, verify_signers}; +use crate::{ + utils::accs_split_first_chunk, + verify::{verify_not_rebalancing_and_not_disabled, verify_pks, verify_signers}, +}; type SetProtocolFeeIxAccounts<'acc> = SetProtocolFeeIxAccs>; @@ -25,7 +28,7 @@ pub fn set_protocol_fee_checked<'acc>( accs: &[AccountHandle<'acc>], ix_data_no_discm: &[u8], ) -> Result<(SetProtocolFeeIxAccounts<'acc>, FeeNanos), ProgramError> { - let accs = accs.first_chunk().ok_or(NOT_ENOUGH_ACCOUNT_KEYS)?; + let (accs, _) = accs_split_first_chunk(accs)?; let accs = SetProtocolFeeIxAccs(*accs); let pool = pool_state_v2_checked(abr.get(*accs.pool_state()))?; diff --git a/controller/program/src/instructions/protocol_fee/set_protocol_fee_beneficiary.rs b/controller/program/src/instructions/protocol_fee/set_protocol_fee_beneficiary.rs index 5a88c74e..803f4c2c 100644 --- a/controller/program/src/instructions/protocol_fee/set_protocol_fee_beneficiary.rs +++ b/controller/program/src/instructions/protocol_fee/set_protocol_fee_beneficiary.rs @@ -9,10 +9,13 @@ use inf1_ctl_jiminy::{ }; use jiminy_cpi::{ account::{Abr, AccountHandle}, - program_error::{ProgramError, NOT_ENOUGH_ACCOUNT_KEYS}, + program_error::ProgramError, }; -use crate::verify::{verify_pks, verify_signers}; +use crate::{ + utils::accs_split_first_chunk, + verify::{verify_pks, verify_signers}, +}; type SetProtocolFeeBeneficiaryIxAccounts<'acc> = SetProtocolFeeBeneficiaryIxAccs>; @@ -22,7 +25,7 @@ pub fn set_protocol_fee_beneficiary_accs_checked<'acc>( abr: &Abr, accs: &[AccountHandle<'acc>], ) -> Result, ProgramError> { - let accs = accs.first_chunk().ok_or(NOT_ENOUGH_ACCOUNT_KEYS)?; + let (accs, _) = accs_split_first_chunk(accs)?; let accs = SetProtocolFeeBeneficiaryIxAccs(*accs); let pool = pool_state_v2_checked(abr.get(*accs.pool_state()))?; @@ -43,7 +46,7 @@ pub fn set_protocol_fee_beneficiary_accs_checked<'acc>( #[inline] pub fn process_set_protocol_fee_beneficiary( abr: &mut Abr, - accs: SetProtocolFeeBeneficiaryIxAccounts, + accs: &SetProtocolFeeBeneficiaryIxAccounts, ) -> Result<(), ProgramError> { let new_beneficiary = *abr.get(*accs.new()).key(); let PoolStateV2 { diff --git a/controller/program/src/instructions/protocol_fee/withdraw_protocol_fees/v1.rs b/controller/program/src/instructions/protocol_fee/withdraw_protocol_fees/v1.rs index a0d1b77c..5bbf03be 100644 --- a/controller/program/src/instructions/protocol_fee/withdraw_protocol_fees/v1.rs +++ b/controller/program/src/instructions/protocol_fee/withdraw_protocol_fees/v1.rs @@ -11,22 +11,19 @@ use inf1_ctl_jiminy::{ }; use jiminy_cpi::{ account::{Abr, AccountHandle}, - program_error::{ - ProgramError, INVALID_ACCOUNT_DATA, INVALID_INSTRUCTION_DATA, INVALID_SEEDS, - NOT_ENOUGH_ACCOUNT_KEYS, - }, + program_error::{ProgramError, INVALID_INSTRUCTION_DATA, INVALID_SEEDS}, Cpi, }; use sanctum_spl_token_jiminy::{ instructions::transfer::transfer_checked_ix_account_handle_perms, - sanctum_spl_token_core::{ - instructions::transfer::{NewTransferCheckedIxAccsBuilder, TransferCheckedIxData}, - state::mint::{Mint, RawMint}, + sanctum_spl_token_core::instructions::transfer::{ + NewTransferCheckedIxAccsBuilder, TransferCheckedIxData, }, }; use crate::{ - token::get_token_account_amount, + token::{checked_mint_of, get_token_account_amount}, + utils::accs_split_first_chunk, verify::{ verify_not_rebalancing_and_not_disabled, verify_pks, verify_signers, verify_tokenkeg_or_22_mint, @@ -41,7 +38,7 @@ pub fn withdraw_protocol_fees_checked<'acc>( accs: &[AccountHandle<'acc>], ix_data_no_discm: &[u8], ) -> Result<(WithdrawProtocolFeesIxAccounts<'acc>, u64), ProgramError> { - let accs = accs.first_chunk().ok_or(NOT_ENOUGH_ACCOUNT_KEYS)?; + let (accs, _) = accs_split_first_chunk(accs)?; let accs = WithdrawProtocolFeesIxAccs(*accs); let data: &[u8; 8] = ix_data_no_discm @@ -92,10 +89,7 @@ pub fn process_withdraw_protocol_fees( accs: &WithdrawProtocolFeesIxAccounts, amt: u64, ) -> Result<(), ProgramError> { - let decimals = RawMint::of_acc_data(abr.get(*accs.lst_mint()).data()) - .and_then(Mint::try_from_raw) - .ok_or(INVALID_ACCOUNT_DATA)? - .decimals(); + let decimals = checked_mint_of(abr.get(*accs.lst_mint()))?.decimals(); cpi.invoke_signed_handle( abr, diff --git a/controller/program/src/instructions/rebalance/end.rs b/controller/program/src/instructions/rebalance/end.rs index 1c2716cf..ded980c7 100644 --- a/controller/program/src/instructions/rebalance/end.rs +++ b/controller/program/src/instructions/rebalance/end.rs @@ -99,8 +99,8 @@ fn end_rebalance_accs_checked<'a, 'acc>( #[inline] pub fn process_end_rebalance( abr: &mut Abr, - accounts: &[AccountHandle], cpi: &mut Cpi, + accounts: &[AccountHandle], ) -> Result<(), ProgramError> { let EndRebalanceIxAccounts { ix_prefix, diff --git a/controller/program/src/instructions/rebalance/set_rebal_auth.rs b/controller/program/src/instructions/rebalance/set_rebal_auth.rs index f4b5e236..98474072 100644 --- a/controller/program/src/instructions/rebalance/set_rebal_auth.rs +++ b/controller/program/src/instructions/rebalance/set_rebal_auth.rs @@ -10,10 +10,13 @@ use inf1_ctl_jiminy::{ }; use jiminy_cpi::{ account::{Abr, AccountHandle}, - program_error::{ProgramError, NOT_ENOUGH_ACCOUNT_KEYS}, + program_error::ProgramError, }; -use crate::verify::{verify_not_rebalancing_and_not_disabled, verify_pks, verify_signers}; +use crate::{ + utils::accs_split_first_chunk, + verify::{verify_not_rebalancing_and_not_disabled, verify_pks, verify_signers}, +}; type SetRebalAuthIxAccounts<'acc> = SetRebalAuthIxAccs>; @@ -22,7 +25,7 @@ pub fn set_rebal_auth_accs_checked<'acc>( abr: &Abr, accs: &[AccountHandle<'acc>], ) -> Result, ProgramError> { - let accs = accs.first_chunk().ok_or(NOT_ENOUGH_ACCOUNT_KEYS)?; + let (accs, _) = accs_split_first_chunk(accs)?; let accs = SetRebalAuthIxAccs(*accs); let expected_pks = NewSetRebalAuthIxAccsBuilder::start() @@ -54,7 +57,7 @@ pub fn set_rebal_auth_accs_checked<'acc>( #[inline] pub fn process_set_rebal_auth( abr: &mut Abr, - accs: SetRebalAuthIxAccounts, + accs: &SetRebalAuthIxAccounts, ) -> Result<(), ProgramError> { let new_rebal_auth = *abr.get(*accs.new()).key(); let PoolStateV2 { diff --git a/controller/program/src/instructions/rebalance/start.rs b/controller/program/src/instructions/rebalance/start.rs index c3ee5e4b..49f621a7 100644 --- a/controller/program/src/instructions/rebalance/start.rs +++ b/controller/program/src/instructions/rebalance/start.rs @@ -197,7 +197,7 @@ pub fn process_start_rebalance( abr: &mut Abr, cpi: &mut Cpi, accounts: &[AccountHandle], - args: StartRebalanceIxArgs, + args: &StartRebalanceIxArgs, clock: &Clock, ) -> Result<(), ProgramError> { let StartRebalanceIxAccounts { @@ -206,7 +206,7 @@ pub fn process_start_rebalance( out_calc, inp_calc_prog, inp_calc, - } = start_rebalance_accs_checked(abr, accounts, &args)?; + } = start_rebalance_accs_checked(abr, accounts, args)?; pool_state_v2_checked_mut(abr.get_mut(*ix_prefix.pool_state()))? .release_yield(clock.slot) diff --git a/controller/program/src/instructions/rps/set_rps_auth.rs b/controller/program/src/instructions/rps/set_rps_auth.rs index b25a7cb3..928c2f7f 100644 --- a/controller/program/src/instructions/rps/set_rps_auth.rs +++ b/controller/program/src/instructions/rps/set_rps_auth.rs @@ -51,7 +51,10 @@ pub fn set_rps_auth_accs_checked<'acc>( } #[inline] -pub fn process_set_rps_auth(abr: &mut Abr, accs: SetRpsAuthIxAccounts) -> Result<(), ProgramError> { +pub fn process_set_rps_auth( + abr: &mut Abr, + accs: &SetRpsAuthIxAccounts, +) -> Result<(), ProgramError> { let new_rps_auth = *abr.get(*accs.new_rps_auth()).key(); let PoolStateV2 { rps_authority, .. } = pool_state_v2_checked_mut(abr.get_mut(*accs.pool_state()))?; diff --git a/controller/program/src/instructions/swap/v2/common.rs b/controller/program/src/instructions/swap/v2/common.rs index dca8272f..0d91b4fa 100644 --- a/controller/program/src/instructions/swap/v2/common.rs +++ b/controller/program/src/instructions/swap/v2/common.rs @@ -230,7 +230,8 @@ pub fn verify_swap_v2( verify_pks(abr, &ix_prefix.0, &expected_pre.0)?; // no signer verification required, only signer is `signer` - // and token transfer will just fail without correct auth + // and token movement CPI from inp_acc will + // just fail without correct auth Ok(()) } diff --git a/controller/program/src/instructions/sync_sol_value.rs b/controller/program/src/instructions/sync_sol_value.rs index e8640eb0..e7c5ba50 100644 --- a/controller/program/src/instructions/sync_sol_value.rs +++ b/controller/program/src/instructions/sync_sol_value.rs @@ -1,6 +1,9 @@ use inf1_core::instructions::sync_sol_value::SyncSolValueIxAccs; use inf1_ctl_jiminy::{ - account_utils::{lst_state_list_checked, lst_state_list_get, pool_state_v2_checked_mut}, + account_utils::{ + lst_state_list_checked, lst_state_list_get, pool_state_v2_checked, + pool_state_v2_checked_mut, + }, err::Inf1CtlErr, instructions::sync_sol_value::{NewSyncSolValueIxPreAccsBuilder, SyncSolValueIxPreAccs}, keys::{LST_STATE_LIST_ID, POOL_STATE_ID}, @@ -9,29 +12,26 @@ use inf1_ctl_jiminy::{ }; use jiminy_cpi::{ account::{Abr, AccountHandle}, - program_error::{ProgramError, NOT_ENOUGH_ACCOUNT_KEYS}, + program_error::ProgramError, }; use jiminy_sysvar_clock::Clock; use crate::{ acc_migrations::pool_state, - svc::lst_ssv_uy, - utils::split_suf_accs, + svc::{lst_ssv_uy, SyncSolValIxAccounts}, + utils::{accs_split_first_chunk, split_suf_accs}, verify::{verify_not_rebalancing_and_not_disabled, verify_pks}, Cpi, }; #[inline] -pub fn process_sync_sol_value( +pub fn sync_sol_value_accs_checked<'a, 'acc>( abr: &mut Abr, - cpi: &mut Cpi, - accounts: &[AccountHandle<'_>], + accs: &'a [AccountHandle<'acc>], lst_idx: usize, clock: &Clock, -) -> Result<(), ProgramError> { - let (ix_prefix, suf) = accounts - .split_first_chunk() - .ok_or(NOT_ENOUGH_ACCOUNT_KEYS)?; +) -> Result, ProgramError> { + let (ix_prefix, suf) = accs_split_first_chunk(accs)?; let ix_prefix = SyncSolValueIxPreAccs(*ix_prefix); pool_state::v2::migrate_idmpt(abr.get_mut(*ix_prefix.pool_state()), clock)?; @@ -56,22 +56,29 @@ pub fn process_sync_sol_value( let [(calc_prog, calc)] = split_suf_accs(suf, &[])?; verify_pks(abr, &[calc_prog], &[&lst_state.sol_value_calculator])?; - let pool = pool_state_v2_checked_mut(abr.get_mut(*ix_prefix.pool_state()))?; + let pool = pool_state_v2_checked(abr.get(*ix_prefix.pool_state()))?; verify_not_rebalancing_and_not_disabled(pool)?; - pool.release_yield(clock.slot) + Ok(SyncSolValueIxAccs { + ix_prefix, + calc_prog: *abr.get(calc_prog).key(), + calc, + }) +} + +#[inline] +pub fn process_sync_sol_value( + abr: &mut Abr, + cpi: &mut Cpi, + accs: &SyncSolValIxAccounts, + lst_idx: usize, + clock: &Clock, +) -> Result<(), ProgramError> { + pool_state_v2_checked_mut(abr.get_mut(*accs.ix_prefix.pool_state()))? + .release_yield(clock.slot) .map_err(Inf1CtlCustomProgErr)?; - lst_ssv_uy( - abr, - cpi, - &SyncSolValueIxAccs { - ix_prefix, - calc_prog: *abr.get(calc_prog).key(), - calc, - }, - lst_idx, - )?; + lst_ssv_uy(abr, cpi, accs, lst_idx)?; Ok(()) } diff --git a/controller/program/src/lib.rs b/controller/program/src/lib.rs index 1ae20031..6614b827 100644 --- a/controller/program/src/lib.rs +++ b/controller/program/src/lib.rs @@ -47,7 +47,7 @@ use jiminy_entrypoint::{ }; use jiminy_log::sol_log; use jiminy_sysvar_clock::Clock; -use jiminy_sysvar_rent::sysvar::SimpleSysvar; +use jiminy_sysvar_rent::{sysvar::SimpleSysvar, Rent}; use crate::{ instructions::{ @@ -103,7 +103,7 @@ use crate::{ verify_swap_v2, }, }, - sync_sol_value::process_sync_sol_value, + sync_sol_value::{process_sync_sol_value, sync_sol_value_accs_checked}, }, utils::ix_data_as_arr, }; @@ -154,13 +154,15 @@ fn process_ix( // `as_uninit_mut` only available in nightly. let cpi: &'static mut Cpi = unsafe { CPI_PTR.as_mut().unwrap_unchecked() }; let mut clock = MaybeUninit::uninit(); + let mut rent = MaybeUninit::uninit(); match data.split_first().ok_or(INVALID_INSTRUCTION_DATA)? { (&SYNC_SOL_VALUE_IX_DISCM, data) => { sol_log("SyncSolValue"); let lst_idx = SyncSolValueIxData::parse_no_discm(ix_data_as_arr(data)?) as usize; let clock = Clock::write_to(&mut clock)?; - process_sync_sol_value(abr, cpi, accounts, lst_idx, clock) + let accs = sync_sol_value_accs_checked(abr, accounts, lst_idx, clock)?; + process_sync_sol_value(abr, cpi, &accs, lst_idx, clock) } // core user-facing ixs // v1 swap + liquidity @@ -198,6 +200,23 @@ fn process_ix( verify_swap_v2(abr, &accs, &args, clock)?; process_swap_exact_in_v2(abr, cpi, &accs, &args, clock) } + // v2 swap + (&SWAP_EXACT_IN_V2_IX_DISCM, data) => { + sol_log("SwapExactInV2"); + let args = parse_swap_ix_args(ix_data_as_arr(data)?); + let accs = swap_v2_split_accs(abr, accounts, &args)?; + let clock = Clock::write_to(&mut clock)?; + verify_swap_v2(abr, &accs, &args, clock)?; + process_swap_exact_in_v2(abr, cpi, &accs, &args, clock) + } + (&SWAP_EXACT_OUT_V2_IX_DISCM, data) => { + sol_log("SwapExactOutV2"); + let args = parse_swap_ix_args(ix_data_as_arr(data)?); + let accs = swap_v2_split_accs(abr, accounts, &args)?; + let clock = Clock::write_to(&mut clock)?; + verify_swap_v2(abr, &accs, &args, clock)?; + process_swap_exact_out_v2(abr, cpi, &accs, &args, clock) + } // admin ixs (&DISABLE_LST_INPUT_IX_DISCM, data) => { sol_log("DisableLstInput"); @@ -211,12 +230,14 @@ fn process_ix( } (&ADD_LST_IX_DISCM, _data) => { sol_log("AddLst"); - process_add_lst(abr, accounts, cpi) + let rent = Rent::write_to(&mut rent)?; + process_add_lst(abr, cpi, accounts, rent) } (&REMOVE_LST_IX_DISCM, data) => { sol_log("RemoveLst"); let lst_idx = RemoveLstIxData::parse_no_discm(ix_data_as_arr(data)?) as usize; - process_remove_lst(abr, cpi, accounts, lst_idx) + let rent = Rent::write_to(&mut rent)?; + process_remove_lst(abr, cpi, accounts, lst_idx, rent) } (&SET_SOL_VALUE_CALC_IX_DISCM, data) => { sol_log("SetSolValueCalculator"); @@ -229,12 +250,12 @@ fn process_ix( (&SET_ADMIN_IX_DISCM, _) => { sol_log("SetAdmin"); let accs = set_admin_accs_checked(abr, accounts)?; - process_set_admin(abr, accs) + process_set_admin(abr, &accs) } (&SET_PRICING_PROG_IX_DISCM, _) => { sol_log("SetPricingProg"); let accs = set_pricing_prog_accs_checked(abr, accounts)?; - process_set_pricing_prog(abr, accs) + process_set_pricing_prog(abr, &accs) } // protocol fees (&SET_PROTOCOL_FEE_IX_DISCM, data) => { @@ -245,23 +266,31 @@ fn process_ix( (&SET_PROTOCOL_FEE_BENEFICIARY_IX_DISCM, _) => { sol_log("SetProtocolFeeBeneficiary"); let accs = set_protocol_fee_beneficiary_accs_checked(abr, accounts)?; - process_set_protocol_fee_beneficiary(abr, accs) + process_set_protocol_fee_beneficiary(abr, &accs) } (&WITHDRAW_PROTOCOL_FEES_IX_DISCM, data) => { sol_log("WithdrawProtocolFees"); let (accs, amt) = withdraw_protocol_fees_checked(abr, accounts, data)?; process_withdraw_protocol_fees(abr, cpi, &accs, amt) } + (&WITHDRAW_PROTOCOL_FEES_V2_IX_DISCM, _) => { + sol_log("WithdrawProtocolFeesV2"); + let accs = withdraw_protocol_fees_v2_checked(abr, accounts)?; + let clock = Clock::write_to(&mut clock)?; + process_withdraw_protocol_fees_v2(abr, cpi, &accs, clock) + } // disable pool system (&ADD_DISABLE_POOL_AUTH_IX_DISCM, _) => { sol_log("AddDisablePoolAuth"); let accs = add_disable_pool_auth_accs_checked(abr, accounts)?; - process_add_disable_pool_auth(abr, cpi, &accs) + let rent = Rent::write_to(&mut rent)?; + process_add_disable_pool_auth(abr, cpi, &accs, rent) } (&REMOVE_DISABLE_POOL_AUTH_IX_DISCM, data) => { sol_log("RemoveDisablePoolAuth"); let (accs, idx) = remove_disable_pool_auth_checked(abr, accounts, data)?; - process_remove_disable_pool_auth(abr, &accs, idx) + let rent = Rent::write_to(&mut rent)?; + process_remove_disable_pool_auth(abr, &accs, idx, rent) } (&DISABLE_POOL_IX_DISCM, _) => { sol_log("DisablePool"); @@ -278,42 +307,21 @@ fn process_ix( sol_log("StartRebalance"); let args = StartRebalanceIxData::parse_no_discm(ix_data_as_arr(data)?); let clock = Clock::write_to(&mut clock)?; - process_start_rebalance(abr, cpi, accounts, args, clock) + process_start_rebalance(abr, cpi, accounts, &args, clock) } (&END_REBALANCE_IX_DISCM, _data) => { sol_log("EndRebalance"); - process_end_rebalance(abr, accounts, cpi) + process_end_rebalance(abr, cpi, accounts) } (&SET_REBAL_AUTH_IX_DISCM, _) => { sol_log("SetRebalAuth"); let accs = set_rebal_auth_accs_checked(abr, accounts)?; - process_set_rebal_auth(abr, accs) - } - // v2 swap - (&SWAP_EXACT_IN_V2_IX_DISCM, data) => { - sol_log("SwapExactInV2"); - let args = parse_swap_ix_args(ix_data_as_arr(data)?); - let accs = swap_v2_split_accs(abr, accounts, &args)?; - let clock = Clock::write_to(&mut clock)?; - verify_swap_v2(abr, &accs, &args, clock)?; - process_swap_exact_in_v2(abr, cpi, &accs, &args, clock) - } - (&SWAP_EXACT_OUT_V2_IX_DISCM, data) => { - sol_log("SwapExactOutV2"); - let args = parse_swap_ix_args(ix_data_as_arr(data)?); - let accs = swap_v2_split_accs(abr, accounts, &args)?; - let clock = Clock::write_to(&mut clock)?; - verify_swap_v2(abr, &accs, &args, clock)?; - process_swap_exact_out_v2(abr, cpi, &accs, &args, clock) - } - // v2 withdraw protocol fees - (&WITHDRAW_PROTOCOL_FEES_V2_IX_DISCM, _) => { - sol_log("WithdrawProtocolFeesV2"); - let accs = withdraw_protocol_fees_v2_checked(abr, accounts)?; - let clock = Clock::write_to(&mut clock)?; - process_withdraw_protocol_fees_v2(abr, cpi, &accs, clock) + process_set_rebal_auth(abr, &accs) } - // v2 RPS + + // discm=22 old Initialize instruction, now unused + + // RPS (&SET_RPS_IX_DISCM, data) => { sol_log("SetRps"); let (accs, rps) = set_rps_checked(abr, accounts, data)?; @@ -323,7 +331,7 @@ fn process_ix( (&SET_RPS_AUTH_IX_DISCM, _) => { sol_log("SetRpsAuth"); let accs = set_rps_auth_accs_checked(abr, accounts)?; - process_set_rps_auth(abr, accs) + process_set_rps_auth(abr, &accs) } _ => Err(INVALID_INSTRUCTION_DATA.into()), } diff --git a/controller/program/src/token.rs b/controller/program/src/token.rs index 15eab7b8..eecfddcb 100644 --- a/controller/program/src/token.rs +++ b/controller/program/src/token.rs @@ -15,9 +15,15 @@ pub fn get_token_account_amount(acc: &Account) -> Result { .ok_or(INVALID_ACCOUNT_DATA)?) } +/// `_checked` because it also verifies that the acc is properly initialized. +/// +/// Compatible with token-22 #[inline] pub fn checked_mint_of(acc: &Account) -> Result, ProgramError> { - Ok(RawMint::of_acc_data(acc.data()) + Ok(acc + .data() + .first_chunk() // ignore token-22 extension data + .map(RawMint::of_acc_data_arr) .and_then(Mint::try_from_raw) .ok_or(INVALID_ACCOUNT_DATA)?) } diff --git a/controller/program/src/verify.rs b/controller/program/src/verify.rs index cec68f8c..12993038 100644 --- a/controller/program/src/verify.rs +++ b/controller/program/src/verify.rs @@ -7,12 +7,10 @@ use inf1_ctl_jiminy::{ }; use jiminy_cpi::{ account::{Abr, Account, AccountHandle}, - program_error::{ - ProgramError, ILLEGAL_OWNER, INVALID_ACCOUNT_DATA, INVALID_ARGUMENT, - MISSING_REQUIRED_SIGNATURE, - }, + program_error::{ProgramError, ILLEGAL_OWNER, INVALID_ARGUMENT, MISSING_REQUIRED_SIGNATURE}, }; -use sanctum_spl_token_jiminy::sanctum_spl_token_core::state::mint::{Mint, RawMint}; + +use crate::token::checked_mint_of; #[inline] pub fn verify_pks<'acc, const LEN: usize>( @@ -160,7 +158,7 @@ fn log_and_return_acc_privilege_err(abr: &Abr, expected_signer: AccountHandle) - } #[inline] -pub fn verify_is_program( +fn verify_is_program( should_be_program: &Account, faulty_err: Inf1CtlErr, ) -> Result<(), ProgramError> { @@ -188,12 +186,8 @@ pub fn verify_tokenkeg_or_22_mint(mint: &Account) -> Result<(), ProgramError> { if *mint.owner() != TOKENKEG_ID && *mint.owner() != TOKEN_2022_ID { return Err(ILLEGAL_OWNER.into()); } - // Verify mint is initialized - RawMint::of_acc_data(mint.data()) - .and_then(Mint::try_from_raw) - .ok_or(INVALID_ACCOUNT_DATA)?; - + checked_mint_of(mint)?; Ok(()) } @@ -229,3 +223,16 @@ pub fn verify_disable_pool_auth_list_no_dup( Inf1CtlErr::DuplicateDisablePoolAuthority, ) } + +#[inline] +pub fn verify_lst_state_list_no_dup( + list: &[LstState], + mint: &[u8; 32], +) -> Result<(), ProgramError> { + verify_list_no_dup_by_key( + list, + mint, + |LstState { mint, .. }| mint, + Inf1CtlErr::DuplicateLst, + ) +}