@drift-labs/sdk 0.2.0-master.20 → 0.2.0-master.23

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 (52) hide show
  1. package/lib/addresses/pda.d.ts +3 -0
  2. package/lib/addresses/pda.js +23 -1
  3. package/lib/admin.d.ts +3 -0
  4. package/lib/admin.js +31 -0
  5. package/lib/clearingHouse.d.ts +11 -4
  6. package/lib/clearingHouse.js +157 -23
  7. package/lib/clearingHouseUser.d.ts +9 -1
  8. package/lib/clearingHouseUser.js +62 -25
  9. package/lib/config.js +1 -1
  10. package/lib/constants/banks.d.ts +2 -0
  11. package/lib/constants/banks.js +9 -0
  12. package/lib/constants/numericConstants.d.ts +2 -0
  13. package/lib/constants/numericConstants.js +4 -1
  14. package/lib/events/sort.js +7 -10
  15. package/lib/events/types.d.ts +2 -1
  16. package/lib/events/types.js +1 -0
  17. package/lib/idl/clearing_house.json +1008 -147
  18. package/lib/index.d.ts +1 -0
  19. package/lib/index.js +1 -0
  20. package/lib/math/amm.js +2 -2
  21. package/lib/math/insurance.d.ts +4 -0
  22. package/lib/math/insurance.js +27 -0
  23. package/lib/math/margin.d.ts +1 -1
  24. package/lib/math/margin.js +5 -7
  25. package/lib/math/orders.d.ts +2 -1
  26. package/lib/math/orders.js +14 -5
  27. package/lib/math/position.js +1 -1
  28. package/lib/types.d.ts +59 -20
  29. package/lib/types.js +0 -3
  30. package/package.json +1 -1
  31. package/src/addresses/pda.ts +47 -0
  32. package/src/admin.ts +65 -0
  33. package/src/clearingHouse.ts +244 -32
  34. package/src/clearingHouseUser.ts +77 -48
  35. package/src/config.ts +1 -1
  36. package/src/constants/banks.ts +16 -0
  37. package/src/constants/numericConstants.ts +4 -0
  38. package/src/events/sort.ts +10 -14
  39. package/src/events/types.ts +3 -0
  40. package/src/idl/clearing_house.json +1008 -147
  41. package/src/index.ts +1 -0
  42. package/src/math/amm.ts +2 -2
  43. package/src/math/insurance.ts +35 -0
  44. package/src/math/margin.ts +3 -10
  45. package/src/math/orders.ts +26 -9
  46. package/src/math/position.ts +2 -2
  47. package/src/types.ts +67 -20
  48. package/src/events/eventSubscriber.js +0 -139
  49. package/src/events/fetchLogs.js +0 -50
  50. package/src/events/pollingLogProvider.js +0 -64
  51. package/src/events/sort.js +0 -44
  52. package/src/events/webSocketLogProvider.js +0 -41
@@ -40,6 +40,7 @@ import { EventEmitter } from 'events';
40
40
  import StrictEventEmitter from 'strict-event-emitter-types';
41
41
  import {
42
42
  getClearingHouseStateAccountPublicKey,
43
+ getInsuranceFundStakeAccountPublicKey,
43
44
  getMarketPublicKey,
44
45
  getUserAccountPublicKey,
45
46
  getUserAccountPublicKeySync,
@@ -224,11 +225,13 @@ export class ClearingHouse {
224
225
  * Forces the accountSubscriber to fetch account updates from rpc
225
226
  */
226
227
  public async fetchAccounts(): Promise<void> {
227
- await Promise.all(
228
- [...this.users.values()]
229
- .map((user) => user.fetchAccounts())
230
- .concat(this.accountSubscriber.fetch())
231
- );
228
+ const promises = [...this.users.values()]
229
+ .map((user) => user.fetchAccounts())
230
+ .concat(this.accountSubscriber.fetch());
231
+ if (this.userStats) {
232
+ promises.concat(this.userStats.fetchAccounts());
233
+ }
234
+ await Promise.all(promises);
232
235
  }
233
236
 
234
237
  public async unsubscribe(): Promise<void> {
@@ -1764,7 +1767,9 @@ export class ClearingHouse {
1764
1767
  const userStatsPublicKey = this.getUserStatsAccountPublicKey();
1765
1768
  const userAccountPublicKey = await this.getUserAccountPublicKey();
1766
1769
 
1767
- const remainingAccounts = this.getRemainingAccounts({
1770
+ // todo merge this with getRemainingAccounts
1771
+ const remainingAccounts = this.getRemainingAccountsWithCounterparty({
1772
+ counterPartyUserAccount: takerInfo.takerUserAccount,
1768
1773
  writableMarketIndex: orderParams.marketIndex,
1769
1774
  });
1770
1775
 
@@ -1985,9 +1990,9 @@ export class ClearingHouse {
1985
1990
  const liquidatorPublicKey = await this.getUserAccountPublicKey();
1986
1991
  const liquidatorStatsPublicKey = this.getUserStatsAccountPublicKey();
1987
1992
 
1988
- const remainingAccounts = this.getRemainingAccountsForLiquidation({
1993
+ const remainingAccounts = this.getRemainingAccountsWithCounterparty({
1989
1994
  writableMarketIndex: marketIndex,
1990
- userAccount,
1995
+ counterPartyUserAccount: userAccount,
1991
1996
  });
1992
1997
 
1993
1998
  return await this.program.instruction.liquidatePerp(
@@ -2039,8 +2044,8 @@ export class ClearingHouse {
2039
2044
  ): Promise<TransactionInstruction> {
2040
2045
  const liquidatorPublicKey = await this.getUserAccountPublicKey();
2041
2046
 
2042
- const remainingAccounts = this.getRemainingAccountsForLiquidation({
2043
- userAccount,
2047
+ const remainingAccounts = this.getRemainingAccountsWithCounterparty({
2048
+ counterPartyUserAccount: userAccount,
2044
2049
  writableBankIndexes: [liabilityBankIndex, assetBankIndex],
2045
2050
  });
2046
2051
 
@@ -2092,8 +2097,8 @@ export class ClearingHouse {
2092
2097
  ): Promise<TransactionInstruction> {
2093
2098
  const liquidatorPublicKey = await this.getUserAccountPublicKey();
2094
2099
 
2095
- const remainingAccounts = this.getRemainingAccountsForLiquidation({
2096
- userAccount,
2100
+ const remainingAccounts = this.getRemainingAccountsWithCounterparty({
2101
+ counterPartyUserAccount: userAccount,
2097
2102
  writableMarketIndex: perpMarketIndex,
2098
2103
  writableBankIndexes: [liabilityBankIndex],
2099
2104
  });
@@ -2146,8 +2151,8 @@ export class ClearingHouse {
2146
2151
  ): Promise<TransactionInstruction> {
2147
2152
  const liquidatorPublicKey = await this.getUserAccountPublicKey();
2148
2153
 
2149
- const remainingAccounts = this.getRemainingAccountsForLiquidation({
2150
- userAccount,
2154
+ const remainingAccounts = this.getRemainingAccountsWithCounterparty({
2155
+ counterPartyUserAccount: userAccount,
2151
2156
  writableMarketIndex: perpMarketIndex,
2152
2157
  writableBankIndexes: [assetBankIndex],
2153
2158
  });
@@ -2171,6 +2176,7 @@ export class ClearingHouse {
2171
2176
  public async resolvePerpBankruptcy(
2172
2177
  userAccountPublicKey: PublicKey,
2173
2178
  userAccount: UserAccount,
2179
+ bankIndex: BN,
2174
2180
  marketIndex: BN
2175
2181
  ): Promise<TransactionSignature> {
2176
2182
  const { txSig } = await this.txSender.send(
@@ -2178,6 +2184,7 @@ export class ClearingHouse {
2178
2184
  await this.getResolvePerpBankruptcyIx(
2179
2185
  userAccountPublicKey,
2180
2186
  userAccount,
2187
+ bankIndex,
2181
2188
  marketIndex
2182
2189
  )
2183
2190
  ),
@@ -2190,24 +2197,36 @@ export class ClearingHouse {
2190
2197
  public async getResolvePerpBankruptcyIx(
2191
2198
  userAccountPublicKey: PublicKey,
2192
2199
  userAccount: UserAccount,
2200
+ bankIndex: BN,
2193
2201
  marketIndex: BN
2194
2202
  ): Promise<TransactionInstruction> {
2195
2203
  const liquidatorPublicKey = await this.getUserAccountPublicKey();
2196
2204
 
2197
- const remainingAccounts = this.getRemainingAccountsForLiquidation({
2205
+ const remainingAccounts = this.getRemainingAccountsWithCounterparty({
2198
2206
  writableMarketIndex: marketIndex,
2199
- userAccount,
2207
+ writableBankIndexes: [bankIndex],
2208
+ counterPartyUserAccount: userAccount,
2200
2209
  });
2201
2210
 
2202
- return await this.program.instruction.resolvePerpBankruptcy(marketIndex, {
2203
- accounts: {
2204
- state: await this.getStatePublicKey(),
2205
- authority: this.wallet.publicKey,
2206
- user: userAccountPublicKey,
2207
- liquidator: liquidatorPublicKey,
2208
- },
2209
- remainingAccounts: remainingAccounts,
2210
- });
2211
+ const bank = this.getBankAccount(bankIndex);
2212
+
2213
+ return await this.program.instruction.resolvePerpBankruptcy(
2214
+ bankIndex,
2215
+ marketIndex,
2216
+ {
2217
+ accounts: {
2218
+ state: await this.getStatePublicKey(),
2219
+ authority: this.wallet.publicKey,
2220
+ user: userAccountPublicKey,
2221
+ liquidator: liquidatorPublicKey,
2222
+ bankVault: bank.vault,
2223
+ insuranceFundVault: bank.insuranceFundVault,
2224
+ insuranceFundVaultAuthority: bank.insuranceFundVaultAuthority,
2225
+ tokenProgram: TOKEN_PROGRAM_ID,
2226
+ },
2227
+ remainingAccounts: remainingAccounts,
2228
+ }
2229
+ );
2211
2230
  }
2212
2231
 
2213
2232
  public async resolveBorrowBankruptcy(
@@ -2236,33 +2255,39 @@ export class ClearingHouse {
2236
2255
  ): Promise<TransactionInstruction> {
2237
2256
  const liquidatorPublicKey = await this.getUserAccountPublicKey();
2238
2257
 
2239
- const remainingAccounts = this.getRemainingAccountsForLiquidation({
2258
+ const remainingAccounts = this.getRemainingAccountsWithCounterparty({
2240
2259
  writableBankIndexes: [bankIndex],
2241
- userAccount,
2260
+ counterPartyUserAccount: userAccount,
2242
2261
  });
2243
2262
 
2263
+ const bank = this.getBankAccount(bankIndex);
2264
+
2244
2265
  return await this.program.instruction.resolveBorrowBankruptcy(bankIndex, {
2245
2266
  accounts: {
2246
2267
  state: await this.getStatePublicKey(),
2247
2268
  authority: this.wallet.publicKey,
2248
2269
  user: userAccountPublicKey,
2249
2270
  liquidator: liquidatorPublicKey,
2271
+ bankVault: bank.vault,
2272
+ insuranceFundVault: bank.insuranceFundVault,
2273
+ insuranceFundVaultAuthority: bank.insuranceFundVaultAuthority,
2274
+ tokenProgram: TOKEN_PROGRAM_ID,
2250
2275
  },
2251
2276
  remainingAccounts: remainingAccounts,
2252
2277
  });
2253
2278
  }
2254
2279
 
2255
- getRemainingAccountsForLiquidation(params: {
2256
- userAccount: UserAccount;
2280
+ getRemainingAccountsWithCounterparty(params: {
2281
+ counterPartyUserAccount: UserAccount;
2257
2282
  writableMarketIndex?: BN;
2258
2283
  writableBankIndexes?: BN[];
2259
2284
  }): AccountMeta[] {
2260
- const liquidateeUserAccount = params.userAccount;
2285
+ const counterPartyUserAccount = params.counterPartyUserAccount;
2261
2286
 
2262
2287
  const oracleAccountMap = new Map<string, AccountMeta>();
2263
2288
  const bankAccountMap = new Map<number, AccountMeta>();
2264
2289
  const marketAccountMap = new Map<number, AccountMeta>();
2265
- for (const bankBalance of liquidateeUserAccount.bankBalances) {
2290
+ for (const bankBalance of counterPartyUserAccount.bankBalances) {
2266
2291
  if (!bankBalance.balance.eq(ZERO)) {
2267
2292
  const bankAccount = this.getBankAccount(bankBalance.bankIndex);
2268
2293
  bankAccountMap.set(bankBalance.bankIndex.toNumber(), {
@@ -2280,7 +2305,7 @@ export class ClearingHouse {
2280
2305
  }
2281
2306
  }
2282
2307
  }
2283
- for (const position of liquidateeUserAccount.positions) {
2308
+ for (const position of counterPartyUserAccount.positions) {
2284
2309
  if (!positionIsAvailable(position)) {
2285
2310
  const market = this.getMarketAccount(position.marketIndex);
2286
2311
  marketAccountMap.set(position.marketIndex.toNumber(), {
@@ -2476,4 +2501,191 @@ export class ClearingHouse {
2476
2501
 
2477
2502
  return oracleData;
2478
2503
  }
2504
+
2505
+ public async initializeInsuranceFundStake(
2506
+ bankIndex: BN
2507
+ ): Promise<TransactionSignature> {
2508
+ const { txSig } = await this.txSender.send(
2509
+ wrapInTx(await this.getInitializeInsuranceFundStakeIx(bankIndex)),
2510
+ [],
2511
+ this.opts
2512
+ );
2513
+ return txSig;
2514
+ }
2515
+
2516
+ public async getInitializeInsuranceFundStakeIx(
2517
+ bankIndex: BN
2518
+ ): Promise<TransactionInstruction> {
2519
+ const ifStakeAccountPublicKey = getInsuranceFundStakeAccountPublicKey(
2520
+ this.program.programId,
2521
+ this.wallet.publicKey,
2522
+ bankIndex
2523
+ );
2524
+
2525
+ return await this.program.instruction.initializeInsuranceFundStake(
2526
+ bankIndex,
2527
+ {
2528
+ accounts: {
2529
+ insuranceFundStake: ifStakeAccountPublicKey,
2530
+ bank: this.getBankAccount(bankIndex).pubkey,
2531
+ userStats: this.getUserStatsAccountPublicKey(),
2532
+ authority: this.wallet.publicKey,
2533
+ payer: this.wallet.publicKey,
2534
+ rent: anchor.web3.SYSVAR_RENT_PUBKEY,
2535
+ systemProgram: anchor.web3.SystemProgram.programId,
2536
+ state: await this.getStatePublicKey(),
2537
+ },
2538
+ }
2539
+ );
2540
+ }
2541
+
2542
+ public async addInsuranceFundStake(
2543
+ bankIndex: BN,
2544
+ amount: BN,
2545
+ collateralAccountPublicKey: PublicKey
2546
+ ): Promise<TransactionSignature> {
2547
+ const bank = this.getBankAccount(bankIndex);
2548
+ const ifStakeAccountPublicKey = getInsuranceFundStakeAccountPublicKey(
2549
+ this.program.programId,
2550
+ this.wallet.publicKey,
2551
+ bankIndex
2552
+ );
2553
+
2554
+ const remainingAccounts = this.getRemainingAccounts({
2555
+ writableBankIndex: bankIndex,
2556
+ });
2557
+
2558
+ return await this.program.rpc.addInsuranceFundStake(bankIndex, amount, {
2559
+ accounts: {
2560
+ state: await this.getStatePublicKey(),
2561
+ bank: bank.pubkey,
2562
+ insuranceFundStake: ifStakeAccountPublicKey,
2563
+ userStats: this.getUserStatsAccountPublicKey(),
2564
+ authority: this.wallet.publicKey,
2565
+ insuranceFundVault: bank.insuranceFundVault,
2566
+ userTokenAccount: collateralAccountPublicKey,
2567
+ tokenProgram: TOKEN_PROGRAM_ID,
2568
+ },
2569
+ remainingAccounts,
2570
+ });
2571
+ }
2572
+
2573
+ public async requestRemoveInsuranceFundStake(
2574
+ bankIndex: BN,
2575
+ amount: BN
2576
+ ): Promise<TransactionSignature> {
2577
+ const bank = this.getBankAccount(bankIndex);
2578
+ const ifStakeAccountPublicKey = getInsuranceFundStakeAccountPublicKey(
2579
+ this.program.programId,
2580
+ this.wallet.publicKey,
2581
+ bankIndex
2582
+ );
2583
+
2584
+ const remainingAccounts = this.getRemainingAccounts({
2585
+ writableBankIndex: bankIndex,
2586
+ });
2587
+
2588
+ return await this.program.rpc.requestRemoveInsuranceFundStake(
2589
+ bankIndex,
2590
+ amount,
2591
+ {
2592
+ accounts: {
2593
+ state: await this.getStatePublicKey(),
2594
+ bank: bank.pubkey,
2595
+ insuranceFundStake: ifStakeAccountPublicKey,
2596
+ userStats: this.getUserStatsAccountPublicKey(),
2597
+ authority: this.wallet.publicKey,
2598
+ insuranceFundVault: bank.insuranceFundVault,
2599
+ // userTokenAccount: collateralAccountPublicKey,
2600
+ // tokenProgram: TOKEN_PROGRAM_ID,
2601
+ },
2602
+ remainingAccounts,
2603
+ }
2604
+ );
2605
+ }
2606
+
2607
+ public async cancelRequestRemoveInsuranceFundStake(
2608
+ bankIndex: BN
2609
+ ): Promise<TransactionSignature> {
2610
+ const bank = this.getBankAccount(bankIndex);
2611
+ const ifStakeAccountPublicKey = getInsuranceFundStakeAccountPublicKey(
2612
+ this.program.programId,
2613
+ this.wallet.publicKey,
2614
+ bankIndex
2615
+ );
2616
+
2617
+ const remainingAccounts = this.getRemainingAccounts({
2618
+ writableBankIndex: bankIndex,
2619
+ });
2620
+
2621
+ return await this.program.rpc.cancelRequestRemoveInsuranceFundStake(
2622
+ bankIndex,
2623
+ {
2624
+ accounts: {
2625
+ state: await this.getStatePublicKey(),
2626
+ bank: bank.pubkey,
2627
+ insuranceFundStake: ifStakeAccountPublicKey,
2628
+ userStats: this.getUserStatsAccountPublicKey(),
2629
+ authority: this.wallet.publicKey,
2630
+ insuranceFundVault: bank.insuranceFundVault,
2631
+ // userTokenAccount: collateralAccountPublicKey,
2632
+ // tokenProgram: TOKEN_PROGRAM_ID,
2633
+ },
2634
+ remainingAccounts,
2635
+ }
2636
+ );
2637
+ }
2638
+
2639
+ public async removeInsuranceFundStake(
2640
+ bankIndex: BN,
2641
+ collateralAccountPublicKey: PublicKey
2642
+ ): Promise<TransactionSignature> {
2643
+ const bank = this.getBankAccount(bankIndex);
2644
+ const ifStakeAccountPublicKey = getInsuranceFundStakeAccountPublicKey(
2645
+ this.program.programId,
2646
+ this.wallet.publicKey,
2647
+ bankIndex
2648
+ );
2649
+
2650
+ const remainingAccounts = this.getRemainingAccounts({
2651
+ writableBankIndex: bankIndex,
2652
+ });
2653
+
2654
+ return await this.program.rpc.removeInsuranceFundStake(bankIndex, {
2655
+ accounts: {
2656
+ state: await this.getStatePublicKey(),
2657
+ bank: bank.pubkey,
2658
+ insuranceFundStake: ifStakeAccountPublicKey,
2659
+ userStats: this.getUserStatsAccountPublicKey(),
2660
+ authority: this.wallet.publicKey,
2661
+ insuranceFundVault: bank.insuranceFundVault,
2662
+ insuranceFundVaultAuthority: bank.insuranceFundVaultAuthority,
2663
+ userTokenAccount: collateralAccountPublicKey,
2664
+ tokenProgram: TOKEN_PROGRAM_ID,
2665
+ },
2666
+ remainingAccounts,
2667
+ });
2668
+ }
2669
+
2670
+ public async settleRevenueToInsuranceFund(
2671
+ bankIndex: BN
2672
+ ): Promise<TransactionSignature> {
2673
+ const bank = this.getBankAccount(bankIndex);
2674
+
2675
+ const remainingAccounts = this.getRemainingAccounts({
2676
+ writableBankIndex: bankIndex,
2677
+ });
2678
+
2679
+ return await this.program.rpc.settleRevenueToInsuranceFund(bankIndex, {
2680
+ accounts: {
2681
+ state: await this.getStatePublicKey(),
2682
+ bank: bank.pubkey,
2683
+ bankVault: bank.vault,
2684
+ bankVaultAuthority: bank.vaultAuthority,
2685
+ insuranceFundVault: bank.insuranceFundVault,
2686
+ tokenProgram: TOKEN_PROGRAM_ID,
2687
+ },
2688
+ remainingAccounts,
2689
+ });
2690
+ }
2479
2691
  }
@@ -46,7 +46,7 @@ import {
46
46
  calculateLiabilityWeight,
47
47
  } from './math/bankBalance';
48
48
  import {
49
- calculateMarginBaseAssetValue,
49
+ calculateBaseAssetValueWithOracle,
50
50
  calculateWorstCaseBaseAssetAmount,
51
51
  } from './math/margin';
52
52
  import { OraclePriceData } from './oracles/types';
@@ -144,6 +144,11 @@ export class ClearingHouseUser {
144
144
  };
145
145
  }
146
146
 
147
+ public getClonedPosition(position: UserPosition): UserPosition {
148
+ const clonedPosition = Object.assign({}, position);
149
+ return clonedPosition;
150
+ }
151
+
147
152
  /**
148
153
  * @param orderId
149
154
  * @returns Order
@@ -180,8 +185,10 @@ export class ClearingHouseUser {
180
185
  * calculates the market position if the lp position was settled
181
186
  * @returns : userPosition
182
187
  */
183
- public getSettledLPPosition(marketIndex: BN): [UserPosition, BN] {
184
- const position = this.getUserPosition(marketIndex);
188
+ public getSettledLPPosition(marketIndex: BN): [UserPosition, BN, BN] {
189
+ const _position = this.getUserPosition(marketIndex);
190
+ const position = this.getClonedPosition(_position);
191
+
185
192
  const market = this.clearingHouse.getMarketAccount(position.marketIndex);
186
193
  const nShares = position.lpShares;
187
194
 
@@ -265,7 +272,7 @@ export class ClearingHouseUser {
265
272
  position.lastCumulativeFundingRate = ZERO;
266
273
  }
267
274
 
268
- return [position, pnl];
275
+ return [position, remainderBaa, pnl];
269
276
  }
270
277
 
271
278
  /**
@@ -289,51 +296,55 @@ export class ClearingHouseUser {
289
296
  return freeCollateral.gte(ZERO) ? freeCollateral : ZERO;
290
297
  }
291
298
 
292
- public getInitialMarginRequirement(): BN {
293
- const postionMarginRequirement = this.getUserAccount().positions.reduce(
294
- (marginRequirement, marketPosition) => {
299
+ /**
300
+ * @returns The margin requirement of a certain type (Initial or Maintenance) in USDC. : QUOTE_PRECISION
301
+ */
302
+ public getMarginRequirement(type: MarginCategory): BN {
303
+ return this.getUserAccount()
304
+ .positions.reduce((marginRequirement, marketPosition) => {
295
305
  const market = this.clearingHouse.getMarketAccount(
296
306
  marketPosition.marketIndex
297
307
  );
298
- const worstCaseBaseAssetAmount =
299
- calculateWorstCaseBaseAssetAmount(marketPosition);
300
308
 
301
- const worstCaseAssetValue = worstCaseBaseAssetAmount
302
- .abs()
303
- .mul(this.getOracleDataForMarket(market.marketIndex).price)
304
- .div(AMM_TO_QUOTE_PRECISION_RATIO.mul(MARK_PRICE_PRECISION));
309
+ if (marketPosition.lpShares.gt(ZERO)) {
310
+ // is an lp
311
+ // clone so we dont mutate the position
312
+ marketPosition = this.getClonedPosition(marketPosition);
305
313
 
306
- const marketMarginRatio = new BN(
307
- calculateMarketMarginRatio(
308
- market,
309
- worstCaseBaseAssetAmount.abs(),
310
- 'Initial'
311
- )
312
- );
313
- return marginRequirement.add(
314
- worstCaseAssetValue.mul(marketMarginRatio).div(MARGIN_PRECISION)
315
- );
316
- },
317
- ZERO
318
- );
314
+ // settle position
315
+ const [settledPosition, dustBaa, _] = this.getSettledLPPosition(
316
+ market.marketIndex
317
+ );
318
+ marketPosition.baseAssetAmount =
319
+ settledPosition.baseAssetAmount.add(dustBaa);
320
+ marketPosition.quoteAssetAmount = settledPosition.quoteAssetAmount;
321
+
322
+ // open orders
323
+ let openAsks;
324
+ if (market.amm.maxBaseAssetReserve > market.amm.baseAssetReserve) {
325
+ openAsks = market.amm.maxBaseAssetReserve
326
+ .sub(market.amm.baseAssetReserve)
327
+ .mul(marketPosition.lpShares)
328
+ .div(market.amm.sqrtK)
329
+ .mul(new BN(-1));
330
+ } else {
331
+ openAsks = ZERO;
332
+ }
319
333
 
320
- const bankMarginRequirement = this.getBankLiabilityValue(
321
- undefined,
322
- 'Initial'
323
- );
334
+ let openBids;
335
+ if (market.amm.minBaseAssetReserve < market.amm.baseAssetReserve) {
336
+ openBids = market.amm.baseAssetReserve
337
+ .sub(market.amm.minBaseAssetReserve)
338
+ .mul(marketPosition.lpShares)
339
+ .div(market.amm.sqrtK);
340
+ } else {
341
+ openBids = ZERO;
342
+ }
324
343
 
325
- return bankMarginRequirement.add(postionMarginRequirement);
326
- }
344
+ marketPosition.openAsks = marketPosition.openAsks.add(openAsks);
345
+ marketPosition.openBids = marketPosition.openBids.add(openBids);
346
+ }
327
347
 
328
- /**
329
- * @returns The maintenance margin requirement in USDC. : QUOTE_PRECISION
330
- */
331
- public getMaintenanceMarginRequirement(): BN {
332
- return this.getUserAccount()
333
- .positions.reduce((marginRequirement, marketPosition) => {
334
- const market = this.clearingHouse.getMarketAccount(
335
- marketPosition.marketIndex
336
- );
337
348
  const worstCaseBaseAssetAmount =
338
349
  calculateWorstCaseBaseAssetAmount(marketPosition);
339
350
 
@@ -349,14 +360,28 @@ export class ClearingHouseUser {
349
360
  calculateMarketMarginRatio(
350
361
  market,
351
362
  worstCaseBaseAssetAmount.abs(),
352
- 'Maintenance'
363
+ type
353
364
  )
354
365
  )
355
366
  )
356
367
  .div(MARGIN_PRECISION)
357
368
  );
358
369
  }, ZERO)
359
- .add(this.getBankLiabilityValue(undefined, 'Maintenance'));
370
+ .add(this.getBankLiabilityValue(undefined, type));
371
+ }
372
+
373
+ /**
374
+ * @returns The initial margin requirement in USDC. : QUOTE_PRECISION
375
+ */
376
+ public getInitialMarginRequirement(): BN {
377
+ return this.getMarginRequirement('Initial');
378
+ }
379
+
380
+ /**
381
+ * @returns The maintenance margin requirement in USDC. : QUOTE_PRECISION
382
+ */
383
+ public getMaintenanceMarginRequirement(): BN {
384
+ return this.getMarginRequirement('Maintenance');
360
385
  }
361
386
 
362
387
  /**
@@ -543,7 +568,7 @@ export class ClearingHouseUser {
543
568
  const market = this.clearingHouse.getMarketAccount(
544
569
  marketPosition.marketIndex
545
570
  );
546
- const posVal = calculateMarginBaseAssetValue(
571
+ const posVal = calculateBaseAssetValueWithOracle(
547
572
  market,
548
573
  marketPosition,
549
574
  this.getOracleDataForMarket(market.marketIndex)
@@ -568,7 +593,11 @@ export class ClearingHouseUser {
568
593
  const market = this.clearingHouse.getMarketAccount(
569
594
  userPosition.marketIndex
570
595
  );
571
- return calculateMarginBaseAssetValue(market, userPosition, oraclePriceData);
596
+ return calculateBaseAssetValueWithOracle(
597
+ market,
598
+ userPosition,
599
+ oraclePriceData
600
+ );
572
601
  }
573
602
 
574
603
  public getPositionSide(
@@ -619,7 +648,7 @@ export class ClearingHouseUser {
619
648
  oraclePriceData
620
649
  );
621
650
  } else {
622
- baseAssetValue = calculateMarginBaseAssetValue(
651
+ baseAssetValue = calculateBaseAssetValueWithOracle(
623
652
  market,
624
653
  position,
625
654
  oraclePriceData
@@ -793,7 +822,7 @@ export class ClearingHouseUser {
793
822
  proposedMarketPosition.marketIndex
794
823
  );
795
824
 
796
- const proposedMarketPositionValue = calculateMarginBaseAssetValue(
825
+ const proposedMarketPositionValue = calculateBaseAssetValueWithOracle(
797
826
  market,
798
827
  proposedMarketPosition,
799
828
  this.getOracleDataForMarket(market.marketIndex)
@@ -810,7 +839,7 @@ export class ClearingHouseUser {
810
839
  const market = this.clearingHouse.getMarketAccount(
811
840
  position.marketIndex
812
841
  );
813
- const positionValue = calculateMarginBaseAssetValue(
842
+ const positionValue = calculateBaseAssetValueWithOracle(
814
843
  market,
815
844
  position,
816
845
  this.getOracleDataForMarket(market.marketIndex)
package/src/config.ts CHANGED
@@ -28,7 +28,7 @@ export const configs: { [key in DriftEnv]: DriftConfig } = {
28
28
  devnet: {
29
29
  ENV: 'devnet',
30
30
  PYTH_ORACLE_MAPPING_ADDRESS: 'BmA9Z6FjioHJPpjT39QazZyhDRUdZy2ezwx4GiDdE2u2',
31
- CLEARING_HOUSE_PROGRAM_ID: '65sz7dRiWDRPZjiRxcTxPM7AE6VK4Nag9HEK6oBJXhJn',
31
+ CLEARING_HOUSE_PROGRAM_ID: 'AXmmKr4MHipFp4SDr6CTUBzJtD1rZPHTzPDVPJ6L6r64',
32
32
  USDC_MINT_ADDRESS: '8zGuJQqwhZafTah7Uc7Z4tXRnguqkn5KLFAP8oV6PHe2',
33
33
  MARKETS: DevnetMarkets,
34
34
  BANKS: DevnetBanks,
@@ -1,5 +1,11 @@
1
1
  import { PublicKey } from '@solana/web3.js';
2
2
  import { BN, DriftEnv, OracleSource } from '../';
3
+ import {
4
+ BANK_BALANCE_PRECISION,
5
+ BANK_BALANCE_PRECISION_EXP,
6
+ LAMPORTS_EXP,
7
+ LAMPORTS_PRECISION,
8
+ } from './numericConstants';
3
9
 
4
10
  export type BankConfig = {
5
11
  symbol: string;
@@ -7,6 +13,8 @@ export type BankConfig = {
7
13
  oracle: PublicKey;
8
14
  mint: PublicKey;
9
15
  oracleSource: OracleSource;
16
+ precision: BN;
17
+ precisionExp: BN;
10
18
  };
11
19
 
12
20
  export const WRAPPED_SOL_MINT = new PublicKey(
@@ -20,6 +28,8 @@ export const DevnetBanks: BankConfig[] = [
20
28
  oracle: PublicKey.default,
21
29
  oracleSource: OracleSource.QUOTE_ASSET,
22
30
  mint: new PublicKey('8zGuJQqwhZafTah7Uc7Z4tXRnguqkn5KLFAP8oV6PHe2'),
31
+ precision: BANK_BALANCE_PRECISION,
32
+ precisionExp: BANK_BALANCE_PRECISION_EXP,
23
33
  },
24
34
  {
25
35
  symbol: 'SOL',
@@ -27,6 +37,8 @@ export const DevnetBanks: BankConfig[] = [
27
37
  oracle: new PublicKey('J83w4HKfqxwcq3BEMMkPFSppX3gqekLyLJBexebFVkix'),
28
38
  oracleSource: OracleSource.PYTH,
29
39
  mint: new PublicKey(WRAPPED_SOL_MINT),
40
+ precision: LAMPORTS_PRECISION,
41
+ precisionExp: LAMPORTS_EXP,
30
42
  },
31
43
  {
32
44
  symbol: 'BTC',
@@ -34,6 +46,8 @@ export const DevnetBanks: BankConfig[] = [
34
46
  oracle: new PublicKey('HovQMDrbAgAYPCmHVSrezcSmkMtXSSUsLDFANExrZh2J'),
35
47
  oracleSource: OracleSource.PYTH,
36
48
  mint: new PublicKey('3BZPwbcqB5kKScF3TEXxwNfx5ipV13kbRVDvfVp5c6fv'),
49
+ precision: BANK_BALANCE_PRECISION,
50
+ precisionExp: BANK_BALANCE_PRECISION_EXP,
37
51
  },
38
52
  ];
39
53
 
@@ -44,6 +58,8 @@ export const MainnetBanks: BankConfig[] = [
44
58
  oracle: PublicKey.default,
45
59
  oracleSource: OracleSource.QUOTE_ASSET,
46
60
  mint: new PublicKey('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'),
61
+ precision: BANK_BALANCE_PRECISION,
62
+ precisionExp: BANK_BALANCE_PRECISION_EXP,
47
63
  },
48
64
  ];
49
65
 
@@ -1,3 +1,4 @@
1
+ import { LAMPORTS_PER_SOL } from '@solana/web3.js';
1
2
  import { BN } from '../';
2
3
 
3
4
  export const ZERO = new BN(0);
@@ -66,3 +67,6 @@ export const BID_ASK_SPREAD_PRECISION = new BN(1000000);
66
67
  export const ONE_YEAR = new BN(31536000);
67
68
 
68
69
  export const QUOTE_ASSET_BANK_INDEX = new BN(0);
70
+
71
+ export const LAMPORTS_PRECISION = new BN(LAMPORTS_PER_SOL);
72
+ export const LAMPORTS_EXP = new BN(Math.log10(LAMPORTS_PER_SOL));