Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions controller/core/src/instructions/protocol_fee/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
pub mod set_protocol_fee;
pub mod set_protocol_fee_beneficiary;
pub mod withdraw_protocol_fees;
pub mod v1;
pub mod v2;
3 changes: 3 additions & 0 deletions controller/core/src/instructions/protocol_fee/v1/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub mod set_protocol_fee;
pub mod set_protocol_fee_beneficiary;
pub mod withdraw_protocol_fees;
1 change: 1 addition & 0 deletions controller/core/src/instructions/protocol_fee/v2/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod withdraw_protocol_fees;
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
use generic_array_struct::generic_array_struct;

use crate::instructions::generic::DiscmOnlyIxData;

// Accounts

#[generic_array_struct(builder pub)]
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
#[repr(transparent)]
pub struct WithdrawProtocolFeesV2IxAccs<T> {
/// The pool's state singleton PDA
pub pool_state: T,

/// The pool's protocol fee beneficiary
pub beneficiary: T,

/// INF token account to withdraw unclaimed protocol fees to
pub withdraw_to: T,

/// INF token mint
pub inf_mint: T,

/// INF token program
pub token_program: T,
}

impl<T: Copy> WithdrawProtocolFeesV2IxAccs<T> {
#[inline]
pub const fn memset(val: T) -> Self {
Self([val; WITHDRAW_PROTOCOL_FEES_V2_IX_ACCS_LEN])
}
}

pub type WithdrawProtocolFeesV2IxKeys<'a> = WithdrawProtocolFeesV2IxAccs<&'a [u8; 32]>;

pub type WithdrawProtocolFeesV2IxKeysOwned = WithdrawProtocolFeesV2IxAccs<[u8; 32]>;

pub type WithdrawProtocolFeesV2IxAccFlags = WithdrawProtocolFeesV2IxAccs<bool>;

pub const WITHDRAW_PROTOCOL_FEES_V2_IX_IS_WRITER: WithdrawProtocolFeesV2IxAccFlags =
WithdrawProtocolFeesV2IxAccFlags::memset(false)
.const_with_pool_state(true)
.const_with_withdraw_to(true)
.const_with_inf_mint(true);

pub const WITHDRAW_PROTOCOL_FEES_V2_IX_IS_SIGNER: WithdrawProtocolFeesV2IxAccFlags =
WithdrawProtocolFeesV2IxAccFlags::memset(false).const_with_beneficiary(true);

// Data

pub const WITHDRAW_PROTOCOL_FEES_V2_IX_DISCM: u8 = 25;

pub type WithdrawProtocolFeesV2IxData = DiscmOnlyIxData<WITHDRAW_PROTOCOL_FEES_V2_IX_DISCM>;

pub const WITHDRAW_PROTOCOL_FEES_V2_IX_DATA_LEN: usize = WithdrawProtocolFeesV2IxData::DATA_LEN;
6 changes: 6 additions & 0 deletions controller/core/src/keys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ id_str!(
"Sysvar1nstructions1111111111111111111111111"
);

id_str!(
INF_MINT_ID_STR,
INF_MINT_ID,
"5oVNBeEEQvYi1cX3ir8Dx5n1P7pdxydbGF2X4TxVusJm"
);

macro_rules! const_pda {
($INTER:ident, $ID_STR:ident, $ID:ident, $BUMP:ident, $const_find:expr) => {
const $INTER: ([u8; 32], u8) = $const_find(&crate::ID);
Expand Down
5 changes: 2 additions & 3 deletions controller/program/src/instructions/protocol_fee/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
pub mod set_protocol_fee;
pub mod set_protocol_fee_beneficiary;
pub mod withdraw_protocol_fee;
pub mod v1;
pub mod v2;
3 changes: 3 additions & 0 deletions controller/program/src/instructions/protocol_fee/v1/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub mod set_protocol_fee;
pub mod set_protocol_fee_beneficiary;
pub mod withdraw_protocol_fees;
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use inf1_ctl_jiminy::{
account_utils::{pool_state_checked, pool_state_checked_mut},
accounts::pool_state::PoolState,
instructions::protocol_fee::set_protocol_fee::{
instructions::protocol_fee::v1::set_protocol_fee::{
NewSetProtocolFeeIxAccsBuilder, SetProtocolFeeIxAccs, SetProtocolFeeIxArgs,
SetProtocolFeeIxData, SET_PROTOCOL_FEE_IX_IS_SIGNER,
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use inf1_ctl_jiminy::{
account_utils::{pool_state_v2_checked, pool_state_v2_checked_mut},
accounts::pool_state::PoolStateV2,
instructions::protocol_fee::set_protocol_fee_beneficiary::{
instructions::protocol_fee::v1::set_protocol_fee_beneficiary::{
NewSetProtocolFeeBeneficiaryIxAccsBuilder, SetProtocolFeeBeneficiaryIxAccs,
SET_PROTOCOL_FEE_BENEFICIARY_IX_IS_SIGNER,
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use inf1_ctl_jiminy::{
account_utils::pool_state_v2_checked,
err::Inf1CtlErr,
instructions::protocol_fee::withdraw_protocol_fees::{
instructions::protocol_fee::v1::withdraw_protocol_fees::{
NewWithdrawProtocolFeesIxAccsBuilder, WithdrawProtocolFeesIxAccs,
WithdrawProtocolFeesIxData, WITHDRAW_PROTOCOL_FEES_IX_IS_SIGNER,
},
Expand Down
1 change: 1 addition & 0 deletions controller/program/src/instructions/protocol_fee/v2/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod withdraw_protocol_fees;
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
use inf1_ctl_jiminy::{
account_utils::{pool_state_v2_checked, pool_state_v2_checked_mut},
err::Inf1CtlErr,
instructions::protocol_fee::v2::withdraw_protocol_fees::{
NewWithdrawProtocolFeesV2IxAccsBuilder, WithdrawProtocolFeesV2IxAccs,
WITHDRAW_PROTOCOL_FEES_V2_IX_IS_SIGNER,
},
keys::POOL_STATE_ID,
pda_onchain::POOL_STATE_SIGNER,
program_err::Inf1CtlCustomProgErr,
svc::InfCalc,
typedefs::pool_sv::PoolSvLamports,
};
use jiminy_cpi::{
account::{Abr, AccountHandle},
program_error::{ProgramError, INVALID_ACCOUNT_DATA, NOT_ENOUGH_ACCOUNT_KEYS},
Cpi,
};
use jiminy_sysvar_clock::Clock;
use sanctum_spl_token_jiminy::{
instructions::mint_to::mint_to_ix_account_handle_perms,
sanctum_spl_token_core::{
instructions::mint_to::{MintToIxData, NewMintToIxAccsBuilder},
state::mint::{Mint, RawMint},
},
};

use crate::verify::{
verify_not_rebalancing_and_not_disabled_v2, verify_pks, verify_signers,
verify_tokenkeg_or_22_mint,
};

type WithdrawProtocolFeesV2IxAccounts<'acc> = WithdrawProtocolFeesV2IxAccs<AccountHandle<'acc>>;

#[inline]
pub fn withdraw_protocol_fees_v2_checked<'acc>(
abr: &Abr,
accs: &[AccountHandle<'acc>],
) -> Result<WithdrawProtocolFeesV2IxAccounts<'acc>, ProgramError> {
let accs = accs.first_chunk().ok_or(NOT_ENOUGH_ACCOUNT_KEYS)?;
let accs = WithdrawProtocolFeesV2IxAccs(*accs);

let pool = pool_state_v2_checked(abr.get(*accs.pool_state()))?;
let mint_acc = abr.get(*accs.inf_mint());

let expected_pks = NewWithdrawProtocolFeesV2IxAccsBuilder::start()
.with_pool_state(&POOL_STATE_ID)
.with_beneficiary(&pool.protocol_fee_beneficiary)
.with_inf_mint(&pool.lp_token_mint)
.with_token_program(mint_acc.owner())
// Free: the beneficiary is free to specify whatever INF token account to withdraw to
// In the case of an invalid INF token acc, token prog mint_to CPI will fail
.with_withdraw_to(abr.get(*accs.withdraw_to()).key())
.build();
verify_pks(abr, &accs.0, &expected_pks.0)?;

verify_signers(abr, &accs.0, &WITHDRAW_PROTOCOL_FEES_V2_IX_IS_SIGNER.0)?;

verify_not_rebalancing_and_not_disabled_v2(pool)?;

verify_tokenkeg_or_22_mint(mint_acc)?;

Ok(accs)
}

#[inline]
pub fn process_withdraw_protocol_fees_v2(
abr: &mut Abr,
cpi: &mut Cpi,
accs: WithdrawProtocolFeesV2IxAccounts,
clock: &Clock,
) -> Result<(), ProgramError> {
let pool = pool_state_v2_checked_mut(abr.get_mut(*accs.pool_state()))?;
pool.release_yield(clock.slot)
.map_err(Inf1CtlCustomProgErr)?;

let protocol_fee_lamports = pool.protocol_fee_lamports;

if protocol_fee_lamports == 0 {
return Ok(());
}

let pool_lamports = PoolSvLamports::from_pool_state_v2(pool);
let inf_mint_data = abr.get(*accs.inf_mint()).data();
let inf_token_supply = RawMint::of_acc_data(inf_mint_data)
.and_then(Mint::try_from_raw)
.map(|a| a.supply())
.ok_or(INVALID_ACCOUNT_DATA)?;

let inf_calc = InfCalc {
pool_lamports,
mint_supply: inf_token_supply,
};

let inf_to_mint = inf_calc
.sol_to_inf(protocol_fee_lamports)
.ok_or(Inf1CtlCustomProgErr(Inf1CtlErr::MathError))?;

if inf_to_mint == 0 {
return Ok(());
}

cpi.invoke_signed_handle(
abr,
*accs.token_program(),
MintToIxData::new(inf_to_mint).as_buf(),
mint_to_ix_account_handle_perms(
NewMintToIxAccsBuilder::start()
.with_auth(*accs.pool_state())
.with_mint(*accs.inf_mint())
.with_to(*accs.withdraw_to())
.build(),
),
&[POOL_STATE_SIGNER],
)?;

let pool = pool_state_v2_checked_mut(abr.get_mut(*accs.pool_state()))?;
pool.protocol_fee_lamports = 0;

Ok(())
}
31 changes: 23 additions & 8 deletions controller/program/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,12 @@ use inf1_ctl_jiminy::instructions::{
remove::{RemoveLiquidityIxData, REMOVE_LIQUIDITY_IX_DISCM},
},
protocol_fee::{
set_protocol_fee::SET_PROTOCOL_FEE_IX_DISCM,
set_protocol_fee_beneficiary::SET_PROTOCOL_FEE_BENEFICIARY_IX_DISCM,
withdraw_protocol_fees::WITHDRAW_PROTOCOL_FEES_IX_DISCM,
v1::{
set_protocol_fee::SET_PROTOCOL_FEE_IX_DISCM,
set_protocol_fee_beneficiary::SET_PROTOCOL_FEE_BENEFICIARY_IX_DISCM,
withdraw_protocol_fees::WITHDRAW_PROTOCOL_FEES_IX_DISCM,
},
v2::withdraw_protocol_fees::WITHDRAW_PROTOCOL_FEES_V2_IX_DISCM,
},
rebalance::{
end::END_REBALANCE_IX_DISCM,
Expand Down Expand Up @@ -76,12 +79,17 @@ use crate::{
},
},
protocol_fee::{
set_protocol_fee::{process_set_protocol_fee, set_protocol_fee_checked},
set_protocol_fee_beneficiary::{
process_set_protocol_fee_beneficiary, set_protocol_fee_beneficiary_accs_checked,
v1::{
set_protocol_fee::{process_set_protocol_fee, set_protocol_fee_checked},
set_protocol_fee_beneficiary::{
process_set_protocol_fee_beneficiary, set_protocol_fee_beneficiary_accs_checked,
},
withdraw_protocol_fees::{
process_withdraw_protocol_fees, withdraw_protocol_fees_checked,
},
},
withdraw_protocol_fee::{
process_withdraw_protocol_fees, withdraw_protocol_fees_checked,
v2::withdraw_protocol_fees::{
process_withdraw_protocol_fees_v2, withdraw_protocol_fees_v2_checked,
},
},
rebalance::{
Expand Down Expand Up @@ -265,6 +273,13 @@ fn process_ix(
let accs = set_rebal_auth_accs_checked(abr, accounts)?;
process_set_rebal_auth(abr, accs)
}
// 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)
}
// v2 swap
(&SWAP_EXACT_OUT_V2_IX_DISCM, data) => {
sol_log("SwapExactOutV2");
Expand Down
5 changes: 2 additions & 3 deletions controller/program/tests/tests/protocol_fee/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
mod set_protocol_fee;
mod set_protocol_fee_beneficiary;
mod withdraw_protocol_fees;
pub mod v1;
pub mod v2;
3 changes: 3 additions & 0 deletions controller/program/tests/tests/protocol_fee/v1/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
mod set_protocol_fee;
mod set_protocol_fee_beneficiary;
mod withdraw_protocol_fees;
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use inf1_core::typedefs::fee_bps::BPS_DENOM;
use inf1_ctl_jiminy::{
accounts::pool_state::{PoolState, PoolStatePacked},
err::Inf1CtlErr,
instructions::protocol_fee::set_protocol_fee::{
instructions::protocol_fee::v1::set_protocol_fee::{
NewSetProtocolFeeIxAccsBuilder, SetProtocolFeeIxArgs, SetProtocolFeeIxData,
SetProtocolFeeIxKeysOwned, SET_PROTOCOL_FEE_IX_ACCS_IDX_ADMIN,
SET_PROTOCOL_FEE_IX_IS_SIGNER, SET_PROTOCOL_FEE_IX_IS_WRITER,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use inf1_ctl_jiminy::{
accounts::pool_state::{PoolStateV2, PoolStateV2Addrs, PoolStateV2FtaVals, PoolStateV2Packed},
instructions::protocol_fee::set_protocol_fee_beneficiary::{
instructions::protocol_fee::v1::set_protocol_fee_beneficiary::{
NewSetProtocolFeeBeneficiaryIxAccsBuilder, SetProtocolFeeBeneficiaryIxData,
SetProtocolFeeBeneficiaryIxKeysOwned, SET_PROTOCOL_FEE_BENEFICIARY_IX_ACCS_IDX_CURR,
SET_PROTOCOL_FEE_BENEFICIARY_IX_ACCS_IDX_NEW, SET_PROTOCOL_FEE_BENEFICIARY_IX_IS_SIGNER,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use generic_array_struct::generic_array_struct;
use inf1_ctl_jiminy::{
accounts::pool_state::{PoolStateV2, PoolStateV2Addrs, PoolStateV2FtaVals},
err::Inf1CtlErr,
instructions::protocol_fee::withdraw_protocol_fees::{
instructions::protocol_fee::v1::withdraw_protocol_fees::{
NewWithdrawProtocolFeesIxAccsBuilder, WithdrawProtocolFeesIxAccsBuilder,
WithdrawProtocolFeesIxData, WithdrawProtocolFeesIxKeysOwned,
WITHDRAW_PROTOCOL_FEES_IX_ACCS_IDX_BENEFICIARY,
Expand Down
1 change: 1 addition & 0 deletions controller/program/tests/tests/protocol_fee/v2/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
mod withdraw_protocol_fees;
Loading