Skip to content

Commit cf07e05

Browse files
committed
Merge remote-tracking branch 'origin/master' into wphan/builder_codes
2 parents 76e2f2f + 31c69e0 commit cf07e05

File tree

16 files changed

+582
-77
lines changed

16 files changed

+582
-77
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Features
1111

12+
- program: auction order params account for twap divergence ([#1882](https://github.com/drift-labs/protocol-v2/pull/1882))
13+
- program: add delegate stake if ([#1859](https://github.com/drift-labs/protocol-v2/pull/1859))
14+
1215
### Fixes
1316

1417
### Breaking

programs/drift/src/controller/insurance.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1098,6 +1098,14 @@ pub fn handle_if_end_swap(
10981098
if_rebalance_config.epoch_max_in_amount
10991099
)?;
11001100

1101+
validate!(
1102+
if_rebalance_config.current_in_amount <= if_rebalance_config.total_in_amount,
1103+
ErrorCode::InvalidIfRebalanceSwap,
1104+
"current_in_amount={} > total_in_amount={}",
1105+
if_rebalance_config.current_in_amount,
1106+
if_rebalance_config.total_in_amount
1107+
)?;
1108+
11011109
let oracle_twap = out_spot_market
11021110
.historical_oracle_data
11031111
.last_oracle_price_twap;

programs/drift/src/instructions/admin.rs

Lines changed: 64 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,12 @@ use crate::instructions::optional_accounts::{load_maps, AccountMaps};
1818
use crate::math::casting::Cast;
1919
use crate::math::constants::{
2020
AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO, DEFAULT_LIQUIDATION_MARGIN_BUFFER_RATIO,
21-
FEE_POOL_TO_REVENUE_POOL_THRESHOLD, IF_FACTOR_PRECISION, INSURANCE_A_MAX, INSURANCE_B_MAX,
22-
INSURANCE_C_MAX, INSURANCE_SPECULATIVE_MAX, LIQUIDATION_FEE_PRECISION,
23-
MAX_CONCENTRATION_COEFFICIENT, MAX_SQRT_K, MAX_UPDATE_K_PRICE_CHANGE, PERCENTAGE_PRECISION,
24-
PERCENTAGE_PRECISION_I64, QUOTE_SPOT_MARKET_INDEX, SPOT_CUMULATIVE_INTEREST_PRECISION,
25-
SPOT_IMF_PRECISION, SPOT_WEIGHT_PRECISION, THIRTEEN_DAY, TWENTY_FOUR_HOUR,
21+
FEE_POOL_TO_REVENUE_POOL_THRESHOLD, GOV_SPOT_MARKET_INDEX, IF_FACTOR_PRECISION,
22+
INSURANCE_A_MAX, INSURANCE_B_MAX, INSURANCE_C_MAX, INSURANCE_SPECULATIVE_MAX,
23+
LIQUIDATION_FEE_PRECISION, MAX_CONCENTRATION_COEFFICIENT, MAX_SQRT_K,
24+
MAX_UPDATE_K_PRICE_CHANGE, PERCENTAGE_PRECISION, PERCENTAGE_PRECISION_I64,
25+
QUOTE_SPOT_MARKET_INDEX, SPOT_CUMULATIVE_INTEREST_PRECISION, SPOT_IMF_PRECISION,
26+
SPOT_WEIGHT_PRECISION, THIRTEEN_DAY, TWENTY_FOUR_HOUR,
2627
};
2728
use crate::math::cp_curve::get_update_k_result;
2829
use crate::math::helpers::get_proportion_u128;
@@ -45,6 +46,7 @@ use crate::state::fulfillment_params::serum::SerumContext;
4546
use crate::state::fulfillment_params::serum::SerumV3FulfillmentConfig;
4647
use crate::state::high_leverage_mode_config::HighLeverageModeConfig;
4748
use crate::state::if_rebalance_config::{IfRebalanceConfig, IfRebalanceConfigParams};
49+
use crate::state::insurance_fund_stake::InsuranceFundStake;
4850
use crate::state::insurance_fund_stake::ProtocolIfSharesTransferConfig;
4951
use crate::state::oracle::get_sb_on_demand_price;
5052
use crate::state::oracle::{
@@ -4915,6 +4917,39 @@ pub fn handle_update_feature_bit_flags_median_trigger_price(
49154917
Ok(())
49164918
}
49174919

4920+
pub fn handle_update_delegate_user_gov_token_insurance_stake(
4921+
ctx: Context<UpdateDelegateUserGovTokenInsuranceStake>,
4922+
) -> Result<()> {
4923+
let insurance_fund_stake = &mut load_mut!(ctx.accounts.insurance_fund_stake)?;
4924+
let user_stats = &mut load_mut!(ctx.accounts.user_stats)?;
4925+
let spot_market = &mut load_mut!(ctx.accounts.spot_market)?;
4926+
4927+
validate!(
4928+
insurance_fund_stake.market_index == GOV_SPOT_MARKET_INDEX,
4929+
ErrorCode::IncorrectSpotMarketAccountPassed,
4930+
"insurance_fund_stake is not for governance market index = {}",
4931+
GOV_SPOT_MARKET_INDEX
4932+
)?;
4933+
4934+
if insurance_fund_stake.market_index == GOV_SPOT_MARKET_INDEX
4935+
&& spot_market.market_index == GOV_SPOT_MARKET_INDEX
4936+
{
4937+
let clock = Clock::get()?;
4938+
let now = clock.unix_timestamp;
4939+
4940+
crate::controller::insurance::update_user_stats_if_stake_amount(
4941+
0,
4942+
ctx.accounts.insurance_fund_vault.amount,
4943+
insurance_fund_stake,
4944+
user_stats,
4945+
spot_market,
4946+
now,
4947+
)?;
4948+
}
4949+
4950+
Ok(())
4951+
}
4952+
49184953
pub fn handle_update_feature_bit_flags_builder_codes(
49194954
ctx: Context<HotAdminUpdateState>,
49204955
enable: bool,
@@ -5803,3 +5838,27 @@ pub struct UpdateIfRebalanceConfig<'info> {
58035838
)]
58045839
pub state: Box<Account<'info, State>>,
58055840
}
5841+
5842+
#[derive(Accounts)]
5843+
pub struct UpdateDelegateUserGovTokenInsuranceStake<'info> {
5844+
#[account(
5845+
mut,
5846+
seeds = [b"spot_market", 15_u16.to_le_bytes().as_ref()],
5847+
bump
5848+
)]
5849+
pub spot_market: AccountLoader<'info, SpotMarket>,
5850+
pub insurance_fund_stake: AccountLoader<'info, InsuranceFundStake>,
5851+
#[account(mut)]
5852+
pub user_stats: AccountLoader<'info, UserStats>,
5853+
pub admin: Signer<'info>,
5854+
#[account(
5855+
mut,
5856+
seeds = [b"insurance_fund_vault".as_ref(), 15_u16.to_le_bytes().as_ref()],
5857+
bump,
5858+
)]
5859+
pub insurance_fund_vault: Box<InterfaceAccount<'info, TokenAccount>>,
5860+
#[account(
5861+
has_one = admin
5862+
)]
5863+
pub state: Box<Account<'info, State>>,
5864+
}

programs/drift/src/lib.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -725,6 +725,7 @@ pub mod drift {
725725
handle_update_spot_market_expiry(ctx, expiry_ts)
726726
}
727727

728+
// IF stakers
728729
pub fn update_user_quote_asset_insurance_stake(
729730
ctx: Context<UpdateUserQuoteAssetInsuranceStake>,
730731
) -> Result<()> {
@@ -737,7 +738,11 @@ pub mod drift {
737738
handle_update_user_gov_token_insurance_stake(ctx)
738739
}
739740

740-
// IF stakers
741+
pub fn update_delegate_user_gov_token_insurance_stake(
742+
ctx: Context<UpdateDelegateUserGovTokenInsuranceStake>,
743+
) -> Result<()> {
744+
handle_update_delegate_user_gov_token_insurance_stake(ctx)
745+
}
741746

742747
pub fn initialize_insurance_fund_stake(
743748
ctx: Context<InitializeInsuranceFundStake>,

programs/drift/src/state/order_params.rs

Lines changed: 38 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -702,13 +702,6 @@ impl OrderParams {
702702
}
703703
.cast::<i64>()?;
704704

705-
let baseline_start_price_offset_slow = mark_twap_slow.safe_sub(
706-
perp_market
707-
.amm
708-
.historical_oracle_data
709-
.last_oracle_price_twap,
710-
)?;
711-
712705
let baseline_start_price_offset_fast = perp_market
713706
.amm
714707
.last_mark_price_twap_5min
@@ -720,27 +713,42 @@ impl OrderParams {
720713
.last_oracle_price_twap_5min,
721714
)?;
722715

723-
let frac_of_long_spread_in_price: i64 = perp_market
724-
.amm
725-
.long_spread
726-
.cast::<i64>()?
727-
.safe_mul(mark_twap_slow)?
728-
.safe_div(PRICE_PRECISION_I64 * 10)?;
716+
let baseline_start_price_offset_slow = mark_twap_slow.safe_sub(
717+
perp_market
718+
.amm
719+
.historical_oracle_data
720+
.last_oracle_price_twap,
721+
)?;
729722

730-
let frac_of_short_spread_in_price: i64 = perp_market
731-
.amm
732-
.short_spread
733-
.cast::<i64>()?
734-
.safe_mul(mark_twap_slow)?
735-
.safe_div(PRICE_PRECISION_I64 * 10)?;
736-
737-
let baseline_start_price_offset = match direction {
738-
PositionDirection::Long => baseline_start_price_offset_slow
739-
.safe_add(frac_of_long_spread_in_price)?
740-
.min(baseline_start_price_offset_fast.safe_sub(frac_of_short_spread_in_price)?),
741-
PositionDirection::Short => baseline_start_price_offset_slow
742-
.safe_sub(frac_of_short_spread_in_price)?
743-
.max(baseline_start_price_offset_fast.safe_add(frac_of_long_spread_in_price)?),
723+
let baseline_start_price_offset = if baseline_start_price_offset_slow
724+
.abs_diff(baseline_start_price_offset_fast)
725+
<= perp_market.amm.last_mark_price_twap_5min / 200
726+
{
727+
let frac_of_long_spread_in_price: i64 = perp_market
728+
.amm
729+
.long_spread
730+
.cast::<i64>()?
731+
.safe_mul(mark_twap_slow)?
732+
.safe_div(PRICE_PRECISION_I64 * 10)?;
733+
734+
let frac_of_short_spread_in_price: i64 = perp_market
735+
.amm
736+
.short_spread
737+
.cast::<i64>()?
738+
.safe_mul(mark_twap_slow)?
739+
.safe_div(PRICE_PRECISION_I64 * 10)?;
740+
741+
match direction {
742+
PositionDirection::Long => baseline_start_price_offset_slow
743+
.safe_add(frac_of_long_spread_in_price)?
744+
.min(baseline_start_price_offset_fast.safe_sub(frac_of_short_spread_in_price)?),
745+
PositionDirection::Short => baseline_start_price_offset_slow
746+
.safe_sub(frac_of_short_spread_in_price)?
747+
.max(baseline_start_price_offset_fast.safe_add(frac_of_long_spread_in_price)?),
748+
}
749+
} else {
750+
// more than 50bps different of fast/slow twap, use fast only
751+
baseline_start_price_offset_fast
744752
};
745753

746754
Ok(baseline_start_price_offset)
@@ -895,15 +903,15 @@ fn get_auction_duration(
895903
) -> DriftResult<u8> {
896904
let percent_diff = price_diff.safe_mul(PERCENTAGE_PRECISION_U64)?.div(price);
897905

898-
let slots_per_bp = if contract_tier.is_as_safe_as_contract(&ContractTier::B) {
906+
let slots_per_pct = if contract_tier.is_as_safe_as_contract(&ContractTier::B) {
899907
100
900908
} else {
901909
60
902910
};
903911

904912
Ok(percent_diff
905-
.safe_mul(slots_per_bp)?
906-
.safe_div_ceil(PERCENTAGE_PRECISION_U64 / 100)? // 1% = 60 slots
913+
.safe_mul(slots_per_pct)?
914+
.safe_div_ceil(PERCENTAGE_PRECISION_U64 / 100)? // 1% = 40 slots
907915
.clamp(1, 180) as u8) // 180 slots max
908916
}
909917

0 commit comments

Comments
 (0)