@gainsnetwork/sdk 1.2.0 → 1.3.0-rc2

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.
Files changed (78) hide show
  1. package/lib/backend/tradingVariables/backend.types.d.ts +11 -4
  2. package/lib/backend/tradingVariables/converter.d.ts +7 -3
  3. package/lib/backend/tradingVariables/converter.js +14 -7
  4. package/lib/backend/tradingVariables/index.js +5 -2
  5. package/lib/backend/tradingVariables/types.d.ts +4 -2
  6. package/lib/contracts/addresses.d.ts +1 -1
  7. package/lib/contracts/addresses.js +5 -4
  8. package/lib/contracts/addresses.json +29 -0
  9. package/lib/contracts/types/generated/GNSBorrowingFeesV6_3_2.d.ts +979 -0
  10. package/lib/contracts/types/generated/GNSBorrowingFeesV6_3_2.js +2 -0
  11. package/lib/contracts/types/generated/GNSBorrowingFeesV6_4.d.ts +1058 -0
  12. package/lib/contracts/types/generated/GNSBorrowingFeesV6_4.js +2 -0
  13. package/lib/contracts/types/generated/GNSMultiCollatDiamond.d.ts +608 -299
  14. package/lib/contracts/types/generated/GNSPairInfosV6_1.d.ts +911 -0
  15. package/lib/contracts/types/generated/GNSPairInfosV6_1.js +2 -0
  16. package/lib/contracts/types/generated/GNSPairsStorageV6.d.ts +660 -0
  17. package/lib/contracts/types/generated/GNSPairsStorageV6.js +2 -0
  18. package/lib/contracts/types/generated/GNSTradingCallbacksV6_3_2.d.ts +806 -0
  19. package/lib/contracts/types/generated/GNSTradingCallbacksV6_3_2.js +2 -0
  20. package/lib/contracts/types/generated/GNSTradingCallbacksV6_4.d.ts +821 -0
  21. package/lib/contracts/types/generated/GNSTradingCallbacksV6_4.js +2 -0
  22. package/lib/contracts/types/generated/factories/GNSBorrowingFeesV6_3_2__factory.d.ts +88 -0
  23. package/lib/contracts/types/generated/factories/GNSBorrowingFeesV6_3_2__factory.js +1654 -0
  24. package/lib/contracts/types/generated/factories/GNSBorrowingFeesV6_4__factory.d.ts +113 -0
  25. package/lib/contracts/types/generated/factories/GNSBorrowingFeesV6_4__factory.js +1742 -0
  26. package/lib/contracts/types/generated/factories/GNSMultiCollatDiamond__factory.js +1933 -250
  27. package/lib/contracts/types/generated/factories/GNSPairInfosV6_1__factory.d.ts +98 -0
  28. package/lib/contracts/types/generated/factories/GNSPairInfosV6_1__factory.js +1485 -0
  29. package/lib/contracts/types/generated/factories/GNSPairsStorageV6__factory.d.ts +117 -0
  30. package/lib/contracts/types/generated/factories/GNSPairsStorageV6__factory.js +1265 -0
  31. package/lib/contracts/types/generated/factories/GNSTradingCallbacksV6_3_2__factory.d.ts +82 -0
  32. package/lib/contracts/types/generated/factories/GNSTradingCallbacksV6_3_2__factory.js +1273 -0
  33. package/lib/contracts/types/generated/factories/GNSTradingCallbacksV6_4__factory.d.ts +82 -0
  34. package/lib/contracts/types/generated/factories/GNSTradingCallbacksV6_4__factory.js +1326 -0
  35. package/lib/contracts/utils/pairs.d.ts +13 -2
  36. package/lib/contracts/utils/pairs.js +70 -11
  37. package/lib/index.d.ts +1 -0
  38. package/lib/index.js +1 -0
  39. package/lib/markets/oi/fetcher.d.ts +58 -0
  40. package/lib/markets/oi/fetcher.js +181 -0
  41. package/lib/markets/oi/validation.d.ts +80 -0
  42. package/lib/markets/oi/validation.js +172 -0
  43. package/lib/markets/price/signedPrices.d.ts +36 -0
  44. package/lib/markets/price/signedPrices.js +181 -0
  45. package/lib/pricing/depthBands/converter.d.ts +65 -0
  46. package/lib/pricing/depthBands/converter.js +155 -0
  47. package/lib/pricing/depthBands/decoder.d.ts +32 -0
  48. package/lib/pricing/depthBands/decoder.js +109 -0
  49. package/lib/pricing/depthBands/encoder.d.ts +19 -0
  50. package/lib/pricing/depthBands/encoder.js +105 -0
  51. package/lib/pricing/depthBands/index.d.ts +8 -0
  52. package/lib/pricing/depthBands/index.js +26 -0
  53. package/lib/pricing/depthBands/types.d.ts +49 -0
  54. package/lib/pricing/depthBands/types.js +10 -0
  55. package/lib/pricing/depthBands/validator.d.ts +22 -0
  56. package/lib/pricing/depthBands/validator.js +113 -0
  57. package/lib/pricing/depthBands.d.ts +39 -0
  58. package/lib/pricing/depthBands.js +92 -0
  59. package/lib/pricing/index.d.ts +4 -0
  60. package/lib/pricing/index.js +20 -0
  61. package/lib/trade/effectiveLeverage/builder.d.ts +23 -0
  62. package/lib/trade/effectiveLeverage/builder.js +30 -0
  63. package/lib/trade/fees/holdingFees/index.d.ts +46 -0
  64. package/lib/trade/fees/holdingFees/index.js +105 -0
  65. package/lib/trade/fees/holdingFees/types.d.ts +23 -0
  66. package/lib/trade/fees/holdingFees/types.js +5 -0
  67. package/lib/trade/fees/trading/holdingFees.d.ts +28 -0
  68. package/lib/trade/fees/trading/holdingFees.js +66 -0
  69. package/lib/trade/fees/trading/holdingFeesStructured.d.ts +28 -0
  70. package/lib/trade/fees/trading/holdingFeesStructured.js +66 -0
  71. package/lib/trade/priceImpact/cumulVol/builder.js +2 -2
  72. package/lib/trade/priceImpact/cumulVol/converter.d.ts +63 -0
  73. package/lib/trade/priceImpact/cumulVol/converter.js +97 -1
  74. package/lib/trade/priceImpact/cumulVol/index.d.ts +3 -1
  75. package/lib/trade/priceImpact/cumulVol/index.js +104 -22
  76. package/lib/trade/priceImpact/cumulVol/types.d.ts +11 -0
  77. package/lib/trade/priceImpact/cumulVol/types.js +2 -0
  78. package/package.json +1 -1
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ /**
3
+ * @dev Holding fees calculation for structured contexts
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getTradePendingHoldingFeesCollateralStructured = void 0;
7
+ const types_1 = require("../../../contracts/types");
8
+ const borrowing_1 = require("../borrowing");
9
+ const borrowingV2_1 = require("../borrowingV2");
10
+ const pairContext_1 = require("../fundingFees/pairContext");
11
+ /**
12
+ * @dev Calculates total holding fees using structured context
13
+ * @param trade The trade to calculate fees for
14
+ * @param tradeInfo Trade info containing contracts version
15
+ * @param tradeFeesData Trade fees data containing initial acc fees
16
+ * @param currentPairPrice Current pair price
17
+ * @param context Structured context with sub-contexts for each fee type
18
+ * @returns Object containing all holding fee components
19
+ */
20
+ const getTradePendingHoldingFeesCollateralStructured = (trade, tradeInfo, tradeFeesData, currentPairPrice, context) => {
21
+ const positionSizeCollateral = trade.collateralAmount * trade.leverage;
22
+ // Calculate funding fees (v10+ only)
23
+ let fundingFeeCollateral = 0;
24
+ if (context.contractsVersion >= types_1.ContractsVersion.V10 &&
25
+ context.funding &&
26
+ tradeFeesData.initialAccFundingFeeP !== undefined) {
27
+ fundingFeeCollateral = (0, pairContext_1.getPairTradeFundingFeesCollateral)({
28
+ positionSizeCollateral,
29
+ openPrice: trade.openPrice,
30
+ long: trade.long,
31
+ currentPairPrice,
32
+ initialAccFundingFeeP: tradeFeesData.initialAccFundingFeeP,
33
+ }, context.funding // TODO: Fix types once funding types are properly imported
34
+ );
35
+ }
36
+ // Calculate borrowing fees v2
37
+ let borrowingFeeCollateral = 0;
38
+ if (context.borrowingV2 && tradeFeesData.initialAccBorrowingFeeP !== undefined) {
39
+ borrowingFeeCollateral = (0, borrowingV2_1.getPairTradeBorrowingFeesCollateral)({
40
+ positionSizeCollateral,
41
+ openPrice: trade.openPrice,
42
+ currentPairPrice,
43
+ initialAccBorrowingFeeP: tradeFeesData.initialAccBorrowingFeeP,
44
+ currentTimestamp: context.currentTimestamp,
45
+ }, context.borrowingV2);
46
+ }
47
+ // Calculate v1 borrowing fees (some markets use v1 indefinitely)
48
+ let borrowingFeeCollateral_old = 0;
49
+ if (context.borrowingV1) {
50
+ borrowingFeeCollateral_old = (0, borrowing_1.getPairBorrowingFee)(positionSizeCollateral, trade.long, context.borrowingV1.initialAccFees || { accPairFee: 0, accGroupFee: 0, block: 0 }, {
51
+ currentBlock: context.borrowingV1.currentBlock,
52
+ group: context.borrowingV1.group,
53
+ pair: context.borrowingV1.pair,
54
+ collateralPriceUsd: context.collateralPriceUsd,
55
+ });
56
+ }
57
+ return {
58
+ fundingFeeCollateral,
59
+ borrowingFeeCollateral,
60
+ borrowingFeeCollateral_old,
61
+ totalFeeCollateral: fundingFeeCollateral +
62
+ borrowingFeeCollateral +
63
+ borrowingFeeCollateral_old,
64
+ };
65
+ };
66
+ exports.getTradePendingHoldingFeesCollateralStructured = getTradePendingHoldingFeesCollateralStructured;
@@ -0,0 +1,28 @@
1
+ /**
2
+ * @dev Holding fees calculation for structured contexts
3
+ */
4
+ import { Trade, TradeInfo, TradeFeesData } from "../../types";
5
+ import { TradeHoldingFees } from "./types";
6
+ import { ContractsVersion } from "../../../contracts/types";
7
+ import type { BorrowingV1SubContext, BorrowingV2SubContext, FundingFeesSubContext } from "../../pnl";
8
+ /**
9
+ * @dev Context for holding fees calculation with structured sub-contexts
10
+ */
11
+ export type GetStructuredHoldingFeesContext = {
12
+ contractsVersion: ContractsVersion;
13
+ currentTimestamp: number;
14
+ collateralPriceUsd: number;
15
+ borrowingV1?: BorrowingV1SubContext;
16
+ borrowingV2?: BorrowingV2SubContext;
17
+ funding?: FundingFeesSubContext;
18
+ };
19
+ /**
20
+ * @dev Calculates total holding fees using structured context
21
+ * @param trade The trade to calculate fees for
22
+ * @param tradeInfo Trade info containing contracts version
23
+ * @param tradeFeesData Trade fees data containing initial acc fees
24
+ * @param currentPairPrice Current pair price
25
+ * @param context Structured context with sub-contexts for each fee type
26
+ * @returns Object containing all holding fee components
27
+ */
28
+ export declare const getTradePendingHoldingFeesCollateralStructured: (trade: Trade, tradeInfo: TradeInfo, tradeFeesData: TradeFeesData, currentPairPrice: number, context: GetStructuredHoldingFeesContext) => TradeHoldingFees;
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ /**
3
+ * @dev Holding fees calculation for structured contexts
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getTradePendingHoldingFeesCollateralStructured = void 0;
7
+ const types_1 = require("../../../contracts/types");
8
+ const borrowing_1 = require("../borrowing");
9
+ const borrowingV2_1 = require("../borrowingV2");
10
+ const fundingFees_1 = require("../fundingFees");
11
+ /**
12
+ * @dev Calculates total holding fees using structured context
13
+ * @param trade The trade to calculate fees for
14
+ * @param tradeInfo Trade info containing contracts version
15
+ * @param tradeFeesData Trade fees data containing initial acc fees
16
+ * @param currentPairPrice Current pair price
17
+ * @param context Structured context with sub-contexts for each fee type
18
+ * @returns Object containing all holding fee components
19
+ */
20
+ const getTradePendingHoldingFeesCollateralStructured = (trade, tradeInfo, tradeFeesData, currentPairPrice, context) => {
21
+ const positionSizeCollateral = trade.collateralAmount * trade.leverage;
22
+ // Calculate funding fees (v10+ only)
23
+ let fundingFeeCollateral = 0;
24
+ if (context.contractsVersion >= types_1.ContractsVersion.V10 &&
25
+ context.funding &&
26
+ tradeFeesData.initialAccFundingFeeP !== undefined) {
27
+ fundingFeeCollateral = (0, fundingFees_1.getTradeFundingFeesCollateral)(trade, tradeInfo, tradeFeesData, currentPairPrice, Object.assign(Object.assign({}, context.funding), { currentTimestamp: context.currentTimestamp }) // TODO: Fix types once funding types are properly imported
28
+ );
29
+ }
30
+ // Calculate borrowing fees v2
31
+ let borrowingFeeCollateral = 0;
32
+ if (context.borrowingV2 &&
33
+ tradeFeesData.initialAccBorrowingFeeP !== undefined) {
34
+ borrowingFeeCollateral = (0, borrowingV2_1.getTradeBorrowingFeesCollateral)({
35
+ positionSizeCollateral,
36
+ openPrice: trade.openPrice,
37
+ currentPairPrice,
38
+ initialAccBorrowingFeeP: tradeFeesData.initialAccBorrowingFeeP,
39
+ currentTimestamp: context.currentTimestamp,
40
+ }, context.borrowingV2);
41
+ }
42
+ // Calculate v1 borrowing fees (some markets use v1 indefinitely)
43
+ let borrowingFeeCollateral_old = 0;
44
+ if (context.borrowingV1) {
45
+ borrowingFeeCollateral_old = (0, borrowing_1.getBorrowingFee)(positionSizeCollateral, undefined, // pairIndex not needed for pair-specific context
46
+ trade.long, context.borrowingV1.initialAccFees || {
47
+ accPairFee: 0,
48
+ accGroupFee: 0,
49
+ block: 0,
50
+ }, {
51
+ currentBlock: context.borrowingV1.currentBlock,
52
+ group: context.borrowingV1.group,
53
+ pair: context.borrowingV1.pair,
54
+ collateralPriceUsd: context.collateralPriceUsd,
55
+ });
56
+ }
57
+ return {
58
+ fundingFeeCollateral,
59
+ borrowingFeeCollateral,
60
+ borrowingFeeCollateral_old,
61
+ totalFeeCollateral: fundingFeeCollateral +
62
+ borrowingFeeCollateral +
63
+ borrowingFeeCollateral_old,
64
+ };
65
+ };
66
+ exports.getTradePendingHoldingFeesCollateralStructured = getTradePendingHoldingFeesCollateralStructured;
@@ -16,7 +16,7 @@ const buildCumulVolContext = (globalTradingVariables, collateralIndex, pairIndex
16
16
  return undefined;
17
17
  }
18
18
  // Get pair-specific data from global variables
19
- const pairDepth = (_a = globalTradingVariables.pairDepths) === null || _a === void 0 ? void 0 : _a[pairIndex];
19
+ const pairDepthBands = (_a = globalTradingVariables.pairDepthBands) === null || _a === void 0 ? void 0 : _a[pairIndex];
20
20
  const pairFactor = (_b = globalTradingVariables.pairFactors) === null || _b === void 0 ? void 0 : _b[pairIndex];
21
21
  const oiWindows = (_c = globalTradingVariables.oiWindows) === null || _c === void 0 ? void 0 : _c[pairIndex];
22
22
  // Get OI windows settings (same for all pairs)
@@ -34,7 +34,7 @@ const buildCumulVolContext = (globalTradingVariables, collateralIndex, pairIndex
34
34
  // Protection factors
35
35
  liquidationParams, currentBlock: additionalParams.currentBlock, contractsVersion: additionalParams.contractsVersion, protectionCloseFactorWhitelist,
36
36
  // Price impact data
37
- pairDepth,
37
+ pairDepthBands,
38
38
  oiWindowsSettings,
39
39
  oiWindows,
40
40
  // User/collateral specific
@@ -4,6 +4,7 @@
4
4
  */
5
5
  import { IPriceImpact } from "../../../contracts/types/generated/GNSMultiCollatDiamond";
6
6
  import { OiWindowsSettings, OiWindow, OiWindows } from "../../types";
7
+ import { DepthBands, PairDepthBands, DepthBandsMapping } from "./types";
7
8
  /**
8
9
  * @dev Converts contract OI windows settings to SDK format
9
10
  * @param contractData Contract OiWindowsSettings struct
@@ -29,3 +30,65 @@ export declare const convertOiWindows: (windowIds: string[], contractWindows: IP
29
30
  * @returns Array of normalized OI windows settings
30
31
  */
31
32
  export declare const convertOiWindowsSettingsArray: (contractDataArray: IPriceImpact.OiWindowsSettingsStructOutput[]) => OiWindowsSettings[];
33
+ /**
34
+ * @dev Converts decoded depth bands from contract to SDK format
35
+ * @param totalDepthUsd Total depth in USD (already decoded from contract)
36
+ * @param bandsBps Array of 30 band percentages in basis points from contract
37
+ * @returns Normalized depth bands with bands in 0-1 range
38
+ */
39
+ export declare const convertDepthBands: (totalDepthUsd: number, bandsBps: number[]) => DepthBands;
40
+ /**
41
+ * @dev Converts decoded pair depth bands from contract to SDK format
42
+ * @param aboveDepth Decoded above depth bands from getPairDepthBandsDecoded
43
+ * @param belowDepth Decoded below depth bands from getPairDepthBandsDecoded
44
+ * @returns Normalized pair depth bands with above/below
45
+ */
46
+ export declare const convertPairDepthBands: (aboveDepth: {
47
+ totalDepthUsd: number;
48
+ bands: number[];
49
+ } | undefined, belowDepth: {
50
+ totalDepthUsd: number;
51
+ bands: number[];
52
+ } | undefined) => PairDepthBands;
53
+ /**
54
+ * @dev Converts decoded depth bands mapping from contract to SDK format
55
+ * @param bandsBps Array of 30 band offset values in basis points from getDepthBandsMappingDecoded
56
+ * @returns Normalized depth bands mapping with offset values in 0-1 range
57
+ */
58
+ export declare const convertDepthBandsMapping: (bandsBps: number[]) => DepthBandsMapping;
59
+ /**
60
+ * @dev Validates depth bands have correct number of bands
61
+ * @param depthBands Depth bands to validate
62
+ * @returns True if valid (30 bands)
63
+ */
64
+ export declare const validateDepthBands: (depthBands: DepthBands) => boolean;
65
+ /**
66
+ * @dev Validates depth bands mapping has correct number of bands
67
+ * @param mapping Depth bands mapping to validate
68
+ * @returns True if valid (30 bands)
69
+ */
70
+ export declare const validateDepthBandsMapping: (mapping: DepthBandsMapping) => boolean;
71
+ /**
72
+ * @dev Alternative converter for decoded pair depth bands from contract
73
+ * @param contractData Decoded pair depth bands from getPairDepthBandsDecoded
74
+ * @returns Normalized pair depth bands
75
+ */
76
+ export declare const convertPairDepthBandsDecoded: (contractData: {
77
+ above: {
78
+ totalDepthUsd: number;
79
+ bands: number[];
80
+ };
81
+ below: {
82
+ totalDepthUsd: number;
83
+ bands: number[];
84
+ };
85
+ }) => PairDepthBands;
86
+ /**
87
+ * @dev Alternative converter for raw slot-based pair depth bands (if needed for legacy)
88
+ * @param aboveSlot1 First slot for above bands
89
+ * @param aboveSlot2 Second slot for above bands
90
+ * @param belowSlot1 First slot for below bands
91
+ * @param belowSlot2 Second slot for below bands
92
+ * @returns Normalized pair depth bands
93
+ */
94
+ export declare const convertPairDepthBandsFromSlots: (aboveSlot1: bigint, aboveSlot2: bigint, belowSlot1: bigint, belowSlot2: bigint) => PairDepthBands;
@@ -4,7 +4,8 @@
4
4
  * @dev All BigNumber values are normalized to floats with appropriate precision
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.convertOiWindowsSettingsArray = exports.convertOiWindows = exports.convertOiWindow = exports.convertOiWindowsSettings = void 0;
7
+ exports.convertPairDepthBandsFromSlots = exports.convertPairDepthBandsDecoded = exports.validateDepthBandsMapping = exports.validateDepthBands = exports.convertDepthBandsMapping = exports.convertPairDepthBands = exports.convertDepthBands = exports.convertOiWindowsSettingsArray = exports.convertOiWindows = exports.convertOiWindow = exports.convertOiWindowsSettings = void 0;
8
+ const depthBands_1 = require("../../../pricing/depthBands");
8
9
  /**
9
10
  * @dev Converts contract OI windows settings to SDK format
10
11
  * @param contractData Contract OiWindowsSettings struct
@@ -57,3 +58,98 @@ const convertOiWindowsSettingsArray = (contractDataArray) => {
57
58
  return contractDataArray.map(exports.convertOiWindowsSettings);
58
59
  };
59
60
  exports.convertOiWindowsSettingsArray = convertOiWindowsSettingsArray;
61
+ /**
62
+ * @dev Converts decoded depth bands from contract to SDK format
63
+ * @param totalDepthUsd Total depth in USD (already decoded from contract)
64
+ * @param bandsBps Array of 30 band percentages in basis points from contract
65
+ * @returns Normalized depth bands with bands in 0-1 range
66
+ */
67
+ const convertDepthBands = (totalDepthUsd, bandsBps) => {
68
+ // Convert bands from basis points to 0-1 range
69
+ const bands = bandsBps.map(bps => bps / 10000);
70
+ return {
71
+ totalDepthUsd,
72
+ bands,
73
+ };
74
+ };
75
+ exports.convertDepthBands = convertDepthBands;
76
+ /**
77
+ * @dev Converts decoded pair depth bands from contract to SDK format
78
+ * @param aboveDepth Decoded above depth bands from getPairDepthBandsDecoded
79
+ * @param belowDepth Decoded below depth bands from getPairDepthBandsDecoded
80
+ * @returns Normalized pair depth bands with above/below
81
+ */
82
+ const convertPairDepthBands = (aboveDepth, belowDepth) => {
83
+ // Convert above bands if configured
84
+ const above = aboveDepth && aboveDepth.totalDepthUsd > 0
85
+ ? (0, exports.convertDepthBands)(aboveDepth.totalDepthUsd, aboveDepth.bands)
86
+ : undefined;
87
+ // Convert below bands if configured
88
+ const below = belowDepth && belowDepth.totalDepthUsd > 0
89
+ ? (0, exports.convertDepthBands)(belowDepth.totalDepthUsd, belowDepth.bands)
90
+ : undefined;
91
+ return {
92
+ above,
93
+ below,
94
+ };
95
+ };
96
+ exports.convertPairDepthBands = convertPairDepthBands;
97
+ /**
98
+ * @dev Converts decoded depth bands mapping from contract to SDK format
99
+ * @param bandsBps Array of 30 band offset values in basis points from getDepthBandsMappingDecoded
100
+ * @returns Normalized depth bands mapping with offset values in 0-1 range
101
+ */
102
+ const convertDepthBandsMapping = (bandsBps) => {
103
+ // Convert bands from basis points to 0-1 range
104
+ const bands = bandsBps.map(bps => bps / 10000);
105
+ return {
106
+ bands,
107
+ };
108
+ };
109
+ exports.convertDepthBandsMapping = convertDepthBandsMapping;
110
+ /**
111
+ * @dev Validates depth bands have correct number of bands
112
+ * @param depthBands Depth bands to validate
113
+ * @returns True if valid (30 bands)
114
+ */
115
+ const validateDepthBands = (depthBands) => {
116
+ return depthBands.bands.length === 30;
117
+ };
118
+ exports.validateDepthBands = validateDepthBands;
119
+ /**
120
+ * @dev Validates depth bands mapping has correct number of bands
121
+ * @param mapping Depth bands mapping to validate
122
+ * @returns True if valid (30 bands)
123
+ */
124
+ const validateDepthBandsMapping = (mapping) => {
125
+ return mapping.bands.length === 30;
126
+ };
127
+ exports.validateDepthBandsMapping = validateDepthBandsMapping;
128
+ /**
129
+ * @dev Alternative converter for decoded pair depth bands from contract
130
+ * @param contractData Decoded pair depth bands from getPairDepthBandsDecoded
131
+ * @returns Normalized pair depth bands
132
+ */
133
+ const convertPairDepthBandsDecoded = (contractData) => {
134
+ return (0, exports.convertPairDepthBands)(contractData.above, contractData.below);
135
+ };
136
+ exports.convertPairDepthBandsDecoded = convertPairDepthBandsDecoded;
137
+ /**
138
+ * @dev Alternative converter for raw slot-based pair depth bands (if needed for legacy)
139
+ * @param aboveSlot1 First slot for above bands
140
+ * @param aboveSlot2 Second slot for above bands
141
+ * @param belowSlot1 First slot for below bands
142
+ * @param belowSlot2 Second slot for below bands
143
+ * @returns Normalized pair depth bands
144
+ */
145
+ const convertPairDepthBandsFromSlots = (aboveSlot1, aboveSlot2, belowSlot1, belowSlot2) => {
146
+ // Use the decoding functions from pricing module if raw slots are provided
147
+ const above = aboveSlot1 !== BigInt(0) || aboveSlot2 !== BigInt(0)
148
+ ? (0, depthBands_1.decodeDepthBands)(aboveSlot1, aboveSlot2)
149
+ : undefined;
150
+ const below = belowSlot1 !== BigInt(0) || belowSlot2 !== BigInt(0)
151
+ ? (0, depthBands_1.decodeDepthBands)(belowSlot1, belowSlot2)
152
+ : undefined;
153
+ return (0, exports.convertPairDepthBands)(above, below);
154
+ };
155
+ exports.convertPairDepthBandsFromSlots = convertPairDepthBandsFromSlots;
@@ -2,6 +2,7 @@
2
2
  * @dev Cumulative volume price impact calculations
3
3
  * @dev Mirrors contract's getTradeCumulVolPriceImpactP functionality
4
4
  */
5
+ import { PairDepthBands, DepthBandsMapping } from "./types";
5
6
  import { LiquidationParams, OiWindows, OiWindowsSettings, PairDepth, PairFactor, UserPriceImpact } from "../../types";
6
7
  import { ContractsVersion } from "../../../contracts/types";
7
8
  export type CumulVolContext = {
@@ -12,9 +13,10 @@ export type CumulVolContext = {
12
13
  currentBlock?: number | undefined;
13
14
  contractsVersion?: ContractsVersion | undefined;
14
15
  protectionCloseFactorWhitelist?: boolean;
15
- pairDepth?: PairDepth | undefined;
16
16
  oiWindowsSettings?: OiWindowsSettings | undefined;
17
17
  oiWindows?: OiWindows | undefined;
18
+ pairDepthBands?: PairDepthBands | undefined;
19
+ depthBandsMapping?: DepthBandsMapping | undefined;
18
20
  userPriceImpact?: UserPriceImpact | undefined;
19
21
  collateralPriceUsd?: number;
20
22
  } & Partial<PairFactor>;
@@ -74,6 +74,89 @@ const getLegacyFactor = (context) => {
74
74
  return (context === null || context === void 0 ? void 0 : context.contractsVersion) === types_1.ContractsVersion.BEFORE_V9_2 ? 1 : 2;
75
75
  };
76
76
  exports.getLegacyFactor = getLegacyFactor;
77
+ /**
78
+ * @dev Mirrors contract's _calculateDepthBandsPriceImpact function
79
+ * @param tradeSizeUsd Trade size in USD (always positive here)
80
+ * @param depthBandParams Depth band parameters
81
+ * @returns Price impact percentage
82
+ */
83
+ const _calculateDepthBandsPriceImpact = (tradeSizeUsd, depthBandParams) => {
84
+ const totalDepthUsd = depthBandParams.depthBands.totalDepthUsd;
85
+ if (totalDepthUsd === 0 || tradeSizeUsd === 0)
86
+ return 0;
87
+ let remainingSizeUsd = tradeSizeUsd;
88
+ let totalWeightedPriceImpactP = 0;
89
+ let prevBandDepthUsd = 0;
90
+ let topOfPrevBandOffsetPpm = 0;
91
+ for (let i = 0; i < 30 && remainingSizeUsd !== 0; i++) {
92
+ const bandLiquidityPercentageBps = depthBandParams.depthBands.bands[i]; // Already in 0-1 format
93
+ const topOfBandOffsetPpm = depthBandParams.depthBandsMapping.bands[i]; // Already in 0-1 format
94
+ const bandDepthUsd = bandLiquidityPercentageBps * totalDepthUsd;
95
+ // Skip if band has same depth as previous (would cause division by zero)
96
+ if (bandDepthUsd <= prevBandDepthUsd) {
97
+ prevBandDepthUsd = bandDepthUsd;
98
+ topOfPrevBandOffsetPpm = topOfBandOffsetPpm;
99
+ continue;
100
+ }
101
+ // Since bandDepthUsd represents liquidity from mid price to top of band, we need to subtract previous band depth
102
+ const bandAvailableDepthUsd = bandDepthUsd - prevBandDepthUsd;
103
+ let depthConsumedUsd;
104
+ // At 100% band always consume all remaining size, even if more than band available depth
105
+ if (bandLiquidityPercentageBps === 1 ||
106
+ remainingSizeUsd <= bandAvailableDepthUsd) {
107
+ depthConsumedUsd = remainingSizeUsd;
108
+ remainingSizeUsd = 0;
109
+ }
110
+ else {
111
+ // Normal case: consume entire band and continue to next
112
+ depthConsumedUsd = bandAvailableDepthUsd;
113
+ remainingSizeUsd -= bandAvailableDepthUsd;
114
+ }
115
+ // Calculate impact contribution from this band using trapezoidal rule
116
+ // Low = previous band's price offset, High = current band's price offset
117
+ const lowOffsetP = topOfPrevBandOffsetPpm;
118
+ const offsetRangeP = topOfBandOffsetPpm - topOfPrevBandOffsetPpm;
119
+ // Calculate average impact using trapezoidal rule: low + (range * fraction / 2)
120
+ const avgImpactP = lowOffsetP +
121
+ (offsetRangeP * depthConsumedUsd) / bandAvailableDepthUsd / 2;
122
+ totalWeightedPriceImpactP += avgImpactP * depthConsumedUsd;
123
+ // Update previous values for next iteration
124
+ topOfPrevBandOffsetPpm = topOfBandOffsetPpm;
125
+ prevBandDepthUsd = bandDepthUsd;
126
+ }
127
+ return totalWeightedPriceImpactP / tradeSizeUsd;
128
+ };
129
+ /**
130
+ * @dev Mirrors contract's _getDepthBandsPriceImpactP function
131
+ * @param cumulativeVolumeUsd Cumulative volume in USD (can be negative)
132
+ * @param tradeSizeUsd Trade size in USD (can be negative)
133
+ * @param depthBandParams Depth band parameters (contains both pair bands and global mapping)
134
+ * @param priceImpactFactor Price impact factor (protection close factor)
135
+ * @param cumulativeFactor Cumulative factor for volume impact
136
+ * @returns Price impact percentage (can be negative)
137
+ */
138
+ const _getDepthBandsPriceImpactP = (cumulativeVolumeUsd, tradeSizeUsd, depthBandParams, priceImpactFactor, cumulativeFactor) => {
139
+ // Check for opposite signs (would revert in contract)
140
+ if ((cumulativeVolumeUsd > 0 && tradeSizeUsd < 0) ||
141
+ (cumulativeVolumeUsd < 0 && tradeSizeUsd > 0)) {
142
+ throw new Error("Wrong params: cumulative volume and trade size have opposite signs");
143
+ }
144
+ const effectiveCumulativeVolumeUsd = cumulativeVolumeUsd * cumulativeFactor;
145
+ const totalSizeLookupUsd = effectiveCumulativeVolumeUsd + tradeSizeUsd;
146
+ const isNegative = totalSizeLookupUsd < 0;
147
+ const effectiveCumulativeVolumeUsdUint = isNegative
148
+ ? -effectiveCumulativeVolumeUsd
149
+ : effectiveCumulativeVolumeUsd;
150
+ const totalSizeLookupUsdUint = isNegative
151
+ ? -totalSizeLookupUsd
152
+ : totalSizeLookupUsd;
153
+ const cumulativeVolPriceImpactP = _calculateDepthBandsPriceImpact(effectiveCumulativeVolumeUsdUint, depthBandParams);
154
+ const totalSizePriceImpactP = _calculateDepthBandsPriceImpact(totalSizeLookupUsdUint, depthBandParams);
155
+ const unscaledPriceImpactP = cumulativeVolPriceImpactP +
156
+ (totalSizePriceImpactP - cumulativeVolPriceImpactP) / 2;
157
+ const scaledPriceImpactP = unscaledPriceImpactP * priceImpactFactor;
158
+ return isNegative ? -scaledPriceImpactP : scaledPriceImpactP;
159
+ };
77
160
  /**
78
161
  * @dev Calculates cumulative volume price impact percentage
79
162
  * @dev Mirrors contract's getTradeCumulVolPriceImpactP function
@@ -88,7 +171,6 @@ exports.getLegacyFactor = getLegacyFactor;
88
171
  * @returns Cumulative volume price impact percentage (not including spread)
89
172
  */
90
173
  const getTradeCumulVolPriceImpactP = (trader, pairIndex, long, tradeOpenInterestUsd, isPnlPositive, open, lastPosIncreaseBlock, context) => {
91
- var _a, _b;
92
174
  // Update context with passed parameters
93
175
  const updatedContext = Object.assign(Object.assign({}, context), { isOpen: open, isPnlPositive: isPnlPositive, createdBlock: context.createdBlock || lastPosIncreaseBlock });
94
176
  if (
@@ -103,32 +185,33 @@ const getTradeCumulVolPriceImpactP = (trader, pairIndex, long, tradeOpenInterest
103
185
  (0, exports.isProtectionCloseFactorActive)(updatedContext) !== true)) {
104
186
  return 0;
105
187
  }
106
- // Calculate trade skew direction (matches Solidity logic)
107
188
  const tradePositiveSkew = (long && open) || (!long && !open);
108
189
  const tradeSkewMultiplier = tradePositiveSkew ? 1 : -1;
109
- // Select depth based on trade direction
110
- // For positive skew (long open or short close), use depth above
111
- // For negative skew (short open or long close), use depth below
112
- const onePercentDepth = tradePositiveSkew
113
- ? (_a = context.pairDepth) === null || _a === void 0 ? void 0 : _a.onePercentDepthAboveUsd
114
- : (_b = context.pairDepth) === null || _b === void 0 ? void 0 : _b.onePercentDepthBelowUsd;
115
- let activeOi = undefined;
116
- if (context.oiWindowsSettings !== undefined) {
117
- activeOi = (0, oiWindows_1.getActiveOi)((0, oiWindows_1.getCurrentOiWindowId)(context.oiWindowsSettings), context.oiWindowsSettings.windowsCount, context.oiWindows, open ? long : !long);
190
+ if (!context.pairDepthBands || !context.depthBandsMapping) {
191
+ return 0;
118
192
  }
119
- if (!onePercentDepth || activeOi === undefined) {
193
+ // Select depth bands based on trade direction
194
+ const depthBands = tradePositiveSkew
195
+ ? context.pairDepthBands.above
196
+ : context.pairDepthBands.below;
197
+ // Return 0 if no depth bands configured (matching contract lines 588-590)
198
+ if (!depthBands || depthBands.totalDepthUsd === 0) {
120
199
  return 0;
121
200
  }
122
- // Apply trade skew multiplier to match Solidity's signed calculation
201
+ // Get active OI for cumulative volume calculation
202
+ let activeOi = 0;
203
+ if (context.oiWindowsSettings !== undefined) {
204
+ activeOi =
205
+ (0, oiWindows_1.getActiveOi)((0, oiWindows_1.getCurrentOiWindowId)(context.oiWindowsSettings), context.oiWindowsSettings.windowsCount, context.oiWindows, open ? long : !long) || 0;
206
+ }
123
207
  const signedActiveOi = activeOi * tradeSkewMultiplier;
124
208
  const signedTradeOi = tradeOpenInterestUsd * tradeSkewMultiplier;
125
- // Calculate impact with proper signs (matching Solidity's _getTradePriceImpactP)
126
- const finalPriceImpactP = ((signedActiveOi * (0, exports.getCumulativeFactor)(updatedContext) +
127
- signedTradeOi / 2) /
128
- onePercentDepth /
129
- (0, exports.getLegacyFactor)(updatedContext)) *
130
- (0, exports.getProtectionCloseFactor)(updatedContext);
131
- return finalPriceImpactP;
209
+ // Calculate price impact using depth bands
210
+ const priceImpactP = _getDepthBandsPriceImpactP(signedActiveOi, signedTradeOi, {
211
+ depthBands: depthBands,
212
+ depthBandsMapping: context.depthBandsMapping,
213
+ }, (0, exports.getProtectionCloseFactor)(updatedContext), (0, exports.getCumulativeFactor)(updatedContext));
214
+ return priceImpactP;
132
215
  };
133
216
  exports.getTradeCumulVolPriceImpactP = getTradeCumulVolPriceImpactP;
134
217
  /**
@@ -195,8 +278,7 @@ const getSpreadWithCumulVolPriceImpactP = (pairSpreadP, buy, collateral, leverag
195
278
  const positionSizeUsd = collateral * leverage * ((context === null || context === void 0 ? void 0 : context.collateralPriceUsd) || 1);
196
279
  const cumulVolImpact = (0, exports.getTradeCumulVolPriceImpactP)("", // trader - not used in calculation
197
280
  0, // pairIndex - not used in calculation
198
- buy, positionSizeUsd, (context === null || context === void 0 ? void 0 : context.isPnlPositive) || false, (context === null || context === void 0 ? void 0 : context.isOpen) !== false, (context === null || context === void 0 ? void 0 : context.createdBlock) || 0, Object.assign(Object.assign({}, context), { pairDepth,
199
- oiWindowsSettings,
281
+ buy, positionSizeUsd, (context === null || context === void 0 ? void 0 : context.isPnlPositive) || false, (context === null || context === void 0 ? void 0 : context.isOpen) !== false, (context === null || context === void 0 ? void 0 : context.createdBlock) || 0, Object.assign(Object.assign({}, context), { oiWindowsSettings,
200
282
  oiWindows }));
201
283
  // If no depth or OI data, return just half spread
202
284
  if (cumulVolImpact === 0 && (!pairDepth || !oiWindowsSettings)) {
@@ -0,0 +1,11 @@
1
+ export type DepthBands = {
2
+ totalDepthUsd: number;
3
+ bands: number[];
4
+ };
5
+ export type PairDepthBands = {
6
+ above: DepthBands | undefined;
7
+ below: DepthBands | undefined;
8
+ };
9
+ export type DepthBandsMapping = {
10
+ bands: number[];
11
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gainsnetwork/sdk",
3
- "version": "1.2.0",
3
+ "version": "1.3.0-rc2",
4
4
  "description": "Gains Network SDK",
5
5
  "main": "./lib/index.js",
6
6
  "files": [