@gainsnetwork/sdk 0.0.0-v10.rc22 → 0.0.0-v10.rc24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,6 +4,7 @@
4
4
  import { MarketPriceResult, MarketPriceContext } from "./types";
5
5
  /**
6
6
  * @dev Calculates the current market price adjusted for skew impact
7
+ * @dev Please always provide oracle price to this and other functions in the sdk. Market price is displayed in the UI.
7
8
  * @param pairIndex Trading pair index
8
9
  * @param oraclePrice Oracle price for the pair
9
10
  * @param context Market price context with depths and OI data
@@ -7,6 +7,7 @@ exports.getCurrentMarketPrice = void 0;
7
7
  const skew_1 = require("../../trade/priceImpact/skew");
8
8
  /**
9
9
  * @dev Calculates the current market price adjusted for skew impact
10
+ * @dev Please always provide oracle price to this and other functions in the sdk. Market price is displayed in the UI.
10
11
  * @param pairIndex Trading pair index
11
12
  * @param oraclePrice Oracle price for the pair
12
13
  * @param context Market price context with depths and OI data
@@ -22,7 +23,7 @@ const getCurrentMarketPrice = (pairIndex, oraclePrice, context) => {
22
23
  open: true,
23
24
  positionSizeToken: 0, // Size 0 for current market price
24
25
  }, context);
25
- skewImpactP = skewResult.priceImpactP;
26
+ skewImpactP = skewResult.basePriceImpactP;
26
27
  }
27
28
  const marketPrice = oraclePrice * (1 + skewImpactP / 100);
28
29
  return {
@@ -10,6 +10,19 @@ import { GetLiquidationPriceContext } from "./types";
10
10
  * @returns Liquidation price
11
11
  */
12
12
  export declare const getLiquidationPrice: (trade: Trade, context: GetLiquidationPriceContext) => number;
13
+ /**
14
+ * @dev Calculate liquidation price after a position size update
15
+ * @dev Mirrors the contract's IncreasePositionSizeUtils.sol and DecreasePositionSizeUtils.sol logic
16
+ * @param existingTrade The current trade before the update
17
+ * @param newCollateralAmount New collateral amount after the update
18
+ * @param newLeverage New leverage after the update
19
+ * @param isLeverageUpdate Whether this is a leverage update vs regular position change
20
+ * @param positionSizeCollateralDelta The absolute change in position size (in collateral terms)
21
+ * @param pnlToRealizeCollateral PnL to be realized (only relevant for leverage decrease)
22
+ * @param context Structured context with all required data (including additionalFeesCollateral for increases)
23
+ * @returns New liquidation price after the update
24
+ */
25
+ export declare const getLiquidationPriceAfterPositionUpdate: (existingTrade: Trade, newCollateralAmount: number, newLeverage: number, isLeverageUpdate: boolean, positionSizeCollateralDelta: number, pnlToRealizeCollateral: number, context: GetLiquidationPriceContext) => number;
13
26
  export declare const getLiqPnlThresholdP: (liquidationParams: LiquidationParams | undefined, leverage: number | undefined) => number;
14
27
  export { convertLiquidationParams, convertLiquidationParamsArray, encodeLiquidationParams, } from "./converter";
15
28
  export * from "./types";
@@ -17,7 +17,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
17
17
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
18
18
  };
19
19
  Object.defineProperty(exports, "__esModule", { value: true });
20
- exports.encodeLiquidationParams = exports.convertLiquidationParamsArray = exports.convertLiquidationParams = exports.getLiqPnlThresholdP = exports.getLiquidationPrice = void 0;
20
+ exports.encodeLiquidationParams = exports.convertLiquidationParamsArray = exports.convertLiquidationParams = exports.getLiqPnlThresholdP = exports.getLiquidationPriceAfterPositionUpdate = exports.getLiquidationPrice = void 0;
21
21
  const types_1 = require("../../contracts/types");
22
22
  const __1 = require("..");
23
23
  /**
@@ -86,6 +86,101 @@ const getLiquidationPrice = (trade, context) => {
86
86
  : Math.max(trade.openPrice + liqPriceDistance, 0);
87
87
  };
88
88
  exports.getLiquidationPrice = getLiquidationPrice;
89
+ /**
90
+ * @dev Calculate liquidation price after a position size update
91
+ * @dev Mirrors the contract's IncreasePositionSizeUtils.sol and DecreasePositionSizeUtils.sol logic
92
+ * @param existingTrade The current trade before the update
93
+ * @param newCollateralAmount New collateral amount after the update
94
+ * @param newLeverage New leverage after the update
95
+ * @param isLeverageUpdate Whether this is a leverage update vs regular position change
96
+ * @param positionSizeCollateralDelta The absolute change in position size (in collateral terms)
97
+ * @param pnlToRealizeCollateral PnL to be realized (only relevant for leverage decrease)
98
+ * @param context Structured context with all required data (including additionalFeesCollateral for increases)
99
+ * @returns New liquidation price after the update
100
+ */
101
+ const getLiquidationPriceAfterPositionUpdate = (existingTrade, newCollateralAmount, newLeverage, isLeverageUpdate, positionSizeCollateralDelta, pnlToRealizeCollateral, context) => {
102
+ var _a, _b;
103
+ const { currentPairPrice, isCounterTrade = false } = context.liquidationSpecific;
104
+ // 1. Calculate closing fees on the new position size
105
+ const closingFeeCollateral = (0, __1.getTotalTradeFeesCollateral)(existingTrade.collateralIndex, "", // No fee tiers applied for liquidation calculation
106
+ existingTrade.pairIndex, newCollateralAmount * newLeverage, isCounterTrade, {
107
+ fee: context.trading.fee,
108
+ collateralPriceUsd: context.core.collateralPriceUsd,
109
+ globalTradeFeeParams: context.trading.globalTradeFeeParams,
110
+ traderFeeMultiplier: 1,
111
+ counterTradeSettings: context.trading.counterTradeSettings,
112
+ });
113
+ // 2. Calculate holding fees on the EXISTING trade (full position)
114
+ const holdingFees = (0, __1.getTradePendingHoldingFeesCollateral)(existingTrade, context.tradeData.tradeInfo, context.tradeData.tradeFeesData, currentPairPrice, {
115
+ contractsVersion: context.core.contractsVersion,
116
+ currentTimestamp: context.core.currentTimestamp,
117
+ collateralPriceUsd: context.core.collateralPriceUsd,
118
+ borrowingV1: context.borrowingV1,
119
+ borrowingV2: context.borrowingV2,
120
+ funding: context.funding,
121
+ initialAccFees: context.tradeData.initialAccFees,
122
+ });
123
+ // 3. Calculate total realized PnL
124
+ const totalRealizedPnlCollateral = context.tradeData.tradeFeesData.realizedPnlCollateral -
125
+ context.tradeData.tradeFeesData.realizedTradingFeesCollateral;
126
+ // 4. Determine if this is an increase or decrease
127
+ const existingPositionSizeCollateral = existingTrade.collateralAmount * existingTrade.leverage;
128
+ const newPositionSizeCollateral = newCollateralAmount * newLeverage;
129
+ const isIncrease = newPositionSizeCollateral > existingPositionSizeCollateral;
130
+ // 5. Calculate additional fee and partial close multiplier based on update type
131
+ let additionalFeeCollateral;
132
+ let partialCloseMultiplier;
133
+ if (isIncrease) {
134
+ // For position increases: use additional fees from context (e.g., opening fees)
135
+ additionalFeeCollateral =
136
+ context.liquidationSpecific.additionalFeeCollateral || 0;
137
+ partialCloseMultiplier = 1; // Set to 1
138
+ }
139
+ else if (isLeverageUpdate) {
140
+ // For leverage decreases: additional fee includes closing fee minus PnL to realize
141
+ additionalFeeCollateral = closingFeeCollateral - pnlToRealizeCollateral;
142
+ partialCloseMultiplier = 1; // Full multiplier for leverage updates
143
+ }
144
+ else {
145
+ // For regular position decreases: no additional fee, scaled multiplier
146
+ additionalFeeCollateral = 0;
147
+ partialCloseMultiplier =
148
+ (existingPositionSizeCollateral - positionSizeCollateralDelta) /
149
+ existingPositionSizeCollateral;
150
+ }
151
+ // 6. Calculate total fees
152
+ const totalFeesCollateral = closingFeeCollateral +
153
+ (holdingFees.totalFeeCollateral - totalRealizedPnlCollateral) *
154
+ partialCloseMultiplier +
155
+ additionalFeeCollateral;
156
+ // 7. Calculate liquidation threshold
157
+ const liqThresholdP = (0, exports.getLiqPnlThresholdP)(context.tradeData.liquidationParams, newLeverage);
158
+ // 8. Calculate liquidation price distance
159
+ const collateralLiqNegativePnl = newCollateralAmount * liqThresholdP;
160
+ // For increases, we need to use the new weighted average open price
161
+ // For decreases, we use the existing open price
162
+ const openPriceToUse = isIncrease
163
+ ? context.liquidationSpecific.newOpenPrice || existingTrade.openPrice
164
+ : existingTrade.openPrice;
165
+ let liqPriceDistance = (openPriceToUse * (collateralLiqNegativePnl - totalFeesCollateral)) /
166
+ newCollateralAmount /
167
+ newLeverage;
168
+ // 9. Apply closing spread for v9.2+
169
+ if (context.core.contractsVersion >= types_1.ContractsVersion.V9_2 &&
170
+ ((((_a = context.tradeData.liquidationParams) === null || _a === void 0 ? void 0 : _a.maxLiqSpreadP) !== undefined &&
171
+ context.tradeData.liquidationParams.maxLiqSpreadP > 0) ||
172
+ (((_b = context.liquidationSpecific.userPriceImpact) === null || _b === void 0 ? void 0 : _b.fixedSpreadP) !==
173
+ undefined &&
174
+ context.liquidationSpecific.userPriceImpact.fixedSpreadP > 0))) {
175
+ const closingSpreadP = (0, __1.getSpreadP)(context.core.spreadP, true, context.tradeData.liquidationParams, context.liquidationSpecific.userPriceImpact);
176
+ liqPriceDistance -= openPriceToUse * closingSpreadP;
177
+ }
178
+ // 10. Calculate final liquidation price
179
+ return existingTrade.long
180
+ ? Math.max(openPriceToUse - liqPriceDistance, 0)
181
+ : Math.max(openPriceToUse + liqPriceDistance, 0);
182
+ };
183
+ exports.getLiquidationPriceAfterPositionUpdate = getLiquidationPriceAfterPositionUpdate;
89
184
  const getLiqPnlThresholdP = (liquidationParams, leverage) => {
90
185
  if (liquidationParams === undefined ||
91
186
  leverage === undefined ||
@@ -38,5 +38,6 @@ export type GetLiquidationPriceContext = {
38
38
  beforeOpened: boolean;
39
39
  isCounterTrade: boolean;
40
40
  userPriceImpact?: UserPriceImpact;
41
+ newOpenPrice?: number;
41
42
  };
42
43
  };
@@ -43,8 +43,11 @@ const getTradeClosingPriceImpact = (input, context) => {
43
43
  positionSizeToken: 0,
44
44
  fixedSpreadP: 0,
45
45
  cumulVolPriceImpactP: 0,
46
- skewPriceImpactP: 0,
46
+ baseSkewPriceImpactP: 0,
47
+ tradeSkewPriceImpactP: 0,
48
+ totalSkewPriceImpactP: 0,
47
49
  totalPriceImpactP: 0,
50
+ totalPriceImpactPFromMarketPrice: 0,
48
51
  priceAfterImpact: input.oraclePrice,
49
52
  tradeValueCollateralNoFactor: 0,
50
53
  };
@@ -83,25 +86,37 @@ const getTradeClosingPriceImpact = (input, context) => {
83
86
  }
84
87
  }
85
88
  // Calculate skew price impact (v10+ only)
86
- const skewPriceImpactP = input.contractsVersion >= types_1.ContractsVersion.V10
89
+ const skewPriceImpactObject = input.contractsVersion >= types_1.ContractsVersion.V10
87
90
  ? (0, skew_1.getTradeSkewPriceImpact)({
88
91
  collateralIndex: input.collateralIndex,
89
92
  pairIndex: input.pairIndex,
90
93
  long: input.trade.long,
91
94
  open: false,
92
95
  positionSizeToken,
93
- }, context.skewContext).priceImpactP
94
- : 0;
96
+ }, context.skewContext)
97
+ : {
98
+ basePriceImpactP: 0,
99
+ tradePriceImpactP: 0,
100
+ totalPriceImpactP: 0,
101
+ };
95
102
  // Total price impact (all components)
96
- const totalPriceImpactP = fixedSpreadP + cumulVolPriceImpactP + skewPriceImpactP;
103
+ const totalPriceImpactP = fixedSpreadP +
104
+ cumulVolPriceImpactP +
105
+ skewPriceImpactObject.totalPriceImpactP;
106
+ const totalPriceImpactPFromMarketPrice = fixedSpreadP +
107
+ cumulVolPriceImpactP +
108
+ skewPriceImpactObject.tradePriceImpactP;
97
109
  // Calculate final price after all impacts
98
110
  const priceAfterImpact = (0, __1.getPriceAfterImpact)(input.currentPairPrice, totalPriceImpactP);
99
111
  return {
100
112
  positionSizeToken,
101
113
  fixedSpreadP,
102
114
  cumulVolPriceImpactP,
103
- skewPriceImpactP,
115
+ baseSkewPriceImpactP: skewPriceImpactObject.basePriceImpactP,
116
+ tradeSkewPriceImpactP: skewPriceImpactObject.tradePriceImpactP,
117
+ totalSkewPriceImpactP: skewPriceImpactObject.totalPriceImpactP,
104
118
  totalPriceImpactP,
119
+ totalPriceImpactPFromMarketPrice,
105
120
  priceAfterImpact,
106
121
  tradeValueCollateralNoFactor,
107
122
  };
@@ -37,8 +37,11 @@ export type TradeClosingPriceImpactResult = {
37
37
  positionSizeToken: number;
38
38
  fixedSpreadP: number;
39
39
  cumulVolPriceImpactP: number;
40
- skewPriceImpactP: number;
40
+ baseSkewPriceImpactP: number;
41
+ tradeSkewPriceImpactP: number;
42
+ totalSkewPriceImpactP: number;
41
43
  totalPriceImpactP: number;
44
+ totalPriceImpactPFromMarketPrice: number;
42
45
  priceAfterImpact: number;
43
46
  tradeValueCollateralNoFactor: number;
44
47
  };
@@ -36,16 +36,17 @@ const getTradeOpeningPriceImpact = (input, context) => {
36
36
  // Calculate position size in tokens using the price after fixed spread and cumul vol impact
37
37
  const positionSizeToken = positionSizeCollateral / priceAfterSpreadAndCumulVolPriceImpact;
38
38
  // Calculate skew price impact (v10+ only)
39
- const skewResult = (0, skew_1.getTradeSkewPriceImpact)({
39
+ const skewPriceImpactObject = (0, skew_1.getTradeSkewPriceImpact)({
40
40
  collateralIndex: input.collateralIndex,
41
41
  pairIndex: input.pairIndex,
42
42
  long: input.long,
43
43
  open: true,
44
44
  positionSizeToken,
45
45
  }, context.skewContext);
46
- const skewPriceImpactP = skewResult.priceImpactP;
46
+ const skewPriceImpactP = skewPriceImpactObject.totalPriceImpactP;
47
47
  // Total price impact (signed - can be positive or negative)
48
48
  const totalPriceImpactP = spreadP + cumulVolPriceImpactP + skewPriceImpactP;
49
+ const totalPriceImpactPFromMarketPrice = spreadP + cumulVolPriceImpactP + skewPriceImpactObject.tradePriceImpactP;
49
50
  // Calculate final price after impact using the same formula as Solidity
50
51
  const priceAfterImpact = (0, __1.getPriceAfterImpact)(input.openPrice, totalPriceImpactP);
51
52
  // Calculate percent profit from impact
@@ -56,8 +57,11 @@ const getTradeOpeningPriceImpact = (input, context) => {
56
57
  priceAfterImpact,
57
58
  percentProfitP,
58
59
  cumulVolPriceImpactP,
59
- skewPriceImpactP,
60
+ baseSkewPriceImpactP: skewPriceImpactObject.basePriceImpactP,
61
+ tradeSkewPriceImpactP: skewPriceImpactObject.tradePriceImpactP,
62
+ totalSkewPriceImpactP: skewPriceImpactObject.totalPriceImpactP,
60
63
  totalPriceImpactP,
64
+ totalPriceImpactPFromMarketPrice,
61
65
  };
62
66
  };
63
67
  exports.getTradeOpeningPriceImpact = getTradeOpeningPriceImpact;
@@ -36,6 +36,9 @@ export type TradeOpeningPriceImpactResult = {
36
36
  priceAfterImpact: number;
37
37
  percentProfitP: number;
38
38
  cumulVolPriceImpactP: number;
39
- skewPriceImpactP: number;
39
+ baseSkewPriceImpactP: number;
40
+ tradeSkewPriceImpactP: number;
41
+ totalSkewPriceImpactP: number;
40
42
  totalPriceImpactP: number;
43
+ totalPriceImpactPFromMarketPrice: number;
41
44
  };
@@ -101,20 +101,25 @@ const getTradeSkewPriceImpact = (input, context) => {
101
101
  // Determine trade direction
102
102
  const tradePositiveSkew = (0, exports.getTradeSkewDirection)(input.long, input.open);
103
103
  // Calculate price impact
104
- const priceImpactP = (0, exports.calculateSkewPriceImpactP)(netSkewToken, input.positionSizeToken, skewDepth, tradePositiveSkew);
104
+ const basePriceImpactP = (0, exports.calculateSkewPriceImpactP)(netSkewToken, 0, skewDepth, tradePositiveSkew);
105
+ // Calculate price impact
106
+ const totalPriceImpactP = (0, exports.calculateSkewPriceImpactP)(netSkewToken, input.positionSizeToken, skewDepth, tradePositiveSkew);
107
+ const tradePriceImpactP = totalPriceImpactP - basePriceImpactP;
105
108
  // Determine trade direction relative to skew
106
109
  let tradeDirection;
107
- if (priceImpactP > 0) {
110
+ if (totalPriceImpactP > 0) {
108
111
  tradeDirection = "increase";
109
112
  }
110
- else if (priceImpactP < 0) {
113
+ else if (totalPriceImpactP < 0) {
111
114
  tradeDirection = "decrease";
112
115
  }
113
116
  else {
114
117
  tradeDirection = "neutral";
115
118
  }
116
119
  return {
117
- priceImpactP,
120
+ basePriceImpactP,
121
+ tradePriceImpactP,
122
+ totalPriceImpactP,
118
123
  netSkewToken,
119
124
  netSkewCollateral: 0,
120
125
  tradeDirection,
@@ -17,7 +17,9 @@ export type SkewPriceImpactInput = {
17
17
  positionSizeToken: number;
18
18
  };
19
19
  export type SkewPriceImpactResult = {
20
- priceImpactP: number;
20
+ basePriceImpactP: number;
21
+ tradePriceImpactP: number;
22
+ totalPriceImpactP: number;
21
23
  netSkewToken: number;
22
24
  netSkewCollateral: number;
23
25
  tradeDirection: "increase" | "decrease" | "neutral";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gainsnetwork/sdk",
3
- "version": "0.0.0-v10.rc22",
3
+ "version": "0.0.0-v10.rc24",
4
4
  "description": "Gains Network SDK",
5
5
  "main": "./lib/index.js",
6
6
  "files": [