@@ -344,6 +344,170 @@ func TestTWAPOrderWithMatchingOrders(t *testing.T) {
344344 require .Equal (t , ctx .BlockTime ().Unix ()+ int64 (twapOrder .TwapParameters .Interval ), triggerTime )
345345}
346346
347+ func TestTWAPOrderWithMatchingOrdersWhereTWAPOrderIsMaker (t * testing.T ) {
348+ tApp := testapp .NewTestAppBuilder (t ).Build ()
349+ ctx := tApp .InitChain ()
350+
351+ // Place a TWAP order to buy 100B quantums over 4 legs
352+ twapOrder := clobtypes.Order {
353+ OrderId : clobtypes.OrderId {
354+ SubaccountId : constants .Alice_Num0 ,
355+ ClientId : 0 ,
356+ OrderFlags : clobtypes .OrderIdFlags_Twap ,
357+ ClobPairId : 0 ,
358+ },
359+ Side : clobtypes .Order_SIDE_BUY ,
360+ Quantums : 100_000_000_000 , // 100B quantums
361+ Subticks : 200_000_000 , // $20,000 per oracle price
362+ TwapParameters : & clobtypes.TwapParameters {
363+ Duration : 320 ,
364+ Interval : 80 ,
365+ PriceTolerance : 10_000 ,
366+ },
367+ GoodTilOneof : & clobtypes.Order_GoodTilBlockTime {
368+ GoodTilBlockTime : uint32 (ctx .BlockTime ().Unix () + 100 ),
369+ },
370+ }
371+
372+ // Place a matching sell order at the same price
373+ matchingOrder := clobtypes.Order {
374+ OrderId : clobtypes.OrderId {
375+ SubaccountId : constants .Bob_Num0 ,
376+ ClientId : 0 ,
377+ OrderFlags : clobtypes .OrderIdFlags_LongTerm ,
378+ ClobPairId : 0 ,
379+ },
380+ Side : clobtypes .Order_SIDE_SELL ,
381+ Quantums : 50_000_000_000 , // 50B quantums
382+ Subticks : 200_000_000 , // $20,000 per oracle price
383+ GoodTilOneof : & clobtypes.Order_GoodTilBlockTime {
384+ GoodTilBlockTime : uint32 (ctx .BlockTime ().Unix () + 3600 ),
385+ },
386+ }
387+
388+ // Place the TWAP order so the first suborder is resting on the book
389+ for _ , checkTx := range testapp .MustMakeCheckTxsWithClobMsg (
390+ ctx ,
391+ tApp .App ,
392+ * clobtypes .NewMsgPlaceOrder (twapOrder ),
393+ ) {
394+ resp := tApp .CheckTx (checkTx )
395+ require .True (t , resp .IsOK (), "Expected CheckTx to succeed. Response: %+v" , resp )
396+ }
397+
398+ suborderId := clobtypes.OrderId {
399+ SubaccountId : constants .Alice_Num0 ,
400+ ClientId : 0 ,
401+ OrderFlags : clobtypes .OrderIdFlags_TwapSuborder ,
402+ ClobPairId : 0 ,
403+ }
404+
405+ ctx = tApp .AdvanceToBlock (2 , testapp.AdvanceToBlockOptions {})
406+
407+ // Place market order sell order as a taker order
408+ for _ , checkTx := range testapp .MustMakeCheckTxsWithClobMsg (
409+ ctx ,
410+ tApp .App ,
411+ * clobtypes .NewMsgPlaceOrder (matchingOrder ),
412+ ) {
413+ resp := tApp .CheckTx (checkTx )
414+ require .True (t , resp .IsOK (), "Expected CheckTx to succeed. Response: %+v" , resp )
415+ }
416+
417+ ctx = tApp .AdvanceToBlock (3 , testapp.AdvanceToBlockOptions {})
418+
419+ ctx = tApp .AdvanceToBlock (4 , testapp.AdvanceToBlockOptions {
420+ BlockTime : ctx .BlockTime ().Add (time .Second * 40 ),
421+ RequestPrepareProposalTxsOverride : [][]byte {
422+ testtx .MustGetTxBytes (& clobtypes.MsgProposedOperations {
423+ OperationsQueue : []clobtypes.OperationRaw {
424+ clobtestutils .NewMatchOperationRaw (
425+ & clobtypes.Order {
426+ OrderId : matchingOrder .OrderId ,
427+ Side : clobtypes .Order_SIDE_SELL ,
428+ Quantums : 50_000_000_000 ,
429+ Subticks : 200_000_000 ,
430+ },
431+ []clobtypes.MakerFill {
432+ {
433+ FillAmount : 25_000_000_000 ,
434+ MakerOrderId : suborderId ,
435+ },
436+ },
437+ ),
438+ },
439+ }),
440+ },
441+ })
442+
443+ // Verify TWAP order state is updated
444+ twapOrderPlacement , found := tApp .App .ClobKeeper .GetTwapOrderPlacement (
445+ ctx ,
446+ twapOrder .OrderId ,
447+ )
448+ require .True (t , found , "TWAP order placement should exist" )
449+ require .Equal (t , uint32 (3 ), twapOrderPlacement .RemainingLegs )
450+ require .Equal (t , uint64 (75_000_000_000 ), twapOrderPlacement .RemainingQuantums ) // 100B - 25B filled
451+
452+ _ , triggerTime , found1 := tApp .App .ClobKeeper .GetTwapTriggerPlacement (
453+ ctx ,
454+ suborderId ,
455+ )
456+ require .True (t , found1 , "Second suborder should exist in trigger store" )
457+
458+ require .Equal (t , int64 (80 ), triggerTime )
459+
460+ _ , placed_suborder1_found := tApp .App .ClobKeeper .MemClob .GetOrder (suborderId )
461+ require .False (t , placed_suborder1_found , "Second suborder should not have been placed yet" )
462+
463+ ctx = tApp .AdvanceToBlock (5 , testapp.AdvanceToBlockOptions {
464+ BlockTime : ctx .BlockTime ().Add (time .Second * 40 ),
465+ })
466+
467+ filled_amount := tApp .App .ClobKeeper .MemClob .GetOrderFilledAmount (ctx , suborderId )
468+ require .Equal (t , uint64 (25_000_000_000 ), filled_amount .ToUint64 ())
469+
470+ ctx = tApp .AdvanceToBlock (6 , testapp.AdvanceToBlockOptions {
471+ BlockTime : ctx .BlockTime ().Add (time .Second * 0 ),
472+ RequestPrepareProposalTxsOverride : [][]byte {
473+ testtx .MustGetTxBytes (& clobtypes.MsgProposedOperations {
474+ OperationsQueue : []clobtypes.OperationRaw {
475+ clobtestutils .NewMatchOperationRaw (
476+ & clobtypes.Order {
477+ OrderId : suborderId ,
478+ Side : clobtypes .Order_SIDE_BUY ,
479+ Quantums : 25_000_000_000 ,
480+ Subticks : 200_000_000 ,
481+ },
482+ []clobtypes.MakerFill {
483+ {
484+ FillAmount : 25_000_000_000 ,
485+ MakerOrderId : matchingOrder .OrderId ,
486+ },
487+ },
488+ ),
489+ },
490+ }),
491+ },
492+ })
493+
494+ // Verify TWAP order state is updated again
495+ twapOrderPlacement , found = tApp .App .ClobKeeper .GetTwapOrderPlacement (
496+ ctx ,
497+ twapOrder .OrderId ,
498+ )
499+ require .True (t , found , "TWAP order placement should still exist" )
500+ require .Equal (t , uint32 (2 ), twapOrderPlacement .RemainingLegs )
501+ require .Equal (t , uint64 (50_000_000_000 ), twapOrderPlacement .RemainingQuantums ) // 75B - 25B filled
502+
503+ _ , triggerTime , found2 := tApp .App .ClobKeeper .GetTwapTriggerPlacement (
504+ ctx ,
505+ suborderId ,
506+ )
507+ require .True (t , found2 , "Third suborder should exist in trigger store" )
508+ require .Equal (t , ctx .BlockTime ().Unix ()+ int64 (twapOrder .TwapParameters .Interval ), triggerTime )
509+ }
510+
347511func TestTwapOrderStopsPlacingSubordersWhenCollateralIsDepleted (t * testing.T ) {
348512 tApp := testapp .NewTestAppBuilder (t ).Build ()
349513 ctx := tApp .InitChain ()
0 commit comments