v9.2.1 Update
Summary
50% of the spread and price impact is now charged on trade opening and closing instead of 100% on trade opening
Existing trades don't pay any spread or impact on close (since they already paid in full on open), and they keep paying 100% spread when partial adding
Spread and price impact on close use the reverse direction as opening spread (makes price lower for longs and higher for shorts)
Price impact on close uses the opposite side depth and opposite side price impact OI (= cumulative vol now)
Price impact OI windows now use new cumulative volume logic (much shorter windows duration possible because more accurate, opening a long / closing a short uses/adds to long windows, opening a short / closing a long uses/adds to short windows, new cumulative factor which will be set to 1 to start with but can be used to adjust weight of price impact OI in price impact formula), we never remove any OI from windows anymore (logic much simpler, no longer need to move trade OI to current window for partials)
Closing price impact higher for short-term trades (depending on protection factor blocks duration and protection factor multiplier per pair), only when net PnL is positive
Liquidation price now takes into account the closing spread (not the price impact) for trades opened after v9.2 and uses new logic for the liquidation pnl % threshold (closer pnl % threshold as leverage increases, more aggressive for higher leverages similarly to MMR)
Existing trades aren't affected by the new liquidation threshold logic, liquidation parameters for trades are stored on opening so they can't change for an open trade even when a group's liquidation parameters are updated, however a trade's liquidation params are refreshed to current value when position size is increased using partials
New stop loss max distance is
liqPnlThresholdP - 10%(eg. -70% PnL when trade liq pnl % threshold is -80%)Added max slippage on close (market close, partial close, tp/sl) mechanism: by default 1% for all opened trades, can be adjusted after trade is open
Extracted cancel reason logic for limit/stop/tp/sl/liq callbacks into getters, will be used by EA-lookbacks to check ability to execute at past chain state
LIQ triggers no longer turned into SL triggers when SL is closer otherwise user could set very low max closing slippage and would never be able to be liquidated if price went past his SL and LIQ price, trigger bots will prioritize SL over LIQ when possible
Full Changelog
core/facets/GNSPairsStorage.sol (update)
Added
initializeGroupLiquidationParams,setGroupLiquidationParams,getGroupLiquidationParams, andgetPairLiquidationParams
core/facets/GNSPriceAggregator.sol (update)
getPricenow accepts_tradeIdinstead of_trader
core/facets/GNSPriceImpact.sol (update)
Added
initializePairFactors,setProtectionCloseFactors,setProtectionCloseFactorBlocks,setCumulativeFactors,getPairFactorsRemoved
removePriceImpactOpenInterest,getTradeLastWindowOiUsd,getTradePriceImpactInfoaddPriceImpactOpenInterestnow accepts_openargumentgetTradePriceImpactnow accepts_isPnlPositive,_open,_lastPosIncreaseBlock, and_contractsVersionarguments
core/facets/GNSTradingCallbacks.sol (update)
Added
validateTriggerOpenOrderCallbackandvalidateTriggerCloseOrderCallbackgetters
core/facets/GNSTradingInteractions.sol (update)
New
updateMaxClosingSlippagePfunctioncloseTradeMarketanddecreasePositionSizenow accept_expectedPriceargument (used for max slippage check in callbacks)
core/facets/GNSTradingStorage.sol (update)
New
updateTradeMaxClosingSlippagePfunctionupdateTradePositionnow accepts_isPartialIncreaseargumentAdded
getTradeLiquidationParams,getTradesLiquidationParams,getAllTradesLiquidationParams, andgetCurrentContractsVersion
interfaces/IGeneralErrors.sol (update)
Added
WrongOrderType()error
interfaces/libraries/IPairsStorageUtils.sol (update)
Added new function definitions
Added
GroupLiquidationParamsUpdatedeventAdded
MaxLiqSpreadPTooHigh,WrongLiqParamsThresholds,WrongLiqParamsLeverages,StartLiqThresholdTooHigh,EndLiqThresholdTooLow,StartLeverageTooLow,EndLeverageTooHigh
interfaces/libraries/IPriceAggregatorUtils.sol (update)
Adjusted
getPricefunction definitionUpdated
PriceRequestedevent: now emitstradeIdinstead oftrader
interfaces/libraries/IPriceImpactUtils.sol (update)
Added new function definitions
Removed deprecated function definitions
Adjusted
addPriceImpactOpenInterestandgetTradePriceImpactfunctions definitionsAdded
ProtectionCloseFactorUpdated,ProtectionCloseFactorBlocksUpdated, andCumulativeFactorUpdatedeventsRemoved
isPartialfromPriceImpactOpenInterestAddedeventRemoved
PriceImpactOpenInterestRemovedevent
interfaces/libraries/ITradingCallbacksUtils.sol (update)
Added
validateTriggerOpenOrderCallbackandvalidateTriggerCloseOrderCallbackfunctions definitions
interfaces/libraries/ITradingCommonUtils.sol (update)
Added
TradePriceImpactInputstruct to avoid stack too deep ingetTradeClosingPriceImpact
interfaces/libraries/ITradingInteractionsUtils.sol (update)
Added
updateMaxClosingSlippagePfunction definitionAdjusted
closeTradeMarketanddecreasePositionSizefunctions definitionsRemoved
WrongOrderType()error
interfaces/libraries/ITradingStorageUtils.sol (update)
Added new function definitions
Adjusted
updateTradePositionfunction definitionTradeStoredevent now also emits the trade liquidation paramsTradePositionUpdatednow emitsisPartialIncreaseNew
TradeMaxClosingSlippagePUpdatedevent
interfaces/libraries/IUpdatePositionSizeUtils.sol (update)
Added
longandcollateralPriceUsdproperties toPositionSizeIncreaseExecutedandPositionSizeDecreaseExecutedevents
interfaces/types/IBorrowingFees.sol (update)
LiqPriceInputstruct has newliquidationParamsproperty
interfaces/types/IPairsStorage.sol (update)
Added
groupLiquidationParamsmapping and correspondingGroupLiquidationParamsstruct__gaplength decreased from 41 to 40
interfaces/types/IPriceImpact.sol (update)
Added
pairFactorsmapping__gaplength decreased from 46 to 45Added
_openproperty toOiWindowUpdatestructNew
PairFactorsstruct
interfaces/types/ITradingStorage.sol (update)
Added
tradeLiquidationParamsmapping__gaplength decreased from 39 to 38New
ContractsVersionenumTradeInfostruct now hascontractsVersionandlastPosIncreaseBlockproperties, and__placeholderwas reduced fromuint48touint8
interfaces/types/IUpdatePositionSize.sol (update)
Added
expectedPriceproperty toDecreasePositionSizeInputstructAdded
priceAfterImpactproperty toDecreasePositionSizeValuesstruct
libraries/ArrayGetters.sol (update)
Added
getTradesLiquidationParamsandgetAllTradesLiquidationParamsgetters
libraries/BorrowingFeesUtils.sol (update)
getTradeLiquidationPrice: calculateclosingFeesCollateralusing newTradingCommonUtils.getTotalClosingFeesCollateralhelper, pass input liquidation params, trade contracts version, and pair spread % to_getTradeLiquidationPrice_getTradeLiquidationPrice: new_liquidationParams,_contractsVersion, and_pairSpreadParguments,_collateralPrecisionDeltais now uint256 (saves one var to avoid stack too deep), calculateliqPnlThresholdPusing newTradingCommonUtils.getLiqPnlThresholdPhelper, incollateralLiqNegativePnlIntcalculation divide by1e10because of new liq threshold precision, if trade opened after v9.2 make liquidation price distance lower by closing spread (= 1/2 pair spread %, capped atmaxLiqSpreadP)
libraries/ConstantsUtils.sol (update)
Replaced
MAX_SL_PbySL_LIQ_BUFFER_P=10%, renamedLIQ_THRESHOLD_PtoLEGACY_LIQ_THRESHOLD_P, addedMIN_LIQ_THRESHOLD_P=50%/MAX_LIQ_SPREAD_P=0.05%/DEFAULT_MAX_CLOSING_SLIPPAGE_P=1%
libraries/PairsStorageUtils.sol (update)
New
initializeGroupLiquidationParamsfunction: initializes group liquidation params for all existing groupsNew
setGroupLiquidationParamsfunction: used to update a group's liquidation params (only affects trades opened after the change)New
getGroupLiquidationParamsandgetPairLiquidationParamsgetters
libraries/PriceAggregatorUtils.sol (update)
getPrice: now accepts_tradeIdargument instead of_trader, passestrader/index/orderTypedata tolinkRequest
libraries/PriceImpactUtils.sol (update)
MAX_WINDOWS_DURATIONlowered from 30 days to 10 minutes,MIN_WINDOWS_DURATIONlowered from 10 minutes to 1 minuteNew
initializePairFactorsfunction that initializes pairs factorsNew
setProtectionCloseFactorsto set the protection close factors for a set of pairsNew
setProtectionCloseFactorBlocksto set the protection close factor duration in blocks for a set of pairsNew
setCumulativeFactorsto set the cumulative factors for a set of pairsaddPriceImpactOpenInterest: Removed partials logic that moved previous trade OI to current window if not expired, changed logic to decide if adds to long or short part of window (opening a long / closing a short adds to long window, opening a short / closing a long adds to short window), removedlastWindowOiUsdupdate (deprecated)Removed
removePriceImpactOpenInterestandgetTradeLastWindowOiUsdgetTradePriceImpact: new_isPnlPositive/_open/_lastPosIncreaseBlock/_contractsVersionarguments, now loadspairFactorsfor pair, uses opposite side depth when_open = false, uses opposite side price impact OI when_open = false, passes_open,protectionCloseFactor(only when_isPnlPositiveis true,_openis false,protectionCloseFactorisn't zero, and protection close factor didn't expire, otherwise passes1e10),cumulativeFactor(when not zero, otherwise passes1e10), and_contractsVersionto_getTradePriceImpactRemoved
getTradePriceImpactInfo(deprecated)New
getPairFactorsgetter_getTradePriceImpact: new_open,_protectionCloseFactor,_cumulativeFactor,_contractsVersionarguments, returns early 0 price impact if trade opened before v9.2 and_open = false(no closing price impact for trades opened before v9.2 since they paid it fully on open), multiplies_startOpenInterestUsdby_cumulativeFactor, multiplies by_protectionCloseFactorinstead of1e10inpriceImpactPcalculation and divides result by 2 if trade opened after v9.2 (charge half price impact if trade opened after v9.2 since they paid half on open already, for trades opened before v9.2 charges full opening price impact), sets_longto!_longif_openis false to invert the price impact direction on close
libraries/TradingCallbacksUtils.sol (update)
closeTradeMarketCallback: use new_getTradeInfogetter, AddTradingCommonUtils.getTradeClosingPriceImpactcall, added max slippage cancel reason check (uses default max slippage % iftradeInfo.maxSlippagePnot set), usepriceAfterImpact(= market price + closing spread and price impact) instead of_a.priceto calculatev.profitP, emitpriceAfterImpactandpriceImpactPin eventexecuteTriggerOpenOrderCallback: moved all cancel reason and spread/price impact logic tovalidateTriggerOpenOrderCallbackexecuteTriggerCloseOrderCallback: moved all cancel reason and spread/price impact logic tovalidateTriggerCloseOrderCallback, emitpriceImpactPinLimitExecutedeventvalidateTriggerOpenOrderCallback: new getter that contains the extracted cancel reason logic ofexecuteTriggerOpenOrderCallbackvalidateTriggerCloseOrderCallback: new getter that contains the extracted cancel reason logic ofexecuteTriggerCloseOrderCallback, for SLs and TPs (not liquidations) setv.executionPricetoTradingCommonUtils.getTradeClosingPriceImpactresult to take into account closing spread and impact, added max slippage cancel reason check for everything but liquidations (uses default max slippage % iftradeInfo.maxSlippagePnot set)_openTradePrep: no logic change, just use newTradingCommonUtils.getTradeOpeningPriceImpacthelper to calculate opening price impactNew
_getTradeInfogetter
libraries/TradingCommonUtils.sol (update)
getMarketExecutionPrice: new_open/_contractsVersionarguments, returns early with 0 spread if_open = falseand_contractsVersion = before v9.2, divides spread by 2 if_contractsVersion >= v9.2, inverts spread direction when_open= falsegetTradeValuePure: combined_borrowingFeeCollateraland_closingFeeCollateralinto_feesCollateralto avoid stack too deep, added_liqPnlThresholdPargument,collateralLiqThresholdis nowuint256and uses_liqPnlThresholdPinstead ofConstantsUtils.LIQ_THRESHOLD_Pand is adjusted for1e10precision, addedint256conversion forcollateralLiqThresholdin return statementgetLiqPnlThresholdP: new pure function that returns the corresponding liquidation PnL threshold percentage to use depending on a trade's liquidation params and leverage; uses new logic (linearly decreasing liq pnl threshold as leverage increases, capped between two values)getTradeLiquidationPrice: pass the stored trade's liquidation paramsgetTradeValueCollateral: passborrowingFeesCollateral + _closingFeesCollateraltogetTradeValuePureinstead of passing them separately, and also passgetTradeLiqPnlThresholdP(_trade)getTradeOpeningPriceImpact: New view helper to calculate the price impact % and price after spread + price impact for trade openings / partial addsgetTradeClosingPriceImpact: New view helper that returns the closing price impact %, price after closing spread and impact, and net trade value used to determine whether net pnl is positive or not; returns early 0% price impact for trades opened before v9.2, otherwise calculates net trade value (taking into account pnl, spread, price impact, closing fees, and borrowing fees) without protection factor and compares it to the initial trade collateral to determine the_isPnlPositivevalue passed togetTradePriceImpactwhich determines the final returnedpriceImpactPandpriceAfterImpactvaluesgetTradeLiqPnlThresholdP: new getter that returns the value ofgetLiqPnlThresholdPby passing the trade's stored liquidation params and its leveragegetTotalClosingFeesCollateral: new getter that returns a trade's closing fee based on its_collateralIndex/_pairIndex/_positionSizeCollateral, used inBorrowingFeesUtils.getTradeLiquidationPrice/TradingCommonUtils.getTradeClosingPriceImpact/DecreasePositionSizeUtils.validateRequestRenamed
addOiCollateraltoupdateOi, now accepts_openargument and passes it tohandleTradeBorrowingCallbackandaddPriceImpactOpenInterestRenamed
addTradeOiCollateraltoupdateOiTrade, now accepts_openargument and passes it toupdateOiRemoved
removeOiCollateralandremoveTradeOiCollateralhandleOiDeltanow usesupdateOi, passes_open = truewhen_newPositionSizeCollateral > existingPositionSizeCollateraland_open = falsewhen_newPositionSizeCollateral < existingPositionSizeCollateral
libraries/TradingInteractionsUtils.sol (update)
New
updateMaxClosingSlippagePfunction that simply callsGNSTradingStorage.updateTradeMaxClosingSlippagePcloseTradeMarket: now accepts_expectedPrice, reverts if_expectedPriceis 0, setspendingOrder.trade.openPriceto_expectedPrice, passes trade id togetPricedecreasePositionSize: now accepts_expectedPrice, passes it torequestDecreasePositionSizetriggerOrder: no longer turn LIQ orders into SL orders when SL is closer, usesTradingCommonUtils.getTradeOpeningPriceImpactto calculatepriceImpactP_openTrade: usesTradingCommonUtils.getTradeOpeningPriceImpactto calculatepriceImpactP, passes trade id togetPrice_getPriceTriggerOrder: passes trade id togetPrice
libraries/TradingStorageUtils.sol (update)
storeTrade: Fetches the corresponding pair's liquidation params and stores them into the newtradeLiquidationParamsmapping, limits the trade SL distance using the new_limitTradeSlDistancehelper, sets_tradeInfo.contractsVersionto the current version usinggetCurrentContractsVersion(), sets_tradeInfo.lastPosIncreaseBlockto current block, no longer sets_tradeInfo.lastOiUpdateTs = 0because corresponding logic was deprecated, callsupdateOiTradewith_open = trueinstead ofaddTradeOiCollateral, emits the trade's liquidation paramsNew
updateTradeMaxClosingSlippagePsetterupdateTradePosition/updateOpenOrderDetails/updateTradeSl: limit the trade's SL distance using the new_limitTradeSlDistancehelper instead of_limitSlDistanceupdateTradePosition: new_isPartialIncreaseargument, sets the trade's stored liquidation params to the current pair liquidation params when_isPartialIncrease = trueand setsi.lastPosIncreaseBlockto current block, emits_isPartialIncreaseinTradePositionUpdatedeventcloseTrade: callsupdateOiTradewith_open = falseinstead ofremoveTradeOiCollateralgetTradeLiquidationParams: new getter to return the newtradeLiquidationParamsmapping valuesgetCurrentContractsVersion: new getter to return the current contracts version (will need to be updated at each significant update)_limitSlDistance: accepts new_liqPnlThresholdPargument, calculatesminSlPas_liqPnlThresholdP - ConstantsUtils.SL_LIQ_BUFFER_P, uses calculatedminSlPinstead ofConstantsUtils.MAX_SL_P, adjustments done for1e10precision ofminSlP_limitTradeSlDistance: new view wrapper accepting_tradeand_newSlarguments; returns a trade's capped SL distance based on its open price, leverage, new stop loss value, whether it's a long or a short, and based on its liquidation pnl % threshold fetched usingTradingCommonUtils.getTradeLiqPnlThresholdP(_trade)
libraries/updateLeverage/UpdateLeverageLifecycles.sol (update)
_initiateRequest: small adjustment to avoid stack too deep, now passes trade id togetPrice_prepareCallbackValues: pass stored trade liquidation params invalues.liqPricecalculation_handleCallback: pass_isPartialIncrease = falsetoupdateTradePosition
libraries/updatePositionSize/DecreasePositionSizeUtils.sol (update)
validateRequest: calculateclosingFeesCollateralusing newTradingCommonUtils.getTotalClosingFeesCollateralhelper, revert ifinput.expectedPriceis 0prepareCallbackValues: addedvalues.priceAfterImpactcalculation using newTradingCommonUtils.getTradeClosingPriceImpacthelper,values.existingPnlCollateralnow usesuint64(values.priceAfterImpact)instead of_answer.pricevalidateCallback: now accepts_pendingOrder(to fetch expected price), added max slippage calculations and corresponding cancel reason check (uses default max slippage % iftradeInfo.maxSlippagePnot set)updateTradeSuccess: pass_isPartialIncrease = falsetoupdateTradePosition
libraries/updatePositionSize/IncreasePositionSizeUtils.sol (update)
prepareCallbackValues: UsesTradingCommonUtils.getTradeOpeningPriceImpactto calculatevalues.priceAfterImpact, passes current pair liquidation params togetTradeLiquidationPriceforvalues.newLiqPricecalculation (already checks using new liquidation params since trade liquidation params will be refreshed on success callback)updateTradeSuccess: pass_isPartialIncrease = truetoupdateTradePosition
libraries/updatePositionSize/UpdatePositionSizeLifecycles.sol (update)
requestDecreasePositionSize: passes_input.expectedPriceto_initiateRequest_initiateRequest: passes trade id togetPriceexecuteIncreasePositionSizeMarket/executeDecreasePositionSizeMarket: pass trade long and current collateral/usd price to eventexecuteDecreasePositionSizeMarket: pass_ordertoDecreasePositionSizeUtils.validateCallback
Was this helpful?