@@ -392,65 +392,85 @@ export class UserPnlSettlerBot implements Bot {
392392 perpMarketAndOracleData [ perpMarketIdx ] . marketAccount . pnlPool ;
393393 let pnlToSettleWithUser = ZERO ;
394394 let pnlPoolTookenAmount = ZERO ;
395+ let settleUser = false ;
395396 if ( userUnsettledPnl . gt ( ZERO ) ) {
396397 pnlPoolTookenAmount = getTokenAmount (
397398 pnlPool . scaledBalance ,
398399 spotMarketAndOracleData [ pnlPool . marketIndex ] . marketAccount ,
399400 SpotBalanceType . DEPOSIT
400401 ) ;
401402 pnlToSettleWithUser = BN . min ( userUnsettledPnl , pnlPoolTookenAmount ) ;
402- }
403-
404- if ( pnlToSettleWithUser . gt ( ZERO ) ) {
405- const netUserPnl = calculateNetUserPnl (
406- perpMarketAndOracleData [ perpMarketIdx ] . marketAccount ,
407- perpMarketAndOracleData [ perpMarketIdx ] . oraclePriceData
408- ) ;
409- let maxPnlPoolExcess = ZERO ;
410- if ( netUserPnl . lt ( pnlPoolTookenAmount ) ) {
411- maxPnlPoolExcess = pnlPoolTookenAmount . sub (
412- BN . max ( netUserPnl , ZERO )
403+ if ( pnlToSettleWithUser . gt ( ZERO ) ) {
404+ const netUserPnl = calculateNetUserPnl (
405+ perpMarketAndOracleData [ perpMarketIdx ] . marketAccount ,
406+ perpMarketAndOracleData [ perpMarketIdx ] . oraclePriceData
413407 ) ;
408+ let maxPnlPoolExcess = ZERO ;
409+ if ( netUserPnl . lt ( pnlPoolTookenAmount ) ) {
410+ maxPnlPoolExcess = pnlPoolTookenAmount . sub (
411+ BN . max ( netUserPnl , ZERO )
412+ ) ;
413+ }
414+
415+ // we're only allowed to settle positive pnl if pnl pool is in excess
416+ if ( maxPnlPoolExcess . lte ( ZERO ) ) {
417+ logger . warn (
418+ `Want to settle positive PnL for user ${ user
419+ . getUserAccountPublicKey ( )
420+ . toBase58 ( ) } in market ${ perpMarketIdx } , but maxPnlPoolExcess is: (${ convertToNumber (
421+ maxPnlPoolExcess ,
422+ QUOTE_PRECISION
423+ ) } )`
424+ ) ;
425+ continue ;
426+ }
427+
428+ const netUserPnlImbalance = calculateNetUserPnlImbalance (
429+ perpMarketAndOracleData [ perpMarketIdx ] . marketAccount ,
430+ spotMarketAndOracleData [ spotMarketIdx ] . marketAccount ,
431+ perpMarketAndOracleData [ perpMarketIdx ] . oraclePriceData
432+ ) ;
433+ if ( netUserPnlImbalance . gt ( ZERO ) ) {
434+ logger . warn (
435+ `Want to settle positive PnL for user ${ user
436+ . getUserAccountPublicKey ( )
437+ . toBase58 ( ) } in market ${ perpMarketIdx } , protocol's AMM lacks excess PnL (${ convertToNumber (
438+ netUserPnlImbalance ,
439+ QUOTE_PRECISION
440+ ) } )`
441+ ) ;
442+ continue ;
443+ }
414444 }
415445
416- // we're only allowed to settle positive pnl if pnl pool is in excess
417- if ( maxPnlPoolExcess . lte ( ZERO ) ) {
446+ // only settle user pnl if they have enough collateral
447+ if ( user . canBeLiquidated ( ) . canBeLiquidated ) {
418448 logger . warn (
419- `Want to settle positive PnL for user ${ user
449+ `Want to settle negative PnL for user ${ user
420450 . getUserAccountPublicKey ( )
421- . toBase58 ( ) } in market ${ perpMarketIdx } , but maxPnlPoolExcess is: (${ convertToNumber (
422- maxPnlPoolExcess ,
423- QUOTE_PRECISION
424- ) } )`
451+ . toBase58 ( ) } , but they have insufficient collateral`
425452 ) ;
426453 continue ;
427454 }
428-
429- const netUserPnlImbalance = calculateNetUserPnlImbalance (
430- perpMarketAndOracleData [ perpMarketIdx ] . marketAccount ,
431- spotMarketAndOracleData [ spotMarketIdx ] . marketAccount ,
432- perpMarketAndOracleData [ perpMarketIdx ] . oraclePriceData
433- ) ;
434- if ( netUserPnlImbalance . gt ( ZERO ) ) {
435- logger . warn (
436- `Want to settle positive PnL for user ${ user
455+ settleUser = true ;
456+ } else {
457+ // only settle negative pnl if unsettled pnl is material
458+ if ( userUnsettledPnl . abs ( ) . gte ( this . minPnlToSettle . abs ( ) ) ) {
459+ logger . info (
460+ `Settling negative pnl for user ${ user
437461 . getUserAccountPublicKey ( )
438- . toBase58 ( ) } in market ${ perpMarketIdx } , protocol's AMM lacks excess PnL (${ convertToNumber (
439- netUserPnlImbalance ,
462+ . toBase58 ( ) } in market ${
463+ settleePosition . marketIndex
464+ } with unsettled pnl: ${ convertToNumber (
465+ userUnsettledPnl ,
440466 QUOTE_PRECISION
441- ) } ) `
467+ ) } `
442468 ) ;
443- continue ;
469+ settleUser = true ;
444470 }
445471 }
446472
447- // only settle user pnl if they have enough collateral
448- if ( user . canBeLiquidated ( ) . canBeLiquidated ) {
449- logger . warn (
450- `Want to settle negative PnL for user ${ user
451- . getUserAccountPublicKey ( )
452- . toBase58 ( ) } , but they have insufficient collateral`
453- ) ;
473+ if ( ! settleUser ) {
454474 continue ;
455475 }
456476
@@ -648,19 +668,16 @@ export class UserPnlSettlerBot implements Bot {
648668 [ ] ,
649669 this . driftClient . opts
650670 ) ;
651- logger . info (
652- `Settle PNL tx sent in ${ Date . now ( ) - sendTxStart } ms, response: ${
653- txSig . txSig
654- } `
655- ) ;
671+ const sendTxDuration = Date . now ( ) - sendTxStart ;
656672 success = true ;
657673
658674 this . logTxAndSlotForUsers (
659675 txSig ,
660676 marketIndex ,
661677 users . map (
662678 ( { settleeUserAccountPublicKey } ) => settleeUserAccountPublicKey
663- )
679+ ) ,
680+ sendTxDuration
664681 ) ;
665682 }
666683 } catch ( err ) {
@@ -698,13 +715,18 @@ export class UserPnlSettlerBot implements Bot {
698715 private logTxAndSlotForUsers (
699716 txSigAndSlot : TxSigAndSlot ,
700717 marketIndex : number ,
701- userAccountPublicKeys : Array < PublicKey >
718+ userAccountPublicKeys : Array < PublicKey > ,
719+ sendTxDuration : number
702720 ) {
703721 const txSig = txSigAndSlot . txSig ;
722+ let userStr = '' ;
723+ let countUsers = 0 ;
704724 for ( const userAccountPublicKey of userAccountPublicKeys ) {
705- logger . info (
706- `Settled pnl user ${ userAccountPublicKey . toBase58 ( ) } in market ${ marketIndex } https://solana.fm/tx/${ txSig } `
707- ) ;
725+ userStr += `${ userAccountPublicKey . toBase58 ( ) } , ` ;
726+ countUsers ++ ;
708727 }
728+ logger . info (
729+ `Settled pnl in market ${ marketIndex } . For ${ countUsers } users: ${ userStr } . Took: ${ sendTxDuration } ms. https://solana.fm/tx/${ txSig } `
730+ ) ;
709731 }
710732}
0 commit comments