Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions .github/workflows/rust.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ on:
push:
branches:
- master
- v2
workflow_dispatch:

env:
Expand Down
14 changes: 7 additions & 7 deletions controller/core/src/yields/update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ impl UpdateYield {
let [withheld, protocol_fee] = if self.new_total_sol_value >= *self.old.total() {
// unchecked-arith: bounds checked above
let gains = self.new_total_sol_value - *self.old.total();
[
// saturation: can overflow if new_total_sol_value is large
// and norm_old_total_sol_value < old.withheld. In this case,
// rely on clamping below to ensure LP solvency invariant
self.old.withheld().saturating_add(gains),
*self.old.protocol_fee(),
]
// since old.withheld <= old.total,
// should never overflow
let new_withheld = match self.old.withheld().checked_add(gains) {
None => return None,
Some(x) => x,
};
[new_withheld, *self.old.protocol_fee()]
} else {
// unchecked-arith: bounds checked above
let losses = *self.old.total() - self.new_total_sol_value;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ pub fn withdraw_protocol_fees_checked<'acc>(
.with_beneficiary(&pool.protocol_fee_beneficiary)
.with_token_program(token_prog)
.with_protocol_fee_accumulator(&expected_protocol_fee_accumulator)
// Free: the beneficiary is entitled to all balances of all ATAs of the protocol fee PDA
// Free: the beneficiary is entitled to all balances of all ATAs of the protocol fee PDA,
// including tokens that are not part of the pool
// owner = token-22 or tokenkeg checked below
.with_lst_mint(mint_acc.key())
// Free: the beneficiary is free to specify whatever token account to withdraw to
Expand Down
14 changes: 7 additions & 7 deletions controller/program/src/instructions/swap/v2/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -458,14 +458,13 @@ pub fn final_sync(
let [inp, out] = [inp, out].map(|(accs, lst_idx)| {
let lst_new = cpi_lst_reserves_sol_val(abr, cpi, &accs)?;
update_lst_state_sol_val(abr, *accs.ix_prefix.lst_state_list(), lst_idx, lst_new)
.map(|lst_sol_val| SyncSolVal { lst_sol_val })
});
let inp_snap = inp?;
let out_snap = out?;
let inp_sync = inp?;
let out_sync = out?;

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

let [out_sync, inp_sync] =
[out_snap, inp_snap].map(|lst_sol_val| SyncSolVal { lst_sol_val });
// exec on out first to reduce odds of overflow
// since out will be a decrease
let new_total_sol_value = out_sync
Expand All @@ -491,12 +490,13 @@ pub fn final_sync(
};

let lst_new = cpi_lst_reserves_sol_val(abr, cpi, &lst_accs)?;
let lst_sol_val =
update_lst_state_sol_val(abr, *accs.ix_prefix.lst_state_list(), lst_idx, lst_new)?;
let lst_sync =
update_lst_state_sol_val(abr, *accs.ix_prefix.lst_state_list(), lst_idx, lst_new)
.map(|lst_sol_val| SyncSolVal { lst_sol_val })?;

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

let new_total_sol_value = SyncSolVal { lst_sol_val }
let new_total_sol_value = lst_sync
.exec(pool.total_sol_value)
.ok_or(Inf1CtlCustomProgErr(Inf1CtlErr::MathError))?;

Expand Down
1 change: 1 addition & 0 deletions controller/program/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ fn process_ix(
process_sync_sol_value(abr, cpi, accounts, lst_idx, clock)
}
// core user-facing ixs
// v1 swap + liquidity
(&SWAP_EXACT_IN_IX_DISCM, data) => {
sol_log("SwapExactIn");
let args = parse_swap_ix_args(ix_data_as_arr(data)?);
Expand Down
56 changes: 28 additions & 28 deletions controller/program/tests/tests/admin/set_sol_value_calculator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use inf1_ctl_jiminy::{
},
keys::{LST_STATE_LIST_ID, POOL_STATE_ID},
program_err::Inf1CtlCustomProgErr,
typedefs::u8bool::U8BoolMut,
ID,
};

Expand All @@ -28,10 +29,11 @@ use inf1_core::instructions::admin::set_sol_value_calculator::{

use inf1_test_utils::{
acc_bef_aft, any_lst_state, any_lst_state_list, any_normal_pk, any_pool_state_v2,
any_spl_stake_pool, any_wsol_lst_state, assert_diffs_lst_state_list,
assert_diffs_pool_state_v2, assert_jiminy_prog_err, find_pool_reserves_ata,
fixtures_accounts_opt_cloned, keys_signer_writable_to_metas, lst_state_list_account, mock_mint,
mock_spl_stake_pool, mock_token_acc, mollusk_exec, pool_state_v2_account,
any_pool_sv_lamports_solvent_strat, any_spl_stake_pool, any_wsol_lst_state,
assert_diffs_lst_state_list, assert_diffs_pool_state_v2, assert_jiminy_prog_err,
find_pool_reserves_ata, fixtures_accounts_opt_cloned, keys_signer_writable_to_metas,
lst_state_list_account, mock_mint, mock_spl_stake_pool, mock_token_acc, mollusk_exec,
pool_state_v2_account, pool_state_v2_u64s_just_lamports_strat,
pool_state_v2_u8_bools_normal_strat, raw_mint, raw_token_acc, silence_mollusk_logs, AccountMap,
AnyLstStateArgs, Diff, DiffLstStateArgs, DiffsPoolStateV2, GenStakePoolArgs, LstStateData,
LstStateListChanges, LstStateListData, LstStatePks, NewLstStatePksBuilder,
Expand Down Expand Up @@ -233,15 +235,25 @@ fn set_sol_value_calculator_proptest(
Ok(())
}

fn any_normal_pool_state_v2_strat() -> impl Strategy<Value = PoolStateV2> {
any_pool_sv_lamports_solvent_strat().prop_flat_map(|ps| {
any_pool_state_v2(PoolStateV2FtaStrat {
u8_bools: pool_state_v2_u8_bools_normal_strat(),
u64s: pool_state_v2_u64s_just_lamports_strat(ps)
// TODO: run on mutable svm with configurable clock to
// test nonzero release case too
.with_last_release_slot(Some(Just(0).boxed())),
..Default::default()
})
})
}

proptest! {
#[test]
fn set_sol_value_calculator_unauthorized_any(
(pool, lsd, stake_pool_addr, stake_pool, non_admin, initial_svc_addr, new_balance) in
(
any_pool_state_v2(PoolStateV2FtaStrat {
u8_bools: pool_state_v2_u8_bools_normal_strat(),
..Default::default()
}),
any_normal_pool_state_v2_strat(),
any_normal_pk(),
any::<u64>(),
).prop_flat_map(
Expand Down Expand Up @@ -295,9 +307,9 @@ proptest! {
fn set_sol_value_calculator_rebalancing_any(
(pool, lsd, stake_pool_addr, stake_pool, initial_svc_addr, new_balance) in
(
any_pool_state_v2(PoolStateV2FtaStrat {
u8_bools: pool_state_v2_u8_bools_normal_strat().with_is_rebalancing(Some(Just(true).boxed())),
..Default::default()
any_normal_pool_state_v2_strat().prop_map(|mut ps| {
U8BoolMut(&mut ps.is_rebalancing).set_true();
ps
}),
any_normal_pk(),
any::<u64>(),
Expand Down Expand Up @@ -354,9 +366,9 @@ proptest! {
fn set_sol_value_calculator_disabled_any(
(pool, lsd, stake_pool_addr, stake_pool, initial_svc_addr, new_balance) in
(
any_pool_state_v2(PoolStateV2FtaStrat {
u8_bools: pool_state_v2_u8_bools_normal_strat().with_is_disabled(Some(Just(true).boxed())),
..Default::default()
any_normal_pool_state_v2_strat().prop_map(|mut ps| {
U8BoolMut(&mut ps.is_disabled).set_true();
ps
}),
any_normal_pk(),
any::<u64>(),
Expand Down Expand Up @@ -419,13 +431,7 @@ proptest! {
#[test]
fn set_sol_value_calculator_wsol_any(
(pool, wsol_lsd, initial_svc_addr, new_balance) in
any_pool_state_v2(PoolStateV2FtaStrat {
u8_bools: pool_state_v2_u8_bools_normal_strat(),
// TODO: run on mutable svm with configurable clock to
// test nonzero release case too
u64s: PoolStateV2U64s::default().with_last_release_slot(Some(Just(0).boxed())),
..Default::default()
}).prop_flat_map(
any_normal_pool_state_v2_strat().prop_flat_map(
|pool| (
Just(pool),
any_wsol_lst_state(AnyLstStateArgs {
Expand Down Expand Up @@ -464,13 +470,7 @@ proptest! {
fn set_sol_value_calculator_sanctum_spl_multi_any(
(pool, lsd, stake_pool_addr, stake_pool, initial_svc_addr, new_balance) in
(
any_pool_state_v2(PoolStateV2FtaStrat {
u8_bools: pool_state_v2_u8_bools_normal_strat(),
// TODO: run on mutable svm with configurable clock to
// test nonzero release case too
u64s: PoolStateV2U64s::default().with_last_release_slot(Some(Just(0).boxed())),
..Default::default()
}),
any_normal_pool_state_v2_strat(),
any_normal_pk(),
any::<u64>(),
).prop_flat_map(
Expand Down
Loading