diff --git a/sdk/src/dlob/DLOB.ts b/sdk/src/dlob/DLOB.ts index 370d44d39..00b5ec0b6 100644 --- a/sdk/src/dlob/DLOB.ts +++ b/sdk/src/dlob/DLOB.ts @@ -46,6 +46,7 @@ import { L3OrderBook, mergeL2LevelGenerators, } from './orderBookLevels'; +import { isUserProtectedMaker } from '../math/userStatus'; export type MarketNodeLists = { restingLimit: { @@ -158,9 +159,10 @@ export class DLOB { const userAccount = user.getUserAccount(); const userAccountPubkey = user.getUserAccountPublicKey(); const userAccountPubkeyString = userAccountPubkey.toString(); + const protectedMaker = isUserProtectedMaker(userAccount); for (const order of userAccount.orders) { - this.insertOrder(order, userAccountPubkeyString, slot); + this.insertOrder(order, userAccountPubkeyString, slot, protectedMaker); } } @@ -174,7 +176,7 @@ export class DLOB { } for (const { user, order } of dlobOrders) { - this.insertOrder(order, user.toString(), slot); + this.insertOrder(order, user.toString(), slot, false); } this.initialized = true; @@ -182,7 +184,7 @@ export class DLOB { } public handleOrderRecord(record: OrderRecord, slot: number): void { - this.insertOrder(record.order, record.user.toString(), slot); + this.insertOrder(record.order, record.user.toString(), slot, false); } public handleOrderActionRecord( @@ -197,14 +199,14 @@ export class DLOB { if (record.taker !== null) { const takerOrder = this.getOrder(record.takerOrderId, record.taker); if (takerOrder) { - this.trigger(takerOrder, record.taker, slot); + this.trigger(takerOrder, record.taker, slot, false); } } if (record.maker !== null) { const makerOrder = this.getOrder(record.makerOrderId, record.maker); if (makerOrder) { - this.trigger(makerOrder, record.maker, slot); + this.trigger(makerOrder, record.maker, slot, false); } } } else if (isVariant(record.action, 'fill')) { @@ -252,6 +254,7 @@ export class DLOB { order: Order, userAccount: string, slot: number, + isUserProtectedMaker: boolean, onInsert?: OrderBookCallback ): void { if (isVariant(order.status, 'init')) { @@ -273,7 +276,12 @@ export class DLOB { .get(marketType) .add(getOrderSignature(order.orderId, userAccount)); } - this.getListForOrder(order, slot)?.insert(order, marketType, userAccount); + this.getListForOrder(order, slot)?.insert( + order, + marketType, + userAccount, + isUserProtectedMaker + ); if (onInsert) { onInsert(); @@ -339,6 +347,7 @@ export class DLOB { order: Order, userAccount: PublicKey, slot: number, + isUserProtectedMaker: boolean, onTrigger?: OrderBookCallback ): void { if (isVariant(order.status, 'init')) { @@ -360,7 +369,8 @@ export class DLOB { this.getListForOrder(order, slot)?.insert( order, marketType, - userAccount.toString() + userAccount.toString(), + isUserProtectedMaker ); if (onTrigger) { onTrigger(); diff --git a/sdk/src/dlob/DLOBNode.ts b/sdk/src/dlob/DLOBNode.ts index bab644acb..db0592cac 100644 --- a/sdk/src/dlob/DLOBNode.ts +++ b/sdk/src/dlob/DLOBNode.ts @@ -19,6 +19,7 @@ export interface DLOBNode { isBaseFilled(): boolean; haveFilled: boolean; userAccount: string | undefined; + isUserProtectedMaker: boolean; } export abstract class OrderNode implements DLOBNode { @@ -27,12 +28,17 @@ export abstract class OrderNode implements DLOBNode { sortValue: BN; haveFilled = false; haveTrigger = false; - - constructor(order: Order, userAccount: string) { + isUserProtectedMaker: boolean; + constructor( + order: Order, + userAccount: string, + isUserProtectedMaker: boolean + ) { // Copy the order over to the node this.order = { ...order }; this.userAccount = userAccount; this.sortValue = this.getSortValue(order); + this.isUserProtectedMaker = isUserProtectedMaker; } abstract getSortValue(order: Order): BN; @@ -140,19 +146,28 @@ export type DLOBNodeType = export function createNode( nodeType: T, order: Order, - userAccount: string + userAccount: string, + isUserProtectedMaker: boolean ): DLOBNodeMap[T] { switch (nodeType) { case 'floatingLimit': - return new FloatingLimitOrderNode(order, userAccount); + return new FloatingLimitOrderNode( + order, + userAccount, + isUserProtectedMaker + ); case 'restingLimit': - return new RestingLimitOrderNode(order, userAccount); + return new RestingLimitOrderNode( + order, + userAccount, + isUserProtectedMaker + ); case 'takingLimit': - return new TakingLimitOrderNode(order, userAccount); + return new TakingLimitOrderNode(order, userAccount, isUserProtectedMaker); case 'market': - return new MarketOrderNode(order, userAccount); + return new MarketOrderNode(order, userAccount, isUserProtectedMaker); case 'trigger': - return new TriggerOrderNode(order, userAccount); + return new TriggerOrderNode(order, userAccount, isUserProtectedMaker); default: throw Error(`Unknown DLOBNode type ${nodeType}`); } diff --git a/sdk/src/dlob/NodeList.ts b/sdk/src/dlob/NodeList.ts index 7add26756..ab2dd235d 100644 --- a/sdk/src/dlob/NodeList.ts +++ b/sdk/src/dlob/NodeList.ts @@ -36,13 +36,19 @@ export class NodeList public insert( order: Order, marketType: MarketTypeStr, - userAccount: string + userAccount: string, + isUserProtectedMaker: boolean ): void { if (isVariant(order.status, 'init')) { return; } - const newNode = createNode(this.nodeType, order, userAccount); + const newNode = createNode( + this.nodeType, + order, + userAccount, + isUserProtectedMaker + ); const orderSignature = getOrderSignature(order.orderId, userAccount); if (this.nodeMap.has(orderSignature)) { @@ -178,6 +184,7 @@ export function* getVammNodeGenerator( isVammNode: () => true, order: undefined, userAccount: undefined, + isUserProtectedMaker: false, isBaseFilled: () => false, haveFilled: false, }; diff --git a/sdk/src/math/userStatus.ts b/sdk/src/math/userStatus.ts new file mode 100644 index 000000000..9a957e0a3 --- /dev/null +++ b/sdk/src/math/userStatus.ts @@ -0,0 +1,5 @@ +import { UserAccount, UserStatus } from '..'; + +export function isUserProtectedMaker(userAccount: UserAccount): boolean { + return (userAccount.status & UserStatus.PROTECTED_MAKER) > 0; +} diff --git a/sdk/src/orderSubscriber/OrderSubscriber.ts b/sdk/src/orderSubscriber/OrderSubscriber.ts index 401d06f80..6694fe4a6 100644 --- a/sdk/src/orderSubscriber/OrderSubscriber.ts +++ b/sdk/src/orderSubscriber/OrderSubscriber.ts @@ -12,6 +12,7 @@ import { EventEmitter } from 'events'; import { BN } from '../index'; import { decodeUser } from '../decode/user'; import { grpcSubscription } from './grpcSubscription'; +import { isUserProtectedMaker } from '../math/userStatus'; export class OrderSubscriber { driftClient: DriftClient; @@ -229,8 +230,9 @@ export class OrderSubscriber { public async getDLOB(slot: number): Promise { const dlob = this.createDLOB(); for (const [key, { userAccount }] of this.usersAccounts.entries()) { + const protectedMaker = isUserProtectedMaker(userAccount); for (const order of userAccount.orders) { - dlob.insertOrder(order, key, slot); + dlob.insertOrder(order, key, slot, protectedMaker); } } return dlob; diff --git a/sdk/src/types.ts b/sdk/src/types.ts index 6a48ac5ca..7c9849e32 100644 --- a/sdk/src/types.ts +++ b/sdk/src/types.ts @@ -67,6 +67,7 @@ export enum UserStatus { BANKRUPT = 2, REDUCE_ONLY = 4, ADVANCED_LP = 8, + PROTECTED_MAKER = 16, } export class MarginMode {