@drift-labs/sdk 2.49.0-beta.3 → 2.49.0-beta.4
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 +1 -1
- package/lib/dlob/DLOB.d.ts +6 -2
- package/lib/dlob/DLOB.js +37 -12
- package/lib/types.d.ts +0 -2
- package/package.json +1 -1
- package/src/dlob/DLOB.ts +55 -15
- package/src/types.ts +0 -2
- package/tests/dlob/helpers.ts +2 -6
- package/tests/dlob/test.ts +190 -0
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.49.0-beta.
|
|
1
|
+
2.49.0-beta.4
|
package/lib/dlob/DLOB.d.ts
CHANGED
|
@@ -68,11 +68,15 @@ export declare class DLOB {
|
|
|
68
68
|
updateRestingLimitOrdersForMarketType(slot: number, marketTypeStr: MarketTypeStr): void;
|
|
69
69
|
getOrder(orderId: number, userAccount: PublicKey): Order | undefined;
|
|
70
70
|
findNodesToFill(marketIndex: number, fallbackBid: BN | undefined, fallbackAsk: BN | undefined, slot: number, ts: number, marketType: MarketType, oraclePriceData: OraclePriceData, stateAccount: StateAccount, marketAccount: PerpMarketAccount | SpotMarketAccount): NodeToFill[];
|
|
71
|
+
getMakerRebate(marketType: MarketType, stateAccount: StateAccount, marketAccount: PerpMarketAccount | SpotMarketAccount): {
|
|
72
|
+
makerRebateNumerator: number;
|
|
73
|
+
makerRebateDenominator: number;
|
|
74
|
+
};
|
|
71
75
|
mergeNodesToFill(restingLimitOrderNodesToFill: NodeToFill[], takingOrderNodesToFill: NodeToFill[]): NodeToFill[];
|
|
72
|
-
findRestingLimitOrderNodesToFill(marketIndex: number, slot: number, marketType: MarketType, oraclePriceData: OraclePriceData, isAmmPaused: boolean, minAuctionDuration: number, fallbackAsk: BN | undefined, fallbackBid: BN | undefined): NodeToFill[];
|
|
76
|
+
findRestingLimitOrderNodesToFill(marketIndex: number, slot: number, marketType: MarketType, oraclePriceData: OraclePriceData, isAmmPaused: boolean, minAuctionDuration: number, makerRebateNumerator: number, makerRebateDenominator: number, fallbackAsk: BN | undefined, fallbackBid: BN | undefined): NodeToFill[];
|
|
73
77
|
findTakingNodesToFill(marketIndex: number, slot: number, marketType: MarketType, oraclePriceData: OraclePriceData, isAmmPaused: boolean, minAuctionDuration: number, fallbackAsk: BN | undefined, fallbackBid?: BN | undefined): NodeToFill[];
|
|
74
78
|
findTakingNodesCrossingMakerNodes(marketIndex: number, slot: number, marketType: MarketType, oraclePriceData: OraclePriceData, takerNodeGenerator: Generator<DLOBNode>, makerNodeGeneratorFn: (marketIndex: number, slot: number, marketType: MarketType, oraclePriceData: OraclePriceData) => Generator<DLOBNode>, doesCross: (takerPrice: BN | undefined, makerPrice: BN) => boolean): NodeToFill[];
|
|
75
|
-
findNodesCrossingFallbackLiquidity(marketType: MarketType, slot: number, oraclePriceData: OraclePriceData, nodeGenerator: Generator<DLOBNode>,
|
|
79
|
+
findNodesCrossingFallbackLiquidity(marketType: MarketType, slot: number, oraclePriceData: OraclePriceData, nodeGenerator: Generator<DLOBNode>, doesCross: (nodePrice: BN | undefined) => boolean, minAuctionDuration: number): NodeToFill[];
|
|
76
80
|
findExpiredNodesToFill(marketIndex: number, ts: number, marketType: MarketType): NodeToFill[];
|
|
77
81
|
findJitAuctionNodesToFill(marketIndex: number, slot: number, oraclePriceData: OraclePriceData, marketType: MarketType): NodeToFill[];
|
|
78
82
|
getTakingBids(marketIndex: number, marketType: MarketType, slot: number, oraclePriceData: OraclePriceData): Generator<DLOBNode>;
|
package/lib/dlob/DLOB.js
CHANGED
|
@@ -304,7 +304,8 @@ class DLOB {
|
|
|
304
304
|
const minAuctionDuration = (0, __1.isVariant)(marketType, 'perp')
|
|
305
305
|
? stateAccount.minPerpAuctionDuration
|
|
306
306
|
: 0;
|
|
307
|
-
const
|
|
307
|
+
const { makerRebateNumerator, makerRebateDenominator } = this.getMakerRebate(marketType, stateAccount, marketAccount);
|
|
308
|
+
const restingLimitOrderNodesToFill = this.findRestingLimitOrderNodesToFill(marketIndex, slot, marketType, oraclePriceData, isAmmPaused, minAuctionDuration, makerRebateNumerator, makerRebateDenominator, fallbackAsk, fallbackBid);
|
|
308
309
|
const takingOrderNodesToFill = this.findTakingNodesToFill(marketIndex, slot, marketType, oraclePriceData, isAmmPaused, minAuctionDuration, fallbackAsk, fallbackBid);
|
|
309
310
|
// get expired market nodes
|
|
310
311
|
const expiredNodesToFill = this.findExpiredNodesToFill(marketIndex, ts, marketType);
|
|
@@ -314,6 +315,28 @@ class DLOB {
|
|
|
314
315
|
}
|
|
315
316
|
return this.mergeNodesToFill(restingLimitOrderNodesToFill, takingOrderNodesToFill).concat(expiredNodesToFill);
|
|
316
317
|
}
|
|
318
|
+
getMakerRebate(marketType, stateAccount, marketAccount) {
|
|
319
|
+
let makerRebateNumerator;
|
|
320
|
+
let makerRebateDenominator;
|
|
321
|
+
if ((0, __1.isVariant)(marketType, 'perp')) {
|
|
322
|
+
makerRebateNumerator =
|
|
323
|
+
stateAccount.perpFeeStructure.feeTiers[0].makerRebateNumerator;
|
|
324
|
+
makerRebateDenominator =
|
|
325
|
+
stateAccount.perpFeeStructure.feeTiers[0].makerRebateDenominator;
|
|
326
|
+
}
|
|
327
|
+
else {
|
|
328
|
+
makerRebateNumerator =
|
|
329
|
+
stateAccount.spotFeeStructure.feeTiers[0].makerRebateNumerator;
|
|
330
|
+
makerRebateDenominator =
|
|
331
|
+
stateAccount.spotFeeStructure.feeTiers[0].makerRebateDenominator;
|
|
332
|
+
}
|
|
333
|
+
// @ts-ignore
|
|
334
|
+
const feeAdjustment = marketAccount.feeAdjustment || 0;
|
|
335
|
+
if (feeAdjustment !== 0) {
|
|
336
|
+
makerRebateNumerator += (makerRebateNumerator * feeAdjustment) / 100;
|
|
337
|
+
}
|
|
338
|
+
return { makerRebateNumerator, makerRebateDenominator };
|
|
339
|
+
}
|
|
317
340
|
mergeNodesToFill(restingLimitOrderNodesToFill, takingOrderNodesToFill) {
|
|
318
341
|
const mergedNodesToFill = new Map();
|
|
319
342
|
const mergeNodesToFillHelper = (nodesToFillArray) => {
|
|
@@ -336,7 +359,7 @@ class DLOB {
|
|
|
336
359
|
mergeNodesToFillHelper(takingOrderNodesToFill);
|
|
337
360
|
return Array.from(mergedNodesToFill.values());
|
|
338
361
|
}
|
|
339
|
-
findRestingLimitOrderNodesToFill(marketIndex, slot, marketType, oraclePriceData, isAmmPaused, minAuctionDuration, fallbackAsk, fallbackBid) {
|
|
362
|
+
findRestingLimitOrderNodesToFill(marketIndex, slot, marketType, oraclePriceData, isAmmPaused, minAuctionDuration, makerRebateNumerator, makerRebateDenominator, fallbackAsk, fallbackBid) {
|
|
340
363
|
const nodesToFill = new Array();
|
|
341
364
|
const crossingNodes = this.findCrossingRestingLimitOrders(marketIndex, slot, marketType, oraclePriceData);
|
|
342
365
|
for (const crossingNode of crossingNodes) {
|
|
@@ -344,8 +367,9 @@ class DLOB {
|
|
|
344
367
|
}
|
|
345
368
|
if (fallbackBid && !isAmmPaused) {
|
|
346
369
|
const askGenerator = this.getRestingLimitAsks(marketIndex, slot, marketType, oraclePriceData);
|
|
347
|
-
const
|
|
348
|
-
|
|
370
|
+
const fallbackBidWithBuffer = fallbackBid.sub(fallbackBid.muln(makerRebateNumerator).divn(makerRebateDenominator));
|
|
371
|
+
const asksCrossingFallback = this.findNodesCrossingFallbackLiquidity(marketType, slot, oraclePriceData, askGenerator, (askPrice) => {
|
|
372
|
+
return askPrice.lte(fallbackBidWithBuffer);
|
|
349
373
|
}, minAuctionDuration);
|
|
350
374
|
for (const askCrossingFallback of asksCrossingFallback) {
|
|
351
375
|
nodesToFill.push(askCrossingFallback);
|
|
@@ -353,8 +377,9 @@ class DLOB {
|
|
|
353
377
|
}
|
|
354
378
|
if (fallbackAsk && !isAmmPaused) {
|
|
355
379
|
const bidGenerator = this.getRestingLimitBids(marketIndex, slot, marketType, oraclePriceData);
|
|
356
|
-
const
|
|
357
|
-
|
|
380
|
+
const fallbackAskWithBuffer = fallbackAsk.add(fallbackAsk.muln(makerRebateNumerator).divn(makerRebateDenominator));
|
|
381
|
+
const bidsCrossingFallback = this.findNodesCrossingFallbackLiquidity(marketType, slot, oraclePriceData, bidGenerator, (bidPrice) => {
|
|
382
|
+
return bidPrice.gte(fallbackAskWithBuffer);
|
|
358
383
|
}, minAuctionDuration);
|
|
359
384
|
for (const bidCrossingFallback of bidsCrossingFallback) {
|
|
360
385
|
nodesToFill.push(bidCrossingFallback);
|
|
@@ -381,8 +406,8 @@ class DLOB {
|
|
|
381
406
|
}
|
|
382
407
|
if (fallbackBid && !isAmmPaused) {
|
|
383
408
|
takingOrderGenerator = this.getTakingAsks(marketIndex, marketType, slot, oraclePriceData);
|
|
384
|
-
const takingAsksCrossingFallback = this.findNodesCrossingFallbackLiquidity(marketType, slot, oraclePriceData, takingOrderGenerator,
|
|
385
|
-
return takerPrice === undefined || takerPrice.lte(
|
|
409
|
+
const takingAsksCrossingFallback = this.findNodesCrossingFallbackLiquidity(marketType, slot, oraclePriceData, takingOrderGenerator, (takerPrice) => {
|
|
410
|
+
return takerPrice === undefined || takerPrice.lte(fallbackBid);
|
|
386
411
|
}, minAuctionDuration);
|
|
387
412
|
for (const takingAskCrossingFallback of takingAsksCrossingFallback) {
|
|
388
413
|
nodesToFill.push(takingAskCrossingFallback);
|
|
@@ -405,8 +430,8 @@ class DLOB {
|
|
|
405
430
|
}
|
|
406
431
|
if (fallbackAsk && !isAmmPaused) {
|
|
407
432
|
takingOrderGenerator = this.getTakingBids(marketIndex, marketType, slot, oraclePriceData);
|
|
408
|
-
const takingBidsCrossingFallback = this.findNodesCrossingFallbackLiquidity(marketType, slot, oraclePriceData, takingOrderGenerator,
|
|
409
|
-
return takerPrice === undefined || takerPrice.gte(
|
|
433
|
+
const takingBidsCrossingFallback = this.findNodesCrossingFallbackLiquidity(marketType, slot, oraclePriceData, takingOrderGenerator, (takerPrice) => {
|
|
434
|
+
return takerPrice === undefined || takerPrice.gte(fallbackAsk);
|
|
410
435
|
}, minAuctionDuration);
|
|
411
436
|
for (const marketBidCrossingFallback of takingBidsCrossingFallback) {
|
|
412
437
|
nodesToFill.push(marketBidCrossingFallback);
|
|
@@ -456,7 +481,7 @@ class DLOB {
|
|
|
456
481
|
}
|
|
457
482
|
return nodesToFill;
|
|
458
483
|
}
|
|
459
|
-
findNodesCrossingFallbackLiquidity(marketType, slot, oraclePriceData, nodeGenerator,
|
|
484
|
+
findNodesCrossingFallbackLiquidity(marketType, slot, oraclePriceData, nodeGenerator, doesCross, minAuctionDuration) {
|
|
460
485
|
var _a;
|
|
461
486
|
const nodesToFill = new Array();
|
|
462
487
|
let nextNode = nodeGenerator.next();
|
|
@@ -468,7 +493,7 @@ class DLOB {
|
|
|
468
493
|
}
|
|
469
494
|
const nodePrice = (0, __1.getLimitPrice)(node.order, oraclePriceData, slot);
|
|
470
495
|
// order crosses if there is no limit price or it crosses fallback price
|
|
471
|
-
const crosses = doesCross(nodePrice
|
|
496
|
+
const crosses = doesCross(nodePrice);
|
|
472
497
|
// fallback is available if auction is complete or it's a spot order
|
|
473
498
|
const fallbackAvailable = (0, __1.isVariant)(marketType, 'spot') ||
|
|
474
499
|
(0, __1.isFallbackAvailableLiquiditySource)(node.order, minAuctionDuration, slot);
|
package/lib/types.d.ts
CHANGED
|
@@ -1025,8 +1025,6 @@ export interface IVersionedWallet {
|
|
|
1025
1025
|
}
|
|
1026
1026
|
export type FeeStructure = {
|
|
1027
1027
|
feeTiers: FeeTier[];
|
|
1028
|
-
makerRebateNumerator: BN;
|
|
1029
|
-
makerRebateDenominator: BN;
|
|
1030
1028
|
fillerRewardStructure: OrderFillerRewardStructure;
|
|
1031
1029
|
flatFillerFee: BN;
|
|
1032
1030
|
referrerRewardEpochUpperBound: BN;
|
package/package.json
CHANGED
package/src/dlob/DLOB.ts
CHANGED
|
@@ -504,6 +504,9 @@ export class DLOB {
|
|
|
504
504
|
? stateAccount.minPerpAuctionDuration
|
|
505
505
|
: 0;
|
|
506
506
|
|
|
507
|
+
const { makerRebateNumerator, makerRebateDenominator } =
|
|
508
|
+
this.getMakerRebate(marketType, stateAccount, marketAccount);
|
|
509
|
+
|
|
507
510
|
const restingLimitOrderNodesToFill: Array<NodeToFill> =
|
|
508
511
|
this.findRestingLimitOrderNodesToFill(
|
|
509
512
|
marketIndex,
|
|
@@ -512,6 +515,8 @@ export class DLOB {
|
|
|
512
515
|
oraclePriceData,
|
|
513
516
|
isAmmPaused,
|
|
514
517
|
minAuctionDuration,
|
|
518
|
+
makerRebateNumerator,
|
|
519
|
+
makerRebateDenominator,
|
|
515
520
|
fallbackAsk,
|
|
516
521
|
fallbackBid
|
|
517
522
|
);
|
|
@@ -549,6 +554,34 @@ export class DLOB {
|
|
|
549
554
|
).concat(expiredNodesToFill);
|
|
550
555
|
}
|
|
551
556
|
|
|
557
|
+
getMakerRebate(
|
|
558
|
+
marketType: MarketType,
|
|
559
|
+
stateAccount: StateAccount,
|
|
560
|
+
marketAccount: PerpMarketAccount | SpotMarketAccount
|
|
561
|
+
): { makerRebateNumerator: number; makerRebateDenominator: number } {
|
|
562
|
+
let makerRebateNumerator: number;
|
|
563
|
+
let makerRebateDenominator: number;
|
|
564
|
+
if (isVariant(marketType, 'perp')) {
|
|
565
|
+
makerRebateNumerator =
|
|
566
|
+
stateAccount.perpFeeStructure.feeTiers[0].makerRebateNumerator;
|
|
567
|
+
makerRebateDenominator =
|
|
568
|
+
stateAccount.perpFeeStructure.feeTiers[0].makerRebateDenominator;
|
|
569
|
+
} else {
|
|
570
|
+
makerRebateNumerator =
|
|
571
|
+
stateAccount.spotFeeStructure.feeTiers[0].makerRebateNumerator;
|
|
572
|
+
makerRebateDenominator =
|
|
573
|
+
stateAccount.spotFeeStructure.feeTiers[0].makerRebateDenominator;
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
// @ts-ignore
|
|
577
|
+
const feeAdjustment = marketAccount.feeAdjustment || 0;
|
|
578
|
+
if (feeAdjustment !== 0) {
|
|
579
|
+
makerRebateNumerator += (makerRebateNumerator * feeAdjustment) / 100;
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
return { makerRebateNumerator, makerRebateDenominator };
|
|
583
|
+
}
|
|
584
|
+
|
|
552
585
|
mergeNodesToFill(
|
|
553
586
|
restingLimitOrderNodesToFill: NodeToFill[],
|
|
554
587
|
takingOrderNodesToFill: NodeToFill[]
|
|
@@ -590,6 +623,8 @@ export class DLOB {
|
|
|
590
623
|
oraclePriceData: OraclePriceData,
|
|
591
624
|
isAmmPaused: boolean,
|
|
592
625
|
minAuctionDuration: number,
|
|
626
|
+
makerRebateNumerator: number,
|
|
627
|
+
makerRebateDenominator: number,
|
|
593
628
|
fallbackAsk: BN | undefined,
|
|
594
629
|
fallbackBid: BN | undefined
|
|
595
630
|
): NodeToFill[] {
|
|
@@ -613,14 +648,18 @@ export class DLOB {
|
|
|
613
648
|
marketType,
|
|
614
649
|
oraclePriceData
|
|
615
650
|
);
|
|
651
|
+
|
|
652
|
+
const fallbackBidWithBuffer = fallbackBid.sub(
|
|
653
|
+
fallbackBid.muln(makerRebateNumerator).divn(makerRebateDenominator)
|
|
654
|
+
);
|
|
655
|
+
|
|
616
656
|
const asksCrossingFallback = this.findNodesCrossingFallbackLiquidity(
|
|
617
657
|
marketType,
|
|
618
658
|
slot,
|
|
619
659
|
oraclePriceData,
|
|
620
660
|
askGenerator,
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
return askPrice.lte(fallbackPrice);
|
|
661
|
+
(askPrice) => {
|
|
662
|
+
return askPrice.lte(fallbackBidWithBuffer);
|
|
624
663
|
},
|
|
625
664
|
minAuctionDuration
|
|
626
665
|
);
|
|
@@ -637,14 +676,18 @@ export class DLOB {
|
|
|
637
676
|
marketType,
|
|
638
677
|
oraclePriceData
|
|
639
678
|
);
|
|
679
|
+
|
|
680
|
+
const fallbackAskWithBuffer = fallbackAsk.add(
|
|
681
|
+
fallbackAsk.muln(makerRebateNumerator).divn(makerRebateDenominator)
|
|
682
|
+
);
|
|
683
|
+
|
|
640
684
|
const bidsCrossingFallback = this.findNodesCrossingFallbackLiquidity(
|
|
641
685
|
marketType,
|
|
642
686
|
slot,
|
|
643
687
|
oraclePriceData,
|
|
644
688
|
bidGenerator,
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
return bidPrice.gte(fallbackPrice);
|
|
689
|
+
(bidPrice) => {
|
|
690
|
+
return bidPrice.gte(fallbackAskWithBuffer);
|
|
648
691
|
},
|
|
649
692
|
minAuctionDuration
|
|
650
693
|
);
|
|
@@ -713,9 +756,8 @@ export class DLOB {
|
|
|
713
756
|
slot,
|
|
714
757
|
oraclePriceData,
|
|
715
758
|
takingOrderGenerator,
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
return takerPrice === undefined || takerPrice.lte(fallbackPrice);
|
|
759
|
+
(takerPrice) => {
|
|
760
|
+
return takerPrice === undefined || takerPrice.lte(fallbackBid);
|
|
719
761
|
},
|
|
720
762
|
minAuctionDuration
|
|
721
763
|
);
|
|
@@ -771,9 +813,8 @@ export class DLOB {
|
|
|
771
813
|
slot,
|
|
772
814
|
oraclePriceData,
|
|
773
815
|
takingOrderGenerator,
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
return takerPrice === undefined || takerPrice.gte(fallbackPrice);
|
|
816
|
+
(takerPrice) => {
|
|
817
|
+
return takerPrice === undefined || takerPrice.gte(fallbackAsk);
|
|
777
818
|
},
|
|
778
819
|
minAuctionDuration
|
|
779
820
|
);
|
|
@@ -875,8 +916,7 @@ export class DLOB {
|
|
|
875
916
|
slot: number,
|
|
876
917
|
oraclePriceData: OraclePriceData,
|
|
877
918
|
nodeGenerator: Generator<DLOBNode>,
|
|
878
|
-
|
|
879
|
-
doesCross: (nodePrice: BN | undefined, fallbackPrice: BN) => boolean,
|
|
919
|
+
doesCross: (nodePrice: BN | undefined) => boolean,
|
|
880
920
|
minAuctionDuration: number
|
|
881
921
|
): NodeToFill[] {
|
|
882
922
|
const nodesToFill = new Array<NodeToFill>();
|
|
@@ -893,7 +933,7 @@ export class DLOB {
|
|
|
893
933
|
const nodePrice = getLimitPrice(node.order, oraclePriceData, slot);
|
|
894
934
|
|
|
895
935
|
// order crosses if there is no limit price or it crosses fallback price
|
|
896
|
-
const crosses = doesCross(nodePrice
|
|
936
|
+
const crosses = doesCross(nodePrice);
|
|
897
937
|
|
|
898
938
|
// fallback is available if auction is complete or it's a spot order
|
|
899
939
|
const fallbackAvailable =
|
package/src/types.ts
CHANGED
|
@@ -1000,8 +1000,6 @@ export interface IVersionedWallet {
|
|
|
1000
1000
|
|
|
1001
1001
|
export type FeeStructure = {
|
|
1002
1002
|
feeTiers: FeeTier[];
|
|
1003
|
-
makerRebateNumerator: BN;
|
|
1004
|
-
makerRebateDenominator: BN;
|
|
1005
1003
|
fillerRewardStructure: OrderFillerRewardStructure;
|
|
1006
1004
|
flatFillerFee: BN;
|
|
1007
1005
|
referrerRewardEpochUpperBound: BN;
|
package/tests/dlob/helpers.ts
CHANGED
|
@@ -539,15 +539,13 @@ export const mockStateAccount: StateAccount = {
|
|
|
539
539
|
feeNumerator: 0,
|
|
540
540
|
feeDenominator: 0,
|
|
541
541
|
makerRebateNumerator: 0,
|
|
542
|
-
makerRebateDenominator:
|
|
542
|
+
makerRebateDenominator: 1,
|
|
543
543
|
referrerRewardNumerator: 0,
|
|
544
544
|
referrerRewardDenominator: 0,
|
|
545
545
|
refereeFeeNumerator: 0,
|
|
546
546
|
refereeFeeDenominator: 0,
|
|
547
547
|
},
|
|
548
548
|
],
|
|
549
|
-
makerRebateNumerator: new BN(0),
|
|
550
|
-
makerRebateDenominator: new BN(0),
|
|
551
549
|
fillerRewardStructure: {
|
|
552
550
|
rewardNumerator: new BN(0),
|
|
553
551
|
rewardDenominator: new BN(0),
|
|
@@ -565,15 +563,13 @@ export const mockStateAccount: StateAccount = {
|
|
|
565
563
|
feeNumerator: 0,
|
|
566
564
|
feeDenominator: 0,
|
|
567
565
|
makerRebateNumerator: 0,
|
|
568
|
-
makerRebateDenominator:
|
|
566
|
+
makerRebateDenominator: 1,
|
|
569
567
|
referrerRewardNumerator: 0,
|
|
570
568
|
referrerRewardDenominator: 0,
|
|
571
569
|
refereeFeeNumerator: 0,
|
|
572
570
|
refereeFeeDenominator: 0,
|
|
573
571
|
},
|
|
574
572
|
],
|
|
575
|
-
makerRebateNumerator: new BN(0),
|
|
576
|
-
makerRebateDenominator: new BN(0),
|
|
577
573
|
fillerRewardStructure: {
|
|
578
574
|
rewardNumerator: new BN(0),
|
|
579
575
|
rewardDenominator: new BN(0),
|
package/tests/dlob/test.ts
CHANGED
|
@@ -1914,6 +1914,8 @@ describe('DLOB Perp Tests', () => {
|
|
|
1914
1914
|
},
|
|
1915
1915
|
false,
|
|
1916
1916
|
10,
|
|
1917
|
+
0,
|
|
1918
|
+
1,
|
|
1917
1919
|
undefined,
|
|
1918
1920
|
undefined
|
|
1919
1921
|
);
|
|
@@ -2059,6 +2061,8 @@ describe('DLOB Perp Tests', () => {
|
|
|
2059
2061
|
},
|
|
2060
2062
|
false,
|
|
2061
2063
|
10,
|
|
2064
|
+
0,
|
|
2065
|
+
1,
|
|
2062
2066
|
undefined,
|
|
2063
2067
|
undefined
|
|
2064
2068
|
);
|
|
@@ -2267,6 +2271,190 @@ describe('DLOB Perp Tests', () => {
|
|
|
2267
2271
|
expect(nodesToFillAfter[1].makerNodes[0]?.order?.orderId).to.equal(3);
|
|
2268
2272
|
});
|
|
2269
2273
|
|
|
2274
|
+
it('Test post only bid fills against fallback', async () => {
|
|
2275
|
+
const vAsk = new BN(150);
|
|
2276
|
+
const vBid = new BN(100);
|
|
2277
|
+
|
|
2278
|
+
const user0 = Keypair.generate();
|
|
2279
|
+
|
|
2280
|
+
const dlob = new DLOB();
|
|
2281
|
+
const marketIndex = 0;
|
|
2282
|
+
|
|
2283
|
+
const makerRebateNumerator = 1;
|
|
2284
|
+
const makerRebateDenominator = 10;
|
|
2285
|
+
|
|
2286
|
+
// post only bid same as ask
|
|
2287
|
+
insertOrderToDLOB(
|
|
2288
|
+
dlob,
|
|
2289
|
+
user0.publicKey,
|
|
2290
|
+
OrderType.LIMIT,
|
|
2291
|
+
MarketType.PERP,
|
|
2292
|
+
1, // orderId
|
|
2293
|
+
marketIndex,
|
|
2294
|
+
vAsk, // same price as vAsk
|
|
2295
|
+
BASE_PRECISION, // quantity
|
|
2296
|
+
PositionDirection.LONG,
|
|
2297
|
+
vBid,
|
|
2298
|
+
vAsk,
|
|
2299
|
+
undefined,
|
|
2300
|
+
undefined,
|
|
2301
|
+
undefined,
|
|
2302
|
+
true
|
|
2303
|
+
);
|
|
2304
|
+
|
|
2305
|
+
// should have no crossing orders
|
|
2306
|
+
const nodesToFillBefore = dlob.findRestingLimitOrderNodesToFill(
|
|
2307
|
+
marketIndex,
|
|
2308
|
+
12, // auction over
|
|
2309
|
+
MarketType.PERP,
|
|
2310
|
+
{
|
|
2311
|
+
price: vBid.add(vAsk).div(new BN(2)),
|
|
2312
|
+
slot: new BN(12),
|
|
2313
|
+
confidence: new BN(1),
|
|
2314
|
+
hasSufficientNumberOfDataPoints: true,
|
|
2315
|
+
},
|
|
2316
|
+
false,
|
|
2317
|
+
10,
|
|
2318
|
+
makerRebateNumerator,
|
|
2319
|
+
makerRebateDenominator,
|
|
2320
|
+
vAsk,
|
|
2321
|
+
vBid
|
|
2322
|
+
);
|
|
2323
|
+
expect(nodesToFillBefore.length).to.equal(0);
|
|
2324
|
+
|
|
2325
|
+
// post only bid crosses ask
|
|
2326
|
+
const price = vAsk.add(vAsk.muln(makerRebateNumerator).divn(makerRebateDenominator));
|
|
2327
|
+
insertOrderToDLOB(
|
|
2328
|
+
dlob,
|
|
2329
|
+
user0.publicKey,
|
|
2330
|
+
OrderType.LIMIT,
|
|
2331
|
+
MarketType.PERP,
|
|
2332
|
+
2, // orderId
|
|
2333
|
+
marketIndex,
|
|
2334
|
+
price, // crosses vask
|
|
2335
|
+
BASE_PRECISION, // quantity
|
|
2336
|
+
PositionDirection.LONG,
|
|
2337
|
+
vBid,
|
|
2338
|
+
vAsk,
|
|
2339
|
+
undefined,
|
|
2340
|
+
undefined,
|
|
2341
|
+
undefined,
|
|
2342
|
+
true
|
|
2343
|
+
);
|
|
2344
|
+
|
|
2345
|
+
// should have no crossing orders
|
|
2346
|
+
const nodesToFillAfter = dlob.findRestingLimitOrderNodesToFill(
|
|
2347
|
+
marketIndex,
|
|
2348
|
+
12, // auction over
|
|
2349
|
+
MarketType.PERP,
|
|
2350
|
+
{
|
|
2351
|
+
price: vBid.add(vAsk).div(new BN(2)),
|
|
2352
|
+
slot: new BN(12),
|
|
2353
|
+
confidence: new BN(1),
|
|
2354
|
+
hasSufficientNumberOfDataPoints: true,
|
|
2355
|
+
},
|
|
2356
|
+
false,
|
|
2357
|
+
10,
|
|
2358
|
+
makerRebateNumerator,
|
|
2359
|
+
makerRebateDenominator,
|
|
2360
|
+
vAsk,
|
|
2361
|
+
vBid
|
|
2362
|
+
);
|
|
2363
|
+
expect(nodesToFillAfter.length).to.equal(1);
|
|
2364
|
+
});
|
|
2365
|
+
|
|
2366
|
+
it('Test post only ask fills against fallback', async () => {
|
|
2367
|
+
const vAsk = new BN(150);
|
|
2368
|
+
const vBid = new BN(100);
|
|
2369
|
+
|
|
2370
|
+
const user0 = Keypair.generate();
|
|
2371
|
+
|
|
2372
|
+
const dlob = new DLOB();
|
|
2373
|
+
const marketIndex = 0;
|
|
2374
|
+
|
|
2375
|
+
const makerRebateNumerator = 1;
|
|
2376
|
+
const makerRebateDenominator = 10;
|
|
2377
|
+
|
|
2378
|
+
// post only bid same as ask
|
|
2379
|
+
insertOrderToDLOB(
|
|
2380
|
+
dlob,
|
|
2381
|
+
user0.publicKey,
|
|
2382
|
+
OrderType.LIMIT,
|
|
2383
|
+
MarketType.PERP,
|
|
2384
|
+
1, // orderId
|
|
2385
|
+
marketIndex,
|
|
2386
|
+
vBid, // same price as vAsk
|
|
2387
|
+
BASE_PRECISION, // quantity
|
|
2388
|
+
PositionDirection.SHORT,
|
|
2389
|
+
vBid,
|
|
2390
|
+
vAsk,
|
|
2391
|
+
undefined,
|
|
2392
|
+
undefined,
|
|
2393
|
+
undefined,
|
|
2394
|
+
true
|
|
2395
|
+
);
|
|
2396
|
+
|
|
2397
|
+
// should have no crossing orders
|
|
2398
|
+
const nodesToFillBefore = dlob.findRestingLimitOrderNodesToFill(
|
|
2399
|
+
marketIndex,
|
|
2400
|
+
12, // auction over
|
|
2401
|
+
MarketType.PERP,
|
|
2402
|
+
{
|
|
2403
|
+
price: vBid.add(vAsk).div(new BN(2)),
|
|
2404
|
+
slot: new BN(12),
|
|
2405
|
+
confidence: new BN(1),
|
|
2406
|
+
hasSufficientNumberOfDataPoints: true,
|
|
2407
|
+
},
|
|
2408
|
+
false,
|
|
2409
|
+
10,
|
|
2410
|
+
makerRebateNumerator,
|
|
2411
|
+
makerRebateDenominator,
|
|
2412
|
+
vAsk,
|
|
2413
|
+
vBid
|
|
2414
|
+
);
|
|
2415
|
+
expect(nodesToFillBefore.length).to.equal(0);
|
|
2416
|
+
|
|
2417
|
+
// post only bid crosses ask
|
|
2418
|
+
const price = vBid.sub(vAsk.muln(makerRebateNumerator).divn(makerRebateDenominator));
|
|
2419
|
+
insertOrderToDLOB(
|
|
2420
|
+
dlob,
|
|
2421
|
+
user0.publicKey,
|
|
2422
|
+
OrderType.LIMIT,
|
|
2423
|
+
MarketType.PERP,
|
|
2424
|
+
2, // orderId
|
|
2425
|
+
marketIndex,
|
|
2426
|
+
price, // crosses vask
|
|
2427
|
+
BASE_PRECISION, // quantity
|
|
2428
|
+
PositionDirection.SHORT,
|
|
2429
|
+
vBid,
|
|
2430
|
+
vAsk,
|
|
2431
|
+
undefined,
|
|
2432
|
+
undefined,
|
|
2433
|
+
undefined,
|
|
2434
|
+
true
|
|
2435
|
+
);
|
|
2436
|
+
|
|
2437
|
+
// should have no crossing orders
|
|
2438
|
+
const nodesToFillAfter = dlob.findRestingLimitOrderNodesToFill(
|
|
2439
|
+
marketIndex,
|
|
2440
|
+
12, // auction over
|
|
2441
|
+
MarketType.PERP,
|
|
2442
|
+
{
|
|
2443
|
+
price: vBid.add(vAsk).div(new BN(2)),
|
|
2444
|
+
slot: new BN(12),
|
|
2445
|
+
confidence: new BN(1),
|
|
2446
|
+
hasSufficientNumberOfDataPoints: true,
|
|
2447
|
+
},
|
|
2448
|
+
false,
|
|
2449
|
+
10,
|
|
2450
|
+
makerRebateNumerator,
|
|
2451
|
+
makerRebateDenominator,
|
|
2452
|
+
vAsk,
|
|
2453
|
+
vBid
|
|
2454
|
+
);
|
|
2455
|
+
expect(nodesToFillAfter.length).to.equal(1);
|
|
2456
|
+
});
|
|
2457
|
+
|
|
2270
2458
|
it('Test trigger orders', () => {
|
|
2271
2459
|
const vAsk = new BN(15);
|
|
2272
2460
|
const vBid = new BN(8);
|
|
@@ -2901,6 +3089,8 @@ describe('DLOB Perp Tests', () => {
|
|
|
2901
3089
|
oracle,
|
|
2902
3090
|
false,
|
|
2903
3091
|
10,
|
|
3092
|
+
0,
|
|
3093
|
+
1,
|
|
2904
3094
|
undefined,
|
|
2905
3095
|
undefined
|
|
2906
3096
|
);
|