@drift-labs/sdk 0.1.29-master.0 → 0.1.30-master.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 (68) hide show
  1. package/lib/accounts/bulkAccountLoader.d.ts +1 -0
  2. package/lib/accounts/bulkAccountLoader.js +33 -13
  3. package/lib/clearingHouse.d.ts +4 -1
  4. package/lib/clearingHouse.js +49 -0
  5. package/lib/constants/markets.js +11 -0
  6. package/lib/idl/clearing_house.json +63 -2
  7. package/lib/index.d.ts +1 -0
  8. package/lib/index.js +1 -0
  9. package/lib/math/amm.d.ts +0 -20
  10. package/lib/math/amm.js +1 -151
  11. package/lib/math/repeg.d.ts +32 -0
  12. package/lib/math/repeg.js +178 -0
  13. package/lib/oracles/pythClient.js +1 -1
  14. package/lib/orderParams.d.ts +1 -1
  15. package/lib/orderParams.js +2 -2
  16. package/lib/tx/retryTxSender.d.ts +5 -2
  17. package/lib/tx/retryTxSender.js +14 -1
  18. package/package.json +1 -1
  19. package/src/accounts/bulkAccountLoader.ts +40 -15
  20. package/src/clearingHouse.ts +71 -0
  21. package/src/constants/markets.ts +11 -0
  22. package/src/idl/clearing_house.json +63 -2
  23. package/src/index.ts +1 -0
  24. package/src/math/amm.ts +1 -212
  25. package/src/math/repeg.ts +253 -0
  26. package/src/oracles/pythClient.ts +1 -1
  27. package/src/orderParams.ts +3 -2
  28. package/src/tx/retryTxSender.ts +19 -1
  29. package/src/accounts/bulkUserSubscription.js +0 -56
  30. package/src/accounts/bulkUserSubscription.js.map +0 -1
  31. package/src/accounts/pollingUserAccountSubscriber.js +0 -139
  32. package/src/accounts/pollingUserAccountSubscriber.js.map +0 -1
  33. package/src/accounts/types.js +0 -11
  34. package/src/accounts/types.js.map +0 -1
  35. package/src/accounts/webSocketUserAccountSubscriber.js +0 -78
  36. package/src/accounts/webSocketUserAccountSubscriber.js.map +0 -1
  37. package/src/addresses.js +0 -59
  38. package/src/addresses.js.map +0 -1
  39. package/src/admin.js +0 -443
  40. package/src/admin.js.map +0 -1
  41. package/src/clearingHouseUser.js +0 -581
  42. package/src/clearingHouseUser.js.map +0 -1
  43. package/src/config.js +0 -37
  44. package/src/config.js.map +0 -1
  45. package/src/factory/clearingHouse.js +0 -65
  46. package/src/factory/clearingHouse.js.map +0 -1
  47. package/src/factory/clearingHouseUser.js +0 -35
  48. package/src/factory/clearingHouseUser.js.map +0 -1
  49. package/src/factory/oracleClient.js +0 -17
  50. package/src/factory/oracleClient.js.map +0 -1
  51. package/src/index.js +0 -56
  52. package/src/index.js.map +0 -1
  53. package/src/math/amm.js +0 -285
  54. package/src/math/amm.js.map +0 -1
  55. package/src/mockUSDCFaucet.js +0 -143
  56. package/src/mockUSDCFaucet.js.map +0 -1
  57. package/src/oracles/pythClient.js +0 -39
  58. package/src/oracles/pythClient.js.map +0 -1
  59. package/src/orderParams.js +0 -109
  60. package/src/orderParams.js.map +0 -1
  61. package/src/orders.js +0 -172
  62. package/src/orders.js.map +0 -1
  63. package/src/tx/retryTxSender.js +0 -137
  64. package/src/tx/retryTxSender.js.map +0 -1
  65. package/src/types.js +0 -61
  66. package/src/types.js.map +0 -1
  67. package/src/wallet.js +0 -23
  68. package/src/wallet.js.map +0 -1
@@ -29,5 +29,6 @@ export declare class BulkAccountLoader {
29
29
  getAccountData(publicKey: PublicKey): Buffer | undefined;
30
30
  startPolling(): void;
31
31
  stopPolling(): void;
32
+ log(msg: string): void;
32
33
  }
33
34
  export {};
@@ -29,11 +29,14 @@ class BulkAccountLoader {
29
29
  addAccount(publicKey, callback) {
30
30
  const existingSize = this.accountsToLoad.size;
31
31
  const callbackId = (0, uuid_1.v4)();
32
+ this.log(`Adding account ${publicKey.toString()} callback id ${callbackId}`);
32
33
  const existingAccountToLoad = this.accountsToLoad.get(publicKey.toString());
33
34
  if (existingAccountToLoad) {
35
+ this.log(`account already exists`);
34
36
  existingAccountToLoad.callbacks.set(callbackId, callback);
35
37
  }
36
38
  else {
39
+ this.log(`account doesn't already exist. creating new callback map`);
37
40
  const callbacks = new Map();
38
41
  callbacks.set(callbackId, callback);
39
42
  const newAccountToLoad = {
@@ -50,6 +53,7 @@ class BulkAccountLoader {
50
53
  return callbackId;
51
54
  }
52
55
  removeAccount(publicKey, callbackId) {
56
+ this.log(`Removing account ${publicKey.toString()} callback id ${callbackId}`);
53
57
  const existingAccountToLoad = this.accountsToLoad.get(publicKey.toString());
54
58
  if (existingAccountToLoad) {
55
59
  existingAccountToLoad.callbacks.delete(callbackId);
@@ -78,13 +82,16 @@ class BulkAccountLoader {
78
82
  load() {
79
83
  return __awaiter(this, void 0, void 0, function* () {
80
84
  if (this.loadPromise) {
85
+ this.log(`Load promise exists. Returning early`);
81
86
  return this.loadPromise;
82
87
  }
83
88
  this.loadPromise = new Promise((resolver) => {
84
89
  this.loadPromiseResolver = resolver;
85
90
  });
91
+ this.log(`Loading`);
86
92
  try {
87
93
  const chunks = this.chunks(Array.from(this.accountsToLoad.values()), GET_MULTIPLE_ACCOUNTS_CHUNK_SIZE);
94
+ this.log(`${chunks.length} chunks`);
88
95
  yield Promise.all(chunks.map((chunk) => {
89
96
  return this.loadChunk(chunk);
90
97
  }));
@@ -95,15 +102,15 @@ class BulkAccountLoader {
95
102
  for (const [_, callback] of this.errorCallbacks) {
96
103
  callback(e);
97
104
  }
105
+ this.log('finished error callbacks');
98
106
  }
99
107
  finally {
108
+ this.log(`resetting load promise`);
100
109
  this.loadPromiseResolver();
101
110
  this.loadPromise = undefined;
102
111
  const now = Date.now();
103
112
  if (now - this.lastUpdate > fiveMinutes) {
104
- if (this.loggingEnabled) {
105
- console.log("Haven't seen updated account in five minutes. Bulk account loader creating new Connection Object");
106
- }
113
+ this.log("Haven't seen updated account in five minutes. Bulk account loader creating new Connection Object");
107
114
  this.connection = new web3_js_1.Connection(
108
115
  // @ts-ignore
109
116
  this.connection._rpcEndpoint, this.connection.commitment);
@@ -114,6 +121,7 @@ class BulkAccountLoader {
114
121
  loadChunk(accountsToLoad) {
115
122
  return __awaiter(this, void 0, void 0, function* () {
116
123
  if (accountsToLoad.length === 0) {
124
+ this.log(`no accounts in chunk`);
117
125
  return;
118
126
  }
119
127
  const args = [
@@ -125,8 +133,8 @@ class BulkAccountLoader {
125
133
  // @ts-ignore
126
134
  const rpcResponse = yield this.connection._rpcRequest('getMultipleAccounts', args);
127
135
  const oneMinuteSinceLastUpdate = Date.now() - this.lastUpdate > oneMinute;
128
- if (this.loggingEnabled && oneMinuteSinceLastUpdate) {
129
- console.log('rpcResponse', JSON.stringify(rpcResponse));
136
+ if (oneMinuteSinceLastUpdate) {
137
+ this.log('rpcResponse ' + JSON.stringify(rpcResponse));
130
138
  }
131
139
  const newSlot = rpcResponse.result.context.slot;
132
140
  for (const i in accountsToLoad) {
@@ -139,10 +147,11 @@ class BulkAccountLoader {
139
147
  const dataType = rpcResponse.result.value[i].data[1];
140
148
  newBuffer = Buffer.from(raw, dataType);
141
149
  }
142
- if (this.loggingEnabled && oneMinuteSinceLastUpdate) {
143
- console.log('oldRPCResponse', oldRPCResponse);
150
+ if (oneMinuteSinceLastUpdate) {
151
+ this.log('oldRPCResponse' + oldRPCResponse);
144
152
  }
145
153
  if (!oldRPCResponse) {
154
+ this.log('No old rpc response, updating account data');
146
155
  this.accountData.set(key, {
147
156
  slot: newSlot,
148
157
  buffer: newBuffer,
@@ -152,10 +161,12 @@ class BulkAccountLoader {
152
161
  continue;
153
162
  }
154
163
  if (newSlot <= oldRPCResponse.slot) {
164
+ this.log(`new slot ${newSlot} old slot ${oldRPCResponse.slot}`);
155
165
  continue;
156
166
  }
157
167
  const oldBuffer = oldRPCResponse.buffer;
158
168
  if (newBuffer && (!oldBuffer || !newBuffer.equals(oldBuffer))) {
169
+ this.log('new buffer, updating account data');
159
170
  this.accountData.set(key, {
160
171
  slot: newSlot,
161
172
  buffer: newBuffer,
@@ -163,13 +174,21 @@ class BulkAccountLoader {
163
174
  this.handleAccountCallbacks(accountToLoad, newBuffer);
164
175
  this.lastUpdate = Date.now();
165
176
  }
177
+ else {
178
+ this.log('unable to update account for newest slot');
179
+ this.log('oldBuffer ' + oldBuffer);
180
+ this.log('newBuffer ' + newBuffer);
181
+ this.log('buffers equal ' + newBuffer.equals(oldBuffer));
182
+ }
166
183
  }
167
184
  });
168
185
  }
169
186
  handleAccountCallbacks(accountToLoad, buffer) {
187
+ this.log('handling account callbacks');
170
188
  for (const [_, callback] of accountToLoad.callbacks) {
171
189
  callback(buffer);
172
190
  }
191
+ this.log('finished account callbacks');
173
192
  }
174
193
  getAccountData(publicKey) {
175
194
  const accountData = this.accountData.get(publicKey.toString());
@@ -179,18 +198,19 @@ class BulkAccountLoader {
179
198
  if (this.intervalId) {
180
199
  return;
181
200
  }
182
- if (this.loggingEnabled) {
183
- console.log(`startPolling`);
184
- }
201
+ this.log('startPolling');
185
202
  this.intervalId = setInterval(this.load.bind(this), this.pollingFrequency);
186
203
  }
187
204
  stopPolling() {
188
205
  if (this.intervalId) {
189
206
  clearInterval(this.intervalId);
190
207
  this.intervalId = undefined;
191
- if (this.loggingEnabled) {
192
- console.log(`stopPolling`);
193
- }
208
+ this.log('stopPolling');
209
+ }
210
+ }
211
+ log(msg) {
212
+ if (this.loggingEnabled) {
213
+ console.log(msg);
194
214
  }
195
215
  }
196
216
  }
@@ -1,7 +1,7 @@
1
1
  /// <reference types="node" />
2
2
  /// <reference types="bn.js" />
3
3
  import { BN, Program, Provider } from '@project-serum/anchor';
4
- import { MarketsAccount, StateAccount, DepositHistoryAccount, FundingPaymentHistoryAccount, FundingRateHistoryAccount, IWallet, LiquidationHistoryAccount, PositionDirection, TradeHistoryAccount, UserAccount, Market, OrderHistoryAccount, OrderStateAccount, OrderParams, Order, ExtendedCurveHistoryAccount } from './types';
4
+ import { MarketsAccount, StateAccount, DepositHistoryAccount, FundingPaymentHistoryAccount, FundingRateHistoryAccount, IWallet, LiquidationHistoryAccount, PositionDirection, TradeHistoryAccount, UserAccount, Market, OrderHistoryAccount, OrderStateAccount, OrderParams, Order, ExtendedCurveHistoryAccount, UserPositionsAccount } from './types';
5
5
  import { Connection, PublicKey, TransactionSignature, Keypair, ConfirmOptions, TransactionInstruction } from '@solana/web3.js';
6
6
  import { MockUSDCFaucet } from './mockUSDCFaucet';
7
7
  import { EventEmitter } from 'events';
@@ -127,6 +127,8 @@ export declare class ClearingHouse {
127
127
  getCancelOrderIx(orderId: BN, oracle?: PublicKey): Promise<TransactionInstruction>;
128
128
  cancelOrderByUserId(userOrderId: number, oracle?: PublicKey): Promise<TransactionSignature>;
129
129
  getCancelOrderByUserIdIx(userOrderId: number, oracle?: PublicKey): Promise<TransactionInstruction>;
130
+ cancelAllOrders(oracles?: PublicKey[]): Promise<TransactionSignature>;
131
+ getCancelAllOrdersIx(oracles: PublicKey[]): Promise<TransactionInstruction>;
130
132
  fillOrder(userAccountPublicKey: PublicKey, userOrdersAccountPublicKey: PublicKey, order: Order): Promise<TransactionSignature>;
131
133
  getFillOrderIx(userAccountPublicKey: PublicKey, userOrdersAccountPublicKey: PublicKey, order: Order): Promise<TransactionInstruction>;
132
134
  initializeUserOrdersThenPlaceAndFillOrder(orderParams: OrderParams, discountToken?: PublicKey, referrer?: PublicKey): Promise<TransactionSignature>;
@@ -141,6 +143,7 @@ export declare class ClearingHouse {
141
143
  */
142
144
  closePosition(marketIndex: BN, discountToken?: PublicKey, referrer?: PublicKey): Promise<TransactionSignature>;
143
145
  getClosePositionIx(marketIndex: BN, discountToken?: PublicKey, referrer?: PublicKey): Promise<TransactionInstruction>;
146
+ closeAllPositions(userPositionsAccount: UserPositionsAccount, discountToken?: PublicKey, referrer?: PublicKey): Promise<TransactionSignature>;
144
147
  liquidate(liquidateeUserAccountPublicKey: PublicKey): Promise<TransactionSignature>;
145
148
  getLiquidateIx(liquidateeUserAccountPublicKey: PublicKey): Promise<TransactionInstruction>;
146
149
  updateFundingRate(oracle: PublicKey, marketIndex: BN): Promise<TransactionSignature>;
@@ -634,6 +634,42 @@ class ClearingHouse {
634
634
  });
635
635
  });
636
636
  }
637
+ cancelAllOrders(oracles) {
638
+ return __awaiter(this, void 0, void 0, function* () {
639
+ return yield this.txSender.send((0, utils_1.wrapInTx)(yield this.getCancelAllOrdersIx(oracles)), [], this.opts);
640
+ });
641
+ }
642
+ getCancelAllOrdersIx(oracles) {
643
+ return __awaiter(this, void 0, void 0, function* () {
644
+ const userAccountPublicKey = yield this.getUserAccountPublicKey();
645
+ const userAccount = yield this.getUserAccount();
646
+ const state = this.getStateAccount();
647
+ const orderState = this.getOrderStateAccount();
648
+ const remainingAccounts = [];
649
+ for (const oracle of oracles) {
650
+ remainingAccounts.push({
651
+ pubkey: oracle,
652
+ isWritable: false,
653
+ isSigner: false,
654
+ });
655
+ }
656
+ return yield this.program.instruction.cancelAllOrders({
657
+ accounts: {
658
+ state: yield this.getStatePublicKey(),
659
+ user: userAccountPublicKey,
660
+ authority: this.wallet.publicKey,
661
+ markets: state.markets,
662
+ userOrders: yield this.getUserOrdersAccountPublicKey(),
663
+ userPositions: userAccount.positions,
664
+ fundingPaymentHistory: state.fundingPaymentHistory,
665
+ fundingRateHistory: state.fundingRateHistory,
666
+ orderState: yield this.getOrderStatePublicKey(),
667
+ orderHistory: orderState.orderHistory,
668
+ },
669
+ remainingAccounts,
670
+ });
671
+ });
672
+ }
637
673
  fillOrder(userAccountPublicKey, userOrdersAccountPublicKey, order) {
638
674
  return __awaiter(this, void 0, void 0, function* () {
639
675
  return yield this.txSender.send((0, utils_1.wrapInTx)(yield this.getFillOrderIx(userAccountPublicKey, userOrdersAccountPublicKey, order)), [], this.opts);
@@ -801,6 +837,19 @@ class ClearingHouse {
801
837
  });
802
838
  });
803
839
  }
840
+ closeAllPositions(userPositionsAccount, discountToken, referrer) {
841
+ return __awaiter(this, void 0, void 0, function* () {
842
+ const ixs = [];
843
+ for (const userPosition of userPositionsAccount.positions) {
844
+ if (userPosition.baseAssetAmount.eq(numericConstants_1.ZERO)) {
845
+ continue;
846
+ }
847
+ ixs.push(yield this.getClosePositionIx(userPosition.marketIndex, discountToken, referrer));
848
+ }
849
+ const tx = new web3_js_1.Transaction().add(...ixs);
850
+ return this.txSender.send(tx, [], this.opts);
851
+ });
852
+ }
804
853
  liquidate(liquidateeUserAccountPublicKey) {
805
854
  return __awaiter(this, void 0, void 0, function* () {
806
855
  return this.txSender.send((0, utils_1.wrapInTx)(yield this.getLiquidateIx(liquidateeUserAccountPublicKey)), [], this.opts);
@@ -177,6 +177,17 @@ exports.Markets = [
177
177
  launchTs: 1648607439000,
178
178
  oracleSource: __1.OracleSource.PYTH,
179
179
  },
180
+ {
181
+ fullName: 'Near',
182
+ category: ['L1', 'Infra'],
183
+ symbol: 'NEAR-PERP',
184
+ baseAssetSymbol: 'NEAR',
185
+ marketIndex: new __1.BN(16),
186
+ devnetPublicKey: '3gnSbT7bhoTdGkFVZc1dW1PvjreWzpUNUD5ppXwv1N59',
187
+ mainnetPublicKey: 'ECSFWQ1bnnpqPVvoy9237t2wddZAaHisW88mYxuEHKWf',
188
+ launchTs: 1649105516000,
189
+ oracleSource: __1.OracleSource.PYTH,
190
+ },
180
191
  // {
181
192
  // symbol: 'mSOL-PERP',
182
193
  // baseAssetSymbol: 'mSOL',
@@ -677,6 +677,57 @@
677
677
  }
678
678
  ]
679
679
  },
680
+ {
681
+ "name": "cancelAllOrders",
682
+ "accounts": [
683
+ {
684
+ "name": "state",
685
+ "isMut": false,
686
+ "isSigner": false
687
+ },
688
+ {
689
+ "name": "orderState",
690
+ "isMut": false,
691
+ "isSigner": false
692
+ },
693
+ {
694
+ "name": "user",
695
+ "isMut": false,
696
+ "isSigner": false
697
+ },
698
+ {
699
+ "name": "authority",
700
+ "isMut": false,
701
+ "isSigner": true
702
+ },
703
+ {
704
+ "name": "markets",
705
+ "isMut": false,
706
+ "isSigner": false
707
+ },
708
+ {
709
+ "name": "userPositions",
710
+ "isMut": true,
711
+ "isSigner": false
712
+ },
713
+ {
714
+ "name": "userOrders",
715
+ "isMut": true,
716
+ "isSigner": false
717
+ },
718
+ {
719
+ "name": "fundingPaymentHistory",
720
+ "isMut": true,
721
+ "isSigner": false
722
+ },
723
+ {
724
+ "name": "orderHistory",
725
+ "isMut": true,
726
+ "isSigner": false
727
+ }
728
+ ],
729
+ "args": []
730
+ },
680
731
  {
681
732
  "name": "expireOrders",
682
733
  "accounts": [
@@ -1444,6 +1495,11 @@
1444
1495
  "isMut": true,
1445
1496
  "isSigner": false
1446
1497
  },
1498
+ {
1499
+ "name": "userOrders",
1500
+ "isMut": true,
1501
+ "isSigner": false
1502
+ },
1447
1503
  {
1448
1504
  "name": "authority",
1449
1505
  "isMut": false,
@@ -3236,8 +3292,8 @@
3236
3292
  "type": "u128"
3237
3293
  },
3238
3294
  {
3239
- "name": "padding1",
3240
- "type": "u64"
3295
+ "name": "netRevenueSinceLastFunding",
3296
+ "type": "i64"
3241
3297
  },
3242
3298
  {
3243
3299
  "name": "padding2",
@@ -4244,6 +4300,11 @@
4244
4300
  "code": 6060,
4245
4301
  "name": "CantExpireOrders",
4246
4302
  "msg": "CantExpireOrders"
4303
+ },
4304
+ {
4305
+ "code": 6061,
4306
+ "name": "InvalidRepegPriceImpact",
4307
+ "msg": "AMM repeg mark price impact vs oracle too large"
4247
4308
  }
4248
4309
  ]
4249
4310
  }
package/lib/index.d.ts CHANGED
@@ -28,6 +28,7 @@ export * from './math/position';
28
28
  export * from './math/amm';
29
29
  export * from './math/trade';
30
30
  export * from './math/orders';
31
+ export * from './math/repeg';
31
32
  export * from './orders';
32
33
  export * from './orderParams';
33
34
  export * from './wallet';
package/lib/index.js CHANGED
@@ -47,6 +47,7 @@ __exportStar(require("./math/position"), exports);
47
47
  __exportStar(require("./math/amm"), exports);
48
48
  __exportStar(require("./math/trade"), exports);
49
49
  __exportStar(require("./math/orders"), exports);
50
+ __exportStar(require("./math/repeg"), exports);
50
51
  __exportStar(require("./orders"), exports);
51
52
  __exportStar(require("./orderParams"), exports);
52
53
  __exportStar(require("./wallet"), exports);
package/lib/math/amm.d.ts CHANGED
@@ -38,24 +38,6 @@ export declare function calculateSwapOutput(inputAssetReserve: BN, swapAmount: B
38
38
  * @param positionDirection
39
39
  */
40
40
  export declare function getSwapDirection(inputAssetType: AssetType, positionDirection: PositionDirection): SwapDirection;
41
- /**
42
- * Helper function calculating adjust k cost
43
- * @param market
44
- * @param marketIndex
45
- * @param numerator
46
- * @param denomenator
47
- * @returns cost : Precision QUOTE_ASSET_PRECISION
48
- */
49
- export declare function calculateAdjustKCost(market: Market, marketIndex: BN, numerator: BN, denomenator: BN): BN;
50
- /**
51
- * Helper function calculating adjust pegMultiplier (repeg) cost
52
- *
53
- * @param market
54
- * @param marketIndex
55
- * @param newPeg
56
- * @returns cost : Precision QUOTE_ASSET_PRECISION
57
- */
58
- export declare function calculateRepegCost(market: Market, marketIndex: BN, newPeg: BN): BN;
59
41
  /**
60
42
  * Helper function calculating terminal price of amm
61
43
  *
@@ -64,5 +46,3 @@ export declare function calculateRepegCost(market: Market, marketIndex: BN, newP
64
46
  */
65
47
  export declare function calculateTerminalPrice(market: Market): BN;
66
48
  export declare function calculateMaxBaseAssetAmountToTrade(amm: AMM, limit_price: BN): [BN, PositionDirection];
67
- export declare function calculateBudgetedK(market: Market, cost: BN): [BN, BN];
68
- export declare function calculateBudgetedPeg(market: Market, cost: BN): BN;
package/lib/math/amm.js CHANGED
@@ -1,9 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.calculateBudgetedPeg = exports.calculateBudgetedK = exports.calculateMaxBaseAssetAmountToTrade = exports.calculateTerminalPrice = exports.calculateRepegCost = exports.calculateAdjustKCost = exports.getSwapDirection = exports.calculateSwapOutput = exports.calculateAmmReservesAfterSwap = exports.calculatePrice = void 0;
3
+ exports.calculateMaxBaseAssetAmountToTrade = exports.calculateTerminalPrice = exports.getSwapDirection = exports.calculateSwapOutput = exports.calculateAmmReservesAfterSwap = exports.calculatePrice = void 0;
4
4
  const anchor_1 = require("@project-serum/anchor");
5
5
  const numericConstants_1 = require("../constants/numericConstants");
6
- const position_1 = require("./position");
7
6
  const types_1 = require("../types");
8
7
  const assert_1 = require("../assert/assert");
9
8
  const __1 = require("..");
@@ -88,92 +87,6 @@ function getSwapDirection(inputAssetType, positionDirection) {
88
87
  return types_1.SwapDirection.ADD;
89
88
  }
90
89
  exports.getSwapDirection = getSwapDirection;
91
- /**
92
- * Helper function calculating adjust k cost
93
- * @param market
94
- * @param marketIndex
95
- * @param numerator
96
- * @param denomenator
97
- * @returns cost : Precision QUOTE_ASSET_PRECISION
98
- */
99
- function calculateAdjustKCost(market, marketIndex, numerator, denomenator) {
100
- const netUserPosition = {
101
- baseAssetAmount: market.baseAssetAmount,
102
- lastCumulativeFundingRate: market.amm.cumulativeFundingRate,
103
- marketIndex: new anchor_1.BN(marketIndex),
104
- quoteAssetAmount: new anchor_1.BN(0),
105
- openOrders: new anchor_1.BN(0),
106
- };
107
- const currentValue = (0, position_1.calculateBaseAssetValue)(market, netUserPosition);
108
- const marketNewK = Object.assign({}, market);
109
- marketNewK.amm = Object.assign({}, market.amm);
110
- marketNewK.amm.baseAssetReserve = market.amm.baseAssetReserve
111
- .mul(numerator)
112
- .div(denomenator);
113
- marketNewK.amm.quoteAssetReserve = market.amm.quoteAssetReserve
114
- .mul(numerator)
115
- .div(denomenator);
116
- marketNewK.amm.sqrtK = market.amm.sqrtK.mul(numerator).div(denomenator);
117
- netUserPosition.quoteAssetAmount = currentValue;
118
- const cost = (0, __1.calculatePositionPNL)(marketNewK, netUserPosition);
119
- const p = numericConstants_1.PEG_PRECISION.mul(numerator).div(denomenator);
120
- const x = market.amm.baseAssetReserve;
121
- const y = market.amm.quoteAssetReserve;
122
- const delta = market.baseAssetAmount;
123
- const k = market.amm.sqrtK.mul(market.amm.sqrtK);
124
- const numer1 = numericConstants_1.PEG_PRECISION.sub(p).mul(y).div(numericConstants_1.PEG_PRECISION);
125
- const numer20 = k
126
- .mul(p)
127
- .mul(p)
128
- .div(numericConstants_1.PEG_PRECISION)
129
- .div(numericConstants_1.PEG_PRECISION)
130
- .div(x.mul(p).div(numericConstants_1.PEG_PRECISION).add(delta));
131
- const numer21 = k.div(x.add(delta));
132
- const formulaCost = numer21
133
- .sub(numer20)
134
- .sub(numer1)
135
- .mul(market.amm.pegMultiplier)
136
- .div(numericConstants_1.AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO);
137
- console.log((0, __1.convertToNumber)(formulaCost, numericConstants_1.QUOTE_PRECISION));
138
- // p.div(p.mul(x).add(delta)).sub()
139
- return cost;
140
- }
141
- exports.calculateAdjustKCost = calculateAdjustKCost;
142
- /**
143
- * Helper function calculating adjust pegMultiplier (repeg) cost
144
- *
145
- * @param market
146
- * @param marketIndex
147
- * @param newPeg
148
- * @returns cost : Precision QUOTE_ASSET_PRECISION
149
- */
150
- function calculateRepegCost(market, marketIndex, newPeg) {
151
- const netUserPosition = {
152
- baseAssetAmount: market.baseAssetAmount,
153
- lastCumulativeFundingRate: market.amm.cumulativeFundingRate,
154
- marketIndex: new anchor_1.BN(marketIndex),
155
- quoteAssetAmount: new anchor_1.BN(0),
156
- openOrders: new anchor_1.BN(0),
157
- };
158
- const currentValue = (0, position_1.calculateBaseAssetValue)(market, netUserPosition);
159
- netUserPosition.quoteAssetAmount = currentValue;
160
- const prevMarketPrice = (0, __1.calculateMarkPrice)(market);
161
- const marketNewPeg = Object.assign({}, market);
162
- marketNewPeg.amm = Object.assign({}, market.amm);
163
- // const marketNewPeg = JSON.parse(JSON.stringify(market));
164
- marketNewPeg.amm.pegMultiplier = newPeg;
165
- console.log('Price moves from', (0, __1.convertToNumber)(prevMarketPrice), 'to', (0, __1.convertToNumber)((0, __1.calculateMarkPrice)(marketNewPeg)));
166
- const cost = (0, __1.calculatePositionPNL)(marketNewPeg, netUserPosition);
167
- const k = market.amm.sqrtK.mul(market.amm.sqrtK);
168
- const newQuoteAssetReserve = k.div(market.amm.baseAssetReserve.add(netUserPosition.baseAssetAmount));
169
- const deltaQuoteAssetReserves = newQuoteAssetReserve.sub(market.amm.quoteAssetReserve);
170
- const cost2 = deltaQuoteAssetReserves
171
- .mul(market.amm.pegMultiplier.sub(newPeg))
172
- .div(numericConstants_1.AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO);
173
- console.log((0, __1.convertToNumber)(cost2, numericConstants_1.QUOTE_PRECISION));
174
- return cost;
175
- }
176
- exports.calculateRepegCost = calculateRepegCost;
177
90
  /**
178
91
  * Helper function calculating terminal price of amm
179
92
  *
@@ -219,66 +132,3 @@ function calculateMaxBaseAssetAmountToTrade(amm, limit_price) {
219
132
  }
220
133
  }
221
134
  exports.calculateMaxBaseAssetAmountToTrade = calculateMaxBaseAssetAmountToTrade;
222
- function calculateBudgetedK(market, cost) {
223
- // wolframalpha.com
224
- // (1/(x+d) - p/(x*p+d))*y*d*Q = C solve for p
225
- // p = (d(y*d*Q - C(x+d))) / (C*x(x+d) + y*y*d*Q)
226
- // todo: assumes k = x * y
227
- // otherwise use: (y(1-p) + (kp^2/(x*p+d)) - k/(x+d)) * Q = C solve for p
228
- // const k = market.amm.sqrtK.mul(market.amm.sqrtK);
229
- const x = market.amm.baseAssetReserve;
230
- const y = market.amm.quoteAssetReserve;
231
- const d = market.baseAssetAmount;
232
- const Q = market.amm.pegMultiplier;
233
- const C = cost.mul(new anchor_1.BN(-1));
234
- const numer1 = y.mul(d).mul(Q).div(numericConstants_1.AMM_RESERVE_PRECISION).div(numericConstants_1.PEG_PRECISION);
235
- const numer2 = C.mul(x.add(d)).div(numericConstants_1.QUOTE_PRECISION);
236
- const denom1 = C.mul(x)
237
- .mul(x.add(d))
238
- .div(numericConstants_1.AMM_RESERVE_PRECISION)
239
- .div(numericConstants_1.QUOTE_PRECISION);
240
- const denom2 = y
241
- .mul(d)
242
- .mul(d)
243
- .mul(Q)
244
- .div(numericConstants_1.AMM_RESERVE_PRECISION)
245
- .div(numericConstants_1.AMM_RESERVE_PRECISION)
246
- .div(numericConstants_1.PEG_PRECISION);
247
- const numerator = d
248
- .mul(numer1.add(numer2))
249
- .div(numericConstants_1.AMM_RESERVE_PRECISION)
250
- .div(numericConstants_1.AMM_RESERVE_PRECISION)
251
- .div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO);
252
- const denominator = denom1
253
- .add(denom2)
254
- .div(numericConstants_1.AMM_RESERVE_PRECISION)
255
- .div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO);
256
- console.log(numerator, denominator);
257
- // const p = (numerator).div(denominator);
258
- // const formulaCost = (numer21.sub(numer20).sub(numer1)).mul(market.amm.pegMultiplier).div(AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO)
259
- // console.log(convertToNumber(formulaCost, QUOTE_PRECISION))
260
- return [numerator, denominator];
261
- }
262
- exports.calculateBudgetedK = calculateBudgetedK;
263
- function calculateBudgetedPeg(market, cost) {
264
- // wolframalpha.com
265
- // (1/(x+d) - p/(x*p+d))*y*d*Q = C solve for p
266
- // p = (d(y*d*Q - C(x+d))) / (C*x(x+d) + y*y*d*Q)
267
- // todo: assumes k = x * y
268
- // otherwise use: (y(1-p) + (kp^2/(x*p+d)) - k/(x+d)) * Q = C solve for p
269
- const k = market.amm.sqrtK.mul(market.amm.sqrtK);
270
- const x = market.amm.baseAssetReserve;
271
- const y = market.amm.quoteAssetReserve;
272
- const d = market.baseAssetAmount;
273
- const Q = market.amm.pegMultiplier;
274
- const C = cost.mul(new anchor_1.BN(-1));
275
- const deltaQuoteAssetReserves = y.sub(k.div(x.add(d)));
276
- const deltaPegMultiplier = C.mul(numericConstants_1.MARK_PRICE_PRECISION)
277
- .div(deltaQuoteAssetReserves.div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO))
278
- .mul(numericConstants_1.PEG_PRECISION)
279
- .div(numericConstants_1.QUOTE_PRECISION);
280
- console.log(Q.toNumber(), 'change by', deltaPegMultiplier.toNumber() / numericConstants_1.MARK_PRICE_PRECISION.toNumber());
281
- const newPeg = Q.sub(deltaPegMultiplier.mul(numericConstants_1.PEG_PRECISION).div(numericConstants_1.MARK_PRICE_PRECISION));
282
- return newPeg;
283
- }
284
- exports.calculateBudgetedPeg = calculateBudgetedPeg;
@@ -0,0 +1,32 @@
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;