@d8x/perpetuals-sdk 0.1.12 → 0.2.0

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 (165) hide show
  1. package/dist/cjs/abi/testnet/IPerpetualManager.json +5215 -0
  2. package/dist/cjs/abi/testnet/LimitOrderBook.json +1075 -0
  3. package/dist/cjs/abi/zkevmTestnet/IPerpetualManager.json +5215 -0
  4. package/dist/cjs/abi/zkevmTestnet/LimitOrderBook.json +1075 -0
  5. package/dist/cjs/abi/zkevmTestnet/LimitOrderBookFactory.json +135 -0
  6. package/dist/cjs/accountTrade.js +441 -0
  7. package/dist/cjs/accountTrade.js.map +1 -0
  8. package/dist/{src → cjs}/brokerTool.js +31 -84
  9. package/dist/cjs/brokerTool.js.map +1 -0
  10. package/dist/cjs/config/defaultConfig.json +47 -0
  11. package/dist/cjs/config/mockSwap.json +4 -0
  12. package/dist/cjs/config/priceFeedConfig.json +104 -0
  13. package/dist/cjs/config/symbolList.json +13 -0
  14. package/dist/cjs/d8XMath.js.map +1 -0
  15. package/dist/cjs/index.js +29 -0
  16. package/dist/cjs/index.js.map +1 -0
  17. package/dist/cjs/liquidatorTool.js +287 -0
  18. package/dist/cjs/liquidatorTool.js.map +1 -0
  19. package/dist/{src → cjs}/liquidityProviderTool.js +12 -65
  20. package/dist/cjs/liquidityProviderTool.js.map +1 -0
  21. package/dist/{src → cjs}/marketData.js +52 -134
  22. package/dist/cjs/marketData.js.map +1 -0
  23. package/dist/{src → cjs}/nodeSDKTypes.d.ts +5 -5
  24. package/dist/cjs/nodeSDKTypes.js +64 -0
  25. package/dist/cjs/nodeSDKTypes.js.map +1 -0
  26. package/dist/{src → cjs}/orderReferrerTool.d.ts +12 -5
  27. package/dist/{src → cjs}/orderReferrerTool.js +114 -112
  28. package/dist/cjs/orderReferrerTool.js.map +1 -0
  29. package/dist/{src → cjs}/perpetualDataHandler.d.ts +1 -1
  30. package/dist/{src → cjs}/perpetualDataHandler.js +47 -109
  31. package/dist/cjs/perpetualDataHandler.js.map +1 -0
  32. package/dist/{src → cjs}/perpetualEventHandler.d.ts +3 -3
  33. package/dist/{src → cjs}/perpetualEventHandler.js +12 -74
  34. package/dist/cjs/perpetualEventHandler.js.map +1 -0
  35. package/dist/cjs/priceFeeds.js +466 -0
  36. package/dist/cjs/priceFeeds.js.map +1 -0
  37. package/dist/{src → cjs}/traderDigests.js +7 -43
  38. package/dist/cjs/traderDigests.js.map +1 -0
  39. package/dist/{src → cjs}/traderInterface.js +13 -66
  40. package/dist/cjs/traderInterface.js.map +1 -0
  41. package/dist/{src → cjs}/triangulator.js +2 -17
  42. package/dist/cjs/triangulator.js.map +1 -0
  43. package/dist/{src → cjs}/utils.js +3 -29
  44. package/dist/cjs/utils.js.map +1 -0
  45. package/dist/cjs/version.d.ts +1 -0
  46. package/dist/{src → cjs}/version.js +1 -1
  47. package/dist/cjs/version.js.map +1 -0
  48. package/dist/{src → cjs}/writeAccessHandler.js +12 -65
  49. package/dist/cjs/writeAccessHandler.js.map +1 -0
  50. package/dist/esm/abi/ERC20.json +288 -0
  51. package/dist/esm/abi/MockTokenSwap.json +186 -0
  52. package/dist/{abi/testnet → esm/abi/central-park}/IPerpetualManager.json +404 -214
  53. package/dist/{abi/testnet → esm/abi/central-park}/LimitOrderBook.json +197 -15
  54. package/dist/esm/abi/central-park/LimitOrderBookFactory.json +135 -0
  55. package/dist/esm/abi/testnet/IPerpetualManager.json +5215 -0
  56. package/dist/esm/abi/testnet/LimitOrderBook.json +1075 -0
  57. package/dist/esm/abi/testnet/LimitOrderBookFactory.json +135 -0
  58. package/dist/esm/abi/zkevmTestnet/IPerpetualManager.json +5215 -0
  59. package/dist/esm/abi/zkevmTestnet/LimitOrderBook.json +1075 -0
  60. package/dist/esm/abi/zkevmTestnet/LimitOrderBookFactory.json +135 -0
  61. package/dist/esm/accountTrade.d.ts +221 -0
  62. package/dist/{src → esm}/accountTrade.js +22 -93
  63. package/dist/esm/accountTrade.js.map +1 -0
  64. package/dist/esm/brokerTool.d.ts +318 -0
  65. package/dist/esm/brokerTool.js +572 -0
  66. package/dist/esm/brokerTool.js.map +1 -0
  67. package/dist/esm/config/defaultConfig.json +47 -0
  68. package/dist/esm/config/mockSwap.json +4 -0
  69. package/dist/esm/config/priceFeedConfig.json +104 -0
  70. package/dist/esm/config/symbolList.json +13 -0
  71. package/dist/esm/d8XMath.d.ts +122 -0
  72. package/dist/esm/d8XMath.js +247 -0
  73. package/dist/esm/d8XMath.js.map +1 -0
  74. package/{src/index.ts → dist/esm/index.d.ts} +1 -15
  75. package/dist/esm/index.js +16 -0
  76. package/dist/esm/index.js.map +1 -0
  77. package/dist/esm/liquidatorTool.d.ts +158 -0
  78. package/dist/{src → esm}/liquidatorTool.js +10 -65
  79. package/dist/esm/liquidatorTool.js.map +1 -0
  80. package/dist/esm/liquidityProviderTool.d.ts +126 -0
  81. package/dist/esm/liquidityProviderTool.js +218 -0
  82. package/dist/esm/liquidityProviderTool.js.map +1 -0
  83. package/dist/esm/marketData.d.ts +309 -0
  84. package/dist/esm/marketData.js +1007 -0
  85. package/dist/esm/marketData.js.map +1 -0
  86. package/dist/esm/nodeSDKTypes.d.ts +266 -0
  87. package/dist/esm/nodeSDKTypes.js +60 -0
  88. package/dist/esm/nodeSDKTypes.js.map +1 -0
  89. package/dist/esm/orderReferrerTool.d.ts +196 -0
  90. package/dist/esm/orderReferrerTool.js +491 -0
  91. package/dist/esm/orderReferrerTool.js.map +1 -0
  92. package/dist/esm/perpetualDataHandler.d.ts +220 -0
  93. package/dist/esm/perpetualDataHandler.js +1060 -0
  94. package/dist/esm/perpetualDataHandler.js.map +1 -0
  95. package/dist/esm/perpetualEventHandler.d.ts +179 -0
  96. package/dist/esm/perpetualEventHandler.js +435 -0
  97. package/dist/esm/perpetualEventHandler.js.map +1 -0
  98. package/dist/esm/priceFeeds.d.ts +115 -0
  99. package/dist/{src → esm}/priceFeeds.js +16 -83
  100. package/dist/esm/priceFeeds.js.map +1 -0
  101. package/dist/esm/traderDigests.d.ts +21 -0
  102. package/dist/esm/traderDigests.js +80 -0
  103. package/dist/esm/traderDigests.js.map +1 -0
  104. package/dist/esm/traderInterface.d.ts +79 -0
  105. package/dist/esm/traderInterface.js +196 -0
  106. package/dist/esm/traderInterface.js.map +1 -0
  107. package/dist/esm/triangulator.d.ts +27 -0
  108. package/dist/esm/triangulator.js +110 -0
  109. package/dist/esm/triangulator.js.map +1 -0
  110. package/dist/esm/utils.d.ts +59 -0
  111. package/dist/esm/utils.js +138 -0
  112. package/dist/esm/utils.js.map +1 -0
  113. package/dist/esm/version.d.ts +1 -0
  114. package/dist/esm/version.js +2 -0
  115. package/dist/esm/version.js.map +1 -0
  116. package/dist/esm/writeAccessHandler.d.ts +50 -0
  117. package/dist/esm/writeAccessHandler.js +157 -0
  118. package/dist/esm/writeAccessHandler.js.map +1 -0
  119. package/package.json +16 -26
  120. package/dist/bundle.js +0 -36793
  121. package/dist/config/defaultConfig.json +0 -47
  122. package/dist/config/mockSwap.json +0 -4
  123. package/dist/config/priceFeedConfig.json +0 -104
  124. package/dist/config/symbolList.json +0 -13
  125. package/dist/src/index.js +0 -45
  126. package/dist/src/nodeSDKTypes.js +0 -115
  127. package/dist/src/version.d.ts +0 -1
  128. package/module.d.ts +0 -1
  129. package/src/accountTrade.ts +0 -392
  130. package/src/brokerTool.ts +0 -507
  131. package/src/d8XMath.ts +0 -319
  132. package/src/liquidatorTool.ts +0 -258
  133. package/src/liquidityProviderTool.ts +0 -186
  134. package/src/marketData.ts +0 -946
  135. package/src/nodeSDKTypes.ts +0 -293
  136. package/src/orderReferrerTool.ts +0 -389
  137. package/src/perpetualDataHandler.ts +0 -1061
  138. package/src/perpetualEventHandler.ts +0 -455
  139. package/src/priceFeeds.ts +0 -381
  140. package/src/traderDigests.ts +0 -91
  141. package/src/traderInterface.ts +0 -159
  142. package/src/triangulator.ts +0 -105
  143. package/src/utils.ts +0 -134
  144. package/src/version.ts +0 -1
  145. package/src/writeAccessHandler.ts +0 -127
  146. /package/dist/{abi → cjs/abi}/ERC20.json +0 -0
  147. /package/dist/{abi → cjs/abi}/MockTokenSwap.json +0 -0
  148. /package/dist/{abi → cjs/abi}/central-park/IPerpetualManager.json +0 -0
  149. /package/dist/{abi → cjs/abi}/central-park/LimitOrderBook.json +0 -0
  150. /package/dist/{abi → cjs/abi}/central-park/LimitOrderBookFactory.json +0 -0
  151. /package/dist/{abi → cjs/abi}/testnet/LimitOrderBookFactory.json +0 -0
  152. /package/dist/{src → cjs}/accountTrade.d.ts +0 -0
  153. /package/dist/{src → cjs}/brokerTool.d.ts +0 -0
  154. /package/dist/{src → cjs}/d8XMath.d.ts +0 -0
  155. /package/dist/{src → cjs}/d8XMath.js +0 -0
  156. /package/dist/{src → cjs}/index.d.ts +0 -0
  157. /package/dist/{src → cjs}/liquidatorTool.d.ts +0 -0
  158. /package/dist/{src → cjs}/liquidityProviderTool.d.ts +0 -0
  159. /package/dist/{src → cjs}/marketData.d.ts +0 -0
  160. /package/dist/{src → cjs}/priceFeeds.d.ts +0 -0
  161. /package/dist/{src → cjs}/traderDigests.d.ts +0 -0
  162. /package/dist/{src → cjs}/traderInterface.d.ts +0 -0
  163. /package/dist/{src → cjs}/triangulator.d.ts +0 -0
  164. /package/dist/{src → cjs}/utils.d.ts +0 -0
  165. /package/dist/{src → cjs}/writeAccessHandler.d.ts +0 -0
package/src/d8XMath.ts DELETED
@@ -1,319 +0,0 @@
1
- import { BigNumber } from "ethers";
2
- import { DECIMALS, ONE_64x64 } from "./nodeSDKTypes";
3
-
4
- /**
5
- * @module d8xMath
6
- */
7
-
8
- /**
9
- * Convert ABK64x64 bigint-format to float.
10
- * Result = x/2^64 if big number, x/2^29 if number
11
- * @param {BigNumber|number} x number in ABDK-format or 2^29
12
- * @returns {number} x/2^64 in number-format (float)
13
- */
14
- export function ABK64x64ToFloat(x: BigNumber | number): number {
15
- if (typeof x == "number") {
16
- return x / 2 ** 29;
17
- }
18
- let s = x.lt(0) ? -1 : 1;
19
- x = x.mul(s);
20
- let xInt = x.div(ONE_64x64);
21
- let dec18 = BigNumber.from(10).pow(BigNumber.from(18));
22
- let xDec = x.sub(xInt.mul(ONE_64x64));
23
- xDec = xDec.mul(dec18).div(ONE_64x64);
24
- let k = 18 - xDec.toString().length;
25
- // console.assert(k >= 0);
26
- let sPad = "0".repeat(k);
27
- let NumberStr = xInt.toString() + "." + sPad + xDec.toString();
28
- return parseFloat(NumberStr) * s;
29
- }
30
-
31
- /**
32
- *
33
- * @param {BigNumber} x BigNumber in Dec-N format
34
- * @returns {number} x as a float (number)
35
- */
36
- export function decNToFloat(x: BigNumber, numDec: number) {
37
- //x: BigNumber in DecN format to float
38
- const DECIMALS = BigNumber.from(10).pow(BigNumber.from(numDec));
39
- let s = x.lt(0) ? -1 : 1;
40
- x = x.mul(s);
41
- let xInt = x.div(DECIMALS);
42
- let xDec = x.sub(xInt.mul(DECIMALS));
43
- let k = numDec - xDec.toString().length;
44
- let sPad = "0".repeat(k);
45
- let NumberStr = xInt.toString() + "." + sPad + xDec.toString();
46
- return parseFloat(NumberStr) * s;
47
- }
48
-
49
- /**
50
- *
51
- * @param {BigNumber} x BigNumber in Dec18 format
52
- * @returns {number} x as a float (number)
53
- */
54
- export function dec18ToFloat(x: BigNumber): number {
55
- //x: BigNumber in Dec18 format to float
56
- let s = x.lt(0) ? -1 : 1;
57
- x = x.mul(s);
58
- let xInt = x.div(DECIMALS);
59
- let xDec = x.sub(xInt.mul(DECIMALS));
60
- let k = 18 - xDec.toString().length;
61
- let sPad = "0".repeat(k);
62
- let NumberStr = xInt.toString() + "." + sPad + xDec.toString();
63
- return parseFloat(NumberStr) * s;
64
- }
65
-
66
- /**
67
- * Converts x into ABDK64x64 format
68
- * @param {number} x number (float)
69
- * @returns {BigNumber} x^64 in big number format
70
- */
71
- export function floatToABK64x64(x: number): BigNumber {
72
- // convert float to ABK64x64 bigint-format
73
- // Create string from number with 18 decimals
74
- if (x === 0) {
75
- return BigNumber.from(0);
76
- }
77
- let sg = Math.sign(x);
78
- x = Math.abs(x);
79
- let strX = Number(x).toFixed(18);
80
- const arrX = strX.split(".");
81
- let xInt = BigNumber.from(arrX[0]);
82
- let xDec = BigNumber.from(arrX[1]);
83
- let xIntBig = xInt.mul(ONE_64x64);
84
- let dec18 = BigNumber.from(10).pow(BigNumber.from(18));
85
- let xDecBig = xDec.mul(ONE_64x64).div(dec18);
86
- return xIntBig.add(xDecBig).mul(sg);
87
- }
88
-
89
- /**
90
- *
91
- * @param {number} x number (float)
92
- * @returns {BigNumber} x as a BigNumber in Dec18 format
93
- */
94
- export function floatToDec18(x: number): BigNumber {
95
- // float number to dec 18
96
- if (x === 0) {
97
- return BigNumber.from(0);
98
- }
99
- let sg = Math.sign(x);
100
- x = Math.abs(x);
101
- let strX = x.toFixed(18);
102
- const arrX = strX.split(".");
103
- let xInt = BigNumber.from(arrX[0]);
104
- let xDec = BigNumber.from(arrX[1]);
105
- let xIntBig = xInt.mul(DECIMALS);
106
- return xIntBig.add(xDec).mul(sg);
107
- }
108
-
109
- /**
110
- *
111
- * @param {BigNumber} x
112
- * @param {BigNumber} y
113
- * @returns {BigNumber} x * y
114
- */
115
- export function mul64x64(x: BigNumber, y: BigNumber) {
116
- return x.mul(y).div(ONE_64x64);
117
- }
118
-
119
- /**
120
- *
121
- * @param {BigNumber} x
122
- * @param {BigNumber} y
123
- * @returns {BigNumber} x / y
124
- */
125
- export function div64x64(x: BigNumber, y: BigNumber) {
126
- return x.mul(ONE_64x64).div(y);
127
- }
128
-
129
- /**
130
- * Determine the liquidation price
131
- * @param {number} LockedInValueQC - trader locked in value in quote currency
132
- * @param {number} position - trader position in base currency
133
- * @param {number} cash_cc - trader available margin cash in collateral currency
134
- * @param {number} maintenance_margin_rate - maintenance margin ratio
135
- * @param {number} S3 - collateral to quote conversion (=S2 if base-collateral, =1 if quuote collateral, = index S3 if quanto)
136
- * @returns {number} Amount to be deposited to have the given leverage when trading into position pos
137
- */
138
- export function calculateLiquidationPriceCollateralBase(
139
- LockedInValueQC: number,
140
- position: number,
141
- cash_cc: number,
142
- maintenance_margin_rate: number
143
- ): number {
144
- // correct only if markprice = spot price
145
- // m_r <= (Sm * Pi - L + cash * S3) / (Sm * |Pi|)
146
- // -> Sm * (Pi + cash - m_r|Pi|) => L
147
- return LockedInValueQC / (position - maintenance_margin_rate * Math.abs(position) + cash_cc);
148
- }
149
-
150
- /**
151
- * Determine the liquidation price
152
- * @param {number} LockedInValueQC - trader locked in value in quote currency
153
- * @param {number} position - trader position in base currency
154
- * @param {number} cash_cc - trader available margin cash in collateral currency
155
- * @param {number} maintenance_margin_rate - maintenance margin ratio
156
- * @param {number} S3 - collateral to quote conversion (=S2 if base-collateral, =1 if quuote collateral, = index S3 if quanto)
157
- * @param {number} Sm - mark price
158
- * @returns {number} Amount to be deposited to have the given leverage when trading into position pos
159
- */
160
- export function calculateLiquidationPriceCollateralQuanto(
161
- LockedInValueQC: number,
162
- position: number,
163
- cash_cc: number,
164
- maintenance_margin_rate: number,
165
- S3: number,
166
- Sm: number
167
- ): number {
168
- // correct only if markprice = spot price and S3 co-moves with Sm
169
- // m_r = (Sm * Pi - L + cash * S3) / (Sm * |Pi|)
170
- // m_r = [Sm * Pi - L + cash * S3(0) * (1 + sign(Pi) (Sm / Sm(0) - 1)] / (Sm * |Pi|)
171
- // -> Sm * (m_r |Pi| - Pi - cash * S3(0) * sign(Pi) / Sm(0)) = - L + cash * S3(0) * (1 - sign(Pi))
172
- let numerator = -LockedInValueQC + cash_cc * S3 * (1 - Math.sign(position));
173
- let denominator = maintenance_margin_rate * Math.abs(position) - position - (cash_cc * S3 * Math.sign(position)) / Sm;
174
- return numerator / denominator;
175
- }
176
-
177
- /**
178
- * Determine the liquidation price
179
- * @param {number} LockedInValueQC - trader locked in value in quote currency
180
- * @param {number} position - trader position in base currency
181
- * @param {number} cash_cc - trader available margin cash in collateral currency
182
- * @param {number} maintenance_margin_rate - maintenance margin ratio
183
- * @param {number} S3 - collateral to quote conversion (=S2 if base-collateral, =1 if quuote collateral, = index S3 if quanto)
184
- * @returns {number} Amount to be deposited to have the given leverage when trading into position pos
185
- */
186
- export function calculateLiquidationPriceCollateralQuote(
187
- LockedInValueQC: number,
188
- position: number,
189
- cash_cc: number,
190
- maintenance_margin_rate: number
191
- ): number {
192
- // m_r = (Sm * Pi - L + cash ) / (Sm * |Pi|)
193
- // -> Sm * (m_r |Pi| - Pi) = - L + cash
194
- let numerator = -LockedInValueQC + cash_cc;
195
- let denominator = maintenance_margin_rate * Math.abs(position) - position;
196
- return numerator / denominator;
197
- }
198
-
199
- /**
200
- *
201
- * @param targetLeverage Leverage of the resulting position. It must be positive unless the resulting position is closed.
202
- * @param currentPosition Current position size, in base currency, signed.
203
- * @param currentLockedInValue Current locked in value, average entry price times position size, in quote currency.
204
- * @param tradeAmount Trade amount, in base currency, signed.
205
- * @param markPrice Mark price, positive.
206
- * @param indexPriceS2 Index price, positive.
207
- * @param indexPriceS3 Collateral index price, positive.
208
- * @param tradePrice Expected price to trade tradeAmount.
209
- * @param feeRate
210
- * @returns {number} Total collateral amount needed for the new position to have he desired leverage.
211
- */
212
- export function getMarginRequiredForLeveragedTrade(
213
- targetLeverage: number | undefined,
214
- currentPosition: number,
215
- currentLockedInValue: number,
216
- tradeAmount: number,
217
- markPrice: number,
218
- indexPriceS2: number,
219
- indexPriceS3: number,
220
- tradePrice: number,
221
- feeRate: number
222
- ): number {
223
- // we solve for margin in:
224
- // |new position| * Sm / leverage + fee rate * |trade amount| * S2 = margin * S3 + current position * Sm - L + trade amount * (Sm - trade price)
225
- // --> M S3 = |P'|Sm/L + FeeQC - PnL + (P'-P)(Price - Sm) = pos value / leverage + fees + price impact - pnl
226
- let isClosing =
227
- currentPosition != 0 && currentPosition * tradeAmount < 0 && currentPosition * (currentPosition + tradeAmount) >= 0;
228
- let feesCC = (feeRate * Math.abs(tradeAmount) * indexPriceS2) / indexPriceS3;
229
- let collRequired = feesCC;
230
-
231
- if (!isClosing) {
232
- if (targetLeverage == undefined || targetLeverage <= 0) {
233
- throw Error("opening trades must have positive leverage");
234
- }
235
- // unrealized pnl (could be + or -) - price impact premium (+)
236
- let pnlQC = currentPosition * markPrice - currentLockedInValue - tradeAmount * (tradePrice - markPrice);
237
- collRequired +=
238
- Math.max(0, (Math.abs(currentPosition + tradeAmount) * markPrice) / targetLeverage - pnlQC) / indexPriceS3;
239
- }
240
- return collRequired;
241
- }
242
-
243
- export function getMaxSignedPositionSize(
244
- marginCollateral: number,
245
- currentPosition: number,
246
- currentLockedInValue: number,
247
- direction: number,
248
- limitPrice: number,
249
- initialMarginRate: number,
250
- feeRate: number,
251
- markPrice: number,
252
- indexPriceS2: number,
253
- indexPriceS3: number
254
- ): number {
255
- // we solve for new position in:
256
- // |new position| * Sm / leverage + fee rate * |trade amount| * S2 = margin * S3 + current position * Sm - L + trade amount * (Sm - entry price)
257
- // |trade amount| = (new position - current position) * direction
258
- let availableCash = marginCollateral * indexPriceS3 + currentPosition * markPrice - currentLockedInValue;
259
- let effectiveMarginRate =
260
- markPrice * initialMarginRate + feeRate * indexPriceS2 + direction * (limitPrice - markPrice);
261
-
262
- return availableCash / effectiveMarginRate;
263
- }
264
-
265
- /**
266
- * Compute the leverage resulting from a trade
267
- * @param tradeAmount Amount to trade, in base currency, signed
268
- * @param marginCollateral Amount of cash in the margin account, in collateral currency
269
- * @param currentPosition Position size before the trade
270
- * @param currentLockedInValue Locked-in value before the trade
271
- * @param price Price charged to trade tradeAmount
272
- * @param indexPriceS3 Spot price of the collateral currency when the trade happens
273
- * @param markPrice Mark price of the index when the trade happens
274
- * @returns Leverage of the resulting position
275
- */
276
- export function getNewPositionLeverage(
277
- tradeAmount: number,
278
- marginCollateral: number,
279
- currentPosition: number,
280
- currentLockedInValue: number,
281
- price: number,
282
- indexPriceS3: number,
283
- markPrice: number
284
- ): number {
285
- let newPosition = tradeAmount + currentPosition;
286
- let pnlQC = currentPosition * markPrice - currentLockedInValue + tradeAmount * (markPrice - price);
287
- return (Math.abs(newPosition) * markPrice) / (marginCollateral * indexPriceS3 + pnlQC);
288
- }
289
-
290
- /**
291
- * Determine amount to be deposited into margin account so that the given leverage
292
- * is obtained when trading a position pos (trade amount = position)
293
- * Does NOT include fees
294
- * Smart contract equivalent: calcMarginForTargetLeverage(..., _ignorePosBalance = false & balance = b0)
295
- * @param {number} pos0 - current position
296
- * @param {number} b0 - current balance
297
- * @param {number} tradeAmnt - amount to trade
298
- * @param {number} targetLvg - target leverage
299
- * @param {number} price - price to trade amount 'tradeAmnt'
300
- * @param {number} S3 - collateral to quote conversion (=S2 if base-collateral, =1 if quote collateral, = index S3 if quanto)
301
- * @param {number} S2Mark - mark price
302
- * @returns {number} Amount to be deposited to have the given leverage when trading into position pos before fees
303
- */
304
- export function getDepositAmountForLvgTrade(
305
- pos0: number,
306
- b0: number,
307
- tradeAmnt: number,
308
- targetLvg: number,
309
- price: number,
310
- S3: number,
311
- S2Mark: number
312
- ) {
313
- let pnl = (tradeAmnt * (S2Mark - price)) / S3;
314
- if (targetLvg == 0) {
315
- targetLvg = (Math.abs(pos0) * S2Mark) / S3 / b0;
316
- }
317
- let b = (Math.abs(pos0 + tradeAmnt) * S2Mark) / S3 / targetLvg;
318
- return -(b0 + pnl - b);
319
- }
@@ -1,258 +0,0 @@
1
- import WriteAccessHandler from "./writeAccessHandler";
2
- import { NodeSDKConfig, PriceFeedSubmission } from "./nodeSDKTypes";
3
- import { ethers } from "ethers";
4
- import { ABK64x64ToFloat, floatToABK64x64 } from "./d8XMath";
5
-
6
- /**
7
- * Functions to liquidate traders. This class requires a private key
8
- * and executes smart-contract interactions that require gas-payments.
9
- * @extends WriteAccessHandler
10
- */
11
- export default class LiquidatorTool extends WriteAccessHandler {
12
- /**
13
- * Constructs a LiquidatorTool instance for a given configuration and private key.
14
- * @param {NodeSDKConfig} config Configuration object, see PerpetualDataHandler.
15
- * readSDKConfig.
16
- * @example
17
- * import { LiquidatorTool, PerpetualDataHandler } from '@d8x/perpetuals-sdk';
18
- * async function main() {
19
- * console.log(LiquidatorTool);
20
- * // load configuration for testnet
21
- * const config = PerpetualDataHandler.readSDKConfig("testnet");
22
- * // LiquidatorTool (authentication required, PK is an environment variable with a private key)
23
- * const pk: string = <string>process.env.PK;
24
- * let lqudtrTool = new LiquidatorTool(config, pk);
25
- * // Create a proxy instance to access the blockchain
26
- * await lqudtrTool.createProxyInstance();
27
- * }
28
- * main();
29
- *
30
- * @param {string} privateKey Private key of account that liquidates.
31
- */
32
- public constructor(config: NodeSDKConfig, privateKey: string) {
33
- super(config, privateKey);
34
- }
35
-
36
- /**
37
- * Liquidate a trader.
38
- * @param {string} symbol Symbol of the form ETH-USD-MATIC.
39
- * @param {string} traderAddr Address of the trader to be liquidated.
40
- * @param {string=} liquidatorAddr Address to be credited if the liquidation succeeds.
41
- * @param {PriceFeedSubmission} priceFeedData optional. VAA and timestamps for oracle. If not provided will query from REST API.
42
- * Defaults to the wallet used to execute the liquidation.
43
- * @example
44
- * import { LiquidatorTool, PerpetualDataHandler } from '@d8x/perpetuals-sdk';
45
- * async function main() {
46
- * console.log(LiquidatorTool);
47
- * // Setup (authentication required, PK is an environment variable with a private key)
48
- * const config = PerpetualDataHandler.readSDKConfig("testnet");
49
- * const pk: string = <string>process.env.PK;
50
- * let lqudtrTool = new LiquidatorTool(config, pk);
51
- * await lqudtrTool.createProxyInstance();
52
- * // liquidate trader
53
- * let liqAmount = await lqudtrTool.liquidateTrader("ETH-USD-MATIC",
54
- * "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B");
55
- * console.log(liqAmount);
56
- * }
57
- * main();
58
- *
59
- * @returns Transaction object.
60
- */
61
- public async liquidateTrader(
62
- symbol: string,
63
- traderAddr: string,
64
- liquidatorAddr: string = "",
65
- priceFeedData?: PriceFeedSubmission
66
- ): Promise<ethers.ContractTransaction> {
67
- // this operation spends gas, so signer is required
68
- if (this.proxyContract == null || this.signer == null) {
69
- throw Error("no proxy contract or wallet initialized. Use createProxyInstance().");
70
- }
71
- // liquidator is signer unless specified otherwise
72
- if (liquidatorAddr == "") {
73
- liquidatorAddr = this.traderAddr;
74
- }
75
- let perpID = LiquidatorTool.symbolToPerpetualId(symbol, this.symbolToPerpStaticInfo);
76
- if (priceFeedData == undefined) {
77
- priceFeedData = await this.fetchLatestFeedPriceInfo(symbol);
78
- }
79
- return await this._liquidateByAMM(perpID, liquidatorAddr, traderAddr, priceFeedData, {
80
- gasLimit: this.gasLimit,
81
- value: this.PRICE_UPDATE_FEE_GWEI * priceFeedData.priceFeedVaas.length,
82
- });
83
- }
84
-
85
- /**
86
- * Check if the collateral of a trader is above the maintenance margin ("maintenance margin safe").
87
- * If not, the position can be liquidated.
88
- * @param {string} symbol Symbol of the form ETH-USD-MATIC.
89
- * @param {string} traderAddr Address of the trader whose position you want to assess.
90
- * @param {number[]} indexPrices optional, index price S2/S3 for which we test
91
- * @example
92
- * import { LiquidatorTool, PerpetualDataHandler } from '@d8x/perpetuals-sdk';
93
- * async function main() {
94
- * console.log(LiquidatorTool);
95
- * // Setup (authentication required, PK is an environment variable with a private key)
96
- * const config = PerpetualDataHandler.readSDKConfig("testnet");
97
- * const pk: string = <string>process.env.PK;
98
- * let lqudtrTool = new LiquidatorTool(config, pk);
99
- * await lqudtrTool.createProxyInstance();
100
- * // check if trader can be liquidated
101
- * let safe = await lqudtrTool.isMaintenanceMarginSafe("ETH-USD-MATIC",
102
- * "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B");
103
- * console.log(safe);
104
- * }
105
- * main();
106
- *
107
- * @returns {boolean} True if the trader is maintenance margin safe in the perpetual.
108
- * False means that the trader's position can be liquidated.
109
- */
110
- public async isMaintenanceMarginSafe(
111
- symbol: string,
112
- traderAddr: string,
113
- indexPrices?: [number, number]
114
- ): Promise<boolean> {
115
- if (this.proxyContract == null) {
116
- throw Error("no proxy contract initialized. Use createProxyInstance().");
117
- }
118
- const idx_notional = 4;
119
- let perpID = LiquidatorTool.symbolToPerpetualId(symbol, this.symbolToPerpStaticInfo);
120
- if (indexPrices == undefined) {
121
- // fetch from API
122
- let obj = await this.priceFeedGetter.fetchPricesForPerpetual(symbol);
123
- indexPrices = [obj.idxPrices[0], obj.idxPrices[1]];
124
- }
125
- let traderState = await this.proxyContract.getTraderState(
126
- perpID,
127
- traderAddr,
128
- indexPrices.map((x) => floatToABK64x64(x))
129
- );
130
- if (traderState[idx_notional] == 0) {
131
- // trader does not have open position
132
- return true;
133
- }
134
- // calculate margin from traderstate
135
- const idx_maintenanceMgnRate = 10;
136
- const idx_marginAccountPositionBC = 4;
137
- const idx_collateralToQuoteConversion = 9;
138
- const idx_marginBalance = 0;
139
- const maintMgnRate = ABK64x64ToFloat(traderState[idx_maintenanceMgnRate]);
140
- const pos = ABK64x64ToFloat(traderState[idx_marginAccountPositionBC]);
141
- const marginbalance = ABK64x64ToFloat(traderState[idx_marginBalance]);
142
- const coll2quote = ABK64x64ToFloat(traderState[idx_collateralToQuoteConversion]);
143
- const base2collateral = indexPrices[0] / coll2quote;
144
- const threshold = Math.abs(pos * base2collateral * maintMgnRate);
145
- return marginbalance >= threshold;
146
- }
147
-
148
- /**
149
- *
150
- * @param perpetualId Perpetual id.
151
- * @param liquidatorAddr Address to be credited for the liquidation.
152
- * @param traderAddr Address of the trader to be liquidated.
153
- * @param priceFeedData contains VAA and timestamps required
154
- * @param options E.g., Gas limit, fee.
155
- * @ignore
156
- */
157
- public async _liquidateByAMM(
158
- perpetualId: number,
159
- liquidatorAddr: string,
160
- traderAddr: string,
161
- priceFeedData: PriceFeedSubmission,
162
- options: object
163
- ) {
164
- return await this.proxyContract!.liquidateByAMM(
165
- perpetualId,
166
- liquidatorAddr,
167
- traderAddr,
168
- priceFeedData.priceFeedVaas,
169
- priceFeedData.timestamps,
170
- options
171
- );
172
- }
173
-
174
- /**
175
- * Total number of active accounts for this symbol, i.e. accounts with positions that are currently open.
176
- * @param {string} symbol Symbol of the form ETH-USD-MATIC.
177
- * @example
178
- * import { LiquidatorTool, PerpetualDataHandler } from '@d8x/perpetuals-sdk';
179
- * async function main() {
180
- * console.log(LiquidatorTool);
181
- * // Setup (authentication required, PK is an environment variable with a private key)
182
- * const config = PerpetualDataHandler.readSDKConfig("testnet");
183
- * const pk: string = <string>process.env.PK;
184
- * let lqudtrTool = new LiquidatorTool(config, pk);
185
- * await lqudtrTool.createProxyInstance();
186
- * // get number of active accounts
187
- * let accounts = await lqudtrTool.countActivePerpAccounts("ETH-USD-MATIC");
188
- * console.log(accounts);
189
- * }
190
- * main();
191
- *
192
- * @returns {number} Number of active accounts.
193
- */
194
- public async countActivePerpAccounts(symbol: string): Promise<number> {
195
- if (this.proxyContract == null) {
196
- throw Error("no proxy contract initialized. Use createProxyInstance().");
197
- }
198
- let perpID = LiquidatorTool.symbolToPerpetualId(symbol, this.symbolToPerpStaticInfo);
199
- let numAccounts = await this.proxyContract.countActivePerpAccounts(perpID);
200
- return Number(numAccounts);
201
- }
202
-
203
- /**
204
- * Get addresses of active accounts by chunks.
205
- * @param {string} symbol Symbol of the form ETH-USD-MATIC.
206
- * @param {number} from From which account we start counting (0-indexed).
207
- * @param {number} to Until which account we count, non inclusive.
208
- * @example
209
- * import { LiquidatorTool, PerpetualDataHandler } from '@d8x/perpetuals-sdk';
210
- * async function main() {
211
- * console.log(LiquidatorTool);
212
- * // Setup (authentication required, PK is an environment variable with a private key)
213
- * const config = PerpetualDataHandler.readSDKConfig("testnet");
214
- * const pk: string = <string>process.env.PK;
215
- * let lqudtrTool = new LiquidatorTool(config, pk);
216
- * await lqudtrTool.createProxyInstance();
217
- * // get all active accounts in chunks
218
- * let accounts = await lqudtrTool.getActiveAccountsByChunks("ETH-USD-MATIC", 0, 4);
219
- * console.log(accounts);
220
- * }
221
- * main();
222
- *
223
- * @returns {string[]} Array of addresses at locations 'from', 'from'+1 ,..., 'to'-1.
224
- */
225
- public async getActiveAccountsByChunks(symbol: string, from: number, to: number): Promise<string[]> {
226
- if (this.proxyContract == null) {
227
- throw Error("no proxy contract initialized. Use createProxyInstance().");
228
- }
229
- let perpID = LiquidatorTool.symbolToPerpetualId(symbol, this.symbolToPerpStaticInfo);
230
- return await this.proxyContract.getActivePerpAccountsByChunks(perpID, from, to);
231
- }
232
-
233
- /**
234
- * Addresses for all the active accounts in this perpetual symbol.
235
- * @param {string} symbol Symbol of the form ETH-USD-MATIC.
236
- * @example
237
- * import { LiquidatorTool, PerpetualDataHandler } from '@d8x/perpetuals-sdk';
238
- * async function main() {
239
- * console.log(LiquidatorTool);
240
- * // Setup (authentication required, PK is an environment variable with a private key)
241
- * const config = PerpetualDataHandler.readSDKConfig("testnet");
242
- * const pk: string = <string>process.env.PK;
243
- * let lqudtrTool = new LiquidatorTool(config, pk);
244
- * await lqudtrTool.createProxyInstance();
245
- * // get all active accounts
246
- * let accounts = await lqudtrTool.getAllActiveAccounts("ETH-USD-MATIC");
247
- * console.log(accounts);
248
- * }
249
- * main();
250
- *
251
- * @returns {string[]} Array of addresses.
252
- */
253
- public async getAllActiveAccounts(symbol: string): Promise<string[]> {
254
- // checks are done inside the intermediate functions
255
- let totalAccounts = await this.countActivePerpAccounts(symbol);
256
- return await this.getActiveAccountsByChunks(symbol, 0, totalAccounts);
257
- }
258
- }