From 6655afee8f03292cbb2d89d3ab5e8316641b964f Mon Sep 17 00:00:00 2001 From: "Ricardo J. Mendez" Date: Wed, 16 Feb 2022 09:32:09 +0100 Subject: [PATCH] Improvements on settling perp pnl This is an optimization on f97370f following Dafy's suggestion here: https://github.com/blockworks-foundation/liquidator-v3/pull/17#issuecomment-1020808416 It uses the client's settlePosPnl function instead of doing all the work itself. It required making the mangoAccounts array global so we can have access to it when liquidating from the RPC endpoint, but I'm not getting any movement from the feed anyway. --- src/liquidator.ts | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/liquidator.ts b/src/liquidator.ts index 588e05d..df3d2cd 100644 --- a/src/liquidator.ts +++ b/src/liquidator.ts @@ -91,6 +91,7 @@ let liqorMangoAccount: MangoAccount; let spotMarkets: Market[]; let perpMarkets: PerpMarket[]; let rootBanks: (RootBank | undefined)[]; +let mangoAccounts: MangoAccount[] = []; async function main() { console.log(`Starting liquidator for ${groupName}...`); @@ -164,7 +165,6 @@ async function main() { // never returns async function liquidatableFromSolanaRpc() { - let mangoAccounts: MangoAccount[] = []; await refreshAccounts(mangoGroup, mangoAccounts); watchAccounts(groupIds.mangoProgramId, mangoGroup, mangoAccounts); @@ -357,6 +357,7 @@ async function liquidatableFromLiquidatableFeed() { if (!candidatesSet.has(account)) { candidatesSet.add(account); candidates.enqueue(account); + console.log(`Enqueued ${account.publicKey.toBase58()}`) } }); @@ -551,7 +552,7 @@ async function liquidateAccount( rootBanks: (RootBank | undefined)[], perpMarkets: PerpMarket[], liqee: MangoAccount, - liqor: MangoAccount, + liqor: MangoAccount ) { const hasPerpOpenOrders = liqee.perpAccounts.some( (pa) => pa.bidsQuantity.gt(ZERO_BN) || pa.asksQuantity.gt(ZERO_BN), @@ -814,7 +815,7 @@ async function liquidatePerps( perpMarkets: PerpMarket[], rootBanks: (RootBank | undefined)[], liqee: MangoAccount, - liqor: MangoAccount, + liqor: MangoAccount ) { console.log('liquidatePerps'); const lowestHealthMarket = perpMarkets @@ -852,8 +853,8 @@ async function liquidatePerps( const liqorInitHealth = liqor.getHealth(mangoGroup, cache, 'Init'); let maxLiabTransfer = liqorInitHealth.mul(liabLimit); + const quoteRootBank = rootBanks[QUOTE_INDEX]; if (liqee.isBankrupt) { - const quoteRootBank = rootBanks[QUOTE_INDEX]; if (quoteRootBank) { // don't do anything it if quote position is zero console.log('resolvePerpBankruptcy', maxLiabTransfer.toString()); @@ -873,6 +874,16 @@ async function liquidatePerps( let maxNet = ZERO_I80F48; let maxNetIndex = mangoGroup.tokens.length - 1; + // We need to settle the positive PnLs to make sure that the account has funds + // to actually compensate for a liquidation. Otherwise we may end up with a + // token liquidation of 0. + // + // https://discord.com/channels/791995070613159966/826034521261604874/934629112734167060 + + if (quoteRootBank) { + await client.settlePosPnl(mangoGroup, cache, liqee, perpMarkets, quoteRootBank, payer, mangoAccounts) + } + for (let i = 0; i < mangoGroup.tokens.length; i++) { const price = cache.priceCache[i] ? cache.priceCache[i].price