@drift-labs/sdk 0.1.30-master.0 → 0.1.30-master.3

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 (82) hide show
  1. package/lib/accounts/bulkAccountLoader.d.ts +2 -2
  2. package/lib/accounts/bulkAccountLoader.js +21 -24
  3. package/lib/accounts/pollingClearingHouseAccountSubscriber.d.ts +15 -0
  4. package/lib/accounts/pollingClearingHouseAccountSubscriber.js +50 -23
  5. package/lib/clearingHouse.d.ts +0 -1
  6. package/lib/clearingHouse.js +0 -14
  7. package/lib/constants/accounts.d.ts +15 -0
  8. package/lib/constants/accounts.js +18 -0
  9. package/lib/constants/markets.js +11 -8
  10. package/lib/factory/clearingHouse.d.ts +14 -4
  11. package/lib/factory/clearingHouse.js +23 -6
  12. package/lib/idl/clearing_house.json +2 -33
  13. package/lib/index.d.ts +0 -1
  14. package/lib/index.js +0 -1
  15. package/lib/math/amm.d.ts +20 -0
  16. package/lib/math/amm.js +151 -1
  17. package/lib/util/promiseTimeout.d.ts +1 -0
  18. package/lib/util/promiseTimeout.js +14 -0
  19. package/package.json +1 -1
  20. package/src/accounts/bulkAccountLoader.ts +22 -32
  21. package/src/accounts/pollingClearingHouseAccountSubscriber.ts +73 -30
  22. package/src/clearingHouse.ts +0 -13
  23. package/src/constants/accounts.ts +26 -0
  24. package/src/constants/markets.ts +11 -8
  25. package/src/factory/clearingHouse.ts +47 -7
  26. package/src/idl/clearing_house.json +2 -33
  27. package/src/index.ts +0 -1
  28. package/src/math/amm.ts +212 -1
  29. package/src/util/promiseTimeout.ts +14 -0
  30. package/lib/math/repeg.d.ts +0 -32
  31. package/lib/math/repeg.js +0 -178
  32. package/src/accounts/pollingClearingHouseAccountSubscriber.js +0 -210
  33. package/src/accounts/pollingClearingHouseAccountSubscriber.js.map +0 -1
  34. package/src/accounts/pollingOracleSubscriber.js +0 -65
  35. package/src/accounts/pollingOracleSubscriber.js.map +0 -1
  36. package/src/accounts/pollingTokenAccountSubscriber.js +0 -65
  37. package/src/accounts/pollingTokenAccountSubscriber.js.map +0 -1
  38. package/src/accounts/utils.js +0 -8
  39. package/src/accounts/utils.js.map +0 -1
  40. package/src/accounts/webSocketAccountSubscriber.js +0 -64
  41. package/src/accounts/webSocketAccountSubscriber.js.map +0 -1
  42. package/src/accounts/webSocketClearingHouseAccountSubscriber.js +0 -212
  43. package/src/accounts/webSocketClearingHouseAccountSubscriber.js.map +0 -1
  44. package/src/assert/assert.js +0 -10
  45. package/src/assert/assert.js.map +0 -1
  46. package/src/constants/markets.js +0 -167
  47. package/src/constants/markets.js.map +0 -1
  48. package/src/constants/numericConstants.js +0 -22
  49. package/src/constants/numericConstants.js.map +0 -1
  50. package/src/math/conversion.js +0 -16
  51. package/src/math/conversion.js.map +0 -1
  52. package/src/math/funding.js +0 -223
  53. package/src/math/funding.js.map +0 -1
  54. package/src/math/insuranceFund.js +0 -23
  55. package/src/math/insuranceFund.js.map +0 -1
  56. package/src/math/market.js +0 -30
  57. package/src/math/market.js.map +0 -1
  58. package/src/math/orders.js +0 -73
  59. package/src/math/orders.js.map +0 -1
  60. package/src/math/position.js +0 -121
  61. package/src/math/position.js.map +0 -1
  62. package/src/math/repeg.ts +0 -253
  63. package/src/math/trade.js +0 -182
  64. package/src/math/trade.js.map +0 -1
  65. package/src/math/utils.js +0 -27
  66. package/src/math/utils.js.map +0 -1
  67. package/src/oracles/switchboardClient.js +0 -60
  68. package/src/oracles/switchboardClient.js.map +0 -1
  69. package/src/oracles/types.js +0 -3
  70. package/src/oracles/types.js.map +0 -1
  71. package/src/token/index.js +0 -39
  72. package/src/token/index.js.map +0 -1
  73. package/src/tx/defaultTxSender.js +0 -13
  74. package/src/tx/defaultTxSender.js.map +0 -1
  75. package/src/tx/types.js +0 -3
  76. package/src/tx/types.js.map +0 -1
  77. package/src/tx/utils.js +0 -9
  78. package/src/tx/utils.js.map +0 -1
  79. package/src/util/computeUnits.js +0 -17
  80. package/src/util/computeUnits.js.map +0 -1
  81. package/src/util/tps.js +0 -17
  82. package/src/util/tps.js.map +0 -1
@@ -10,6 +10,7 @@ import { DefaultTxSender } from '../tx/defaultTxSender';
10
10
  import { ClearingHouseAccountSubscriber } from '../accounts/types';
11
11
  import { PollingClearingHouseAccountSubscriber } from '../accounts/pollingClearingHouseAccountSubscriber';
12
12
  import { Admin } from '../admin';
13
+ import { RetryTxSender } from '../tx/retryTxSender';
13
14
 
14
15
  export type ClearingHouseConfigType = 'websocket' | 'polling' | 'custom';
15
16
 
@@ -19,7 +20,7 @@ type BaseClearingHouseConfig = {
19
20
  wallet: IWallet;
20
21
  programID: PublicKey;
21
22
  opts?: ConfirmOptions;
22
- txSender?: TxSender;
23
+ txSenderConfig?: TxSenderConfig;
23
24
  };
24
25
 
25
26
  type WebSocketClearingHouseConfiguration = BaseClearingHouseConfig;
@@ -32,12 +33,28 @@ type ClearingHouseConfig =
32
33
  | PollingClearingHouseConfiguration
33
34
  | WebSocketClearingHouseConfiguration;
34
35
 
36
+ export type TxSenderType = 'default' | 'retry';
37
+
38
+ type BaseTxSenderConfig = {
39
+ type: TxSenderType;
40
+ };
41
+
42
+ type DefaultTxSenderConfig = BaseTxSenderConfig;
43
+
44
+ type RetryTxSenderConfig = BaseTxSenderConfig & {
45
+ timeout?: number;
46
+ retrySleep?: number;
47
+ additionalConnections?: Connection[];
48
+ };
49
+
50
+ type TxSenderConfig = DefaultTxSenderConfig | RetryTxSenderConfig;
51
+
35
52
  export function getWebSocketClearingHouseConfig(
36
53
  connection: Connection,
37
54
  wallet: IWallet,
38
55
  programID: PublicKey,
39
56
  opts: ConfirmOptions = Provider.defaultOptions(),
40
- txSender?: TxSender
57
+ txSenderConfig?: TxSenderConfig
41
58
  ): WebSocketClearingHouseConfiguration {
42
59
  return {
43
60
  type: 'websocket',
@@ -45,7 +62,7 @@ export function getWebSocketClearingHouseConfig(
45
62
  wallet,
46
63
  programID,
47
64
  opts,
48
- txSender,
65
+ txSenderConfig,
49
66
  };
50
67
  }
51
68
 
@@ -55,7 +72,7 @@ export function getPollingClearingHouseConfig(
55
72
  programID: PublicKey,
56
73
  accountLoader: BulkAccountLoader,
57
74
  opts: ConfirmOptions = Provider.defaultOptions(),
58
- txSender?: TxSender
75
+ txSenderConfig?: TxSenderConfig
59
76
  ): PollingClearingHouseConfiguration {
60
77
  return {
61
78
  type: 'polling',
@@ -64,7 +81,7 @@ export function getPollingClearingHouseConfig(
64
81
  programID,
65
82
  accountLoader,
66
83
  opts,
67
- txSender,
84
+ txSenderConfig,
68
85
  };
69
86
  }
70
87
 
@@ -85,7 +102,19 @@ export function getClearingHouse(config: ClearingHouseConfig): ClearingHouse {
85
102
  );
86
103
  }
87
104
 
88
- const txSender = config.txSender || new DefaultTxSender(provider);
105
+ let txSender: TxSender;
106
+ if (config.txSenderConfig?.type === 'retry') {
107
+ const txSenderConfig = config.txSenderConfig as RetryTxSenderConfig;
108
+ txSender = new RetryTxSender(
109
+ provider,
110
+ txSenderConfig.timeout,
111
+ txSenderConfig.retrySleep,
112
+ txSenderConfig.additionalConnections
113
+ );
114
+ } else {
115
+ txSender = new DefaultTxSender(provider);
116
+ }
117
+
89
118
  return new ClearingHouse(
90
119
  config.connection,
91
120
  config.wallet,
@@ -113,7 +142,18 @@ export function getAdmin(config: ClearingHouseConfig): Admin {
113
142
  );
114
143
  }
115
144
 
116
- const txSender = config.txSender || new DefaultTxSender(provider);
145
+ let txSender: TxSender;
146
+ if (config.txSenderConfig?.type === 'retry') {
147
+ const txSenderConfig = config.txSenderConfig as RetryTxSenderConfig;
148
+ txSender = new RetryTxSender(
149
+ provider,
150
+ txSenderConfig.timeout,
151
+ txSenderConfig.retrySleep,
152
+ txSenderConfig.additionalConnections
153
+ );
154
+ } else {
155
+ txSender = new DefaultTxSender(provider);
156
+ }
117
157
  return new Admin(
118
158
  config.connection,
119
159
  config.wallet,
@@ -1482,32 +1482,6 @@
1482
1482
  }
1483
1483
  ]
1484
1484
  },
1485
- {
1486
- "name": "deleteUser",
1487
- "accounts": [
1488
- {
1489
- "name": "user",
1490
- "isMut": true,
1491
- "isSigner": false
1492
- },
1493
- {
1494
- "name": "userPositions",
1495
- "isMut": true,
1496
- "isSigner": false
1497
- },
1498
- {
1499
- "name": "userOrders",
1500
- "isMut": true,
1501
- "isSigner": false
1502
- },
1503
- {
1504
- "name": "authority",
1505
- "isMut": false,
1506
- "isSigner": true
1507
- }
1508
- ],
1509
- "args": []
1510
- },
1511
1485
  {
1512
1486
  "name": "settleFundingPayment",
1513
1487
  "accounts": [
@@ -3292,8 +3266,8 @@
3292
3266
  "type": "u128"
3293
3267
  },
3294
3268
  {
3295
- "name": "netRevenueSinceLastFunding",
3296
- "type": "i64"
3269
+ "name": "padding1",
3270
+ "type": "u64"
3297
3271
  },
3298
3272
  {
3299
3273
  "name": "padding2",
@@ -4300,11 +4274,6 @@
4300
4274
  "code": 6060,
4301
4275
  "name": "CantExpireOrders",
4302
4276
  "msg": "CantExpireOrders"
4303
- },
4304
- {
4305
- "code": 6061,
4306
- "name": "InvalidRepegPriceImpact",
4307
- "msg": "AMM repeg mark price impact vs oracle too large"
4308
4277
  }
4309
4278
  ]
4310
4279
  }
package/src/index.ts CHANGED
@@ -29,7 +29,6 @@ export * from './math/position';
29
29
  export * from './math/amm';
30
30
  export * from './math/trade';
31
31
  export * from './math/orders';
32
- export * from './math/repeg';
33
32
  export * from './orders';
34
33
  export * from './orderParams';
35
34
  export * from './wallet';
package/src/math/amm.ts CHANGED
@@ -4,7 +4,11 @@ import {
4
4
  MARK_PRICE_PRECISION,
5
5
  PEG_PRECISION,
6
6
  ZERO,
7
+ AMM_TO_QUOTE_PRECISION_RATIO,
8
+ QUOTE_PRECISION,
9
+ AMM_RESERVE_PRECISION,
7
10
  } from '../constants/numericConstants';
11
+ import { calculateBaseAssetValue } from './position';
8
12
  import {
9
13
  AMM,
10
14
  PositionDirection,
@@ -13,7 +17,12 @@ import {
13
17
  isVariant,
14
18
  } from '../types';
15
19
  import { assert } from '../assert/assert';
16
- import { squareRootBN } from '..';
20
+ import {
21
+ calculatePositionPNL,
22
+ calculateMarkPrice,
23
+ convertToNumber,
24
+ squareRootBN,
25
+ } from '..';
17
26
 
18
27
  /**
19
28
  * Calculates a price given an arbitrary base and quote amount (they must have the same precision)
@@ -130,6 +139,125 @@ export function getSwapDirection(
130
139
  return SwapDirection.ADD;
131
140
  }
132
141
 
142
+ /**
143
+ * Helper function calculating adjust k cost
144
+ * @param market
145
+ * @param marketIndex
146
+ * @param numerator
147
+ * @param denomenator
148
+ * @returns cost : Precision QUOTE_ASSET_PRECISION
149
+ */
150
+ export function calculateAdjustKCost(
151
+ market: Market,
152
+ marketIndex: BN,
153
+ numerator: BN,
154
+ denomenator: BN
155
+ ): BN {
156
+ const netUserPosition = {
157
+ baseAssetAmount: market.baseAssetAmount,
158
+ lastCumulativeFundingRate: market.amm.cumulativeFundingRate,
159
+ marketIndex: new BN(marketIndex),
160
+ quoteAssetAmount: new BN(0),
161
+ openOrders: new BN(0),
162
+ };
163
+
164
+ const currentValue = calculateBaseAssetValue(market, netUserPosition);
165
+
166
+ const marketNewK = Object.assign({}, market);
167
+ marketNewK.amm = Object.assign({}, market.amm);
168
+
169
+ marketNewK.amm.baseAssetReserve = market.amm.baseAssetReserve
170
+ .mul(numerator)
171
+ .div(denomenator);
172
+ marketNewK.amm.quoteAssetReserve = market.amm.quoteAssetReserve
173
+ .mul(numerator)
174
+ .div(denomenator);
175
+ marketNewK.amm.sqrtK = market.amm.sqrtK.mul(numerator).div(denomenator);
176
+
177
+ netUserPosition.quoteAssetAmount = currentValue;
178
+
179
+ const cost = calculatePositionPNL(marketNewK, netUserPosition);
180
+
181
+ const p = PEG_PRECISION.mul(numerator).div(denomenator);
182
+ const x = market.amm.baseAssetReserve;
183
+ const y = market.amm.quoteAssetReserve;
184
+ const delta = market.baseAssetAmount;
185
+ const k = market.amm.sqrtK.mul(market.amm.sqrtK);
186
+
187
+ const numer1 = PEG_PRECISION.sub(p).mul(y).div(PEG_PRECISION);
188
+ const numer20 = k
189
+ .mul(p)
190
+ .mul(p)
191
+ .div(PEG_PRECISION)
192
+ .div(PEG_PRECISION)
193
+ .div(x.mul(p).div(PEG_PRECISION).add(delta));
194
+ const numer21 = k.div(x.add(delta));
195
+
196
+ const formulaCost = numer21
197
+ .sub(numer20)
198
+ .sub(numer1)
199
+ .mul(market.amm.pegMultiplier)
200
+ .div(AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO);
201
+ console.log(convertToNumber(formulaCost, QUOTE_PRECISION));
202
+
203
+ // p.div(p.mul(x).add(delta)).sub()
204
+
205
+ return cost;
206
+ }
207
+
208
+ /**
209
+ * Helper function calculating adjust pegMultiplier (repeg) cost
210
+ *
211
+ * @param market
212
+ * @param marketIndex
213
+ * @param newPeg
214
+ * @returns cost : Precision QUOTE_ASSET_PRECISION
215
+ */
216
+ export function calculateRepegCost(
217
+ market: Market,
218
+ marketIndex: BN,
219
+ newPeg: BN
220
+ ): BN {
221
+ const netUserPosition = {
222
+ baseAssetAmount: market.baseAssetAmount,
223
+ lastCumulativeFundingRate: market.amm.cumulativeFundingRate,
224
+ marketIndex: new BN(marketIndex),
225
+ quoteAssetAmount: new BN(0),
226
+ openOrders: new BN(0),
227
+ };
228
+
229
+ const currentValue = calculateBaseAssetValue(market, netUserPosition);
230
+ netUserPosition.quoteAssetAmount = currentValue;
231
+ const prevMarketPrice = calculateMarkPrice(market);
232
+ const marketNewPeg = Object.assign({}, market);
233
+ marketNewPeg.amm = Object.assign({}, market.amm);
234
+
235
+ // const marketNewPeg = JSON.parse(JSON.stringify(market));
236
+ marketNewPeg.amm.pegMultiplier = newPeg;
237
+
238
+ console.log(
239
+ 'Price moves from',
240
+ convertToNumber(prevMarketPrice),
241
+ 'to',
242
+ convertToNumber(calculateMarkPrice(marketNewPeg))
243
+ );
244
+
245
+ const cost = calculatePositionPNL(marketNewPeg, netUserPosition);
246
+
247
+ const k = market.amm.sqrtK.mul(market.amm.sqrtK);
248
+ const newQuoteAssetReserve = k.div(
249
+ market.amm.baseAssetReserve.add(netUserPosition.baseAssetAmount)
250
+ );
251
+ const deltaQuoteAssetReserves = newQuoteAssetReserve.sub(
252
+ market.amm.quoteAssetReserve
253
+ );
254
+ const cost2 = deltaQuoteAssetReserves
255
+ .mul(market.amm.pegMultiplier.sub(newPeg))
256
+ .div(AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO);
257
+ console.log(convertToNumber(cost2, QUOTE_PRECISION));
258
+ return cost;
259
+ }
260
+
133
261
  /**
134
262
  * Helper function calculating terminal price of amm
135
263
  *
@@ -187,3 +315,86 @@ export function calculateMaxBaseAssetAmountToTrade(
187
315
  return [new BN(0), PositionDirection.LONG];
188
316
  }
189
317
  }
318
+
319
+ export function calculateBudgetedK(market: Market, cost: BN): [BN, BN] {
320
+ // wolframalpha.com
321
+ // (1/(x+d) - p/(x*p+d))*y*d*Q = C solve for p
322
+ // p = (d(y*d*Q - C(x+d))) / (C*x(x+d) + y*y*d*Q)
323
+
324
+ // todo: assumes k = x * y
325
+ // otherwise use: (y(1-p) + (kp^2/(x*p+d)) - k/(x+d)) * Q = C solve for p
326
+
327
+ // const k = market.amm.sqrtK.mul(market.amm.sqrtK);
328
+ const x = market.amm.baseAssetReserve;
329
+ const y = market.amm.quoteAssetReserve;
330
+
331
+ const d = market.baseAssetAmount;
332
+ const Q = market.amm.pegMultiplier;
333
+
334
+ const C = cost.mul(new BN(-1));
335
+
336
+ const numer1 = y.mul(d).mul(Q).div(AMM_RESERVE_PRECISION).div(PEG_PRECISION);
337
+ const numer2 = C.mul(x.add(d)).div(QUOTE_PRECISION);
338
+ const denom1 = C.mul(x)
339
+ .mul(x.add(d))
340
+ .div(AMM_RESERVE_PRECISION)
341
+ .div(QUOTE_PRECISION);
342
+ const denom2 = y
343
+ .mul(d)
344
+ .mul(d)
345
+ .mul(Q)
346
+ .div(AMM_RESERVE_PRECISION)
347
+ .div(AMM_RESERVE_PRECISION)
348
+ .div(PEG_PRECISION);
349
+
350
+ const numerator = d
351
+ .mul(numer1.add(numer2))
352
+ .div(AMM_RESERVE_PRECISION)
353
+ .div(AMM_RESERVE_PRECISION)
354
+ .div(AMM_TO_QUOTE_PRECISION_RATIO);
355
+ const denominator = denom1
356
+ .add(denom2)
357
+ .div(AMM_RESERVE_PRECISION)
358
+ .div(AMM_TO_QUOTE_PRECISION_RATIO);
359
+ console.log(numerator, denominator);
360
+ // const p = (numerator).div(denominator);
361
+
362
+ // const formulaCost = (numer21.sub(numer20).sub(numer1)).mul(market.amm.pegMultiplier).div(AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO)
363
+ // console.log(convertToNumber(formulaCost, QUOTE_PRECISION))
364
+
365
+ return [numerator, denominator];
366
+ }
367
+
368
+ export function calculateBudgetedPeg(market: Market, cost: BN): BN {
369
+ // wolframalpha.com
370
+ // (1/(x+d) - p/(x*p+d))*y*d*Q = C solve for p
371
+ // p = (d(y*d*Q - C(x+d))) / (C*x(x+d) + y*y*d*Q)
372
+
373
+ // todo: assumes k = x * y
374
+ // otherwise use: (y(1-p) + (kp^2/(x*p+d)) - k/(x+d)) * Q = C solve for p
375
+
376
+ const k = market.amm.sqrtK.mul(market.amm.sqrtK);
377
+ const x = market.amm.baseAssetReserve;
378
+ const y = market.amm.quoteAssetReserve;
379
+
380
+ const d = market.baseAssetAmount;
381
+ const Q = market.amm.pegMultiplier;
382
+
383
+ const C = cost.mul(new BN(-1));
384
+
385
+ const deltaQuoteAssetReserves = y.sub(k.div(x.add(d)));
386
+ const deltaPegMultiplier = C.mul(MARK_PRICE_PRECISION)
387
+ .div(deltaQuoteAssetReserves.div(AMM_TO_QUOTE_PRECISION_RATIO))
388
+ .mul(PEG_PRECISION)
389
+ .div(QUOTE_PRECISION);
390
+ console.log(
391
+ Q.toNumber(),
392
+ 'change by',
393
+ deltaPegMultiplier.toNumber() / MARK_PRICE_PRECISION.toNumber()
394
+ );
395
+ const newPeg = Q.sub(
396
+ deltaPegMultiplier.mul(PEG_PRECISION).div(MARK_PRICE_PRECISION)
397
+ );
398
+
399
+ return newPeg;
400
+ }
@@ -0,0 +1,14 @@
1
+ export function promiseTimeout<T>(
2
+ promise: Promise<T>,
3
+ timeoutMs: number
4
+ ): Promise<T | null> {
5
+ let timeoutId: ReturnType<typeof setTimeout>;
6
+ const timeoutPromise: Promise<null> = new Promise((resolve) => {
7
+ timeoutId = setTimeout(() => resolve(null), timeoutMs);
8
+ });
9
+
10
+ return Promise.race([promise, timeoutPromise]).then((result: T | null) => {
11
+ clearTimeout(timeoutId);
12
+ return result;
13
+ });
14
+ }
@@ -1,32 +0,0 @@
1
- /// <reference types="bn.js" />
2
- import { BN } from '@project-serum/anchor';
3
- import { Market } from '../types';
4
- /**
5
- * Helper function calculating adjust k cost
6
- * @param market
7
- * @param marketIndex
8
- * @param numerator
9
- * @param denomenator
10
- * @returns cost : Precision QUOTE_ASSET_PRECISION
11
- */
12
- export declare function calculateAdjustKCost(market: Market, marketIndex: BN, numerator: BN, denomenator: BN): BN;
13
- /**
14
- * Helper function calculating adjust pegMultiplier (repeg) cost
15
- *
16
- * @param market
17
- * @param marketIndex
18
- * @param newPeg
19
- * @returns cost : Precision QUOTE_ASSET_PRECISION
20
- */
21
- export declare function calculateRepegCost(market: Market, marketIndex: BN, newPeg: BN): BN;
22
- /**
23
- * Helper function calculating adjust pegMultiplier (repeg) cost
24
- *
25
- * @param market
26
- * @param marketIndex
27
- * @param newPeg
28
- * @returns cost : Precision QUOTE_ASSET_PRECISION
29
- */
30
- export declare function calculateReserveRebalanceCost(market: Market, marketIndex: BN): BN;
31
- export declare function calculateBudgetedK(market: Market, cost: BN): [BN, BN];
32
- export declare function calculateBudgetedPeg(market: Market, cost: BN): BN;
package/lib/math/repeg.js DELETED
@@ -1,178 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.calculateBudgetedPeg = exports.calculateBudgetedK = exports.calculateReserveRebalanceCost = exports.calculateRepegCost = exports.calculateAdjustKCost = void 0;
4
- const anchor_1 = require("@project-serum/anchor");
5
- const numericConstants_1 = require("../constants/numericConstants");
6
- const position_1 = require("./position");
7
- const amm_1 = require("./amm");
8
- const __1 = require("..");
9
- /**
10
- * Helper function calculating adjust k cost
11
- * @param market
12
- * @param marketIndex
13
- * @param numerator
14
- * @param denomenator
15
- * @returns cost : Precision QUOTE_ASSET_PRECISION
16
- */
17
- function calculateAdjustKCost(market, marketIndex, numerator, denomenator) {
18
- const netUserPosition = {
19
- baseAssetAmount: market.baseAssetAmount,
20
- lastCumulativeFundingRate: market.amm.cumulativeFundingRate,
21
- marketIndex: new anchor_1.BN(marketIndex),
22
- quoteAssetAmount: numericConstants_1.ZERO,
23
- openOrders: numericConstants_1.ZERO,
24
- };
25
- const currentValue = (0, position_1.calculateBaseAssetValue)(market, netUserPosition);
26
- const marketNewK = Object.assign({}, market);
27
- marketNewK.amm = Object.assign({}, market.amm);
28
- marketNewK.amm.baseAssetReserve = market.amm.baseAssetReserve
29
- .mul(numerator)
30
- .div(denomenator);
31
- marketNewK.amm.quoteAssetReserve = market.amm.quoteAssetReserve
32
- .mul(numerator)
33
- .div(denomenator);
34
- marketNewK.amm.sqrtK = market.amm.sqrtK.mul(numerator).div(denomenator);
35
- netUserPosition.quoteAssetAmount = currentValue;
36
- const cost = (0, __1.calculatePositionPNL)(marketNewK, netUserPosition);
37
- return cost;
38
- }
39
- exports.calculateAdjustKCost = calculateAdjustKCost;
40
- /**
41
- * Helper function calculating adjust pegMultiplier (repeg) cost
42
- *
43
- * @param market
44
- * @param marketIndex
45
- * @param newPeg
46
- * @returns cost : Precision QUOTE_ASSET_PRECISION
47
- */
48
- function calculateRepegCost(market, marketIndex, newPeg) {
49
- const netUserPosition = {
50
- baseAssetAmount: market.baseAssetAmount,
51
- lastCumulativeFundingRate: market.amm.cumulativeFundingRate,
52
- marketIndex: new anchor_1.BN(marketIndex),
53
- quoteAssetAmount: new anchor_1.BN(0),
54
- openOrders: numericConstants_1.ZERO,
55
- };
56
- const currentValue = (0, position_1.calculateBaseAssetValue)(market, netUserPosition);
57
- netUserPosition.quoteAssetAmount = currentValue;
58
- const prevMarketPrice = (0, __1.calculateMarkPrice)(market);
59
- const marketNewPeg = Object.assign({}, market);
60
- marketNewPeg.amm = Object.assign({}, market.amm);
61
- // const marketNewPeg = JSON.parse(JSON.stringify(market));
62
- marketNewPeg.amm.pegMultiplier = newPeg;
63
- console.log('Price moves from', (0, __1.convertToNumber)(prevMarketPrice), 'to', (0, __1.convertToNumber)((0, __1.calculateMarkPrice)(marketNewPeg)));
64
- const cost = (0, __1.calculatePositionPNL)(marketNewPeg, netUserPosition);
65
- return cost;
66
- }
67
- exports.calculateRepegCost = calculateRepegCost;
68
- /**
69
- * Helper function calculating adjust pegMultiplier (repeg) cost
70
- *
71
- * @param market
72
- * @param marketIndex
73
- * @param newPeg
74
- * @returns cost : Precision QUOTE_ASSET_PRECISION
75
- */
76
- function calculateReserveRebalanceCost(market, marketIndex) {
77
- const netUserPosition = {
78
- baseAssetAmount: market.baseAssetAmount,
79
- lastCumulativeFundingRate: market.amm.cumulativeFundingRate,
80
- marketIndex: new anchor_1.BN(marketIndex),
81
- quoteAssetAmount: new anchor_1.BN(0),
82
- openOrders: numericConstants_1.ZERO,
83
- };
84
- const currentValue = (0, position_1.calculateBaseAssetValue)(market, netUserPosition);
85
- netUserPosition.quoteAssetAmount = currentValue;
86
- const prevMarketPrice = (0, __1.calculateMarkPrice)(market);
87
- const marketNewPeg = Object.assign({}, market);
88
- marketNewPeg.amm = Object.assign({}, market.amm);
89
- // const marketNewPeg = JSON.parse(JSON.stringify(market));
90
- const newPeg = (0, amm_1.calculateTerminalPrice)(market)
91
- .mul(numericConstants_1.PEG_PRECISION)
92
- .div(numericConstants_1.MARK_PRICE_PRECISION);
93
- // const newPeg = prevMarketPrice.mul(PEG_PRECISION).div(MARK_PRICE_PRECISION);
94
- const newBaseReserve = market.amm.baseAssetReserve.add(market.baseAssetAmount);
95
- const newQuoteReserve = market.amm.sqrtK
96
- .mul(market.amm.sqrtK)
97
- .div(newBaseReserve);
98
- console.log('current reserves on close, quote:', (0, __1.convertToNumber)(newQuoteReserve, numericConstants_1.AMM_RESERVE_PRECISION), 'base:', (0, __1.convertToNumber)(newBaseReserve, numericConstants_1.AMM_RESERVE_PRECISION));
99
- let newSqrtK;
100
- if (newPeg.lt(market.amm.pegMultiplier)) {
101
- newSqrtK = newBaseReserve;
102
- }
103
- else {
104
- newSqrtK = newQuoteReserve;
105
- }
106
- marketNewPeg.amm.baseAssetReserve = newSqrtK.sub(market.baseAssetAmount); // newSqrtK.sub(market.baseAssetAmount);
107
- marketNewPeg.amm.quoteAssetReserve = newSqrtK
108
- .mul(newSqrtK)
109
- .div(marketNewPeg.amm.baseAssetReserve);
110
- marketNewPeg.amm.sqrtK = newSqrtK;
111
- marketNewPeg.amm.pegMultiplier = newPeg;
112
- console.log('Price moves from', (0, __1.convertToNumber)(prevMarketPrice), 'to', (0, __1.convertToNumber)((0, __1.calculateMarkPrice)(marketNewPeg)));
113
- const cost = (0, __1.calculatePositionPNL)(marketNewPeg, netUserPosition);
114
- return cost;
115
- }
116
- exports.calculateReserveRebalanceCost = calculateReserveRebalanceCost;
117
- function calculateBudgetedK(market, cost) {
118
- // wolframalpha.com
119
- // (1/(x+d) - p/(x*p+d))*y*d*Q = C solve for p
120
- // p = (d(y*d*Q - C(x+d))) / (C*x(x+d) + y*y*d*Q)
121
- // todo: assumes k = x * y
122
- // otherwise use: (y(1-p) + (kp^2/(x*p+d)) - k/(x+d)) * Q = C solve for p
123
- // const k = market.amm.sqrtK.mul(market.amm.sqrtK);
124
- const x = market.amm.baseAssetReserve;
125
- const y = market.amm.quoteAssetReserve;
126
- const d = market.baseAssetAmount;
127
- const Q = market.amm.pegMultiplier;
128
- const C = cost.mul(new anchor_1.BN(-1));
129
- const numer1 = y.mul(d).mul(Q).div(numericConstants_1.AMM_RESERVE_PRECISION).div(numericConstants_1.PEG_PRECISION);
130
- const numer2 = C.mul(x.add(d)).div(numericConstants_1.QUOTE_PRECISION);
131
- const denom1 = C.mul(x)
132
- .mul(x.add(d))
133
- .div(numericConstants_1.AMM_RESERVE_PRECISION)
134
- .div(numericConstants_1.QUOTE_PRECISION);
135
- const denom2 = y
136
- .mul(d)
137
- .mul(d)
138
- .mul(Q)
139
- .div(numericConstants_1.AMM_RESERVE_PRECISION)
140
- .div(numericConstants_1.AMM_RESERVE_PRECISION)
141
- .div(numericConstants_1.PEG_PRECISION);
142
- const numerator = d
143
- .mul(numer1.add(numer2))
144
- .div(numericConstants_1.AMM_RESERVE_PRECISION)
145
- .div(numericConstants_1.AMM_RESERVE_PRECISION)
146
- .div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO);
147
- const denominator = denom1
148
- .add(denom2)
149
- .div(numericConstants_1.AMM_RESERVE_PRECISION)
150
- .div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO);
151
- console.log(numerator, denominator);
152
- // const p = (numerator).div(denominator);
153
- // const formulaCost = (numer21.sub(numer20).sub(numer1)).mul(market.amm.pegMultiplier).div(AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO)
154
- // console.log(convertToNumber(formulaCost, QUOTE_PRECISION))
155
- return [numerator, denominator];
156
- }
157
- exports.calculateBudgetedK = calculateBudgetedK;
158
- function calculateBudgetedPeg(market, cost) {
159
- // wolframalpha.com
160
- // (1/(x+d) - p/(x*p+d))*y*d*Q = C solve for p
161
- // p = (d(y*d*Q - C(x+d))) / (C*x(x+d) + y*y*d*Q)
162
- // todo: assumes k = x * y
163
- // otherwise use: (y(1-p) + (kp^2/(x*p+d)) - k/(x+d)) * Q = C solve for p
164
- const k = market.amm.sqrtK.mul(market.amm.sqrtK);
165
- const x = market.amm.baseAssetReserve;
166
- const y = market.amm.quoteAssetReserve;
167
- const d = market.baseAssetAmount;
168
- const Q = market.amm.pegMultiplier;
169
- const C = cost.mul(new anchor_1.BN(-1));
170
- const deltaQuoteAssetReserves = y.sub(k.div(x.add(d)));
171
- const deltaPegMultiplier = C.mul(numericConstants_1.MARK_PRICE_PRECISION).div(deltaQuoteAssetReserves.div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO));
172
- // .mul(PEG_PRECISION)
173
- // .div(QUOTE_PRECISION);
174
- console.log(Q.toNumber(), 'change by', deltaPegMultiplier.toNumber() / numericConstants_1.MARK_PRICE_PRECISION.toNumber());
175
- const newPeg = Q.sub(deltaPegMultiplier.mul(numericConstants_1.PEG_PRECISION).div(numericConstants_1.MARK_PRICE_PRECISION));
176
- return newPeg;
177
- }
178
- exports.calculateBudgetedPeg = calculateBudgetedPeg;