Skip to content

Commit

Permalink
program: allow accelerated update user idle (#669)
Browse files Browse the repository at this point in the history
* program: allow accelerated update user idle

* change to slots and add comment

* CHANGELOG
  • Loading branch information
crispheaney authored Oct 26, 2023
1 parent a7f352b commit e7af273
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 8 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Features

- program: add accelerated user update idle ([#669](https://github.com/drift-labs/protocol-v2/pull/669))
- program: make user status a bit flag ([#619](https://github.com/drift-labs/protocol-v2/pull/619))
- program: place and take uses auction end price for market orders ([#650](https://github.com/drift-labs/protocol-v2/pull/650))
- program: reduce cus for place_spot_order ([#662](https://github.com/drift-labs/protocol-v2/pull/662))
Expand Down
23 changes: 21 additions & 2 deletions programs/drift/src/instructions/keeper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::instructions::optional_accounts::{
};
use crate::math::constants::QUOTE_SPOT_MARKET_INDEX;
use crate::math::insurance::if_shares_to_vault_amount;
use crate::math::margin::calculate_user_equity;
use crate::math::orders::{estimate_price_from_side, find_bids_and_asks_from_users};
use crate::math::spot_withdraw::validate_spot_market_vault_amount;
use crate::state::fill_mode::FillMode;
Expand All @@ -29,10 +30,10 @@ use crate::state::spot_market_map::{
use crate::state::state::State;
use crate::state::user::{MarketType, OrderStatus, User, UserStats};
use crate::state::user_map::load_user_maps;
use crate::validate;
use crate::validation::user::validate_user_is_idle;
use crate::{controller, load, math};
use crate::{load_mut, QUOTE_PRECISION_U64};
use crate::{validate, QUOTE_PRECISION_I128};

#[access_control(
fill_not_paused(&ctx.accounts.state)
Expand Down Expand Up @@ -357,7 +358,25 @@ pub fn handle_update_user_idle<'info>(ctx: Context<UpdateUserIdle>) -> Result<()
let mut user = load_mut!(ctx.accounts.user)?;
let clock = Clock::get()?;

validate_user_is_idle(&user, clock.slot)?;
let AccountMaps {
perp_market_map,
spot_market_map,
mut oracle_map,
} = load_maps(
&mut ctx.remaining_accounts.iter().peekable(),
&MarketSet::new(),
&MarketSet::new(),
Clock::get()?.slot,
None,
)?;

let (equity, _) =
calculate_user_equity(&user, &perp_market_map, &spot_market_map, &mut oracle_map)?;

// user flipped to idle faster if equity is less than 1
let accelerated = equity < QUOTE_PRECISION_I128;

validate_user_is_idle(&user, clock.slot, accelerated)?;

user.idle = true;

Expand Down
11 changes: 6 additions & 5 deletions programs/drift/src/validation/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,14 @@ pub fn validate_user_deletion(user: &User, user_stats: &UserStats) -> DriftResul
Ok(())
}

pub fn validate_user_is_idle(user: &User, slot: u64) -> DriftResult {
pub fn validate_user_is_idle(user: &User, slot: u64, accelerated: bool) -> DriftResult {
let slots_since_last_active = slot.saturating_sub(user.last_active_slot);

#[cfg(feature = "mainnet-beta")]
let slots_before_idle = 1512000_u64;
#[cfg(not(feature = "mainnet-beta"))]
let slots_before_idle = 0_u64;
let slots_before_idle = if accelerated {
9000_u64 // 60 * 60 / .4 (~1 hour)
} else {
1512000_u64 // 60 * 60 * 24 * 7 / .4 (~1 week)
};

validate!(
slots_since_last_active >= slots_before_idle,
Expand Down
12 changes: 11 additions & 1 deletion sdk/src/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3148,12 +3148,22 @@ export class User {
};
}

public canMakeIdle(slot: BN, slotsBeforeIdle: BN): boolean {
public canMakeIdle(slot: BN): boolean {
const userAccount = this.getUserAccount();
if (userAccount.idle) {
return false;
}

const { totalAssetValue, totalLiabilityValue } = this.getSpotMarketAssetAndLiabilityValue();
const equity = totalAssetValue.sub(totalLiabilityValue);

let slotsBeforeIdle: BN;
if (equity.lt(QUOTE_PRECISION)) {
slotsBeforeIdle = new BN(9000); // 1 hour
} else {
slotsBeforeIdle = new BN(1512000); // 1 week
}

const userLastActiveSlot = userAccount.lastActiveSlot;
const slotsSinceLastActive = slot.sub(userLastActiveSlot);
if (slotsSinceLastActive.lt(slotsBeforeIdle)) {
Expand Down

0 comments on commit e7af273

Please sign in to comment.