@gearbox-protocol/sdk 11.11.3 → 11.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/dist/cjs/plugins/bots/BotsPlugin.js +26 -111
  2. package/dist/cjs/plugins/bots/PartialLiquidationBotV310Contract.js +38 -6
  3. package/dist/cjs/plugins/bots/config.js +2 -5
  4. package/dist/cjs/plugins/bots/index.js +0 -2
  5. package/dist/cjs/plugins/bots/types.js +3 -11
  6. package/dist/cjs/sdk/accounts/AbstractCreditAccountsService.js +38 -9
  7. package/dist/cjs/sdk/accounts/CreditAccountsServiceV310.js +16 -1
  8. package/dist/esm/plugins/bots/BotsPlugin.js +28 -121
  9. package/dist/esm/plugins/bots/PartialLiquidationBotV310Contract.js +41 -6
  10. package/dist/esm/plugins/bots/config.js +2 -5
  11. package/dist/esm/plugins/bots/index.js +0 -1
  12. package/dist/esm/plugins/bots/types.js +2 -9
  13. package/dist/esm/sdk/accounts/AbstractCreditAccountsService.js +38 -9
  14. package/dist/esm/sdk/accounts/CreditAccountsServiceV310.js +17 -2
  15. package/dist/types/plugins/bots/BotsPlugin.d.ts +3 -13
  16. package/dist/types/plugins/bots/PartialLiquidationBotV310Contract.d.ts +19 -6
  17. package/dist/types/plugins/bots/config.d.ts +1 -1
  18. package/dist/types/plugins/bots/index.d.ts +0 -1
  19. package/dist/types/plugins/bots/types.d.ts +10 -25
  20. package/dist/types/sdk/accounts/AbstractCreditAccountsService.d.ts +5 -6
  21. package/dist/types/sdk/accounts/CreditAccountsServiceV310.d.ts +1 -1
  22. package/dist/types/sdk/accounts/types.d.ts +8 -6
  23. package/package.json +1 -1
  24. package/dist/cjs/plugins/bots/PartialLiquidationBotBaseContract.js +0 -75
  25. package/dist/cjs/plugins/bots/PartialLiquidationBotV300Contract.js +0 -65
  26. package/dist/esm/plugins/bots/PartialLiquidationBotBaseContract.js +0 -53
  27. package/dist/esm/plugins/bots/PartialLiquidationBotV300Contract.js +0 -41
  28. package/dist/types/plugins/bots/PartialLiquidationBotBaseContract.d.ts +0 -25
  29. package/dist/types/plugins/bots/PartialLiquidationBotV300Contract.d.ts +0 -227
@@ -18,71 +18,34 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var BotsPlugin_exports = {};
20
20
  __export(BotsPlugin_exports, {
21
- BotsPlugin: () => BotsPlugin,
22
- UnsupportedBotVersionError: () => UnsupportedBotVersionError
21
+ BotsPlugin: () => BotsPlugin
23
22
  });
24
23
  module.exports = __toCommonJS(BotsPlugin_exports);
25
24
  var import_viem = require("viem");
26
25
  var import_iBytecodeRepository = require("../../abi/310/iBytecodeRepository.js");
27
- var import_peripheryCompressor = require("../../abi/compressors/peripheryCompressor.js");
28
26
  var import_sdk = require("../../sdk/index.js");
29
27
  var import_iPartialLiquidationBotV310 = require("./abi/iPartialLiquidationBotV310.js");
30
28
  var import_config = require("./config.js");
31
- var import_PartialLiquidationBotV300Contract = require("./PartialLiquidationBotV300Contract.js");
32
29
  var import_PartialLiquidationBotV310Contract = require("./PartialLiquidationBotV310Contract.js");
33
30
  var import_types = require("./types.js");
34
- class UnsupportedBotVersionError extends Error {
35
- state;
36
- constructor(state) {
37
- super(
38
- `unsupported bot version ${state.baseParams.version} for bot at ${state.baseParams.addr}`
39
- );
40
- this.state = state;
41
- }
42
- }
43
31
  class BotsPlugin extends import_sdk.BasePlugin {
44
- #botsByMarket;
32
+ #bots;
45
33
  get loaded() {
46
- return !!this.#botsByMarket;
34
+ return !!this.#bots;
35
+ }
36
+ get bots() {
37
+ return this.#bots?.values() ?? [];
47
38
  }
48
39
  async load(force) {
49
40
  if (!force && this.loaded) {
50
41
  return this.state;
51
42
  }
52
- const [pcAddr] = this.sdk.addressProvider.mustGetLatest(
53
- import_sdk.AP_PERIPHERY_COMPRESSOR,
54
- import_sdk.VERSION_RANGE_310
55
- );
56
- this.logger?.debug(`loading bots with periphery compressor ${pcAddr}`);
57
- const mcs = this.sdk.marketRegister.marketConfigurators.map(
58
- (mc) => mc.address
59
- );
60
- const botsData = await this.client.multicall({
61
- contracts: mcs.map(
62
- (mc) => ({
63
- address: pcAddr,
64
- abi: import_peripheryCompressor.peripheryCompressorAbi,
65
- functionName: "getBots",
66
- args: [mc]
67
- })
68
- ),
69
- allowFailure: false
70
- });
71
- this.#botsByMarket = new import_sdk.AddressMap();
72
- for (let i = 0; i < mcs.length; i++) {
73
- const mc = mcs[i];
74
- const marketBotData = botsData[i];
75
- this.#loadStateMarketState(mc, marketBotData);
76
- }
77
- return this.state;
78
- }
79
- async findDeployedPartialLiquidationBots() {
80
43
  const treasury = this.sdk.addressProvider.getAddress(import_sdk.AP_TREASURY);
81
44
  const bcr = this.sdk.addressProvider.getAddress(import_sdk.AP_BYTECODE_REPOSITORY);
82
45
  const configs = import_config.PARTIAL_LIQUIDATION_BOT_CONFIGS[this.sdk.networkType] ?? [];
83
- const result = new import_sdk.AddressMap();
46
+ this.#bots = new import_sdk.AddressMap();
84
47
  if (!configs.length) {
85
- return result;
48
+ return this.state;
86
49
  }
87
50
  const deployedBots = await this.client.multicall({
88
51
  contracts: configs.map(
@@ -91,7 +54,7 @@ class BotsPlugin extends import_sdk.BasePlugin {
91
54
  abi: import_iBytecodeRepository.iBytecodeRepositoryAbi,
92
55
  functionName: "computeAddress",
93
56
  args: [
94
- (0, import_viem.stringToHex)("BOT::PARTIAL_LIQUIDATION", { size: 32 }),
57
+ (0, import_viem.stringToHex)(import_types.BOT_PARTIAL_LIQUIDATION, { size: 32 }),
95
58
  310,
96
59
  (0, import_viem.encodeAbiParameters)(import_types.BOT_PARAMS_ABI, [
97
60
  treasury,
@@ -141,88 +104,41 @@ class BotsPlugin extends import_sdk.BasePlugin {
141
104
  const serialized = serializedBots[i];
142
105
  const expected = expectedBots.mustGet(botAddrs[i]);
143
106
  if (serialized.status === "success") {
144
- const [
145
- treasury2,
146
- minHealthFactor,
147
- maxHealthFactor,
148
- premiumScaleFactor,
149
- feeScaleFactor
150
- ] = (0, import_viem.decodeAbiParameters)(import_types.BOT_PARAMS_ABI, serialized.result);
151
- if (!(0, import_sdk.hexEq)(treasury2, expected.treasury) || minHealthFactor !== expected.minHealthFactor || maxHealthFactor !== expected.maxHealthFactor || premiumScaleFactor !== expected.premiumScaleFactor || feeScaleFactor !== expected.feeScaleFactor) {
107
+ const bot = new import_PartialLiquidationBotV310Contract.PartialLiquidationBotV310Contract(this.sdk, {
108
+ addr: botAddrs[i],
109
+ version: BigInt(310),
110
+ contractType: import_types.BOT_PARTIAL_LIQUIDATION,
111
+ serializedParams: serialized.result
112
+ });
113
+ if (!(0, import_sdk.hexEq)(treasury, expected.treasury) || bot.minHealthFactor !== expected.minHealthFactor || bot.maxHealthFactor !== expected.maxHealthFactor || bot.premiumScaleFactor !== expected.premiumScaleFactor || bot.feeScaleFactor !== expected.feeScaleFactor) {
152
114
  this.logger?.error(
153
115
  `serialized bot ${botAddrs[i]} does not match expected bot`,
154
116
  serialized.error
155
117
  );
156
118
  } else {
157
- result.upsert(botAddrs[i], expected);
119
+ this.#bots.upsert(botAddrs[i], bot);
158
120
  }
159
121
  }
160
122
  }
161
- return result;
162
- }
163
- #loadStateMarketState(mc, state) {
164
- const bots = state.map((state2) => this.#createBot(mc, state2)).sort((a, b) => a.minHealthFactor - b.minHealthFactor);
165
- if (bots.length && (0, import_sdk.isV300)(Number(bots[0].version))) {
166
- if (bots.length !== 4) {
167
- throw new Error(`expected 4 bots v300 for market configurator ${mc}`);
168
- }
169
- for (let i = 0; i < bots.length; i++) {
170
- bots[i].botType = import_types.LIQUIDATION_BOT_TYPES[i];
171
- }
172
- }
173
- this.botsByMarket.upsert(mc, bots);
123
+ return this.state;
174
124
  }
175
125
  stateHuman(raw) {
176
126
  return {
177
- bots: Object.fromEntries(
178
- this.botsByMarket.entries().map(([mc, bots]) => [
179
- this.labelAddress(mc),
180
- bots.map((b) => b.stateHuman(raw))
181
- ])
182
- )
127
+ bots: this.#bots?.values().map((bot) => bot.stateHuman(raw)) ?? []
183
128
  };
184
129
  }
185
- get botsByMarket() {
186
- if (!this.#botsByMarket) {
187
- throw new Error("bots plugin not loaded");
188
- }
189
- return this.#botsByMarket;
190
- }
191
- botsByMarketConfigurator(mc) {
192
- return this.botsByMarket.get(mc) ?? [];
193
- }
194
- get allBots() {
195
- return this.botsByMarket.values().flat();
196
- }
197
130
  get state() {
198
131
  return {
199
- bots: import_sdk.TypedObjectUtils.fromEntries(
200
- this.botsByMarket.entries().map(([mc, bots]) => [mc, bots.map((b) => b.state)])
201
- )
132
+ bots: this.#bots?.values().map((bot) => bot.state) ?? []
202
133
  };
203
134
  }
204
135
  hydrate(state) {
205
- this.#botsByMarket = new import_sdk.AddressMap();
206
- for (const [mc, botStates] of import_sdk.TypedObjectUtils.entries(state.bots)) {
207
- this.#loadStateMarketState(mc, botStates);
208
- }
209
- }
210
- #createBot(marketConfigurator, data) {
211
- const v = Number(data.baseParams.version);
212
- if ((0, import_sdk.isV300)(v)) {
213
- return new import_PartialLiquidationBotV300Contract.PartialLiquidationBotV300Contract(
214
- this.sdk,
215
- data,
216
- marketConfigurator
217
- );
218
- } else if ((0, import_sdk.isV310)(v)) {
219
- return new import_PartialLiquidationBotV310Contract.PartialLiquidationBotV310Contract(
220
- this.sdk,
221
- data,
222
- marketConfigurator
136
+ this.#bots = new import_sdk.AddressMap();
137
+ for (const botState of state.bots) {
138
+ this.#bots.upsert(
139
+ botState.addr,
140
+ new import_PartialLiquidationBotV310Contract.PartialLiquidationBotV310Contract(this.sdk, botState)
223
141
  );
224
- } else {
225
- throw new Error(`unsupported bot version: ${v}`);
226
142
  }
227
143
  }
228
144
  static getMigrationBotData(chainId) {
@@ -231,6 +147,5 @@ class BotsPlugin extends import_sdk.BasePlugin {
231
147
  }
232
148
  // Annotate the CommonJS export names for ESM import in node:
233
149
  0 && (module.exports = {
234
- BotsPlugin,
235
- UnsupportedBotVersionError
150
+ BotsPlugin
236
151
  });
@@ -21,18 +21,50 @@ __export(PartialLiquidationBotV310Contract_exports, {
21
21
  PartialLiquidationBotV310Contract: () => PartialLiquidationBotV310Contract
22
22
  });
23
23
  module.exports = __toCommonJS(PartialLiquidationBotV310Contract_exports);
24
+ var import_viem = require("viem");
25
+ var import_sdk = require("../../sdk/index.js");
24
26
  var import_abi = require("./abi/index.js");
25
- var import_PartialLiquidationBotBaseContract = require("./PartialLiquidationBotBaseContract.js");
27
+ var import_types = require("./types.js");
26
28
  const abi = import_abi.iPartialLiquidationBotV310Abi;
27
- class PartialLiquidationBotV310Contract extends import_PartialLiquidationBotBaseContract.PartialLiquidationBotBaseContract {
28
- constructor(sdk, args, marketConfigurator) {
29
+ class PartialLiquidationBotV310Contract extends import_sdk.BaseContract {
30
+ treasury;
31
+ minHealthFactor;
32
+ maxHealthFactor;
33
+ premiumScaleFactor;
34
+ feeScaleFactor;
35
+ #serializedParams;
36
+ constructor(sdk, args) {
29
37
  super(sdk, {
38
+ ...args,
30
39
  abi,
31
- ...args.baseParams,
32
- requiredPermissions: args.requiredPermissions,
33
- marketConfigurator,
34
40
  name: "PartialLiquidationBotV310"
35
41
  });
42
+ [
43
+ this.treasury,
44
+ this.minHealthFactor,
45
+ this.maxHealthFactor,
46
+ this.premiumScaleFactor,
47
+ this.feeScaleFactor
48
+ ] = (0, import_viem.decodeAbiParameters)(import_types.BOT_PARAMS_ABI, args.serializedParams);
49
+ this.#serializedParams = args.serializedParams;
50
+ }
51
+ stateHuman(raw) {
52
+ return {
53
+ ...super.stateHuman(raw),
54
+ treasury: this.treasury,
55
+ minHealthFactor: (0, import_sdk.formatPercentage)(this.minHealthFactor),
56
+ maxHealthFactor: (0, import_sdk.formatPercentage)(this.maxHealthFactor),
57
+ premiumScaleFactor: (0, import_sdk.formatPercentage)(this.premiumScaleFactor),
58
+ feeScaleFactor: (0, import_sdk.formatPercentage)(this.feeScaleFactor)
59
+ };
60
+ }
61
+ get state() {
62
+ return {
63
+ addr: this.address,
64
+ version: BigInt(this.version),
65
+ contractType: (0, import_viem.stringToHex)(this.contractType, { size: 32 }),
66
+ serializedParams: this.#serializedParams
67
+ };
36
68
  }
37
69
  }
38
70
  // Annotate the CommonJS export names for ESM import in node:
@@ -60,13 +60,10 @@ const LEGACY_MIGRATION_BOT = {
60
60
  address: ACCOUNT_MIGRATOR_BOT,
61
61
  previewer: ACCOUNT_MIGRATOR_PREVIEWER,
62
62
  version: 310,
63
- botType: "MIGRATION_BOT"
63
+ baseType: "LEGACY_MIGRATION"
64
64
  };
65
65
  const PERMISSION_BY_TYPE = {
66
- LIQUIDATION_PROTECTION: BigInt(
67
- import_sdk.BotPermissions.ADD_COLLATERAL | import_sdk.BotPermissions.WITHDRAW_COLLATERAL | import_sdk.BotPermissions.DECREASE_DEBT
68
- ),
69
- MIGRATION: BigInt(
66
+ LEGACY_MIGRATION: BigInt(
70
67
  import_sdk.BotPermissions.EXTERNAL_CALLS | import_sdk.BotPermissions.UPDATE_QUOTA | import_sdk.BotPermissions.DECREASE_DEBT
71
68
  )
72
69
  };
@@ -18,7 +18,6 @@ module.exports = __toCommonJS(bots_exports);
18
18
  __reExport(bots_exports, require("./abi/index.js"), module.exports);
19
19
  __reExport(bots_exports, require("./BotsPlugin.js"), module.exports);
20
20
  __reExport(bots_exports, require("./config.js"), module.exports);
21
- __reExport(bots_exports, require("./PartialLiquidationBotV300Contract.js"), module.exports);
22
21
  __reExport(bots_exports, require("./PartialLiquidationBotV310Contract.js"), module.exports);
23
22
  __reExport(bots_exports, require("./types.js"), module.exports);
24
23
  // Annotate the CommonJS export names for ESM import in node:
@@ -26,7 +25,6 @@ __reExport(bots_exports, require("./types.js"), module.exports);
26
25
  ...require("./abi/index.js"),
27
26
  ...require("./BotsPlugin.js"),
28
27
  ...require("./config.js"),
29
- ...require("./PartialLiquidationBotV300Contract.js"),
30
28
  ...require("./PartialLiquidationBotV310Contract.js"),
31
29
  ...require("./types.js")
32
30
  });
@@ -19,10 +19,10 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
19
19
  var types_exports = {};
20
20
  __export(types_exports, {
21
21
  BOT_PARAMS_ABI: () => BOT_PARAMS_ABI,
22
- LIQUIDATION_BOT_TYPES: () => LIQUIDATION_BOT_TYPES,
23
- MIGRATION_BOT_TYPES: () => MIGRATION_BOT_TYPES
22
+ BOT_PARTIAL_LIQUIDATION: () => BOT_PARTIAL_LIQUIDATION
24
23
  });
25
24
  module.exports = __toCommonJS(types_exports);
25
+ const BOT_PARTIAL_LIQUIDATION = "BOT::PARTIAL_LIQUIDATION";
26
26
  const BOT_PARAMS_ABI = [
27
27
  { type: "address", name: "treasury" },
28
28
  { type: "uint16", name: "minHealthFactor" },
@@ -30,16 +30,8 @@ const BOT_PARAMS_ABI = [
30
30
  { type: "uint16", name: "premiumScaleFactor" },
31
31
  { type: "uint16", name: "feeScaleFactor" }
32
32
  ];
33
- const LIQUIDATION_BOT_TYPES = [
34
- "PARTIAL_LIQUIDATION_BOT",
35
- "DELEVERAGE_BOT_PEGGED",
36
- "DELEVERAGE_BOT_LV",
37
- "DELEVERAGE_BOT_HV"
38
- ];
39
- const MIGRATION_BOT_TYPES = ["MIGRATION_BOT"];
40
33
  // Annotate the CommonJS export names for ESM import in node:
41
34
  0 && (module.exports = {
42
35
  BOT_PARAMS_ABI,
43
- LIQUIDATION_BOT_TYPES,
44
- MIGRATION_BOT_TYPES
36
+ BOT_PARTIAL_LIQUIDATION
45
37
  });
@@ -205,12 +205,12 @@ class AbstractCreditAccountService extends import_base.SDKConstruct {
205
205
  }
206
206
  /**
207
207
  * Method to get all connected bots for credit account
208
- * @param {Array<{ creditAccount: Address; creditManager: Address }>} accountsToCheck - list of credit accounts
208
+ * @param {Array<AccountToCheck>} accountsToCheck - list of credit accounts
209
209
  and their credit managers to check connected bots on
210
210
  * @returns call result of getConnectedBots for each credit account
211
211
  */
212
- async getConnectedBots(accountsToCheck, legacyMigrationBot) {
213
- const [resp, migration] = await Promise.all([
212
+ async getConnectedBots(accountsToCheck, legacyMigrationBot, additionalBots) {
213
+ const [resp, migration, additional] = await Promise.all([
214
214
  this.client.multicall({
215
215
  contracts: accountsToCheck.map((o) => {
216
216
  const pool = this.sdk.marketRegister.findByCreditManager(
@@ -225,12 +225,41 @@ class AbstractCreditAccountService extends import_base.SDKConstruct {
225
225
  }),
226
226
  allowFailure: true
227
227
  }),
228
- this.getActiveMigrationBots(accountsToCheck, legacyMigrationBot)
228
+ this.getActiveMigrationBots(accountsToCheck, legacyMigrationBot),
229
+ this.getActiveBots(accountsToCheck, additionalBots)
229
230
  ]);
230
- return { legacy: resp, legacyMigration: migration };
231
+ return {
232
+ legacy: resp,
233
+ additionalBots: additional,
234
+ legacyMigration: migration
235
+ };
236
+ }
237
+ async getActiveBots(accountsToCheck, bots) {
238
+ const result = await this.client.multicall({
239
+ contracts: accountsToCheck.flatMap((ca) => {
240
+ const cm = this.sdk.marketRegister.findCreditManager(ca.creditManager);
241
+ return bots.map((bot) => {
242
+ return {
243
+ abi: (0, import_constants.isV300)(cm.creditFacade.version) ? import_v300.iBotListV300Abi : import_generated.iBotListV310Abi,
244
+ address: cm.creditFacade.botList,
245
+ functionName: "getBotStatus",
246
+ args: (0, import_constants.isV300)(cm.creditFacade.version) ? [bot, ca.creditManager, ca.creditAccount] : [bot, ca.creditAccount]
247
+ };
248
+ });
249
+ }),
250
+ allowFailure: true
251
+ });
252
+ const botsByCAIndex = accountsToCheck.reduce((acc, _, index) => {
253
+ const r = result.slice(index * bots.length, (index + 1) * bots.length);
254
+ acc.push({
255
+ result: r
256
+ });
257
+ return acc;
258
+ }, []);
259
+ return botsByCAIndex;
231
260
  }
232
- async getActiveMigrationBots(accountsToCheck, legacyMigrationBot) {
233
- if (legacyMigrationBot) {
261
+ async getActiveMigrationBots(accountsToCheck, bot) {
262
+ if (bot) {
234
263
  const result = await this.client.multicall({
235
264
  contracts: accountsToCheck.map((ca) => {
236
265
  const cm = this.sdk.marketRegister.findCreditManager(
@@ -240,12 +269,12 @@ class AbstractCreditAccountService extends import_base.SDKConstruct {
240
269
  abi: (0, import_constants.isV300)(cm.creditFacade.version) ? import_v300.iBotListV300Abi : import_generated.iBotListV310Abi,
241
270
  address: cm.creditFacade.botList,
242
271
  functionName: "getBotStatus",
243
- args: (0, import_constants.isV300)(cm.creditFacade.version) ? [legacyMigrationBot, ca.creditManager, ca.creditAccount] : [legacyMigrationBot, ca.creditAccount]
272
+ args: (0, import_constants.isV300)(cm.creditFacade.version) ? [bot, ca.creditManager, ca.creditAccount] : [bot, ca.creditAccount]
244
273
  };
245
274
  }),
246
275
  allowFailure: true
247
276
  });
248
- return { result, botAddress: legacyMigrationBot };
277
+ return { result, botAddress: bot };
249
278
  }
250
279
  return void 0;
251
280
  }
@@ -31,7 +31,7 @@ class CreditAccountServiceV310 extends import_AbstractCreditAccountsService.Abst
31
31
  */
32
32
  async setBot({
33
33
  botAddress,
34
- permissions,
34
+ permissions: defaultPermissions,
35
35
  targetContract
36
36
  }) {
37
37
  const cm = this.sdk.marketRegister.findCreditManager(
@@ -41,6 +41,21 @@ class CreditAccountServiceV310 extends import_AbstractCreditAccountsService.Abst
41
41
  creditManager: targetContract.creditManager,
42
42
  creditAccount: targetContract
43
43
  }) : [];
44
+ const permissions = defaultPermissions !== null ? defaultPermissions : await (0, import_viem.getContract)({
45
+ address: botAddress,
46
+ client: this.sdk.client,
47
+ abi: [
48
+ {
49
+ type: "function",
50
+ name: "requiredPermissions",
51
+ inputs: [],
52
+ outputs: [
53
+ { name: "", type: "uint192", internalType: "uint192" }
54
+ ],
55
+ stateMutability: "view"
56
+ }
57
+ ]
58
+ }).read.requiredPermissions();
44
59
  const addBotCall = {
45
60
  target: cm.creditFacade.address,
46
61
  callData: (0, import_viem.encodeFunctionData)({
@@ -1,22 +1,12 @@
1
- import {
2
- decodeAbiParameters,
3
- encodeAbiParameters,
4
- stringToHex
5
- } from "viem";
1
+ import { encodeAbiParameters, stringToHex } from "viem";
6
2
  import { iBytecodeRepositoryAbi } from "../../abi/310/iBytecodeRepository.js";
7
- import { peripheryCompressorAbi } from "../../abi/compressors/peripheryCompressor.js";
8
3
  import {
9
4
  AddressMap,
10
5
  AP_BYTECODE_REPOSITORY,
11
- AP_PERIPHERY_COMPRESSOR,
12
6
  AP_TREASURY,
13
7
  BasePlugin,
14
8
  chains as CHAINS,
15
- hexEq,
16
- isV300,
17
- isV310,
18
- TypedObjectUtils,
19
- VERSION_RANGE_310
9
+ hexEq
20
10
  } from "../../sdk/index.js";
21
11
  import { iPartialLiquidationBotV310Abi } from "./abi/iPartialLiquidationBotV310.js";
22
12
  import {
@@ -25,64 +15,29 @@ import {
25
15
  PARTIAL_LIQUIDATION_BOT_DEPLOYER,
26
16
  PARTIAL_LIQUIDATION_BOT_SALT
27
17
  } from "./config.js";
28
- import { PartialLiquidationBotV300Contract } from "./PartialLiquidationBotV300Contract.js";
29
18
  import { PartialLiquidationBotV310Contract } from "./PartialLiquidationBotV310Contract.js";
30
19
  import {
31
20
  BOT_PARAMS_ABI,
32
- LIQUIDATION_BOT_TYPES
21
+ BOT_PARTIAL_LIQUIDATION
33
22
  } from "./types.js";
34
- class UnsupportedBotVersionError extends Error {
35
- state;
36
- constructor(state) {
37
- super(
38
- `unsupported bot version ${state.baseParams.version} for bot at ${state.baseParams.addr}`
39
- );
40
- this.state = state;
41
- }
42
- }
43
23
  class BotsPlugin extends BasePlugin {
44
- #botsByMarket;
24
+ #bots;
45
25
  get loaded() {
46
- return !!this.#botsByMarket;
26
+ return !!this.#bots;
27
+ }
28
+ get bots() {
29
+ return this.#bots?.values() ?? [];
47
30
  }
48
31
  async load(force) {
49
32
  if (!force && this.loaded) {
50
33
  return this.state;
51
34
  }
52
- const [pcAddr] = this.sdk.addressProvider.mustGetLatest(
53
- AP_PERIPHERY_COMPRESSOR,
54
- VERSION_RANGE_310
55
- );
56
- this.logger?.debug(`loading bots with periphery compressor ${pcAddr}`);
57
- const mcs = this.sdk.marketRegister.marketConfigurators.map(
58
- (mc) => mc.address
59
- );
60
- const botsData = await this.client.multicall({
61
- contracts: mcs.map(
62
- (mc) => ({
63
- address: pcAddr,
64
- abi: peripheryCompressorAbi,
65
- functionName: "getBots",
66
- args: [mc]
67
- })
68
- ),
69
- allowFailure: false
70
- });
71
- this.#botsByMarket = new AddressMap();
72
- for (let i = 0; i < mcs.length; i++) {
73
- const mc = mcs[i];
74
- const marketBotData = botsData[i];
75
- this.#loadStateMarketState(mc, marketBotData);
76
- }
77
- return this.state;
78
- }
79
- async findDeployedPartialLiquidationBots() {
80
35
  const treasury = this.sdk.addressProvider.getAddress(AP_TREASURY);
81
36
  const bcr = this.sdk.addressProvider.getAddress(AP_BYTECODE_REPOSITORY);
82
37
  const configs = PARTIAL_LIQUIDATION_BOT_CONFIGS[this.sdk.networkType] ?? [];
83
- const result = new AddressMap();
38
+ this.#bots = new AddressMap();
84
39
  if (!configs.length) {
85
- return result;
40
+ return this.state;
86
41
  }
87
42
  const deployedBots = await this.client.multicall({
88
43
  contracts: configs.map(
@@ -91,7 +46,7 @@ class BotsPlugin extends BasePlugin {
91
46
  abi: iBytecodeRepositoryAbi,
92
47
  functionName: "computeAddress",
93
48
  args: [
94
- stringToHex("BOT::PARTIAL_LIQUIDATION", { size: 32 }),
49
+ stringToHex(BOT_PARTIAL_LIQUIDATION, { size: 32 }),
95
50
  310,
96
51
  encodeAbiParameters(BOT_PARAMS_ABI, [
97
52
  treasury,
@@ -141,88 +96,41 @@ class BotsPlugin extends BasePlugin {
141
96
  const serialized = serializedBots[i];
142
97
  const expected = expectedBots.mustGet(botAddrs[i]);
143
98
  if (serialized.status === "success") {
144
- const [
145
- treasury2,
146
- minHealthFactor,
147
- maxHealthFactor,
148
- premiumScaleFactor,
149
- feeScaleFactor
150
- ] = decodeAbiParameters(BOT_PARAMS_ABI, serialized.result);
151
- if (!hexEq(treasury2, expected.treasury) || minHealthFactor !== expected.minHealthFactor || maxHealthFactor !== expected.maxHealthFactor || premiumScaleFactor !== expected.premiumScaleFactor || feeScaleFactor !== expected.feeScaleFactor) {
99
+ const bot = new PartialLiquidationBotV310Contract(this.sdk, {
100
+ addr: botAddrs[i],
101
+ version: BigInt(310),
102
+ contractType: BOT_PARTIAL_LIQUIDATION,
103
+ serializedParams: serialized.result
104
+ });
105
+ if (!hexEq(treasury, expected.treasury) || bot.minHealthFactor !== expected.minHealthFactor || bot.maxHealthFactor !== expected.maxHealthFactor || bot.premiumScaleFactor !== expected.premiumScaleFactor || bot.feeScaleFactor !== expected.feeScaleFactor) {
152
106
  this.logger?.error(
153
107
  `serialized bot ${botAddrs[i]} does not match expected bot`,
154
108
  serialized.error
155
109
  );
156
110
  } else {
157
- result.upsert(botAddrs[i], expected);
111
+ this.#bots.upsert(botAddrs[i], bot);
158
112
  }
159
113
  }
160
114
  }
161
- return result;
162
- }
163
- #loadStateMarketState(mc, state) {
164
- const bots = state.map((state2) => this.#createBot(mc, state2)).sort((a, b) => a.minHealthFactor - b.minHealthFactor);
165
- if (bots.length && isV300(Number(bots[0].version))) {
166
- if (bots.length !== 4) {
167
- throw new Error(`expected 4 bots v300 for market configurator ${mc}`);
168
- }
169
- for (let i = 0; i < bots.length; i++) {
170
- bots[i].botType = LIQUIDATION_BOT_TYPES[i];
171
- }
172
- }
173
- this.botsByMarket.upsert(mc, bots);
115
+ return this.state;
174
116
  }
175
117
  stateHuman(raw) {
176
118
  return {
177
- bots: Object.fromEntries(
178
- this.botsByMarket.entries().map(([mc, bots]) => [
179
- this.labelAddress(mc),
180
- bots.map((b) => b.stateHuman(raw))
181
- ])
182
- )
119
+ bots: this.#bots?.values().map((bot) => bot.stateHuman(raw)) ?? []
183
120
  };
184
121
  }
185
- get botsByMarket() {
186
- if (!this.#botsByMarket) {
187
- throw new Error("bots plugin not loaded");
188
- }
189
- return this.#botsByMarket;
190
- }
191
- botsByMarketConfigurator(mc) {
192
- return this.botsByMarket.get(mc) ?? [];
193
- }
194
- get allBots() {
195
- return this.botsByMarket.values().flat();
196
- }
197
122
  get state() {
198
123
  return {
199
- bots: TypedObjectUtils.fromEntries(
200
- this.botsByMarket.entries().map(([mc, bots]) => [mc, bots.map((b) => b.state)])
201
- )
124
+ bots: this.#bots?.values().map((bot) => bot.state) ?? []
202
125
  };
203
126
  }
204
127
  hydrate(state) {
205
- this.#botsByMarket = new AddressMap();
206
- for (const [mc, botStates] of TypedObjectUtils.entries(state.bots)) {
207
- this.#loadStateMarketState(mc, botStates);
208
- }
209
- }
210
- #createBot(marketConfigurator, data) {
211
- const v = Number(data.baseParams.version);
212
- if (isV300(v)) {
213
- return new PartialLiquidationBotV300Contract(
214
- this.sdk,
215
- data,
216
- marketConfigurator
217
- );
218
- } else if (isV310(v)) {
219
- return new PartialLiquidationBotV310Contract(
220
- this.sdk,
221
- data,
222
- marketConfigurator
128
+ this.#bots = new AddressMap();
129
+ for (const botState of state.bots) {
130
+ this.#bots.upsert(
131
+ botState.addr,
132
+ new PartialLiquidationBotV310Contract(this.sdk, botState)
223
133
  );
224
- } else {
225
- throw new Error(`unsupported bot version: ${v}`);
226
134
  }
227
135
  }
228
136
  static getMigrationBotData(chainId) {
@@ -230,6 +138,5 @@ class BotsPlugin extends BasePlugin {
230
138
  }
231
139
  }
232
140
  export {
233
- BotsPlugin,
234
- UnsupportedBotVersionError
141
+ BotsPlugin
235
142
  };