@drift-labs/sdk 2.0.14 → 2.0.16

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.
@@ -4448,6 +4448,258 @@ describe('DLOB Spot Tests', () => {
4448
4448
  expect(nodesToFillAfter[1].makerNode?.order?.orderId).to.equal(3);
4449
4449
  });
4450
4450
 
4451
+ it('Test market orders skipping maker with same authority', () => {
4452
+ const vAsk = new BN(15);
4453
+ const vBid = new BN(8);
4454
+
4455
+ const mockUserMap = new MockUserMap();
4456
+ const user0 = Keypair.generate();
4457
+ const userAuth0 = Keypair.generate();
4458
+ const user1 = Keypair.generate();
4459
+ const userAuth1 = Keypair.generate();
4460
+
4461
+ mockUserMap.addUserAccountAuthority(user0.publicKey, userAuth0.publicKey);
4462
+ mockUserMap.addUserAccountAuthority(user1.publicKey, userAuth1.publicKey);
4463
+
4464
+ const dlob = new DLOB(
4465
+ mockPerpMarkets,
4466
+ mockSpotMarkets,
4467
+ mockStateAccount,
4468
+ mockUserMap,
4469
+ false
4470
+ );
4471
+ const marketIndex = 0;
4472
+
4473
+ const slot = 12;
4474
+ const oracle = {
4475
+ price: vBid.add(vAsk).div(new BN(2)),
4476
+ slot: new BN(slot),
4477
+ confidence: new BN(1),
4478
+ hasSufficientNumberOfDataPoints: true,
4479
+ };
4480
+
4481
+ // insert some limit sells below vAMM ask, above bid
4482
+ insertOrderToDLOB(
4483
+ dlob,
4484
+ user0.publicKey,
4485
+ OrderType.LIMIT,
4486
+ MarketType.PERP,
4487
+ 1, // orderId
4488
+ marketIndex,
4489
+ new BN(14), // price
4490
+ BASE_PRECISION, // quantity
4491
+ PositionDirection.SHORT,
4492
+ vBid,
4493
+ vAsk
4494
+ );
4495
+ insertOrderToDLOB(
4496
+ dlob,
4497
+ user1.publicKey,
4498
+ OrderType.LIMIT,
4499
+ MarketType.PERP,
4500
+ 2, // orderId
4501
+ marketIndex,
4502
+ new BN(13), // price
4503
+ BASE_PRECISION, // quantity
4504
+ PositionDirection.SHORT,
4505
+ vBid,
4506
+ vAsk
4507
+ );
4508
+
4509
+ // should have no crossing orders
4510
+ const nodesToFillBefore = dlob.findNodesToFill(
4511
+ marketIndex,
4512
+ undefined,
4513
+ undefined,
4514
+ 12, // auction over
4515
+ Date.now(),
4516
+ MarketType.PERP,
4517
+ oracle
4518
+ );
4519
+ expect(nodesToFillBefore.length).to.equal(0);
4520
+
4521
+ // place two market buy orders to eat the best ask
4522
+ insertOrderToDLOB(
4523
+ dlob,
4524
+ user1.publicKey,
4525
+ OrderType.MARKET,
4526
+ MarketType.PERP,
4527
+ 3, // orderId
4528
+ marketIndex,
4529
+ new BN(0), // price
4530
+ BASE_PRECISION, // quantity
4531
+ PositionDirection.LONG,
4532
+ vBid,
4533
+ vAsk
4534
+ );
4535
+ insertOrderToDLOB(
4536
+ dlob,
4537
+ user0.publicKey,
4538
+ OrderType.MARKET,
4539
+ MarketType.PERP,
4540
+ 4, // orderId
4541
+ marketIndex,
4542
+ new BN(0), // price
4543
+ BASE_PRECISION, // quantity
4544
+ PositionDirection.LONG,
4545
+ vBid,
4546
+ vAsk
4547
+ );
4548
+
4549
+ const nodesToFillAfter = dlob.findNodesToFill(
4550
+ marketIndex,
4551
+ undefined,
4552
+ undefined,
4553
+ slot, // auction over
4554
+ Date.now(),
4555
+ MarketType.PERP,
4556
+ oracle
4557
+ );
4558
+
4559
+ printBookState(dlob, marketIndex, vBid, vAsk, slot, oracle);
4560
+
4561
+ for (const n of nodesToFillAfter) {
4562
+ console.log(
4563
+ `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()}`
4564
+ );
4565
+ }
4566
+ expect(nodesToFillAfter.length).to.equal(2);
4567
+
4568
+ // taker should fill completely with best maker
4569
+ expect(nodesToFillAfter[0].node.order?.orderId).to.equal(3);
4570
+ expect(nodesToFillAfter[0].makerNode?.order?.orderId).to.equal(1);
4571
+
4572
+ // taker should fill completely with second best maker
4573
+ expect(nodesToFillAfter[1].node.order?.orderId).to.equal(4);
4574
+ expect(nodesToFillAfter[1].makerNode?.order?.orderId).to.equal(2);
4575
+ });
4576
+
4577
+ it('Test limit orders skipping maker with same authority', () => {
4578
+ const vAsk = new BN(15);
4579
+ const vBid = new BN(8);
4580
+
4581
+ const mockUserMap = new MockUserMap();
4582
+ const user0 = Keypair.generate();
4583
+ const userAuth0 = Keypair.generate();
4584
+ const user1 = Keypair.generate();
4585
+ const userAuth1 = Keypair.generate();
4586
+
4587
+ mockUserMap.addUserAccountAuthority(user0.publicKey, userAuth0.publicKey);
4588
+ mockUserMap.addUserAccountAuthority(user1.publicKey, userAuth1.publicKey);
4589
+
4590
+ const dlob = new DLOB(
4591
+ mockPerpMarkets,
4592
+ mockSpotMarkets,
4593
+ mockStateAccount,
4594
+ mockUserMap,
4595
+ false
4596
+ );
4597
+ const marketIndex = 0;
4598
+
4599
+ const slot = 12;
4600
+ const oracle = {
4601
+ price: vBid.add(vAsk).div(new BN(2)),
4602
+ slot: new BN(slot),
4603
+ confidence: new BN(1),
4604
+ hasSufficientNumberOfDataPoints: true,
4605
+ };
4606
+
4607
+ // insert some limit sells below vAMM ask, above bid
4608
+ insertOrderToDLOB(
4609
+ dlob,
4610
+ user0.publicKey,
4611
+ OrderType.LIMIT,
4612
+ MarketType.PERP,
4613
+ 1, // orderId
4614
+ marketIndex,
4615
+ new BN(14), // price
4616
+ BASE_PRECISION, // quantity
4617
+ PositionDirection.SHORT,
4618
+ vBid,
4619
+ vAsk
4620
+ );
4621
+ insertOrderToDLOB(
4622
+ dlob,
4623
+ user1.publicKey,
4624
+ OrderType.LIMIT,
4625
+ MarketType.PERP,
4626
+ 2, // orderId
4627
+ marketIndex,
4628
+ new BN(13), // price
4629
+ BASE_PRECISION, // quantity
4630
+ PositionDirection.SHORT,
4631
+ vBid,
4632
+ vAsk
4633
+ );
4634
+
4635
+ // should have no crossing orders
4636
+ const nodesToFillBefore = dlob.findNodesToFill(
4637
+ marketIndex,
4638
+ undefined,
4639
+ undefined,
4640
+ 12, // auction over
4641
+ Date.now(),
4642
+ MarketType.PERP,
4643
+ oracle
4644
+ );
4645
+ expect(nodesToFillBefore.length).to.equal(0);
4646
+
4647
+ // place two market buy orders to eat the best ask
4648
+ insertOrderToDLOB(
4649
+ dlob,
4650
+ user1.publicKey,
4651
+ OrderType.LIMIT,
4652
+ MarketType.PERP,
4653
+ 3, // orderId
4654
+ marketIndex,
4655
+ new BN(15), // price
4656
+ BASE_PRECISION, // quantity
4657
+ PositionDirection.LONG,
4658
+ vBid,
4659
+ vAsk
4660
+ );
4661
+ insertOrderToDLOB(
4662
+ dlob,
4663
+ user0.publicKey,
4664
+ OrderType.LIMIT,
4665
+ MarketType.PERP,
4666
+ 4, // orderId
4667
+ marketIndex,
4668
+ new BN(14), // price
4669
+ BASE_PRECISION, // quantity
4670
+ PositionDirection.LONG,
4671
+ vBid,
4672
+ vAsk
4673
+ );
4674
+
4675
+ const nodesToFillAfter = dlob.findNodesToFill(
4676
+ marketIndex,
4677
+ undefined,
4678
+ undefined,
4679
+ slot, // auction over
4680
+ Date.now(),
4681
+ MarketType.PERP,
4682
+ oracle
4683
+ );
4684
+
4685
+ printBookState(dlob, marketIndex, vBid, vAsk, slot, oracle);
4686
+
4687
+ for (const n of nodesToFillAfter) {
4688
+ console.log(
4689
+ `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()}`
4690
+ );
4691
+ }
4692
+ expect(nodesToFillAfter.length).to.equal(2);
4693
+
4694
+ // taker should fill completely with best maker
4695
+ expect(nodesToFillAfter[0].node.order?.orderId).to.equal(2);
4696
+ expect(nodesToFillAfter[0].makerNode?.order?.orderId).to.equal(4);
4697
+
4698
+ // taker should fill completely with second best maker
4699
+ expect(nodesToFillAfter[1].node.order?.orderId).to.equal(1);
4700
+ expect(nodesToFillAfter[1].makerNode?.order?.orderId).to.equal(3);
4701
+ });
4702
+
4451
4703
  it('Test trigger orders', () => {
4452
4704
  const vAsk = new BN(15);
4453
4705
  const vBid = new BN(8);
@@ -1,77 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.EventList = void 0;
4
- class Node {
5
- constructor(event, next, prev) {
6
- this.event = event;
7
- this.next = next;
8
- this.prev = prev;
9
- }
10
- }
11
- class EventList {
12
- constructor(eventType, maxSize, sortFn, orderDirection) {
13
- this.eventType = eventType;
14
- this.maxSize = maxSize;
15
- this.sortFn = sortFn;
16
- this.orderDirection = orderDirection;
17
- this.size = 0;
18
- }
19
- insert(event) {
20
- this.size++;
21
- const newNode = new Node(event);
22
- if (this.head === undefined) {
23
- this.head = this.tail = newNode;
24
- return;
25
- }
26
- if (this.sortFn(this.head.event, newNode.event) ===
27
- (this.orderDirection === 'asc' ? 'less than' : 'greater than')) {
28
- this.head.prev = newNode;
29
- newNode.next = this.head;
30
- this.head = newNode;
31
- }
32
- else {
33
- let currentNode = this.head;
34
- while (currentNode.next !== undefined &&
35
- this.sortFn(currentNode.next.event, newNode.event) !==
36
- (this.orderDirection === 'asc' ? 'less than' : 'greater than')) {
37
- currentNode = currentNode.next;
38
- }
39
- newNode.next = currentNode.next;
40
- if (currentNode.next !== undefined) {
41
- newNode.next.prev = newNode;
42
- }
43
- currentNode.next = newNode;
44
- newNode.prev = currentNode;
45
- }
46
- if (this.size > this.maxSize) {
47
- this.detach();
48
- }
49
- }
50
- detach() {
51
- const node = this.tail;
52
- if (node.prev !== undefined) {
53
- node.prev.next = node.next;
54
- }
55
- else {
56
- this.head = node.next;
57
- }
58
- if (node.next !== undefined) {
59
- node.next.prev = node.prev;
60
- }
61
- else {
62
- this.tail = node.prev;
63
- }
64
- this.size--;
65
- }
66
- toArray() {
67
- return Array.from(this);
68
- }
69
- *[Symbol.iterator]() {
70
- let node = this.head;
71
- while (node) {
72
- yield node.event;
73
- node = node.next;
74
- }
75
- }
76
- }
77
- exports.EventList = EventList;