@drift-labs/sdk 2.57.0-beta.0 → 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.0
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: {
@@ -234,6 +234,16 @@ exports.DevnetPerpMarkets = [
234
234
  launchTs: 1704209558000,
235
235
  oracleSource: __1.OracleSource.PYTH,
236
236
  },
237
+ // {
238
+ // fullName: 'WIF',
239
+ // category: ['Meme', 'Dog'],
240
+ // symbol: 'WIF-PERP',
241
+ // baseAssetSymbol: 'WIF',
242
+ // marketIndex: 23,
243
+ // oracle: new PublicKey('5i1sz2QQjCQt9PnhuPvqbiYUAYCgjdRnza1JbiH2qRCo'),
244
+ // launchTs: 1706219971000,
245
+ // oracleSource: OracleSource.PYTH,
246
+ // },
237
247
  ];
238
248
  exports.MainnetPerpMarkets = [
239
249
  {
@@ -466,6 +476,16 @@ exports.MainnetPerpMarkets = [
466
476
  launchTs: 1704209558000,
467
477
  oracleSource: __1.OracleSource.PYTH,
468
478
  },
479
+ {
480
+ fullName: 'WIF',
481
+ category: ['Meme', 'Dog'],
482
+ symbol: 'WIF-PERP',
483
+ baseAssetSymbol: 'WIF',
484
+ marketIndex: 23,
485
+ oracle: new web3_js_1.PublicKey('6ABgrEZk8urs6kJ1JNdC1sspH5zKXRqxy8sg3ZG2cQps'),
486
+ launchTs: 1706219971000,
487
+ oracleSource: __1.OracleSource.PYTH,
488
+ },
469
489
  ];
470
490
  exports.PerpMarkets = {
471
491
  devnet: exports.DevnetPerpMarkets,
@@ -140,6 +140,16 @@ exports.MainnetSpotMarkets = [
140
140
  precisionExp: numericConstants_1.NINE,
141
141
  serumMarket: new web3_js_1.PublicKey('H87FfmHABiZLRGrDsXRZtqq25YpARzaokCzL1vMYGiep'),
142
142
  },
143
+ {
144
+ symbol: 'WIF',
145
+ marketIndex: 10,
146
+ oracle: new web3_js_1.PublicKey('6ABgrEZk8urs6kJ1JNdC1sspH5zKXRqxy8sg3ZG2cQps'),
147
+ oracleSource: __1.OracleSource.PYTH,
148
+ mint: new web3_js_1.PublicKey('EKpQGSJtjMFqKZ9KQanSqYXRcF8fBopzLHYxdM65zcjm'),
149
+ precision: new __1.BN(10).pow(numericConstants_1.SIX),
150
+ precisionExp: numericConstants_1.SIX,
151
+ serumMarket: new web3_js_1.PublicKey('2BtDHBTCTUxvdur498ZEcMgimasaFrY5GzLv8wS8XgCb'),
152
+ },
143
153
  ];
144
154
  exports.SpotMarkets = {
145
155
  devnet: exports.DevnetSpotMarkets,
@@ -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.0",
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
@@ -244,6 +244,16 @@ export const DevnetPerpMarkets: PerpMarketConfig[] = [
244
244
  launchTs: 1704209558000,
245
245
  oracleSource: OracleSource.PYTH,
246
246
  },
247
+ // {
248
+ // fullName: 'WIF',
249
+ // category: ['Meme', 'Dog'],
250
+ // symbol: 'WIF-PERP',
251
+ // baseAssetSymbol: 'WIF',
252
+ // marketIndex: 23,
253
+ // oracle: new PublicKey('5i1sz2QQjCQt9PnhuPvqbiYUAYCgjdRnza1JbiH2qRCo'),
254
+ // launchTs: 1706219971000,
255
+ // oracleSource: OracleSource.PYTH,
256
+ // },
247
257
  ];
248
258
 
249
259
  export const MainnetPerpMarkets: PerpMarketConfig[] = [
@@ -477,6 +487,16 @@ export const MainnetPerpMarkets: PerpMarketConfig[] = [
477
487
  launchTs: 1704209558000,
478
488
  oracleSource: OracleSource.PYTH,
479
489
  },
490
+ {
491
+ fullName: 'WIF',
492
+ category: ['Meme', 'Dog'],
493
+ symbol: 'WIF-PERP',
494
+ baseAssetSymbol: 'WIF',
495
+ marketIndex: 23,
496
+ oracle: new PublicKey('6ABgrEZk8urs6kJ1JNdC1sspH5zKXRqxy8sg3ZG2cQps'),
497
+ launchTs: 1706219971000,
498
+ oracleSource: OracleSource.PYTH,
499
+ },
480
500
  ];
481
501
 
482
502
  export const PerpMarkets: { [key in DriftEnv]: PerpMarketConfig[] } = {
@@ -170,6 +170,16 @@ export const MainnetSpotMarkets: SpotMarketConfig[] = [
170
170
  precisionExp: NINE,
171
171
  serumMarket: new PublicKey('H87FfmHABiZLRGrDsXRZtqq25YpARzaokCzL1vMYGiep'),
172
172
  },
173
+ {
174
+ symbol: 'WIF',
175
+ marketIndex: 10,
176
+ oracle: new PublicKey('6ABgrEZk8urs6kJ1JNdC1sspH5zKXRqxy8sg3ZG2cQps'),
177
+ oracleSource: OracleSource.PYTH,
178
+ mint: new PublicKey('EKpQGSJtjMFqKZ9KQanSqYXRcF8fBopzLHYxdM65zcjm'),
179
+ precision: new BN(10).pow(SIX),
180
+ precisionExp: SIX,
181
+ serumMarket: new PublicKey('2BtDHBTCTUxvdur498ZEcMgimasaFrY5GzLv8wS8XgCb'),
182
+ },
173
183
  ];
174
184
 
175
185
  export const SpotMarkets: { [key in DriftEnv]: SpotMarketConfig[] } = {
@@ -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)', () => {