Merge pull request #482 from drift-labs/master

master -> mainnet
This commit is contained in:
lowkeynicc
2025-08-04 16:52:41 -04:00
committed by GitHub
6 changed files with 68 additions and 10 deletions

View File

@@ -1,6 +1,10 @@
git submodule init git submodule init
git submodule update --recursive git submodule update --recursive
rm -rf node_modules
rm -rf drift-common/protocol/sdk/node_modules
rm -rf drift-common/common-ts/node_modules
echo "building sdk..." echo "building sdk..."
cd drift-common/protocol/sdk cd drift-common/protocol/sdk
yarn clean && yarn && yarn build && yarn link yarn clean && yarn && yarn build && yarn link

View File

@@ -13,7 +13,7 @@ import {
PerpOperation, PerpOperation,
PositionDirection, PositionDirection,
ZERO, ZERO,
calculateBidAskPrice, calculateAMMBidAskPrice,
getLimitPrice, getLimitPrice,
isOperationPaused, isOperationPaused,
isVariant, isVariant,
@@ -177,9 +177,11 @@ export class DLOBSubscriberIO extends DLOBSubscriber {
let bestBid = bestDlobBid; let bestBid = bestDlobBid;
let bestAsk = bestDlobAsk; let bestAsk = bestDlobAsk;
if (marketType === 'perp') { if (marketType === 'perp') {
const [bestVammBid, bestVammAsk] = calculateBidAskPrice( const [bestVammBid, bestVammAsk] = calculateAMMBidAskPrice(
this.driftClient.getPerpMarketAccount(marketArgs.marketIndex).amm, this.driftClient.getPerpMarketAccount(marketArgs.marketIndex).amm,
oraclePriceData, this.driftClient.getMMOracleDataForPerpMarket(
marketArgs.marketIndex
),
true true
); );

View File

@@ -79,7 +79,7 @@ const sdkConfig = initialize({ env: process.env.ENV });
const stateCommitment: Commitment = 'confirmed'; const stateCommitment: Commitment = 'confirmed';
const serverPort = process.env.PORT || 6969; const serverPort = process.env.PORT || 6969;
export const ORDERBOOK_UPDATE_INTERVAL = 1000; export const ORDERBOOK_UPDATE_INTERVAL = parseInt(process.env.ORDERBOOK_UPDATE_INTERVAL) || 400;
const WS_FALLBACK_FETCH_INTERVAL = ORDERBOOK_UPDATE_INTERVAL * 60; const WS_FALLBACK_FETCH_INTERVAL = ORDERBOOK_UPDATE_INTERVAL * 60;
const useWebsocket = process.env.USE_WEBSOCKET?.toLowerCase() === 'true'; const useWebsocket = process.env.USE_WEBSOCKET?.toLowerCase() === 'true';
const hermesUrl = process.env.HERMES_ENDPOINT; const hermesUrl = process.env.HERMES_ENDPOINT;

View File

@@ -118,7 +118,7 @@ const useOrderSubscriber =
process.env.USE_ORDER_SUBSCRIBER?.toLowerCase() === 'true'; process.env.USE_ORDER_SUBSCRIBER?.toLowerCase() === 'true';
const ORDERBOOK_UPDATE_INTERVAL = const ORDERBOOK_UPDATE_INTERVAL =
parseInt(process.env.ORDERBOOK_UPDATE_INTERVAL) || 1000; parseInt(process.env.ORDERBOOK_UPDATE_INTERVAL) || 400;
const WS_FALLBACK_FETCH_INTERVAL = 60_000; const WS_FALLBACK_FETCH_INTERVAL = 60_000;
const KILLSWITCH_SLOT_DIFF_THRESHOLD = const KILLSWITCH_SLOT_DIFF_THRESHOLD =

View File

@@ -25,6 +25,7 @@ import {
PERCENTAGE_PRECISION_EXP, PERCENTAGE_PRECISION_EXP,
} from '@drift-labs/sdk'; } from '@drift-labs/sdk';
import { RedisClient } from '@drift/common/clients'; import { RedisClient } from '@drift/common/clients';
import { TradeOffsetPrice } from '@drift/common';
import { logger } from './logger'; import { logger } from './logger';
import { NextFunction, Request, Response } from 'express'; import { NextFunction, Request, Response } from 'express';
import FEATURE_FLAGS from './featureFlags'; import FEATURE_FLAGS from './featureFlags';
@@ -746,6 +747,37 @@ export const convertRawL2ToBN = (rawL2: any): L2OrderBook => {
}; };
}; };
/**
* Maps TradeOffsetPrice values to corresponding property names in estimatedPrices object
* @param offsetFrom - TradeOffsetPrice type or 'marketBased' or undefined
* @returns Property name string for accessing estimatedPrices
*/
export const mapTradeOffsetPriceToProperty = (
offsetFrom: TradeOffsetPrice | 'marketBased' | undefined
): string => {
switch (offsetFrom) {
case 'best':
return 'bestPrice';
case 'worst':
return 'worstPrice';
case 'oracle':
return 'oraclePrice';
case 'mark':
return 'markPrice';
case 'entry':
return 'entryPrice';
case 'bestOffer':
// For bestOffer, we'll use the best price (could be refined based on direction)
return 'bestPrice';
case 'marketBased':
// Default to mark price for market-based pricing
return 'markPrice';
default:
// Default fallback to mark price
return 'markPrice';
}
};
/** /**
* Get L2 orderbook data and calculate estimated prices * Get L2 orderbook data and calculate estimated prices
* @param driftClient - DriftClient instance * @param driftClient - DriftClient instance
@@ -935,11 +967,18 @@ export const mapToMarketOrderParams = async (
}; };
} }
const startPriceProperty = mapTradeOffsetPriceToProperty(
params.auctionStartPriceOffsetFrom
);
const startPrice = estimatedPrices[startPriceProperty];
processedSlippageTolerance = calculateDynamicSlippage( processedSlippageTolerance = calculateDynamicSlippage(
params.marketIndex, params.marketIndex,
params.marketType, params.marketType,
driftClient, driftClient,
l2Formatted l2Formatted,
startPrice,
estimatedPrices.worstPrice
); );
} }
} else { } else {
@@ -1072,7 +1111,9 @@ export const calculateDynamicSlippage = (
marketIndex: number, marketIndex: number,
marketType: string, marketType: string,
driftClient: DriftClient, driftClient: DriftClient,
l2Formatted: L2OrderBook l2Formatted: L2OrderBook,
startPrice: BN,
worstPrice: BN
): number => { ): number => {
// Determine if this is a major market (PERP with marketIndex 0, 1, or 2) // Determine if this is a major market (PERP with marketIndex 0, 1, or 2)
const isPerp = marketType.toLowerCase() === 'perp'; const isPerp = marketType.toLowerCase() === 'perp';
@@ -1113,17 +1154,28 @@ export const calculateDynamicSlippage = (
let dynamicSlippage = baseSlippage + spreadBaseSlippage; let dynamicSlippage = baseSlippage + spreadBaseSlippage;
// use halfway to worst price as size adjusted slippage
if (startPrice && worstPrice) {
const sizeAdjustedSlippage =
(startPrice.sub(worstPrice).abs().toNumber() /
BN.max(startPrice, worstPrice).toNumber() /
2) *
100;
dynamicSlippage = Math.max(dynamicSlippage, sizeAdjustedSlippage);
}
// Apply multiplier from env var // Apply multiplier from env var
const multiplier = isMajor const multiplier = isMajor
? parseFloat(process.env.DYNAMIC_SLIPPAGE_MULTIPLIER_MAJOR || '1.02') ? parseFloat(process.env.DYNAMIC_SLIPPAGE_MULTIPLIER_MAJOR || '1.02')
: parseFloat(process.env.DYNAMIC_SLIPPAGE_MULTIPLIER_NON_MAJOR || '1.5'); : parseFloat(process.env.DYNAMIC_SLIPPAGE_MULTIPLIER_NON_MAJOR || '1.4');
dynamicSlippage = dynamicSlippage * multiplier; dynamicSlippage = dynamicSlippage * multiplier;
// Enforce minimum and maximum limits from env vars // Enforce minimum and maximum limits from env vars
const minSlippage = parseFloat(process.env.DYNAMIC_SLIPPAGE_MIN || '0.05'); // 0.05% minimum const minSlippage = parseFloat(process.env.DYNAMIC_SLIPPAGE_MIN || '0.05'); // 0.05% minimum
const maxSlippage = parseFloat(process.env.DYNAMIC_SLIPPAGE_MAX || '5'); // 5% maximum const maxSlippage = parseFloat(process.env.DYNAMIC_SLIPPAGE_MAX || '5'); // 5% maximum
return Math.min(Math.max(dynamicSlippage, minSlippage), maxSlippage); return Math.min(Math.max(dynamicSlippage, minSlippage), maxSlippage) / 100;
}; };
/** /**