Skip to content

Commit 1ef2911

Browse files
committed
fix: pass price updates to paginated accounts and isLiquidatable check
1 parent 937fe74 commit 1ef2911

File tree

2 files changed

+46
-20
lines changed

2 files changed

+46
-20
lines changed

src/services/RedstoneServiceV3.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,14 @@ import {
99
tickerInfoTokensByNetwork,
1010
tokenSymbolByAddress,
1111
} from "@gearbox-protocol/sdk-gov";
12-
import { iCreditFacadeV3MulticallAbi } from "@gearbox-protocol/types/abi";
12+
import {
13+
iCreditFacadeV3MulticallAbi,
14+
iUpdatablePriceFeedAbi,
15+
} from "@gearbox-protocol/types/abi";
1316
import { DataServiceWrapper } from "@redstone-finance/evm-connector";
1417
import type { SignedDataPackage } from "redstone-protocol";
1518
import { RedstonePayload } from "redstone-protocol";
16-
import type { Address } from "viem";
19+
import type { Address, MulticallContracts } from "viem";
1720
import {
1821
encodeAbiParameters,
1922
encodeFunctionData,
@@ -210,6 +213,19 @@ export class RedstoneServiceV3 {
210213
);
211214
}
212215

216+
public toDirectMulticallUpdates(
217+
priceUpdates?: PriceOnDemandExtras[],
218+
): MulticallContracts<unknown[]> {
219+
return (
220+
priceUpdates?.map(({ callData, address }) => ({
221+
abi: iUpdatablePriceFeedAbi,
222+
address,
223+
functionName: "updatePrice",
224+
args: [callData],
225+
})) ?? []
226+
);
227+
}
228+
213229
public async dataCompressorUpdates(
214230
ca: CreditAccountData,
215231
): Promise<PriceOnDemand[]> {

src/services/scanner/Scanner.ts

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ export class Scanner {
255255
result.push(accData);
256256
}
257257
return liquidatableOnly
258-
? this.#filterLiquidatable(result, blockNumber)
258+
? this.#filterLiquidatable(result, priceUpdates, blockNumber)
259259
: this.#filterZeroDebt(result);
260260
}
261261

@@ -303,7 +303,7 @@ export class Scanner {
303303
cms: Address[],
304304
selection: AccountSelection,
305305
): Promise<CreditAccountDataRaw[]> {
306-
const { liquidatableOnly, blockNumber } = selection;
306+
const { liquidatableOnly, blockNumber, priceUpdates } = selection;
307307
const accs: CreditAccountDataRaw[] = [];
308308
// do not use Promise.all, because it crashes anvil
309309
for (const cm of cms) {
@@ -314,7 +314,7 @@ export class Scanner {
314314
`loaded ${accs.length} credit accounts from ${cms.length} credit managers`,
315315
);
316316
return liquidatableOnly
317-
? this.#filterLiquidatable(accs, blockNumber)
317+
? this.#filterLiquidatable(accs, priceUpdates, blockNumber)
318318
: this.#filterZeroDebt(accs);
319319
}
320320

@@ -334,7 +334,7 @@ export class Scanner {
334334
async #getAccountsFromManager2(
335335
cm: Address,
336336
{ priceUpdates, blockNumber }: AccountSelection,
337-
pageSize = 25,
337+
pageSize = 30,
338338
): Promise<CreditAccountDataRaw[]> {
339339
const accAddrs = await this.client.pub.readContract({
340340
address: cm,
@@ -348,17 +348,22 @@ export class Scanner {
348348
for (let i = 0; i < accAddrs.length; i += pageSize) {
349349
const page = accAddrs.slice(i, i + pageSize);
350350
const resp = await simulateMulticall(this.client.pub, {
351-
contracts: page.map(acc => ({
352-
address: this.dataCompressor.address,
353-
abi: iDataCompressorV3Abi,
354-
functionName: "getCreditAccountData",
355-
args: [acc, priceUpdates],
356-
})),
351+
contracts: [
352+
...this.redstone.toDirectMulticallUpdates(priceUpdates),
353+
...page.map(acc => ({
354+
address: this.dataCompressor.address,
355+
abi: iDataCompressorV3Abi,
356+
functionName: "getCreditAccountData",
357+
args: [acc, priceUpdates],
358+
})),
359+
],
357360
blockNumber,
358361
allowFailure: false,
359362
gas: 550_000_000n,
360363
});
361-
result.push(...(resp as any as CreditAccountDataRaw[]));
364+
result.push(
365+
...(resp.slice(priceUpdates.length) as CreditAccountDataRaw[]),
366+
);
362367
this.log.debug(
363368
`loaded page ${i + 1} of ${accAddrs.length} accounts from ${cm}`,
364369
);
@@ -372,22 +377,27 @@ export class Scanner {
372377

373378
async #filterLiquidatable(
374379
accs: CreditAccountDataRaw[],
380+
priceUpdates: PriceOnDemandExtras[],
375381
blockNumber?: bigint,
376382
): Promise<CreditAccountDataRaw[]> {
377383
this.log.debug(
378384
`filtering liquidatable credit accounts from selection of ${accs.length}...`,
379385
);
380386
// @ts-ignore
381-
const mc = await this.client.pub.multicall({
387+
let mc = await this.client.pub.multicall({
382388
blockNumber,
383389
allowFailure: true,
384-
contracts: accs.map(({ addr, creditManager }) => ({
385-
address: creditManager as Address,
386-
abi: iCreditManagerV3Abi,
387-
functionName: "isLiquidatable",
388-
args: [addr as Address, PERCENTAGE_FACTOR],
389-
})),
390+
contracts: [
391+
...this.redstone.toDirectMulticallUpdates(priceUpdates),
392+
...accs.map(({ addr, creditManager }) => ({
393+
address: creditManager as Address,
394+
abi: iCreditManagerV3Abi,
395+
functionName: "isLiquidatable",
396+
args: [addr as Address, PERCENTAGE_FACTOR],
397+
})),
398+
],
390399
});
400+
mc = mc.slice(priceUpdates.length);
391401
const result = accs.filter(
392402
(_, i) => mc[i].status === "success" && mc[i].result,
393403
);

0 commit comments

Comments
 (0)