diff --git a/apps/alpha-liquidator/src/config.ts b/apps/alpha-liquidator/src/config.ts index d79eb19df7..c66e5cf6f5 100644 --- a/apps/alpha-liquidator/src/config.ts +++ b/apps/alpha-liquidator/src/config.ts @@ -31,7 +31,8 @@ if (!process.env.RPC_ENDPOINT) { /*eslint sort-keys: "error"*/ let envSchema = z.object({ ACCOUNT_COOL_DOWN_SECONDS: z.string().default("120").transform((s) => parseInt(s, 10)), - ACCOUNT_REFRESH_INTERVAL_SECONDS: z.string().default("600").transform((s) => parseInt(s, 10)), + /// 30 minutes + ACCOUNT_REFRESH_INTERVAL_SECONDS: z.string().default("1800").transform((s) => parseInt(s, 10)), EXCLUDE_ISOLATED_BANKS: z.string().optional().default("false").transform((s) => s === "true" || s === "1"), IS_DEV: z .string() @@ -84,6 +85,7 @@ let envSchema = z.object({ return Keypair.fromSecretKey(new Uint8Array(JSON.parse(keypairStr))); } }), + WS_ENDPOINT: z.string().url().optional(), WS_RESET_INTERVAL_SECONDS: z.string().optional().default("300").transform((s) => parseInt(s, 10)), }); diff --git a/apps/alpha-liquidator/src/liquidator.ts b/apps/alpha-liquidator/src/liquidator.ts index 035779fe71..6dbf7b1819 100644 --- a/apps/alpha-liquidator/src/liquidator.ts +++ b/apps/alpha-liquidator/src/liquidator.ts @@ -81,6 +81,12 @@ class Liquidator { console.log("Start with DEBUG=mfi:* to see more logs"); + try { + await this.rebalanceIfNeeded(); + } catch (e) { + console.error("Error during initial rebalance: ", e); + } + await this.startLiquidatorDataLoader(); await this.mainLoop(); } @@ -227,7 +233,15 @@ class Liquidator { console.log("Loading data, this may take a moment...") const debug = getDebugLogger("load-all-marginfi-accounts"); debug("Loading all Marginfi accounts"); - const allKeys = (await this.client.getAllMarginfiAccountAddresses()); + let allKeys = []; + + // If whitelist is set, filter out all accounts that are not in the whitelist + if (env_config.MARGINFI_ACCOUNT_WHITELIST) { + allKeys = env_config.MARGINFI_ACCOUNT_WHITELIST; + } else { + allKeys = (await this.client.getAllMarginfiAccountAddresses()); + } + debug("Retrieved all Marginfi account addresses, found: %d", allKeys.length); const [slot, ais] = await chunkedGetRawMultipleAccountInfos(this.connection, allKeys.map((k) => k.toBase58()), 16 * 64, 64); debug("Received account information for slot %d, got: %d accounts", slot, ais.size); @@ -242,15 +256,11 @@ class Liquidator { this.accountInfos.set(pubkey, account); processedAccounts++; - if (processedAccounts % 1000 === 0) { + if (processedAccounts % 5000 === 0) { const progress = ((processedAccounts / totalAccounts) * 100).toFixed(2); debug("Processed %d accounts out of %d (%s%%)", processedAccounts, totalAccounts, progress); } } - if (processedAccounts % 1000 !== 0) { - const progress = ((processedAccounts / totalAccounts) * 100).toFixed(2); - debug("Final progress: %s%%", progress); - } console.log("Finished loading all Marginfi accounts"); } @@ -273,14 +283,12 @@ class Liquidator { const accountInfo = info.accountInfo; if (accountInfo.data.length !== this.client.program.account.marginfiAccount.size) { - debug("Received account update for account with public key: %s, but data length is incorrect", pubkey.toBase58()); return; } try { const account = MarginfiAccountWrapper.fromAccountDataRaw(pubkey, this.client, accountInfo.data); this.accountInfos.set(pubkey, account); - debug("Updated Marginfi account for public key: %s", pubkey.toBase58()); } catch (error) { debug("Failed to decode Marginfi account for public key: %s, Error: %s", pubkey.toBase58(), error); } @@ -450,7 +458,6 @@ class Liquidator { private async rebalancingStage() { const debug = getDebugLogger("rebalancing-stage"); debug("Starting rebalancing stage"); - captureMessage("Starting rebalancing stage"); await this.sellNonUsdcDeposits(); await this.repayAllDebt(); await this.depositRemainingUsdc(); @@ -480,6 +487,14 @@ class Liquidator { } } + private async swapNonUsdcInTokenAccounts2() { + const debug = getDebugLogger("swap-non-usdc-in-token-accounts"); + debug("Swapping any remaining non-usdc to usdc"); + + const banks = Array.from(this.client.banks.values()).filter((bank) => !bank.mint.equals(USDC_MINT)); + const usdcBank = this.client.getBankByMint(USDC_MINT)!; + } + private async swapNonUsdcInTokenAccounts() { const debug = getDebugLogger("swap-non-usdc-in-token-accounts"); debug("Swapping any remaining non-usdc to usdc"); diff --git a/apps/alpha-liquidator/src/utils/connection.ts b/apps/alpha-liquidator/src/utils/connection.ts index 2cec04c3e3..415f7ea1c5 100644 --- a/apps/alpha-liquidator/src/utils/connection.ts +++ b/apps/alpha-liquidator/src/utils/connection.ts @@ -14,6 +14,7 @@ const createConnection = () => new Connection(env_config.RPC_ENDPOINT, { commitment, fetch: fetchWithRetry, + wsEndpoint: env_config.WS_ENDPOINT, }); export let connection = createConnection(); diff --git a/packages/marginfi-client-v2/src/client.ts b/packages/marginfi-client-v2/src/client.ts index bd9443f5cf..23f045d45f 100644 --- a/packages/marginfi-client-v2/src/client.ts +++ b/packages/marginfi-client-v2/src/client.ts @@ -464,7 +464,7 @@ class MarginfiClient { try { const getLatestBlockhashAndContext = await connection.getLatestBlockhashAndContext(); - minContextSlot = getLatestBlockhashAndContext.context.slot; + minContextSlot = getLatestBlockhashAndContext.context.slot - 4; blockhash = getLatestBlockhashAndContext.value.blockhash; lastValidBlockHeight = getLatestBlockhashAndContext.value.lastValidBlockHeight; @@ -526,7 +526,7 @@ class MarginfiClient { }; signature = await connection.sendTransaction(versionedTransaction, { - minContextSlot: mergedOpts.minContextSlot, + // minContextSlot: mergedOpts.minContextSlot, skipPreflight: mergedOpts.skipPreflight, preflightCommitment: mergedOpts.preflightCommitment, maxRetries: mergedOpts.maxRetries,