@drift-labs/sdk 2.31.1-beta.9 → 2.32.0

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 (42) hide show
  1. package/VERSION +1 -1
  2. package/lib/constants/perpMarkets.js +20 -0
  3. package/lib/dlob/orderBookLevels.js +2 -2
  4. package/lib/driftClient.d.ts +51 -4
  5. package/lib/driftClient.js +195 -194
  6. package/lib/idl/drift.json +31 -1
  7. package/lib/index.d.ts +3 -0
  8. package/lib/index.js +3 -0
  9. package/lib/marinade/index.d.ts +11 -0
  10. package/lib/marinade/index.js +36 -0
  11. package/lib/marinade/types.d.ts +1963 -0
  12. package/lib/marinade/types.js +1965 -0
  13. package/lib/math/spotBalance.d.ts +9 -2
  14. package/lib/math/spotBalance.js +54 -6
  15. package/lib/math/superStake.d.ts +22 -0
  16. package/lib/math/superStake.js +108 -0
  17. package/lib/math/utils.d.ts +1 -0
  18. package/lib/math/utils.js +5 -1
  19. package/lib/orderParams.d.ts +18 -5
  20. package/lib/orderParams.js +17 -1
  21. package/lib/user.d.ts +45 -1
  22. package/lib/user.js +227 -9
  23. package/package.json +1 -1
  24. package/src/assert/assert.js +9 -0
  25. package/src/constants/perpMarkets.ts +20 -0
  26. package/src/dlob/orderBookLevels.ts +3 -2
  27. package/src/driftClient.ts +373 -223
  28. package/src/idl/drift.json +31 -1
  29. package/src/index.ts +3 -0
  30. package/src/marinade/idl/idl.json +1962 -0
  31. package/src/marinade/index.ts +64 -0
  32. package/src/marinade/types.ts +3925 -0
  33. package/src/math/spotBalance.ts +83 -5
  34. package/src/math/superStake.ts +148 -0
  35. package/src/math/utils.ts +4 -0
  36. package/src/orderParams.ts +35 -5
  37. package/src/token/index.js +38 -0
  38. package/src/user.ts +453 -15
  39. package/src/util/computeUnits.js +27 -0
  40. package/src/util/promiseTimeout.js +14 -0
  41. package/src/util/tps.js +27 -0
  42. package/tests/spot/test.ts +156 -0
package/lib/user.js CHANGED
@@ -80,6 +80,17 @@ class User {
80
80
  getSpotPosition(marketIndex) {
81
81
  return this.getUserAccount().spotPositions.find((position) => position.marketIndex === marketIndex);
82
82
  }
83
+ getEmptySpotPosition(marketIndex) {
84
+ return {
85
+ marketIndex,
86
+ scaledBalance: numericConstants_1.ZERO,
87
+ balanceType: _1.SpotBalanceType.DEPOSIT,
88
+ cumulativeDeposits: numericConstants_1.ZERO,
89
+ openAsks: numericConstants_1.ZERO,
90
+ openBids: numericConstants_1.ZERO,
91
+ openOrders: 0,
92
+ };
93
+ }
83
94
  /**
84
95
  * Returns the token amount for a given market. The spot market precision is based on the token mint decimals.
85
96
  * Positive if it is a deposit, negative if it is a borrow.
@@ -282,7 +293,7 @@ class User {
282
293
  * @returns : Precision QUOTE_PRECISION
283
294
  */
284
295
  getFreeCollateral() {
285
- const totalCollateral = this.getTotalCollateral();
296
+ const totalCollateral = this.getTotalCollateral('Initial', true);
286
297
  const initialMarginRequirement = this.getInitialMarginRequirement();
287
298
  const freeCollateral = totalCollateral.sub(initialMarginRequirement);
288
299
  return freeCollateral.gte(numericConstants_1.ZERO) ? freeCollateral : numericConstants_1.ZERO;
@@ -491,10 +502,6 @@ class User {
491
502
  }
492
503
  return assetValue;
493
504
  }
494
- getSpotTokenAmount(marketIndex) {
495
- const spotPosition = this.getSpotPosition(marketIndex);
496
- return (0, spotBalance_1.getTokenAmount)(spotPosition.scaledBalance, this.driftClient.getSpotMarketAccount(marketIndex), spotPosition.balanceType);
497
- }
498
505
  getSpotPositionValue(marketIndex, marginCategory, includeOpenOrders, strict = false, now) {
499
506
  const { totalAssetValue, totalLiabilityValue } = this.getSpotMarketAssetAndLiabilityValue(marketIndex, marginCategory, undefined, includeOpenOrders, strict, now);
500
507
  return totalAssetValue.sub(totalLiabilityValue);
@@ -671,8 +678,9 @@ class User {
671
678
  * @returns : Precision TEN_THOUSAND
672
679
  */
673
680
  getLeverage() {
674
- // get leverage components
675
- const { perpLiabilityValue, perpPnl, spotAssetValue, spotLiabilityValue } = this.getLeverageComponents();
681
+ return this.calculateLeverageFromComponents(this.getLeverageComponents());
682
+ }
683
+ calculateLeverageFromComponents({ perpLiabilityValue, perpPnl, spotAssetValue, spotLiabilityValue, }) {
676
684
  const totalLiabilityValue = perpLiabilityValue.add(spotLiabilityValue);
677
685
  const totalAssetValue = spotAssetValue.add(perpPnl);
678
686
  const netAssetValue = totalAssetValue.sub(spotLiabilityValue);
@@ -1070,13 +1078,13 @@ class User {
1070
1078
  // if the user is buying/selling and already short/long, need to account for closing out short/long
1071
1079
  if ((0, types_1.isVariant)(direction, 'long') && currentSpotMarketNetValue.lt(numericConstants_1.ZERO)) {
1072
1080
  tradeAmount = currentSpotMarketNetValue.abs();
1073
- const marginRatio = (0, _1.calculateSpotMarketMarginRatio)(market, 'Initial', this.getSpotTokenAmount(targetMarketIndex), _1.SpotBalanceType.BORROW);
1081
+ const marginRatio = (0, _1.calculateSpotMarketMarginRatio)(market, 'Initial', this.getTokenAmount(targetMarketIndex).abs(), _1.SpotBalanceType.BORROW);
1074
1082
  freeCollateral = freeCollateral.add(tradeAmount.mul(new _1.BN(marginRatio)).div(numericConstants_1.MARGIN_PRECISION));
1075
1083
  }
1076
1084
  else if ((0, types_1.isVariant)(direction, 'short') &&
1077
1085
  currentSpotMarketNetValue.gt(numericConstants_1.ZERO)) {
1078
1086
  tradeAmount = currentSpotMarketNetValue;
1079
- const marginRatio = (0, _1.calculateSpotMarketMarginRatio)(market, 'Initial', this.getSpotTokenAmount(targetMarketIndex), _1.SpotBalanceType.DEPOSIT);
1087
+ const marginRatio = (0, _1.calculateSpotMarketMarginRatio)(market, 'Initial', this.getTokenAmount(targetMarketIndex), _1.SpotBalanceType.DEPOSIT);
1080
1088
  freeCollateral = freeCollateral.add(tradeAmount.mul(new _1.BN(marginRatio)).div(numericConstants_1.MARGIN_PRECISION));
1081
1089
  }
1082
1090
  tradeAmount = tradeAmount.add(freeCollateral.mul(numericConstants_1.MARGIN_PRECISION).div(new _1.BN(marginRatio)));
@@ -1089,6 +1097,216 @@ class User {
1089
1097
  }
1090
1098
  return tradeAmount;
1091
1099
  }
1100
+ /**
1101
+ * Calculates the max amount of token that can be swapped from inMarket to outMarket
1102
+ * Assumes swap happens at oracle price
1103
+ *
1104
+ * @param inMarketIndex
1105
+ * @param outMarketIndex
1106
+ * @param calculateSwap function to similate in to out swa
1107
+ * @param iterationLimit how long to run appromixation before erroring out
1108
+ */
1109
+ getMaxSwapAmount({ inMarketIndex, outMarketIndex, calculateSwap, iterationLimit = 1000, }) {
1110
+ const inMarket = this.driftClient.getSpotMarketAccount(inMarketIndex);
1111
+ const outMarket = this.driftClient.getSpotMarketAccount(outMarketIndex);
1112
+ const inOraclePrice = this.getOracleDataForSpotMarket(inMarketIndex).price;
1113
+ const outOraclePrice = this.getOracleDataForSpotMarket(outMarketIndex).price;
1114
+ const inPrecision = new _1.BN(10 ** inMarket.decimals);
1115
+ const outPrecision = new _1.BN(10 ** outMarket.decimals);
1116
+ const outSaferThanIn = inMarket.initialAssetWeight < outMarket.initialAssetWeight;
1117
+ const inSpotPosition = this.getSpotPosition(inMarketIndex) ||
1118
+ this.getEmptySpotPosition(inMarketIndex);
1119
+ const outSpotPosition = this.getSpotPosition(outMarketIndex) ||
1120
+ this.getEmptySpotPosition(outMarketIndex);
1121
+ const freeCollateral = this.getFreeCollateral();
1122
+ const inContributionInitial = this.calculateSpotPositionFreeCollateralContribution(inSpotPosition);
1123
+ const { totalAssetValue: inTotalAssetValueInitial, totalLiabilityValue: inTotalLiabilityValueInitial, } = this.calculateSpotPositionLeverageContribution(inSpotPosition);
1124
+ const outContributionInitial = this.calculateSpotPositionFreeCollateralContribution(outSpotPosition);
1125
+ const { totalAssetValue: outTotalAssetValueInitial, totalLiabilityValue: outTotalLiabilityValueInitial, } = this.calculateSpotPositionLeverageContribution(outSpotPosition);
1126
+ const initialContribution = inContributionInitial.add(outContributionInitial);
1127
+ const { perpLiabilityValue, perpPnl, spotAssetValue, spotLiabilityValue } = this.getLeverageComponents();
1128
+ if (!calculateSwap) {
1129
+ calculateSwap = (inSwap) => {
1130
+ return inSwap
1131
+ .mul(outPrecision)
1132
+ .mul(inOraclePrice)
1133
+ .div(outOraclePrice)
1134
+ .div(inPrecision);
1135
+ };
1136
+ }
1137
+ let inSwap = numericConstants_1.ZERO;
1138
+ let outSwap = numericConstants_1.ZERO;
1139
+ const inTokenAmount = this.getTokenAmount(inMarketIndex);
1140
+ if (freeCollateral.lt(numericConstants_1.ONE)) {
1141
+ if (outSaferThanIn && inTokenAmount.gt(numericConstants_1.ZERO)) {
1142
+ inSwap = inTokenAmount;
1143
+ outSwap = calculateSwap(inSwap);
1144
+ }
1145
+ }
1146
+ else {
1147
+ let minSwap = numericConstants_1.ZERO;
1148
+ let maxSwap = freeCollateral
1149
+ .mul(inPrecision)
1150
+ .mul(numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION)
1151
+ .div(numericConstants_1.SPOT_MARKET_WEIGHT_PRECISION.div(new _1.BN(100)))
1152
+ .div(inOraclePrice); // just assume user can go 100x
1153
+ inSwap = maxSwap.div(numericConstants_1.TWO);
1154
+ const error = _1.BN.min(numericConstants_1.QUOTE_PRECISION, freeCollateral.div(new _1.BN(100)));
1155
+ let i = 0;
1156
+ let freeCollateralAfter = freeCollateral;
1157
+ while (freeCollateralAfter.gt(error) || freeCollateralAfter.isNeg()) {
1158
+ outSwap = calculateSwap(inSwap);
1159
+ const inPositionAfter = this.cloneAndUpdateSpotPosition(inSpotPosition, inSwap.neg(), inMarket);
1160
+ const outPositionAfter = this.cloneAndUpdateSpotPosition(outSpotPosition, outSwap, outMarket);
1161
+ const inContributionAfter = this.calculateSpotPositionFreeCollateralContribution(inPositionAfter);
1162
+ const outContributionAfter = this.calculateSpotPositionFreeCollateralContribution(outPositionAfter);
1163
+ const contributionAfter = inContributionAfter.add(outContributionAfter);
1164
+ const contributionDelta = contributionAfter.sub(initialContribution);
1165
+ freeCollateralAfter = freeCollateral.add(contributionDelta);
1166
+ if (freeCollateralAfter.gt(error)) {
1167
+ minSwap = inSwap;
1168
+ inSwap = minSwap.add(maxSwap).div(numericConstants_1.TWO);
1169
+ }
1170
+ else if (freeCollateralAfter.isNeg()) {
1171
+ maxSwap = inSwap;
1172
+ inSwap = minSwap.add(maxSwap).div(numericConstants_1.TWO);
1173
+ }
1174
+ if (i++ > iterationLimit) {
1175
+ throw new Error('getMaxSwapAmount iteration limit reached');
1176
+ }
1177
+ }
1178
+ }
1179
+ const inPositionAfter = this.cloneAndUpdateSpotPosition(inSpotPosition, inSwap.neg(), inMarket);
1180
+ const outPositionAfter = this.cloneAndUpdateSpotPosition(outSpotPosition, outSwap, outMarket);
1181
+ const { totalAssetValue: inTotalAssetValueAfter, totalLiabilityValue: inTotalLiabilityValueAfter, } = this.calculateSpotPositionLeverageContribution(inPositionAfter);
1182
+ const { totalAssetValue: outTotalAssetValueAfter, totalLiabilityValue: outTotalLiabilityValueAfter, } = this.calculateSpotPositionLeverageContribution(outPositionAfter);
1183
+ const spotAssetValueDelta = inTotalAssetValueAfter
1184
+ .add(outTotalAssetValueAfter)
1185
+ .sub(inTotalAssetValueInitial)
1186
+ .sub(outTotalAssetValueInitial);
1187
+ const spotLiabilityValueDelta = inTotalLiabilityValueAfter
1188
+ .add(outTotalLiabilityValueAfter)
1189
+ .sub(inTotalLiabilityValueInitial)
1190
+ .sub(outTotalLiabilityValueInitial);
1191
+ const spotAssetValueAfter = spotAssetValue.add(spotAssetValueDelta);
1192
+ const spotLiabilityValueAfter = spotLiabilityValue.add(spotLiabilityValueDelta);
1193
+ const leverage = this.calculateLeverageFromComponents({
1194
+ perpLiabilityValue,
1195
+ perpPnl,
1196
+ spotAssetValue: spotAssetValueAfter,
1197
+ spotLiabilityValue: spotLiabilityValueAfter,
1198
+ });
1199
+ return { inAmount: inSwap, outAmount: outSwap, leverage };
1200
+ }
1201
+ cloneAndUpdateSpotPosition(position, tokenAmount, market) {
1202
+ const clonedPosition = Object.assign({}, position);
1203
+ if (tokenAmount.eq(numericConstants_1.ZERO)) {
1204
+ return clonedPosition;
1205
+ }
1206
+ const preTokenAmount = (0, _1.getSignedTokenAmount)((0, spotBalance_1.getTokenAmount)(position.scaledBalance, market, position.balanceType), position.balanceType);
1207
+ if ((0, _1.sigNum)(preTokenAmount).eq((0, _1.sigNum)(tokenAmount))) {
1208
+ const scaledBalanceDelta = (0, _1.getBalance)(tokenAmount.abs(), market, position.balanceType);
1209
+ clonedPosition.scaledBalance =
1210
+ clonedPosition.scaledBalance.add(scaledBalanceDelta);
1211
+ return clonedPosition;
1212
+ }
1213
+ const updateDirection = tokenAmount.isNeg()
1214
+ ? _1.SpotBalanceType.BORROW
1215
+ : _1.SpotBalanceType.DEPOSIT;
1216
+ if (tokenAmount.abs().gte(preTokenAmount.abs())) {
1217
+ clonedPosition.scaledBalance = (0, _1.getBalance)(tokenAmount.abs().sub(preTokenAmount.abs()), market, updateDirection);
1218
+ clonedPosition.balanceType = updateDirection;
1219
+ }
1220
+ else {
1221
+ const scaledBalanceDelta = (0, _1.getBalance)(tokenAmount.abs(), market, position.balanceType);
1222
+ clonedPosition.scaledBalance =
1223
+ clonedPosition.scaledBalance.sub(scaledBalanceDelta);
1224
+ }
1225
+ return clonedPosition;
1226
+ }
1227
+ calculateSpotPositionFreeCollateralContribution(spotPosition) {
1228
+ let freeCollateralContribution = numericConstants_1.ZERO;
1229
+ const now = new _1.BN(new Date().getTime() / 1000);
1230
+ const strict = true;
1231
+ const marginCategory = 'Initial';
1232
+ const spotMarketAccount = this.driftClient.getSpotMarketAccount(spotPosition.marketIndex);
1233
+ const oraclePriceData = this.getOracleDataForSpotMarket(spotPosition.marketIndex);
1234
+ const [worstCaseTokenAmount, worstCaseQuoteTokenAmount] = (0, spotPosition_1.getWorstCaseTokenAmounts)(spotPosition, spotMarketAccount, oraclePriceData);
1235
+ if (worstCaseTokenAmount.gt(numericConstants_1.ZERO)) {
1236
+ const baseAssetValue = this.getSpotAssetValue(worstCaseTokenAmount, oraclePriceData, spotMarketAccount, marginCategory, strict, now);
1237
+ freeCollateralContribution =
1238
+ freeCollateralContribution.add(baseAssetValue);
1239
+ }
1240
+ else {
1241
+ const baseLiabilityValue = this.getSpotLiabilityValue(worstCaseTokenAmount, oraclePriceData, spotMarketAccount, marginCategory, undefined, strict, now).abs();
1242
+ freeCollateralContribution =
1243
+ freeCollateralContribution.sub(baseLiabilityValue);
1244
+ }
1245
+ freeCollateralContribution.add(worstCaseQuoteTokenAmount);
1246
+ return freeCollateralContribution;
1247
+ }
1248
+ calculateSpotPositionLeverageContribution(spotPosition) {
1249
+ let totalAssetValue = numericConstants_1.ZERO;
1250
+ let totalLiabilityValue = numericConstants_1.ZERO;
1251
+ const now = new _1.BN(new Date().getTime() / 1000);
1252
+ const spotMarketAccount = this.driftClient.getSpotMarketAccount(spotPosition.marketIndex);
1253
+ const oraclePriceData = this.getOracleDataForSpotMarket(spotPosition.marketIndex);
1254
+ const [worstCaseTokenAmount, worstCaseQuoteTokenAmount] = (0, spotPosition_1.getWorstCaseTokenAmounts)(spotPosition, spotMarketAccount, oraclePriceData);
1255
+ if (worstCaseTokenAmount.gt(numericConstants_1.ZERO)) {
1256
+ totalAssetValue = this.getSpotAssetValue(worstCaseTokenAmount, oraclePriceData, spotMarketAccount, undefined, false, now);
1257
+ }
1258
+ else {
1259
+ totalLiabilityValue = this.getSpotLiabilityValue(worstCaseTokenAmount, oraclePriceData, spotMarketAccount, undefined, undefined, false, now).abs();
1260
+ }
1261
+ if (worstCaseQuoteTokenAmount.gt(numericConstants_1.ZERO)) {
1262
+ totalAssetValue = totalAssetValue.add(worstCaseQuoteTokenAmount);
1263
+ }
1264
+ else {
1265
+ totalLiabilityValue = totalLiabilityValue.add(worstCaseQuoteTokenAmount.abs());
1266
+ }
1267
+ return {
1268
+ totalAssetValue,
1269
+ totalLiabilityValue,
1270
+ };
1271
+ }
1272
+ /**
1273
+ * Estimates what the user leverage will be after swap
1274
+ * @param inMarketIndex
1275
+ * @param outMarketIndex
1276
+ * @param inAmount
1277
+ * @param outAmount
1278
+ */
1279
+ accountLeverageAfterSwap({ inMarketIndex, outMarketIndex, inAmount, outAmount, }) {
1280
+ const inMarket = this.driftClient.getSpotMarketAccount(inMarketIndex);
1281
+ const outMarket = this.driftClient.getSpotMarketAccount(outMarketIndex);
1282
+ const inSpotPosition = this.getSpotPosition(inMarketIndex) ||
1283
+ this.getEmptySpotPosition(inMarketIndex);
1284
+ const outSpotPosition = this.getSpotPosition(outMarketIndex) ||
1285
+ this.getEmptySpotPosition(outMarketIndex);
1286
+ const { totalAssetValue: inTotalAssetValueInitial, totalLiabilityValue: inTotalLiabilityValueInitial, } = this.calculateSpotPositionLeverageContribution(inSpotPosition);
1287
+ const { totalAssetValue: outTotalAssetValueInitial, totalLiabilityValue: outTotalLiabilityValueInitial, } = this.calculateSpotPositionLeverageContribution(outSpotPosition);
1288
+ const { perpLiabilityValue, perpPnl, spotAssetValue, spotLiabilityValue } = this.getLeverageComponents();
1289
+ const inPositionAfter = this.cloneAndUpdateSpotPosition(inSpotPosition, inAmount.abs().neg(), inMarket);
1290
+ const outPositionAfter = this.cloneAndUpdateSpotPosition(outSpotPosition, outAmount.abs(), outMarket);
1291
+ const { totalAssetValue: inTotalAssetValueAfter, totalLiabilityValue: inTotalLiabilityValueAfter, } = this.calculateSpotPositionLeverageContribution(inPositionAfter);
1292
+ const { totalAssetValue: outTotalAssetValueAfter, totalLiabilityValue: outTotalLiabilityValueAfter, } = this.calculateSpotPositionLeverageContribution(outPositionAfter);
1293
+ const spotAssetValueDelta = inTotalAssetValueAfter
1294
+ .add(outTotalAssetValueAfter)
1295
+ .sub(inTotalAssetValueInitial)
1296
+ .sub(outTotalAssetValueInitial);
1297
+ const spotLiabilityValueDelta = inTotalLiabilityValueAfter
1298
+ .add(outTotalLiabilityValueAfter)
1299
+ .sub(inTotalLiabilityValueInitial)
1300
+ .sub(outTotalLiabilityValueInitial);
1301
+ const spotAssetValueAfter = spotAssetValue.add(spotAssetValueDelta);
1302
+ const spotLiabilityValueAfter = spotLiabilityValue.add(spotLiabilityValueDelta);
1303
+ return this.calculateLeverageFromComponents({
1304
+ perpLiabilityValue,
1305
+ perpPnl,
1306
+ spotAssetValue: spotAssetValueAfter,
1307
+ spotLiabilityValue: spotLiabilityValueAfter,
1308
+ });
1309
+ }
1092
1310
  // TODO - should this take the price impact of the trade into account for strict accuracy?
1093
1311
  /**
1094
1312
  * Returns the leverage ratio for the account after adding (or subtracting) the given quote size to the given position
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drift-labs/sdk",
3
- "version": "2.31.1-beta.9",
3
+ "version": "2.32.0",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/index.d.ts",
6
6
  "author": "crispheaney",
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.assert = void 0;
4
+ function assert(condition, error) {
5
+ if (!condition) {
6
+ throw new Error(error || 'Unspecified AssertionError');
7
+ }
8
+ }
9
+ exports.assert = assert;
@@ -134,6 +134,16 @@ export const DevnetPerpMarkets: PerpMarketConfig[] = [
134
134
  launchTs: 1683125906000,
135
135
  oracleSource: OracleSource.PYTH,
136
136
  },
137
+ {
138
+ fullName: 'RNDR',
139
+ category: ['Infra'],
140
+ symbol: 'RNDR-PERP',
141
+ baseAssetSymbol: 'RNDR',
142
+ marketIndex: 12,
143
+ oracle: new PublicKey('C2QvUPBiU3fViSyqA4nZgGyYqLgYf9PRpd8B8oLoo48w'),
144
+ launchTs: 1683125906000,
145
+ oracleSource: OracleSource.PYTH,
146
+ },
137
147
  ];
138
148
 
139
149
  export const MainnetPerpMarkets: PerpMarketConfig[] = [
@@ -257,6 +267,16 @@ export const MainnetPerpMarkets: PerpMarketConfig[] = [
257
267
  launchTs: 1683125906000,
258
268
  oracleSource: OracleSource.PYTH,
259
269
  },
270
+ {
271
+ fullName: 'RNDR',
272
+ category: ['Infra'],
273
+ symbol: 'RNDR-PERP',
274
+ baseAssetSymbol: 'RNDR',
275
+ marketIndex: 12,
276
+ oracle: new PublicKey('CYGfrBJB9HgLf9iZyN4aH5HvUAi2htQ4MjPxeXMf4Egn'),
277
+ launchTs: 1683125906000,
278
+ oracleSource: OracleSource.PYTH,
279
+ },
260
280
  ];
261
281
 
262
282
  export const PerpMarkets: { [key in DriftEnv]: PerpMarketConfig[] } = {
@@ -12,6 +12,7 @@ import {
12
12
  PositionDirection,
13
13
  standardizePrice,
14
14
  SwapDirection,
15
+ ZERO,
15
16
  } from '..';
16
17
  import { PublicKey } from '@solana/web3.js';
17
18
 
@@ -169,7 +170,7 @@ export function getVammL2Generator({
169
170
  pegMultiplier: updatedAmm.pegMultiplier,
170
171
  };
171
172
  const getL2Bids = function* () {
172
- while (numBids < numOrders) {
173
+ while (numBids < numOrders && baseSize.gt(ZERO)) {
173
174
  const [afterSwapQuoteReserves, afterSwapBaseReserves] =
174
175
  calculateAmmReservesAfterSwap(
175
176
  bidAmm,
@@ -208,7 +209,7 @@ export function getVammL2Generator({
208
209
  pegMultiplier: updatedAmm.pegMultiplier,
209
210
  };
210
211
  const getL2Asks = function* () {
211
- while (numAsks < numOrders) {
212
+ while (numAsks < numOrders && askSize.gt(ZERO)) {
212
213
  const [afterSwapQuoteReserves, afterSwapBaseReserves] =
213
214
  calculateAmmReservesAfterSwap(
214
215
  askAmm,