@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/src/clearingHouseUser.ts
CHANGED
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
PRICE_TO_QUOTE_PRECISION,
|
|
22
22
|
MARGIN_PRECISION,
|
|
23
23
|
BANK_WEIGHT_PRECISION,
|
|
24
|
+
BANK_BALANCE_PRECISION_EXP,
|
|
24
25
|
} from './constants/numericConstants';
|
|
25
26
|
import {
|
|
26
27
|
UserAccountSubscriber,
|
|
@@ -32,12 +33,22 @@ import {
|
|
|
32
33
|
calculateBaseAssetValue,
|
|
33
34
|
calculatePositionFundingPNL,
|
|
34
35
|
calculatePositionPNL,
|
|
36
|
+
calculateUnsettledAssetWeight,
|
|
37
|
+
calculateMarketMarginRatio,
|
|
35
38
|
PositionDirection,
|
|
36
39
|
calculateTradeSlippage,
|
|
37
40
|
BN,
|
|
38
41
|
BankAccount,
|
|
39
42
|
} from '.';
|
|
40
|
-
import {
|
|
43
|
+
import {
|
|
44
|
+
getTokenAmount,
|
|
45
|
+
calculateAssetWeight,
|
|
46
|
+
calculateLiabilityWeight,
|
|
47
|
+
} from './math/bankBalance';
|
|
48
|
+
import {
|
|
49
|
+
calculateMarginBaseAssetValue,
|
|
50
|
+
calculateWorstCaseBaseAssetAmount,
|
|
51
|
+
} from './math/margin';
|
|
41
52
|
import { OraclePriceData } from './oracles/types';
|
|
42
53
|
import { ClearingHouseUserConfig } from './clearingHouseUserConfig';
|
|
43
54
|
import { PollingUserAccountSubscriber } from './accounts/pollingUserAccountSubscriber';
|
|
@@ -124,7 +135,6 @@ export class ClearingHouseUser {
|
|
|
124
135
|
quoteAssetAmount: ZERO,
|
|
125
136
|
quoteEntryAmount: ZERO,
|
|
126
137
|
openOrders: ZERO,
|
|
127
|
-
unsettledPnl: ZERO,
|
|
128
138
|
openBids: ZERO,
|
|
129
139
|
openAsks: ZERO,
|
|
130
140
|
};
|
|
@@ -184,26 +194,43 @@ export class ClearingHouseUser {
|
|
|
184
194
|
}
|
|
185
195
|
|
|
186
196
|
public getInitialMarginRequirement(): BN {
|
|
187
|
-
|
|
188
|
-
|
|
197
|
+
const postionMarginRequirement = this.getUserAccount().positions.reduce(
|
|
198
|
+
(marginRequirement, marketPosition) => {
|
|
189
199
|
const market = this.clearingHouse.getMarketAccount(
|
|
190
200
|
marketPosition.marketIndex
|
|
191
201
|
);
|
|
192
|
-
|
|
193
|
-
|
|
202
|
+
const worstCaseBaseAssetAmount =
|
|
203
|
+
calculateWorstCaseBaseAssetAmount(marketPosition);
|
|
204
|
+
|
|
205
|
+
const worstCaseAssetValue = worstCaseBaseAssetAmount
|
|
206
|
+
.abs()
|
|
207
|
+
.mul(this.getOracleDataForMarket(market.marketIndex).price)
|
|
208
|
+
.div(AMM_TO_QUOTE_PRECISION_RATIO.mul(MARK_PRICE_PRECISION));
|
|
209
|
+
|
|
210
|
+
const marketMarginRatio = new BN(
|
|
211
|
+
calculateMarketMarginRatio(
|
|
194
212
|
market,
|
|
195
|
-
|
|
196
|
-
|
|
213
|
+
worstCaseBaseAssetAmount.abs(),
|
|
214
|
+
'Initial'
|
|
197
215
|
)
|
|
198
|
-
.mul(new BN(market.marginRatioInitial))
|
|
199
|
-
.div(MARGIN_PRECISION)
|
|
200
216
|
);
|
|
201
|
-
|
|
202
|
-
|
|
217
|
+
return marginRequirement.add(
|
|
218
|
+
worstCaseAssetValue.mul(marketMarginRatio).div(MARGIN_PRECISION)
|
|
219
|
+
);
|
|
220
|
+
},
|
|
221
|
+
ZERO
|
|
222
|
+
);
|
|
223
|
+
|
|
224
|
+
const bankMarginRequirement = this.getBankLiabilityValue(
|
|
225
|
+
undefined,
|
|
226
|
+
'Initial'
|
|
227
|
+
);
|
|
228
|
+
|
|
229
|
+
return bankMarginRequirement.add(postionMarginRequirement);
|
|
203
230
|
}
|
|
204
231
|
|
|
205
232
|
/**
|
|
206
|
-
* @returns The
|
|
233
|
+
* @returns The maintenance margin requirement in USDC. : QUOTE_PRECISION
|
|
207
234
|
*/
|
|
208
235
|
public getMaintenanceMarginRequirement(): BN {
|
|
209
236
|
return this.getUserAccount()
|
|
@@ -211,24 +238,40 @@ export class ClearingHouseUser {
|
|
|
211
238
|
const market = this.clearingHouse.getMarketAccount(
|
|
212
239
|
marketPosition.marketIndex
|
|
213
240
|
);
|
|
241
|
+
const worstCaseBaseAssetAmount =
|
|
242
|
+
calculateWorstCaseBaseAssetAmount(marketPosition);
|
|
243
|
+
|
|
244
|
+
const worstCaseAssetValue = worstCaseBaseAssetAmount
|
|
245
|
+
.abs()
|
|
246
|
+
.mul(this.getOracleDataForMarket(market.marketIndex).price)
|
|
247
|
+
.div(AMM_TO_QUOTE_PRECISION_RATIO.mul(MARK_PRICE_PRECISION));
|
|
248
|
+
|
|
214
249
|
return marginRequirement.add(
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
250
|
+
worstCaseAssetValue
|
|
251
|
+
.mul(
|
|
252
|
+
new BN(
|
|
253
|
+
calculateMarketMarginRatio(
|
|
254
|
+
market,
|
|
255
|
+
worstCaseBaseAssetAmount.abs(),
|
|
256
|
+
'Maintenance'
|
|
257
|
+
)
|
|
258
|
+
)
|
|
259
|
+
)
|
|
221
260
|
.div(MARGIN_PRECISION)
|
|
222
261
|
);
|
|
223
262
|
}, ZERO)
|
|
224
|
-
.add(this.
|
|
263
|
+
.add(this.getBankLiabilityValue(undefined, 'Maintenance'));
|
|
225
264
|
}
|
|
226
265
|
|
|
227
266
|
/**
|
|
228
267
|
* calculates unrealized position price pnl
|
|
229
268
|
* @returns : Precision QUOTE_PRECISION
|
|
230
269
|
*/
|
|
231
|
-
public getUnrealizedPNL(
|
|
270
|
+
public getUnrealizedPNL(
|
|
271
|
+
withFunding?: boolean,
|
|
272
|
+
marketIndex?: BN,
|
|
273
|
+
withWeightMarginCategory?: MarginCategory
|
|
274
|
+
): BN {
|
|
232
275
|
return this.getUserAccount()
|
|
233
276
|
.positions.filter((pos) =>
|
|
234
277
|
marketIndex ? pos.marketIndex === marketIndex : true
|
|
@@ -237,28 +280,28 @@ export class ClearingHouseUser {
|
|
|
237
280
|
const market = this.clearingHouse.getMarketAccount(
|
|
238
281
|
marketPosition.marketIndex
|
|
239
282
|
);
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
this.getOracleDataForMarket(market.marketIndex)
|
|
246
|
-
)
|
|
283
|
+
let pnl0 = calculatePositionPNL(
|
|
284
|
+
market,
|
|
285
|
+
marketPosition,
|
|
286
|
+
withFunding,
|
|
287
|
+
this.getOracleDataForMarket(market.marketIndex)
|
|
247
288
|
);
|
|
248
|
-
}, ZERO);
|
|
249
|
-
}
|
|
250
289
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
290
|
+
if (withWeightMarginCategory !== undefined) {
|
|
291
|
+
if (pnl0.gt(ZERO)) {
|
|
292
|
+
pnl0 = pnl0
|
|
293
|
+
.mul(
|
|
294
|
+
calculateUnsettledAssetWeight(
|
|
295
|
+
market,
|
|
296
|
+
pnl0,
|
|
297
|
+
withWeightMarginCategory
|
|
298
|
+
)
|
|
299
|
+
)
|
|
300
|
+
.div(new BN(BANK_WEIGHT_PRECISION));
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
return pnl.add(pnl0);
|
|
262
305
|
}, ZERO);
|
|
263
306
|
}
|
|
264
307
|
|
|
@@ -279,14 +322,18 @@ export class ClearingHouseUser {
|
|
|
279
322
|
}, ZERO);
|
|
280
323
|
}
|
|
281
324
|
|
|
282
|
-
public
|
|
325
|
+
public getBankLiabilityValue(
|
|
326
|
+
bankIndex?: BN,
|
|
327
|
+
withWeightMarginCategory?: MarginCategory
|
|
328
|
+
): BN {
|
|
283
329
|
return this.getUserAccount().bankBalances.reduce(
|
|
284
|
-
(
|
|
330
|
+
(totalLiabilityValue, bankBalance) => {
|
|
285
331
|
if (
|
|
286
332
|
bankBalance.balance.eq(ZERO) ||
|
|
287
|
-
isVariant(bankBalance.balanceType, 'deposit')
|
|
333
|
+
isVariant(bankBalance.balanceType, 'deposit') ||
|
|
334
|
+
(bankIndex !== undefined && !bankBalance.bankIndex.eq(bankIndex))
|
|
288
335
|
) {
|
|
289
|
-
return
|
|
336
|
+
return totalLiabilityValue;
|
|
290
337
|
}
|
|
291
338
|
|
|
292
339
|
// Todo this needs to account for whether it's based on initial or maintenance requirements
|
|
@@ -299,23 +346,42 @@ export class ClearingHouseUser {
|
|
|
299
346
|
bankAccount,
|
|
300
347
|
bankBalance.balanceType
|
|
301
348
|
);
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
.
|
|
308
|
-
|
|
349
|
+
|
|
350
|
+
let liabilityValue = tokenAmount
|
|
351
|
+
.mul(this.getOracleDataForBank(bankAccount.bankIndex).price)
|
|
352
|
+
.div(MARK_PRICE_PRECISION)
|
|
353
|
+
.div(
|
|
354
|
+
new BN(10).pow(
|
|
355
|
+
new BN(bankAccount.decimals).sub(BANK_BALANCE_PRECISION_EXP)
|
|
356
|
+
)
|
|
357
|
+
);
|
|
358
|
+
|
|
359
|
+
if (withWeightMarginCategory !== undefined) {
|
|
360
|
+
const weight = calculateLiabilityWeight(
|
|
361
|
+
tokenAmount,
|
|
362
|
+
bankAccount,
|
|
363
|
+
withWeightMarginCategory
|
|
364
|
+
);
|
|
365
|
+
liabilityValue = liabilityValue
|
|
366
|
+
.mul(weight)
|
|
367
|
+
.div(BANK_WEIGHT_PRECISION);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
return totalLiabilityValue.add(liabilityValue);
|
|
309
371
|
},
|
|
310
372
|
ZERO
|
|
311
373
|
);
|
|
312
374
|
}
|
|
313
375
|
|
|
314
|
-
public
|
|
376
|
+
public getBankAssetValue(
|
|
377
|
+
bankIndex?: BN,
|
|
378
|
+
withWeightMarginCategory?: MarginCategory
|
|
379
|
+
): BN {
|
|
315
380
|
return this.getUserAccount().bankBalances.reduce(
|
|
316
381
|
(totalAssetValue, bankBalance) => {
|
|
317
382
|
if (
|
|
318
383
|
bankBalance.balance.eq(ZERO) ||
|
|
384
|
+
isVariant(bankBalance.balanceType, 'borrow') ||
|
|
319
385
|
(bankIndex !== undefined && !bankBalance.bankIndex.eq(bankIndex))
|
|
320
386
|
) {
|
|
321
387
|
return totalAssetValue;
|
|
@@ -326,32 +392,46 @@ export class ClearingHouseUser {
|
|
|
326
392
|
bankBalance.bankIndex
|
|
327
393
|
);
|
|
328
394
|
|
|
329
|
-
|
|
395
|
+
const tokenAmount = getTokenAmount(
|
|
330
396
|
bankBalance.balance,
|
|
331
397
|
bankAccount,
|
|
332
398
|
bankBalance.balanceType
|
|
333
399
|
);
|
|
334
400
|
|
|
335
|
-
|
|
336
|
-
|
|
401
|
+
let assetValue = tokenAmount
|
|
402
|
+
.mul(this.getOracleDataForBank(bankAccount.bankIndex).price)
|
|
403
|
+
.div(MARK_PRICE_PRECISION)
|
|
404
|
+
.div(
|
|
405
|
+
new BN(10).pow(
|
|
406
|
+
new BN(bankAccount.decimals).sub(BANK_BALANCE_PRECISION_EXP)
|
|
407
|
+
)
|
|
408
|
+
);
|
|
409
|
+
if (withWeightMarginCategory !== undefined) {
|
|
410
|
+
const weight = calculateAssetWeight(
|
|
411
|
+
tokenAmount,
|
|
412
|
+
bankAccount,
|
|
413
|
+
withWeightMarginCategory
|
|
414
|
+
);
|
|
415
|
+
assetValue = assetValue.mul(weight).div(BANK_WEIGHT_PRECISION);
|
|
337
416
|
}
|
|
338
417
|
|
|
339
|
-
return totalAssetValue.add(
|
|
340
|
-
tokenAmount
|
|
341
|
-
.mul(this.getOracleDataForBank(bankAccount.bankIndex).price)
|
|
342
|
-
.div(MARK_PRICE_PRECISION)
|
|
343
|
-
);
|
|
418
|
+
return totalAssetValue.add(assetValue);
|
|
344
419
|
},
|
|
345
420
|
ZERO
|
|
346
421
|
);
|
|
347
422
|
}
|
|
348
423
|
|
|
424
|
+
public getNetBankValue(withWeightMarginCategory?: MarginCategory): BN {
|
|
425
|
+
return this.getBankAssetValue(undefined, withWeightMarginCategory).sub(
|
|
426
|
+
this.getBankLiabilityValue(undefined, withWeightMarginCategory)
|
|
427
|
+
);
|
|
428
|
+
}
|
|
429
|
+
|
|
349
430
|
/**
|
|
350
431
|
* calculates TotalCollateral: collateral + unrealized pnl
|
|
351
|
-
* TODO: rename to total equity (for perpetuals swaps)
|
|
352
432
|
* @returns : Precision QUOTE_PRECISION
|
|
353
433
|
*/
|
|
354
|
-
public getTotalCollateral(): BN {
|
|
434
|
+
public getTotalCollateral(marginCategory: MarginCategory = 'Initial'): BN {
|
|
355
435
|
return this.getUserAccount()
|
|
356
436
|
.bankBalances.reduce((totalAssetValue, bankBalance) => {
|
|
357
437
|
if (
|
|
@@ -371,20 +451,32 @@ export class ClearingHouseUser {
|
|
|
371
451
|
bankAccount,
|
|
372
452
|
bankBalance.balanceType
|
|
373
453
|
);
|
|
454
|
+
|
|
455
|
+
const weight = calculateAssetWeight(
|
|
456
|
+
tokenAmount,
|
|
457
|
+
bankAccount,
|
|
458
|
+
marginCategory
|
|
459
|
+
);
|
|
460
|
+
|
|
374
461
|
return totalAssetValue.add(
|
|
375
462
|
tokenAmount
|
|
376
463
|
.mul(this.getOracleDataForBank(bankAccount.bankIndex).price)
|
|
377
|
-
.mul(
|
|
464
|
+
.mul(weight)
|
|
378
465
|
.div(BANK_WEIGHT_PRECISION)
|
|
379
466
|
.div(MARK_PRICE_PRECISION)
|
|
467
|
+
// Adjust for decimals of bank account
|
|
468
|
+
.div(
|
|
469
|
+
new BN(10).pow(
|
|
470
|
+
new BN(bankAccount.decimals).sub(BANK_BALANCE_PRECISION_EXP)
|
|
471
|
+
)
|
|
472
|
+
)
|
|
380
473
|
);
|
|
381
474
|
}, ZERO)
|
|
382
|
-
.add(this.getUnrealizedPNL(true))
|
|
383
|
-
.add(this.getUnsettledPNL());
|
|
475
|
+
.add(this.getUnrealizedPNL(true, undefined, marginCategory));
|
|
384
476
|
}
|
|
385
477
|
|
|
386
478
|
/**
|
|
387
|
-
* calculates sum of position value across all positions
|
|
479
|
+
* calculates sum of position value across all positions in margin system
|
|
388
480
|
* @returns : Precision QUOTE_PRECISION
|
|
389
481
|
*/
|
|
390
482
|
getTotalPositionValue(): BN {
|
|
@@ -393,20 +485,20 @@ export class ClearingHouseUser {
|
|
|
393
485
|
const market = this.clearingHouse.getMarketAccount(
|
|
394
486
|
marketPosition.marketIndex
|
|
395
487
|
);
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
this.getOracleDataForMarket(market.marketIndex)
|
|
401
|
-
)
|
|
488
|
+
const posVal = calculateMarginBaseAssetValue(
|
|
489
|
+
market,
|
|
490
|
+
marketPosition,
|
|
491
|
+
this.getOracleDataForMarket(market.marketIndex)
|
|
402
492
|
);
|
|
493
|
+
|
|
494
|
+
return positionValue.add(posVal);
|
|
403
495
|
},
|
|
404
496
|
ZERO
|
|
405
497
|
);
|
|
406
498
|
}
|
|
407
499
|
|
|
408
500
|
/**
|
|
409
|
-
* calculates position value
|
|
501
|
+
* calculates position value in margin system
|
|
410
502
|
* @returns : Precision QUOTE_PRECISION
|
|
411
503
|
*/
|
|
412
504
|
public getPositionValue(
|
|
@@ -418,7 +510,7 @@ export class ClearingHouseUser {
|
|
|
418
510
|
const market = this.clearingHouse.getMarketAccount(
|
|
419
511
|
userPosition.marketIndex
|
|
420
512
|
);
|
|
421
|
-
return
|
|
513
|
+
return calculateMarginBaseAssetValue(market, userPosition, oraclePriceData);
|
|
422
514
|
}
|
|
423
515
|
|
|
424
516
|
public getPositionSide(
|
|
@@ -434,12 +526,13 @@ export class ClearingHouseUser {
|
|
|
434
526
|
}
|
|
435
527
|
|
|
436
528
|
/**
|
|
437
|
-
* calculates average exit price for closing 100% of position
|
|
529
|
+
* calculates average exit price (optionally for closing up to 100% of position)
|
|
438
530
|
* @returns : Precision MARK_PRICE_PRECISION
|
|
439
531
|
*/
|
|
440
532
|
public getPositionEstimatedExitPriceAndPnl(
|
|
441
533
|
position: UserPosition,
|
|
442
|
-
amountToClose?: BN
|
|
534
|
+
amountToClose?: BN,
|
|
535
|
+
useAMMClose = false
|
|
443
536
|
): [BN, BN] {
|
|
444
537
|
const market = this.clearingHouse.getMarketAccount(position.marketIndex);
|
|
445
538
|
|
|
@@ -459,11 +552,21 @@ export class ClearingHouseUser {
|
|
|
459
552
|
} as UserPosition;
|
|
460
553
|
}
|
|
461
554
|
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
555
|
+
let baseAssetValue: BN;
|
|
556
|
+
|
|
557
|
+
if (useAMMClose) {
|
|
558
|
+
baseAssetValue = calculateBaseAssetValue(
|
|
559
|
+
market,
|
|
560
|
+
position,
|
|
561
|
+
oraclePriceData
|
|
562
|
+
);
|
|
563
|
+
} else {
|
|
564
|
+
baseAssetValue = calculateMarginBaseAssetValue(
|
|
565
|
+
market,
|
|
566
|
+
position,
|
|
567
|
+
oraclePriceData
|
|
568
|
+
);
|
|
569
|
+
}
|
|
467
570
|
if (position.baseAssetAmount.eq(ZERO)) {
|
|
468
571
|
return [ZERO, ZERO];
|
|
469
572
|
}
|
|
@@ -505,19 +608,13 @@ export class ClearingHouseUser {
|
|
|
505
608
|
category: MarginCategory = 'Initial'
|
|
506
609
|
): BN {
|
|
507
610
|
const market = this.clearingHouse.getMarketAccount(marketIndex);
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
marginRatioCategory = market.marginRatioMaintenance;
|
|
516
|
-
break;
|
|
517
|
-
default:
|
|
518
|
-
marginRatioCategory = market.marginRatioInitial;
|
|
519
|
-
break;
|
|
520
|
-
}
|
|
611
|
+
|
|
612
|
+
const marginRatioCategory = calculateMarketMarginRatio(
|
|
613
|
+
market,
|
|
614
|
+
// worstCaseBaseAssetAmount.abs(),
|
|
615
|
+
ZERO, // todo
|
|
616
|
+
category
|
|
617
|
+
);
|
|
521
618
|
const maxLeverage = TEN_THOUSAND.mul(TEN_THOUSAND).div(
|
|
522
619
|
new BN(marginRatioCategory)
|
|
523
620
|
);
|
|
@@ -624,7 +721,6 @@ export class ClearingHouseUser {
|
|
|
624
721
|
quoteAssetAmount: new BN(0),
|
|
625
722
|
quoteEntryAmount: new BN(0),
|
|
626
723
|
openOrders: new BN(0),
|
|
627
|
-
unsettledPnl: new BN(0),
|
|
628
724
|
openBids: new BN(0),
|
|
629
725
|
openAsks: new BN(0),
|
|
630
726
|
};
|
|
@@ -635,7 +731,7 @@ export class ClearingHouseUser {
|
|
|
635
731
|
proposedMarketPosition.marketIndex
|
|
636
732
|
);
|
|
637
733
|
|
|
638
|
-
const proposedMarketPositionValue =
|
|
734
|
+
const proposedMarketPositionValue = calculateMarginBaseAssetValue(
|
|
639
735
|
market,
|
|
640
736
|
proposedMarketPosition,
|
|
641
737
|
this.getOracleDataForMarket(market.marketIndex)
|
|
@@ -652,14 +748,19 @@ export class ClearingHouseUser {
|
|
|
652
748
|
const market = this.clearingHouse.getMarketAccount(
|
|
653
749
|
position.marketIndex
|
|
654
750
|
);
|
|
655
|
-
const positionValue =
|
|
751
|
+
const positionValue = calculateMarginBaseAssetValue(
|
|
656
752
|
market,
|
|
657
753
|
position,
|
|
658
754
|
this.getOracleDataForMarket(market.marketIndex)
|
|
659
755
|
);
|
|
660
|
-
const marketMarginRequirement = positionValue
|
|
661
|
-
|
|
662
|
-
|
|
756
|
+
const marketMarginRequirement = positionValue;
|
|
757
|
+
new BN(
|
|
758
|
+
calculateMarketMarginRatio(
|
|
759
|
+
market,
|
|
760
|
+
position.baseAssetAmount.abs(),
|
|
761
|
+
'Maintenance'
|
|
762
|
+
)
|
|
763
|
+
).div(MARGIN_PRECISION);
|
|
663
764
|
totalMarginRequirement = totalMarginRequirement.add(
|
|
664
765
|
marketMarginRequirement
|
|
665
766
|
);
|
|
@@ -684,7 +785,15 @@ export class ClearingHouseUser {
|
|
|
684
785
|
const marginRequirementAfterTrade =
|
|
685
786
|
marginRequirementExcludingTargetMarket.add(
|
|
686
787
|
proposedMarketPositionValue
|
|
687
|
-
.mul(
|
|
788
|
+
.mul(
|
|
789
|
+
new BN(
|
|
790
|
+
calculateMarketMarginRatio(
|
|
791
|
+
market,
|
|
792
|
+
proposedMarketPosition.baseAssetAmount.abs(),
|
|
793
|
+
'Maintenance'
|
|
794
|
+
)
|
|
795
|
+
)
|
|
796
|
+
)
|
|
688
797
|
.div(MARGIN_PRECISION)
|
|
689
798
|
);
|
|
690
799
|
const freeCollateralAfterTrade = totalCollateral.sub(
|
|
@@ -755,11 +864,11 @@ export class ClearingHouseUser {
|
|
|
755
864
|
|
|
756
865
|
const closeBaseAmount = currentPosition.baseAssetAmount
|
|
757
866
|
.mul(closeQuoteAmount)
|
|
758
|
-
.div(currentPosition.quoteAssetAmount)
|
|
867
|
+
.div(currentPosition.quoteAssetAmount.abs())
|
|
759
868
|
.add(
|
|
760
869
|
currentPosition.baseAssetAmount
|
|
761
870
|
.mul(closeQuoteAmount)
|
|
762
|
-
.mod(currentPosition.quoteAssetAmount)
|
|
871
|
+
.mod(currentPosition.quoteAssetAmount.abs())
|
|
763
872
|
)
|
|
764
873
|
.neg();
|
|
765
874
|
|
package/src/config.ts
CHANGED
|
@@ -28,7 +28,7 @@ export const configs: { [key in DriftEnv]: DriftConfig } = {
|
|
|
28
28
|
devnet: {
|
|
29
29
|
ENV: 'devnet',
|
|
30
30
|
PYTH_ORACLE_MAPPING_ADDRESS: 'BmA9Z6FjioHJPpjT39QazZyhDRUdZy2ezwx4GiDdE2u2',
|
|
31
|
-
CLEARING_HOUSE_PROGRAM_ID: '
|
|
31
|
+
CLEARING_HOUSE_PROGRAM_ID: '7HDuhZ94TVTWpH3vba3dJhGWyHvQuy2zBjniRxE7PU88',
|
|
32
32
|
USDC_MINT_ADDRESS: '8zGuJQqwhZafTah7Uc7Z4tXRnguqkn5KLFAP8oV6PHe2',
|
|
33
33
|
MARKETS: DevnetMarkets,
|
|
34
34
|
BANKS: DevnetBanks,
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Banks = exports.MainnetBanks = exports.DevnetBanks = exports.WRAPPED_SOL_MINT = void 0;
|
|
4
|
+
const web3_js_1 = require("@solana/web3.js");
|
|
5
|
+
const __1 = require("../");
|
|
6
|
+
exports.WRAPPED_SOL_MINT = new web3_js_1.PublicKey('So11111111111111111111111111111111111111112');
|
|
7
|
+
exports.DevnetBanks = [
|
|
8
|
+
{
|
|
9
|
+
symbol: 'USDC',
|
|
10
|
+
bankIndex: new __1.BN(0),
|
|
11
|
+
oracle: web3_js_1.PublicKey.default,
|
|
12
|
+
oracleSource: __1.OracleSource.QUOTE_ASSET,
|
|
13
|
+
mint: new web3_js_1.PublicKey('8zGuJQqwhZafTah7Uc7Z4tXRnguqkn5KLFAP8oV6PHe2'),
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
symbol: 'SOL',
|
|
17
|
+
bankIndex: new __1.BN(1),
|
|
18
|
+
oracle: new web3_js_1.PublicKey('J83w4HKfqxwcq3BEMMkPFSppX3gqekLyLJBexebFVkix'),
|
|
19
|
+
oracleSource: __1.OracleSource.PYTH,
|
|
20
|
+
mint: new web3_js_1.PublicKey(exports.WRAPPED_SOL_MINT),
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
symbol: 'BTC',
|
|
24
|
+
bankIndex: new __1.BN(2),
|
|
25
|
+
oracle: new web3_js_1.PublicKey('HovQMDrbAgAYPCmHVSrezcSmkMtXSSUsLDFANExrZh2J'),
|
|
26
|
+
oracleSource: __1.OracleSource.PYTH,
|
|
27
|
+
mint: new web3_js_1.PublicKey('3BZPwbcqB5kKScF3TEXxwNfx5ipV13kbRVDvfVp5c6fv'),
|
|
28
|
+
},
|
|
29
|
+
];
|
|
30
|
+
exports.MainnetBanks = [
|
|
31
|
+
{
|
|
32
|
+
symbol: 'USDC',
|
|
33
|
+
bankIndex: new __1.BN(0),
|
|
34
|
+
oracle: web3_js_1.PublicKey.default,
|
|
35
|
+
oracleSource: __1.OracleSource.QUOTE_ASSET,
|
|
36
|
+
mint: new web3_js_1.PublicKey('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'),
|
|
37
|
+
},
|
|
38
|
+
];
|
|
39
|
+
exports.Banks = {
|
|
40
|
+
devnet: exports.DevnetBanks,
|
|
41
|
+
'mainnet-beta': exports.MainnetBanks,
|
|
42
|
+
};
|
package/src/constants/banks.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { BN, OracleSource } from '../';
|
|
2
|
-
import { DriftEnv } from '../';
|
|
3
1
|
import { PublicKey } from '@solana/web3.js';
|
|
2
|
+
import { BN, DriftEnv, OracleSource } from '../';
|
|
4
3
|
|
|
5
4
|
export type BankConfig = {
|
|
6
5
|
symbol: string;
|
|
@@ -10,6 +9,10 @@ export type BankConfig = {
|
|
|
10
9
|
oracleSource: OracleSource;
|
|
11
10
|
};
|
|
12
11
|
|
|
12
|
+
export const WRAPPED_SOL_MINT = new PublicKey(
|
|
13
|
+
'So11111111111111111111111111111111111111112'
|
|
14
|
+
);
|
|
15
|
+
|
|
13
16
|
export const DevnetBanks: BankConfig[] = [
|
|
14
17
|
{
|
|
15
18
|
symbol: 'USDC',
|
|
@@ -23,7 +26,7 @@ export const DevnetBanks: BankConfig[] = [
|
|
|
23
26
|
bankIndex: new BN(1),
|
|
24
27
|
oracle: new PublicKey('J83w4HKfqxwcq3BEMMkPFSppX3gqekLyLJBexebFVkix'),
|
|
25
28
|
oracleSource: OracleSource.PYTH,
|
|
26
|
-
mint: new PublicKey(
|
|
29
|
+
mint: new PublicKey(WRAPPED_SOL_MINT),
|
|
27
30
|
},
|
|
28
31
|
{
|
|
29
32
|
symbol: 'BTC',
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Markets = exports.MainnetMarkets = exports.DevnetMarkets = void 0;
|
|
4
|
+
const __1 = require("../");
|
|
5
|
+
const web3_js_1 = require("@solana/web3.js");
|
|
6
|
+
exports.DevnetMarkets = [
|
|
7
|
+
{
|
|
8
|
+
fullName: 'Solana',
|
|
9
|
+
category: ['L1', 'Infra'],
|
|
10
|
+
symbol: 'SOL-PERP',
|
|
11
|
+
baseAssetSymbol: 'SOL',
|
|
12
|
+
marketIndex: new __1.BN(0),
|
|
13
|
+
oracle: new web3_js_1.PublicKey('J83w4HKfqxwcq3BEMMkPFSppX3gqekLyLJBexebFVkix'),
|
|
14
|
+
launchTs: 1655751353000,
|
|
15
|
+
oracleSource: __1.OracleSource.PYTH,
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
fullName: 'Bitcoin',
|
|
19
|
+
category: ['L1', 'Payment'],
|
|
20
|
+
symbol: 'BTC-PERP',
|
|
21
|
+
baseAssetSymbol: 'BTC',
|
|
22
|
+
marketIndex: new __1.BN(1),
|
|
23
|
+
oracle: new web3_js_1.PublicKey('HovQMDrbAgAYPCmHVSrezcSmkMtXSSUsLDFANExrZh2J'),
|
|
24
|
+
launchTs: 1655751353000,
|
|
25
|
+
oracleSource: __1.OracleSource.PYTH,
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
fullName: 'Ethereum',
|
|
29
|
+
category: ['L1', 'Infra'],
|
|
30
|
+
symbol: 'ETH-PERP',
|
|
31
|
+
baseAssetSymbol: 'ETH',
|
|
32
|
+
marketIndex: new __1.BN(2),
|
|
33
|
+
oracle: new web3_js_1.PublicKey('EdVCmQ9FSPcVe5YySXDPCRmc8aDQLKJ9xvYBMZPie1Vw'),
|
|
34
|
+
launchTs: 1637691133472,
|
|
35
|
+
oracleSource: __1.OracleSource.PYTH,
|
|
36
|
+
},
|
|
37
|
+
];
|
|
38
|
+
exports.MainnetMarkets = [];
|
|
39
|
+
exports.Markets = {
|
|
40
|
+
devnet: exports.DevnetMarkets,
|
|
41
|
+
'mainnet-beta': [],
|
|
42
|
+
};
|