@drift-labs/sdk 2.92.0-beta.2 → 2.92.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.
package/VERSION CHANGED
@@ -1 +1 @@
1
- 2.92.0-beta.2
1
+ 2.92.0-beta.3
package/bun.lockb CHANGED
Binary file
@@ -21,6 +21,8 @@ export declare class AdminClient extends DriftClient {
21
21
  getInitializeOpenbookV2FulfillmentConfigIx(marketIndex: number, openbookMarket: PublicKey): Promise<TransactionInstruction>;
22
22
  initializePerpMarket(marketIndex: number, priceOracle: PublicKey, baseAssetReserve: BN, quoteAssetReserve: BN, periodicity: BN, pegMultiplier?: BN, oracleSource?: OracleSource, contractTier?: ContractTier, marginRatioInitial?: number, marginRatioMaintenance?: number, liquidatorFee?: number, ifLiquidatorFee?: number, imfFactor?: number, activeStatus?: boolean, baseSpread?: number, maxSpread?: number, maxOpenInterest?: BN, maxRevenueWithdrawPerPeriod?: BN, quoteMaxInsurance?: BN, orderStepSize?: BN, orderTickSize?: BN, minOrderSize?: BN, concentrationCoefScale?: BN, curveUpdateIntensity?: number, ammJitIntensity?: number, name?: string): Promise<TransactionSignature>;
23
23
  getInitializePerpMarketIx(marketIndex: number, priceOracle: PublicKey, baseAssetReserve: BN, quoteAssetReserve: BN, periodicity: BN, pegMultiplier?: BN, oracleSource?: OracleSource, contractTier?: ContractTier, marginRatioInitial?: number, marginRatioMaintenance?: number, liquidatorFee?: number, ifLiquidatorFee?: number, imfFactor?: number, activeStatus?: boolean, baseSpread?: number, maxSpread?: number, maxOpenInterest?: BN, maxRevenueWithdrawPerPeriod?: BN, quoteMaxInsurance?: BN, orderStepSize?: BN, orderTickSize?: BN, minOrderSize?: BN, concentrationCoefScale?: BN, curveUpdateIntensity?: number, ammJitIntensity?: number, name?: string): Promise<TransactionInstruction>;
24
+ initializePredictionMarket(perpMarketIndex: number): Promise<TransactionSignature>;
25
+ getInitializePredictionMarketIx(perpMarketIndex: number): Promise<TransactionInstruction>;
24
26
  deleteInitializedPerpMarket(marketIndex: number): Promise<TransactionSignature>;
25
27
  getDeleteInitializedPerpMarketIx(marketIndex: number): Promise<TransactionInstruction>;
26
28
  moveAmmPrice(perpMarketIndex: number, baseAssetReserve: BN, quoteAssetReserve: BN, sqrtK?: BN): Promise<TransactionSignature>;
@@ -236,6 +236,23 @@ class AdminClient extends driftClient_1.DriftClient {
236
236
  },
237
237
  });
238
238
  }
239
+ async initializePredictionMarket(perpMarketIndex) {
240
+ const updatePerpMarketConcentrationCoefIx = await this.getInitializePredictionMarketIx(perpMarketIndex);
241
+ const tx = await this.buildTransaction(updatePerpMarketConcentrationCoefIx);
242
+ const { txSig } = await this.sendTransaction(tx, [], this.opts);
243
+ return txSig;
244
+ }
245
+ async getInitializePredictionMarketIx(perpMarketIndex) {
246
+ return await this.program.instruction.initializePredictionMarket({
247
+ accounts: {
248
+ state: await this.getStatePublicKey(),
249
+ admin: this.isSubscribed
250
+ ? this.getStateAccount().admin
251
+ : this.wallet.publicKey,
252
+ perpMarket: await (0, pda_1.getPerpMarketPublicKey)(this.program.programId, perpMarketIndex),
253
+ },
254
+ });
255
+ }
239
256
  async deleteInitializedPerpMarket(marketIndex) {
240
257
  const deleteInitializeMarketIx = await this.getDeleteInitializedPerpMarketIx(marketIndex);
241
258
  const tx = await this.buildTransaction(deleteInitializeMarketIx);
@@ -68,3 +68,4 @@ export declare const SLOT_TIME_ESTIMATE_MS = 400;
68
68
  export declare const DUST_POSITION_SIZE: BN;
69
69
  export declare const FUEL_WINDOW: BN;
70
70
  export declare const FUEL_START_TS: BN;
71
+ export declare const MAX_PREDICTION_PRICE: BN;
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MARGIN_PRECISION = exports.AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO = exports.PRICE_TO_QUOTE_PRECISION = exports.PRICE_DIV_PEG = exports.AMM_TO_QUOTE_PRECISION_RATIO = exports.BASE_PRECISION_EXP = exports.BASE_PRECISION = exports.AMM_RESERVE_PRECISION = exports.PEG_PRECISION = exports.FUNDING_RATE_BUFFER_PRECISION = exports.FUNDING_RATE_PRECISION = exports.PRICE_PRECISION = exports.QUOTE_PRECISION = exports.LIQUIDATION_FEE_PRECISION = exports.SPOT_MARKET_IMF_PRECISION = exports.SPOT_MARKET_IMF_PRECISION_EXP = exports.SPOT_MARKET_BALANCE_PRECISION = exports.SPOT_MARKET_BALANCE_PRECISION_EXP = exports.SPOT_MARKET_WEIGHT_PRECISION = exports.SPOT_MARKET_UTILIZATION_PRECISION = exports.SPOT_MARKET_UTILIZATION_PRECISION_EXP = exports.SPOT_MARKET_CUMULATIVE_INTEREST_PRECISION = exports.SPOT_MARKET_CUMULATIVE_INTEREST_PRECISION_EXP = exports.SPOT_MARKET_RATE_PRECISION = exports.SPOT_MARKET_RATE_PRECISION_EXP = exports.AMM_RESERVE_PRECISION_EXP = exports.PEG_PRECISION_EXP = exports.FUNDING_RATE_PRECISION_EXP = exports.PRICE_PRECISION_EXP = exports.FUNDING_RATE_BUFFER_PRECISION_EXP = exports.QUOTE_PRECISION_EXP = exports.CONCENTRATION_PRECISION = exports.PERCENTAGE_PRECISION = exports.PERCENTAGE_PRECISION_EXP = exports.MAX_LEVERAGE_ORDER_SIZE = exports.MAX_LEVERAGE = exports.TEN_MILLION = exports.BN_MAX = exports.TEN_THOUSAND = exports.TEN = exports.NINE = exports.EIGHT = exports.SEVEN = exports.SIX = exports.FIVE = exports.FOUR = exports.THREE = exports.TWO = exports.ONE = exports.ZERO = void 0;
4
- exports.FUEL_START_TS = exports.FUEL_WINDOW = exports.DUST_POSITION_SIZE = exports.SLOT_TIME_ESTIMATE_MS = exports.IDLE_TIME_SLOTS = exports.ACCOUNT_AGE_DELETION_CUTOFF_SECONDS = exports.DEFAULT_REVENUE_SINCE_LAST_FUNDING_SPREAD_RETREAT = exports.OPEN_ORDER_MARGIN_REQUIREMENT = exports.LAMPORTS_EXP = exports.LAMPORTS_PRECISION = exports.GOV_SPOT_MARKET_INDEX = exports.QUOTE_SPOT_MARKET_INDEX = exports.ONE_YEAR = exports.ONE_HOUR = exports.FIVE_MINUTE = exports.FUNDING_RATE_OFFSET_DENOMINATOR = exports.LIQUIDATION_PCT_PRECISION = exports.BID_ASK_SPREAD_PRECISION = void 0;
4
+ exports.MAX_PREDICTION_PRICE = exports.FUEL_START_TS = exports.FUEL_WINDOW = exports.DUST_POSITION_SIZE = exports.SLOT_TIME_ESTIMATE_MS = exports.IDLE_TIME_SLOTS = exports.ACCOUNT_AGE_DELETION_CUTOFF_SECONDS = exports.DEFAULT_REVENUE_SINCE_LAST_FUNDING_SPREAD_RETREAT = exports.OPEN_ORDER_MARGIN_REQUIREMENT = exports.LAMPORTS_EXP = exports.LAMPORTS_PRECISION = exports.GOV_SPOT_MARKET_INDEX = exports.QUOTE_SPOT_MARKET_INDEX = exports.ONE_YEAR = exports.ONE_HOUR = exports.FIVE_MINUTE = exports.FUNDING_RATE_OFFSET_DENOMINATOR = exports.LIQUIDATION_PCT_PRECISION = exports.BID_ASK_SPREAD_PRECISION = void 0;
5
5
  const web3_js_1 = require("@solana/web3.js");
6
6
  const __1 = require("../");
7
7
  exports.ZERO = new __1.BN(0);
@@ -72,3 +72,4 @@ exports.SLOT_TIME_ESTIMATE_MS = 400;
72
72
  exports.DUST_POSITION_SIZE = exports.QUOTE_PRECISION.divn(100); // Dust position is any position smaller than 1c
73
73
  exports.FUEL_WINDOW = new __1.BN(60 * 60 * 24 * 28); // 28 days
74
74
  exports.FUEL_START_TS = new __1.BN(1723147200); // unix timestamp
75
+ exports.MAX_PREDICTION_PRICE = exports.PRICE_PRECISION;
@@ -104,7 +104,7 @@ function getVammL2Generator({ marketAccount, oraclePriceData, numOrders, now, to
104
104
  openAsks = __1.ZERO;
105
105
  }
106
106
  now = now !== null && now !== void 0 ? now : new __1.BN(Date.now() / 1000);
107
- const [bidReserves, askReserves] = (0, __1.calculateSpreadReserves)(updatedAmm, oraclePriceData, now);
107
+ const [bidReserves, askReserves] = (0, __1.calculateSpreadReserves)(updatedAmm, oraclePriceData, now, (0, __1.isVariant)(marketAccount.contractType, 'prediction'));
108
108
  let numBids = 0;
109
109
  let topOfBookBidSize = __1.ZERO;
110
110
  let bidSize = openBids.div(new __1.BN(numBaseOrders));
@@ -3980,6 +3980,7 @@ class DriftClient {
3980
3980
  }
3981
3981
  const [pullIx, _responses, success] = await feedAccount.fetchUpdateIx({
3982
3982
  numSignatures,
3983
+ // @ts-ignore :: TODO someone needs to look at this
3983
3984
  feedConfigs: this.sbProgramFeedConfigs.get(feed.toString()),
3984
3985
  });
3985
3986
  if (!success) {
@@ -3403,6 +3403,27 @@
3403
3403
  }
3404
3404
  ]
3405
3405
  },
3406
+ {
3407
+ "name": "initializePredictionMarket",
3408
+ "accounts": [
3409
+ {
3410
+ "name": "admin",
3411
+ "isMut": false,
3412
+ "isSigner": true
3413
+ },
3414
+ {
3415
+ "name": "state",
3416
+ "isMut": false,
3417
+ "isSigner": false
3418
+ },
3419
+ {
3420
+ "name": "perpMarket",
3421
+ "isMut": true,
3422
+ "isSigner": false
3423
+ }
3424
+ ],
3425
+ "args": []
3426
+ },
3406
3427
  {
3407
3428
  "name": "deleteInitializedPerpMarket",
3408
3429
  "accounts": [
@@ -12906,6 +12927,11 @@
12906
12927
  "code": 6283,
12907
12928
  "name": "LiquidationOrderFailedToFill",
12908
12929
  "msg": "Liquidation order failed to fill"
12930
+ },
12931
+ {
12932
+ "code": 6284,
12933
+ "name": "InvalidPredictionMarketOrder",
12934
+ "msg": "Invalid prediction market order"
12909
12935
  }
12910
12936
  ],
12911
12937
  "metadata": {
package/lib/math/amm.d.ts CHANGED
@@ -6,13 +6,13 @@ export declare function calculatePegFromTargetPrice(targetPrice: BN, baseAssetRe
6
6
  export declare function calculateOptimalPegAndBudget(amm: AMM, oraclePriceData: OraclePriceData): [BN, BN, BN, boolean];
7
7
  export declare function calculateNewAmm(amm: AMM, oraclePriceData: OraclePriceData): [BN, BN, BN, BN];
8
8
  export declare function calculateUpdatedAMM(amm: AMM, oraclePriceData: OraclePriceData): AMM;
9
- export declare function calculateUpdatedAMMSpreadReserves(amm: AMM, direction: PositionDirection, oraclePriceData: OraclePriceData): {
9
+ export declare function calculateUpdatedAMMSpreadReserves(amm: AMM, direction: PositionDirection, oraclePriceData: OraclePriceData, isPrediction?: boolean): {
10
10
  baseAssetReserve: BN;
11
11
  quoteAssetReserve: BN;
12
12
  sqrtK: BN;
13
13
  newPeg: BN;
14
14
  };
15
- export declare function calculateBidAskPrice(amm: AMM, oraclePriceData: OraclePriceData, withUpdate?: boolean): [BN, BN];
15
+ export declare function calculateBidAskPrice(amm: AMM, oraclePriceData: OraclePriceData, withUpdate?: boolean, isPrediction?: boolean): [BN, BN];
16
16
  /**
17
17
  * Calculates a price given an arbitrary base and quote amount (they must have the same precision)
18
18
  *
@@ -64,7 +64,8 @@ export declare function calculateSpreadBN(baseSpread: number, lastOracleReserveP
64
64
  shortSpread: number;
65
65
  };
66
66
  export declare function calculateSpread(amm: AMM, oraclePriceData: OraclePriceData, now?: BN, reservePrice?: BN): [number, number];
67
- export declare function calculateSpreadReserves(amm: AMM, oraclePriceData: OraclePriceData, now?: BN): {
67
+ export declare function getQuoteAssetReservePredictionMarketBounds(amm: AMM, direction: PositionDirection): [BN, BN];
68
+ export declare function calculateSpreadReserves(amm: AMM, oraclePriceData: OraclePriceData, now?: BN, isPrediction?: boolean): {
68
69
  baseAssetReserve: any;
69
70
  quoteAssetReserve: any;
70
71
  }[];
@@ -92,6 +93,6 @@ export declare function getSwapDirection(inputAssetType: AssetType, positionDire
92
93
  * @returns cost : Precision PRICE_PRECISION
93
94
  */
94
95
  export declare function calculateTerminalPrice(market: PerpMarketAccount): BN;
95
- export declare function calculateMaxBaseAssetAmountToTrade(amm: AMM, limit_price: BN, direction: PositionDirection, oraclePriceData?: OraclePriceData, now?: BN): [BN, PositionDirection];
96
+ export declare function calculateMaxBaseAssetAmountToTrade(amm: AMM, limit_price: BN, direction: PositionDirection, oraclePriceData?: OraclePriceData, now?: BN, isPrediction?: boolean): [BN, PositionDirection];
96
97
  export declare function calculateQuoteAssetAmountSwapped(quoteAssetReserves: BN, pegMultiplier: BN, swapDirection: SwapDirection): BN;
97
98
  export declare function calculateMaxBaseAssetAmountFillable(amm: AMM, orderDirection: PositionDirection): BN;
package/lib/math/amm.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.calculateMaxBaseAssetAmountFillable = exports.calculateQuoteAssetAmountSwapped = exports.calculateMaxBaseAssetAmountToTrade = exports.calculateTerminalPrice = exports.getSwapDirection = exports.calculateSwapOutput = exports.calculateSpreadReserves = exports.calculateSpread = exports.calculateSpreadBN = exports.calculateVolSpreadBN = exports.calculateMaxSpread = exports.calculateEffectiveLeverage = exports.calculateReferencePriceOffset = exports.calculateInventoryScale = exports.calculateInventoryLiquidityRatio = exports.calculateMarketOpenBidAsk = exports.calculateAmmReservesAfterSwap = exports.calculatePrice = exports.calculateBidAskPrice = exports.calculateUpdatedAMMSpreadReserves = exports.calculateUpdatedAMM = exports.calculateNewAmm = exports.calculateOptimalPegAndBudget = exports.calculatePegFromTargetPrice = void 0;
3
+ exports.calculateMaxBaseAssetAmountFillable = exports.calculateQuoteAssetAmountSwapped = exports.calculateMaxBaseAssetAmountToTrade = exports.calculateTerminalPrice = exports.getSwapDirection = exports.calculateSwapOutput = exports.calculateSpreadReserves = exports.getQuoteAssetReservePredictionMarketBounds = exports.calculateSpread = exports.calculateSpreadBN = exports.calculateVolSpreadBN = exports.calculateMaxSpread = exports.calculateEffectiveLeverage = exports.calculateReferencePriceOffset = exports.calculateInventoryScale = exports.calculateInventoryLiquidityRatio = exports.calculateMarketOpenBidAsk = exports.calculateAmmReservesAfterSwap = exports.calculatePrice = exports.calculateBidAskPrice = exports.calculateUpdatedAMMSpreadReserves = exports.calculateUpdatedAMM = exports.calculateNewAmm = exports.calculateOptimalPegAndBudget = exports.calculatePegFromTargetPrice = void 0;
4
4
  const anchor_1 = require("@coral-xyz/anchor");
5
5
  const numericConstants_1 = require("../constants/numericConstants");
6
6
  const types_1 = require("../types");
@@ -103,9 +103,9 @@ function calculateUpdatedAMM(amm, oraclePriceData) {
103
103
  return newAmm;
104
104
  }
105
105
  exports.calculateUpdatedAMM = calculateUpdatedAMM;
106
- function calculateUpdatedAMMSpreadReserves(amm, direction, oraclePriceData) {
106
+ function calculateUpdatedAMMSpreadReserves(amm, direction, oraclePriceData, isPrediction = false) {
107
107
  const newAmm = calculateUpdatedAMM(amm, oraclePriceData);
108
- const [shortReserves, longReserves] = calculateSpreadReserves(newAmm, oraclePriceData);
108
+ const [shortReserves, longReserves] = calculateSpreadReserves(newAmm, oraclePriceData, undefined, isPrediction);
109
109
  const dirReserves = (0, types_1.isVariant)(direction, 'long')
110
110
  ? longReserves
111
111
  : shortReserves;
@@ -118,7 +118,7 @@ function calculateUpdatedAMMSpreadReserves(amm, direction, oraclePriceData) {
118
118
  return result;
119
119
  }
120
120
  exports.calculateUpdatedAMMSpreadReserves = calculateUpdatedAMMSpreadReserves;
121
- function calculateBidAskPrice(amm, oraclePriceData, withUpdate = true) {
121
+ function calculateBidAskPrice(amm, oraclePriceData, withUpdate = true, isPrediction = false) {
122
122
  let newAmm;
123
123
  if (withUpdate) {
124
124
  newAmm = calculateUpdatedAMM(amm, oraclePriceData);
@@ -126,7 +126,7 @@ function calculateBidAskPrice(amm, oraclePriceData, withUpdate = true) {
126
126
  else {
127
127
  newAmm = amm;
128
128
  }
129
- const [bidReserves, askReserves] = calculateSpreadReserves(newAmm, oraclePriceData);
129
+ const [bidReserves, askReserves] = calculateSpreadReserves(newAmm, oraclePriceData, undefined, isPrediction);
130
130
  const askPrice = calculatePrice(askReserves.baseAssetReserve, askReserves.quoteAssetReserve, newAmm.pegMultiplier);
131
131
  const bidPrice = calculatePrice(bidReserves.baseAssetReserve, bidReserves.quoteAssetReserve, newAmm.pegMultiplier);
132
132
  return [bidPrice, askPrice];
@@ -442,7 +442,30 @@ function calculateSpread(amm, oraclePriceData, now, reservePrice) {
442
442
  return [longSpread, shortSpread];
443
443
  }
444
444
  exports.calculateSpread = calculateSpread;
445
- function calculateSpreadReserves(amm, oraclePriceData, now) {
445
+ function getQuoteAssetReservePredictionMarketBounds(amm, direction) {
446
+ let quoteAssetReserveLowerBound = numericConstants_1.ZERO;
447
+ const pegSqrt = (0, __1.squareRootBN)(amm.pegMultiplier.mul(numericConstants_1.PEG_PRECISION).addn(1)).addn(1);
448
+ let quoteAssetReserveUpperBound = amm.sqrtK
449
+ .mul(pegSqrt)
450
+ .div(amm.pegMultiplier);
451
+ if (direction === types_1.PositionDirection.LONG) {
452
+ quoteAssetReserveLowerBound = this.amm.sqrtK
453
+ .muln(22361)
454
+ .mul(pegSqrt)
455
+ .divn(100000)
456
+ .div(amm.pegMultiplier);
457
+ }
458
+ else {
459
+ quoteAssetReserveUpperBound = amm.sqrtK
460
+ .muln(97467)
461
+ .mul(pegSqrt)
462
+ .divn(100000)
463
+ .div(amm.pegMultiplier);
464
+ }
465
+ return [quoteAssetReserveLowerBound, quoteAssetReserveUpperBound];
466
+ }
467
+ exports.getQuoteAssetReservePredictionMarketBounds = getQuoteAssetReservePredictionMarketBounds;
468
+ function calculateSpreadReserves(amm, oraclePriceData, now, isPrediction = false) {
446
469
  function calculateSpreadReserve(spread, direction, amm) {
447
470
  if (spread === 0) {
448
471
  return {
@@ -463,6 +486,10 @@ function calculateSpreadReserves(amm, oraclePriceData, now) {
463
486
  else {
464
487
  quoteAssetReserve = amm.quoteAssetReserve.sub(quoteAssetReserveDelta.abs());
465
488
  }
489
+ if (isPrediction) {
490
+ const [qarLower, qarUpper] = getQuoteAssetReservePredictionMarketBounds(amm, direction);
491
+ quoteAssetReserve = (0, __1.clampBN)(quoteAssetReserve, qarLower, qarUpper);
492
+ }
466
493
  const baseAssetReserve = amm.sqrtK.mul(amm.sqrtK).div(quoteAssetReserve);
467
494
  return {
468
495
  baseAssetReserve,
@@ -542,7 +569,7 @@ function calculateTerminalPrice(market) {
542
569
  return terminalPrice;
543
570
  }
544
571
  exports.calculateTerminalPrice = calculateTerminalPrice;
545
- function calculateMaxBaseAssetAmountToTrade(amm, limit_price, direction, oraclePriceData, now) {
572
+ function calculateMaxBaseAssetAmountToTrade(amm, limit_price, direction, oraclePriceData, now, isPrediction = false) {
546
573
  const invariant = amm.sqrtK.mul(amm.sqrtK);
547
574
  const newBaseAssetReserveSquared = invariant
548
575
  .mul(numericConstants_1.PRICE_PRECISION)
@@ -550,7 +577,7 @@ function calculateMaxBaseAssetAmountToTrade(amm, limit_price, direction, oracleP
550
577
  .div(limit_price)
551
578
  .div(numericConstants_1.PEG_PRECISION);
552
579
  const newBaseAssetReserve = (0, __1.squareRootBN)(newBaseAssetReserveSquared);
553
- const [shortSpreadReserves, longSpreadReserves] = calculateSpreadReserves(amm, oraclePriceData, now);
580
+ const [shortSpreadReserves, longSpreadReserves] = calculateSpreadReserves(amm, oraclePriceData, now, isPrediction);
554
581
  const baseAssetReserveBefore = (0, types_1.isVariant)(direction, 'long')
555
582
  ? longSpreadReserves.baseAssetReserve
556
583
  : shortSpreadReserves.baseAssetReserve;
@@ -7,5 +7,18 @@ imfFactor: BN, liabilityWeight: BN, precision: BN): BN;
7
7
  export declare function calculateSizeDiscountAssetWeight(size: BN, // AMM_RESERVE_PRECISION
8
8
  imfFactor: BN, assetWeight: BN): BN;
9
9
  export declare function calculateOraclePriceForPerpMargin(perpPosition: PerpPosition, market: PerpMarketAccount, oraclePriceData: OraclePriceData): BN;
10
+ /**
11
+ * This is _not_ the same as liability value as for prediction markets, the liability for the short in prediction market is (1 - oracle price) * base
12
+ * See {@link calculatePerpLiabilityValue} to get the liabiltiy value
13
+ * @param market
14
+ * @param perpPosition
15
+ * @param oraclePriceData
16
+ * @param includeOpenOrders
17
+ */
10
18
  export declare function calculateBaseAssetValueWithOracle(market: PerpMarketAccount, perpPosition: PerpPosition, oraclePriceData: OraclePriceData, includeOpenOrders?: boolean): BN;
11
- export declare function calculateWorstCaseBaseAssetAmount(perpPosition: PerpPosition): BN;
19
+ export declare function calculateWorstCaseBaseAssetAmount(perpPosition: PerpPosition, perpMarket: PerpMarketAccount, oraclePrice: BN): BN;
20
+ export declare function calculateWorstCasePerpLiabilityValue(perpPosition: PerpPosition, perpMarket: PerpMarketAccount, oraclePrice: BN): {
21
+ worstCaseBaseAssetAmount: BN;
22
+ worstCaseLiabilityValue: BN;
23
+ };
24
+ export declare function calculatePerpLiabilityValue(baseAssetAmount: BN, oraclePrice: BN, isPredictionMarket: boolean): BN;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.calculateWorstCaseBaseAssetAmount = exports.calculateBaseAssetValueWithOracle = exports.calculateOraclePriceForPerpMargin = exports.calculateSizeDiscountAssetWeight = exports.calculateSizePremiumLiabilityWeight = void 0;
3
+ exports.calculatePerpLiabilityValue = exports.calculateWorstCasePerpLiabilityValue = exports.calculateWorstCaseBaseAssetAmount = exports.calculateBaseAssetValueWithOracle = exports.calculateOraclePriceForPerpMargin = exports.calculateSizeDiscountAssetWeight = exports.calculateSizePremiumLiabilityWeight = void 0;
4
4
  const utils_1 = require("./utils");
5
5
  const numericConstants_1 = require("../constants/numericConstants");
6
6
  const anchor_1 = require("@coral-xyz/anchor");
@@ -56,25 +56,63 @@ function calculateOraclePriceForPerpMargin(perpPosition, market, oraclePriceData
56
56
  return marginPrice;
57
57
  }
58
58
  exports.calculateOraclePriceForPerpMargin = calculateOraclePriceForPerpMargin;
59
+ /**
60
+ * This is _not_ the same as liability value as for prediction markets, the liability for the short in prediction market is (1 - oracle price) * base
61
+ * See {@link calculatePerpLiabilityValue} to get the liabiltiy value
62
+ * @param market
63
+ * @param perpPosition
64
+ * @param oraclePriceData
65
+ * @param includeOpenOrders
66
+ */
59
67
  function calculateBaseAssetValueWithOracle(market, perpPosition, oraclePriceData, includeOpenOrders = false) {
60
68
  let price = oraclePriceData.price;
61
69
  if ((0, types_1.isVariant)(market.status, 'settlement')) {
62
70
  price = market.expiryPrice;
63
71
  }
64
72
  const baseAssetAmount = includeOpenOrders
65
- ? calculateWorstCaseBaseAssetAmount(perpPosition)
73
+ ? calculateWorstCaseBaseAssetAmount(perpPosition, market, oraclePriceData.price)
66
74
  : perpPosition.baseAssetAmount;
67
75
  return baseAssetAmount.abs().mul(price).div(numericConstants_1.AMM_RESERVE_PRECISION);
68
76
  }
69
77
  exports.calculateBaseAssetValueWithOracle = calculateBaseAssetValueWithOracle;
70
- function calculateWorstCaseBaseAssetAmount(perpPosition) {
78
+ function calculateWorstCaseBaseAssetAmount(perpPosition, perpMarket, oraclePrice) {
79
+ return calculateWorstCasePerpLiabilityValue(perpPosition, perpMarket, oraclePrice).worstCaseBaseAssetAmount;
80
+ }
81
+ exports.calculateWorstCaseBaseAssetAmount = calculateWorstCaseBaseAssetAmount;
82
+ function calculateWorstCasePerpLiabilityValue(perpPosition, perpMarket, oraclePrice) {
71
83
  const allBids = perpPosition.baseAssetAmount.add(perpPosition.openBids);
72
84
  const allAsks = perpPosition.baseAssetAmount.add(perpPosition.openAsks);
73
- if (allBids.abs().gt(allAsks.abs())) {
74
- return allBids;
85
+ const isPredictionMarket = (0, types_1.isVariant)(perpMarket.contractType, 'prediction');
86
+ const allBidsLiabilityValue = calculatePerpLiabilityValue(allBids, oraclePrice, isPredictionMarket);
87
+ const allAsksLiabilityValue = calculatePerpLiabilityValue(allAsks, oraclePrice, isPredictionMarket);
88
+ if (allAsksLiabilityValue.gte(allBidsLiabilityValue)) {
89
+ return {
90
+ worstCaseBaseAssetAmount: allAsks,
91
+ worstCaseLiabilityValue: allAsksLiabilityValue,
92
+ };
75
93
  }
76
94
  else {
77
- return allAsks;
95
+ return {
96
+ worstCaseBaseAssetAmount: allBids,
97
+ worstCaseLiabilityValue: allBidsLiabilityValue,
98
+ };
78
99
  }
79
100
  }
80
- exports.calculateWorstCaseBaseAssetAmount = calculateWorstCaseBaseAssetAmount;
101
+ exports.calculateWorstCasePerpLiabilityValue = calculateWorstCasePerpLiabilityValue;
102
+ function calculatePerpLiabilityValue(baseAssetAmount, oraclePrice, isPredictionMarket) {
103
+ if (isPredictionMarket) {
104
+ if (baseAssetAmount.gt(numericConstants_1.ZERO)) {
105
+ return baseAssetAmount.mul(oraclePrice).div(numericConstants_1.BASE_PRECISION);
106
+ }
107
+ else {
108
+ return baseAssetAmount
109
+ .abs()
110
+ .mul(numericConstants_1.MAX_PREDICTION_PRICE.sub(oraclePrice))
111
+ .div(numericConstants_1.BASE_PRECISION);
112
+ }
113
+ }
114
+ else {
115
+ return baseAssetAmount.abs().mul(oraclePrice).div(numericConstants_1.BASE_PRECISION);
116
+ }
117
+ }
118
+ exports.calculatePerpLiabilityValue = calculatePerpLiabilityValue;
package/lib/types.d.ts CHANGED
@@ -78,6 +78,9 @@ export declare class ContractType {
78
78
  static readonly FUTURE: {
79
79
  future: {};
80
80
  };
81
+ static readonly PREDICTION: {
82
+ prediction: {};
83
+ };
81
84
  }
82
85
  export declare class ContractTier {
83
86
  static readonly A: {
package/lib/types.js CHANGED
@@ -63,6 +63,7 @@ class ContractType {
63
63
  exports.ContractType = ContractType;
64
64
  ContractType.PERPETUAL = { perpetual: {} };
65
65
  ContractType.FUTURE = { future: {} };
66
+ ContractType.PREDICTION = { prediction: {} };
66
67
  class ContractTier {
67
68
  }
68
69
  exports.ContractTier = ContractTier;
package/lib/user.d.ts CHANGED
@@ -164,7 +164,7 @@ export declare class User {
164
164
  * @returns : number (value from [0, 100])
165
165
  */
166
166
  getHealth(): number;
167
- calculateWeightedPerpPositionValue(perpPosition: PerpPosition, marginCategory?: MarginCategory, liquidationBuffer?: BN, includeOpenOrders?: boolean, strict?: boolean): BN;
167
+ calculateWeightedPerpPositionLiability(perpPosition: PerpPosition, marginCategory?: MarginCategory, liquidationBuffer?: BN, includeOpenOrders?: boolean, strict?: boolean): BN;
168
168
  /**
169
169
  * calculates position value of a single perp market in margin system
170
170
  * @returns : Precision QUOTE_PRECISION
@@ -174,12 +174,17 @@ export declare class User {
174
174
  * calculates sum of position value across all positions in margin system
175
175
  * @returns : Precision QUOTE_PRECISION
176
176
  */
177
- getTotalPerpPositionValue(marginCategory?: MarginCategory, liquidationBuffer?: BN, includeOpenOrders?: boolean, strict?: boolean): BN;
177
+ getTotalPerpPositionLiability(marginCategory?: MarginCategory, liquidationBuffer?: BN, includeOpenOrders?: boolean, strict?: boolean): BN;
178
178
  /**
179
- * calculates position value in margin system
179
+ * calculates position value based on oracle
180
180
  * @returns : Precision QUOTE_PRECISION
181
181
  */
182
182
  getPerpPositionValue(marketIndex: number, oraclePriceData: OraclePriceData, includeOpenOrders?: boolean): BN;
183
+ /**
184
+ * calculates position liabiltiy value in margin system
185
+ * @returns : Precision QUOTE_PRECISION
186
+ */
187
+ getPerpLiabilityValue(marketIndex: number, oraclePriceData: OraclePriceData, includeOpenOrders?: boolean): BN;
183
188
  getPositionSide(currentPosition: Pick<PerpPosition, 'baseAssetAmount'>): PositionDirection | undefined;
184
189
  /**
185
190
  * calculates average exit price (optionally for closing up to 100% of position)
@@ -264,7 +269,7 @@ export declare class User {
264
269
  */
265
270
  liquidationPrice(marketIndex: number, positionBaseSizeChange?: BN, estimatedEntryPrice?: BN, marginCategory?: MarginCategory, includeOpenOrders?: boolean): BN;
266
271
  calculateEntriesEffectOnFreeCollateral(market: PerpMarketAccount, oraclePrice: BN, perpPosition: PerpPosition, positionBaseSizeChange: BN, estimatedEntryPrice: BN, includeOpenOrders: boolean): BN;
267
- calculateFreeCollateralDeltaForPerp(market: PerpMarketAccount, perpPosition: PerpPosition, positionBaseSizeChange: BN, marginCategory?: MarginCategory, includeOpenOrders?: boolean): BN | undefined;
272
+ calculateFreeCollateralDeltaForPerp(market: PerpMarketAccount, perpPosition: PerpPosition, positionBaseSizeChange: BN, oraclePrice: BN, marginCategory?: MarginCategory, includeOpenOrders?: boolean): BN | undefined;
268
273
  calculateFreeCollateralDeltaForSpot(market: SpotMarketAccount, signedTokenAmount: BN, marginCategory?: MarginCategory): BN;
269
274
  /**
270
275
  * Calculates the estimated liquidation price for a position after closing a quote amount of the position.
@@ -292,9 +297,13 @@ export declare class User {
292
297
  *
293
298
  * @param targetMarketIndex
294
299
  * @param tradeSide
295
- * @returns tradeSizeAllowed : Precision QUOTE_PRECISION
300
+ * @param isLp
301
+ * @returns { tradeSize: BN, oppositeSideTradeSize: BN} : Precision QUOTE_PRECISION
296
302
  */
297
- getMaxTradeSizeUSDCForPerp(targetMarketIndex: number, tradeSide: PositionDirection, isLp?: boolean): BN;
303
+ getMaxTradeSizeUSDCForPerp(targetMarketIndex: number, tradeSide: PositionDirection, isLp?: boolean): {
304
+ tradeSize: BN;
305
+ oppositeSideTradeSize: BN;
306
+ };
298
307
  /**
299
308
  * Get the maximum trade size for a given market, taking into account the user's current leverage, positions, collateral, etc.
300
309
  *