@drift-labs/sdk 2.17.0 → 2.18.0-beta.1

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.
@@ -41,14 +41,16 @@ function insertOrderToDLOB(
41
41
  slot?: BN,
42
42
  maxTs = ZERO,
43
43
  oraclePriceOffset = new BN(0),
44
- postOnly = false
44
+ postOnly = false,
45
+ auctionDuration = 10
45
46
  ) {
47
+ slot = slot || new BN(1);
46
48
  dlob.insertOrder(
47
49
  {
48
50
  status: OrderStatus.OPEN,
49
51
  orderType,
50
52
  marketType,
51
- slot: slot || new BN(1),
53
+ slot,
52
54
  orderId,
53
55
  userOrderId: 0,
54
56
  marketIndex,
@@ -65,12 +67,13 @@ function insertOrderToDLOB(
65
67
  postOnly,
66
68
  immediateOrCancel: false,
67
69
  oraclePriceOffset: oraclePriceOffset.toNumber(),
68
- auctionDuration: 10,
70
+ auctionDuration,
69
71
  auctionStartPrice,
70
72
  auctionEndPrice,
71
73
  maxTs,
72
74
  },
73
- userAccount
75
+ userAccount,
76
+ slot.toNumber()
74
77
  );
75
78
  }
76
79
 
@@ -92,12 +95,13 @@ function insertTriggerOrderToDLOB(
92
95
  maxTs = ZERO,
93
96
  oraclePriceOffset = new BN(0)
94
97
  ) {
98
+ slot = slot || new BN(1);
95
99
  dlob.insertOrder(
96
100
  {
97
101
  status: OrderStatus.OPEN,
98
102
  orderType,
99
103
  marketType,
100
- slot: slot || new BN(1),
104
+ slot,
101
105
  orderId,
102
106
  userOrderId: 0,
103
107
  marketIndex,
@@ -119,7 +123,8 @@ function insertTriggerOrderToDLOB(
119
123
  auctionEndPrice,
120
124
  maxTs,
121
125
  },
122
- userAccount
126
+ userAccount,
127
+ slot.toNumber()
123
128
  );
124
129
  }
125
130
 
@@ -545,6 +550,266 @@ describe('DLOB Tests', () => {
545
550
  true
546
551
  );
547
552
  });
553
+
554
+ it('DLOB update resting limit orders bids', () => {
555
+ const vAsk = new BN(15);
556
+ const vBid = new BN(10);
557
+
558
+ let slot = 1;
559
+ const oracle = {
560
+ price: vBid.add(vAsk).div(new BN(2)),
561
+ slot: new BN(slot),
562
+ confidence: new BN(1),
563
+ hasSufficientNumberOfDataPoints: true,
564
+ };
565
+
566
+ const user0 = Keypair.generate();
567
+ const user1 = Keypair.generate();
568
+ const user2 = Keypair.generate();
569
+
570
+ const dlob = new DLOB();
571
+ const marketIndex = 0;
572
+ const marketType = MarketType.PERP;
573
+
574
+ insertOrderToDLOB(
575
+ dlob,
576
+ user0.publicKey,
577
+ OrderType.LIMIT,
578
+ MarketType.PERP,
579
+ 1, // orderId
580
+ marketIndex,
581
+ new BN(11), // price
582
+ BASE_PRECISION, // quantity
583
+ PositionDirection.LONG,
584
+ vBid,
585
+ vAsk,
586
+ new BN(1)
587
+ );
588
+ insertOrderToDLOB(
589
+ dlob,
590
+ user1.publicKey,
591
+ OrderType.LIMIT,
592
+ MarketType.PERP,
593
+ 2, // orderId
594
+ marketIndex,
595
+ new BN(12), // price
596
+ BASE_PRECISION, // quantity
597
+ PositionDirection.LONG,
598
+ vBid,
599
+ vAsk,
600
+ new BN(11)
601
+ );
602
+ insertOrderToDLOB(
603
+ dlob,
604
+ user2.publicKey,
605
+ OrderType.LIMIT,
606
+ MarketType.PERP,
607
+ 3, // orderId
608
+ marketIndex,
609
+ new BN(13), // price
610
+ BASE_PRECISION, // quantity
611
+ PositionDirection.LONG,
612
+ vBid,
613
+ vAsk,
614
+ new BN(21)
615
+ );
616
+
617
+ let takingBids = Array.from(
618
+ dlob.getTakingBids(marketIndex, marketType, slot, oracle)
619
+ );
620
+
621
+ expect(takingBids.length).to.equal(3);
622
+ expect(takingBids[0].order.orderId).to.equal(1);
623
+ expect(takingBids[1].order.orderId).to.equal(2);
624
+ expect(takingBids[2].order.orderId).to.equal(3);
625
+
626
+ let restingBids = Array.from(
627
+ dlob.getRestingLimitBids(marketIndex, slot, marketType, oracle)
628
+ );
629
+
630
+ expect(restingBids.length).to.equal(0);
631
+
632
+ slot += 11;
633
+
634
+ takingBids = Array.from(
635
+ dlob.getTakingBids(marketIndex, marketType, slot, oracle)
636
+ );
637
+
638
+ expect(takingBids.length).to.equal(2);
639
+ expect(takingBids[0].order.orderId).to.equal(2);
640
+ expect(takingBids[1].order.orderId).to.equal(3);
641
+
642
+ restingBids = Array.from(
643
+ dlob.getRestingLimitBids(marketIndex, slot, marketType, oracle)
644
+ );
645
+
646
+ expect(restingBids.length).to.equal(1);
647
+ expect(restingBids[0].order.orderId).to.equal(1);
648
+
649
+ slot += 11;
650
+
651
+ takingBids = Array.from(
652
+ dlob.getTakingBids(marketIndex, marketType, slot, oracle)
653
+ );
654
+
655
+ expect(takingBids.length).to.equal(1);
656
+ expect(takingBids[0].order.orderId).to.equal(3);
657
+
658
+ restingBids = Array.from(
659
+ dlob.getRestingLimitBids(marketIndex, slot, marketType, oracle)
660
+ );
661
+
662
+ expect(restingBids.length).to.equal(2);
663
+ expect(restingBids[0].order.orderId).to.equal(2);
664
+ expect(restingBids[1].order.orderId).to.equal(1);
665
+
666
+ slot += 11;
667
+
668
+ takingBids = Array.from(
669
+ dlob.getTakingBids(marketIndex, marketType, slot, oracle)
670
+ );
671
+
672
+ expect(takingBids.length).to.equal(0);
673
+
674
+ restingBids = Array.from(
675
+ dlob.getRestingLimitBids(marketIndex, slot, marketType, oracle)
676
+ );
677
+
678
+ expect(restingBids.length).to.equal(3);
679
+ expect(restingBids[0].order.orderId).to.equal(3);
680
+ expect(restingBids[1].order.orderId).to.equal(2);
681
+ expect(restingBids[2].order.orderId).to.equal(1);
682
+ });
683
+
684
+ it('DLOB update resting limit orders asks', () => {
685
+ const vAsk = new BN(15);
686
+ const vBid = new BN(10);
687
+
688
+ let slot = 1;
689
+ const oracle = {
690
+ price: vBid.add(vAsk).div(new BN(2)),
691
+ slot: new BN(slot),
692
+ confidence: new BN(1),
693
+ hasSufficientNumberOfDataPoints: true,
694
+ };
695
+
696
+ const user0 = Keypair.generate();
697
+ const user1 = Keypair.generate();
698
+ const user2 = Keypair.generate();
699
+
700
+ const dlob = new DLOB();
701
+ const marketIndex = 0;
702
+ const marketType = MarketType.PERP;
703
+
704
+ insertOrderToDLOB(
705
+ dlob,
706
+ user0.publicKey,
707
+ OrderType.LIMIT,
708
+ MarketType.PERP,
709
+ 1, // orderId
710
+ marketIndex,
711
+ new BN(13), // price
712
+ BASE_PRECISION, // quantity
713
+ PositionDirection.SHORT,
714
+ vBid,
715
+ vAsk,
716
+ new BN(1)
717
+ );
718
+ insertOrderToDLOB(
719
+ dlob,
720
+ user1.publicKey,
721
+ OrderType.LIMIT,
722
+ MarketType.PERP,
723
+ 2, // orderId
724
+ marketIndex,
725
+ new BN(12), // price
726
+ BASE_PRECISION, // quantity
727
+ PositionDirection.SHORT,
728
+ vBid,
729
+ vAsk,
730
+ new BN(11)
731
+ );
732
+ insertOrderToDLOB(
733
+ dlob,
734
+ user2.publicKey,
735
+ OrderType.LIMIT,
736
+ MarketType.PERP,
737
+ 3, // orderId
738
+ marketIndex,
739
+ new BN(11), // price
740
+ BASE_PRECISION, // quantity
741
+ PositionDirection.SHORT,
742
+ vBid,
743
+ vAsk,
744
+ new BN(21)
745
+ );
746
+
747
+ let takingBids = Array.from(
748
+ dlob.getTakingAsks(marketIndex, marketType, slot, oracle)
749
+ );
750
+
751
+ expect(takingBids.length).to.equal(3);
752
+ expect(takingBids[0].order.orderId).to.equal(1);
753
+ expect(takingBids[1].order.orderId).to.equal(2);
754
+ expect(takingBids[2].order.orderId).to.equal(3);
755
+
756
+ let restingBids = Array.from(
757
+ dlob.getRestingLimitAsks(marketIndex, slot, marketType, oracle)
758
+ );
759
+
760
+ expect(restingBids.length).to.equal(0);
761
+
762
+ slot += 11;
763
+
764
+ takingBids = Array.from(
765
+ dlob.getTakingAsks(marketIndex, marketType, slot, oracle)
766
+ );
767
+
768
+ expect(takingBids.length).to.equal(2);
769
+ expect(takingBids[0].order.orderId).to.equal(2);
770
+ expect(takingBids[1].order.orderId).to.equal(3);
771
+
772
+ restingBids = Array.from(
773
+ dlob.getRestingLimitAsks(marketIndex, slot, marketType, oracle)
774
+ );
775
+
776
+ expect(restingBids.length).to.equal(1);
777
+ expect(restingBids[0].order.orderId).to.equal(1);
778
+
779
+ slot += 11;
780
+
781
+ takingBids = Array.from(
782
+ dlob.getTakingAsks(marketIndex, marketType, slot, oracle)
783
+ );
784
+
785
+ expect(takingBids.length).to.equal(1);
786
+ expect(takingBids[0].order.orderId).to.equal(3);
787
+
788
+ restingBids = Array.from(
789
+ dlob.getRestingLimitAsks(marketIndex, slot, marketType, oracle)
790
+ );
791
+
792
+ expect(restingBids.length).to.equal(2);
793
+ expect(restingBids[0].order.orderId).to.equal(2);
794
+ expect(restingBids[1].order.orderId).to.equal(1);
795
+
796
+ slot += 11;
797
+
798
+ takingBids = Array.from(
799
+ dlob.getTakingAsks(marketIndex, marketType, slot, oracle)
800
+ );
801
+
802
+ expect(takingBids.length).to.equal(0);
803
+
804
+ restingBids = Array.from(
805
+ dlob.getRestingLimitAsks(marketIndex, slot, marketType, oracle)
806
+ );
807
+
808
+ expect(restingBids.length).to.equal(3);
809
+ expect(restingBids[0].order.orderId).to.equal(3);
810
+ expect(restingBids[1].order.orderId).to.equal(2);
811
+ expect(restingBids[2].order.orderId).to.equal(1);
812
+ });
548
813
  });
549
814
 
550
815
  describe('DLOB Perp Tests', () => {
@@ -569,6 +834,8 @@ describe('DLOB Perp Tests', () => {
569
834
  price: new BN(0),
570
835
  direction: PositionDirection.LONG,
571
836
  orderType: OrderType.MARKET,
837
+ slot: new BN(0),
838
+ postOnly: false,
572
839
  },
573
840
  {
574
841
  expectedIdx: 1,
@@ -577,6 +844,8 @@ describe('DLOB Perp Tests', () => {
577
844
  price: new BN(0),
578
845
  direction: PositionDirection.LONG,
579
846
  orderType: OrderType.MARKET,
847
+ slot: new BN(1),
848
+ postOnly: false,
580
849
  },
581
850
  {
582
851
  expectedIdx: 2,
@@ -585,6 +854,8 @@ describe('DLOB Perp Tests', () => {
585
854
  price: new BN(0),
586
855
  direction: PositionDirection.LONG,
587
856
  orderType: OrderType.MARKET,
857
+ slot: new BN(2),
858
+ postOnly: false,
588
859
  },
589
860
  {
590
861
  expectedIdx: 3,
@@ -593,6 +864,8 @@ describe('DLOB Perp Tests', () => {
593
864
  price: new BN(12),
594
865
  direction: PositionDirection.LONG,
595
866
  orderType: OrderType.LIMIT,
867
+ slot: new BN(3),
868
+ postOnly: false,
596
869
  },
597
870
  {
598
871
  expectedIdx: 4,
@@ -601,6 +874,8 @@ describe('DLOB Perp Tests', () => {
601
874
  price: new BN(11),
602
875
  direction: PositionDirection.LONG,
603
876
  orderType: OrderType.LIMIT,
877
+ slot: new BN(4),
878
+ postOnly: false,
604
879
  },
605
880
  {
606
881
  expectedIdx: 7,
@@ -609,6 +884,8 @@ describe('DLOB Perp Tests', () => {
609
884
  price: new BN(8),
610
885
  direction: PositionDirection.LONG,
611
886
  orderType: OrderType.LIMIT,
887
+ slot: new BN(5),
888
+ postOnly: true,
612
889
  },
613
890
  {
614
891
  expectedIdx: 5,
@@ -617,6 +894,8 @@ describe('DLOB Perp Tests', () => {
617
894
  price: undefined,
618
895
  direction: undefined,
619
896
  orderType: undefined,
897
+ slot: undefined,
898
+ postOnly: false,
620
899
  },
621
900
  {
622
901
  expectedIdx: 6,
@@ -625,6 +904,8 @@ describe('DLOB Perp Tests', () => {
625
904
  price: new BN(9),
626
905
  direction: PositionDirection.LONG,
627
906
  orderType: OrderType.LIMIT,
907
+ slot: new BN(6),
908
+ postOnly: true,
628
909
  },
629
910
  ];
630
911
 
@@ -645,8 +926,12 @@ describe('DLOB Perp Tests', () => {
645
926
  t.price || new BN(0), // price
646
927
  BASE_PRECISION, // quantity
647
928
  t.direction || PositionDirection.LONG,
648
- vBid,
649
- vAsk
929
+ !t.postOnly ? vBid : ZERO,
930
+ !t.postOnly ? vAsk : ZERO,
931
+ t.slot,
932
+ undefined,
933
+ undefined,
934
+ t.postOnly
650
935
  );
651
936
  }
652
937
 
@@ -682,29 +967,34 @@ describe('DLOB Perp Tests', () => {
682
967
  }
683
968
  expect(countBids).to.equal(testCases.length);
684
969
 
685
- const marketBids = dlob.getMarketBids(marketIndex, MarketType.PERP);
970
+ const takingBids = dlob.getTakingBids(
971
+ marketIndex,
972
+ MarketType.PERP,
973
+ slot,
974
+ oracle
975
+ );
686
976
  countBids = 0;
687
- for (const bid of marketBids) {
977
+ for (const bid of takingBids) {
688
978
  expect(bid.isVammNode(), `expected vAMM node`).to.be.eq(
689
- expectedTestCase.slice(0, 3)[countBids].isVamm
979
+ expectedTestCase.slice(0, 5)[countBids].isVamm
690
980
  );
691
981
  expect(bid.order?.orderId, `expected orderId`).to.equal(
692
- expectedTestCase.slice(0, 3)[countBids].orderId
982
+ expectedTestCase.slice(0, 5)[countBids].orderId
693
983
  );
694
984
  expect(bid.order?.price.toNumber(), `expected price`).to.equal(
695
- expectedTestCase.slice(0, 3)[countBids].price?.toNumber()
985
+ expectedTestCase.slice(0, 5)[countBids].price?.toNumber()
696
986
  );
697
987
  expect(bid.order?.direction, `expected order direction`).to.equal(
698
- expectedTestCase.slice(0, 3)[countBids].direction
988
+ expectedTestCase.slice(0, 5)[countBids].direction
699
989
  );
700
990
  expect(bid.order?.orderType, `expected order type`).to.equal(
701
- expectedTestCase.slice(0, 3)[countBids].orderType
991
+ expectedTestCase.slice(0, 5)[countBids].orderType
702
992
  );
703
993
  countBids++;
704
994
  }
705
- expect(countBids).to.equal(expectedTestCase.slice(0, 3).length);
995
+ expect(countBids).to.equal(expectedTestCase.slice(0, 5).length);
706
996
 
707
- const limitBids = dlob.getLimitBids(
997
+ const limitBids = dlob.getRestingLimitBids(
708
998
  marketIndex,
709
999
  slot,
710
1000
  MarketType.PERP,
@@ -713,28 +1003,28 @@ describe('DLOB Perp Tests', () => {
713
1003
  countBids = 0;
714
1004
  let idx = 0;
715
1005
  for (const bid of limitBids) {
716
- if (expectedTestCase.slice(3)[idx].isVamm) {
1006
+ if (expectedTestCase.slice(5)[idx].isVamm) {
717
1007
  idx++;
718
1008
  }
719
1009
  expect(bid.isVammNode(), `expected vAMM node`).to.be.eq(
720
- expectedTestCase.slice(3)[idx].isVamm
1010
+ expectedTestCase.slice(5)[idx].isVamm
721
1011
  );
722
1012
  expect(bid.order?.orderId, `expected orderId`).to.equal(
723
- expectedTestCase.slice(3)[idx].orderId
1013
+ expectedTestCase.slice(5)[idx].orderId
724
1014
  );
725
1015
  expect(bid.order?.price.toNumber(), `expected price`).to.equal(
726
- expectedTestCase.slice(3)[idx].price?.toNumber()
1016
+ expectedTestCase.slice(5)[idx].price?.toNumber()
727
1017
  );
728
1018
  expect(bid.order?.direction, `expected order direction`).to.equal(
729
- expectedTestCase.slice(3)[idx].direction
1019
+ expectedTestCase.slice(5)[idx].direction
730
1020
  );
731
1021
  expect(bid.order?.orderType, `expected order type`).to.equal(
732
- expectedTestCase.slice(3)[idx].orderType
1022
+ expectedTestCase.slice(5)[idx].orderType
733
1023
  );
734
1024
  countBids++;
735
1025
  idx++;
736
1026
  }
737
- expect(countBids).to.equal(expectedTestCase.slice(3).length - 1); // subtract one since test case 5 is vAMM node
1027
+ expect(countBids).to.equal(expectedTestCase.slice(5).length - 1); // subtract one since test case 5 is vAMM node
738
1028
  });
739
1029
 
740
1030
  it('Test proper bids on multiple markets', () => {
@@ -904,6 +1194,8 @@ describe('DLOB Perp Tests', () => {
904
1194
  price: new BN(0),
905
1195
  direction: PositionDirection.SHORT,
906
1196
  orderType: OrderType.MARKET,
1197
+ slot: new BN(0),
1198
+ postOnly: false,
907
1199
  },
908
1200
  {
909
1201
  expectedIdx: 1,
@@ -912,6 +1204,8 @@ describe('DLOB Perp Tests', () => {
912
1204
  price: new BN(0),
913
1205
  direction: PositionDirection.SHORT,
914
1206
  orderType: OrderType.MARKET,
1207
+ slot: new BN(1),
1208
+ postOnly: false,
915
1209
  },
916
1210
  {
917
1211
  expectedIdx: 2,
@@ -920,6 +1214,8 @@ describe('DLOB Perp Tests', () => {
920
1214
  price: new BN(0),
921
1215
  direction: PositionDirection.SHORT,
922
1216
  orderType: OrderType.MARKET,
1217
+ slot: new BN(2),
1218
+ postOnly: false,
923
1219
  },
924
1220
  {
925
1221
  expectedIdx: 3,
@@ -928,6 +1224,8 @@ describe('DLOB Perp Tests', () => {
928
1224
  price: new BN(13),
929
1225
  direction: PositionDirection.SHORT,
930
1226
  orderType: OrderType.LIMIT,
1227
+ slot: new BN(3),
1228
+ postOnly: false,
931
1229
  },
932
1230
  {
933
1231
  expectedIdx: 6,
@@ -936,6 +1234,8 @@ describe('DLOB Perp Tests', () => {
936
1234
  price: new BN(16),
937
1235
  direction: PositionDirection.SHORT,
938
1236
  orderType: OrderType.LIMIT,
1237
+ slot: new BN(4),
1238
+ postOnly: true,
939
1239
  },
940
1240
  {
941
1241
  expectedIdx: 5,
@@ -944,6 +1244,8 @@ describe('DLOB Perp Tests', () => {
944
1244
  price: undefined,
945
1245
  direction: undefined,
946
1246
  orderType: undefined,
1247
+ slot: new BN(0),
1248
+ postOnly: false,
947
1249
  },
948
1250
  {
949
1251
  expectedIdx: 7,
@@ -952,6 +1254,8 @@ describe('DLOB Perp Tests', () => {
952
1254
  price: new BN(17),
953
1255
  direction: PositionDirection.SHORT,
954
1256
  orderType: OrderType.LIMIT,
1257
+ slot: new BN(4),
1258
+ postOnly: true,
955
1259
  },
956
1260
  {
957
1261
  expectedIdx: 4,
@@ -960,6 +1264,8 @@ describe('DLOB Perp Tests', () => {
960
1264
  price: new BN(14),
961
1265
  direction: PositionDirection.SHORT,
962
1266
  orderType: OrderType.LIMIT,
1267
+ slot: new BN(4),
1268
+ postOnly: true,
963
1269
  },
964
1270
  ];
965
1271
 
@@ -980,8 +1286,12 @@ describe('DLOB Perp Tests', () => {
980
1286
  t.price || new BN(0), // price
981
1287
  BASE_PRECISION, // quantity
982
1288
  t.direction || PositionDirection.SHORT,
983
- vBid,
984
- vAsk
1289
+ !t.postOnly ? vBid : ZERO,
1290
+ !t.postOnly ? vAsk : ZERO,
1291
+ t.slot,
1292
+ undefined,
1293
+ undefined,
1294
+ t.postOnly
985
1295
  );
986
1296
  }
987
1297
 
@@ -1008,29 +1318,34 @@ describe('DLOB Perp Tests', () => {
1008
1318
  }
1009
1319
  expect(countAsks).to.equal(testCases.length);
1010
1320
 
1011
- const marketAsks = dlob.getMarketAsks(marketIndex, MarketType.PERP);
1321
+ const takingAsks = dlob.getTakingAsks(
1322
+ marketIndex,
1323
+ MarketType.PERP,
1324
+ slot,
1325
+ oracle
1326
+ );
1012
1327
  countAsks = 0;
1013
- for (const ask of marketAsks) {
1328
+ for (const ask of takingAsks) {
1014
1329
  expect(ask.isVammNode()).to.be.eq(
1015
- expectedTestCase.slice(0, 3)[countAsks].isVamm
1330
+ expectedTestCase.slice(0, 4)[countAsks].isVamm
1016
1331
  );
1017
1332
  expect(ask.order?.orderId).to.equal(
1018
- expectedTestCase.slice(0, 3)[countAsks].orderId
1333
+ expectedTestCase.slice(0, 4)[countAsks].orderId
1019
1334
  );
1020
1335
  expect(ask.order?.price.toNumber()).to.equal(
1021
- expectedTestCase.slice(0, 3)[countAsks].price?.toNumber()
1336
+ expectedTestCase.slice(0, 4)[countAsks].price?.toNumber()
1022
1337
  );
1023
1338
  expect(ask.order?.direction).to.equal(
1024
- expectedTestCase.slice(0, 3)[countAsks].direction
1339
+ expectedTestCase.slice(0, 4)[countAsks].direction
1025
1340
  );
1026
1341
  expect(ask.order?.orderType).to.equal(
1027
- expectedTestCase.slice(0, 3)[countAsks].orderType
1342
+ expectedTestCase.slice(0, 4)[countAsks].orderType
1028
1343
  );
1029
1344
  countAsks++;
1030
1345
  }
1031
- expect(countAsks).to.equal(expectedTestCase.slice(0, 3).length);
1346
+ expect(countAsks).to.equal(expectedTestCase.slice(0, 4).length);
1032
1347
 
1033
- const limitAsks = dlob.getLimitAsks(
1348
+ const limitAsks = dlob.getRestingLimitAsks(
1034
1349
  marketIndex,
1035
1350
  slot,
1036
1351
  MarketType.PERP,
@@ -1039,26 +1354,26 @@ describe('DLOB Perp Tests', () => {
1039
1354
  countAsks = 0;
1040
1355
  let idx = 0;
1041
1356
  for (const ask of limitAsks) {
1042
- if (expectedTestCase.slice(3)[idx].isVamm) {
1357
+ if (expectedTestCase.slice(4)[idx].isVamm) {
1043
1358
  idx++;
1044
1359
  }
1045
- expect(ask.isVammNode()).to.be.eq(expectedTestCase.slice(3)[idx].isVamm);
1360
+ expect(ask.isVammNode()).to.be.eq(expectedTestCase.slice(4)[idx].isVamm);
1046
1361
  expect(ask.order?.orderId).to.equal(
1047
- expectedTestCase.slice(3)[idx].orderId
1362
+ expectedTestCase.slice(4)[idx].orderId
1048
1363
  );
1049
1364
  expect(ask.order?.price.toNumber()).to.equal(
1050
- expectedTestCase.slice(3)[idx].price?.toNumber()
1365
+ expectedTestCase.slice(4)[idx].price?.toNumber()
1051
1366
  );
1052
1367
  expect(ask.order?.direction).to.equal(
1053
- expectedTestCase.slice(3)[idx].direction
1368
+ expectedTestCase.slice(4)[idx].direction
1054
1369
  );
1055
1370
  expect(ask.order?.orderType).to.equal(
1056
- expectedTestCase.slice(3)[idx].orderType
1371
+ expectedTestCase.slice(4)[idx].orderType
1057
1372
  );
1058
1373
  countAsks++;
1059
1374
  idx++;
1060
1375
  }
1061
- expect(countAsks).to.equal(expectedTestCase.slice(3).length - 1); // subtract one since test case includes vAMM node
1376
+ expect(countAsks).to.equal(expectedTestCase.slice(4).length - 1); // subtract one since test case includes vAMM node
1062
1377
  });
1063
1378
 
1064
1379
  it('Test insert market orders', () => {
@@ -1185,7 +1500,12 @@ describe('DLOB Perp Tests', () => {
1185
1500
  BASE_PRECISION,
1186
1501
  PositionDirection.LONG,
1187
1502
  vBid,
1188
- vAsk
1503
+ vAsk,
1504
+ undefined,
1505
+ undefined,
1506
+ undefined,
1507
+ undefined,
1508
+ 0
1189
1509
  );
1190
1510
 
1191
1511
  insertOrderToDLOB(
@@ -1199,7 +1519,12 @@ describe('DLOB Perp Tests', () => {
1199
1519
  BASE_PRECISION,
1200
1520
  PositionDirection.LONG,
1201
1521
  vBid,
1202
- vAsk
1522
+ vAsk,
1523
+ undefined,
1524
+ undefined,
1525
+ undefined,
1526
+ undefined,
1527
+ 0
1203
1528
  );
1204
1529
 
1205
1530
  insertOrderToDLOB(
@@ -1213,7 +1538,12 @@ describe('DLOB Perp Tests', () => {
1213
1538
  BASE_PRECISION,
1214
1539
  PositionDirection.LONG,
1215
1540
  vBid,
1216
- vAsk
1541
+ vAsk,
1542
+ undefined,
1543
+ undefined,
1544
+ undefined,
1545
+ undefined,
1546
+ 0
1217
1547
  );
1218
1548
 
1219
1549
  insertOrderToDLOB(
@@ -1227,7 +1557,12 @@ describe('DLOB Perp Tests', () => {
1227
1557
  BASE_PRECISION,
1228
1558
  PositionDirection.SHORT,
1229
1559
  vBid,
1230
- vAsk
1560
+ vAsk,
1561
+ undefined,
1562
+ undefined,
1563
+ undefined,
1564
+ undefined,
1565
+ 0
1231
1566
  );
1232
1567
 
1233
1568
  insertOrderToDLOB(
@@ -1241,7 +1576,12 @@ describe('DLOB Perp Tests', () => {
1241
1576
  BASE_PRECISION,
1242
1577
  PositionDirection.SHORT,
1243
1578
  vBid,
1244
- vAsk
1579
+ vAsk,
1580
+ undefined,
1581
+ undefined,
1582
+ undefined,
1583
+ undefined,
1584
+ 0
1245
1585
  );
1246
1586
 
1247
1587
  insertOrderToDLOB(
@@ -1255,7 +1595,12 @@ describe('DLOB Perp Tests', () => {
1255
1595
  BASE_PRECISION,
1256
1596
  PositionDirection.SHORT,
1257
1597
  vBid,
1258
- vAsk
1598
+ vAsk,
1599
+ undefined,
1600
+ undefined,
1601
+ undefined,
1602
+ undefined,
1603
+ 0
1259
1604
  );
1260
1605
 
1261
1606
  let asks = 0;
@@ -1552,7 +1897,7 @@ describe('DLOB Perp Tests', () => {
1552
1897
  );
1553
1898
 
1554
1899
  // should have no crossing orders
1555
- const nodesToFillBefore = dlob.findLimitOrderNodesToFill(
1900
+ const nodesToFillBefore = dlob.findRestingLimitOrderNodesToFill(
1556
1901
  marketIndex,
1557
1902
  12, // auction over
1558
1903
  MarketType.PERP,
@@ -1563,6 +1908,7 @@ describe('DLOB Perp Tests', () => {
1563
1908
  hasSufficientNumberOfDataPoints: true,
1564
1909
  },
1565
1910
  false,
1911
+ 10,
1566
1912
  undefined,
1567
1913
  undefined
1568
1914
  );
@@ -1696,7 +2042,7 @@ describe('DLOB Perp Tests', () => {
1696
2042
  const endSlot = 12;
1697
2043
 
1698
2044
  // should have no crossing orders
1699
- const nodesToFillBefore = dlob.findLimitOrderNodesToFill(
2045
+ const nodesToFillBefore = dlob.findRestingLimitOrderNodesToFill(
1700
2046
  marketIndex,
1701
2047
  endSlot,
1702
2048
  MarketType.PERP,
@@ -1707,6 +2053,7 @@ describe('DLOB Perp Tests', () => {
1707
2053
  hasSufficientNumberOfDataPoints: true,
1708
2054
  },
1709
2055
  false,
2056
+ 10,
1710
2057
  undefined,
1711
2058
  undefined
1712
2059
  );
@@ -2293,7 +2640,8 @@ describe('DLOB Perp Tests', () => {
2293
2640
  new BN(slot),
2294
2641
  ZERO,
2295
2642
  new BN(1).mul(PRICE_PRECISION),
2296
- true
2643
+ true,
2644
+ 0
2297
2645
  );
2298
2646
  insertOrderToDLOB(
2299
2647
  dlob,
@@ -2310,7 +2658,8 @@ describe('DLOB Perp Tests', () => {
2310
2658
  new BN(slot),
2311
2659
  ZERO,
2312
2660
  new BN(1).mul(PRICE_PRECISION),
2313
- true
2661
+ true,
2662
+ 0
2314
2663
  );
2315
2664
  insertOrderToDLOB(
2316
2665
  dlob,
@@ -2327,7 +2676,8 @@ describe('DLOB Perp Tests', () => {
2327
2676
  new BN(slot),
2328
2677
  ZERO,
2329
2678
  new BN(1).mul(PRICE_PRECISION),
2330
- true
2679
+ true,
2680
+ 0
2331
2681
  );
2332
2682
 
2333
2683
  // should have no crossing orders
@@ -2496,12 +2846,13 @@ describe('DLOB Perp Tests', () => {
2496
2846
  // should have no crossing orders
2497
2847
  const auctionOverSlot = slot * 10;
2498
2848
  const auctionOverTs = ts * 10;
2499
- const nodesToFillBefore = dlob.findLimitOrderNodesToFill(
2849
+ const nodesToFillBefore = dlob.findRestingLimitOrderNodesToFill(
2500
2850
  marketIndex,
2501
2851
  auctionOverSlot, // auction over
2502
2852
  MarketType.PERP,
2503
2853
  oracle,
2504
2854
  false,
2855
+ 10,
2505
2856
  undefined,
2506
2857
  undefined
2507
2858
  );
@@ -3012,7 +3363,6 @@ describe('DLOB Perp Tests', () => {
3012
3363
  printCrossedNodes(n, afterAuctionSlot);
3013
3364
  }
3014
3365
 
3015
- // taker should fill first order completely with best maker (1/1)
3016
3366
  expect(
3017
3367
  nodesToFillAfter[0].node.order?.orderId,
3018
3368
  'wrong taker orderId'
@@ -3022,7 +3372,6 @@ describe('DLOB Perp Tests', () => {
3022
3372
  'wrong maker orderId'
3023
3373
  ).to.equal(undefined);
3024
3374
 
3025
- // taker should fill second order completely with vamm
3026
3375
  expect(
3027
3376
  nodesToFillAfter[1].node.order?.orderId,
3028
3377
  'wrong taker orderId'
@@ -3070,7 +3419,8 @@ describe('DLOB Perp Tests', () => {
3070
3419
  new BN(slot),
3071
3420
  new BN(200),
3072
3421
  undefined,
3073
- true
3422
+ true,
3423
+ 0
3074
3424
  );
3075
3425
  // insert a buy above the vBid
3076
3426
  insertOrderToDLOB(
@@ -3085,8 +3435,11 @@ describe('DLOB Perp Tests', () => {
3085
3435
  PositionDirection.LONG,
3086
3436
  vBid,
3087
3437
  vAsk,
3088
- new BN(slot - 1), // later order becomes taker
3089
- new BN(200)
3438
+ new BN(slot + 1), // later order becomes taker
3439
+ new BN(200),
3440
+ undefined,
3441
+ undefined,
3442
+ 0
3090
3443
  );
3091
3444
 
3092
3445
  console.log(`Book state before fill:`);
@@ -3242,11 +3595,13 @@ describe('DLOB Perp Tests', () => {
3242
3595
  vBid.sub(PRICE_PRECISION),
3243
3596
  new BN(1).mul(BASE_PRECISION), // quantity
3244
3597
  PositionDirection.SHORT,
3245
- vAsk,
3246
- vBid,
3598
+ ZERO,
3599
+ ZERO,
3247
3600
  new BN(slot),
3248
3601
  new BN(200),
3249
- undefined
3602
+ undefined,
3603
+ undefined,
3604
+ 0
3250
3605
  );
3251
3606
 
3252
3607
  // Market buy right above amm bid. crosses limit sell but can't be used
@@ -3277,9 +3632,13 @@ describe('DLOB Perp Tests', () => {
3277
3632
  vAsk.add(PRICE_PRECISION), // price,
3278
3633
  new BN(8768).mul(BASE_PRECISION).div(new BN(10000)), // quantity
3279
3634
  PositionDirection.LONG,
3280
- vBid,
3281
- vAsk,
3282
- new BN(slot)
3635
+ ZERO,
3636
+ ZERO,
3637
+ new BN(slot),
3638
+ undefined,
3639
+ undefined,
3640
+ undefined,
3641
+ 0
3283
3642
  );
3284
3643
 
3285
3644
  // Market sell right below amm ask. crosses limit buy but can't be used
@@ -3302,12 +3661,13 @@ describe('DLOB Perp Tests', () => {
3302
3661
  console.log(`Book state before fill:`);
3303
3662
  printBookState(dlob, marketIndex, vBid, vAsk, slot, oracle);
3304
3663
 
3305
- const nodesToFillBefore = dlob.findMarketNodesToFill(
3664
+ const nodesToFillBefore = dlob.findTakingNodesToFill(
3306
3665
  marketIndex,
3307
3666
  slot,
3308
3667
  MarketType.PERP,
3309
3668
  oracle,
3310
3669
  false,
3670
+ 10,
3311
3671
  vAsk,
3312
3672
  vBid
3313
3673
  );
@@ -3325,10 +3685,13 @@ describe('DLOB Perp Tests', () => {
3325
3685
  vBid.add(PRICE_PRECISION.div(TWO)),
3326
3686
  new BN(1).mul(BASE_PRECISION), // quantity
3327
3687
  PositionDirection.SHORT,
3328
- vAsk,
3329
- vBid,
3330
- new BN(slot),
3331
- new BN(200)
3688
+ ZERO,
3689
+ ZERO,
3690
+ new BN(slot),
3691
+ new BN(200),
3692
+ undefined,
3693
+ undefined,
3694
+ 0
3332
3695
  );
3333
3696
 
3334
3697
  // insert a buy below the amm ask
@@ -3342,17 +3705,22 @@ describe('DLOB Perp Tests', () => {
3342
3705
  vAsk.sub(PRICE_PRECISION.div(TWO)), // price,
3343
3706
  new BN(8768).mul(BASE_PRECISION).div(new BN(10000)), // quantity
3344
3707
  PositionDirection.LONG,
3345
- vBid,
3346
- vAsk,
3347
- new BN(slot)
3708
+ ZERO,
3709
+ ZERO,
3710
+ new BN(slot),
3711
+ undefined,
3712
+ undefined,
3713
+ undefined,
3714
+ 0
3348
3715
  );
3349
3716
 
3350
- const nodesToFillAfter = dlob.findMarketNodesToFill(
3717
+ const nodesToFillAfter = dlob.findTakingNodesToFill(
3351
3718
  marketIndex,
3352
3719
  slot,
3353
3720
  MarketType.PERP,
3354
3721
  oracle,
3355
3722
  false,
3723
+ 10,
3356
3724
  vAsk,
3357
3725
  vBid
3358
3726
  );
@@ -3377,6 +3745,138 @@ describe('DLOB Perp Tests', () => {
3377
3745
  'wrong maker orderId'
3378
3746
  ).to.equal(5);
3379
3747
  });
3748
+
3749
+ it('Test limit bid fills during auction', () => {
3750
+ const vAsk = new BN(20).mul(PRICE_PRECISION);
3751
+ const vBid = new BN(5).mul(PRICE_PRECISION);
3752
+
3753
+ const user0 = Keypair.generate();
3754
+ const user1 = Keypair.generate();
3755
+ const user2 = Keypair.generate();
3756
+ const user3 = Keypair.generate();
3757
+
3758
+ const dlob = new DLOB();
3759
+ const marketIndex = 0;
3760
+
3761
+ const slot = 9;
3762
+ const ts = 9;
3763
+ const oracle = {
3764
+ price: vBid.add(vAsk).div(new BN(2)), // 11.5
3765
+ slot: new BN(slot),
3766
+ confidence: new BN(1),
3767
+ hasSufficientNumberOfDataPoints: true,
3768
+ };
3769
+
3770
+ insertOrderToDLOB(
3771
+ dlob,
3772
+ user3.publicKey,
3773
+ OrderType.LIMIT,
3774
+ MarketType.PERP,
3775
+ 2, // orderId
3776
+ marketIndex,
3777
+ vAsk, // price
3778
+ new BN(1).mul(BASE_PRECISION), // quantity
3779
+ PositionDirection.LONG,
3780
+ vBid.add(PRICE_PRECISION),
3781
+ vAsk,
3782
+ new BN(0),
3783
+ new BN(200),
3784
+ undefined,
3785
+ undefined,
3786
+ 10
3787
+ );
3788
+
3789
+ insertOrderToDLOB(
3790
+ dlob,
3791
+ user2.publicKey,
3792
+ OrderType.LIMIT,
3793
+ MarketType.PERP,
3794
+ 4, // orderId
3795
+ marketIndex,
3796
+ vBid, // price
3797
+ new BN(1).mul(BASE_PRECISION), // quantity
3798
+ PositionDirection.SHORT,
3799
+ vAsk.sub(PRICE_PRECISION),
3800
+ vBid,
3801
+ new BN(0),
3802
+ new BN(200),
3803
+ undefined,
3804
+ undefined,
3805
+ 10
3806
+ );
3807
+
3808
+ // insert a sell right above amm bid
3809
+ insertOrderToDLOB(
3810
+ dlob,
3811
+ user0.publicKey,
3812
+ OrderType.LIMIT,
3813
+ MarketType.PERP,
3814
+ 5, // orderId
3815
+ marketIndex,
3816
+ oracle.price,
3817
+ new BN(1).mul(BASE_PRECISION), // quantity
3818
+ PositionDirection.SHORT,
3819
+ ZERO,
3820
+ ZERO,
3821
+ new BN(slot),
3822
+ new BN(200),
3823
+ undefined,
3824
+ true,
3825
+ 0
3826
+ );
3827
+
3828
+ // insert a buy below the amm ask
3829
+ insertOrderToDLOB(
3830
+ dlob,
3831
+ user1.publicKey,
3832
+ OrderType.LIMIT,
3833
+ MarketType.PERP,
3834
+ 6, // orderId
3835
+ marketIndex,
3836
+ oracle.price, // price,
3837
+ new BN(8768).mul(BASE_PRECISION).div(new BN(10000)), // quantity
3838
+ PositionDirection.LONG,
3839
+ ZERO,
3840
+ ZERO,
3841
+ new BN(slot),
3842
+ undefined,
3843
+ undefined,
3844
+ true,
3845
+ 0
3846
+ );
3847
+
3848
+ const nodesToFillAfter = dlob.findNodesToFill(
3849
+ marketIndex,
3850
+ vBid,
3851
+ vAsk,
3852
+ slot,
3853
+ ts,
3854
+ MarketType.PERP,
3855
+ oracle,
3856
+ mockStateAccount,
3857
+ mockPerpMarkets[marketIndex]
3858
+ );
3859
+
3860
+ expect(nodesToFillAfter.length).to.equal(2);
3861
+
3862
+ expect(
3863
+ nodesToFillAfter[0].node.order?.orderId,
3864
+ 'wrong taker orderId'
3865
+ ).to.equal(4);
3866
+ expect(
3867
+ nodesToFillAfter[0].makerNode?.order?.orderId,
3868
+ 'wrong maker orderId'
3869
+ ).to.equal(6);
3870
+
3871
+ expect(
3872
+ nodesToFillAfter[1].node.order?.orderId,
3873
+ 'wrong taker orderId'
3874
+ ).to.equal(2);
3875
+ expect(
3876
+ nodesToFillAfter[1].makerNode?.order?.orderId,
3877
+ 'wrong maker orderId'
3878
+ ).to.equal(5);
3879
+ });
3380
3880
  });
3381
3881
 
3382
3882
  describe('DLOB Spot Tests', () => {
@@ -3400,6 +3900,8 @@ describe('DLOB Spot Tests', () => {
3400
3900
  price: new BN(0), // will calc 108
3401
3901
  direction: PositionDirection.LONG,
3402
3902
  orderType: OrderType.MARKET,
3903
+ slot: new BN(0),
3904
+ postOnly: false,
3403
3905
  },
3404
3906
  {
3405
3907
  expectedIdx: 1,
@@ -3407,6 +3909,8 @@ describe('DLOB Spot Tests', () => {
3407
3909
  price: new BN(0), // will calc 108
3408
3910
  direction: PositionDirection.LONG,
3409
3911
  orderType: OrderType.MARKET,
3912
+ slot: new BN(1),
3913
+ postOnly: false,
3410
3914
  },
3411
3915
  {
3412
3916
  expectedIdx: 2,
@@ -3414,6 +3918,8 @@ describe('DLOB Spot Tests', () => {
3414
3918
  price: new BN(0), // will calc 108
3415
3919
  direction: PositionDirection.LONG,
3416
3920
  orderType: OrderType.MARKET,
3921
+ slot: new BN(2),
3922
+ postOnly: false,
3417
3923
  },
3418
3924
  {
3419
3925
  expectedIdx: 4,
@@ -3421,6 +3927,8 @@ describe('DLOB Spot Tests', () => {
3421
3927
  price: new BN(110),
3422
3928
  direction: PositionDirection.LONG,
3423
3929
  orderType: OrderType.LIMIT,
3930
+ slot: new BN(0),
3931
+ postOnly: true,
3424
3932
  },
3425
3933
  {
3426
3934
  expectedIdx: 5,
@@ -3428,6 +3936,8 @@ describe('DLOB Spot Tests', () => {
3428
3936
  price: new BN(109),
3429
3937
  direction: PositionDirection.LONG,
3430
3938
  orderType: OrderType.LIMIT,
3939
+ slot: new BN(0),
3940
+ postOnly: true,
3431
3941
  },
3432
3942
  {
3433
3943
  expectedIdx: 6,
@@ -3435,6 +3945,8 @@ describe('DLOB Spot Tests', () => {
3435
3945
  price: new BN(107),
3436
3946
  direction: PositionDirection.LONG,
3437
3947
  orderType: OrderType.LIMIT,
3948
+ slot: new BN(0),
3949
+ postOnly: true,
3438
3950
  },
3439
3951
  {
3440
3952
  expectedIdx: 7,
@@ -3442,6 +3954,8 @@ describe('DLOB Spot Tests', () => {
3442
3954
  price: new BN(106),
3443
3955
  direction: PositionDirection.LONG,
3444
3956
  orderType: OrderType.LIMIT,
3957
+ slot: new BN(0),
3958
+ postOnly: true,
3445
3959
  },
3446
3960
  ];
3447
3961
 
@@ -3458,8 +3972,12 @@ describe('DLOB Spot Tests', () => {
3458
3972
  t.price || new BN(0), // price
3459
3973
  BASE_PRECISION, // quantity
3460
3974
  t.direction || PositionDirection.LONG,
3461
- vBid,
3462
- vAsk
3975
+ !t.postOnly ? vBid : ZERO,
3976
+ !t.postOnly ? vAsk : ZERO,
3977
+ t.slot,
3978
+ undefined,
3979
+ undefined,
3980
+ t.postOnly
3463
3981
  );
3464
3982
  }
3465
3983
 
@@ -3651,6 +4169,8 @@ describe('DLOB Spot Tests', () => {
3651
4169
  price: new BN(0),
3652
4170
  direction: PositionDirection.SHORT,
3653
4171
  orderType: OrderType.MARKET,
4172
+ slot: new BN(0),
4173
+ postOnly: false,
3654
4174
  },
3655
4175
  {
3656
4176
  expectedIdx: 1,
@@ -3658,6 +4178,8 @@ describe('DLOB Spot Tests', () => {
3658
4178
  price: new BN(0),
3659
4179
  direction: PositionDirection.SHORT,
3660
4180
  orderType: OrderType.MARKET,
4181
+ slot: new BN(1),
4182
+ postOnly: false,
3661
4183
  },
3662
4184
  {
3663
4185
  expectedIdx: 2,
@@ -3665,6 +4187,8 @@ describe('DLOB Spot Tests', () => {
3665
4187
  price: new BN(0),
3666
4188
  direction: PositionDirection.SHORT,
3667
4189
  orderType: OrderType.MARKET,
4190
+ slot: new BN(2),
4191
+ postOnly: false,
3668
4192
  },
3669
4193
  {
3670
4194
  expectedIdx: 3,
@@ -3672,6 +4196,8 @@ describe('DLOB Spot Tests', () => {
3672
4196
  price: new BN(13),
3673
4197
  direction: PositionDirection.SHORT,
3674
4198
  orderType: OrderType.LIMIT,
4199
+ slot: new BN(3),
4200
+ postOnly: false,
3675
4201
  },
3676
4202
  {
3677
4203
  expectedIdx: 6,
@@ -3679,6 +4205,8 @@ describe('DLOB Spot Tests', () => {
3679
4205
  price: new BN(16),
3680
4206
  direction: PositionDirection.SHORT,
3681
4207
  orderType: OrderType.LIMIT,
4208
+ slot: new BN(0),
4209
+ postOnly: true,
3682
4210
  },
3683
4211
  {
3684
4212
  expectedIdx: 7,
@@ -3686,6 +4214,8 @@ describe('DLOB Spot Tests', () => {
3686
4214
  price: new BN(17),
3687
4215
  direction: PositionDirection.SHORT,
3688
4216
  orderType: OrderType.LIMIT,
4217
+ slot: new BN(0),
4218
+ postOnly: true,
3689
4219
  },
3690
4220
  {
3691
4221
  expectedIdx: 4,
@@ -3693,6 +4223,8 @@ describe('DLOB Spot Tests', () => {
3693
4223
  price: new BN(14),
3694
4224
  direction: PositionDirection.SHORT,
3695
4225
  orderType: OrderType.LIMIT,
4226
+ slot: new BN(0),
4227
+ postOnly: true,
3696
4228
  },
3697
4229
  ];
3698
4230
 
@@ -3709,8 +4241,12 @@ describe('DLOB Spot Tests', () => {
3709
4241
  t.price || new BN(0), // price
3710
4242
  BASE_PRECISION, // quantity
3711
4243
  t.direction || PositionDirection.SHORT,
3712
- vBid,
3713
- vAsk
4244
+ !t.postOnly ? vBid : ZERO,
4245
+ !t.postOnly ? vAsk : ZERO,
4246
+ t.slot,
4247
+ undefined,
4248
+ undefined,
4249
+ t.postOnly
3714
4250
  );
3715
4251
  }
3716
4252
 
@@ -4573,7 +5109,8 @@ describe('DLOB Spot Tests', () => {
4573
5109
  BASE_PRECISION, // quantity
4574
5110
  PositionDirection.SHORT,
4575
5111
  vBid,
4576
- vAsk
5112
+ vAsk,
5113
+ new BN(1)
4577
5114
  );
4578
5115
  insertOrderToDLOB(
4579
5116
  dlob,
@@ -4586,7 +5123,8 @@ describe('DLOB Spot Tests', () => {
4586
5123
  BASE_PRECISION, // quantity
4587
5124
  PositionDirection.SHORT,
4588
5125
  vBid,
4589
- vAsk
5126
+ vAsk,
5127
+ new BN(1)
4590
5128
  );
4591
5129
 
4592
5130
  // should have no crossing orders
@@ -4616,7 +5154,7 @@ describe('DLOB Spot Tests', () => {
4616
5154
  PositionDirection.LONG,
4617
5155
  vBid,
4618
5156
  vAsk,
4619
- undefined,
5157
+ new BN(0),
4620
5158
  undefined,
4621
5159
  undefined,
4622
5160
  true
@@ -4633,7 +5171,7 @@ describe('DLOB Spot Tests', () => {
4633
5171
  PositionDirection.LONG,
4634
5172
  vBid,
4635
5173
  vAsk,
4636
- undefined,
5174
+ new BN(0),
4637
5175
  undefined,
4638
5176
  undefined,
4639
5177
  true
@@ -4669,6 +5207,186 @@ describe('DLOB Spot Tests', () => {
4669
5207
  expect(nodesToFillAfter[1].makerNode?.order?.orderId).to.equal(3);
4670
5208
  });
4671
5209
 
5210
+ it('Test limit orders skipping more recent post onlys', () => {
5211
+ const vAsk = new BN(15);
5212
+ const vBid = new BN(8);
5213
+
5214
+ const user0 = Keypair.generate();
5215
+ const user1 = Keypair.generate();
5216
+
5217
+ const dlob = new DLOB();
5218
+ const marketIndex = 0;
5219
+
5220
+ const slot = 12;
5221
+ const oracle = {
5222
+ price: vBid.add(vAsk).div(new BN(2)),
5223
+ slot: new BN(slot),
5224
+ confidence: new BN(1),
5225
+ hasSufficientNumberOfDataPoints: true,
5226
+ };
5227
+
5228
+ // insert some limit sells below vAMM ask, above bid
5229
+ insertOrderToDLOB(
5230
+ dlob,
5231
+ user0.publicKey,
5232
+ OrderType.LIMIT,
5233
+ MarketType.PERP,
5234
+ 1, // orderId
5235
+ marketIndex,
5236
+ new BN(14), // price
5237
+ BASE_PRECISION, // quantity
5238
+ PositionDirection.SHORT,
5239
+ vBid,
5240
+ vAsk,
5241
+ new BN(1)
5242
+ );
5243
+ insertOrderToDLOB(
5244
+ dlob,
5245
+ user1.publicKey,
5246
+ OrderType.LIMIT,
5247
+ MarketType.PERP,
5248
+ 2, // orderId
5249
+ marketIndex,
5250
+ new BN(13), // price
5251
+ BASE_PRECISION, // quantity
5252
+ PositionDirection.SHORT,
5253
+ vBid,
5254
+ vAsk,
5255
+ new BN(1)
5256
+ );
5257
+
5258
+ // should have no crossing orders
5259
+ const nodesToFillBefore = dlob.findNodesToFill(
5260
+ marketIndex,
5261
+ undefined,
5262
+ undefined,
5263
+ 12, // auction over
5264
+ Date.now(),
5265
+ MarketType.PERP,
5266
+ oracle,
5267
+ mockStateAccount,
5268
+ mockPerpMarkets[marketIndex]
5269
+ );
5270
+ expect(nodesToFillBefore.length).to.equal(0);
5271
+
5272
+ // add post only orders that are newer than resting limit orders and thus cant match
5273
+ insertOrderToDLOB(
5274
+ dlob,
5275
+ user1.publicKey,
5276
+ OrderType.LIMIT,
5277
+ MarketType.PERP,
5278
+ 3, // orderId
5279
+ marketIndex,
5280
+ new BN(15), // price
5281
+ BASE_PRECISION, // quantity
5282
+ PositionDirection.LONG,
5283
+ vBid,
5284
+ vAsk,
5285
+ new BN(2),
5286
+ undefined,
5287
+ undefined,
5288
+ true
5289
+ );
5290
+ insertOrderToDLOB(
5291
+ dlob,
5292
+ user0.publicKey,
5293
+ OrderType.LIMIT,
5294
+ MarketType.PERP,
5295
+ 4, // orderId
5296
+ marketIndex,
5297
+ new BN(14), // price
5298
+ BASE_PRECISION, // quantity
5299
+ PositionDirection.LONG,
5300
+ vBid,
5301
+ vAsk,
5302
+ new BN(2),
5303
+ undefined,
5304
+ undefined,
5305
+ true
5306
+ );
5307
+
5308
+ let nodesToFillAfter = dlob.findNodesToFill(
5309
+ marketIndex,
5310
+ undefined,
5311
+ undefined,
5312
+ slot, // auction over
5313
+ Date.now(),
5314
+ MarketType.PERP,
5315
+ oracle,
5316
+ mockStateAccount,
5317
+ mockPerpMarkets[marketIndex]
5318
+ );
5319
+
5320
+ expect(nodesToFillAfter.length).to.equal(0);
5321
+
5322
+ // add post only orders that are older than resting limit orders
5323
+ insertOrderToDLOB(
5324
+ dlob,
5325
+ user1.publicKey,
5326
+ OrderType.LIMIT,
5327
+ MarketType.PERP,
5328
+ 5, // orderId
5329
+ marketIndex,
5330
+ new BN(15), // price
5331
+ BASE_PRECISION, // quantity
5332
+ PositionDirection.LONG,
5333
+ vBid,
5334
+ vAsk,
5335
+ new BN(0),
5336
+ undefined,
5337
+ undefined,
5338
+ true
5339
+ );
5340
+ insertOrderToDLOB(
5341
+ dlob,
5342
+ user0.publicKey,
5343
+ OrderType.LIMIT,
5344
+ MarketType.PERP,
5345
+ 6, // orderId
5346
+ marketIndex,
5347
+ new BN(14), // price
5348
+ BASE_PRECISION, // quantity
5349
+ PositionDirection.LONG,
5350
+ vBid,
5351
+ vAsk,
5352
+ new BN(0),
5353
+ undefined,
5354
+ undefined,
5355
+ true
5356
+ );
5357
+
5358
+ nodesToFillAfter = dlob.findNodesToFill(
5359
+ marketIndex,
5360
+ undefined,
5361
+ undefined,
5362
+ slot, // auction over
5363
+ Date.now(),
5364
+ MarketType.PERP,
5365
+ oracle,
5366
+ mockStateAccount,
5367
+ mockPerpMarkets[marketIndex]
5368
+ );
5369
+
5370
+ expect(nodesToFillAfter.length).to.equal(2);
5371
+
5372
+ printBookState(dlob, marketIndex, vBid, vAsk, slot, oracle);
5373
+
5374
+ for (const n of nodesToFillAfter) {
5375
+ console.log(
5376
+ `cross found: taker orderId: ${n.node.order?.orderId.toString()}: BAA: ${n.node.order?.baseAssetAmountFilled.toString()}/${n.node.order?.baseAssetAmount.toString()}, maker orderId: ${n.makerNode?.order?.orderId.toString()}: BAA: ${n.makerNode?.order?.baseAssetAmountFilled.toString()}/${n.makerNode?.order?.baseAssetAmount.toString()}`
5377
+ );
5378
+ }
5379
+ expect(nodesToFillAfter.length).to.equal(2);
5380
+
5381
+ // taker should fill completely with best maker
5382
+ expect(nodesToFillAfter[0].node.order?.orderId).to.equal(2);
5383
+ expect(nodesToFillAfter[0].makerNode?.order?.orderId).to.equal(6);
5384
+
5385
+ // taker should fill completely with second best maker
5386
+ expect(nodesToFillAfter[1].node.order?.orderId).to.equal(1);
5387
+ expect(nodesToFillAfter[1].makerNode?.order?.orderId).to.equal(5);
5388
+ });
5389
+
4672
5390
  it('Test trigger orders', () => {
4673
5391
  const vAsk = new BN(15);
4674
5392
  const vBid = new BN(8);