@drift-labs/sdk 2.37.1-beta.8 → 2.37.1-beta.9

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.37.1-beta.8
1
+ 2.37.1-beta.9
@@ -26,6 +26,7 @@ export declare class AdminClient extends DriftClient {
26
26
  updateAmmJitIntensity(perpMarketIndex: number, ammJitIntensity: number): Promise<TransactionSignature>;
27
27
  updatePerpMarketName(perpMarketIndex: number, name: string): Promise<TransactionSignature>;
28
28
  updateSpotMarketName(spotMarketIndex: number, name: string): Promise<TransactionSignature>;
29
+ updatePerpMarketPerLpBase(perpMarketIndex: number, perLpBase: number): Promise<TransactionSignature>;
29
30
  updatePerpMarketMaxSpread(perpMarketIndex: number, maxSpread: number): Promise<TransactionSignature>;
30
31
  updatePerpFeeStructure(feeStructure: FeeStructure): Promise<TransactionSignature>;
31
32
  updateSpotFeeStructure(feeStructure: FeeStructure): Promise<TransactionSignature>;
@@ -365,6 +365,16 @@ class AdminClient extends driftClient_1.DriftClient {
365
365
  },
366
366
  });
367
367
  }
368
+ async updatePerpMarketPerLpBase(perpMarketIndex, perLpBase) {
369
+ const perpMarketPublicKey = await (0, pda_1.getPerpMarketPublicKey)(this.program.programId, perpMarketIndex);
370
+ return await this.program.rpc.updatePerpMarketPerLpBase(perLpBase, {
371
+ accounts: {
372
+ admin: this.wallet.publicKey,
373
+ state: await this.getStatePublicKey(),
374
+ perpMarket: perpMarketPublicKey,
375
+ },
376
+ });
377
+ }
368
378
  async updatePerpMarketMaxSpread(perpMarketIndex, maxSpread) {
369
379
  const perpMarketPublicKey = await (0, pda_1.getPerpMarketPublicKey)(this.program.programId, perpMarketIndex);
370
380
  return await this.program.rpc.updatePerpMarketMaxSpread(maxSpread, {
@@ -3882,6 +3882,32 @@
3882
3882
  }
3883
3883
  ]
3884
3884
  },
3885
+ {
3886
+ "name": "updatePerpMarketPerLpBase",
3887
+ "accounts": [
3888
+ {
3889
+ "name": "admin",
3890
+ "isMut": false,
3891
+ "isSigner": true
3892
+ },
3893
+ {
3894
+ "name": "state",
3895
+ "isMut": false,
3896
+ "isSigner": false
3897
+ },
3898
+ {
3899
+ "name": "perpMarket",
3900
+ "isMut": true,
3901
+ "isSigner": false
3902
+ }
3903
+ ],
3904
+ "args": [
3905
+ {
3906
+ "name": "perLpBase",
3907
+ "type": "i8"
3908
+ }
3909
+ ]
3910
+ },
3885
3911
  {
3886
3912
  "name": "updateLpCooldownTime",
3887
3913
  "accounts": [
@@ -6978,9 +7004,20 @@
6978
7004
  ],
6979
7005
  "type": "i32"
6980
7006
  },
7007
+ {
7008
+ "name": "perLpBase",
7009
+ "docs": [
7010
+ "expo for unit of per_lp, base 10 (if per_lp_base=X, then per_lp unit is 10^X)"
7011
+ ],
7012
+ "type": "i8"
7013
+ },
6981
7014
  {
6982
7015
  "name": "padding1",
6983
- "type": "u32"
7016
+ "type": "u8"
7017
+ },
7018
+ {
7019
+ "name": "padding2",
7020
+ "type": "u16"
6984
7021
  },
6985
7022
  {
6986
7023
  "name": "totalFeeEarnedPerLp",
@@ -7447,13 +7484,8 @@
7447
7484
  "type": "u8"
7448
7485
  },
7449
7486
  {
7450
- "name": "padding",
7451
- "type": {
7452
- "array": [
7453
- "u8",
7454
- 1
7455
- ]
7456
- }
7487
+ "name": "perLpBase",
7488
+ "type": "i8"
7457
7489
  }
7458
7490
  ]
7459
7491
  }
package/lib/types.d.ts CHANGED
@@ -821,6 +821,7 @@ export type AMM = {
821
821
  bidQuoteAssetReserve: BN;
822
822
  askBaseAssetReserve: BN;
823
823
  askQuoteAssetReserve: BN;
824
+ perLpBase: number;
824
825
  };
825
826
  export type PerpPosition = {
826
827
  baseAssetAmount: BN;
@@ -837,6 +838,7 @@ export type PerpPosition = {
837
838
  remainderBaseAssetAmount: number;
838
839
  lastBaseAssetAmountPerLp: BN;
839
840
  lastQuoteAssetAmountPerLp: BN;
841
+ perLpBase: number;
840
842
  };
841
843
  export type UserStatsAccount = {
842
844
  numberOfSubAccounts: number;
package/lib/user.js CHANGED
@@ -145,6 +145,7 @@ class User {
145
145
  lpShares: numericConstants_1.ZERO,
146
146
  lastBaseAssetAmountPerLp: numericConstants_1.ZERO,
147
147
  lastQuoteAssetAmountPerLp: numericConstants_1.ZERO,
148
+ perLpBase: 0,
148
149
  };
149
150
  }
150
151
  getClonedPosition(position) {
@@ -258,17 +259,54 @@ class User {
258
259
  }
259
260
  const position = this.getClonedPosition(originalPosition);
260
261
  const market = this.driftClient.getPerpMarketAccount(position.marketIndex);
262
+ if (market.amm.perLpBase != position.perLpBase) {
263
+ // perLpBase = 1 => per 10 LP shares, perLpBase = -1 => per 0.1 LP shares
264
+ const expoDiff = market.amm.perLpBase - position.perLpBase;
265
+ const marketPerLpRebaseScalar = new _1.BN(10 ** Math.abs(expoDiff));
266
+ if (expoDiff > 0) {
267
+ position.lastBaseAssetAmountPerLp =
268
+ position.lastBaseAssetAmountPerLp.mul(marketPerLpRebaseScalar);
269
+ position.lastQuoteAssetAmountPerLp =
270
+ position.lastQuoteAssetAmountPerLp.mul(marketPerLpRebaseScalar);
271
+ }
272
+ else {
273
+ position.lastBaseAssetAmountPerLp =
274
+ position.lastBaseAssetAmountPerLp.div(marketPerLpRebaseScalar);
275
+ position.lastQuoteAssetAmountPerLp =
276
+ position.lastQuoteAssetAmountPerLp.div(marketPerLpRebaseScalar);
277
+ }
278
+ position.perLpBase = position.perLpBase + expoDiff;
279
+ }
261
280
  const nShares = position.lpShares;
262
281
  // incorp unsettled funding on pre settled position
263
282
  const quoteFundingPnl = (0, _1.calculatePositionFundingPNL)(market, position);
283
+ let baseUnit = numericConstants_1.AMM_RESERVE_PRECISION;
284
+ if (market.amm.perLpBase == position.perLpBase) {
285
+ if (position.perLpBase >= 0 &&
286
+ position.perLpBase <= numericConstants_1.AMM_RESERVE_PRECISION_EXP.toNumber()) {
287
+ const marketPerLpRebase = new _1.BN(10 ** market.amm.perLpBase);
288
+ baseUnit = baseUnit.mul(marketPerLpRebase);
289
+ }
290
+ else if (position.perLpBase < 0 &&
291
+ position.perLpBase >= -numericConstants_1.AMM_RESERVE_PRECISION_EXP.toNumber()) {
292
+ const marketPerLpRebase = new _1.BN(10 ** Math.abs(market.amm.perLpBase));
293
+ baseUnit = baseUnit.div(marketPerLpRebase);
294
+ }
295
+ else {
296
+ throw 'cannot calc';
297
+ }
298
+ }
299
+ else {
300
+ throw 'market.amm.perLpBase != position.perLpBase';
301
+ }
264
302
  const deltaBaa = market.amm.baseAssetAmountPerLp
265
303
  .sub(position.lastBaseAssetAmountPerLp)
266
304
  .mul(nShares)
267
- .div(numericConstants_1.AMM_RESERVE_PRECISION);
305
+ .div(baseUnit);
268
306
  const deltaQaa = market.amm.quoteAssetAmountPerLp
269
307
  .sub(position.lastQuoteAssetAmountPerLp)
270
308
  .mul(nShares)
271
- .div(numericConstants_1.AMM_RESERVE_PRECISION);
309
+ .div(baseUnit);
272
310
  function sign(v) {
273
311
  return v.isNeg() ? new _1.BN(-1) : new _1.BN(1);
274
312
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drift-labs/sdk",
3
- "version": "2.37.1-beta.8",
3
+ "version": "2.37.1-beta.9",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/index.d.ts",
6
6
  "author": "crispheaney",
@@ -691,6 +691,24 @@ export class AdminClient extends DriftClient {
691
691
  });
692
692
  }
693
693
 
694
+ public async updatePerpMarketPerLpBase(
695
+ perpMarketIndex: number,
696
+ perLpBase: number
697
+ ): Promise<TransactionSignature> {
698
+ const perpMarketPublicKey = await getPerpMarketPublicKey(
699
+ this.program.programId,
700
+ perpMarketIndex
701
+ );
702
+
703
+ return await this.program.rpc.updatePerpMarketPerLpBase(perLpBase, {
704
+ accounts: {
705
+ admin: this.wallet.publicKey,
706
+ state: await this.getStatePublicKey(),
707
+ perpMarket: perpMarketPublicKey,
708
+ },
709
+ });
710
+ }
711
+
694
712
  public async updatePerpMarketMaxSpread(
695
713
  perpMarketIndex: number,
696
714
  maxSpread: number
@@ -3882,6 +3882,32 @@
3882
3882
  }
3883
3883
  ]
3884
3884
  },
3885
+ {
3886
+ "name": "updatePerpMarketPerLpBase",
3887
+ "accounts": [
3888
+ {
3889
+ "name": "admin",
3890
+ "isMut": false,
3891
+ "isSigner": true
3892
+ },
3893
+ {
3894
+ "name": "state",
3895
+ "isMut": false,
3896
+ "isSigner": false
3897
+ },
3898
+ {
3899
+ "name": "perpMarket",
3900
+ "isMut": true,
3901
+ "isSigner": false
3902
+ }
3903
+ ],
3904
+ "args": [
3905
+ {
3906
+ "name": "perLpBase",
3907
+ "type": "i8"
3908
+ }
3909
+ ]
3910
+ },
3885
3911
  {
3886
3912
  "name": "updateLpCooldownTime",
3887
3913
  "accounts": [
@@ -6978,9 +7004,20 @@
6978
7004
  ],
6979
7005
  "type": "i32"
6980
7006
  },
7007
+ {
7008
+ "name": "perLpBase",
7009
+ "docs": [
7010
+ "expo for unit of per_lp, base 10 (if per_lp_base=X, then per_lp unit is 10^X)"
7011
+ ],
7012
+ "type": "i8"
7013
+ },
6981
7014
  {
6982
7015
  "name": "padding1",
6983
- "type": "u32"
7016
+ "type": "u8"
7017
+ },
7018
+ {
7019
+ "name": "padding2",
7020
+ "type": "u16"
6984
7021
  },
6985
7022
  {
6986
7023
  "name": "totalFeeEarnedPerLp",
@@ -7447,13 +7484,8 @@
7447
7484
  "type": "u8"
7448
7485
  },
7449
7486
  {
7450
- "name": "padding",
7451
- "type": {
7452
- "array": [
7453
- "u8",
7454
- 1
7455
- ]
7456
- }
7487
+ "name": "perLpBase",
7488
+ "type": "i8"
7457
7489
  }
7458
7490
  ]
7459
7491
  }
package/src/types.ts CHANGED
@@ -767,6 +767,8 @@ export type AMM = {
767
767
  bidQuoteAssetReserve: BN;
768
768
  askBaseAssetReserve: BN;
769
769
  askQuoteAssetReserve: BN;
770
+
771
+ perLpBase: number; // i8
770
772
  };
771
773
 
772
774
  // # User Account Types
@@ -785,6 +787,7 @@ export type PerpPosition = {
785
787
  remainderBaseAssetAmount: number;
786
788
  lastBaseAssetAmountPerLp: BN;
787
789
  lastQuoteAssetAmountPerLp: BN;
790
+ perLpBase: number;
788
791
  };
789
792
 
790
793
  export type UserStatsAccount = {
package/src/user.ts CHANGED
@@ -31,6 +31,7 @@ import {
31
31
  BASE_PRECISION,
32
32
  ONE,
33
33
  TWO,
34
+ AMM_RESERVE_PRECISION_EXP,
34
35
  } from './constants/numericConstants';
35
36
  import {
36
37
  UserAccountSubscriber,
@@ -264,6 +265,7 @@ export class User {
264
265
  lpShares: ZERO,
265
266
  lastBaseAssetAmountPerLp: ZERO,
266
267
  lastQuoteAssetAmountPerLp: ZERO,
268
+ perLpBase: 0,
267
269
  };
268
270
  }
269
271
 
@@ -427,21 +429,62 @@ export class User {
427
429
  }
428
430
 
429
431
  const position = this.getClonedPosition(originalPosition);
430
-
431
432
  const market = this.driftClient.getPerpMarketAccount(position.marketIndex);
433
+
434
+ if (market.amm.perLpBase != position.perLpBase) {
435
+ // perLpBase = 1 => per 10 LP shares, perLpBase = -1 => per 0.1 LP shares
436
+ const expoDiff = market.amm.perLpBase - position.perLpBase;
437
+ const marketPerLpRebaseScalar = new BN(10 ** Math.abs(expoDiff));
438
+
439
+ if (expoDiff > 0) {
440
+ position.lastBaseAssetAmountPerLp =
441
+ position.lastBaseAssetAmountPerLp.mul(marketPerLpRebaseScalar);
442
+ position.lastQuoteAssetAmountPerLp =
443
+ position.lastQuoteAssetAmountPerLp.mul(marketPerLpRebaseScalar);
444
+ } else {
445
+ position.lastBaseAssetAmountPerLp =
446
+ position.lastBaseAssetAmountPerLp.div(marketPerLpRebaseScalar);
447
+ position.lastQuoteAssetAmountPerLp =
448
+ position.lastQuoteAssetAmountPerLp.div(marketPerLpRebaseScalar);
449
+ }
450
+
451
+ position.perLpBase = position.perLpBase + expoDiff;
452
+ }
453
+
432
454
  const nShares = position.lpShares;
433
455
 
434
456
  // incorp unsettled funding on pre settled position
435
457
  const quoteFundingPnl = calculatePositionFundingPNL(market, position);
436
458
 
459
+ let baseUnit = AMM_RESERVE_PRECISION;
460
+ if (market.amm.perLpBase == position.perLpBase) {
461
+ if (
462
+ position.perLpBase >= 0 &&
463
+ position.perLpBase <= AMM_RESERVE_PRECISION_EXP.toNumber()
464
+ ) {
465
+ const marketPerLpRebase = new BN(10 ** market.amm.perLpBase);
466
+ baseUnit = baseUnit.mul(marketPerLpRebase);
467
+ } else if (
468
+ position.perLpBase < 0 &&
469
+ position.perLpBase >= -AMM_RESERVE_PRECISION_EXP.toNumber()
470
+ ) {
471
+ const marketPerLpRebase = new BN(10 ** Math.abs(market.amm.perLpBase));
472
+ baseUnit = baseUnit.div(marketPerLpRebase);
473
+ } else {
474
+ throw 'cannot calc';
475
+ }
476
+ } else {
477
+ throw 'market.amm.perLpBase != position.perLpBase';
478
+ }
479
+
437
480
  const deltaBaa = market.amm.baseAssetAmountPerLp
438
481
  .sub(position.lastBaseAssetAmountPerLp)
439
482
  .mul(nShares)
440
- .div(AMM_RESERVE_PRECISION);
483
+ .div(baseUnit);
441
484
  const deltaQaa = market.amm.quoteAssetAmountPerLp
442
485
  .sub(position.lastQuoteAssetAmountPerLp)
443
486
  .mul(nShares)
444
- .div(AMM_RESERVE_PRECISION);
487
+ .div(baseUnit);
445
488
 
446
489
  function sign(v: BN) {
447
490
  return v.isNeg() ? new BN(-1) : new BN(1);
@@ -39,9 +39,11 @@ export const mockPerpPosition: PerpPosition = {
39
39
  remainderBaseAssetAmount: 0,
40
40
  lastBaseAssetAmountPerLp: new BN(0),
41
41
  lastQuoteAssetAmountPerLp: new BN(0),
42
+ perLpBase: 0,
42
43
  };
43
44
 
44
45
  export const mockAMM: AMM = {
46
+ perLpBase: 0,
45
47
  /* these values create a bid/ask price of 12 */
46
48
  baseAssetReserve: new BN(1).mul(BASE_PRECISION),
47
49
  quoteAssetReserve: new BN(12)