@hypurrquant/defi-cli 0.2.5 → 0.3.0

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.
@@ -986,6 +986,7 @@ var init_dist2 = __esm({
986
986
  TxStatus2["DryRun"] = "dry_run";
987
987
  TxStatus2["Simulated"] = "simulated";
988
988
  TxStatus2["SimulationFailed"] = "simulation_failed";
989
+ TxStatus2["NeedsApproval"] = "needs_approval";
989
990
  TxStatus2["Pending"] = "pending";
990
991
  TxStatus2["Confirmed"] = "confirmed";
991
992
  TxStatus2["Failed"] = "failed";
@@ -1235,6 +1236,7 @@ __export(dist_exports2, {
1235
1236
  HlpVaultAdapter: () => HlpVaultAdapter,
1236
1237
  KinetiqAdapter: () => KinetiqAdapter,
1237
1238
  MasterChefAdapter: () => MasterChefAdapter,
1239
+ MerchantMoeLBAdapter: () => MerchantMoeLBAdapter,
1238
1240
  MorphoBlueAdapter: () => MorphoBlueAdapter,
1239
1241
  PendleAdapter: () => PendleAdapter,
1240
1242
  RyskAdapter: () => RyskAdapter,
@@ -1251,6 +1253,7 @@ __export(dist_exports2, {
1251
1253
  createLending: () => createLending,
1252
1254
  createLiquidStaking: () => createLiquidStaking,
1253
1255
  createMasterChef: () => createMasterChef,
1256
+ createMerchantMoeLB: () => createMerchantMoeLB,
1254
1257
  createNft: () => createNft,
1255
1258
  createOptions: () => createOptions,
1256
1259
  createOracleFromCdp: () => createOracleFromCdp,
@@ -1263,31 +1266,169 @@ import { encodeFunctionData as encodeFunctionData22, parseAbi as parseAbi22, cre
1263
1266
  import { encodeFunctionData as encodeFunctionData32, parseAbi as parseAbi32, createPublicClient as createPublicClient3, http as http3, decodeAbiParameters as decodeAbiParameters3, concatHex, zeroAddress } from "viem";
1264
1267
  import { encodeFunctionData as encodeFunctionData4, parseAbi as parseAbi4, zeroAddress as zeroAddress2 } from "viem";
1265
1268
  import { encodeFunctionData as encodeFunctionData5, parseAbi as parseAbi5 } from "viem";
1266
- import { encodeFunctionData as encodeFunctionData6, parseAbi as parseAbi6, createPublicClient as createPublicClient4, http as http4, decodeAbiParameters as decodeAbiParameters4 } from "viem";
1269
+ import { encodeFunctionData as encodeFunctionData6, parseAbi as parseAbi6, decodeAbiParameters as decodeAbiParameters4 } from "viem";
1267
1270
  import { encodeFunctionData as encodeFunctionData7, parseAbi as parseAbi7, zeroAddress as zeroAddress3 } from "viem";
1268
- import { createPublicClient as createPublicClient5, encodeFunctionData as encodeFunctionData8, http as http5, parseAbi as parseAbi8, zeroAddress as zeroAddress4 } from "viem";
1269
- import { encodeFunctionData as encodeFunctionData9, parseAbi as parseAbi9, createPublicClient as createPublicClient6, http as http6 } from "viem";
1270
- import { createPublicClient as createPublicClient7, http as http7, parseAbi as parseAbi10, encodeFunctionData as encodeFunctionData10, zeroAddress as zeroAddress5 } from "viem";
1271
- import { createPublicClient as createPublicClient8, http as http8, parseAbi as parseAbi11, encodeFunctionData as encodeFunctionData11, zeroAddress as zeroAddress6 } from "viem";
1272
- import { createPublicClient as createPublicClient9, http as http9, parseAbi as parseAbi12 } from "viem";
1273
- import { createPublicClient as createPublicClient10, http as http10, parseAbi as parseAbi13, encodeFunctionData as encodeFunctionData12 } from "viem";
1274
- import { createPublicClient as createPublicClient11, http as http11, parseAbi as parseAbi14, encodeFunctionData as encodeFunctionData13 } from "viem";
1275
- import { createPublicClient as createPublicClient12, http as http12, parseAbi as parseAbi15, encodeFunctionData as encodeFunctionData14 } from "viem";
1276
- import { createPublicClient as createPublicClient13, http as http13, parseAbi as parseAbi16, encodeFunctionData as encodeFunctionData15, zeroAddress as zeroAddress7 } from "viem";
1277
- import { createPublicClient as createPublicClient14, http as http14, parseAbi as parseAbi17, encodeFunctionData as encodeFunctionData16, zeroAddress as zeroAddress8 } from "viem";
1278
- import { createPublicClient as createPublicClient15, http as http15, parseAbi as parseAbi18 } from "viem";
1279
- import { createPublicClient as createPublicClient16, http as http16, parseAbi as parseAbi19, encodeFunctionData as encodeFunctionData17 } from "viem";
1280
- import { parseAbi as parseAbi20, encodeFunctionData as encodeFunctionData18 } from "viem";
1281
- import { createPublicClient as createPublicClient17, http as http17, parseAbi as parseAbi21, encodeFunctionData as encodeFunctionData19, zeroAddress as zeroAddress9 } from "viem";
1282
- import { createPublicClient as createPublicClient18, http as http18, parseAbi as parseAbi222, encodeFunctionData as encodeFunctionData20, zeroAddress as zeroAddress10 } from "viem";
1283
- import { parseAbi as parseAbi23, encodeFunctionData as encodeFunctionData21 } from "viem";
1271
+ import { createPublicClient as createPublicClient4, encodeFunctionData as encodeFunctionData8, http as http4, parseAbi as parseAbi8, zeroAddress as zeroAddress4 } from "viem";
1272
+ import { encodeFunctionData as encodeFunctionData9, parseAbi as parseAbi9, createPublicClient as createPublicClient5, http as http5 } from "viem";
1273
+ import {
1274
+ encodeFunctionData as encodeFunctionData10,
1275
+ decodeFunctionResult as decodeFunctionResult22,
1276
+ parseAbi as parseAbi10,
1277
+ createPublicClient as createPublicClient6,
1278
+ http as http6
1279
+ } from "viem";
1280
+ import { createPublicClient as createPublicClient7, http as http7, parseAbi as parseAbi11, encodeFunctionData as encodeFunctionData11, decodeFunctionResult as decodeFunctionResult3, zeroAddress as zeroAddress5 } from "viem";
1281
+ import { createPublicClient as createPublicClient8, http as http8, parseAbi as parseAbi12, encodeFunctionData as encodeFunctionData12, zeroAddress as zeroAddress6 } from "viem";
1282
+ import { createPublicClient as createPublicClient9, http as http9, parseAbi as parseAbi13 } from "viem";
1283
+ import { createPublicClient as createPublicClient10, http as http10, parseAbi as parseAbi14, encodeFunctionData as encodeFunctionData13 } from "viem";
1284
+ import { createPublicClient as createPublicClient11, http as http11, parseAbi as parseAbi15, encodeFunctionData as encodeFunctionData14 } from "viem";
1285
+ import { createPublicClient as createPublicClient12, http as http12, parseAbi as parseAbi16, encodeFunctionData as encodeFunctionData15 } from "viem";
1286
+ import { parseAbi as parseAbi17, encodeFunctionData as encodeFunctionData16, decodeFunctionResult as decodeFunctionResult4, zeroAddress as zeroAddress7 } from "viem";
1287
+ import { createPublicClient as createPublicClient13, http as http13, parseAbi as parseAbi18, encodeFunctionData as encodeFunctionData17, zeroAddress as zeroAddress8 } from "viem";
1288
+ import { createPublicClient as createPublicClient14, http as http14, parseAbi as parseAbi19 } from "viem";
1289
+ import { createPublicClient as createPublicClient15, http as http15, parseAbi as parseAbi20, encodeFunctionData as encodeFunctionData18 } from "viem";
1290
+ import { parseAbi as parseAbi21, encodeFunctionData as encodeFunctionData19 } from "viem";
1291
+ import { createPublicClient as createPublicClient16, http as http16, parseAbi as parseAbi222, encodeFunctionData as encodeFunctionData20, zeroAddress as zeroAddress9 } from "viem";
1292
+ import { createPublicClient as createPublicClient17, http as http17, parseAbi as parseAbi23, encodeFunctionData as encodeFunctionData21, zeroAddress as zeroAddress10 } from "viem";
1284
1293
  import { parseAbi as parseAbi24, encodeFunctionData as encodeFunctionData222 } from "viem";
1285
- import { createPublicClient as createPublicClient19, http as http19, parseAbi as parseAbi25 } from "viem";
1294
+ import { parseAbi as parseAbi25, encodeFunctionData as encodeFunctionData23 } from "viem";
1295
+ import { createPublicClient as createPublicClient18, http as http18, parseAbi as parseAbi26 } from "viem";
1296
+ function decodeAddressResult(data) {
1297
+ if (!data) return null;
1298
+ try {
1299
+ return decodeFunctionResult22({ abi: _addressAbi, functionName: "f", data });
1300
+ } catch {
1301
+ return null;
1302
+ }
1303
+ }
1304
+ function decodeUint256Result(data) {
1305
+ if (!data) return null;
1306
+ try {
1307
+ return decodeFunctionResult22({ abi: _uint256Abi, functionName: "f", data });
1308
+ } catch {
1309
+ return null;
1310
+ }
1311
+ }
1312
+ function decodeBoolResult(data) {
1313
+ if (!data) return null;
1314
+ try {
1315
+ return decodeFunctionResult22({ abi: _boolAbi, functionName: "f", data });
1316
+ } catch {
1317
+ return null;
1318
+ }
1319
+ }
1320
+ function decodeStringResult(data) {
1321
+ if (!data) return "?";
1322
+ try {
1323
+ return decodeFunctionResult22({ abi: erc20Abi2, functionName: "symbol", data });
1324
+ } catch {
1325
+ return "?";
1326
+ }
1327
+ }
1328
+ function decodeRangeResult(data) {
1329
+ if (!data) return null;
1330
+ try {
1331
+ return decodeFunctionResult22({ abi: _rangeAbi, functionName: "f", data });
1332
+ } catch {
1333
+ return null;
1334
+ }
1335
+ }
1336
+ function decodeBinResult(data) {
1337
+ if (!data) return null;
1338
+ try {
1339
+ return decodeFunctionResult22({ abi: _binAbi, functionName: "f", data });
1340
+ } catch {
1341
+ return null;
1342
+ }
1343
+ }
1344
+ function decodeUint256ArrayResult(data) {
1345
+ if (!data) return null;
1346
+ try {
1347
+ return decodeFunctionResult22({ abi: _uint256ArrayAbi, functionName: "f", data });
1348
+ } catch {
1349
+ return null;
1350
+ }
1351
+ }
1352
+ function extractRewarderAddress(hooksParams) {
1353
+ if (!hooksParams || hooksParams === "0x0000000000000000000000000000000000000000000000000000000000000000") {
1354
+ return null;
1355
+ }
1356
+ const hex = hooksParams.slice(2);
1357
+ if (hex.length < 64) return null;
1358
+ const addrHex = hex.slice(24, 64);
1359
+ if (addrHex === "0000000000000000000000000000000000000000") return null;
1360
+ return `0x${addrHex}`;
1361
+ }
1362
+ function buildUniformDistribution(deltaIds) {
1363
+ const PRECISION = 10n ** 18n;
1364
+ const n = deltaIds.length;
1365
+ const xBins = deltaIds.filter((d) => d >= 0).length;
1366
+ const yBins = deltaIds.filter((d) => d <= 0).length;
1367
+ const distributionX = [];
1368
+ const distributionY = [];
1369
+ for (const delta of deltaIds) {
1370
+ const xShare = delta >= 0 && xBins > 0 ? PRECISION / BigInt(xBins) : 0n;
1371
+ const yShare = delta <= 0 && yBins > 0 ? PRECISION / BigInt(yBins) : 0n;
1372
+ distributionX.push(xShare);
1373
+ distributionY.push(yShare);
1374
+ }
1375
+ const xSum = distributionX.reduce((a, b) => a + b, 0n);
1376
+ const ySum = distributionY.reduce((a, b) => a + b, 0n);
1377
+ if (xSum > 0n && xSum !== PRECISION) {
1378
+ const firstX = distributionX.findIndex((v) => v > 0n);
1379
+ if (firstX !== -1) distributionX[firstX] += PRECISION - xSum;
1380
+ }
1381
+ if (ySum > 0n && ySum !== PRECISION) {
1382
+ const firstY = distributionY.findIndex((v) => v > 0n);
1383
+ if (firstY !== -1) distributionY[firstY] += PRECISION - ySum;
1384
+ }
1385
+ return { distributionX, distributionY };
1386
+ }
1286
1387
  function u256ToF64(v) {
1287
1388
  const MAX_U128 = (1n << 128n) - 1n;
1288
1389
  if (v > MAX_U128) return Infinity;
1289
1390
  return Number(v);
1290
1391
  }
1392
+ function decodeAddress(data) {
1393
+ if (!data || data.length < 66) return null;
1394
+ return `0x${data.slice(26, 66)}`;
1395
+ }
1396
+ function decodeAddressArray(data) {
1397
+ if (!data) return [];
1398
+ try {
1399
+ return decodeFunctionResult3({
1400
+ abi: REWARDS_CONTROLLER_ABI,
1401
+ functionName: "getRewardsByAsset",
1402
+ data
1403
+ });
1404
+ } catch {
1405
+ return [];
1406
+ }
1407
+ }
1408
+ function decodeReserveData(data) {
1409
+ if (!data) return null;
1410
+ try {
1411
+ return decodeFunctionResult3({
1412
+ abi: POOL_ABI,
1413
+ functionName: "getReserveData",
1414
+ data
1415
+ });
1416
+ } catch {
1417
+ return null;
1418
+ }
1419
+ }
1420
+ function decodeRewardsData(data) {
1421
+ if (!data) return null;
1422
+ try {
1423
+ return decodeFunctionResult3({
1424
+ abi: REWARDS_CONTROLLER_ABI,
1425
+ functionName: "getRewardsData",
1426
+ data
1427
+ });
1428
+ } catch {
1429
+ return null;
1430
+ }
1431
+ }
1291
1432
  function u256ToF642(v) {
1292
1433
  const MAX_U128 = (1n << 128n) - 1n;
1293
1434
  if (v > MAX_U128) return Infinity;
@@ -1302,6 +1443,30 @@ function defaultMarketParams(loanToken = zeroAddress7) {
1302
1443
  lltv: 0n
1303
1444
  };
1304
1445
  }
1446
+ function decodeMarket(data) {
1447
+ if (!data) return null;
1448
+ try {
1449
+ return decodeFunctionResult4({
1450
+ abi: MORPHO_ABI,
1451
+ functionName: "market",
1452
+ data
1453
+ });
1454
+ } catch {
1455
+ return null;
1456
+ }
1457
+ }
1458
+ function decodeMarketParams(data) {
1459
+ if (!data) return null;
1460
+ try {
1461
+ return decodeFunctionResult4({
1462
+ abi: MORPHO_ABI,
1463
+ functionName: "idToMarketParams",
1464
+ data
1465
+ });
1466
+ } catch {
1467
+ return null;
1468
+ }
1469
+ }
1305
1470
  function createDex(entry, rpcUrl) {
1306
1471
  switch (entry.interface) {
1307
1472
  case "uniswap_v3":
@@ -1441,7 +1606,10 @@ function createOracleFromCdp(entry, _asset, rpcUrl) {
1441
1606
  throw DefiError.unsupported(`Oracle not available for CDP interface '${entry.interface}'`);
1442
1607
  }
1443
1608
  }
1444
- var DEFAULT_FEE, swapRouterAbi, quoterAbi, ramsesQuoterAbi, positionManagerAbi, UniswapV3Adapter, abi, lbQuoterAbi, UniswapV2Adapter, abi2, algebraQuoterAbi, algebraSingleQuoterAbi, algebraPositionManagerAbi, AlgebraV3Adapter, abi3, BalancerV3Adapter, poolAbi, CurveStableSwapAdapter, abi4, abiV2, SolidlyAdapter, abi5, WooFiAdapter, gaugeAbi, veAbi, voterAbi, SolidlyGaugeAdapter, masterchefAbi, MasterChefAdapter, POOL_ABI, ERC20_ABI, INCENTIVES_ABI, REWARDS_CONTROLLER_ABI, POOL_PROVIDER_ABI, ADDRESSES_PROVIDER_ABI, ORACLE_ABI, ERC20_DECIMALS_ABI, AaveV3Adapter, POOL_ABI2, ERC20_ABI2, AaveV2Adapter, ORACLE_ABI2, AaveOracleAdapter, CTOKEN_ABI, BSC_BLOCKS_PER_YEAR, CompoundV2Adapter, COMET_ABI, SECONDS_PER_YEAR, CompoundV3Adapter, EULER_VAULT_ABI, SECONDS_PER_YEAR2, EulerV2Adapter, MORPHO_ABI, META_MORPHO_ABI, IRM_ABI, SECONDS_PER_YEAR3, MorphoBlueAdapter, BORROWER_OPS_ABI, TROVE_MANAGER_ABI, HINT_HELPERS_ABI, SORTED_TROVES_ABI, FelixCdpAdapter, PRICE_FEED_ABI, FelixOracleAdapter, ERC4626_ABI, ERC4626VaultAdapter, GENERIC_LST_ABI, GenericLstAdapter, STHYPE_ABI, ERC20_ABI3, StHypeAdapter, KINETIQ_ABI, ORACLE_ABI3, WHYPE, HYPERLEND_ORACLE, KinetiqAdapter, PendleAdapter, GenericYieldAdapter, HLP_ABI, HlpVaultAdapter, GenericDerivativesAdapter, RYSK_ABI, RyskAdapter, GenericOptionsAdapter, ERC721_ABI, ERC721Adapter, DexSpotPrice;
1609
+ function createMerchantMoeLB(entry, rpcUrl) {
1610
+ return new MerchantMoeLBAdapter(entry, rpcUrl);
1611
+ }
1612
+ var DEFAULT_FEE, swapRouterAbi, quoterAbi, ramsesQuoterAbi, positionManagerAbi, UniswapV3Adapter, abi, lbQuoterAbi, UniswapV2Adapter, abi2, algebraQuoterAbi, algebraSingleQuoterAbi, algebraPositionManagerAbi, AlgebraV3Adapter, abi3, BalancerV3Adapter, poolAbi, CurveStableSwapAdapter, abi4, abiV2, SolidlyAdapter, abi5, WooFiAdapter, gaugeAbi, veAbi, voterAbi, SolidlyGaugeAdapter, masterchefAbi, MasterChefAdapter, lbRouterAbi, lbFactoryAbi, lbPairAbi, lbRewarderAbi, masterChefAbi, veMoeAbi, lbPairBinAbi, lbQuoterAbi2, erc20Abi2, _addressAbi, _uint256Abi, _boolAbi, _rangeAbi, _binAbi, _uint256ArrayAbi, MerchantMoeLBAdapter, POOL_ABI, ERC20_ABI, INCENTIVES_ABI, REWARDS_CONTROLLER_ABI, POOL_PROVIDER_ABI, ADDRESSES_PROVIDER_ABI, ORACLE_ABI, ERC20_DECIMALS_ABI, AaveV3Adapter, POOL_ABI2, ERC20_ABI2, AaveV2Adapter, ORACLE_ABI2, AaveOracleAdapter, CTOKEN_ABI, BSC_BLOCKS_PER_YEAR, CompoundV2Adapter, COMET_ABI, SECONDS_PER_YEAR, CompoundV3Adapter, EULER_VAULT_ABI, SECONDS_PER_YEAR2, EulerV2Adapter, MORPHO_ABI, META_MORPHO_ABI, IRM_ABI, SECONDS_PER_YEAR3, MorphoBlueAdapter, BORROWER_OPS_ABI, TROVE_MANAGER_ABI, HINT_HELPERS_ABI, SORTED_TROVES_ABI, FelixCdpAdapter, PRICE_FEED_ABI, FelixOracleAdapter, ERC4626_ABI, ERC4626VaultAdapter, GENERIC_LST_ABI, GenericLstAdapter, STHYPE_ABI, ERC20_ABI3, StHypeAdapter, KINETIQ_ABI, ORACLE_ABI3, WHYPE, HYPERLEND_ORACLE, KinetiqAdapter, PendleAdapter, GenericYieldAdapter, HLP_ABI, HlpVaultAdapter, GenericDerivativesAdapter, RYSK_ABI, RyskAdapter, GenericOptionsAdapter, ERC721_ABI, ERC721Adapter, DexSpotPrice;
1445
1613
  var init_dist3 = __esm({
1446
1614
  "../defi-protocols/dist/index.js"() {
1447
1615
  "use strict";
@@ -1475,6 +1643,7 @@ var init_dist3 = __esm({
1475
1643
  init_dist2();
1476
1644
  init_dist2();
1477
1645
  init_dist2();
1646
+ init_dist2();
1478
1647
  DEFAULT_FEE = 3e3;
1479
1648
  swapRouterAbi = parseAbi3([
1480
1649
  "struct ExactInputSingleParams { address tokenIn; address tokenOut; uint24 fee; address recipient; uint256 deadline; uint256 amountIn; uint256 amountOutMinimum; uint160 sqrtPriceLimitX96; }",
@@ -2291,15 +2460,6 @@ var init_dist3 = __esm({
2291
2460
  approvals: [{ token: params.token_in, spender: this.router, amount: params.amount_in }]
2292
2461
  };
2293
2462
  }
2294
- async callGetAmountsOut(client, callData) {
2295
- const result = await client.call({ to: this.router, data: callData });
2296
- if (!result.data) return 0n;
2297
- const [amounts] = decodeAbiParameters4(
2298
- [{ name: "amounts", type: "uint256[]" }],
2299
- result.data
2300
- );
2301
- return amounts.length >= 2 ? amounts[amounts.length - 1] : 0n;
2302
- }
2303
2463
  encodeV1(params, stable) {
2304
2464
  return encodeFunctionData6({
2305
2465
  abi: abi4,
@@ -2316,7 +2476,6 @@ var init_dist3 = __esm({
2316
2476
  }
2317
2477
  async quote(params) {
2318
2478
  if (!this.rpcUrl) throw DefiError.rpcError("No RPC URL configured");
2319
- const client = createPublicClient4({ transport: http4(this.rpcUrl) });
2320
2479
  const candidates = [
2321
2480
  { callData: this.encodeV1(params, false), stable: false },
2322
2481
  { callData: this.encodeV1(params, true), stable: true }
@@ -2327,16 +2486,26 @@ var init_dist3 = __esm({
2327
2486
  { callData: this.encodeV2(params, true), stable: true }
2328
2487
  );
2329
2488
  }
2330
- const results = await Promise.allSettled(
2331
- candidates.map((c) => this.callGetAmountsOut(client, c.callData))
2489
+ const rawResults = await multicallRead(
2490
+ this.rpcUrl,
2491
+ candidates.map((c) => [this.router, c.callData])
2332
2492
  );
2333
2493
  let bestOut = 0n;
2334
2494
  let bestStable = false;
2335
- for (let i = 0; i < results.length; i++) {
2336
- const r = results[i];
2337
- if (r.status === "fulfilled" && r.value > bestOut) {
2338
- bestOut = r.value;
2339
- bestStable = candidates[i].stable;
2495
+ for (let i = 0; i < rawResults.length; i++) {
2496
+ const raw = rawResults[i];
2497
+ if (!raw) continue;
2498
+ try {
2499
+ const [amounts] = decodeAbiParameters4(
2500
+ [{ name: "amounts", type: "uint256[]" }],
2501
+ raw
2502
+ );
2503
+ const out = amounts.length >= 2 ? amounts[amounts.length - 1] : 0n;
2504
+ if (out > bestOut) {
2505
+ bestOut = out;
2506
+ bestStable = candidates[i].stable;
2507
+ }
2508
+ } catch {
2340
2509
  }
2341
2510
  }
2342
2511
  if (bestOut === 0n) {
@@ -2548,7 +2717,7 @@ var init_dist3 = __esm({
2548
2717
  async buildClaimRewards(gauge, account) {
2549
2718
  if (account && this.rpcUrl) {
2550
2719
  try {
2551
- const client = createPublicClient5({ transport: http5(this.rpcUrl) });
2720
+ const client = createPublicClient4({ transport: http4(this.rpcUrl) });
2552
2721
  const listLen = await client.readContract({
2553
2722
  address: gauge,
2554
2723
  abi: gaugeAbi,
@@ -2806,7 +2975,7 @@ var init_dist3 = __esm({
2806
2975
  if (!this.rpcUrl) {
2807
2976
  throw DefiError.unsupported(`[${this.protocolName}] getPendingRewards requires RPC`);
2808
2977
  }
2809
- const client = createPublicClient6({ transport: http6(this.rpcUrl) });
2978
+ const client = createPublicClient5({ transport: http5(this.rpcUrl) });
2810
2979
  const rewards = await client.readContract({
2811
2980
  address: this.masterchef,
2812
2981
  abi: masterchefAbi,
@@ -2820,7 +2989,591 @@ var init_dist3 = __esm({
2820
2989
  }));
2821
2990
  }
2822
2991
  };
2823
- POOL_ABI = parseAbi10([
2992
+ lbRouterAbi = parseAbi10([
2993
+ "struct LiquidityParameters { address tokenX; address tokenY; uint256 binStep; uint256 amountX; uint256 amountY; uint256 amountXMin; uint256 amountYMin; uint256 activeIdDesired; uint256 idSlippage; int256[] deltaIds; uint256[] distributionX; uint256[] distributionY; address to; address refundTo; uint256 deadline; }",
2994
+ "function addLiquidity(LiquidityParameters calldata liquidityParameters) external returns (uint256 amountXAdded, uint256 amountYAdded, uint256 amountXLeft, uint256 amountYLeft, uint256[] memory depositIds, uint256[] memory liquidityMinted)",
2995
+ "function removeLiquidity(address tokenX, address tokenY, uint16 binStep, uint256 amountXMin, uint256 amountYMin, uint256[] memory ids, uint256[] memory amounts, address to, uint256 deadline) external returns (uint256 amountX, uint256 amountY)"
2996
+ ]);
2997
+ lbFactoryAbi = parseAbi10([
2998
+ "function getNumberOfLBPairs() external view returns (uint256)",
2999
+ "function getLBPairAtIndex(uint256 index) external view returns (address)"
3000
+ ]);
3001
+ lbPairAbi = parseAbi10([
3002
+ "function getLBHooksParameters() external view returns (bytes32)",
3003
+ "function getActiveId() external view returns (uint24)",
3004
+ "function getBinStep() external view returns (uint16)",
3005
+ "function getTokenX() external view returns (address)",
3006
+ "function getTokenY() external view returns (address)",
3007
+ "function balanceOf(address account, uint256 id) external view returns (uint256)",
3008
+ "function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory)"
3009
+ ]);
3010
+ lbRewarderAbi = parseAbi10([
3011
+ "function getRewardToken() external view returns (address)",
3012
+ "function getRewardedRange() external view returns (uint256 minBinId, uint256 maxBinId)",
3013
+ "function getPendingRewards(address user, uint256[] calldata ids) external view returns (uint256 pendingRewards)",
3014
+ "function claim(address user, uint256[] calldata ids) external",
3015
+ "function getPid() external view returns (uint256)",
3016
+ "function isStopped() external view returns (bool)",
3017
+ "function getLBPair() external view returns (address)",
3018
+ "function getMasterChef() external view returns (address)"
3019
+ ]);
3020
+ masterChefAbi = parseAbi10([
3021
+ "function getMoePerSecond() external view returns (uint256)",
3022
+ "function getTreasuryShare() external view returns (uint256)",
3023
+ "function getStaticShare() external view returns (uint256)",
3024
+ "function getVeMoe() external view returns (address)"
3025
+ ]);
3026
+ veMoeAbi = parseAbi10([
3027
+ "function getWeight(uint256 pid) external view returns (uint256)",
3028
+ "function getTotalWeight() external view returns (uint256)",
3029
+ "function getTopPoolIds() external view returns (uint256[] memory)"
3030
+ ]);
3031
+ lbPairBinAbi = parseAbi10([
3032
+ "function getBin(uint24 id) external view returns (uint128 reserveX, uint128 reserveY)",
3033
+ "function getActiveId() external view returns (uint24)"
3034
+ ]);
3035
+ lbQuoterAbi2 = parseAbi10([
3036
+ "function findBestPathFromAmountIn(address[] calldata route, uint128 amountIn) external view returns ((address[] route, address[] pairs, uint256[] binSteps, uint256[] versions, uint128[] amounts, uint128[] virtualAmountsWithoutSlippage, uint128[] fees))"
3037
+ ]);
3038
+ erc20Abi2 = parseAbi10([
3039
+ "function symbol() external view returns (string)"
3040
+ ]);
3041
+ _addressAbi = parseAbi10(["function f() external view returns (address)"]);
3042
+ _uint256Abi = parseAbi10(["function f() external view returns (uint256)"]);
3043
+ _boolAbi = parseAbi10(["function f() external view returns (bool)"]);
3044
+ _rangeAbi = parseAbi10(["function f() external view returns (uint256 minBinId, uint256 maxBinId)"]);
3045
+ _binAbi = parseAbi10(["function f() external view returns (uint128 reserveX, uint128 reserveY)"]);
3046
+ _uint256ArrayAbi = parseAbi10(["function f() external view returns (uint256[] memory)"]);
3047
+ MerchantMoeLBAdapter = class {
3048
+ protocolName;
3049
+ lbRouter;
3050
+ lbFactory;
3051
+ lbQuoter;
3052
+ rpcUrl;
3053
+ /** WMNT address (lb_mid_wmnt in config) used for MOE price routing */
3054
+ wmnt;
3055
+ /** USDT address (lb_mid_usdt in config) used for MNT/USD price routing */
3056
+ usdt;
3057
+ constructor(entry, rpcUrl) {
3058
+ this.protocolName = entry.name;
3059
+ const lbRouter = entry.contracts?.["lb_router"];
3060
+ if (!lbRouter) {
3061
+ throw new DefiError("CONTRACT_ERROR", "Missing 'lb_router' contract address");
3062
+ }
3063
+ const lbFactory = entry.contracts?.["lb_factory"];
3064
+ if (!lbFactory) {
3065
+ throw new DefiError("CONTRACT_ERROR", "Missing 'lb_factory' contract address");
3066
+ }
3067
+ this.lbRouter = lbRouter;
3068
+ this.lbFactory = lbFactory;
3069
+ this.lbQuoter = entry.contracts?.["lb_quoter"];
3070
+ this.wmnt = entry.contracts?.["lb_mid_wmnt"];
3071
+ this.usdt = entry.contracts?.["lb_mid_usdt"];
3072
+ this.rpcUrl = rpcUrl;
3073
+ }
3074
+ name() {
3075
+ return this.protocolName;
3076
+ }
3077
+ requireRpc() {
3078
+ if (!this.rpcUrl) {
3079
+ throw DefiError.rpcError(`[${this.protocolName}] RPC URL required`);
3080
+ }
3081
+ return this.rpcUrl;
3082
+ }
3083
+ /**
3084
+ * Build an addLiquidity transaction for a Liquidity Book pair.
3085
+ * Distributes tokenX/tokenY uniformly across active bin ± numBins.
3086
+ */
3087
+ async buildAddLiquidity(params) {
3088
+ const numBins = params.numBins ?? 5;
3089
+ const deadline = params.deadline ?? BigInt("18446744073709551615");
3090
+ let activeIdDesired = params.activeIdDesired;
3091
+ if (activeIdDesired === void 0) {
3092
+ const rpcUrl = this.requireRpc();
3093
+ const client = createPublicClient6({ transport: http6(rpcUrl) });
3094
+ const activeId = await client.readContract({
3095
+ address: params.pool,
3096
+ abi: lbPairAbi,
3097
+ functionName: "getActiveId"
3098
+ });
3099
+ activeIdDesired = activeId;
3100
+ }
3101
+ const deltaIds = [];
3102
+ for (let d = -numBins; d <= numBins; d++) {
3103
+ deltaIds.push(d);
3104
+ }
3105
+ const { distributionX, distributionY } = buildUniformDistribution(deltaIds);
3106
+ const data = encodeFunctionData10({
3107
+ abi: lbRouterAbi,
3108
+ functionName: "addLiquidity",
3109
+ args: [
3110
+ {
3111
+ tokenX: params.tokenX,
3112
+ tokenY: params.tokenY,
3113
+ binStep: BigInt(params.binStep),
3114
+ amountX: params.amountX,
3115
+ amountY: params.amountY,
3116
+ amountXMin: 0n,
3117
+ amountYMin: 0n,
3118
+ activeIdDesired: BigInt(activeIdDesired),
3119
+ idSlippage: BigInt(numBins + 2),
3120
+ deltaIds: deltaIds.map(BigInt),
3121
+ distributionX,
3122
+ distributionY,
3123
+ to: params.recipient,
3124
+ refundTo: params.recipient,
3125
+ deadline
3126
+ }
3127
+ ]
3128
+ });
3129
+ return {
3130
+ description: `[${this.protocolName}] LB addLiquidity ${params.amountX} tokenX + ${params.amountY} tokenY across ${deltaIds.length} bins`,
3131
+ to: this.lbRouter,
3132
+ data,
3133
+ value: 0n,
3134
+ gas_estimate: 8e5,
3135
+ approvals: [
3136
+ { token: params.tokenX, spender: this.lbRouter, amount: params.amountX },
3137
+ { token: params.tokenY, spender: this.lbRouter, amount: params.amountY }
3138
+ ]
3139
+ };
3140
+ }
3141
+ /**
3142
+ * Build a removeLiquidity transaction for specific LB bins.
3143
+ */
3144
+ async buildRemoveLiquidity(params) {
3145
+ const deadline = params.deadline ?? BigInt("18446744073709551615");
3146
+ const data = encodeFunctionData10({
3147
+ abi: lbRouterAbi,
3148
+ functionName: "removeLiquidity",
3149
+ args: [
3150
+ params.tokenX,
3151
+ params.tokenY,
3152
+ params.binStep,
3153
+ params.amountXMin ?? 0n,
3154
+ params.amountYMin ?? 0n,
3155
+ params.binIds.map(BigInt),
3156
+ params.amounts,
3157
+ params.recipient,
3158
+ deadline
3159
+ ]
3160
+ });
3161
+ return {
3162
+ description: `[${this.protocolName}] LB removeLiquidity from ${params.binIds.length} bins`,
3163
+ to: this.lbRouter,
3164
+ data,
3165
+ value: 0n,
3166
+ gas_estimate: 6e5
3167
+ };
3168
+ }
3169
+ /**
3170
+ * Auto-detect bin IDs for a pool from the rewarder's rewarded range.
3171
+ * Falls back to active bin ± 50 scan if no rewarder exists.
3172
+ */
3173
+ async autoDetectBins(pool) {
3174
+ const rpcUrl = this.requireRpc();
3175
+ const client = createPublicClient6({ transport: http6(rpcUrl) });
3176
+ const hooksParams = await client.readContract({
3177
+ address: pool,
3178
+ abi: lbPairAbi,
3179
+ functionName: "getLBHooksParameters"
3180
+ });
3181
+ const rewarder = extractRewarderAddress(hooksParams);
3182
+ if (rewarder) {
3183
+ const range = await client.readContract({
3184
+ address: rewarder,
3185
+ abi: lbRewarderAbi,
3186
+ functionName: "getRewardedRange"
3187
+ });
3188
+ const min = Number(range[0]);
3189
+ const max = Number(range[1]);
3190
+ const ids2 = [];
3191
+ for (let b = min; b <= max; b++) ids2.push(b);
3192
+ return ids2;
3193
+ }
3194
+ const activeId = await client.readContract({
3195
+ address: pool,
3196
+ abi: lbPairAbi,
3197
+ functionName: "getActiveId"
3198
+ });
3199
+ const ids = [];
3200
+ for (let b = activeId - 50; b <= activeId + 50; b++) ids.push(b);
3201
+ return ids;
3202
+ }
3203
+ /**
3204
+ * Get pending MOE rewards for a user across specified bin IDs.
3205
+ * If binIds is omitted, auto-detects from the rewarder's rewarded range.
3206
+ * Reads the rewarder address from the pool's hooks parameters.
3207
+ */
3208
+ async getPendingRewards(user, pool, binIds) {
3209
+ const rpcUrl = this.requireRpc();
3210
+ const client = createPublicClient6({ transport: http6(rpcUrl) });
3211
+ const hooksParams = await client.readContract({
3212
+ address: pool,
3213
+ abi: lbPairAbi,
3214
+ functionName: "getLBHooksParameters"
3215
+ });
3216
+ const rewarder = extractRewarderAddress(hooksParams);
3217
+ if (!rewarder) {
3218
+ return [];
3219
+ }
3220
+ let resolvedBinIds = binIds;
3221
+ if (!resolvedBinIds || resolvedBinIds.length === 0) {
3222
+ const range = await client.readContract({
3223
+ address: rewarder,
3224
+ abi: lbRewarderAbi,
3225
+ functionName: "getRewardedRange"
3226
+ });
3227
+ const min = Number(range[0]);
3228
+ const max = Number(range[1]);
3229
+ resolvedBinIds = [];
3230
+ for (let b = min; b <= max; b++) resolvedBinIds.push(b);
3231
+ }
3232
+ const [pending, rewardToken] = await Promise.all([
3233
+ client.readContract({
3234
+ address: rewarder,
3235
+ abi: lbRewarderAbi,
3236
+ functionName: "getPendingRewards",
3237
+ args: [user, resolvedBinIds.map(BigInt)]
3238
+ }),
3239
+ client.readContract({
3240
+ address: rewarder,
3241
+ abi: lbRewarderAbi,
3242
+ functionName: "getRewardToken"
3243
+ })
3244
+ ]);
3245
+ return [
3246
+ {
3247
+ token: rewardToken,
3248
+ symbol: "MOE",
3249
+ amount: pending
3250
+ }
3251
+ ];
3252
+ }
3253
+ /**
3254
+ * Build a claim rewards transaction for specific LB bins.
3255
+ * If binIds is omitted, auto-detects from the rewarder's rewarded range.
3256
+ */
3257
+ async buildClaimRewards(user, pool, binIds) {
3258
+ const rpcUrl = this.requireRpc();
3259
+ const client = createPublicClient6({ transport: http6(rpcUrl) });
3260
+ const hooksParams = await client.readContract({
3261
+ address: pool,
3262
+ abi: lbPairAbi,
3263
+ functionName: "getLBHooksParameters"
3264
+ });
3265
+ const rewarder = extractRewarderAddress(hooksParams);
3266
+ if (!rewarder) {
3267
+ throw new DefiError("CONTRACT_ERROR", `[${this.protocolName}] Pool ${pool} has no active rewarder`);
3268
+ }
3269
+ let resolvedBinIds = binIds;
3270
+ if (!resolvedBinIds || resolvedBinIds.length === 0) {
3271
+ const range = await client.readContract({
3272
+ address: rewarder,
3273
+ abi: lbRewarderAbi,
3274
+ functionName: "getRewardedRange"
3275
+ });
3276
+ const min = Number(range[0]);
3277
+ const max = Number(range[1]);
3278
+ resolvedBinIds = [];
3279
+ for (let b = min; b <= max; b++) resolvedBinIds.push(b);
3280
+ }
3281
+ const data = encodeFunctionData10({
3282
+ abi: lbRewarderAbi,
3283
+ functionName: "claim",
3284
+ args: [user, resolvedBinIds.map(BigInt)]
3285
+ });
3286
+ return {
3287
+ description: `[${this.protocolName}] LB claim rewards for ${resolvedBinIds.length} bins`,
3288
+ to: rewarder,
3289
+ data,
3290
+ value: 0n,
3291
+ gas_estimate: 3e5
3292
+ };
3293
+ }
3294
+ /**
3295
+ * Discover all active rewarded LB pools by iterating the factory.
3296
+ * Uses 7 multicall batches to minimise RPC round-trips and avoid 429s.
3297
+ *
3298
+ * Batch 1: getNumberOfLBPairs(), then getLBPairAtIndex(i) for all i
3299
+ * Batch 2: getLBHooksParameters() for all pairs → extract rewarder addresses
3300
+ * Batch 3: isStopped/getRewardedRange/getRewardToken/getPid/getMasterChef for each rewarder
3301
+ * Batch 4: getTokenX/getTokenY for each rewarded pair, then symbol() for unique tokens
3302
+ * Batch 5: Bootstrap MasterChef→VeMoe, then getMoePerSecond/getTreasuryShare/getStaticShare/getTotalWeight/getTopPoolIds
3303
+ * Batch 6: VeMoe.getWeight(pid) for each rewarded pool
3304
+ * Batch 7: Pool.getBin(binId) for all bins in rewarded range of each pool
3305
+ * Price: LB Quoter findBestPathFromAmountIn for MOE/WMNT and WMNT/USDT prices
3306
+ */
3307
+ async discoverRewardedPools() {
3308
+ const rpcUrl = this.requireRpc();
3309
+ const client = createPublicClient6({ transport: http6(rpcUrl) });
3310
+ const pairCount = await client.readContract({
3311
+ address: this.lbFactory,
3312
+ abi: lbFactoryAbi,
3313
+ functionName: "getNumberOfLBPairs"
3314
+ });
3315
+ const count = Number(pairCount);
3316
+ if (count === 0) return [];
3317
+ const batch1Calls = Array.from({ length: count }, (_, i) => [
3318
+ this.lbFactory,
3319
+ encodeFunctionData10({ abi: lbFactoryAbi, functionName: "getLBPairAtIndex", args: [BigInt(i)] })
3320
+ ]);
3321
+ const batch1Results = await multicallRead(rpcUrl, batch1Calls);
3322
+ const pairAddresses = batch1Results.map((r) => decodeAddressResult(r)).filter((a) => a !== null);
3323
+ if (pairAddresses.length === 0) return [];
3324
+ const batch2Calls = pairAddresses.map((pair) => [
3325
+ pair,
3326
+ encodeFunctionData10({ abi: lbPairAbi, functionName: "getLBHooksParameters" })
3327
+ ]);
3328
+ const batch2Results = await multicallRead(rpcUrl, batch2Calls);
3329
+ const rewardedPairs = [];
3330
+ for (let i = 0; i < pairAddresses.length; i++) {
3331
+ const raw = batch2Results[i];
3332
+ if (!raw) continue;
3333
+ let hooksBytes;
3334
+ try {
3335
+ const _bytes32Abi = parseAbi10(["function f() external view returns (bytes32)"]);
3336
+ hooksBytes = decodeFunctionResult22({ abi: _bytes32Abi, functionName: "f", data: raw });
3337
+ } catch {
3338
+ continue;
3339
+ }
3340
+ const rewarder = extractRewarderAddress(hooksBytes);
3341
+ if (rewarder) {
3342
+ rewardedPairs.push({ pool: pairAddresses[i], rewarder });
3343
+ }
3344
+ }
3345
+ if (rewardedPairs.length === 0) return [];
3346
+ const batch3Calls = [];
3347
+ for (const { rewarder } of rewardedPairs) {
3348
+ batch3Calls.push([rewarder, encodeFunctionData10({ abi: lbRewarderAbi, functionName: "isStopped" })]);
3349
+ batch3Calls.push([rewarder, encodeFunctionData10({ abi: lbRewarderAbi, functionName: "getRewardedRange" })]);
3350
+ batch3Calls.push([rewarder, encodeFunctionData10({ abi: lbRewarderAbi, functionName: "getRewardToken" })]);
3351
+ batch3Calls.push([rewarder, encodeFunctionData10({ abi: lbRewarderAbi, functionName: "getPid" })]);
3352
+ batch3Calls.push([rewarder, encodeFunctionData10({ abi: lbRewarderAbi, functionName: "getMasterChef" })]);
3353
+ }
3354
+ const batch3Results = await multicallRead(rpcUrl, batch3Calls);
3355
+ const batch4aCalls = [];
3356
+ for (const { pool } of rewardedPairs) {
3357
+ batch4aCalls.push([pool, encodeFunctionData10({ abi: lbPairAbi, functionName: "getTokenX" })]);
3358
+ batch4aCalls.push([pool, encodeFunctionData10({ abi: lbPairAbi, functionName: "getTokenY" })]);
3359
+ }
3360
+ const batch4aResults = await multicallRead(rpcUrl, batch4aCalls);
3361
+ const tokenXAddresses = [];
3362
+ const tokenYAddresses = [];
3363
+ for (let i = 0; i < rewardedPairs.length; i++) {
3364
+ tokenXAddresses.push(decodeAddressResult(batch4aResults[i * 2] ?? null));
3365
+ tokenYAddresses.push(decodeAddressResult(batch4aResults[i * 2 + 1] ?? null));
3366
+ }
3367
+ const uniqueTokens = Array.from(
3368
+ new Set([...tokenXAddresses, ...tokenYAddresses].filter((a) => a !== null))
3369
+ );
3370
+ const batch4bCalls = uniqueTokens.map((token) => [
3371
+ token,
3372
+ encodeFunctionData10({ abi: erc20Abi2, functionName: "symbol" })
3373
+ ]);
3374
+ const batch4bResults = await multicallRead(rpcUrl, batch4bCalls);
3375
+ const symbolMap = /* @__PURE__ */ new Map();
3376
+ for (let i = 0; i < uniqueTokens.length; i++) {
3377
+ symbolMap.set(uniqueTokens[i], decodeStringResult(batch4bResults[i] ?? null));
3378
+ }
3379
+ const STRIDE3 = 5;
3380
+ const poolData = [];
3381
+ for (let i = 0; i < rewardedPairs.length; i++) {
3382
+ const base = i * STRIDE3;
3383
+ poolData.push({
3384
+ stopped: decodeBoolResult(batch3Results[base] ?? null) ?? false,
3385
+ range: decodeRangeResult(batch3Results[base + 1] ?? null),
3386
+ rewardToken: decodeAddressResult(batch3Results[base + 2] ?? null),
3387
+ pid: Number(decodeUint256Result(batch3Results[base + 3] ?? null) ?? 0n),
3388
+ masterChef: decodeAddressResult(batch3Results[base + 4] ?? null)
3389
+ });
3390
+ }
3391
+ const masterChefAddr = poolData.map((d) => d.masterChef).find((a) => a !== null) ?? null;
3392
+ let moePerDay = 0;
3393
+ let topPoolIds = /* @__PURE__ */ new Set();
3394
+ let totalWeightRaw = 0n;
3395
+ let veMoeAddr = null;
3396
+ if (masterChefAddr) {
3397
+ veMoeAddr = await client.readContract({
3398
+ address: masterChefAddr,
3399
+ abi: masterChefAbi,
3400
+ functionName: "getVeMoe"
3401
+ });
3402
+ const batch5Calls = [
3403
+ [masterChefAddr, encodeFunctionData10({ abi: masterChefAbi, functionName: "getMoePerSecond" })],
3404
+ [masterChefAddr, encodeFunctionData10({ abi: masterChefAbi, functionName: "getTreasuryShare" })],
3405
+ [masterChefAddr, encodeFunctionData10({ abi: masterChefAbi, functionName: "getStaticShare" })],
3406
+ [veMoeAddr, encodeFunctionData10({ abi: veMoeAbi, functionName: "getTotalWeight" })],
3407
+ [veMoeAddr, encodeFunctionData10({ abi: veMoeAbi, functionName: "getTopPoolIds" })]
3408
+ ];
3409
+ const batch5Results = await multicallRead(rpcUrl, batch5Calls);
3410
+ const moePerSecRaw = decodeUint256Result(batch5Results[0] ?? null) ?? 0n;
3411
+ const treasuryShareRaw = decodeUint256Result(batch5Results[1] ?? null) ?? 0n;
3412
+ const staticShareRaw = decodeUint256Result(batch5Results[2] ?? null) ?? 0n;
3413
+ totalWeightRaw = decodeUint256Result(batch5Results[3] ?? null) ?? 0n;
3414
+ const topPoolIdsRaw = decodeUint256ArrayResult(batch5Results[4] ?? null) ?? [];
3415
+ topPoolIds = new Set(topPoolIdsRaw.map(Number));
3416
+ const PRECISION = 10n ** 18n;
3417
+ const netPerSec = moePerSecRaw * (PRECISION - treasuryShareRaw) / PRECISION * (PRECISION - staticShareRaw) / PRECISION;
3418
+ moePerDay = Number(netPerSec * 86400n) / 1e18;
3419
+ }
3420
+ const weightByPid = /* @__PURE__ */ new Map();
3421
+ if (veMoeAddr && rewardedPairs.length > 0) {
3422
+ const batch6Calls = poolData.map((d) => [
3423
+ veMoeAddr,
3424
+ encodeFunctionData10({ abi: veMoeAbi, functionName: "getWeight", args: [BigInt(d.pid)] })
3425
+ ]);
3426
+ const batch6Results = await multicallRead(rpcUrl, batch6Calls);
3427
+ for (let i = 0; i < poolData.length; i++) {
3428
+ weightByPid.set(poolData[i].pid, decodeUint256Result(batch6Results[i] ?? null) ?? 0n);
3429
+ }
3430
+ }
3431
+ let moePriceUsd = 0;
3432
+ let wmntPriceUsd = 0;
3433
+ const MOE_ADDR = "0x4515A45337F461A11Ff0FE8aBF3c606AE5dC00c9";
3434
+ if (this.lbQuoter && this.wmnt && this.usdt) {
3435
+ try {
3436
+ const [moeWmntQuote, wmntUsdtQuote] = await Promise.all([
3437
+ client.readContract({
3438
+ address: this.lbQuoter,
3439
+ abi: lbQuoterAbi2,
3440
+ functionName: "findBestPathFromAmountIn",
3441
+ args: [[MOE_ADDR, this.wmnt], 10n ** 18n]
3442
+ }),
3443
+ client.readContract({
3444
+ address: this.lbQuoter,
3445
+ abi: lbQuoterAbi2,
3446
+ functionName: "findBestPathFromAmountIn",
3447
+ args: [[this.wmnt, this.usdt], 10n ** 18n]
3448
+ })
3449
+ ]);
3450
+ const moeInWmnt = Number(moeWmntQuote.amounts.at(-1) ?? 0n) / 1e18;
3451
+ wmntPriceUsd = Number(wmntUsdtQuote.amounts.at(-1) ?? 0n) / 1e6;
3452
+ moePriceUsd = moeInWmnt * wmntPriceUsd;
3453
+ } catch {
3454
+ }
3455
+ }
3456
+ const binRequests = [];
3457
+ for (let i = 0; i < rewardedPairs.length; i++) {
3458
+ const range = poolData[i].range;
3459
+ if (!range) continue;
3460
+ const minBin = Number(range[0]);
3461
+ const maxBin = Number(range[1]);
3462
+ for (let b = minBin; b <= maxBin; b++) {
3463
+ binRequests.push({ poolIdx: i, binId: b });
3464
+ }
3465
+ }
3466
+ const binReservesX = /* @__PURE__ */ new Map();
3467
+ const binReservesY = /* @__PURE__ */ new Map();
3468
+ if (binRequests.length > 0) {
3469
+ const batch7Calls = binRequests.map(({ poolIdx, binId }) => [
3470
+ rewardedPairs[poolIdx].pool,
3471
+ encodeFunctionData10({ abi: lbPairBinAbi, functionName: "getBin", args: [binId] })
3472
+ ]);
3473
+ const batch7Results = await multicallRead(rpcUrl, batch7Calls);
3474
+ for (let j = 0; j < binRequests.length; j++) {
3475
+ const { poolIdx, binId } = binRequests[j];
3476
+ const decoded = decodeBinResult(batch7Results[j] ?? null);
3477
+ if (!decoded) continue;
3478
+ if (!binReservesX.has(poolIdx)) {
3479
+ binReservesX.set(poolIdx, /* @__PURE__ */ new Map());
3480
+ binReservesY.set(poolIdx, /* @__PURE__ */ new Map());
3481
+ }
3482
+ binReservesX.get(poolIdx).set(binId, decoded[0]);
3483
+ binReservesY.get(poolIdx).set(binId, decoded[1]);
3484
+ }
3485
+ }
3486
+ const stableSymbols = /* @__PURE__ */ new Set(["USDT", "USDC", "MUSD", "AUSD", "USDY", "FDUSD"]);
3487
+ const mntSymbols = /* @__PURE__ */ new Set(["WMNT", "MNT"]);
3488
+ const moeSymbols = /* @__PURE__ */ new Set(["MOE"]);
3489
+ const sixDecimalStables = /* @__PURE__ */ new Set(["USDT", "USDC", "FDUSD"]);
3490
+ const getTokenPriceUsd = (sym) => {
3491
+ if (stableSymbols.has(sym)) return 1;
3492
+ if (mntSymbols.has(sym)) return wmntPriceUsd;
3493
+ if (moeSymbols.has(sym)) return moePriceUsd;
3494
+ return 0;
3495
+ };
3496
+ const getTokenDecimals = (sym) => {
3497
+ return sixDecimalStables.has(sym) ? 6 : 18;
3498
+ };
3499
+ const results = [];
3500
+ for (let i = 0; i < rewardedPairs.length; i++) {
3501
+ const { pool, rewarder } = rewardedPairs[i];
3502
+ const data = poolData[i];
3503
+ const tokenX = tokenXAddresses[i] ?? "0x0000000000000000000000000000000000000000";
3504
+ const tokenY = tokenYAddresses[i] ?? "0x0000000000000000000000000000000000000000";
3505
+ const symX = symbolMap.get(tokenX) ?? "?";
3506
+ const symY = symbolMap.get(tokenY) ?? "?";
3507
+ const isTopPool = topPoolIds.has(data.pid);
3508
+ const weight = weightByPid.get(data.pid) ?? 0n;
3509
+ let poolMoePerDay = 0;
3510
+ if (isTopPool && totalWeightRaw > 0n && weight > 0n) {
3511
+ poolMoePerDay = moePerDay * (Number(weight) / Number(totalWeightRaw));
3512
+ }
3513
+ const rxMap = binReservesX.get(i);
3514
+ const ryMap = binReservesY.get(i);
3515
+ const range = data.range;
3516
+ let rangeTvlUsd = 0;
3517
+ let rewardedBins = 0;
3518
+ if (range) {
3519
+ const minBin = Number(range[0]);
3520
+ const maxBin = Number(range[1]);
3521
+ rewardedBins = maxBin - minBin + 1;
3522
+ if (rxMap && ryMap) {
3523
+ const priceX = getTokenPriceUsd(symX);
3524
+ const priceY = getTokenPriceUsd(symY);
3525
+ const decX = getTokenDecimals(symX);
3526
+ const decY = getTokenDecimals(symY);
3527
+ for (let b = minBin; b <= maxBin; b++) {
3528
+ const rx = rxMap.get(b) ?? 0n;
3529
+ const ry = ryMap.get(b) ?? 0n;
3530
+ rangeTvlUsd += Number(rx) / 10 ** decX * priceX;
3531
+ rangeTvlUsd += Number(ry) / 10 ** decY * priceY;
3532
+ }
3533
+ }
3534
+ }
3535
+ const aprPercent = rangeTvlUsd > 0 && moePriceUsd > 0 ? poolMoePerDay * moePriceUsd * 365 / rangeTvlUsd * 100 : 0;
3536
+ results.push({
3537
+ pool,
3538
+ rewarder,
3539
+ rewardToken: data.rewardToken ?? "0x0000000000000000000000000000000000000000",
3540
+ minBinId: range ? Number(range[0]) : 0,
3541
+ maxBinId: range ? Number(range[1]) : 0,
3542
+ pid: data.pid,
3543
+ stopped: data.stopped,
3544
+ tokenX,
3545
+ tokenY,
3546
+ symbolX: symX,
3547
+ symbolY: symY,
3548
+ isTopPool,
3549
+ moePerDay: poolMoePerDay,
3550
+ rangeTvlUsd,
3551
+ aprPercent,
3552
+ rewardedBins
3553
+ });
3554
+ }
3555
+ return results;
3556
+ }
3557
+ /**
3558
+ * Get a user's LB positions (bin balances) across a range of bin IDs.
3559
+ * If binIds is omitted, auto-detects from the rewarder's rewarded range (or active ± 50).
3560
+ */
3561
+ async getUserPositions(user, pool, binIds) {
3562
+ const rpcUrl = this.requireRpc();
3563
+ const client = createPublicClient6({ transport: http6(rpcUrl) });
3564
+ const resolvedBinIds = binIds && binIds.length > 0 ? binIds : await this.autoDetectBins(pool);
3565
+ const accounts = resolvedBinIds.map(() => user);
3566
+ const ids = resolvedBinIds.map(BigInt);
3567
+ const balances = await client.readContract({
3568
+ address: pool,
3569
+ abi: lbPairAbi,
3570
+ functionName: "balanceOfBatch",
3571
+ args: [accounts, ids]
3572
+ });
3573
+ return resolvedBinIds.map((binId, i) => ({ binId, balance: balances[i] ?? 0n })).filter((p) => p.balance > 0n);
3574
+ }
3575
+ };
3576
+ POOL_ABI = parseAbi11([
2824
3577
  "function supply(address asset, uint256 amount, address onBehalfOf, uint16 referralCode) external",
2825
3578
  "function borrow(address asset, uint256 amount, uint256 interestRateMode, uint16 referralCode, address onBehalfOf) external",
2826
3579
  "function repay(address asset, uint256 amount, uint256 interestRateMode, address onBehalfOf) external returns (uint256)",
@@ -2828,27 +3581,27 @@ var init_dist3 = __esm({
2828
3581
  "function getUserAccountData(address user) external view returns (uint256 totalCollateralBase, uint256 totalDebtBase, uint256 availableBorrowsBase, uint256 currentLiquidationThreshold, uint256 ltv, uint256 healthFactor)",
2829
3582
  "function getReserveData(address asset) external view returns (uint256 configuration, uint128 liquidityIndex, uint128 currentLiquidityRate, uint128 variableBorrowIndex, uint128 currentVariableBorrowRate, uint128 currentStableBorrowRate, uint40 lastUpdateTimestamp, uint16 id, address aTokenAddress, address stableDebtTokenAddress, address variableDebtTokenAddress, address interestRateStrategyAddress, uint128 accruedToTreasury, uint128 unbacked, uint128 isolationModeTotalDebt)"
2830
3583
  ]);
2831
- ERC20_ABI = parseAbi10([
3584
+ ERC20_ABI = parseAbi11([
2832
3585
  "function totalSupply() external view returns (uint256)"
2833
3586
  ]);
2834
- INCENTIVES_ABI = parseAbi10([
3587
+ INCENTIVES_ABI = parseAbi11([
2835
3588
  "function getIncentivesController() external view returns (address)"
2836
3589
  ]);
2837
- REWARDS_CONTROLLER_ABI = parseAbi10([
3590
+ REWARDS_CONTROLLER_ABI = parseAbi11([
2838
3591
  "function getRewardsByAsset(address asset) external view returns (address[])",
2839
3592
  "function getRewardsData(address asset, address reward) external view returns (uint256 index, uint256 emissionsPerSecond, uint256 lastUpdateTimestamp, uint256 distributionEnd)"
2840
3593
  ]);
2841
- POOL_PROVIDER_ABI = parseAbi10([
3594
+ POOL_PROVIDER_ABI = parseAbi11([
2842
3595
  "function ADDRESSES_PROVIDER() external view returns (address)"
2843
3596
  ]);
2844
- ADDRESSES_PROVIDER_ABI = parseAbi10([
3597
+ ADDRESSES_PROVIDER_ABI = parseAbi11([
2845
3598
  "function getPriceOracle() external view returns (address)"
2846
3599
  ]);
2847
- ORACLE_ABI = parseAbi10([
3600
+ ORACLE_ABI = parseAbi11([
2848
3601
  "function getAssetPrice(address asset) external view returns (uint256)",
2849
3602
  "function BASE_CURRENCY_UNIT() external view returns (uint256)"
2850
3603
  ]);
2851
- ERC20_DECIMALS_ABI = parseAbi10([
3604
+ ERC20_DECIMALS_ABI = parseAbi11([
2852
3605
  "function decimals() external view returns (uint8)"
2853
3606
  ]);
2854
3607
  AaveV3Adapter = class {
@@ -2866,7 +3619,7 @@ var init_dist3 = __esm({
2866
3619
  return this.protocolName;
2867
3620
  }
2868
3621
  async buildSupply(params) {
2869
- const data = encodeFunctionData10({
3622
+ const data = encodeFunctionData11({
2870
3623
  abi: POOL_ABI,
2871
3624
  functionName: "supply",
2872
3625
  args: [params.asset, params.amount, params.on_behalf_of, 0]
@@ -2882,7 +3635,7 @@ var init_dist3 = __esm({
2882
3635
  }
2883
3636
  async buildBorrow(params) {
2884
3637
  const rateMode = params.interest_rate_mode === InterestRateMode.Stable ? 1n : 2n;
2885
- const data = encodeFunctionData10({
3638
+ const data = encodeFunctionData11({
2886
3639
  abi: POOL_ABI,
2887
3640
  functionName: "borrow",
2888
3641
  args: [params.asset, params.amount, rateMode, 0, params.on_behalf_of]
@@ -2897,7 +3650,7 @@ var init_dist3 = __esm({
2897
3650
  }
2898
3651
  async buildRepay(params) {
2899
3652
  const rateMode = params.interest_rate_mode === InterestRateMode.Stable ? 1n : 2n;
2900
- const data = encodeFunctionData10({
3653
+ const data = encodeFunctionData11({
2901
3654
  abi: POOL_ABI,
2902
3655
  functionName: "repay",
2903
3656
  args: [params.asset, params.amount, rateMode, params.on_behalf_of]
@@ -2912,7 +3665,7 @@ var init_dist3 = __esm({
2912
3665
  };
2913
3666
  }
2914
3667
  async buildWithdraw(params) {
2915
- const data = encodeFunctionData10({
3668
+ const data = encodeFunctionData11({
2916
3669
  abi: POOL_ABI,
2917
3670
  functionName: "withdraw",
2918
3671
  args: [params.asset, params.amount, params.to]
@@ -2927,15 +3680,21 @@ var init_dist3 = __esm({
2927
3680
  }
2928
3681
  async getRates(asset) {
2929
3682
  if (!this.rpcUrl) throw DefiError.rpcError("No RPC URL configured");
2930
- const client = createPublicClient7({ transport: http7(this.rpcUrl) });
2931
- const result = await client.readContract({
2932
- address: this.pool,
3683
+ const reserveCallData = encodeFunctionData11({
2933
3684
  abi: POOL_ABI,
2934
3685
  functionName: "getReserveData",
2935
3686
  args: [asset]
2936
- }).catch((e) => {
3687
+ });
3688
+ const [reserveRaw] = await multicallRead(this.rpcUrl, [
3689
+ [this.pool, reserveCallData]
3690
+ ]).catch((e) => {
2937
3691
  throw DefiError.rpcError(`[${this.protocolName}] getReserveData failed: ${e}`);
2938
3692
  });
3693
+ const reserveDecoded = decodeReserveData(reserveRaw ?? null);
3694
+ if (!reserveDecoded) {
3695
+ throw DefiError.rpcError(`[${this.protocolName}] getReserveData returned no data`);
3696
+ }
3697
+ const result = reserveDecoded;
2939
3698
  const RAY = 1e27;
2940
3699
  const SECONDS_PER_YEAR4 = 31536e3;
2941
3700
  const toApy = (rayRate) => {
@@ -2947,74 +3706,56 @@ var init_dist3 = __esm({
2947
3706
  const stableRate = toApy(result[5]);
2948
3707
  const aTokenAddress = result[8];
2949
3708
  const variableDebtTokenAddress = result[10];
2950
- const [totalSupply, totalBorrow] = await Promise.all([
2951
- client.readContract({
2952
- address: aTokenAddress,
2953
- abi: ERC20_ABI,
2954
- functionName: "totalSupply"
2955
- }).catch(() => 0n),
2956
- client.readContract({
2957
- address: variableDebtTokenAddress,
2958
- abi: ERC20_ABI,
2959
- functionName: "totalSupply"
2960
- }).catch(() => 0n)
3709
+ const [supplyRaw, borrowRaw] = await multicallRead(this.rpcUrl, [
3710
+ [aTokenAddress, encodeFunctionData11({ abi: ERC20_ABI, functionName: "totalSupply" })],
3711
+ [variableDebtTokenAddress, encodeFunctionData11({ abi: ERC20_ABI, functionName: "totalSupply" })]
2961
3712
  ]);
3713
+ const totalSupply = decodeU256(supplyRaw ?? null);
3714
+ const totalBorrow = decodeU256(borrowRaw ?? null);
2962
3715
  const utilization = totalSupply > 0n ? Number(totalBorrow * 10000n / totalSupply) / 100 : 0;
2963
3716
  const supplyRewardTokens = [];
2964
3717
  const borrowRewardTokens = [];
2965
3718
  const supplyEmissions = [];
2966
3719
  const borrowEmissions = [];
2967
3720
  try {
2968
- const controllerAddr = await client.readContract({
2969
- address: aTokenAddress,
2970
- abi: INCENTIVES_ABI,
2971
- functionName: "getIncentivesController"
2972
- });
3721
+ const [controllerRaw] = await multicallRead(this.rpcUrl, [
3722
+ [aTokenAddress, encodeFunctionData11({ abi: INCENTIVES_ABI, functionName: "getIncentivesController" })]
3723
+ ]);
3724
+ const controllerAddr = decodeAddress(controllerRaw ?? null);
2973
3725
  if (controllerAddr && controllerAddr !== zeroAddress5) {
2974
- const [supplyRewards, borrowRewards] = await Promise.all([
2975
- client.readContract({
2976
- address: controllerAddr,
2977
- abi: REWARDS_CONTROLLER_ABI,
2978
- functionName: "getRewardsByAsset",
2979
- args: [aTokenAddress]
2980
- }).catch(() => []),
2981
- client.readContract({
2982
- address: controllerAddr,
2983
- abi: REWARDS_CONTROLLER_ABI,
2984
- functionName: "getRewardsByAsset",
2985
- args: [variableDebtTokenAddress]
2986
- }).catch(() => [])
3726
+ const [supplyRewardsRaw, borrowRewardsRaw] = await multicallRead(this.rpcUrl, [
3727
+ [controllerAddr, encodeFunctionData11({ abi: REWARDS_CONTROLLER_ABI, functionName: "getRewardsByAsset", args: [aTokenAddress] })],
3728
+ [controllerAddr, encodeFunctionData11({ abi: REWARDS_CONTROLLER_ABI, functionName: "getRewardsByAsset", args: [variableDebtTokenAddress] })]
2987
3729
  ]);
2988
- const supplyDataPromises = supplyRewards.map(
2989
- (reward) => client.readContract({
2990
- address: controllerAddr,
2991
- abi: REWARDS_CONTROLLER_ABI,
2992
- functionName: "getRewardsData",
2993
- args: [aTokenAddress, reward]
2994
- }).catch(() => null)
2995
- );
2996
- const supplyData = await Promise.all(supplyDataPromises);
2997
- for (let i = 0; i < supplyRewards.length; i++) {
2998
- const data = supplyData[i];
2999
- if (data && data[1] > 0n) {
3000
- supplyRewardTokens.push(supplyRewards[i]);
3001
- supplyEmissions.push(data[1].toString());
3730
+ const supplyRewards = decodeAddressArray(supplyRewardsRaw ?? null);
3731
+ const borrowRewards = decodeAddressArray(borrowRewardsRaw ?? null);
3732
+ const rewardsDataCalls = [
3733
+ ...supplyRewards.map((reward) => [
3734
+ controllerAddr,
3735
+ encodeFunctionData11({ abi: REWARDS_CONTROLLER_ABI, functionName: "getRewardsData", args: [aTokenAddress, reward] })
3736
+ ]),
3737
+ ...borrowRewards.map((reward) => [
3738
+ controllerAddr,
3739
+ encodeFunctionData11({ abi: REWARDS_CONTROLLER_ABI, functionName: "getRewardsData", args: [variableDebtTokenAddress, reward] })
3740
+ ])
3741
+ ];
3742
+ if (rewardsDataCalls.length > 0) {
3743
+ const rewardsDataResults = await multicallRead(this.rpcUrl, rewardsDataCalls);
3744
+ const supplyDataResults = rewardsDataResults.slice(0, supplyRewards.length);
3745
+ const borrowDataResults = rewardsDataResults.slice(supplyRewards.length);
3746
+ for (let i = 0; i < supplyRewards.length; i++) {
3747
+ const data = decodeRewardsData(supplyDataResults[i] ?? null);
3748
+ if (data && data[1] > 0n) {
3749
+ supplyRewardTokens.push(supplyRewards[i]);
3750
+ supplyEmissions.push(data[1].toString());
3751
+ }
3002
3752
  }
3003
- }
3004
- const borrowDataPromises = borrowRewards.map(
3005
- (reward) => client.readContract({
3006
- address: controllerAddr,
3007
- abi: REWARDS_CONTROLLER_ABI,
3008
- functionName: "getRewardsData",
3009
- args: [variableDebtTokenAddress, reward]
3010
- }).catch(() => null)
3011
- );
3012
- const borrowData = await Promise.all(borrowDataPromises);
3013
- for (let i = 0; i < borrowRewards.length; i++) {
3014
- const data = borrowData[i];
3015
- if (data && data[1] > 0n) {
3016
- borrowRewardTokens.push(borrowRewards[i]);
3017
- borrowEmissions.push(data[1].toString());
3753
+ for (let i = 0; i < borrowRewards.length; i++) {
3754
+ const data = decodeRewardsData(borrowDataResults[i] ?? null);
3755
+ if (data && data[1] > 0n) {
3756
+ borrowRewardTokens.push(borrowRewards[i]);
3757
+ borrowEmissions.push(data[1].toString());
3758
+ }
3018
3759
  }
3019
3760
  }
3020
3761
  }
@@ -3026,55 +3767,49 @@ var init_dist3 = __esm({
3026
3767
  const hasBorrowRewards = borrowRewardTokens.length > 0;
3027
3768
  if ((hasSupplyRewards || hasBorrowRewards) && totalSupply > 0n) {
3028
3769
  try {
3029
- const providerAddr = await client.readContract({
3030
- address: this.pool,
3031
- abi: POOL_PROVIDER_ABI,
3032
- functionName: "ADDRESSES_PROVIDER"
3033
- });
3034
- const oracleAddr = await client.readContract({
3035
- address: providerAddr,
3036
- abi: ADDRESSES_PROVIDER_ABI,
3037
- functionName: "getPriceOracle"
3038
- });
3039
- const [assetPrice, baseCurrencyUnit, assetDecimals] = await Promise.all([
3040
- client.readContract({
3041
- address: oracleAddr,
3042
- abi: ORACLE_ABI,
3043
- functionName: "getAssetPrice",
3044
- args: [asset]
3045
- }),
3046
- client.readContract({
3047
- address: oracleAddr,
3048
- abi: ORACLE_ABI,
3049
- functionName: "BASE_CURRENCY_UNIT"
3050
- }),
3051
- client.readContract({
3052
- address: asset,
3053
- abi: ERC20_DECIMALS_ABI,
3054
- functionName: "decimals"
3055
- }).catch(() => 18)
3770
+ const [providerRaw] = await multicallRead(this.rpcUrl, [
3771
+ [this.pool, encodeFunctionData11({ abi: POOL_PROVIDER_ABI, functionName: "ADDRESSES_PROVIDER" })]
3772
+ ]);
3773
+ const providerAddr = decodeAddress(providerRaw ?? null);
3774
+ if (!providerAddr) throw new Error("No provider address");
3775
+ const [oracleRaw] = await multicallRead(this.rpcUrl, [
3776
+ [providerAddr, encodeFunctionData11({ abi: ADDRESSES_PROVIDER_ABI, functionName: "getPriceOracle" })]
3056
3777
  ]);
3057
- const priceUnit = Number(baseCurrencyUnit);
3778
+ const oracleAddr = decodeAddress(oracleRaw ?? null);
3779
+ if (!oracleAddr) throw new Error("No oracle address");
3780
+ const [assetPriceRaw, baseCurrencyUnitRaw, assetDecimalsRaw] = await multicallRead(this.rpcUrl, [
3781
+ [oracleAddr, encodeFunctionData11({ abi: ORACLE_ABI, functionName: "getAssetPrice", args: [asset] })],
3782
+ [oracleAddr, encodeFunctionData11({ abi: ORACLE_ABI, functionName: "BASE_CURRENCY_UNIT" })],
3783
+ [asset, encodeFunctionData11({ abi: ERC20_DECIMALS_ABI, functionName: "decimals" })]
3784
+ ]);
3785
+ const assetPrice = decodeU256(assetPriceRaw ?? null);
3786
+ const baseCurrencyUnit = decodeU256(baseCurrencyUnitRaw ?? null);
3787
+ const assetDecimals = assetDecimalsRaw ? Number(decodeU256(assetDecimalsRaw)) : 18;
3788
+ const priceUnit = Number(baseCurrencyUnit) || 1e8;
3058
3789
  const assetPriceF = Number(assetPrice) / priceUnit;
3059
3790
  const assetDecimalsDivisor = 10 ** assetDecimals;
3791
+ const allRewardTokens = Array.from(/* @__PURE__ */ new Set([...supplyRewardTokens, ...borrowRewardTokens]));
3792
+ const rewardPriceCalls = allRewardTokens.flatMap((token) => [
3793
+ [oracleAddr, encodeFunctionData11({ abi: ORACLE_ABI, functionName: "getAssetPrice", args: [token] })],
3794
+ [token, encodeFunctionData11({ abi: ERC20_DECIMALS_ABI, functionName: "decimals" })]
3795
+ ]);
3796
+ const rewardPriceResults = rewardPriceCalls.length > 0 ? await multicallRead(this.rpcUrl, rewardPriceCalls) : [];
3797
+ const rewardPriceMap = /* @__PURE__ */ new Map();
3798
+ for (let i = 0; i < allRewardTokens.length; i++) {
3799
+ const priceRaw = rewardPriceResults[i * 2] ?? null;
3800
+ const decimalsRaw = rewardPriceResults[i * 2 + 1] ?? null;
3801
+ const price = decodeU256(priceRaw);
3802
+ const decimals = decimalsRaw ? Number(decodeU256(decimalsRaw)) : 18;
3803
+ rewardPriceMap.set(allRewardTokens[i].toLowerCase(), { price, decimals });
3804
+ }
3060
3805
  if (hasSupplyRewards) {
3061
3806
  let totalSupplyIncentiveUsdPerYear = 0;
3062
3807
  const totalSupplyUsd = Number(totalSupply) / assetDecimalsDivisor * assetPriceF;
3063
3808
  for (let i = 0; i < supplyRewardTokens.length; i++) {
3064
3809
  const emissionPerSec = BigInt(supplyEmissions[i]);
3065
- const [rewardPrice, rewardDecimals] = await Promise.all([
3066
- client.readContract({
3067
- address: oracleAddr,
3068
- abi: ORACLE_ABI,
3069
- functionName: "getAssetPrice",
3070
- args: [supplyRewardTokens[i]]
3071
- }).catch(() => 0n),
3072
- client.readContract({
3073
- address: supplyRewardTokens[i],
3074
- abi: ERC20_DECIMALS_ABI,
3075
- functionName: "decimals"
3076
- }).catch(() => 18)
3077
- ]);
3810
+ const entry = rewardPriceMap.get(supplyRewardTokens[i].toLowerCase());
3811
+ const rewardPrice = entry?.price ?? 0n;
3812
+ const rewardDecimals = entry?.decimals ?? 18;
3078
3813
  if (rewardPrice > 0n) {
3079
3814
  const rewardPriceF = Number(rewardPrice) / priceUnit;
3080
3815
  const emissionPerYear = Number(emissionPerSec) / 10 ** rewardDecimals * SECONDS_PER_YEAR4;
@@ -3090,19 +3825,9 @@ var init_dist3 = __esm({
3090
3825
  const totalBorrowUsd = Number(totalBorrow) / assetDecimalsDivisor * assetPriceF;
3091
3826
  for (let i = 0; i < borrowRewardTokens.length; i++) {
3092
3827
  const emissionPerSec = BigInt(borrowEmissions[i]);
3093
- const [rewardPrice, rewardDecimals] = await Promise.all([
3094
- client.readContract({
3095
- address: oracleAddr,
3096
- abi: ORACLE_ABI,
3097
- functionName: "getAssetPrice",
3098
- args: [borrowRewardTokens[i]]
3099
- }).catch(() => 0n),
3100
- client.readContract({
3101
- address: borrowRewardTokens[i],
3102
- abi: ERC20_DECIMALS_ABI,
3103
- functionName: "decimals"
3104
- }).catch(() => 18)
3105
- ]);
3828
+ const entry = rewardPriceMap.get(borrowRewardTokens[i].toLowerCase());
3829
+ const rewardPrice = entry?.price ?? 0n;
3830
+ const rewardDecimals = entry?.decimals ?? 18;
3106
3831
  if (rewardPrice > 0n) {
3107
3832
  const rewardPriceF = Number(rewardPrice) / priceUnit;
3108
3833
  const emissionPerYear = Number(emissionPerSec) / 10 ** rewardDecimals * SECONDS_PER_YEAR4;
@@ -3166,7 +3891,7 @@ var init_dist3 = __esm({
3166
3891
  };
3167
3892
  }
3168
3893
  };
3169
- POOL_ABI2 = parseAbi11([
3894
+ POOL_ABI2 = parseAbi12([
3170
3895
  "function deposit(address asset, uint256 amount, address onBehalfOf, uint16 referralCode) external",
3171
3896
  "function borrow(address asset, uint256 amount, uint256 interestRateMode, uint16 referralCode, address onBehalfOf) external",
3172
3897
  "function repay(address asset, uint256 amount, uint256 rateMode, address onBehalfOf) external returns (uint256)",
@@ -3179,7 +3904,7 @@ var init_dist3 = __esm({
3179
3904
  // [9]=variableDebtTokenAddress, [10]=interestRateStrategyAddress, [11]=id
3180
3905
  "function getReserveData(address asset) external view returns (uint256 configuration, uint128 liquidityIndex, uint128 variableBorrowIndex, uint128 currentLiquidityRate, uint128 currentVariableBorrowRate, uint128 currentStableBorrowRate, uint40 lastUpdateTimestamp, address aTokenAddress, address stableDebtTokenAddress, address variableDebtTokenAddress, address interestRateStrategyAddress, uint8 id)"
3181
3906
  ]);
3182
- ERC20_ABI2 = parseAbi11([
3907
+ ERC20_ABI2 = parseAbi12([
3183
3908
  "function totalSupply() external view returns (uint256)"
3184
3909
  ]);
3185
3910
  AaveV2Adapter = class {
@@ -3197,7 +3922,7 @@ var init_dist3 = __esm({
3197
3922
  return this.protocolName;
3198
3923
  }
3199
3924
  async buildSupply(params) {
3200
- const data = encodeFunctionData11({
3925
+ const data = encodeFunctionData12({
3201
3926
  abi: POOL_ABI2,
3202
3927
  functionName: "deposit",
3203
3928
  args: [params.asset, params.amount, params.on_behalf_of, 0]
@@ -3213,7 +3938,7 @@ var init_dist3 = __esm({
3213
3938
  }
3214
3939
  async buildBorrow(params) {
3215
3940
  const rateMode = params.interest_rate_mode === InterestRateMode.Stable ? 1n : 2n;
3216
- const data = encodeFunctionData11({
3941
+ const data = encodeFunctionData12({
3217
3942
  abi: POOL_ABI2,
3218
3943
  functionName: "borrow",
3219
3944
  args: [params.asset, params.amount, rateMode, 0, params.on_behalf_of]
@@ -3228,7 +3953,7 @@ var init_dist3 = __esm({
3228
3953
  }
3229
3954
  async buildRepay(params) {
3230
3955
  const rateMode = params.interest_rate_mode === InterestRateMode.Stable ? 1n : 2n;
3231
- const data = encodeFunctionData11({
3956
+ const data = encodeFunctionData12({
3232
3957
  abi: POOL_ABI2,
3233
3958
  functionName: "repay",
3234
3959
  args: [params.asset, params.amount, rateMode, params.on_behalf_of]
@@ -3243,7 +3968,7 @@ var init_dist3 = __esm({
3243
3968
  };
3244
3969
  }
3245
3970
  async buildWithdraw(params) {
3246
- const data = encodeFunctionData11({
3971
+ const data = encodeFunctionData12({
3247
3972
  abi: POOL_ABI2,
3248
3973
  functionName: "withdraw",
3249
3974
  args: [params.asset, params.amount, params.to]
@@ -3331,7 +4056,7 @@ var init_dist3 = __esm({
3331
4056
  };
3332
4057
  }
3333
4058
  };
3334
- ORACLE_ABI2 = parseAbi12([
4059
+ ORACLE_ABI2 = parseAbi13([
3335
4060
  "function getAssetPrice(address asset) external view returns (uint256)",
3336
4061
  "function getAssetsPrices(address[] calldata assets) external view returns (uint256[] memory)",
3337
4062
  "function BASE_CURRENCY_UNIT() external view returns (uint256)"
@@ -3408,7 +4133,7 @@ var init_dist3 = __esm({
3408
4133
  });
3409
4134
  }
3410
4135
  };
3411
- CTOKEN_ABI = parseAbi13([
4136
+ CTOKEN_ABI = parseAbi14([
3412
4137
  "function supplyRatePerBlock() external view returns (uint256)",
3413
4138
  "function borrowRatePerBlock() external view returns (uint256)",
3414
4139
  "function totalSupply() external view returns (uint256)",
@@ -3435,7 +4160,7 @@ var init_dist3 = __esm({
3435
4160
  return this.protocolName;
3436
4161
  }
3437
4162
  async buildSupply(params) {
3438
- const data = encodeFunctionData12({
4163
+ const data = encodeFunctionData13({
3439
4164
  abi: CTOKEN_ABI,
3440
4165
  functionName: "mint",
3441
4166
  args: [params.amount]
@@ -3449,7 +4174,7 @@ var init_dist3 = __esm({
3449
4174
  };
3450
4175
  }
3451
4176
  async buildBorrow(params) {
3452
- const data = encodeFunctionData12({
4177
+ const data = encodeFunctionData13({
3453
4178
  abi: CTOKEN_ABI,
3454
4179
  functionName: "borrow",
3455
4180
  args: [params.amount]
@@ -3463,7 +4188,7 @@ var init_dist3 = __esm({
3463
4188
  };
3464
4189
  }
3465
4190
  async buildRepay(params) {
3466
- const data = encodeFunctionData12({
4191
+ const data = encodeFunctionData13({
3467
4192
  abi: CTOKEN_ABI,
3468
4193
  functionName: "repayBorrow",
3469
4194
  args: [params.amount]
@@ -3477,7 +4202,7 @@ var init_dist3 = __esm({
3477
4202
  };
3478
4203
  }
3479
4204
  async buildWithdraw(params) {
3480
- const data = encodeFunctionData12({
4205
+ const data = encodeFunctionData13({
3481
4206
  abi: CTOKEN_ABI,
3482
4207
  functionName: "redeem",
3483
4208
  args: [params.amount]
@@ -3526,7 +4251,7 @@ var init_dist3 = __esm({
3526
4251
  );
3527
4252
  }
3528
4253
  };
3529
- COMET_ABI = parseAbi14([
4254
+ COMET_ABI = parseAbi15([
3530
4255
  "function getUtilization() external view returns (uint256)",
3531
4256
  "function getSupplyRate(uint256 utilization) external view returns (uint64)",
3532
4257
  "function getBorrowRate(uint256 utilization) external view returns (uint64)",
@@ -3552,7 +4277,7 @@ var init_dist3 = __esm({
3552
4277
  return this.protocolName;
3553
4278
  }
3554
4279
  async buildSupply(params) {
3555
- const data = encodeFunctionData13({
4280
+ const data = encodeFunctionData14({
3556
4281
  abi: COMET_ABI,
3557
4282
  functionName: "supply",
3558
4283
  args: [params.asset, params.amount]
@@ -3566,7 +4291,7 @@ var init_dist3 = __esm({
3566
4291
  };
3567
4292
  }
3568
4293
  async buildBorrow(params) {
3569
- const data = encodeFunctionData13({
4294
+ const data = encodeFunctionData14({
3570
4295
  abi: COMET_ABI,
3571
4296
  functionName: "withdraw",
3572
4297
  args: [params.asset, params.amount]
@@ -3580,7 +4305,7 @@ var init_dist3 = __esm({
3580
4305
  };
3581
4306
  }
3582
4307
  async buildRepay(params) {
3583
- const data = encodeFunctionData13({
4308
+ const data = encodeFunctionData14({
3584
4309
  abi: COMET_ABI,
3585
4310
  functionName: "supply",
3586
4311
  args: [params.asset, params.amount]
@@ -3594,7 +4319,7 @@ var init_dist3 = __esm({
3594
4319
  };
3595
4320
  }
3596
4321
  async buildWithdraw(params) {
3597
- const data = encodeFunctionData13({
4322
+ const data = encodeFunctionData14({
3598
4323
  abi: COMET_ABI,
3599
4324
  functionName: "withdraw",
3600
4325
  args: [params.asset, params.amount]
@@ -3648,7 +4373,7 @@ var init_dist3 = __esm({
3648
4373
  );
3649
4374
  }
3650
4375
  };
3651
- EULER_VAULT_ABI = parseAbi15([
4376
+ EULER_VAULT_ABI = parseAbi16([
3652
4377
  "function deposit(uint256 amount, address receiver) external returns (uint256)",
3653
4378
  "function withdraw(uint256 amount, address receiver, address owner) external returns (uint256)",
3654
4379
  "function borrow(uint256 amount, address receiver) external returns (uint256)",
@@ -3674,7 +4399,7 @@ var init_dist3 = __esm({
3674
4399
  return this.protocolName;
3675
4400
  }
3676
4401
  async buildSupply(params) {
3677
- const data = encodeFunctionData14({
4402
+ const data = encodeFunctionData15({
3678
4403
  abi: EULER_VAULT_ABI,
3679
4404
  functionName: "deposit",
3680
4405
  args: [params.amount, params.on_behalf_of]
@@ -3688,7 +4413,7 @@ var init_dist3 = __esm({
3688
4413
  };
3689
4414
  }
3690
4415
  async buildBorrow(params) {
3691
- const data = encodeFunctionData14({
4416
+ const data = encodeFunctionData15({
3692
4417
  abi: EULER_VAULT_ABI,
3693
4418
  functionName: "borrow",
3694
4419
  args: [params.amount, params.on_behalf_of]
@@ -3702,7 +4427,7 @@ var init_dist3 = __esm({
3702
4427
  };
3703
4428
  }
3704
4429
  async buildRepay(params) {
3705
- const data = encodeFunctionData14({
4430
+ const data = encodeFunctionData15({
3706
4431
  abi: EULER_VAULT_ABI,
3707
4432
  functionName: "repay",
3708
4433
  args: [params.amount, params.on_behalf_of]
@@ -3716,7 +4441,7 @@ var init_dist3 = __esm({
3716
4441
  };
3717
4442
  }
3718
4443
  async buildWithdraw(params) {
3719
- const data = encodeFunctionData14({
4444
+ const data = encodeFunctionData15({
3720
4445
  abi: EULER_VAULT_ABI,
3721
4446
  functionName: "withdraw",
3722
4447
  args: [params.amount, params.to, params.to]
@@ -3765,7 +4490,7 @@ var init_dist3 = __esm({
3765
4490
  );
3766
4491
  }
3767
4492
  };
3768
- MORPHO_ABI = parseAbi16([
4493
+ MORPHO_ABI = parseAbi17([
3769
4494
  "function market(bytes32 id) external view returns (uint128 totalSupplyAssets, uint128 totalSupplyShares, uint128 totalBorrowAssets, uint128 totalBorrowShares, uint128 lastUpdate, uint128 fee)",
3770
4495
  "function idToMarketParams(bytes32 id) external view returns (address loanToken, address collateralToken, address oracle, address irm, uint256 lltv)",
3771
4496
  "function supply((address loanToken, address collateralToken, address oracle, address irm, uint256 lltv) marketParams, uint256 assets, uint256 shares, address onBehalf, bytes data) external returns (uint256 assetsSupplied, uint256 sharesSupplied)",
@@ -3773,13 +4498,13 @@ var init_dist3 = __esm({
3773
4498
  "function repay((address loanToken, address collateralToken, address oracle, address irm, uint256 lltv) marketParams, uint256 assets, uint256 shares, address onBehalf, bytes data) external returns (uint256 assetsRepaid, uint256 sharesRepaid)",
3774
4499
  "function withdraw((address loanToken, address collateralToken, address oracle, address irm, uint256 lltv) marketParams, uint256 assets, uint256 shares, address onBehalf, address receiver) external returns (uint256 assetsWithdrawn, uint256 sharesWithdrawn)"
3775
4500
  ]);
3776
- META_MORPHO_ABI = parseAbi16([
4501
+ META_MORPHO_ABI = parseAbi17([
3777
4502
  "function supplyQueueLength() external view returns (uint256)",
3778
4503
  "function supplyQueue(uint256 index) external view returns (bytes32)",
3779
4504
  "function totalAssets() external view returns (uint256)",
3780
4505
  "function totalSupply() external view returns (uint256)"
3781
4506
  ]);
3782
- IRM_ABI = parseAbi16([
4507
+ IRM_ABI = parseAbi17([
3783
4508
  "function borrowRateView((address loanToken, address collateralToken, address oracle, address irm, uint256 lltv) marketParams, (uint128 totalSupplyAssets, uint128 totalSupplyShares, uint128 totalBorrowAssets, uint128 totalBorrowShares, uint128 lastUpdate, uint128 fee) market) external view returns (uint256)"
3784
4509
  ]);
3785
4510
  SECONDS_PER_YEAR3 = 365.25 * 24 * 3600;
@@ -3802,7 +4527,7 @@ var init_dist3 = __esm({
3802
4527
  }
3803
4528
  async buildSupply(params) {
3804
4529
  const market = defaultMarketParams(params.asset);
3805
- const data = encodeFunctionData15({
4530
+ const data = encodeFunctionData16({
3806
4531
  abi: MORPHO_ABI,
3807
4532
  functionName: "supply",
3808
4533
  args: [market, params.amount, 0n, params.on_behalf_of, "0x"]
@@ -3817,7 +4542,7 @@ var init_dist3 = __esm({
3817
4542
  }
3818
4543
  async buildBorrow(params) {
3819
4544
  const market = defaultMarketParams(params.asset);
3820
- const data = encodeFunctionData15({
4545
+ const data = encodeFunctionData16({
3821
4546
  abi: MORPHO_ABI,
3822
4547
  functionName: "borrow",
3823
4548
  args: [market, params.amount, 0n, params.on_behalf_of, params.on_behalf_of]
@@ -3832,7 +4557,7 @@ var init_dist3 = __esm({
3832
4557
  }
3833
4558
  async buildRepay(params) {
3834
4559
  const market = defaultMarketParams(params.asset);
3835
- const data = encodeFunctionData15({
4560
+ const data = encodeFunctionData16({
3836
4561
  abi: MORPHO_ABI,
3837
4562
  functionName: "repay",
3838
4563
  args: [market, params.amount, 0n, params.on_behalf_of, "0x"]
@@ -3847,7 +4572,7 @@ var init_dist3 = __esm({
3847
4572
  }
3848
4573
  async buildWithdraw(params) {
3849
4574
  const market = defaultMarketParams(params.asset);
3850
- const data = encodeFunctionData15({
4575
+ const data = encodeFunctionData16({
3851
4576
  abi: MORPHO_ABI,
3852
4577
  functionName: "withdraw",
3853
4578
  args: [market, params.amount, 0n, params.to, params.to]
@@ -3865,14 +4590,12 @@ var init_dist3 = __esm({
3865
4590
  if (!this.defaultVault) {
3866
4591
  throw DefiError.contractError(`[${this.protocolName}] No MetaMorpho vault configured for rate query`);
3867
4592
  }
3868
- const client = createPublicClient13({ transport: http13(this.rpcUrl) });
3869
- const queueLen = await client.readContract({
3870
- address: this.defaultVault,
3871
- abi: META_MORPHO_ABI,
3872
- functionName: "supplyQueueLength"
3873
- }).catch((e) => {
4593
+ const [queueLenRaw] = await multicallRead(this.rpcUrl, [
4594
+ [this.defaultVault, encodeFunctionData16({ abi: META_MORPHO_ABI, functionName: "supplyQueueLength" })]
4595
+ ]).catch((e) => {
3874
4596
  throw DefiError.rpcError(`[${this.protocolName}] supplyQueueLength failed: ${e}`);
3875
4597
  });
4598
+ const queueLen = decodeU256(queueLenRaw ?? null);
3876
4599
  if (queueLen === 0n) {
3877
4600
  return {
3878
4601
  protocol: this.protocolName,
@@ -3884,45 +4607,40 @@ var init_dist3 = __esm({
3884
4607
  total_borrow: 0n
3885
4608
  };
3886
4609
  }
3887
- const marketId = await client.readContract({
3888
- address: this.defaultVault,
3889
- abi: META_MORPHO_ABI,
3890
- functionName: "supplyQueue",
3891
- args: [0n]
3892
- }).catch((e) => {
4610
+ const [marketIdRaw] = await multicallRead(this.rpcUrl, [
4611
+ [this.defaultVault, encodeFunctionData16({ abi: META_MORPHO_ABI, functionName: "supplyQueue", args: [0n] })]
4612
+ ]).catch((e) => {
3893
4613
  throw DefiError.rpcError(`[${this.protocolName}] supplyQueue(0) failed: ${e}`);
3894
4614
  });
3895
- const mkt = await client.readContract({
3896
- address: this.morpho,
3897
- abi: MORPHO_ABI,
3898
- functionName: "market",
3899
- args: [marketId]
3900
- }).catch((e) => {
3901
- throw DefiError.rpcError(`[${this.protocolName}] market() failed: ${e}`);
4615
+ if (!marketIdRaw || marketIdRaw.length < 66) {
4616
+ throw DefiError.rpcError(`[${this.protocolName}] supplyQueue(0) returned no data`);
4617
+ }
4618
+ const marketId = marketIdRaw.slice(0, 66);
4619
+ const [marketRaw, paramsRaw] = await multicallRead(this.rpcUrl, [
4620
+ [this.morpho, encodeFunctionData16({ abi: MORPHO_ABI, functionName: "market", args: [marketId] })],
4621
+ [this.morpho, encodeFunctionData16({ abi: MORPHO_ABI, functionName: "idToMarketParams", args: [marketId] })]
4622
+ ]).catch((e) => {
4623
+ throw DefiError.rpcError(`[${this.protocolName}] market/idToMarketParams failed: ${e}`);
3902
4624
  });
3903
- const [totalSupplyAssets, totalSupplyShares, totalBorrowAssets, totalBorrowShares, lastUpdate, fee] = mkt;
4625
+ const mktDecoded = decodeMarket(marketRaw ?? null);
4626
+ if (!mktDecoded) throw DefiError.rpcError(`[${this.protocolName}] market() returned no data`);
4627
+ const [totalSupplyAssets, totalSupplyShares, totalBorrowAssets, totalBorrowShares, lastUpdate, fee] = mktDecoded;
4628
+ const paramsDecoded = decodeMarketParams(paramsRaw ?? null);
4629
+ if (!paramsDecoded) throw DefiError.rpcError(`[${this.protocolName}] idToMarketParams returned no data`);
4630
+ const [loanToken, collateralToken, oracle, irm, lltv] = paramsDecoded;
3904
4631
  const supplyF = Number(totalSupplyAssets);
3905
4632
  const borrowF = Number(totalBorrowAssets);
3906
4633
  const util = supplyF > 0 ? borrowF / supplyF : 0;
3907
- const params2 = await client.readContract({
3908
- address: this.morpho,
3909
- abi: MORPHO_ABI,
3910
- functionName: "idToMarketParams",
3911
- args: [marketId]
3912
- }).catch((e) => {
3913
- throw DefiError.rpcError(`[${this.protocolName}] idToMarketParams failed: ${e}`);
3914
- });
3915
- const [loanToken, collateralToken, oracle, irm, lltv] = params2;
3916
4634
  const irmMarketParams = { loanToken, collateralToken, oracle, irm, lltv };
3917
4635
  const irmMarket = { totalSupplyAssets, totalSupplyShares, totalBorrowAssets, totalBorrowShares, lastUpdate, fee };
3918
- const borrowRatePerSec = await client.readContract({
3919
- address: irm,
3920
- abi: IRM_ABI,
3921
- functionName: "borrowRateView",
3922
- args: [irmMarketParams, irmMarket]
3923
- }).catch((e) => {
3924
- throw DefiError.rpcError(`[${this.protocolName}] borrowRateView failed: ${e}`);
3925
- });
4636
+ const borrowRatePerSec = await (async () => {
4637
+ const [borrowRateRaw] = await multicallRead(this.rpcUrl, [
4638
+ [irm, encodeFunctionData16({ abi: IRM_ABI, functionName: "borrowRateView", args: [irmMarketParams, irmMarket] })]
4639
+ ]).catch((e) => {
4640
+ throw DefiError.rpcError(`[${this.protocolName}] borrowRateView failed: ${e}`);
4641
+ });
4642
+ return decodeU256(borrowRateRaw ?? null);
4643
+ })();
3926
4644
  const ratePerSec = Number(borrowRatePerSec) / 1e18;
3927
4645
  const borrowApy = ratePerSec * SECONDS_PER_YEAR3 * 100;
3928
4646
  const feePct = Number(fee) / 1e18;
@@ -3943,18 +4661,18 @@ var init_dist3 = __esm({
3943
4661
  );
3944
4662
  }
3945
4663
  };
3946
- BORROWER_OPS_ABI = parseAbi17([
4664
+ BORROWER_OPS_ABI = parseAbi18([
3947
4665
  "function openTrove(address _owner, uint256 _ownerIndex, uint256 _collAmount, uint256 _boldAmount, uint256 _upperHint, uint256 _lowerHint, uint256 _annualInterestRate, uint256 _maxUpfrontFee, address _addManager, address _removeManager, address _receiver) external returns (uint256)",
3948
4666
  "function adjustTrove(uint256 _troveId, uint256 _collChange, bool _isCollIncrease, uint256 _debtChange, bool _isDebtIncrease, uint256 _upperHint, uint256 _lowerHint, uint256 _maxUpfrontFee) external",
3949
4667
  "function closeTrove(uint256 _troveId) external"
3950
4668
  ]);
3951
- TROVE_MANAGER_ABI = parseAbi17([
4669
+ TROVE_MANAGER_ABI = parseAbi18([
3952
4670
  "function getLatestTroveData(uint256 _troveId) external view returns (uint256 entireDebt, uint256 entireColl, uint256 redistDebtGain, uint256 redistCollGain, uint256 accruedInterest, uint256 recordedDebt, uint256 annualInterestRate, uint256 accruedBatchManagementFee, uint256 weightedRecordedDebt, uint256 lastInterestRateAdjTime)"
3953
4671
  ]);
3954
- HINT_HELPERS_ABI = parseAbi17([
4672
+ HINT_HELPERS_ABI = parseAbi18([
3955
4673
  "function getApproxHint(uint256 _collIndex, uint256 _interestRate, uint256 _numTrials, uint256 _inputRandomSeed) external view returns (uint256 hintId, uint256 diff, uint256 latestRandomSeed)"
3956
4674
  ]);
3957
- SORTED_TROVES_ABI = parseAbi17([
4675
+ SORTED_TROVES_ABI = parseAbi18([
3958
4676
  "function findInsertPosition(uint256 _annualInterestRate, uint256 _prevId, uint256 _nextId) external view returns (uint256 prevId, uint256 nextId)"
3959
4677
  ]);
3960
4678
  FelixCdpAdapter = class {
@@ -3982,7 +4700,7 @@ var init_dist3 = __esm({
3982
4700
  if (!this.hintHelpers || !this.sortedTroves || !this.rpcUrl) {
3983
4701
  return [0n, 0n];
3984
4702
  }
3985
- const client = createPublicClient14({ transport: http14(this.rpcUrl) });
4703
+ const client = createPublicClient13({ transport: http13(this.rpcUrl) });
3986
4704
  const approxResult = await client.readContract({
3987
4705
  address: this.hintHelpers,
3988
4706
  abi: HINT_HELPERS_ABI,
@@ -4005,7 +4723,7 @@ var init_dist3 = __esm({
4005
4723
  const interestRate = 50000000000000000n;
4006
4724
  const [upperHint, lowerHint] = await this.getHints(interestRate);
4007
4725
  const hasHints = upperHint !== 0n || lowerHint !== 0n;
4008
- const data = encodeFunctionData16({
4726
+ const data = encodeFunctionData17({
4009
4727
  abi: BORROWER_OPS_ABI,
4010
4728
  functionName: "openTrove",
4011
4729
  args: [
@@ -4034,7 +4752,7 @@ var init_dist3 = __esm({
4034
4752
  async buildAdjust(params) {
4035
4753
  const collChange = params.collateral_delta ?? 0n;
4036
4754
  const debtChange = params.debt_delta ?? 0n;
4037
- const data = encodeFunctionData16({
4755
+ const data = encodeFunctionData17({
4038
4756
  abi: BORROWER_OPS_ABI,
4039
4757
  functionName: "adjustTrove",
4040
4758
  args: [
@@ -4057,7 +4775,7 @@ var init_dist3 = __esm({
4057
4775
  };
4058
4776
  }
4059
4777
  async buildClose(params) {
4060
- const data = encodeFunctionData16({
4778
+ const data = encodeFunctionData17({
4061
4779
  abi: BORROWER_OPS_ABI,
4062
4780
  functionName: "closeTrove",
4063
4781
  args: [params.cdp_id]
@@ -4073,7 +4791,7 @@ var init_dist3 = __esm({
4073
4791
  async getCdpInfo(cdpId) {
4074
4792
  if (!this.rpcUrl) throw DefiError.rpcError(`[${this.protocolName}] getCdpInfo requires RPC \u2014 set HYPEREVM_RPC_URL`);
4075
4793
  if (!this.troveManager) throw DefiError.contractError(`[${this.protocolName}] trove_manager contract not configured`);
4076
- const client = createPublicClient14({ transport: http14(this.rpcUrl) });
4794
+ const client = createPublicClient13({ transport: http13(this.rpcUrl) });
4077
4795
  const data = await client.readContract({
4078
4796
  address: this.troveManager,
4079
4797
  abi: TROVE_MANAGER_ABI,
@@ -4106,7 +4824,7 @@ var init_dist3 = __esm({
4106
4824
  };
4107
4825
  }
4108
4826
  };
4109
- PRICE_FEED_ABI = parseAbi18([
4827
+ PRICE_FEED_ABI = parseAbi19([
4110
4828
  "function fetchPrice() external view returns (uint256 price, bool isNewOracleFailureDetected)",
4111
4829
  "function lastGoodPrice() external view returns (uint256)"
4112
4830
  ]);
@@ -4132,7 +4850,7 @@ var init_dist3 = __esm({
4132
4850
  if (asset !== this.asset && this.asset !== "0x0000000000000000000000000000000000000000") {
4133
4851
  throw DefiError.unsupported(`[${this.protocolName}] Felix PriceFeed only supports asset ${this.asset}`);
4134
4852
  }
4135
- const client = createPublicClient15({ transport: http15(this.rpcUrl) });
4853
+ const client = createPublicClient14({ transport: http14(this.rpcUrl) });
4136
4854
  let priceVal;
4137
4855
  try {
4138
4856
  const result = await client.readContract({
@@ -4171,7 +4889,7 @@ var init_dist3 = __esm({
4171
4889
  return results;
4172
4890
  }
4173
4891
  };
4174
- ERC4626_ABI = parseAbi19([
4892
+ ERC4626_ABI = parseAbi20([
4175
4893
  "function asset() external view returns (address)",
4176
4894
  "function totalAssets() external view returns (uint256)",
4177
4895
  "function totalSupply() external view returns (uint256)",
@@ -4195,7 +4913,7 @@ var init_dist3 = __esm({
4195
4913
  return this.protocolName;
4196
4914
  }
4197
4915
  async buildDeposit(assets, receiver) {
4198
- const data = encodeFunctionData17({
4916
+ const data = encodeFunctionData18({
4199
4917
  abi: ERC4626_ABI,
4200
4918
  functionName: "deposit",
4201
4919
  args: [assets, receiver]
@@ -4209,7 +4927,7 @@ var init_dist3 = __esm({
4209
4927
  };
4210
4928
  }
4211
4929
  async buildWithdraw(assets, receiver, owner) {
4212
- const data = encodeFunctionData17({
4930
+ const data = encodeFunctionData18({
4213
4931
  abi: ERC4626_ABI,
4214
4932
  functionName: "withdraw",
4215
4933
  args: [assets, receiver, owner]
@@ -4224,7 +4942,7 @@ var init_dist3 = __esm({
4224
4942
  }
4225
4943
  async totalAssets() {
4226
4944
  if (!this.rpcUrl) throw DefiError.rpcError("No RPC URL configured");
4227
- const client = createPublicClient16({ transport: http16(this.rpcUrl) });
4945
+ const client = createPublicClient15({ transport: http15(this.rpcUrl) });
4228
4946
  return client.readContract({
4229
4947
  address: this.vaultAddress,
4230
4948
  abi: ERC4626_ABI,
@@ -4235,7 +4953,7 @@ var init_dist3 = __esm({
4235
4953
  }
4236
4954
  async convertToShares(assets) {
4237
4955
  if (!this.rpcUrl) throw DefiError.rpcError("No RPC URL configured");
4238
- const client = createPublicClient16({ transport: http16(this.rpcUrl) });
4956
+ const client = createPublicClient15({ transport: http15(this.rpcUrl) });
4239
4957
  return client.readContract({
4240
4958
  address: this.vaultAddress,
4241
4959
  abi: ERC4626_ABI,
@@ -4247,7 +4965,7 @@ var init_dist3 = __esm({
4247
4965
  }
4248
4966
  async convertToAssets(shares) {
4249
4967
  if (!this.rpcUrl) throw DefiError.rpcError("No RPC URL configured");
4250
- const client = createPublicClient16({ transport: http16(this.rpcUrl) });
4968
+ const client = createPublicClient15({ transport: http15(this.rpcUrl) });
4251
4969
  return client.readContract({
4252
4970
  address: this.vaultAddress,
4253
4971
  abi: ERC4626_ABI,
@@ -4259,7 +4977,7 @@ var init_dist3 = __esm({
4259
4977
  }
4260
4978
  async getVaultInfo() {
4261
4979
  if (!this.rpcUrl) throw DefiError.rpcError("No RPC URL configured");
4262
- const client = createPublicClient16({ transport: http16(this.rpcUrl) });
4980
+ const client = createPublicClient15({ transport: http15(this.rpcUrl) });
4263
4981
  const [totalAssets, totalSupply, asset] = await Promise.all([
4264
4982
  client.readContract({ address: this.vaultAddress, abi: ERC4626_ABI, functionName: "totalAssets" }).catch((e) => {
4265
4983
  throw DefiError.rpcError(`[${this.protocolName}] totalAssets failed: ${e}`);
@@ -4280,7 +4998,7 @@ var init_dist3 = __esm({
4280
4998
  };
4281
4999
  }
4282
5000
  };
4283
- GENERIC_LST_ABI = parseAbi20([
5001
+ GENERIC_LST_ABI = parseAbi21([
4284
5002
  "function stake() external payable returns (uint256)",
4285
5003
  "function unstake(uint256 amount) external returns (uint256)"
4286
5004
  ]);
@@ -4297,7 +5015,7 @@ var init_dist3 = __esm({
4297
5015
  return this.protocolName;
4298
5016
  }
4299
5017
  async buildStake(params) {
4300
- const data = encodeFunctionData18({ abi: GENERIC_LST_ABI, functionName: "stake" });
5018
+ const data = encodeFunctionData19({ abi: GENERIC_LST_ABI, functionName: "stake" });
4301
5019
  return {
4302
5020
  description: `[${this.protocolName}] Stake ${params.amount} HYPE`,
4303
5021
  to: this.staking,
@@ -4307,7 +5025,7 @@ var init_dist3 = __esm({
4307
5025
  };
4308
5026
  }
4309
5027
  async buildUnstake(params) {
4310
- const data = encodeFunctionData18({
5028
+ const data = encodeFunctionData19({
4311
5029
  abi: GENERIC_LST_ABI,
4312
5030
  functionName: "unstake",
4313
5031
  args: [params.amount]
@@ -4324,11 +5042,11 @@ var init_dist3 = __esm({
4324
5042
  throw DefiError.unsupported(`[${this.protocolName}] getInfo requires RPC`);
4325
5043
  }
4326
5044
  };
4327
- STHYPE_ABI = parseAbi21([
5045
+ STHYPE_ABI = parseAbi222([
4328
5046
  "function submit(address referral) external payable returns (uint256)",
4329
5047
  "function requestWithdrawals(uint256[] amounts, address owner) external returns (uint256[] requestIds)"
4330
5048
  ]);
4331
- ERC20_ABI3 = parseAbi21([
5049
+ ERC20_ABI3 = parseAbi222([
4332
5050
  "function totalSupply() external view returns (uint256)"
4333
5051
  ]);
4334
5052
  StHypeAdapter = class {
@@ -4348,7 +5066,7 @@ var init_dist3 = __esm({
4348
5066
  return this.protocolName;
4349
5067
  }
4350
5068
  async buildStake(params) {
4351
- const data = encodeFunctionData19({
5069
+ const data = encodeFunctionData20({
4352
5070
  abi: STHYPE_ABI,
4353
5071
  functionName: "submit",
4354
5072
  args: [zeroAddress9]
@@ -4362,7 +5080,7 @@ var init_dist3 = __esm({
4362
5080
  };
4363
5081
  }
4364
5082
  async buildUnstake(params) {
4365
- const data = encodeFunctionData19({
5083
+ const data = encodeFunctionData20({
4366
5084
  abi: STHYPE_ABI,
4367
5085
  functionName: "requestWithdrawals",
4368
5086
  args: [[params.amount], params.recipient]
@@ -4377,7 +5095,7 @@ var init_dist3 = __esm({
4377
5095
  }
4378
5096
  async getInfo() {
4379
5097
  if (!this.rpcUrl) throw DefiError.rpcError("No RPC URL configured");
4380
- const client = createPublicClient17({ transport: http17(this.rpcUrl) });
5098
+ const client = createPublicClient16({ transport: http16(this.rpcUrl) });
4381
5099
  const tokenAddr = this.sthypeToken ?? this.staking;
4382
5100
  const totalSupply = await client.readContract({
4383
5101
  address: tokenAddr,
@@ -4395,12 +5113,12 @@ var init_dist3 = __esm({
4395
5113
  };
4396
5114
  }
4397
5115
  };
4398
- KINETIQ_ABI = parseAbi222([
5116
+ KINETIQ_ABI = parseAbi23([
4399
5117
  "function stake() external payable returns (uint256)",
4400
5118
  "function requestUnstake(uint256 amount) external returns (uint256)",
4401
5119
  "function totalStaked() external view returns (uint256)"
4402
5120
  ]);
4403
- ORACLE_ABI3 = parseAbi222([
5121
+ ORACLE_ABI3 = parseAbi23([
4404
5122
  "function getAssetPrice(address asset) external view returns (uint256)"
4405
5123
  ]);
4406
5124
  WHYPE = "0x5555555555555555555555555555555555555555";
@@ -4422,7 +5140,7 @@ var init_dist3 = __esm({
4422
5140
  return this.protocolName;
4423
5141
  }
4424
5142
  async buildStake(params) {
4425
- const data = encodeFunctionData20({ abi: KINETIQ_ABI, functionName: "stake" });
5143
+ const data = encodeFunctionData21({ abi: KINETIQ_ABI, functionName: "stake" });
4426
5144
  return {
4427
5145
  description: `[${this.protocolName}] Stake ${params.amount} HYPE for kHYPE`,
4428
5146
  to: this.staking,
@@ -4432,7 +5150,7 @@ var init_dist3 = __esm({
4432
5150
  };
4433
5151
  }
4434
5152
  async buildUnstake(params) {
4435
- const data = encodeFunctionData20({
5153
+ const data = encodeFunctionData21({
4436
5154
  abi: KINETIQ_ABI,
4437
5155
  functionName: "requestUnstake",
4438
5156
  args: [params.amount]
@@ -4447,7 +5165,7 @@ var init_dist3 = __esm({
4447
5165
  }
4448
5166
  async getInfo() {
4449
5167
  if (!this.rpcUrl) throw DefiError.rpcError("No RPC URL configured");
4450
- const client = createPublicClient18({ transport: http18(this.rpcUrl) });
5168
+ const client = createPublicClient17({ transport: http17(this.rpcUrl) });
4451
5169
  const totalStaked = await client.readContract({
4452
5170
  address: this.staking,
4453
5171
  abi: KINETIQ_ABI,
@@ -4518,7 +5236,7 @@ var init_dist3 = __esm({
4518
5236
  );
4519
5237
  }
4520
5238
  };
4521
- HLP_ABI = parseAbi23([
5239
+ HLP_ABI = parseAbi24([
4522
5240
  "function deposit(uint256 amount) external returns (uint256)",
4523
5241
  "function withdraw(uint256 shares) external returns (uint256)"
4524
5242
  ]);
@@ -4535,7 +5253,7 @@ var init_dist3 = __esm({
4535
5253
  return this.protocolName;
4536
5254
  }
4537
5255
  async buildOpenPosition(params) {
4538
- const data = encodeFunctionData21({
5256
+ const data = encodeFunctionData222({
4539
5257
  abi: HLP_ABI,
4540
5258
  functionName: "deposit",
4541
5259
  args: [params.collateral]
@@ -4549,7 +5267,7 @@ var init_dist3 = __esm({
4549
5267
  };
4550
5268
  }
4551
5269
  async buildClosePosition(params) {
4552
- const data = encodeFunctionData21({
5270
+ const data = encodeFunctionData222({
4553
5271
  abi: HLP_ABI,
4554
5272
  functionName: "withdraw",
4555
5273
  args: [params.size]
@@ -4584,7 +5302,7 @@ var init_dist3 = __esm({
4584
5302
  );
4585
5303
  }
4586
5304
  };
4587
- RYSK_ABI = parseAbi24([
5305
+ RYSK_ABI = parseAbi25([
4588
5306
  "function openOption(address underlying, uint256 strikePrice, uint256 expiry, bool isCall, uint256 amount) external returns (uint256 premium)",
4589
5307
  "function closeOption(address underlying, uint256 strikePrice, uint256 expiry, bool isCall, uint256 amount) external returns (uint256 payout)"
4590
5308
  ]);
@@ -4601,7 +5319,7 @@ var init_dist3 = __esm({
4601
5319
  return this.protocolName;
4602
5320
  }
4603
5321
  async buildBuy(params) {
4604
- const data = encodeFunctionData222({
5322
+ const data = encodeFunctionData23({
4605
5323
  abi: RYSK_ABI,
4606
5324
  functionName: "openOption",
4607
5325
  args: [
@@ -4621,7 +5339,7 @@ var init_dist3 = __esm({
4621
5339
  };
4622
5340
  }
4623
5341
  async buildSell(params) {
4624
- const data = encodeFunctionData222({
5342
+ const data = encodeFunctionData23({
4625
5343
  abi: RYSK_ABI,
4626
5344
  functionName: "closeOption",
4627
5345
  args: [
@@ -4662,7 +5380,7 @@ var init_dist3 = __esm({
4662
5380
  );
4663
5381
  }
4664
5382
  };
4665
- ERC721_ABI = parseAbi25([
5383
+ ERC721_ABI = parseAbi26([
4666
5384
  "function name() returns (string)",
4667
5385
  "function symbol() returns (string)",
4668
5386
  "function totalSupply() returns (uint256)",
@@ -4682,7 +5400,7 @@ var init_dist3 = __esm({
4682
5400
  }
4683
5401
  async getCollectionInfo(collection) {
4684
5402
  if (!this.rpcUrl) throw DefiError.rpcError("No RPC URL configured");
4685
- const client = createPublicClient19({ transport: http19(this.rpcUrl) });
5403
+ const client = createPublicClient18({ transport: http18(this.rpcUrl) });
4686
5404
  const [collectionName, symbol, totalSupply] = await Promise.all([
4687
5405
  client.readContract({ address: collection, abi: ERC721_ABI, functionName: "name" }).catch((e) => {
4688
5406
  throw DefiError.rpcError(`[${this.protocolName}] name failed: ${e}`);
@@ -4701,7 +5419,7 @@ var init_dist3 = __esm({
4701
5419
  }
4702
5420
  async getTokenInfo(collection, tokenId) {
4703
5421
  if (!this.rpcUrl) throw DefiError.rpcError("No RPC URL configured");
4704
- const client = createPublicClient19({ transport: http19(this.rpcUrl) });
5422
+ const client = createPublicClient18({ transport: http18(this.rpcUrl) });
4705
5423
  const [owner, tokenUri] = await Promise.all([
4706
5424
  client.readContract({ address: collection, abi: ERC721_ABI, functionName: "ownerOf", args: [tokenId] }).catch((e) => {
4707
5425
  throw DefiError.rpcError(`[${this.protocolName}] ownerOf failed: ${e}`);
@@ -4717,7 +5435,7 @@ var init_dist3 = __esm({
4717
5435
  }
4718
5436
  async getBalance(owner, collection) {
4719
5437
  if (!this.rpcUrl) throw DefiError.rpcError("No RPC URL configured");
4720
- const client = createPublicClient19({ transport: http19(this.rpcUrl) });
5438
+ const client = createPublicClient18({ transport: http18(this.rpcUrl) });
4721
5439
  return client.readContract({ address: collection, abi: ERC721_ABI, functionName: "balanceOf", args: [owner] }).catch((e) => {
4722
5440
  throw DefiError.rpcError(`[${this.protocolName}] balanceOf failed: ${e}`);
4723
5441
  });
@@ -4773,9 +5491,10 @@ import { z } from "zod";
4773
5491
 
4774
5492
  // src/executor.ts
4775
5493
  init_dist2();
4776
- import { createPublicClient as createPublicClient20, createWalletClient, http as http20, parseAbi as parseAbi26, encodeFunctionData as encodeFunctionData23 } from "viem";
5494
+ init_dist2();
5495
+ import { createPublicClient as createPublicClient19, createWalletClient, http as http19, parseAbi as parseAbi27, encodeFunctionData as encodeFunctionData24 } from "viem";
4777
5496
  import { privateKeyToAccount } from "viem/accounts";
4778
- var ERC20_ABI4 = parseAbi26([
5497
+ var ERC20_ABI4 = parseAbi27([
4779
5498
  "function allowance(address owner, address spender) external view returns (uint256)",
4780
5499
  "function approve(address spender, uint256 amount) external returns (bool)"
4781
5500
  ]);
@@ -4811,7 +5530,7 @@ var Executor = class _Executor {
4811
5530
  ` Approving ${amount} of ${token} for ${spender}...
4812
5531
  `
4813
5532
  );
4814
- const approveData = encodeFunctionData23({
5533
+ const approveData = encodeFunctionData24({
4815
5534
  abi: ERC20_ABI4,
4816
5535
  functionName: "approve",
4817
5536
  args: [spender, amount]
@@ -4854,7 +5573,7 @@ var Executor = class _Executor {
4854
5573
  /** Fetch EIP-1559 fee params from the network. Returns [maxFeePerGas, maxPriorityFeePerGas]. */
4855
5574
  async fetchEip1559Fees(rpcUrl) {
4856
5575
  try {
4857
- const client = createPublicClient20({ transport: http20(rpcUrl) });
5576
+ const client = createPublicClient19({ transport: http19(rpcUrl) });
4858
5577
  const gasPrice = await client.getGasPrice();
4859
5578
  let priorityFee = DEFAULT_PRIORITY_FEE_WEI;
4860
5579
  try {
@@ -4870,7 +5589,7 @@ var Executor = class _Executor {
4870
5589
  /** Estimate gas dynamically with buffer, falling back to a hardcoded estimate */
4871
5590
  async estimateGasWithBuffer(rpcUrl, tx, from) {
4872
5591
  try {
4873
- const client = createPublicClient20({ transport: http20(rpcUrl) });
5592
+ const client = createPublicClient19({ transport: http19(rpcUrl) });
4874
5593
  const estimated = await client.estimateGas({
4875
5594
  to: tx.to,
4876
5595
  data: tx.data,
@@ -4891,9 +5610,49 @@ var Executor = class _Executor {
4891
5610
  if (!rpcUrl) {
4892
5611
  throw DefiError.rpcError("No RPC URL \u2014 cannot simulate. Set HYPEREVM_RPC_URL.");
4893
5612
  }
4894
- const client = createPublicClient20({ transport: http20(rpcUrl) });
5613
+ const client = createPublicClient19({ transport: http19(rpcUrl) });
4895
5614
  const privateKey = process.env["DEFI_PRIVATE_KEY"];
4896
5615
  const from = privateKey ? privateKeyToAccount(privateKey).address : "0x0000000000000000000000000000000000000001";
5616
+ if (tx.approvals && tx.approvals.length > 0) {
5617
+ const pendingApprovals = [];
5618
+ for (const approval of tx.approvals) {
5619
+ try {
5620
+ const allowance = await client.readContract({
5621
+ address: approval.token,
5622
+ abi: ERC20_ABI4,
5623
+ functionName: "allowance",
5624
+ args: [from, approval.spender]
5625
+ });
5626
+ if (allowance < approval.amount) {
5627
+ pendingApprovals.push({
5628
+ token: approval.token,
5629
+ spender: approval.spender,
5630
+ needed: approval.amount.toString(),
5631
+ current: allowance.toString()
5632
+ });
5633
+ }
5634
+ } catch {
5635
+ }
5636
+ }
5637
+ if (pendingApprovals.length > 0) {
5638
+ return {
5639
+ tx_hash: void 0,
5640
+ status: TxStatus.NeedsApproval,
5641
+ gas_used: tx.gas_estimate,
5642
+ description: tx.description,
5643
+ details: {
5644
+ to: tx.to,
5645
+ from,
5646
+ data: tx.data,
5647
+ value: tx.value.toString(),
5648
+ mode: "simulated",
5649
+ result: "needs_approval",
5650
+ pending_approvals: pendingApprovals,
5651
+ hint: "Use --broadcast to auto-approve and execute"
5652
+ }
5653
+ };
5654
+ }
5655
+ }
4897
5656
  try {
4898
5657
  await client.call({ to: tx.to, data: tx.data, value: tx.value, account: from });
4899
5658
  const gasEstimate = await this.estimateGasWithBuffer(rpcUrl, tx, from);
@@ -4964,8 +5723,8 @@ var Executor = class _Executor {
4964
5723
  if (!rpcUrl) {
4965
5724
  throw DefiError.rpcError("No RPC URL configured for broadcasting");
4966
5725
  }
4967
- const publicClient = createPublicClient20({ transport: http20(rpcUrl) });
4968
- const walletClient = createWalletClient({ account, transport: http20(rpcUrl) });
5726
+ const publicClient = createPublicClient19({ transport: http19(rpcUrl) });
5727
+ const walletClient = createWalletClient({ account, transport: http19(rpcUrl) });
4969
5728
  if (tx.approvals && tx.approvals.length > 0) {
4970
5729
  for (const approval of tx.approvals) {
4971
5730
  await this.checkAndApprove(
@@ -5604,8 +6363,8 @@ server.tool(
5604
6363
  const user = address;
5605
6364
  const { ProtocolCategory: ProtocolCategory2, multicallRead: multicallRead2 } = await Promise.resolve().then(() => (init_dist2(), dist_exports));
5606
6365
  const { createLending: _createLending } = await Promise.resolve().then(() => (init_dist3(), dist_exports2));
5607
- const { encodeFunctionData: encodeFunctionData24, parseAbi: parseAbi27 } = await import("viem");
5608
- const POOL_ABI3 = parseAbi27([
6366
+ const { encodeFunctionData: encodeFunctionData25, parseAbi: parseAbi28 } = await import("viem");
6367
+ const POOL_ABI3 = parseAbi28([
5609
6368
  "function getUserAccountData(address user) external view returns (uint256 totalCollateralBase, uint256 totalDebtBase, uint256 availableBorrowsBase, uint256 currentLiquidationThreshold, uint256 ltv, uint256 healthFactor)"
5610
6369
  ]);
5611
6370
  const lendingProtos = registry.getProtocolsForChain(chainName).filter((p) => p.category === ProtocolCategory2.Lending);
@@ -5614,7 +6373,7 @@ server.tool(
5614
6373
  const poolAddr = p.contracts?.pool;
5615
6374
  if (!poolAddr) continue;
5616
6375
  try {
5617
- const callData = encodeFunctionData24({ abi: POOL_ABI3, functionName: "getUserAccountData", args: [user] });
6376
+ const callData = encodeFunctionData25({ abi: POOL_ABI3, functionName: "getUserAccountData", args: [user] });
5618
6377
  const results = await multicallRead2(rpcUrl, [[poolAddr, callData]]);
5619
6378
  const raw = results[0];
5620
6379
  if (!raw || raw.length < 2 + 6 * 64) continue;