@drift-labs/sdk 0.2.0-master.11 → 0.2.0-master.12
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/lib/clearingHouse.d.ts +7 -2
- package/lib/clearingHouse.js +157 -37
- package/lib/clearingHouseUser.d.ts +10 -15
- package/lib/clearingHouseUser.js +92 -74
- package/lib/config.js +1 -1
- package/lib/constants/banks.d.ts +2 -2
- package/lib/constants/banks.js +4 -3
- package/lib/constants/numericConstants.d.ts +2 -0
- package/lib/constants/numericConstants.js +3 -1
- package/lib/events/eventList.js +3 -0
- package/lib/events/types.d.ts +2 -1
- package/lib/factory/bigNum.d.ts +1 -0
- package/lib/factory/bigNum.js +37 -11
- package/lib/idl/clearing_house.json +97 -19
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/math/bankBalance.d.ts +3 -1
- package/lib/math/bankBalance.js +54 -1
- package/lib/math/margin.d.ts +11 -0
- package/lib/math/margin.js +72 -0
- package/lib/math/market.d.ts +4 -1
- package/lib/math/market.js +35 -1
- package/lib/math/position.d.ts +8 -0
- package/lib/math/position.js +42 -12
- package/lib/orders.d.ts +1 -2
- package/lib/orders.js +2 -77
- package/lib/tokenFaucet.d.ts +1 -0
- package/lib/tokenFaucet.js +23 -12
- package/lib/tx/retryTxSender.js +9 -2
- package/lib/types.d.ts +24 -3
- package/lib/types.js +6 -0
- package/lib/util/getTokenAddress.d.ts +2 -0
- package/lib/util/getTokenAddress.js +9 -0
- package/package.json +1 -1
- package/src/clearingHouse.ts +301 -47
- package/src/clearingHouseConfig.js +2 -0
- package/src/clearingHouseUser.ts +213 -104
- package/src/clearingHouseUserConfig.js +2 -0
- package/src/config.ts +1 -1
- package/src/constants/banks.js +42 -0
- package/src/constants/banks.ts +6 -3
- package/src/constants/markets.js +42 -0
- package/src/constants/numericConstants.js +41 -0
- package/src/constants/numericConstants.ts +3 -0
- package/src/events/eventList.ts +3 -0
- package/src/events/types.ts +2 -0
- package/src/factory/bigNum.js +37 -11
- package/src/factory/bigNum.ts +43 -13
- package/src/idl/clearing_house.json +97 -19
- package/src/index.js +67 -98
- package/src/index.ts +1 -0
- package/src/math/bankBalance.ts +98 -1
- package/src/math/margin.ts +124 -0
- package/src/math/market.ts +66 -1
- package/src/math/position.ts +59 -9
- package/src/orders.ts +4 -157
- package/src/tokenFaucet.js +189 -0
- package/src/tokenFaucet.ts +38 -15
- package/src/tx/retryTxSender.ts +11 -3
- package/src/types.js +12 -1
- package/src/types.ts +25 -3
- package/src/{accounts/fetch.js → util/computeUnits.js} +11 -13
- package/src/util/getTokenAddress.js +9 -0
- package/src/util/getTokenAddress.ts +18 -0
- package/tests/bn/test.ts +2 -0
- package/src/addresses/pda.js +0 -104
- package/src/math/bankBalance.js +0 -75
- package/src/math/market.js +0 -57
- package/src/math/orders.js +0 -110
- package/src/math/position.js +0 -140
- package/src/orders.js +0 -134
- package/src/tx/retryTxSender.js +0 -188
package/lib/clearingHouseUser.js
CHANGED
|
@@ -6,6 +6,7 @@ const position_1 = require("./math/position");
|
|
|
6
6
|
const numericConstants_1 = require("./constants/numericConstants");
|
|
7
7
|
const _1 = require(".");
|
|
8
8
|
const bankBalance_1 = require("./math/bankBalance");
|
|
9
|
+
const margin_1 = require("./math/margin");
|
|
9
10
|
const pollingUserAccountSubscriber_1 = require("./accounts/pollingUserAccountSubscriber");
|
|
10
11
|
const webSocketUserAccountSubscriber_1 = require("./accounts/webSocketUserAccountSubscriber");
|
|
11
12
|
class ClearingHouseUser {
|
|
@@ -68,7 +69,6 @@ class ClearingHouseUser {
|
|
|
68
69
|
quoteAssetAmount: numericConstants_1.ZERO,
|
|
69
70
|
quoteEntryAmount: numericConstants_1.ZERO,
|
|
70
71
|
openOrders: numericConstants_1.ZERO,
|
|
71
|
-
unsettledPnl: numericConstants_1.ZERO,
|
|
72
72
|
openBids: numericConstants_1.ZERO,
|
|
73
73
|
openAsks: numericConstants_1.ZERO,
|
|
74
74
|
};
|
|
@@ -114,49 +114,55 @@ class ClearingHouseUser {
|
|
|
114
114
|
return freeCollateral.gte(numericConstants_1.ZERO) ? freeCollateral : numericConstants_1.ZERO;
|
|
115
115
|
}
|
|
116
116
|
getInitialMarginRequirement() {
|
|
117
|
-
|
|
118
|
-
.positions.reduce((marginRequirement, marketPosition) => {
|
|
117
|
+
const postionMarginRequirement = this.getUserAccount().positions.reduce((marginRequirement, marketPosition) => {
|
|
119
118
|
const market = this.clearingHouse.getMarketAccount(marketPosition.marketIndex);
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
.
|
|
123
|
-
|
|
124
|
-
|
|
119
|
+
const worstCaseBaseAssetAmount = (0, margin_1.calculateWorstCaseBaseAssetAmount)(marketPosition);
|
|
120
|
+
const worstCaseAssetValue = worstCaseBaseAssetAmount
|
|
121
|
+
.abs()
|
|
122
|
+
.mul(this.getOracleDataForMarket(market.marketIndex).price)
|
|
123
|
+
.div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO.mul(numericConstants_1.MARK_PRICE_PRECISION));
|
|
124
|
+
const marketMarginRatio = new _1.BN((0, _1.calculateMarketMarginRatio)(market, worstCaseBaseAssetAmount.abs(), 'Initial'));
|
|
125
|
+
return marginRequirement.add(worstCaseAssetValue.mul(marketMarginRatio).div(numericConstants_1.MARGIN_PRECISION));
|
|
126
|
+
}, numericConstants_1.ZERO);
|
|
127
|
+
const bankMarginRequirement = this.getBankLiabilityValue(undefined, 'Initial');
|
|
128
|
+
return bankMarginRequirement.add(postionMarginRequirement);
|
|
125
129
|
}
|
|
126
130
|
/**
|
|
127
|
-
* @returns The
|
|
131
|
+
* @returns The maintenance margin requirement in USDC. : QUOTE_PRECISION
|
|
128
132
|
*/
|
|
129
133
|
getMaintenanceMarginRequirement() {
|
|
130
134
|
return this.getUserAccount()
|
|
131
135
|
.positions.reduce((marginRequirement, marketPosition) => {
|
|
132
136
|
const market = this.clearingHouse.getMarketAccount(marketPosition.marketIndex);
|
|
133
|
-
|
|
134
|
-
|
|
137
|
+
const worstCaseBaseAssetAmount = (0, margin_1.calculateWorstCaseBaseAssetAmount)(marketPosition);
|
|
138
|
+
const worstCaseAssetValue = worstCaseBaseAssetAmount
|
|
139
|
+
.abs()
|
|
140
|
+
.mul(this.getOracleDataForMarket(market.marketIndex).price)
|
|
141
|
+
.div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO.mul(numericConstants_1.MARK_PRICE_PRECISION));
|
|
142
|
+
return marginRequirement.add(worstCaseAssetValue
|
|
143
|
+
.mul(new _1.BN((0, _1.calculateMarketMarginRatio)(market, worstCaseBaseAssetAmount.abs(), 'Maintenance')))
|
|
135
144
|
.div(numericConstants_1.MARGIN_PRECISION));
|
|
136
145
|
}, numericConstants_1.ZERO)
|
|
137
|
-
.add(this.
|
|
146
|
+
.add(this.getBankLiabilityValue(undefined, 'Maintenance'));
|
|
138
147
|
}
|
|
139
148
|
/**
|
|
140
149
|
* calculates unrealized position price pnl
|
|
141
150
|
* @returns : Precision QUOTE_PRECISION
|
|
142
151
|
*/
|
|
143
|
-
getUnrealizedPNL(withFunding, marketIndex) {
|
|
152
|
+
getUnrealizedPNL(withFunding, marketIndex, withWeightMarginCategory) {
|
|
144
153
|
return this.getUserAccount()
|
|
145
154
|
.positions.filter((pos) => marketIndex ? pos.marketIndex === marketIndex : true)
|
|
146
155
|
.reduce((pnl, marketPosition) => {
|
|
147
156
|
const market = this.clearingHouse.getMarketAccount(marketPosition.marketIndex);
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
.positions.filter((pos) => marketIndex ? pos.marketIndex === marketIndex : true)
|
|
158
|
-
.reduce((pnl, marketPosition) => {
|
|
159
|
-
return pnl.add(marketPosition.unsettledPnl);
|
|
157
|
+
let pnl0 = (0, _1.calculatePositionPNL)(market, marketPosition, withFunding, this.getOracleDataForMarket(market.marketIndex));
|
|
158
|
+
if (withWeightMarginCategory !== undefined) {
|
|
159
|
+
if (pnl0.gt(numericConstants_1.ZERO)) {
|
|
160
|
+
pnl0 = pnl0
|
|
161
|
+
.mul((0, _1.calculateUnsettledAssetWeight)(market, pnl0, withWeightMarginCategory))
|
|
162
|
+
.div(new _1.BN(numericConstants_1.BANK_WEIGHT_PRECISION));
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return pnl.add(pnl0);
|
|
160
166
|
}, numericConstants_1.ZERO);
|
|
161
167
|
}
|
|
162
168
|
/**
|
|
@@ -171,45 +177,58 @@ class ClearingHouseUser {
|
|
|
171
177
|
return pnl.add((0, _1.calculatePositionFundingPNL)(market, marketPosition));
|
|
172
178
|
}, numericConstants_1.ZERO);
|
|
173
179
|
}
|
|
174
|
-
|
|
175
|
-
return this.getUserAccount().bankBalances.reduce((
|
|
180
|
+
getBankLiabilityValue(bankIndex, withWeightMarginCategory) {
|
|
181
|
+
return this.getUserAccount().bankBalances.reduce((totalLiabilityValue, bankBalance) => {
|
|
176
182
|
if (bankBalance.balance.eq(numericConstants_1.ZERO) ||
|
|
177
|
-
(0, types_1.isVariant)(bankBalance.balanceType, 'deposit')
|
|
178
|
-
|
|
183
|
+
(0, types_1.isVariant)(bankBalance.balanceType, 'deposit') ||
|
|
184
|
+
(bankIndex !== undefined && !bankBalance.bankIndex.eq(bankIndex))) {
|
|
185
|
+
return totalLiabilityValue;
|
|
179
186
|
}
|
|
180
187
|
// Todo this needs to account for whether it's based on initial or maintenance requirements
|
|
181
188
|
const bankAccount = this.clearingHouse.getBankAccount(bankBalance.bankIndex);
|
|
182
189
|
const tokenAmount = (0, bankBalance_1.getTokenAmount)(bankBalance.balance, bankAccount, bankBalance.balanceType);
|
|
183
|
-
|
|
190
|
+
let liabilityValue = tokenAmount
|
|
184
191
|
.mul(this.getOracleDataForBank(bankAccount.bankIndex).price)
|
|
185
|
-
.
|
|
186
|
-
.div(numericConstants_1.
|
|
187
|
-
|
|
192
|
+
.div(numericConstants_1.MARK_PRICE_PRECISION)
|
|
193
|
+
.div(new _1.BN(10).pow(new _1.BN(bankAccount.decimals).sub(numericConstants_1.BANK_BALANCE_PRECISION_EXP)));
|
|
194
|
+
if (withWeightMarginCategory !== undefined) {
|
|
195
|
+
const weight = (0, bankBalance_1.calculateLiabilityWeight)(tokenAmount, bankAccount, withWeightMarginCategory);
|
|
196
|
+
liabilityValue = liabilityValue
|
|
197
|
+
.mul(weight)
|
|
198
|
+
.div(numericConstants_1.BANK_WEIGHT_PRECISION);
|
|
199
|
+
}
|
|
200
|
+
return totalLiabilityValue.add(liabilityValue);
|
|
188
201
|
}, numericConstants_1.ZERO);
|
|
189
202
|
}
|
|
190
|
-
|
|
203
|
+
getBankAssetValue(bankIndex, withWeightMarginCategory) {
|
|
191
204
|
return this.getUserAccount().bankBalances.reduce((totalAssetValue, bankBalance) => {
|
|
192
205
|
if (bankBalance.balance.eq(numericConstants_1.ZERO) ||
|
|
206
|
+
(0, types_1.isVariant)(bankBalance.balanceType, 'borrow') ||
|
|
193
207
|
(bankIndex !== undefined && !bankBalance.bankIndex.eq(bankIndex))) {
|
|
194
208
|
return totalAssetValue;
|
|
195
209
|
}
|
|
196
210
|
// Todo this needs to account for whether it's based on initial or maintenance requirements
|
|
197
211
|
const bankAccount = this.clearingHouse.getBankAccount(bankBalance.bankIndex);
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
tokenAmount = tokenAmount.mul(new _1.BN(-1));
|
|
201
|
-
}
|
|
202
|
-
return totalAssetValue.add(tokenAmount
|
|
212
|
+
const tokenAmount = (0, bankBalance_1.getTokenAmount)(bankBalance.balance, bankAccount, bankBalance.balanceType);
|
|
213
|
+
let assetValue = tokenAmount
|
|
203
214
|
.mul(this.getOracleDataForBank(bankAccount.bankIndex).price)
|
|
204
|
-
.div(numericConstants_1.MARK_PRICE_PRECISION)
|
|
215
|
+
.div(numericConstants_1.MARK_PRICE_PRECISION)
|
|
216
|
+
.div(new _1.BN(10).pow(new _1.BN(bankAccount.decimals).sub(numericConstants_1.BANK_BALANCE_PRECISION_EXP)));
|
|
217
|
+
if (withWeightMarginCategory !== undefined) {
|
|
218
|
+
const weight = (0, bankBalance_1.calculateAssetWeight)(tokenAmount, bankAccount, withWeightMarginCategory);
|
|
219
|
+
assetValue = assetValue.mul(weight).div(numericConstants_1.BANK_WEIGHT_PRECISION);
|
|
220
|
+
}
|
|
221
|
+
return totalAssetValue.add(assetValue);
|
|
205
222
|
}, numericConstants_1.ZERO);
|
|
206
223
|
}
|
|
224
|
+
getNetBankValue(withWeightMarginCategory) {
|
|
225
|
+
return this.getBankAssetValue(undefined, withWeightMarginCategory).sub(this.getBankLiabilityValue(undefined, withWeightMarginCategory));
|
|
226
|
+
}
|
|
207
227
|
/**
|
|
208
228
|
* calculates TotalCollateral: collateral + unrealized pnl
|
|
209
|
-
* TODO: rename to total equity (for perpetuals swaps)
|
|
210
229
|
* @returns : Precision QUOTE_PRECISION
|
|
211
230
|
*/
|
|
212
|
-
getTotalCollateral() {
|
|
231
|
+
getTotalCollateral(marginCategory = 'Initial') {
|
|
213
232
|
return this.getUserAccount()
|
|
214
233
|
.bankBalances.reduce((totalAssetValue, bankBalance) => {
|
|
215
234
|
if (bankBalance.balance.eq(numericConstants_1.ZERO) ||
|
|
@@ -219,33 +238,36 @@ class ClearingHouseUser {
|
|
|
219
238
|
// Todo this needs to account for whether it's based on initial or maintenance requirements
|
|
220
239
|
const bankAccount = this.clearingHouse.getBankAccount(bankBalance.bankIndex);
|
|
221
240
|
const tokenAmount = (0, bankBalance_1.getTokenAmount)(bankBalance.balance, bankAccount, bankBalance.balanceType);
|
|
241
|
+
const weight = (0, bankBalance_1.calculateAssetWeight)(tokenAmount, bankAccount, marginCategory);
|
|
222
242
|
return totalAssetValue.add(tokenAmount
|
|
223
243
|
.mul(this.getOracleDataForBank(bankAccount.bankIndex).price)
|
|
224
|
-
.mul(
|
|
244
|
+
.mul(weight)
|
|
225
245
|
.div(numericConstants_1.BANK_WEIGHT_PRECISION)
|
|
226
|
-
.div(numericConstants_1.MARK_PRICE_PRECISION)
|
|
246
|
+
.div(numericConstants_1.MARK_PRICE_PRECISION)
|
|
247
|
+
// Adjust for decimals of bank account
|
|
248
|
+
.div(new _1.BN(10).pow(new _1.BN(bankAccount.decimals).sub(numericConstants_1.BANK_BALANCE_PRECISION_EXP))));
|
|
227
249
|
}, numericConstants_1.ZERO)
|
|
228
|
-
.add(this.getUnrealizedPNL(true))
|
|
229
|
-
.add(this.getUnsettledPNL());
|
|
250
|
+
.add(this.getUnrealizedPNL(true, undefined, marginCategory));
|
|
230
251
|
}
|
|
231
252
|
/**
|
|
232
|
-
* calculates sum of position value across all positions
|
|
253
|
+
* calculates sum of position value across all positions in margin system
|
|
233
254
|
* @returns : Precision QUOTE_PRECISION
|
|
234
255
|
*/
|
|
235
256
|
getTotalPositionValue() {
|
|
236
257
|
return this.getUserAccount().positions.reduce((positionValue, marketPosition) => {
|
|
237
258
|
const market = this.clearingHouse.getMarketAccount(marketPosition.marketIndex);
|
|
238
|
-
|
|
259
|
+
const posVal = (0, margin_1.calculateMarginBaseAssetValue)(market, marketPosition, this.getOracleDataForMarket(market.marketIndex));
|
|
260
|
+
return positionValue.add(posVal);
|
|
239
261
|
}, numericConstants_1.ZERO);
|
|
240
262
|
}
|
|
241
263
|
/**
|
|
242
|
-
* calculates position value
|
|
264
|
+
* calculates position value in margin system
|
|
243
265
|
* @returns : Precision QUOTE_PRECISION
|
|
244
266
|
*/
|
|
245
267
|
getPositionValue(marketIndex, oraclePriceData) {
|
|
246
268
|
const userPosition = this.getUserPosition(marketIndex) || this.getEmptyPosition(marketIndex);
|
|
247
269
|
const market = this.clearingHouse.getMarketAccount(userPosition.marketIndex);
|
|
248
|
-
return (0,
|
|
270
|
+
return (0, margin_1.calculateMarginBaseAssetValue)(market, userPosition, oraclePriceData);
|
|
249
271
|
}
|
|
250
272
|
getPositionSide(currentPosition) {
|
|
251
273
|
if (currentPosition.baseAssetAmount.gt(numericConstants_1.ZERO)) {
|
|
@@ -259,10 +281,10 @@ class ClearingHouseUser {
|
|
|
259
281
|
}
|
|
260
282
|
}
|
|
261
283
|
/**
|
|
262
|
-
* calculates average exit price for closing 100% of position
|
|
284
|
+
* calculates average exit price (optionally for closing up to 100% of position)
|
|
263
285
|
* @returns : Precision MARK_PRICE_PRECISION
|
|
264
286
|
*/
|
|
265
|
-
getPositionEstimatedExitPriceAndPnl(position, amountToClose) {
|
|
287
|
+
getPositionEstimatedExitPriceAndPnl(position, amountToClose, useAMMClose = false) {
|
|
266
288
|
const market = this.clearingHouse.getMarketAccount(position.marketIndex);
|
|
267
289
|
const entryPrice = (0, position_1.calculateEntryPrice)(position);
|
|
268
290
|
const oraclePriceData = this.getOracleDataForMarket(position.marketIndex);
|
|
@@ -277,7 +299,13 @@ class ClearingHouseUser {
|
|
|
277
299
|
quoteAssetAmount: position.quoteAssetAmount,
|
|
278
300
|
};
|
|
279
301
|
}
|
|
280
|
-
|
|
302
|
+
let baseAssetValue;
|
|
303
|
+
if (useAMMClose) {
|
|
304
|
+
baseAssetValue = (0, _1.calculateBaseAssetValue)(market, position, oraclePriceData);
|
|
305
|
+
}
|
|
306
|
+
else {
|
|
307
|
+
baseAssetValue = (0, margin_1.calculateMarginBaseAssetValue)(market, position, oraclePriceData);
|
|
308
|
+
}
|
|
281
309
|
if (position.baseAssetAmount.eq(numericConstants_1.ZERO)) {
|
|
282
310
|
return [numericConstants_1.ZERO, numericConstants_1.ZERO];
|
|
283
311
|
}
|
|
@@ -311,18 +339,10 @@ class ClearingHouseUser {
|
|
|
311
339
|
*/
|
|
312
340
|
getMaxLeverage(marketIndex, category = 'Initial') {
|
|
313
341
|
const market = this.clearingHouse.getMarketAccount(marketIndex);
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
break;
|
|
319
|
-
case 'Maintenance':
|
|
320
|
-
marginRatioCategory = market.marginRatioMaintenance;
|
|
321
|
-
break;
|
|
322
|
-
default:
|
|
323
|
-
marginRatioCategory = market.marginRatioInitial;
|
|
324
|
-
break;
|
|
325
|
-
}
|
|
342
|
+
const marginRatioCategory = (0, _1.calculateMarketMarginRatio)(market,
|
|
343
|
+
// worstCaseBaseAssetAmount.abs(),
|
|
344
|
+
numericConstants_1.ZERO, // todo
|
|
345
|
+
category);
|
|
326
346
|
const maxLeverage = numericConstants_1.TEN_THOUSAND.mul(numericConstants_1.TEN_THOUSAND).div(new _1.BN(marginRatioCategory));
|
|
327
347
|
return maxLeverage;
|
|
328
348
|
}
|
|
@@ -395,23 +415,21 @@ class ClearingHouseUser {
|
|
|
395
415
|
quoteAssetAmount: new _1.BN(0),
|
|
396
416
|
quoteEntryAmount: new _1.BN(0),
|
|
397
417
|
openOrders: new _1.BN(0),
|
|
398
|
-
unsettledPnl: new _1.BN(0),
|
|
399
418
|
openBids: new _1.BN(0),
|
|
400
419
|
openAsks: new _1.BN(0),
|
|
401
420
|
};
|
|
402
421
|
if (proposedBaseAssetAmount.eq(numericConstants_1.ZERO))
|
|
403
422
|
return new _1.BN(-1);
|
|
404
423
|
const market = this.clearingHouse.getMarketAccount(proposedMarketPosition.marketIndex);
|
|
405
|
-
const proposedMarketPositionValue = (0,
|
|
424
|
+
const proposedMarketPositionValue = (0, margin_1.calculateMarginBaseAssetValue)(market, proposedMarketPosition, this.getOracleDataForMarket(market.marketIndex));
|
|
406
425
|
// total position value after trade
|
|
407
426
|
const totalPositionValueAfterTrade = totalPositionValueExcludingTargetMarket.add(proposedMarketPositionValue);
|
|
408
427
|
const marginRequirementExcludingTargetMarket = this.getUserAccount().positions.reduce((totalMarginRequirement, position) => {
|
|
409
428
|
if (!position.marketIndex.eq(marketPosition.marketIndex)) {
|
|
410
429
|
const market = this.clearingHouse.getMarketAccount(position.marketIndex);
|
|
411
|
-
const positionValue = (0,
|
|
412
|
-
const marketMarginRequirement = positionValue
|
|
413
|
-
|
|
414
|
-
.div(numericConstants_1.MARGIN_PRECISION);
|
|
430
|
+
const positionValue = (0, margin_1.calculateMarginBaseAssetValue)(market, position, this.getOracleDataForMarket(market.marketIndex));
|
|
431
|
+
const marketMarginRequirement = positionValue;
|
|
432
|
+
new _1.BN((0, _1.calculateMarketMarginRatio)(market, position.baseAssetAmount.abs(), 'Maintenance')).div(numericConstants_1.MARGIN_PRECISION);
|
|
415
433
|
totalMarginRequirement = totalMarginRequirement.add(marketMarginRequirement);
|
|
416
434
|
}
|
|
417
435
|
return totalMarginRequirement;
|
|
@@ -423,7 +441,7 @@ class ClearingHouseUser {
|
|
|
423
441
|
return new _1.BN(-1);
|
|
424
442
|
}
|
|
425
443
|
const marginRequirementAfterTrade = marginRequirementExcludingTargetMarket.add(proposedMarketPositionValue
|
|
426
|
-
.mul(new _1.BN(market.
|
|
444
|
+
.mul(new _1.BN((0, _1.calculateMarketMarginRatio)(market, proposedMarketPosition.baseAssetAmount.abs(), 'Maintenance')))
|
|
427
445
|
.div(numericConstants_1.MARGIN_PRECISION));
|
|
428
446
|
const freeCollateralAfterTrade = totalCollateral.sub(marginRequirementAfterTrade);
|
|
429
447
|
const marketMaxLeverage = this.getMaxLeverage(proposedMarketPosition.marketIndex, 'Maintenance');
|
|
@@ -470,10 +488,10 @@ class ClearingHouseUser {
|
|
|
470
488
|
this.getEmptyPosition(positionMarketIndex);
|
|
471
489
|
const closeBaseAmount = currentPosition.baseAssetAmount
|
|
472
490
|
.mul(closeQuoteAmount)
|
|
473
|
-
.div(currentPosition.quoteAssetAmount)
|
|
491
|
+
.div(currentPosition.quoteAssetAmount.abs())
|
|
474
492
|
.add(currentPosition.baseAssetAmount
|
|
475
493
|
.mul(closeQuoteAmount)
|
|
476
|
-
.mod(currentPosition.quoteAssetAmount))
|
|
494
|
+
.mod(currentPosition.quoteAssetAmount.abs()))
|
|
477
495
|
.neg();
|
|
478
496
|
return this.liquidationPrice({
|
|
479
497
|
marketIndex: positionMarketIndex,
|
package/lib/config.js
CHANGED
|
@@ -7,7 +7,7 @@ exports.configs = {
|
|
|
7
7
|
devnet: {
|
|
8
8
|
ENV: 'devnet',
|
|
9
9
|
PYTH_ORACLE_MAPPING_ADDRESS: 'BmA9Z6FjioHJPpjT39QazZyhDRUdZy2ezwx4GiDdE2u2',
|
|
10
|
-
CLEARING_HOUSE_PROGRAM_ID: '
|
|
10
|
+
CLEARING_HOUSE_PROGRAM_ID: '7HDuhZ94TVTWpH3vba3dJhGWyHvQuy2zBjniRxE7PU88',
|
|
11
11
|
USDC_MINT_ADDRESS: '8zGuJQqwhZafTah7Uc7Z4tXRnguqkn5KLFAP8oV6PHe2',
|
|
12
12
|
MARKETS: markets_1.DevnetMarkets,
|
|
13
13
|
BANKS: banks_1.DevnetBanks,
|
package/lib/constants/banks.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/// <reference types="bn.js" />
|
|
2
|
-
import { BN, OracleSource } from '../';
|
|
3
|
-
import { DriftEnv } from '../';
|
|
4
2
|
import { PublicKey } from '@solana/web3.js';
|
|
3
|
+
import { BN, DriftEnv, OracleSource } from '../';
|
|
5
4
|
export declare type BankConfig = {
|
|
6
5
|
symbol: string;
|
|
7
6
|
bankIndex: BN;
|
|
@@ -9,6 +8,7 @@ export declare type BankConfig = {
|
|
|
9
8
|
mint: PublicKey;
|
|
10
9
|
oracleSource: OracleSource;
|
|
11
10
|
};
|
|
11
|
+
export declare const WRAPPED_SOL_MINT: PublicKey;
|
|
12
12
|
export declare const DevnetBanks: BankConfig[];
|
|
13
13
|
export declare const MainnetBanks: BankConfig[];
|
|
14
14
|
export declare const Banks: {
|
package/lib/constants/banks.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Banks = exports.MainnetBanks = exports.DevnetBanks = void 0;
|
|
4
|
-
const __1 = require("../");
|
|
3
|
+
exports.Banks = exports.MainnetBanks = exports.DevnetBanks = exports.WRAPPED_SOL_MINT = void 0;
|
|
5
4
|
const web3_js_1 = require("@solana/web3.js");
|
|
5
|
+
const __1 = require("../");
|
|
6
|
+
exports.WRAPPED_SOL_MINT = new web3_js_1.PublicKey('So11111111111111111111111111111111111111112');
|
|
6
7
|
exports.DevnetBanks = [
|
|
7
8
|
{
|
|
8
9
|
symbol: 'USDC',
|
|
@@ -16,7 +17,7 @@ exports.DevnetBanks = [
|
|
|
16
17
|
bankIndex: new __1.BN(1),
|
|
17
18
|
oracle: new web3_js_1.PublicKey('J83w4HKfqxwcq3BEMMkPFSppX3gqekLyLJBexebFVkix'),
|
|
18
19
|
oracleSource: __1.OracleSource.PYTH,
|
|
19
|
-
mint: new web3_js_1.PublicKey(
|
|
20
|
+
mint: new web3_js_1.PublicKey(exports.WRAPPED_SOL_MINT),
|
|
20
21
|
},
|
|
21
22
|
{
|
|
22
23
|
symbol: 'BTC',
|
|
@@ -21,6 +21,8 @@ export declare const BANK_RATE_PRECISION: BN;
|
|
|
21
21
|
export declare const BANK_WEIGHT_PRECISION: BN;
|
|
22
22
|
export declare const BANK_BALANCE_PRECISION_EXP: BN;
|
|
23
23
|
export declare const BANK_BALANCE_PRECISION: BN;
|
|
24
|
+
export declare const BANK_IMF_PRECISION_EXP: BN;
|
|
25
|
+
export declare const BANK_IMF_PRECISION: BN;
|
|
24
26
|
export declare const LIQUIDATION_FEE_PRECISION: BN;
|
|
25
27
|
export declare const QUOTE_PRECISION: BN;
|
|
26
28
|
export declare const MARK_PRICE_PRECISION: BN;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.QUOTE_ASSET_BANK_INDEX = exports.ONE_YEAR = exports.BID_ASK_SPREAD_PRECISION = 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_PAYMENT_PRECISION = exports.MARK_PRICE_PRECISION = exports.QUOTE_PRECISION = exports.LIQUIDATION_FEE_PRECISION = exports.BANK_BALANCE_PRECISION = exports.BANK_BALANCE_PRECISION_EXP = exports.BANK_WEIGHT_PRECISION = exports.BANK_RATE_PRECISION = exports.BANK_UTILIZATION_PRECISION = exports.BANK_CUMULATIVE_INTEREST_PRECISION = exports.BANK_INTEREST_PRECISION = exports.AMM_RESERVE_PRECISION_EXP = exports.PEG_PRECISION_EXP = exports.FUNDING_RATE_PRECISION_EXP = exports.MARK_PRICE_PRECISION_EXP = exports.FUNDING_PAYMENT_PRECISION_EXP = exports.QUOTE_PRECISION_EXP = exports.MAX_LEVERAGE = exports.TEN_MILLION = exports.BN_MAX = exports.TEN_THOUSAND = exports.TEN = exports.TWO = exports.ONE = exports.ZERO = void 0;
|
|
3
|
+
exports.QUOTE_ASSET_BANK_INDEX = exports.ONE_YEAR = exports.BID_ASK_SPREAD_PRECISION = 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_PAYMENT_PRECISION = exports.MARK_PRICE_PRECISION = exports.QUOTE_PRECISION = exports.LIQUIDATION_FEE_PRECISION = exports.BANK_IMF_PRECISION = exports.BANK_IMF_PRECISION_EXP = exports.BANK_BALANCE_PRECISION = exports.BANK_BALANCE_PRECISION_EXP = exports.BANK_WEIGHT_PRECISION = exports.BANK_RATE_PRECISION = exports.BANK_UTILIZATION_PRECISION = exports.BANK_CUMULATIVE_INTEREST_PRECISION = exports.BANK_INTEREST_PRECISION = exports.AMM_RESERVE_PRECISION_EXP = exports.PEG_PRECISION_EXP = exports.FUNDING_RATE_PRECISION_EXP = exports.MARK_PRICE_PRECISION_EXP = exports.FUNDING_PAYMENT_PRECISION_EXP = exports.QUOTE_PRECISION_EXP = exports.MAX_LEVERAGE = exports.TEN_MILLION = exports.BN_MAX = exports.TEN_THOUSAND = exports.TEN = exports.TWO = exports.ONE = exports.ZERO = void 0;
|
|
4
4
|
const __1 = require("../");
|
|
5
5
|
exports.ZERO = new __1.BN(0);
|
|
6
6
|
exports.ONE = new __1.BN(1);
|
|
@@ -23,6 +23,8 @@ exports.BANK_RATE_PRECISION = new __1.BN(1000000);
|
|
|
23
23
|
exports.BANK_WEIGHT_PRECISION = new __1.BN(100);
|
|
24
24
|
exports.BANK_BALANCE_PRECISION_EXP = new __1.BN(6);
|
|
25
25
|
exports.BANK_BALANCE_PRECISION = new __1.BN(10).pow(exports.BANK_BALANCE_PRECISION_EXP);
|
|
26
|
+
exports.BANK_IMF_PRECISION_EXP = new __1.BN(6);
|
|
27
|
+
exports.BANK_IMF_PRECISION = new __1.BN(10).pow(exports.BANK_IMF_PRECISION_EXP);
|
|
26
28
|
exports.LIQUIDATION_FEE_PRECISION = new __1.BN(1000000);
|
|
27
29
|
exports.QUOTE_PRECISION = new __1.BN(10).pow(exports.QUOTE_PRECISION_EXP);
|
|
28
30
|
exports.MARK_PRICE_PRECISION = new __1.BN(10).pow(exports.MARK_PRICE_PRECISION_EXP);
|
package/lib/events/eventList.js
CHANGED
package/lib/events/types.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Commitment, TransactionSignature } from '@solana/web3.js';
|
|
2
|
-
import { DepositRecord, FundingPaymentRecord, FundingRateRecord, LiquidationRecord, OrderRecord } from '../index';
|
|
2
|
+
import { DepositRecord, FundingPaymentRecord, FundingRateRecord, LiquidationRecord, OrderRecord, SettlePnlRecord } from '../index';
|
|
3
3
|
export declare type EventSubscriptionOptions = {
|
|
4
4
|
eventTypes?: EventType[];
|
|
5
5
|
maxEventsPerType?: number;
|
|
@@ -27,6 +27,7 @@ export declare type EventMap = {
|
|
|
27
27
|
LiquidationRecord: Event<LiquidationRecord>;
|
|
28
28
|
FundingRateRecord: Event<FundingRateRecord>;
|
|
29
29
|
OrderRecord: Event<OrderRecord>;
|
|
30
|
+
SettlePnlRecord: Event<SettlePnlRecord>;
|
|
30
31
|
};
|
|
31
32
|
export declare type EventType = keyof EventMap;
|
|
32
33
|
export interface EventSubscriberEvents {
|
package/lib/factory/bigNum.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export declare class BigNum {
|
|
|
6
6
|
static delim: string;
|
|
7
7
|
static spacer: string;
|
|
8
8
|
constructor(val: BN | number | string, precisionVal?: BN | number | string);
|
|
9
|
+
private bigNumFromParam;
|
|
9
10
|
add(bn: BigNum): BigNum;
|
|
10
11
|
sub(bn: BigNum): BigNum;
|
|
11
12
|
mul(bn: BigNum | BN): BigNum;
|
package/lib/factory/bigNum.js
CHANGED
|
@@ -10,6 +10,9 @@ class BigNum {
|
|
|
10
10
|
this.val = new anchor_1.BN(val);
|
|
11
11
|
this.precision = new anchor_1.BN(precisionVal);
|
|
12
12
|
}
|
|
13
|
+
bigNumFromParam(bn) {
|
|
14
|
+
return anchor_1.BN.isBN(bn) ? BigNum.from(bn) : bn;
|
|
15
|
+
}
|
|
13
16
|
add(bn) {
|
|
14
17
|
(0, assert_1.assert)(bn.precision.eq(this.precision), 'Adding unequal precisions');
|
|
15
18
|
return BigNum.from(this.val.add(bn.val), this.precision);
|
|
@@ -19,7 +22,7 @@ class BigNum {
|
|
|
19
22
|
return BigNum.from(this.val.sub(bn.val), this.precision);
|
|
20
23
|
}
|
|
21
24
|
mul(bn) {
|
|
22
|
-
const mulVal =
|
|
25
|
+
const mulVal = this.bigNumFromParam(bn);
|
|
23
26
|
return BigNum.from(this.val.mul(mulVal.val), this.precision.add(mulVal.precision));
|
|
24
27
|
}
|
|
25
28
|
/**
|
|
@@ -28,12 +31,12 @@ class BigNum {
|
|
|
28
31
|
* @returns
|
|
29
32
|
*/
|
|
30
33
|
scalarMul(bn) {
|
|
31
|
-
if (
|
|
34
|
+
if (anchor_1.BN.isBN(bn))
|
|
32
35
|
return BigNum.from(this.val.mul(bn), this.precision);
|
|
33
36
|
return BigNum.from(this.val.mul(bn.val), this.precision.add(bn.precision)).shift(bn.precision.neg());
|
|
34
37
|
}
|
|
35
38
|
div(bn) {
|
|
36
|
-
if (
|
|
39
|
+
if (anchor_1.BN.isBN(bn))
|
|
37
40
|
return BigNum.from(this.val.div(bn), this.precision);
|
|
38
41
|
return BigNum.from(this.val.div(bn.val), this.precision.sub(bn.precision));
|
|
39
42
|
}
|
|
@@ -73,35 +76,35 @@ class BigNum {
|
|
|
73
76
|
.toPrecision(precision);
|
|
74
77
|
}
|
|
75
78
|
gt(bn, ignorePrecision) {
|
|
76
|
-
const comparisonVal =
|
|
79
|
+
const comparisonVal = this.bigNumFromParam(bn);
|
|
77
80
|
if (!ignorePrecision && !comparisonVal.eq(numericConstants_1.ZERO)) {
|
|
78
81
|
(0, assert_1.assert)(comparisonVal.precision.eq(this.precision), 'Trying to compare numbers with different precision. Yo can opt to ignore precision using the ignorePrecision parameter');
|
|
79
82
|
}
|
|
80
83
|
return this.val.gt(comparisonVal.val);
|
|
81
84
|
}
|
|
82
85
|
lt(bn, ignorePrecision) {
|
|
83
|
-
const comparisonVal =
|
|
86
|
+
const comparisonVal = this.bigNumFromParam(bn);
|
|
84
87
|
if (!ignorePrecision && !comparisonVal.val.eq(numericConstants_1.ZERO)) {
|
|
85
88
|
(0, assert_1.assert)(comparisonVal.precision.eq(this.precision), 'Trying to compare numbers with different precision. Yo can opt to ignore precision using the ignorePrecision parameter');
|
|
86
89
|
}
|
|
87
90
|
return this.val.lt(comparisonVal.val);
|
|
88
91
|
}
|
|
89
92
|
gte(bn, ignorePrecision) {
|
|
90
|
-
const comparisonVal =
|
|
93
|
+
const comparisonVal = this.bigNumFromParam(bn);
|
|
91
94
|
if (!ignorePrecision && !comparisonVal.val.eq(numericConstants_1.ZERO)) {
|
|
92
95
|
(0, assert_1.assert)(comparisonVal.precision.eq(this.precision), 'Trying to compare numbers with different precision. Yo can opt to ignore precision using the ignorePrecision parameter');
|
|
93
96
|
}
|
|
94
97
|
return this.val.gte(comparisonVal.val);
|
|
95
98
|
}
|
|
96
99
|
lte(bn, ignorePrecision) {
|
|
97
|
-
const comparisonVal =
|
|
100
|
+
const comparisonVal = this.bigNumFromParam(bn);
|
|
98
101
|
if (!ignorePrecision && !comparisonVal.val.eq(numericConstants_1.ZERO)) {
|
|
99
102
|
(0, assert_1.assert)(comparisonVal.precision.eq(this.precision), 'Trying to compare numbers with different precision. Yo can opt to ignore precision using the ignorePrecision parameter');
|
|
100
103
|
}
|
|
101
104
|
return this.val.lte(comparisonVal.val);
|
|
102
105
|
}
|
|
103
106
|
eq(bn, ignorePrecision) {
|
|
104
|
-
const comparisonVal =
|
|
107
|
+
const comparisonVal = this.bigNumFromParam(bn);
|
|
105
108
|
if (!ignorePrecision && !comparisonVal.val.eq(numericConstants_1.ZERO)) {
|
|
106
109
|
(0, assert_1.assert)(comparisonVal.precision.eq(this.precision), 'Trying to compare numbers with different precision. Yo can opt to ignore precision using the ignorePrecision parameter');
|
|
107
110
|
}
|
|
@@ -149,8 +152,14 @@ class BigNum {
|
|
|
149
152
|
// remove leading zeroes
|
|
150
153
|
printString = printString.replace(/^0+/, '');
|
|
151
154
|
// add zero if leading delim
|
|
152
|
-
if (
|
|
153
|
-
printString
|
|
155
|
+
if (this.isNeg()) {
|
|
156
|
+
if (printString[1] === BigNum.delim)
|
|
157
|
+
printString = printString.replace('-.', '-0.');
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
if (printString[0] === BigNum.delim)
|
|
161
|
+
printString = `0${printString}`;
|
|
162
|
+
}
|
|
154
163
|
// remove trailing delim
|
|
155
164
|
if (printString[printString.length - 1] === BigNum.delim)
|
|
156
165
|
printString = printString.slice(0, printString.length - 1);
|
|
@@ -261,10 +270,27 @@ class BigNum {
|
|
|
261
270
|
* @returns
|
|
262
271
|
*/
|
|
263
272
|
toNotional(useTradePrecision, precisionOverride) {
|
|
273
|
+
var _a;
|
|
264
274
|
const prefix = `${this.lt(BigNum.zero()) ? `-` : ``}$`;
|
|
265
|
-
const
|
|
275
|
+
const usingCustomPrecision = true && (useTradePrecision || precisionOverride);
|
|
276
|
+
let val = usingCustomPrecision
|
|
266
277
|
? this.prettyPrint(useTradePrecision, precisionOverride)
|
|
267
278
|
: BigNum.fromPrint(this.toFixed(2), new anchor_1.BN(2)).prettyPrint();
|
|
279
|
+
// Append two trailing zeroes if not using custom precision
|
|
280
|
+
if (!usingCustomPrecision) {
|
|
281
|
+
const [_, rightSide] = val.split(BigNum.delim);
|
|
282
|
+
const trailingLength = (_a = rightSide === null || rightSide === void 0 ? void 0 : rightSide.length) !== null && _a !== void 0 ? _a : 0;
|
|
283
|
+
if (trailingLength < 2) {
|
|
284
|
+
const numHasDecimals = this.print().includes(BigNum.delim);
|
|
285
|
+
// Handle case where pretty print won't include the decimal point
|
|
286
|
+
if (trailingLength === 0 && numHasDecimals) {
|
|
287
|
+
val = `${val}.00`;
|
|
288
|
+
}
|
|
289
|
+
else {
|
|
290
|
+
val = `${val}${new Array(2 - trailingLength).fill('0').join('')}`;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
}
|
|
268
294
|
return `${prefix}${val.replace('-', '')}`;
|
|
269
295
|
}
|
|
270
296
|
toMillified(precision = 3) {
|