@drift-labs/sdk 2.52.0-beta.1 → 2.52.0-beta.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 (40) hide show
  1. package/VERSION +1 -1
  2. package/lib/accounts/webSocketAccountSubscriber.d.ts +1 -1
  3. package/lib/accounts/webSocketAccountSubscriber.js +7 -4
  4. package/lib/accounts/webSocketProgramAccountSubscriber.d.ts +1 -1
  5. package/lib/accounts/webSocketProgramAccountSubscriber.js +7 -4
  6. package/lib/dlob/orderBookLevels.d.ts +22 -0
  7. package/lib/dlob/orderBookLevels.js +115 -1
  8. package/lib/driftClient.js +7 -2
  9. package/lib/events/webSocketLogProvider.js +3 -3
  10. package/lib/factory/bigNum.d.ts +1 -1
  11. package/lib/factory/bigNum.js +5 -2
  12. package/lib/idl/drift.json +13 -1
  13. package/lib/math/amm.d.ts +5 -1
  14. package/lib/math/amm.js +62 -13
  15. package/lib/phoenix/phoenixSubscriber.js +2 -2
  16. package/lib/slot/SlotSubscriber.d.ts +11 -3
  17. package/lib/slot/SlotSubscriber.js +40 -4
  18. package/lib/types.d.ts +1 -1
  19. package/lib/user.d.ts +1 -1
  20. package/lib/user.js +14 -6
  21. package/lib/userMap/userMap.d.ts +3 -0
  22. package/lib/userMap/userMap.js +9 -0
  23. package/package.json +1 -1
  24. package/src/accounts/webSocketAccountSubscriber.ts +7 -4
  25. package/src/accounts/webSocketProgramAccountSubscriber.ts +7 -4
  26. package/src/dlob/orderBookLevels.ts +136 -0
  27. package/src/driftClient.ts +7 -2
  28. package/src/events/webSocketLogProvider.ts +3 -3
  29. package/src/factory/bigNum.ts +11 -2
  30. package/src/idl/drift.json +13 -1
  31. package/src/math/amm.ts +159 -25
  32. package/src/phoenix/phoenixSubscriber.ts +2 -2
  33. package/src/slot/SlotSubscriber.ts +52 -5
  34. package/src/types.ts +1 -1
  35. package/src/user.ts +19 -6
  36. package/src/userMap/userMap.ts +12 -0
  37. package/tests/amm/test.ts +219 -11
  38. package/tests/bn/test.ts +27 -0
  39. package/tests/dlob/helpers.ts +1 -1
  40. package/tests/dlob/test.ts +372 -2
@@ -3,7 +3,9 @@ import { EventEmitter } from 'events';
3
3
  import StrictEventEmitter from 'strict-event-emitter-types/types/src';
4
4
 
5
5
  // eslint-disable-next-line @typescript-eslint/ban-types
6
- type SlotSubscriberConfig = {}; // for future customization
6
+ type SlotSubscriberConfig = {
7
+ resubTimeoutMs?: number;
8
+ }; // for future customization
7
9
 
8
10
  export interface SlotSubscriberEvents {
9
11
  newSlot: (newSlot: number) => void;
@@ -14,15 +16,22 @@ export class SlotSubscriber {
14
16
  subscriptionId: number;
15
17
  eventEmitter: StrictEventEmitter<EventEmitter, SlotSubscriberEvents>;
16
18
 
19
+ // Reconnection
20
+ timeoutId?: NodeJS.Timeout;
21
+ resubTimeoutMs?: number;
22
+ isUnsubscribing = false;
23
+ receivingData = false;
24
+
17
25
  public constructor(
18
26
  private connection: Connection,
19
- _config?: SlotSubscriberConfig
27
+ config?: SlotSubscriberConfig
20
28
  ) {
21
29
  this.eventEmitter = new EventEmitter();
30
+ this.resubTimeoutMs = config?.resubTimeoutMs;
22
31
  }
23
32
 
24
33
  public async subscribe(): Promise<void> {
25
- if (this.subscriptionId) {
34
+ if (this.subscriptionId != null) {
26
35
  return;
27
36
  }
28
37
 
@@ -30,19 +39,57 @@ export class SlotSubscriber {
30
39
 
31
40
  this.subscriptionId = this.connection.onSlotChange((slotInfo) => {
32
41
  if (!this.currentSlot || this.currentSlot < slotInfo.slot) {
42
+ if (this.resubTimeoutMs && !this.isUnsubscribing) {
43
+ this.receivingData = true;
44
+ clearTimeout(this.timeoutId);
45
+ this.setTimeout();
46
+ }
33
47
  this.currentSlot = slotInfo.slot;
34
48
  this.eventEmitter.emit('newSlot', slotInfo.slot);
35
49
  }
36
50
  });
51
+
52
+ if (this.resubTimeoutMs) {
53
+ this.setTimeout();
54
+ }
55
+ }
56
+
57
+ private setTimeout(): void {
58
+ this.timeoutId = setTimeout(async () => {
59
+ if (this.isUnsubscribing) {
60
+ // If we are in the process of unsubscribing, do not attempt to resubscribe
61
+ return;
62
+ }
63
+
64
+ if (this.receivingData) {
65
+ console.log(
66
+ `No new slot in ${this.resubTimeoutMs}ms, slot subscriber resubscribing`
67
+ );
68
+ await this.unsubscribe(true);
69
+ this.receivingData = false;
70
+ await this.subscribe();
71
+ }
72
+ }, this.resubTimeoutMs);
37
73
  }
38
74
 
39
75
  public getSlot(): number {
40
76
  return this.currentSlot;
41
77
  }
42
78
 
43
- public async unsubscribe(): Promise<void> {
44
- if (this.subscriptionId) {
79
+ public async unsubscribe(onResub = false): Promise<void> {
80
+ if (!onResub) {
81
+ this.resubTimeoutMs = undefined;
82
+ }
83
+ this.isUnsubscribing = true;
84
+ clearTimeout(this.timeoutId);
85
+ this.timeoutId = undefined;
86
+
87
+ if (this.subscriptionId != null) {
45
88
  await this.connection.removeSlotChangeListener(this.subscriptionId);
89
+ this.subscriptionId = undefined;
90
+ this.isUnsubscribing = false;
91
+ } else {
92
+ this.isUnsubscribing = false;
46
93
  }
47
94
  }
48
95
  }
package/src/types.ts CHANGED
@@ -710,7 +710,7 @@ export type AMM = {
710
710
  pegMultiplier: BN;
711
711
  cumulativeFundingRateLong: BN;
712
712
  cumulativeFundingRateShort: BN;
713
- last24hAvgFundingRate: BN;
713
+ last24HAvgFundingRate: BN;
714
714
  lastFundingRateShort: BN;
715
715
  lastFundingRateLong: BN;
716
716
 
package/src/user.ts CHANGED
@@ -27,6 +27,7 @@ import {
27
27
  OPEN_ORDER_MARGIN_REQUIREMENT,
28
28
  PRICE_PRECISION,
29
29
  QUOTE_PRECISION,
30
+ QUOTE_PRECISION_EXP,
30
31
  QUOTE_SPOT_MARKET_INDEX,
31
32
  SPOT_MARKET_WEIGHT_PRECISION,
32
33
  TEN,
@@ -40,6 +41,7 @@ import {
40
41
  UserAccountSubscriber,
41
42
  } from './accounts/types';
42
43
  import {
44
+ BigNum,
43
45
  BN,
44
46
  calculateBaseAssetValue,
45
47
  calculateMarketMarginRatio,
@@ -3013,7 +3015,7 @@ export class User {
3013
3015
  let makerFee =
3014
3016
  feeTier.makerRebateNumerator / feeTier.makerRebateDenominator;
3015
3017
 
3016
- if (marketIndex && isVariant(marketType, 'perp')) {
3018
+ if (marketIndex !== undefined && isVariant(marketType, 'perp')) {
3017
3019
  const marketAccount = this.driftClient.getPerpMarketAccount(marketIndex);
3018
3020
  takerFee += (takerFee * marketAccount.feeAdjustment) / 100;
3019
3021
  makerFee += (makerFee * marketAccount.feeAdjustment) / 100;
@@ -3030,11 +3032,22 @@ export class User {
3030
3032
  * @param quoteAmount
3031
3033
  * @returns feeForQuote : Precision QUOTE_PRECISION
3032
3034
  */
3033
- public calculateFeeForQuoteAmount(quoteAmount: BN): BN {
3034
- const feeTier = this.getUserFeeTier(MarketType.PERP);
3035
- return quoteAmount
3036
- .mul(new BN(feeTier.feeNumerator))
3037
- .div(new BN(feeTier.feeDenominator));
3035
+ public calculateFeeForQuoteAmount(quoteAmount: BN, marketIndex?: number): BN {
3036
+ if (marketIndex !== undefined) {
3037
+ const takerFeeMultiplier = this.getMarketFees(
3038
+ MarketType.PERP,
3039
+ marketIndex
3040
+ ).takerFee;
3041
+ const feeAmountNum =
3042
+ BigNum.from(quoteAmount, QUOTE_PRECISION_EXP).toNum() *
3043
+ takerFeeMultiplier;
3044
+ return BigNum.fromPrint(feeAmountNum.toString(), QUOTE_PRECISION_EXP).val;
3045
+ } else {
3046
+ const feeTier = this.getUserFeeTier(MarketType.PERP);
3047
+ return quoteAmount
3048
+ .mul(new BN(feeTier.feeNumerator))
3049
+ .div(new BN(feeTier.feeDenominator));
3050
+ }
3038
3051
  }
3039
3052
 
3040
3053
  /**
@@ -60,6 +60,7 @@ export class UserMap implements UserMapInterface {
60
60
  }
61
61
  };
62
62
  private decode;
63
+ private mostRecentSlot = 0;
63
64
 
64
65
  private syncPromise?: Promise<void>;
65
66
  private syncPromiseResolver: () => void;
@@ -312,6 +313,8 @@ export class UserMap implements UserMapInterface {
312
313
 
313
314
  const slot = rpcResponseAndContext.context.slot;
314
315
 
316
+ this.updateLatestSlot(slot);
317
+
315
318
  const programAccountBufferMap = new Map<string, Buffer>();
316
319
  for (const programAccount of rpcResponseAndContext.value) {
317
320
  programAccountBufferMap.set(
@@ -373,6 +376,7 @@ export class UserMap implements UserMapInterface {
373
376
  userAccount: UserAccount,
374
377
  slot: number
375
378
  ) {
379
+ this.updateLatestSlot(slot);
376
380
  if (!this.userMap.has(key)) {
377
381
  this.addPubkey(new PublicKey(key), userAccount, slot);
378
382
  } else {
@@ -380,4 +384,12 @@ export class UserMap implements UserMapInterface {
380
384
  user.accountSubscriber.updateData(userAccount, slot);
381
385
  }
382
386
  }
387
+
388
+ updateLatestSlot(slot: number): void {
389
+ this.mostRecentSlot = Math.max(slot, this.mostRecentSlot);
390
+ }
391
+
392
+ public getSlot(): number {
393
+ return this.mostRecentSlot;
394
+ }
383
395
  }
package/tests/amm/test.ts CHANGED
@@ -4,6 +4,8 @@ import {
4
4
  PRICE_PRECISION,
5
5
  AMM_RESERVE_PRECISION,
6
6
  QUOTE_PRECISION,
7
+ PERCENTAGE_PRECISION,
8
+ calculateSpread,
7
9
  calculateSpreadBN,
8
10
  ZERO,
9
11
  ONE,
@@ -19,6 +21,12 @@ import {
19
21
  L2Level,
20
22
  calculateUpdatedAMM,
21
23
  calculateMarketOpenBidAsk,
24
+ calculateSpreadReserves,
25
+ calculatePrice,
26
+ BID_ASK_SPREAD_PRECISION,
27
+ squareRootBN,
28
+ calculateReferencePriceOffset,
29
+ calculateInventoryLiquidityRatio,
22
30
  } from '../../src';
23
31
  import { mockPerpMarkets } from '../dlob/helpers';
24
32
 
@@ -293,7 +301,7 @@ describe('AMM Tests', () => {
293
301
  volume24H,
294
302
  true
295
303
  );
296
- console.log(terms1);
304
+ // console.log(terms1);
297
305
 
298
306
  console.log('long/short spread:', l1, s1);
299
307
  assert(l1 == 14864);
@@ -326,11 +334,77 @@ describe('AMM Tests', () => {
326
334
  true
327
335
  );
328
336
 
329
- console.log(terms2);
337
+ // console.log(terms2);
330
338
  assert(terms2.effectiveLeverageCapped >= 1.0002);
331
339
  assert(terms2.inventorySpreadScale == 1.73492);
332
340
  assert(terms2.longSpread == 4262);
333
341
  assert(terms2.shortSpread == 43238);
342
+
343
+ // add spread offset
344
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
345
+ // @ts-ignore
346
+ const terms3: AMMSpreadTerms = calculateSpreadBN(
347
+ 300,
348
+ new BN(0),
349
+ new BN(484),
350
+ 47500,
351
+ new BN(923807816209694),
352
+ new BN(925117623772584),
353
+ new BN(13731157),
354
+ new BN(-1314027016625),
355
+ new BN(13667686),
356
+ new BN(115876379475),
357
+ new BN(91316628),
358
+ new BN(928097825691666),
359
+ new BN(907979542352912),
360
+ new BN(945977491145601),
361
+ new BN(161188),
362
+ new BN(1459632439),
363
+ new BN(12358265776),
364
+ new BN(72230366233),
365
+ new BN(432067603632),
366
+ true
367
+ );
368
+
369
+ console.log(terms3);
370
+ assert(terms3.effectiveLeverageCapped >= 1.0002);
371
+ assert(terms3.inventorySpreadScale == 1.73492);
372
+ assert(terms3.longSpread == 4262);
373
+ assert(terms3.shortSpread == 43238);
374
+ assert(terms3.longSpread + terms3.shortSpread == 47500);
375
+
376
+ // add spread offset
377
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
378
+ // @ts-ignore
379
+ const terms4: AMMSpreadTerms = calculateSpreadBN(
380
+ 300,
381
+ new BN(0),
382
+ new BN(484),
383
+ 47500,
384
+ new BN(923807816209694),
385
+ new BN(925117623772584),
386
+ new BN(13731157),
387
+ new BN(-1314027016625),
388
+ new BN(13667686),
389
+ new BN(115876379475),
390
+ new BN(91316628),
391
+ new BN(928097825691666),
392
+ new BN(907979542352912),
393
+ new BN(945977491145601),
394
+ new BN(161188),
395
+ new BN(1459632439),
396
+ new BN(12358265776),
397
+ new BN(72230366233),
398
+ new BN(432067603632),
399
+ true
400
+ );
401
+
402
+ console.log(terms4);
403
+ assert(terms4.effectiveLeverageCapped >= 1.0002);
404
+ assert(terms4.inventorySpreadScale == 1.73492);
405
+ assert(terms4.longSpread == 4262);
406
+ assert(terms4.shortSpread == 43238);
407
+ assert(terms4.longSpread + terms4.shortSpread == 47500);
334
408
  });
335
409
 
336
410
  it('Corner Case Spreads', () => {
@@ -361,16 +435,150 @@ describe('AMM Tests', () => {
361
435
 
362
436
  console.log(terms2);
363
437
  assert(terms2.effectiveLeverageCapped <= 1.000001);
364
- assert(
365
- terms2.inventorySpreadScale == 1.013527,
366
- `got: ${terms2.inventorySpreadScale}`
438
+ assert(terms2.inventorySpreadScale == 1.0306);
439
+ assert(terms2.longSpread == 515);
440
+ assert(terms2.shortSpread == 5668);
441
+ });
442
+
443
+ it('Spread Reserves (with offset)', () => {
444
+ const myMockPerpMarkets = _.cloneDeep(mockPerpMarkets);
445
+ const mockMarket1 = myMockPerpMarkets[0];
446
+ const mockAmm = mockMarket1.amm;
447
+ const now = new BN(new Date().getTime() / 1000); //todo
448
+
449
+ const oraclePriceData = {
450
+ price: new BN(13.553 * PRICE_PRECISION.toNumber()),
451
+ slot: new BN(68 + 1),
452
+ confidence: new BN(1),
453
+ hasSufficientNumberOfDataPoints: true,
454
+ };
455
+
456
+ const reserves = calculateSpreadReserves(mockAmm, oraclePriceData, now);
457
+ assert(reserves[0].baseAssetReserve.eq(new BN('1000000000')));
458
+ assert(reserves[0].quoteAssetReserve.eq(new BN('12000000000')));
459
+ assert(reserves[1].baseAssetReserve.eq(new BN('1000000000')));
460
+ assert(reserves[1].quoteAssetReserve.eq(new BN('12000000000')));
461
+
462
+ mockAmm.baseAssetReserve = new BN(1000000000);
463
+ mockAmm.quoteAssetReserve = new BN(1000000000);
464
+ mockAmm.sqrtK = new BN(1000000000);
465
+
466
+ mockAmm.baseAssetAmountWithAmm = new BN(0);
467
+ mockAmm.pegMultiplier = new BN(13.553 * PEG_PRECISION.toNumber());
468
+ mockAmm.ammJitIntensity = 100;
469
+ mockAmm.curveUpdateIntensity = 200;
470
+ mockAmm.baseSpread = 2500;
471
+ mockAmm.maxSpread = 25000;
472
+
473
+ mockAmm.last24HAvgFundingRate = new BN(7590328523);
474
+
475
+ mockAmm.lastMarkPriceTwap = new BN(
476
+ (oraclePriceData.price.toNumber() / 1e6 - 0.01) * 1e6
477
+ );
478
+ mockAmm.historicalOracleData.lastOraclePriceTwap = new BN(
479
+ (oraclePriceData.price.toNumber() / 1e6 + 0.015) * 1e6
367
480
  );
368
- assert(terms2.longSpread == 1146);
369
- assert(terms2.shortSpread == 6686);
481
+
482
+ mockAmm.historicalOracleData.lastOraclePriceTwap5Min = new BN(
483
+ (oraclePriceData.price.toNumber() / 1e6 + 0.005) * 1e6
484
+ );
485
+ mockAmm.lastMarkPriceTwap5Min = new BN(
486
+ (oraclePriceData.price.toNumber() / 1e6 - 0.005) * 1e6
487
+ );
488
+
489
+ console.log('starting rr:');
490
+ let reservePrice = undefined;
491
+ if (!reservePrice) {
492
+ reservePrice = calculatePrice(
493
+ mockAmm.baseAssetReserve,
494
+ mockAmm.quoteAssetReserve,
495
+ mockAmm.pegMultiplier
496
+ );
497
+ }
498
+
499
+ const targetPrice = oraclePriceData?.price || reservePrice;
500
+ const confInterval = oraclePriceData.confidence || ZERO;
501
+ const targetMarkSpreadPct = reservePrice
502
+ .sub(targetPrice)
503
+ .mul(BID_ASK_SPREAD_PRECISION)
504
+ .div(reservePrice);
505
+
506
+ const confIntervalPct = confInterval
507
+ .mul(BID_ASK_SPREAD_PRECISION)
508
+ .div(reservePrice);
509
+
510
+ // now = now || new BN(new Date().getTime() / 1000); //todo
511
+ const liveOracleStd = calculateLiveOracleStd(mockAmm, oraclePriceData, now);
512
+ console.log('reservePrice:', reservePrice.toString());
513
+ console.log('targetMarkSpreadPct:', targetMarkSpreadPct.toString());
514
+ console.log('confIntervalPct:', confIntervalPct.toString());
515
+
516
+ console.log('liveOracleStd:', liveOracleStd.toString());
517
+
518
+ const tt = calculateSpread(mockAmm, oraclePriceData, now);
519
+ console.log(tt);
520
+
521
+ console.log('amm.baseAssetReserve:', mockAmm.baseAssetReserve.toString());
522
+ assert(mockAmm.baseAssetReserve.eq(new BN('1000000000')));
523
+ const reserves2 = calculateSpreadReserves(mockAmm, oraclePriceData, now);
524
+ console.log(reserves2[1].baseAssetReserve.toString());
525
+ console.log(reserves2[1].quoteAssetReserve.toString());
526
+
527
+ assert(reserves2[0].baseAssetReserve.eq(new BN('1006711408')));
528
+ assert(reserves2[0].quoteAssetReserve.eq(new BN('993333334')));
529
+ assert(reserves2[1].baseAssetReserve.eq(new BN('993377484')));
530
+ assert(reserves2[1].quoteAssetReserve.eq(new BN('1006666666')));
531
+
532
+ // create imbalance for reference price offset
533
+ mockAmm.baseAssetReserve = new BN(1000000000 * 1.1);
534
+ mockAmm.quoteAssetReserve = new BN(1000000000 / 1.1);
535
+ mockAmm.sqrtK = squareRootBN(
536
+ mockAmm.baseAssetReserve.mul(mockAmm.quoteAssetReserve)
537
+ );
538
+
539
+ mockAmm.baseAssetAmountWithAmm = new BN(-1000000000 * 0.1);
540
+
541
+ const maxOffset = Math.max(
542
+ mockAmm.maxSpread / 5,
543
+ PERCENTAGE_PRECISION.toNumber() / 1000
544
+ );
545
+ const liquidityFraction = calculateInventoryLiquidityRatio(
546
+ mockAmm.baseAssetAmountWithAmm,
547
+ mockAmm.baseAssetReserve,
548
+ mockAmm.minBaseAssetReserve,
549
+ mockAmm.maxBaseAssetReserve
550
+ );
551
+ console.log('liquidityFraction:', liquidityFraction.toString());
552
+ assert(liquidityFraction.eq(new BN(1000000))); // full
553
+
554
+ const referencePriceOffset = calculateReferencePriceOffset(
555
+ reservePrice,
556
+ mockAmm.last24HAvgFundingRate,
557
+ liquidityFraction,
558
+ mockAmm.historicalOracleData.lastOraclePriceTwap5Min,
559
+ mockAmm.lastMarkPriceTwap5Min,
560
+ mockAmm.historicalOracleData.lastOraclePriceTwap,
561
+ mockAmm.lastMarkPriceTwap,
562
+ maxOffset
563
+ );
564
+ console.log('referencePriceOffset:', referencePriceOffset.toString());
565
+ assert(referencePriceOffset.eq(new BN(5000)));
566
+ assert(referencePriceOffset.eq(new BN(maxOffset)));
567
+
568
+ const reserves3 = calculateSpreadReserves(mockAmm, oraclePriceData, now);
569
+ console.log(reserves3[1].baseAssetReserve.toString());
570
+ console.log(reserves3[1].quoteAssetReserve.toString());
571
+
572
+ assert(reserves3[0].baseAssetReserve.eq(new BN('1164705879')));
573
+ assert(reserves3[0].quoteAssetReserve.eq(new BN('858585859')));
574
+ assert(reserves3[1].baseAssetReserve.eq(new BN('1042105261')));
575
+ assert(reserves3[1].quoteAssetReserve.eq(new BN('959595959')));
370
576
  });
371
577
 
372
578
  it('live update functions', () => {
373
- const mockAmm = mockPerpMarkets[0].amm;
579
+ const myMockPerpMarkets = _.cloneDeep(mockPerpMarkets);
580
+ const mockMarket1 = myMockPerpMarkets[0];
581
+ const mockAmm = mockMarket1.amm;
374
582
  const now = new BN(new Date().getTime() / 1000); //todo
375
583
 
376
584
  const oraclePriceData = {
@@ -469,8 +677,8 @@ describe('AMM Tests', () => {
469
677
 
470
678
  assert(markTwapLive.eq(new BN('1949826')));
471
679
  assert(oracleTwapLive.eq(new BN('1942510')));
472
- assert(est1.eq(new BN('15692')), `got: ${est1}`);
473
- assert(est2.eq(new BN('15692')));
680
+ assert(est1.eq(new BN('16525')));
681
+ assert(est2.eq(new BN('16525')));
474
682
  });
475
683
 
476
684
  it('predicted funding rate mock2', async () => {
@@ -559,7 +767,7 @@ describe('AMM Tests', () => {
559
767
  assert(markTwapLive.eq(new BN('1222131')));
560
768
  assert(oracleTwapLive.eq(new BN('1222586')));
561
769
  assert(est1.eq(est2));
562
- assert(est2.eq(new BN('-1550')), `got: ${est2}`);
770
+ assert(est2.eq(new BN('-719')));
563
771
  });
564
772
 
565
773
  it('orderbook L2 gen (no topOfBookQuoteAmounts, 10 numOrders, low liquidity)', async () => {
package/tests/bn/test.ts CHANGED
@@ -147,6 +147,33 @@ describe('BigNum Tests', () => {
147
147
  '-1.0000000000000'
148
148
  );
149
149
  expect(BigNum.from('-100', 6).print()).to.equal('-0.000100');
150
+
151
+ // Case 7: really large numbers + switching between scientific/financial
152
+ expect(BigNum.fromPrint('123000000000').toMillified(3)).to.equal('123B');
153
+ expect(
154
+ BigNum.fromPrint('123000000000').toMillified(3, undefined, 'scientific')
155
+ ).to.equal('123G'); // (G = Giga)
156
+ expect(BigNum.fromPrint('123000000000000').toMillified(3)).to.equal('123T');
157
+ expect(
158
+ BigNum.fromPrint('123000000000000').toMillified(
159
+ 3,
160
+ undefined,
161
+ 'scientific'
162
+ )
163
+ ).to.equal('123T'); // (T = Tera)
164
+ expect(BigNum.fromPrint('123000000000000000').toMillified(3)).to.equal(
165
+ '123Q'
166
+ );
167
+ expect(
168
+ BigNum.fromPrint('123000000000000000').toMillified(
169
+ 3,
170
+ undefined,
171
+ 'scientific'
172
+ )
173
+ ).to.equal('123P'); // (P = Peta)
174
+
175
+ // TODO : Need to make the appropriate changes for the next line to pass
176
+ // expect(BigNum.fromPrint('123000000000000000000').toMillified(3)).to.equal('123000Q');
150
177
  });
151
178
 
152
179
  it('can initialise from string values correctly', () => {
@@ -84,7 +84,7 @@ export const mockAMM: AMM = {
84
84
  baseAssetAmountWithUnsettledLp: new BN(0),
85
85
  orderStepSize: new BN(0),
86
86
  orderTickSize: new BN(1),
87
- last24hAvgFundingRate: new BN(0),
87
+ last24HAvgFundingRate: new BN(0),
88
88
  lastFundingRateShort: new BN(0),
89
89
  lastFundingRateLong: new BN(0),
90
90
  concentrationCoef: new BN(0),