Skip to content

Commit d915a52

Browse files
authored
Merge pull request #413 from Gearbox-protocol/bot-fixes
fix: better support for v310 bots
2 parents ebf118a + 2348196 commit d915a52

File tree

5 files changed

+97
-29
lines changed

5 files changed

+97
-29
lines changed

src/plugins/bots/config.ts

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -44,17 +44,14 @@ export const LEGACY_MIGRATION_BOT: MigrationBotState = {
4444
address: ACCOUNT_MIGRATOR_BOT,
4545
previewer: ACCOUNT_MIGRATOR_PREVIEWER,
4646
version: 310,
47-
botType: "MIGRATION_BOT",
47+
baseType: "LEGACY_MIGRATION",
4848
};
4949

50-
export const PERMISSION_BY_TYPE: Record<BotBaseType, bigint> = {
51-
LIQUIDATION_PROTECTION: BigInt(
52-
BotPermissions.ADD_COLLATERAL |
53-
BotPermissions.WITHDRAW_COLLATERAL |
54-
BotPermissions.DECREASE_DEBT,
55-
),
56-
57-
MIGRATION: BigInt(
50+
export const PERMISSION_BY_TYPE: Record<
51+
Extract<BotBaseType, "LEGACY_MIGRATION">,
52+
bigint
53+
> = {
54+
LEGACY_MIGRATION: BigInt(
5855
BotPermissions.EXTERNAL_CALLS |
5956
BotPermissions.UPDATE_QUOTA |
6057
BotPermissions.DECREASE_DEBT,

src/plugins/bots/types.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,11 @@ export interface BotsPluginState {
4040
bots: BotState[];
4141
}
4242

43-
export type BotBaseType = "LIQUIDATION_PROTECTION" | "MIGRATION";
44-
45-
export const MIGRATION_BOT_TYPES = ["MIGRATION_BOT"] as const;
46-
export type MigrationBotType = (typeof MIGRATION_BOT_TYPES)[number];
43+
export type BotBaseType = "LIQUIDATION_PROTECTION" | "LEGACY_MIGRATION";
4744

4845
export type MigrationBotState = {
4946
address: Address;
5047
version: 310;
51-
5248
previewer: Address;
53-
botType: MigrationBotType;
49+
baseType: Extract<BotBaseType, "LEGACY_MIGRATION">;
5450
};

src/sdk/accounts/AbstractCreditAccountsService.ts

Lines changed: 57 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import type { ILogger, IPriceUpdateTx, MultiCall } from "../types/index.js";
3939
import { AddressMap, childLogger } from "../utils/index.js";
4040
import { simulateWithPriceUpdates } from "../utils/viem/index.js";
4141
import type {
42+
AccountToCheck,
4243
AddCollateralProps,
4344
ChangeDeptProps,
4445
ClaimDelayedProps,
@@ -280,18 +281,22 @@ export abstract class AbstractCreditAccountService extends SDKConstruct {
280281

281282
/**
282283
* Method to get all connected bots for credit account
283-
* @param {Array<{ creditAccount: Address; creditManager: Address }>} accountsToCheck - list of credit accounts
284+
* @param {Array<AccountToCheck>} accountsToCheck - list of credit accounts
284285
and their credit managers to check connected bots on
285286
* @returns call result of getConnectedBots for each credit account
286287
*/
287288
public async getConnectedBots(
288-
accountsToCheck: Array<{ creditAccount: Address; creditManager: Address }>,
289+
accountsToCheck: Array<AccountToCheck>,
289290
legacyMigrationBot: Address | undefined,
291+
additionalBots: Array<Address>,
290292
): Promise<{
291293
legacy: GetConnectedBotsResult;
292294
legacyMigration: GetConnectedMigrationBotsResult;
295+
additionalBots: Array<
296+
Omit<NonNullable<GetConnectedMigrationBotsResult>, "botAddress">
297+
>;
293298
}> {
294-
const [resp, migration] = await Promise.all([
299+
const [resp, migration, additional] = await Promise.all([
295300
this.client.multicall({
296301
contracts: accountsToCheck.map(o => {
297302
const pool = this.sdk.marketRegister.findByCreditManager(
@@ -308,15 +313,58 @@ export abstract class AbstractCreditAccountService extends SDKConstruct {
308313
allowFailure: true,
309314
}),
310315
this.getActiveMigrationBots(accountsToCheck, legacyMigrationBot),
316+
this.getActiveBots(accountsToCheck, additionalBots),
311317
]);
312318

313-
return { legacy: resp, legacyMigration: migration };
319+
return {
320+
legacy: resp,
321+
additionalBots: additional,
322+
legacyMigration: migration,
323+
};
324+
}
325+
private async getActiveBots(
326+
accountsToCheck: Array<AccountToCheck>,
327+
bots: Array<Address>,
328+
) {
329+
const result = await this.client.multicall({
330+
contracts: accountsToCheck.flatMap(ca => {
331+
const cm = this.sdk.marketRegister.findCreditManager(ca.creditManager);
332+
333+
return bots.map(bot => {
334+
return {
335+
abi: isV300(cm.creditFacade.version)
336+
? iBotListV300Abi
337+
: iBotListV310Abi,
338+
address: cm.creditFacade.botList,
339+
functionName: "getBotStatus",
340+
args: isV300(cm.creditFacade.version)
341+
? [bot, ca.creditManager, ca.creditAccount]
342+
: [bot, ca.creditAccount],
343+
} as const;
344+
});
345+
}),
346+
allowFailure: true,
347+
});
348+
349+
const botsByCAIndex = accountsToCheck.reduce<
350+
Array<Omit<NonNullable<GetConnectedMigrationBotsResult>, "botAddress">>
351+
>((acc, _, index) => {
352+
const r = result.slice(index * bots.length, (index + 1) * bots.length);
353+
354+
acc.push({
355+
result: r,
356+
});
357+
358+
return acc;
359+
}, []);
360+
361+
return botsByCAIndex;
314362
}
315363
private async getActiveMigrationBots(
316364
accountsToCheck: Array<{ creditAccount: Address; creditManager: Address }>,
317-
legacyMigrationBot: Address | undefined,
365+
bot: Address | undefined,
318366
) {
319-
if (legacyMigrationBot) {
367+
if (bot) {
320368
const result = await this.client.multicall({
321369
contracts: accountsToCheck.map(ca => {
322370
const cm = this.sdk.marketRegister.findCreditManager(
@@ -330,14 +378,14 @@ export abstract class AbstractCreditAccountService extends SDKConstruct {
330378
address: cm.creditFacade.botList,
331379
functionName: "getBotStatus",
332380
args: isV300(cm.creditFacade.version)
333-
? [legacyMigrationBot, ca.creditManager, ca.creditAccount]
334-
: [legacyMigrationBot, ca.creditAccount],
381+
? [bot, ca.creditManager, ca.creditAccount]
382+
: [bot, ca.creditAccount],
335383
} as const;
336384
}),
337385
allowFailure: true,
338386
});
339387

340-
return { result, botAddress: legacyMigrationBot };
388+
return { result, botAddress: bot };
341389
}
342390

343391
return undefined;

src/sdk/accounts/CreditAccountsServiceV310.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { encodeFunctionData } from "viem";
1+
import { encodeFunctionData, getContract } from "viem";
22
import { iCreditFacadeMulticallV310Abi } from "../../abi/310/generated.js";
33
import { MAX_UINT256 } from "../constants/math.js";
44
import type { MultiCall } from "../types/index.js";
@@ -23,7 +23,7 @@ export class CreditAccountServiceV310
2323
*/
2424
public async setBot({
2525
botAddress,
26-
permissions,
26+
permissions: defaultPermissions,
2727

2828
targetContract,
2929
}: SetBotProps): Promise<
@@ -41,6 +41,24 @@ export class CreditAccountServiceV310
4141
})
4242
: [];
4343

44+
const permissions =
45+
defaultPermissions !== null
46+
? defaultPermissions
47+
: await getContract({
48+
address: botAddress,
49+
client: this.sdk.client,
50+
abi: [
51+
{
52+
type: "function",
53+
name: "requiredPermissions",
54+
inputs: [],
55+
outputs: [
56+
{ name: "", type: "uint192", internalType: "uint192" },
57+
],
58+
stateMutability: "view",
59+
},
60+
],
61+
}).read.requiredPermissions();
4462
const addBotCall: MultiCall = {
4563
target: cm.creditFacade.address,
4664
callData: encodeFunctionData({

src/sdk/accounts/types.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,11 @@ export interface WithdrawCollateralProps extends PrepareUpdateQuotasProps {
204204
creditAccount: RouterCASlice;
205205
}
206206

207+
export type AccountToCheck = {
208+
creditAccount: Address;
209+
creditManager: Address;
210+
};
211+
207212
export interface ExecuteSwapProps extends PrepareUpdateQuotasProps {
208213
/**
209214
* Array of MultiCall from router methods getSingleSwap or getAllSwaps
@@ -447,7 +452,7 @@ export interface SetBotProps {
447452
/**
448453
* Permissions to set for the bot
449454
*/
450-
permissions: bigint;
455+
permissions: bigint | null;
451456
/**
452457
* Minimal credit account data {@link RouterCASlice} on which operation is performed; if omitted, credit manager data is used
453458
* Minimal credit manager data {@link CMSlice} on which operation is performed; used only if credit account is omitted
@@ -522,17 +527,21 @@ export interface ICreditAccountsService extends SDKConstruct {
522527
getRewards(creditAccount: Address): Promise<Array<Rewards>>;
523528
/**
524529
* Method to get all connected bots for credit account
525-
* @param {Array<{ creditAccount: Address; creditManager: Address }>} accountsToCheck - list of credit accounts
530+
* @param {Array<AccountToCheck>} accountsToCheck - list of credit accounts
526531
* @param {Address | undefined} legacyMigrationBot - address of the bot to check connected bots on
527532
* and their credit managers to check connected bots on
528533
* @returns call result of getConnectedBots for each credit account
529534
*/
530535
getConnectedBots(
531-
accountsToCheck: Array<{ creditAccount: Address; creditManager: Address }>,
536+
accountsToCheck: Array<AccountToCheck>,
532537
legacyMigrationBot: Address | undefined,
538+
additionalBots: Array<Address>,
533539
): Promise<{
534540
legacy: GetConnectedBotsResult;
535541
legacyMigration: GetConnectedMigrationBotsResult;
542+
additionalBots: Array<
543+
Omit<NonNullable<GetConnectedMigrationBotsResult>, "botAddress">
544+
>;
536545
}>;
537546
/**
538547
* V3.1 method, throws in V3. Connects/disables a bot and updates prices

0 commit comments

Comments
 (0)