Skip to content

Commit ebf118a

Browse files
committed
feat: get rid of v300 partial liquidation bots
1 parent bff08f4 commit ebf118a

File tree

6 files changed

+91
-341
lines changed

6 files changed

+91
-341
lines changed

src/plugins/bots/BotsPlugin.ts

Lines changed: 30 additions & 155 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,13 @@
1-
import {
2-
type Address,
3-
decodeAbiParameters,
4-
encodeAbiParameters,
5-
stringToHex,
6-
} from "viem";
1+
import { encodeAbiParameters, stringToHex } from "viem";
72
import { iBytecodeRepositoryAbi } from "../../abi/310/iBytecodeRepository.js";
8-
import { peripheryCompressorAbi } from "../../abi/compressors/peripheryCompressor.js";
93
import type { IGearboxSDKPlugin } from "../../sdk/index.js";
104
import {
115
AddressMap,
126
AP_BYTECODE_REPOSITORY,
13-
AP_PERIPHERY_COMPRESSOR,
147
AP_TREASURY,
158
BasePlugin,
169
chains as CHAINS,
1710
hexEq,
18-
isV300,
19-
isV310,
20-
TypedObjectUtils,
21-
VERSION_RANGE_310,
2211
} from "../../sdk/index.js";
2312
import { iPartialLiquidationBotV310Abi } from "./abi/iPartialLiquidationBotV310.js";
2413
import {
@@ -27,88 +16,40 @@ import {
2716
PARTIAL_LIQUIDATION_BOT_DEPLOYER,
2817
PARTIAL_LIQUIDATION_BOT_SALT,
2918
} from "./config.js";
30-
import { PartialLiquidationBotV300Contract } from "./PartialLiquidationBotV300Contract.js";
3119
import { PartialLiquidationBotV310Contract } from "./PartialLiquidationBotV310Contract.js";
3220
import {
3321
BOT_PARAMS_ABI,
22+
BOT_PARTIAL_LIQUIDATION,
3423
type BotParameters,
35-
type BotState,
3624
type BotsPluginState,
3725
type BotsPluginStateHuman,
38-
LIQUIDATION_BOT_TYPES,
3926
type MigrationBotState,
4027
} from "./types.js";
4128

42-
export class UnsupportedBotVersionError extends Error {
43-
public readonly state: BotState;
44-
45-
constructor(state: BotState) {
46-
super(
47-
`unsupported bot version ${state.baseParams.version} for bot at ${state.baseParams.addr}`,
48-
);
49-
this.state = state;
50-
}
51-
}
52-
53-
export type PartialLiquidationBotContract =
54-
| PartialLiquidationBotV300Contract
55-
| PartialLiquidationBotV310Contract;
56-
5729
export class BotsPlugin
5830
extends BasePlugin<BotsPluginState>
5931
implements IGearboxSDKPlugin<BotsPluginState>
6032
{
61-
#botsByMarket?: AddressMap<PartialLiquidationBotContract[]>;
33+
#bots?: AddressMap<PartialLiquidationBotV310Contract>;
6234

6335
public get loaded(): boolean {
64-
return !!this.#botsByMarket;
36+
return !!this.#bots;
37+
}
38+
39+
public get bots(): PartialLiquidationBotV310Contract[] {
40+
return this.#bots?.values() ?? [];
6541
}
6642

6743
public async load(force?: boolean): Promise<BotsPluginState> {
6844
if (!force && this.loaded) {
6945
return this.state;
7046
}
71-
72-
const [pcAddr] = this.sdk.addressProvider.mustGetLatest(
73-
AP_PERIPHERY_COMPRESSOR,
74-
VERSION_RANGE_310,
75-
);
76-
this.logger?.debug(`loading bots with periphery compressor ${pcAddr}`);
77-
const mcs = this.sdk.marketRegister.marketConfigurators.map(
78-
mc => mc.address,
79-
);
80-
81-
const botsData = await this.client.multicall({
82-
contracts: mcs.map(
83-
mc =>
84-
({
85-
address: pcAddr,
86-
abi: peripheryCompressorAbi,
87-
functionName: "getBots",
88-
args: [mc],
89-
}) as const,
90-
),
91-
allowFailure: false,
92-
});
93-
94-
this.#botsByMarket = new AddressMap();
95-
for (let i = 0; i < mcs.length; i++) {
96-
const mc = mcs[i];
97-
const marketBotData = botsData[i];
98-
this.#loadStateMarketState(mc, marketBotData);
99-
}
100-
return this.state;
101-
}
102-
103-
public async findDeployedPartialLiquidationBots(): Promise<
104-
AddressMap<BotParameters>
105-
> {
10647
const treasury = this.sdk.addressProvider.getAddress(AP_TREASURY);
10748
const bcr = this.sdk.addressProvider.getAddress(AP_BYTECODE_REPOSITORY);
10849
const configs = PARTIAL_LIQUIDATION_BOT_CONFIGS[this.sdk.networkType] ?? [];
109-
const result = new AddressMap<BotParameters>();
50+
this.#bots = new AddressMap<PartialLiquidationBotV310Contract>();
11051
if (!configs.length) {
111-
return result;
52+
return this.state;
11253
}
11354
const deployedBots = await this.client.multicall({
11455
contracts: configs.map(
@@ -118,7 +59,7 @@ export class BotsPlugin
11859
abi: iBytecodeRepositoryAbi,
11960
functionName: "computeAddress",
12061
args: [
121-
stringToHex("BOT::PARTIAL_LIQUIDATION", { size: 32 }),
62+
stringToHex(BOT_PARTIAL_LIQUIDATION, { size: 32 }),
12263
310,
12364
encodeAbiParameters(BOT_PARAMS_ABI, [
12465
treasury,
@@ -170,116 +111,50 @@ export class BotsPlugin
170111
const serialized = serializedBots[i];
171112
const expected = expectedBots.mustGet(botAddrs[i]);
172113
if (serialized.status === "success") {
173-
const [
174-
treasury,
175-
minHealthFactor,
176-
maxHealthFactor,
177-
premiumScaleFactor,
178-
feeScaleFactor,
179-
] = decodeAbiParameters(BOT_PARAMS_ABI, serialized.result);
114+
const bot = new PartialLiquidationBotV310Contract(this.sdk, {
115+
addr: botAddrs[i],
116+
version: BigInt(310),
117+
contractType: BOT_PARTIAL_LIQUIDATION,
118+
serializedParams: serialized.result,
119+
});
180120
if (
181121
!hexEq(treasury, expected.treasury) ||
182-
minHealthFactor !== expected.minHealthFactor ||
183-
maxHealthFactor !== expected.maxHealthFactor ||
184-
premiumScaleFactor !== expected.premiumScaleFactor ||
185-
feeScaleFactor !== expected.feeScaleFactor
122+
bot.minHealthFactor !== expected.minHealthFactor ||
123+
bot.maxHealthFactor !== expected.maxHealthFactor ||
124+
bot.premiumScaleFactor !== expected.premiumScaleFactor ||
125+
bot.feeScaleFactor !== expected.feeScaleFactor
186126
) {
187127
this.logger?.error(
188128
`serialized bot ${botAddrs[i]} does not match expected bot`,
189129
serialized.error,
190130
);
191131
} else {
192-
result.upsert(botAddrs[i], expected);
132+
this.#bots.upsert(botAddrs[i], bot);
193133
}
194134
}
195135
}
196-
return result;
197-
}
198-
199-
#loadStateMarketState(mc: Address, state: readonly BotState[]): void {
200-
// for v300, assume that each market configurator has exactly 4 bots
201-
// sort them by minHealthFactor and assign type based on index
202-
const bots = state
203-
.map(state => this.#createBot(mc, state))
204-
.sort((a, b) => a.minHealthFactor - b.minHealthFactor);
205-
if (bots.length && isV300(Number(bots[0].version))) {
206-
if (bots.length !== 4) {
207-
throw new Error(`expected 4 bots v300 for market configurator ${mc}`);
208-
}
209-
for (let i = 0; i < bots.length; i++) {
210-
(bots[i] as PartialLiquidationBotV300Contract).botType =
211-
LIQUIDATION_BOT_TYPES[i];
212-
}
213-
}
214-
this.botsByMarket.upsert(mc, bots);
136+
return this.state;
215137
}
216138

217139
public stateHuman(raw?: boolean): BotsPluginStateHuman {
218140
return {
219-
bots: Object.fromEntries(
220-
this.botsByMarket
221-
.entries()
222-
.map(([mc, bots]) => [
223-
this.labelAddress(mc),
224-
bots.map(b => b.stateHuman(raw)),
225-
]),
226-
),
141+
bots: this.#bots?.values().map(bot => bot.stateHuman(raw)) ?? [],
227142
};
228143
}
229144

230-
public get botsByMarket(): AddressMap<PartialLiquidationBotContract[]> {
231-
if (!this.#botsByMarket) {
232-
throw new Error("bots plugin not loaded");
233-
}
234-
return this.#botsByMarket;
235-
}
236-
237-
public botsByMarketConfigurator(
238-
mc: Address,
239-
): PartialLiquidationBotContract[] {
240-
return this.botsByMarket.get(mc) ?? [];
241-
}
242-
243-
public get allBots(): PartialLiquidationBotContract[] {
244-
return this.botsByMarket.values().flat();
245-
}
246-
247145
public get state(): BotsPluginState {
248146
return {
249-
bots: TypedObjectUtils.fromEntries(
250-
this.botsByMarket
251-
.entries()
252-
.map(([mc, bots]) => [mc, bots.map(b => b.state)]),
253-
),
147+
bots: this.#bots?.values().map(bot => bot.state) ?? [],
254148
};
255149
}
256150

257151
public hydrate(state: BotsPluginState): void {
258-
this.#botsByMarket = new AddressMap();
259-
for (const [mc, botStates] of TypedObjectUtils.entries(state.bots)) {
260-
this.#loadStateMarketState(mc, botStates);
261-
}
262-
}
263-
264-
#createBot(
265-
marketConfigurator: Address,
266-
data: BotState,
267-
): PartialLiquidationBotContract {
268-
const v = Number(data.baseParams.version);
269-
if (isV300(v)) {
270-
return new PartialLiquidationBotV300Contract(
271-
this.sdk,
272-
data,
273-
marketConfigurator,
274-
);
275-
} else if (isV310(v)) {
276-
return new PartialLiquidationBotV310Contract(
277-
this.sdk,
278-
data,
279-
marketConfigurator,
152+
this.#bots = new AddressMap();
153+
for (const botState of state.bots) {
154+
this.#bots.upsert(
155+
botState.addr,
156+
new PartialLiquidationBotV310Contract(this.sdk, botState),
280157
);
281-
} else {
282-
throw new Error(`unsupported bot version: ${v}`);
283158
}
284159
}
285160

src/plugins/bots/PartialLiquidationBotBaseContract.ts

Lines changed: 0 additions & 85 deletions
This file was deleted.

0 commit comments

Comments
 (0)