Skip to content

Commit 83e22ec

Browse files
authored
big cargo test (#1644)
1 parent 1f70026 commit 83e22ec

File tree

7 files changed

+275
-149
lines changed

7 files changed

+275
-149
lines changed

programs/drift/src/instructions/lp_pool.rs

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ use crate::state::lp_pool::{
4545

4646
pub fn handle_update_constituent_target_base<'c: 'info, 'info>(
4747
ctx: Context<'_, '_, 'c, 'info, UpdateConstituentTargetBase<'info>>,
48-
constituent_indexes: Vec<u16>,
4948
) -> Result<()> {
5049
let lp_pool = &ctx.accounts.lp_pool.load()?;
5150
let lp_pool_key: &Pubkey = &ctx.accounts.lp_pool.key();
@@ -99,16 +98,6 @@ pub fn handle_update_constituent_target_base<'c: 'info, 'info>(
9998
msg!("weight datum: {:?}", datum);
10099
}
101100

102-
let exists_invalid_constituent_index = constituent_indexes
103-
.iter()
104-
.any(|index| *index as u32 >= num_constituents);
105-
106-
validate!(
107-
!exists_invalid_constituent_index,
108-
ErrorCode::InvalidUpdateConstituentTargetBaseArgument,
109-
"Constituent index larger than number of constituent target weights"
110-
)?;
111-
112101
let slot = Clock::get()?.slot;
113102

114103
let amm_constituent_mapping: AccountZeroCopy<
@@ -133,8 +122,7 @@ pub fn handle_update_constituent_target_base<'c: 'info, 'info>(
133122
"Amm mapping PDA does not match expected PDA"
134123
)?;
135124

136-
let mut amm_inventories: Vec<(u16, i64)> = vec![];
137-
let mut oracle_prices: Vec<i64> = vec![];
125+
let mut amm_inventories: Vec<(u16, i64, i64)> = vec![];
138126
for (_, datum) in amm_constituent_mapping.iter().enumerate() {
139127
let cache_info = amm_cache.get(datum.perp_market_index as u32);
140128

@@ -163,19 +151,42 @@ pub fn handle_update_constituent_target_base<'c: 'info, 'info>(
163151
continue;
164152
}
165153

166-
amm_inventories.push((datum.perp_market_index, cache_info.position));
167-
oracle_prices.push(cache_info.oracle_price);
154+
amm_inventories.push((
155+
datum.perp_market_index,
156+
cache_info.position,
157+
cache_info.oracle_price,
158+
));
168159
}
169160

170161
if amm_inventories.is_empty() {
171162
msg!("No valid inventories found for constituent target weights update");
172163
return Ok(());
173164
}
174165

166+
let remaining_accounts = &mut ctx.remaining_accounts.iter().peekable();
167+
let constituent_map =
168+
ConstituentMap::load(&ConstituentSet::new(), &lp_pool_key, remaining_accounts)?;
169+
170+
let mut constituent_indexes_and_prices: Vec<(u16, i64)> = vec![];
171+
for (index, loader) in &constituent_map.0 {
172+
let constituent_ref = loader.load()?;
173+
constituent_indexes_and_prices.push((*index, constituent_ref.last_oracle_price));
174+
}
175+
176+
let exists_invalid_constituent_index = constituent_indexes_and_prices
177+
.iter()
178+
.any(|(index, _)| *index as u32 >= num_constituents);
179+
180+
validate!(
181+
!exists_invalid_constituent_index,
182+
ErrorCode::InvalidUpdateConstituentTargetBaseArgument,
183+
"Constituent index larger than number of constituent target weights"
184+
)?;
185+
175186
constituent_target_base.update_target_base(
176187
&amm_constituent_mapping,
177188
amm_inventories.as_slice(),
178-
constituent_indexes.as_slice(),
189+
constituent_indexes_and_prices.as_slice(),
179190
slot,
180191
)?;
181192

programs/drift/src/lib.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1792,9 +1792,8 @@ pub mod drift {
17921792

17931793
pub fn update_lp_constituent_target_base<'c: 'info, 'info>(
17941794
ctx: Context<'_, '_, 'c, 'info, UpdateConstituentTargetBase<'info>>,
1795-
constituent_indexes: Vec<u16>,
17961795
) -> Result<()> {
1797-
handle_update_constituent_target_base(ctx, constituent_indexes)
1796+
handle_update_constituent_target_base(ctx)
17981797
}
17991798

18001799
pub fn update_lp_pool_aum<'c: 'info, 'info>(

programs/drift/src/state/lp_pool.rs

Lines changed: 63 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
use crate::error::{DriftResult, ErrorCode};
22
use crate::math::casting::Cast;
33
use crate::math::constants::{
4-
BASE_PRECISION_I64, PERCENTAGE_PRECISION_I128, PERCENTAGE_PRECISION_I64, QUOTE_PRECISION,
4+
BASE_PRECISION_I128, BASE_PRECISION_I64, PERCENTAGE_PRECISION_I128, PERCENTAGE_PRECISION_I64,
5+
QUOTE_PRECISION,
56
};
67
use crate::math::safe_math::SafeMath;
78
use crate::math::spot_balance::get_token_amount;
@@ -565,7 +566,7 @@ impl Constituent {
565566
// }
566567

567568
#[zero_copy]
568-
#[derive(Debug, Default, BorshDeserialize, BorshSerialize)]
569+
#[derive(Debug, BorshDeserialize, BorshSerialize)]
569570
#[repr(C)]
570571
pub struct AmmConstituentDatum {
571572
pub perp_market_index: u16,
@@ -576,6 +577,18 @@ pub struct AmmConstituentDatum {
576577
pub weight: i64,
577578
}
578579

580+
impl Default for AmmConstituentDatum {
581+
fn default() -> Self {
582+
AmmConstituentDatum {
583+
perp_market_index: u16::MAX,
584+
constituent_index: u16::MAX,
585+
_padding: [0; 4],
586+
last_slot: 0,
587+
weight: 0,
588+
}
589+
}
590+
}
591+
579592
#[zero_copy]
580593
#[derive(Debug, Default)]
581594
#[repr(C)]
@@ -745,13 +758,15 @@ pub fn calculate_target_weight(
745758
lp_pool_aum: u128,
746759
validation_flags: WeightValidationFlags,
747760
) -> DriftResult<i64> {
748-
let notional = target_base.safe_mul(price)?.safe_div(BASE_PRECISION_I64)?;
761+
let notional: i128 = (target_base as i128)
762+
.safe_mul(price as i128)?
763+
.safe_div(BASE_PRECISION_I128)?;
749764

750765
let target_weight = notional
751-
.cast::<i128>()?
752766
.safe_mul(PERCENTAGE_PRECISION_I128)?
753767
.safe_div(lp_pool_aum.cast::<i128>()?)?
754-
.cast::<i64>()?;
768+
.cast::<i64>()?
769+
.clamp(-1 * PERCENTAGE_PRECISION_I64, PERCENTAGE_PRECISION_I64);
755770

756771
// if (validation_flags as u8 & (WeightValidationFlags::NoNegativeWeights as u8) != 0)
757772
// && target_weight < 0
@@ -781,37 +796,57 @@ impl<'a> AccountZeroCopyMut<'a, TargetsDatum, ConstituentTargetBaseFixed> {
781796
&mut self,
782797
mapping: &AccountZeroCopy<'a, AmmConstituentDatum, AmmConstituentMappingFixed>,
783798
// (perp market index, inventory, price)
784-
amm_inventory: &[(u16, i64)],
785-
constituents_indexes: &[u16],
799+
amm_inventory_and_prices: &[(u16, i64, i64)],
800+
constituents_indexes_and_prices: &[(u16, i64)],
786801
slot: u64,
787802
) -> DriftResult<Vec<i128>> {
788-
let mut results = Vec::with_capacity(constituents_indexes.len());
789-
790-
for (i, constituent_index) in constituents_indexes.iter().enumerate() {
791-
let mut target_amount = 0i128;
792-
793-
for (perp_market_index, inventory) in amm_inventory.iter() {
794-
let idx = mapping
795-
.iter()
796-
.position(|d| &d.perp_market_index == perp_market_index)
797-
.expect("missing mapping for this market index");
798-
let weight = mapping.get(idx as u32).weight; // PERCENTAGE_PRECISION
799-
800-
target_amount += (*inventory as i128)
803+
let mut results = Vec::with_capacity(constituents_indexes_and_prices.len());
804+
for (i, constituent_index_and_price) in constituents_indexes_and_prices.iter().enumerate() {
805+
let mut target_notional = 0i128;
806+
let constituent_index = constituent_index_and_price.0;
807+
let price = constituent_index_and_price.1;
808+
809+
for (perp_market_index, inventory, price) in amm_inventory_and_prices.iter() {
810+
let idx = mapping.iter().position(|d| {
811+
&d.perp_market_index == perp_market_index
812+
&& d.constituent_index == constituent_index
813+
});
814+
if idx.is_none() {
815+
msg!(
816+
"No mapping found for perp market index {} and constituent index {}",
817+
perp_market_index,
818+
constituent_index
819+
);
820+
continue;
821+
}
822+
823+
let weight = mapping.get(idx.unwrap() as u32).weight; // PERCENTAGE_PRECISION
824+
825+
let notional: i128 = (*inventory as i128)
826+
.safe_mul(*price as i128)?
827+
.safe_div(BASE_PRECISION_I128)?;
828+
829+
target_notional += notional
801830
.saturating_mul(weight as i128)
802-
.saturating_div(PERCENTAGE_PRECISION_I64 as i128);
831+
.saturating_div(PERCENTAGE_PRECISION_I128);
803832
}
804833

805834
let cell = self.get_mut(i as u32);
835+
let target_base = target_notional
836+
.safe_mul(BASE_PRECISION_I128)?
837+
.safe_div(price as i128)?
838+
* -1; // Want to target opposite sign of total scaled notional inventory
839+
806840
msg!(
807-
"updating constituent index {} target amount to {}",
841+
"updating constituent index {} target base to {} from target notional {}",
808842
constituent_index,
809-
target_amount
843+
target_base,
844+
target_notional,
810845
);
811-
cell.target_base = target_amount as i64;
846+
cell.target_base = target_base.cast::<i64>()?;
812847
cell.last_slot = slot;
813848

814-
results.push(target_amount);
849+
results.push(target_base);
815850
}
816851

817852
Ok(results)
@@ -825,7 +860,9 @@ impl<'a> AccountZeroCopyMut<'a, AmmConstituentDatum, AmmConstituentMappingFixed>
825860
let mut open_slot_index: Option<u32> = None;
826861
for i in 0..len {
827862
let cell = self.get(i as u32);
828-
if cell.constituent_index == datum.constituent_index {
863+
if cell.constituent_index == datum.constituent_index
864+
&& cell.perp_market_index == datum.perp_market_index
865+
{
829866
return Err(ErrorCode::DefaultError);
830867
}
831868
if cell.last_slot == 0 && open_slot_index.is_none() {

0 commit comments

Comments
 (0)