@drift-labs/sdk 2.57.0-beta.1 → 2.57.0-beta.2

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.
package/VERSION CHANGED
@@ -1 +1 @@
1
- 2.57.0-beta.1
1
+ 2.57.0-beta.2
@@ -12,6 +12,7 @@ export declare class AdminClient extends DriftClient {
12
12
  deleteInitializedPerpMarket(marketIndex: number): Promise<TransactionSignature>;
13
13
  moveAmmPrice(perpMarketIndex: number, baseAssetReserve: BN, quoteAssetReserve: BN, sqrtK?: BN): Promise<TransactionSignature>;
14
14
  updateK(perpMarketIndex: number, sqrtK: BN): Promise<TransactionSignature>;
15
+ recenterPerpMarketAmm(perpMarketIndex: number, pegMultiplier: BN, sqrtK: BN): Promise<TransactionSignature>;
15
16
  updatePerpMarketConcentrationScale(perpMarketIndex: number, concentrationScale: BN): Promise<TransactionSignature>;
16
17
  moveAmmToPrice(perpMarketIndex: number, targetPrice: BN): Promise<TransactionSignature>;
17
18
  repegAmmCurve(newPeg: BN, perpMarketIndex: number): Promise<TransactionSignature>;
@@ -191,6 +191,18 @@ class AdminClient extends driftClient_1.DriftClient {
191
191
  const { txSig } = await this.sendTransaction(tx, [], this.opts);
192
192
  return txSig;
193
193
  }
194
+ async recenterPerpMarketAmm(perpMarketIndex, pegMultiplier, sqrtK) {
195
+ const marketPublicKey = await (0, pda_1.getPerpMarketPublicKey)(this.program.programId, perpMarketIndex);
196
+ const tx = await this.program.transaction.recenterPerpMarketAmm(pegMultiplier, sqrtK, {
197
+ accounts: {
198
+ state: await this.getStatePublicKey(),
199
+ admin: this.wallet.publicKey,
200
+ perpMarket: marketPublicKey,
201
+ },
202
+ });
203
+ const { txSig } = await this.sendTransaction(tx, [], this.opts);
204
+ return txSig;
205
+ }
194
206
  async updatePerpMarketConcentrationScale(perpMarketIndex, concentrationScale) {
195
207
  return await this.program.rpc.updatePerpMarketConcentrationCoef(concentrationScale, {
196
208
  accounts: {
@@ -2972,6 +2972,36 @@
2972
2972
  }
2973
2973
  ]
2974
2974
  },
2975
+ {
2976
+ "name": "recenterPerpMarketAmm",
2977
+ "accounts": [
2978
+ {
2979
+ "name": "admin",
2980
+ "isMut": false,
2981
+ "isSigner": true
2982
+ },
2983
+ {
2984
+ "name": "state",
2985
+ "isMut": false,
2986
+ "isSigner": false
2987
+ },
2988
+ {
2989
+ "name": "perpMarket",
2990
+ "isMut": true,
2991
+ "isSigner": false
2992
+ }
2993
+ ],
2994
+ "args": [
2995
+ {
2996
+ "name": "pegMultiplier",
2997
+ "type": "u128"
2998
+ },
2999
+ {
3000
+ "name": "sqrtK",
3001
+ "type": "u128"
3002
+ }
3003
+ ]
3004
+ },
2975
3005
  {
2976
3006
  "name": "updatePerpMarketExpiry",
2977
3007
  "accounts": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drift-labs/sdk",
3
- "version": "2.57.0-beta.1",
3
+ "version": "2.57.0-beta.2",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/index.d.ts",
6
6
  "author": "crispheaney",
@@ -358,6 +358,32 @@ export class AdminClient extends DriftClient {
358
358
  return txSig;
359
359
  }
360
360
 
361
+ public async recenterPerpMarketAmm(
362
+ perpMarketIndex: number,
363
+ pegMultiplier: BN,
364
+ sqrtK: BN
365
+ ): Promise<TransactionSignature> {
366
+ const marketPublicKey = await getPerpMarketPublicKey(
367
+ this.program.programId,
368
+ perpMarketIndex
369
+ );
370
+
371
+ const tx = await this.program.transaction.recenterPerpMarketAmm(
372
+ pegMultiplier,
373
+ sqrtK,
374
+ {
375
+ accounts: {
376
+ state: await this.getStatePublicKey(),
377
+ admin: this.wallet.publicKey,
378
+ perpMarket: marketPublicKey,
379
+ },
380
+ }
381
+ );
382
+
383
+ const { txSig } = await this.sendTransaction(tx, [], this.opts);
384
+ return txSig;
385
+ }
386
+
361
387
  public async updatePerpMarketConcentrationScale(
362
388
  perpMarketIndex: number,
363
389
  concentrationScale: BN
@@ -2972,6 +2972,36 @@
2972
2972
  }
2973
2973
  ]
2974
2974
  },
2975
+ {
2976
+ "name": "recenterPerpMarketAmm",
2977
+ "accounts": [
2978
+ {
2979
+ "name": "admin",
2980
+ "isMut": false,
2981
+ "isSigner": true
2982
+ },
2983
+ {
2984
+ "name": "state",
2985
+ "isMut": false,
2986
+ "isSigner": false
2987
+ },
2988
+ {
2989
+ "name": "perpMarket",
2990
+ "isMut": true,
2991
+ "isSigner": false
2992
+ }
2993
+ ],
2994
+ "args": [
2995
+ {
2996
+ "name": "pegMultiplier",
2997
+ "type": "u128"
2998
+ },
2999
+ {
3000
+ "name": "sqrtK",
3001
+ "type": "u128"
3002
+ }
3003
+ ]
3004
+ },
2975
3005
  {
2976
3006
  "name": "updatePerpMarketExpiry",
2977
3007
  "accounts": [
package/tests/amm/test.ts CHANGED
@@ -31,6 +31,7 @@ import {
31
31
  ContractTier,
32
32
  isOracleValid,
33
33
  OracleGuardRails,
34
+ // calculateReservePrice,
34
35
  } from '../../src';
35
36
  import { mockPerpMarkets } from '../dlob/helpers';
36
37
 
@@ -437,11 +438,242 @@ describe('AMM Tests', () => {
437
438
  true
438
439
  );
439
440
 
440
- console.log(terms2);
441
+ // console.log(terms2);
441
442
  assert(terms2.effectiveLeverageCapped <= 1.000001);
442
443
  assert(terms2.inventorySpreadScale == 1.0306);
443
444
  assert(terms2.longSpread == 515);
444
445
  assert(terms2.shortSpread == 5668);
446
+
447
+ const suiExample = {
448
+ status: 'active',
449
+ contractType: 'perpetual',
450
+ contractTier: 'c',
451
+ expiryTs: '0',
452
+ expiryPrice: '0',
453
+ marketIndex: 9,
454
+ pubkey: '91NsaUmTNNdLGbYtwmoiYSn9SgWHCsZiChfMYMYZ2nQx',
455
+ name: 'SUI-PERP',
456
+ amm: {
457
+ baseAssetReserve: '234381482764434',
458
+ sqrtK: '109260723000000001',
459
+ lastFundingRate: '-16416',
460
+ lastFundingRateTs: '1705845755',
461
+ lastMarkPriceTwap: '1105972',
462
+ lastMarkPriceTwap5Min: '1101202',
463
+ lastMarkPriceTwapTs: '1705846920',
464
+ lastTradeTs: '1705846920',
465
+ oracle: '3Qub3HaAJaa2xNY7SUqPKd3vVwTqDfDDkEUMPjXD2c1q',
466
+ oracleSource: 'pyth',
467
+ historicalOracleData: {
468
+ lastOraclePrice: '1099778',
469
+ lastOracleDelay: '2',
470
+ lastOracleConf: '0',
471
+ lastOraclePriceTwap: '1106680',
472
+ lastOraclePriceTwap5Min: '1102634',
473
+ lastOraclePriceTwapTs: '1705846920',
474
+ },
475
+ lastOracleReservePriceSpreadPct: '-262785',
476
+ lastOracleConfPct: '1359',
477
+ fundingPeriod: '3600',
478
+ quoteAssetReserve: '50933655038273508156',
479
+ pegMultiplier: '4',
480
+ cumulativeFundingRateLong: '186069301',
481
+ cumulativeFundingRateShort: '186007157',
482
+ last24HAvgFundingRate: '35147',
483
+ lastFundingRateShort: '-16416',
484
+ lastFundingRateLong: '-16416',
485
+ totalLiquidationFee: '4889264000',
486
+ totalFeeMinusDistributions: '-29523583393',
487
+ totalFeeWithdrawn: '5251194706',
488
+ totalFee: '7896066035',
489
+ totalFeeEarnedPerLp: '77063238',
490
+ userLpShares: '109260723000000000',
491
+ baseAssetAmountWithUnsettledLp: '-762306519581',
492
+ orderStepSize: '1000000000',
493
+ orderTickSize: '100',
494
+ maxFillReserveFraction: '100',
495
+ maxSlippageRatio: '50',
496
+ baseSpread: '5000',
497
+ curveUpdateIntensity: '100',
498
+ baseAssetAmountWithAmm: '306519581',
499
+ baseAssetAmountLong: '223405000000000',
500
+ baseAssetAmountShort: '-224167000000000',
501
+ quoteAssetAmount: '57945607973',
502
+ terminalQuoteAssetReserve: '50933588428309274920',
503
+ concentrationCoef: '1207100',
504
+ feePool: '[object Object]',
505
+ totalExchangeFee: '10110336057',
506
+ totalMmFee: '-1870961568',
507
+ netRevenueSinceLastFunding: '-141830281',
508
+ lastUpdateSlot: '243204071',
509
+ lastOracleNormalisedPrice: '1098594',
510
+ lastOracleValid: 'true',
511
+ lastBidPriceTwap: '1105864',
512
+ lastAskPriceTwap: '1106081',
513
+ longSpread: '259471',
514
+ shortSpread: '3314',
515
+ maxSpread: '29500',
516
+ baseAssetAmountPerLp: '-11388426214145',
517
+ quoteAssetAmountPerLp: '13038990874',
518
+ targetBaseAssetAmountPerLp: '0',
519
+ ammJitIntensity: '200',
520
+ maxOpenInterest: '2000000000000000',
521
+ maxBaseAssetReserve: '282922257844734',
522
+ minBaseAssetReserve: '194169322578092',
523
+ totalSocialLoss: '0',
524
+ quoteBreakEvenAmountLong: '-237442196125',
525
+ quoteBreakEvenAmountShort: '243508341566',
526
+ quoteEntryAmountLong: '-234074123777',
527
+ quoteEntryAmountShort: '240215285058',
528
+ markStd: '237945',
529
+ oracleStd: '8086',
530
+ longIntensityCount: '0',
531
+ longIntensityVolume: '162204',
532
+ shortIntensityCount: '995',
533
+ shortIntensityVolume: '2797331131',
534
+ volume24H: '91370028405',
535
+ minOrderSize: '1000000000',
536
+ maxPositionSize: '0',
537
+ bidBaseAssetReserve: '234770820775670',
538
+ bidQuoteAssetReserve: '50849187948657797529',
539
+ askBaseAssetReserve: '205083797418879',
540
+ askQuoteAssetReserve: '58209891472312580749',
541
+ perLpBase: '4',
542
+ },
543
+ numberOfUsersWithBase: '279',
544
+ numberOfUsers: '436',
545
+ marginRatioInitial: '1000',
546
+ marginRatioMaintenance: '500',
547
+ nextFillRecordId: '69433',
548
+ nextFundingRateRecordId: '6221',
549
+ nextCurveRecordId: '1731',
550
+ pnlPool: {
551
+ scaledBalance: '61514197782399',
552
+ marketIndex: '0',
553
+ },
554
+ liquidatorFee: '10000',
555
+ ifLiquidationFee: '20000',
556
+ imfFactor: '450',
557
+ unrealizedPnlImfFactor: '450',
558
+ unrealizedPnlMaxImbalance: '200000000',
559
+ unrealizedPnlInitialAssetWeight: '0',
560
+ unrealizedPnlMaintenanceAssetWeight: '10000',
561
+ insuranceClaim: {
562
+ revenueWithdrawSinceLastSettle: '100000000',
563
+ maxRevenueWithdrawPerPeriod: '100000000',
564
+ lastRevenueWithdrawTs: '1705846454',
565
+ quoteSettledInsurance: '164388488',
566
+ quoteMaxInsurance: '1000000000',
567
+ },
568
+ quoteSpotMarketIndex: '0',
569
+ feeAdjustment: '0',
570
+ };
571
+
572
+ const reservePrice = calculatePrice(
573
+ new BN(suiExample.amm.baseAssetReserve),
574
+ new BN(suiExample.amm.quoteAssetReserve),
575
+ new BN(suiExample.amm.pegMultiplier)
576
+ );
577
+ console.log('reservePrice', reservePrice.toString());
578
+ assert(reservePrice.eq(new BN('869243')));
579
+
580
+ const reservePriceMod = calculatePrice(
581
+ new BN(suiExample.amm.baseAssetReserve),
582
+ new BN(suiExample.amm.quoteAssetReserve),
583
+ new BN(suiExample.amm.pegMultiplier).add(ONE)
584
+ );
585
+ console.log('reservePriceMod', reservePriceMod.toString());
586
+ assert(reservePriceMod.eq(new BN('1086554')));
587
+
588
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
589
+ // @ts-ignore
590
+ const termsSuiExample: AMMSpreadTerms = calculateSpreadBN(
591
+ Number(suiExample.amm.baseSpread.toString()),
592
+ new BN(suiExample.amm.lastOracleReservePriceSpreadPct),
593
+ new BN(suiExample.amm.lastOracleConfPct),
594
+ Number(suiExample.amm.maxSpread.toString()),
595
+ new BN(suiExample.amm.quoteAssetReserve),
596
+ new BN(suiExample.amm.terminalQuoteAssetReserve),
597
+ new BN(suiExample.amm.pegMultiplier),
598
+ new BN(suiExample.amm.baseAssetAmountWithAmm),
599
+ reservePrice, // reserve price
600
+ new BN(suiExample.amm.totalFeeMinusDistributions),
601
+ new BN(suiExample.amm.netRevenueSinceLastFunding),
602
+ new BN(suiExample.amm.baseAssetReserve),
603
+ new BN(suiExample.amm.minBaseAssetReserve),
604
+ new BN(suiExample.amm.maxBaseAssetReserve),
605
+ new BN(suiExample.amm.markStd),
606
+ new BN(suiExample.amm.oracleStd),
607
+ new BN(suiExample.amm.longIntensityVolume),
608
+ new BN(suiExample.amm.shortIntensityVolume),
609
+ new BN(suiExample.amm.volume24H),
610
+ true
611
+ );
612
+
613
+ // console.log(termsSuiExample);
614
+ assert(termsSuiExample.effectiveLeverageCapped <= 1.000001);
615
+ assert(termsSuiExample.inventorySpreadScale == 1.00007);
616
+ assert(termsSuiExample.longSpread == 259073);
617
+ assert(termsSuiExample.shortSpread == 3712);
618
+
619
+ // reset amm reserves/peg to balanced values s.t. liquidity/price is the same
620
+ // to avoid error prone int math
621
+
622
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
623
+ // @ts-ignore
624
+ const termsSuiExampleMod1: AMMSpreadTerms = calculateSpreadBN(
625
+ Number(suiExample.amm.baseSpread.toString()),
626
+ ZERO,
627
+ new BN(suiExample.amm.lastOracleConfPct),
628
+ Number(suiExample.amm.maxSpread.toString()),
629
+ new BN(suiExample.amm.quoteAssetReserve),
630
+ new BN(suiExample.amm.terminalQuoteAssetReserve),
631
+ new BN(suiExample.amm.pegMultiplier),
632
+ new BN(suiExample.amm.baseAssetAmountWithAmm),
633
+ reservePriceMod, // reserve price
634
+ new BN(suiExample.amm.totalFeeMinusDistributions),
635
+ new BN(suiExample.amm.netRevenueSinceLastFunding),
636
+ new BN(suiExample.amm.baseAssetReserve),
637
+ new BN(suiExample.amm.minBaseAssetReserve),
638
+ new BN(suiExample.amm.maxBaseAssetReserve),
639
+ new BN(suiExample.amm.markStd),
640
+ new BN(suiExample.amm.oracleStd),
641
+ new BN(suiExample.amm.longIntensityVolume),
642
+ new BN(suiExample.amm.shortIntensityVolume),
643
+ new BN(suiExample.amm.volume24H),
644
+ true
645
+ );
646
+ console.log(termsSuiExampleMod1);
647
+
648
+ // todo: add sdk recenter function?
649
+
650
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
651
+ // @ts-ignore
652
+ const termsSuiExampleMod2: AMMSpreadTerms = calculateSpreadBN(
653
+ Number(suiExample.amm.baseSpread.toString()),
654
+ ZERO,
655
+ new BN(suiExample.amm.lastOracleConfPct),
656
+ Number(suiExample.amm.maxSpread.toString()),
657
+ new BN(suiExample.amm.sqrtK),
658
+ new BN(suiExample.amm.terminalQuoteAssetReserve),
659
+ reservePriceMod, // peg
660
+ new BN(suiExample.amm.baseAssetAmountWithAmm),
661
+ reservePriceMod, // reserve price
662
+ new BN(suiExample.amm.totalFeeMinusDistributions),
663
+ new BN(suiExample.amm.netRevenueSinceLastFunding),
664
+ new BN(suiExample.amm.sqrtK),
665
+ new BN(suiExample.amm.sqrtK.sub()),
666
+ new BN(suiExample.amm.maxBaseAssetReserve),
667
+ new BN(suiExample.amm.markStd),
668
+ new BN(suiExample.amm.oracleStd),
669
+ new BN(suiExample.amm.longIntensityVolume),
670
+ new BN(suiExample.amm.shortIntensityVolume),
671
+ new BN(suiExample.amm.volume24H),
672
+ true
673
+ );
674
+
675
+ console.log(termsSuiExampleMod2);
676
+ // assert(_.isEqual(termsSuiExampleMod2, termsSuiExampleMod1));
445
677
  });
446
678
 
447
679
  it('Spread Reserves (with offset)', () => {