Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
13 changes: 12 additions & 1 deletion programs/drift/src/controller/amm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,9 +192,20 @@ pub fn update_spreads(
market.amm.max_base_asset_reserve,
)?;

let signed_liquidity_ratio =
let mut signed_liquidity_ratio =
liquidity_ratio.safe_mul(market.amm.get_protocol_owned_position()?.signum().cast()?)?;

let deadband_pct = market.get_reference_offset_deadband_pct()?;
if signed_liquidity_ratio.unsigned_abs() <= deadband_pct {
signed_liquidity_ratio = 0;
} else {
signed_liquidity_ratio = signed_liquidity_ratio.safe_sub(
deadband_pct
.cast::<i128>()?
.safe_mul(signed_liquidity_ratio.signum())?,
)?;
}

amm_spread::calculate_reference_price_offset(
reserve_price,
market.amm.last_24h_avg_funding_rate,
Expand Down
3 changes: 2 additions & 1 deletion programs/drift/src/instructions/admin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -983,7 +983,8 @@ pub fn handle_initialize_perp_market(
protected_maker_dynamic_divisor: 0,
padding1: 0,
last_fill_price: 0,
padding: [0; 24],
reference_offset_deadband_pct: 0,
padding: [0; 23],
amm: AMM {
oracle: *ctx.accounts.oracle.key,
oracle_source,
Expand Down
53 changes: 40 additions & 13 deletions programs/drift/src/math/amm_spread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,9 @@ use crate::math::casting::Cast;
use crate::math::constants::{
AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO_I128, AMM_TO_QUOTE_PRECISION_RATIO_I128,
BID_ASK_SPREAD_PRECISION, BID_ASK_SPREAD_PRECISION_I128, DEFAULT_LARGE_BID_ASK_FACTOR,
DEFAULT_REVENUE_SINCE_LAST_FUNDING_SPREAD_RETREAT, FUNDING_RATE_BUFFER,
MAX_BID_ASK_INVENTORY_SKEW_FACTOR, PEG_PRECISION, PERCENTAGE_PRECISION,
PERCENTAGE_PRECISION_I128, PERCENTAGE_PRECISION_U64, PRICE_PRECISION, PRICE_PRECISION_I128,
PRICE_PRECISION_I64,
DEFAULT_REVENUE_SINCE_LAST_FUNDING_SPREAD_RETREAT, MAX_BID_ASK_INVENTORY_SKEW_FACTOR,
PEG_PRECISION, PERCENTAGE_PRECISION, PERCENTAGE_PRECISION_I128, PERCENTAGE_PRECISION_I64,
PERCENTAGE_PRECISION_U64, PRICE_PRECISION, PRICE_PRECISION_I128, PRICE_PRECISION_I64,
};
use crate::math::safe_math::SafeMath;
use crate::state::perp_market::{ContractType, PerpMarket, AMM};
Expand Down Expand Up @@ -193,6 +192,37 @@ pub fn calculate_inventory_liquidity_ratio(
Ok(amm_inventory_pct)
}

pub fn calculate_inventory_liquidity_ratio_for_reference_price_offset(
base_asset_amount_with_amm: i128,
base_asset_reserve: u128,
min_base_asset_reserve: u128,
max_base_asset_reserve: u128,
) -> DriftResult<i128> {
// computes min(1, x/(1-x)) for 0 < x < 1

// inventory scale
let (max_bids, max_asks) = _calculate_market_open_bids_asks(
base_asset_reserve,
min_base_asset_reserve,
max_base_asset_reserve,
)?;

let avg_liquidity = (max_bids.safe_add(max_asks.abs())?).safe_div(2)?;

let amm_inventory_pct = if base_asset_amount_with_amm.abs() < avg_liquidity {
base_asset_amount_with_amm
.abs()
.safe_mul(PERCENTAGE_PRECISION_I128)
.unwrap_or(i128::MAX)
.safe_div(avg_liquidity.max(1))?
.min(PERCENTAGE_PRECISION_I128)
} else {
PERCENTAGE_PRECISION_I128 // 100%
};

Ok(amm_inventory_pct)
}

pub fn calculate_spread_inventory_scale(
base_asset_amount_with_amm: i128,
base_asset_reserve: u128,
Expand Down Expand Up @@ -587,17 +617,12 @@ pub fn calculate_reference_price_offset(
.cast::<i64>()?
.safe_sub(oracle_twap_slow)?
.clamp(-max_offset_in_price, max_offset_in_price);
// convert last_24h_avg_funding_rate to quote denominated premium
let mark_premium_day: i64 = last_24h_avg_funding_rate
.safe_div(FUNDING_RATE_BUFFER.cast()?)?
.safe_mul(24)?
.clamp(-max_offset_in_price, max_offset_in_price); // todo: look at how 24h funding is calc w.r.t. the funding_period

// take average clamped premium as the price-based offset
let mark_premium_avg = mark_premium_minute
.safe_add(mark_premium_hour)?
.safe_add(mark_premium_day)?
.safe_div(3_i64)?;
.safe_mul(75)?
.safe_add(mark_premium_hour.safe_mul(25)?)?
.safe_div(100_i64)?;

let mark_premium_avg_pct: i64 = mark_premium_avg
.safe_mul(PRICE_PRECISION_I64)?
Expand All @@ -613,7 +638,9 @@ pub fn calculate_reference_price_offset(
let offset_pct = if (mark_premium_avg_pct >= 0 && inventory_pct >= 0)
|| (mark_premium_avg_pct <= 0 && inventory_pct <= 0)
{
mark_premium_avg_pct.safe_add(inventory_pct)?
mark_premium_avg_pct
.safe_mul(inventory_pct.cast::<i64>()?)?
.safe_div(PERCENTAGE_PRECISION_I64)?
} else {
0
};
Expand Down
12 changes: 10 additions & 2 deletions programs/drift/src/state/perp_market.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,10 @@ pub struct PerpMarket {
pub protected_maker_dynamic_divisor: u8,
pub padding1: u32,
pub last_fill_price: u64,
pub padding: [u8; 24],
/// Reference price offset deadband percentage (0-100). 0 disables deadband.
/// Stored in former padding to preserve zero-copy layout.
pub reference_offset_deadband_pct: u8,
pub padding: [u8; 23],
}

impl Default for PerpMarket {
Expand Down Expand Up @@ -280,7 +283,8 @@ impl Default for PerpMarket {
protected_maker_dynamic_divisor: 0,
padding1: 0,
last_fill_price: 0,
padding: [0; 24],
reference_offset_deadband_pct: 0,
padding: [0; 23],
}
}
}
Expand All @@ -294,6 +298,10 @@ impl MarketIndexOffset for PerpMarket {
}

impl PerpMarket {
pub fn get_reference_offset_deadband_pct(&self) -> DriftResult<u128> {
let pct = self.reference_offset_deadband_pct as u128;
Ok(PERCENTAGE_PRECISION.safe_mul(pct)?.safe_div(100_u128)?)
}
pub fn oracle_id(&self) -> OracleIdentifier {
(self.amm.oracle, self.amm.oracle_source)
}
Expand Down
Loading