@hypurrquant/defi-cli 0.3.0 → 0.3.2

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.
package/dist/index.js CHANGED
@@ -1019,6 +1019,24 @@ var Registry = class _Registry {
1019
1019
  if (!token) throw new Error(`Token not found: ${symbol}`);
1020
1020
  return token;
1021
1021
  }
1022
+ /**
1023
+ * Resolve a pool by name (e.g. "WHYPE/USDC") from a protocol's pool list.
1024
+ * Returns the pool info or throws if not found.
1025
+ */
1026
+ resolvePool(protocolSlug, poolName) {
1027
+ const protocol = this.getProtocol(protocolSlug);
1028
+ if (!protocol.pools || protocol.pools.length === 0) {
1029
+ throw new Error(`Protocol ${protocol.name} has no pools configured`);
1030
+ }
1031
+ const pool = protocol.pools.find(
1032
+ (p) => p.name.toLowerCase() === poolName.toLowerCase()
1033
+ );
1034
+ if (!pool) {
1035
+ const available = protocol.pools.map((p) => p.name).join(", ");
1036
+ throw new Error(`Pool '${poolName}' not found in ${protocol.name}. Available: ${available}`);
1037
+ }
1038
+ return pool;
1039
+ }
1022
1040
  };
1023
1041
 
1024
1042
  // src/executor.ts
@@ -1129,8 +1147,11 @@ var Executor = class _Executor {
1129
1147
  return buffered > MAX_GAS_LIMIT ? MAX_GAS_LIMIT : buffered;
1130
1148
  }
1131
1149
  } catch {
1150
+ if (tx.gas_estimate) {
1151
+ return _Executor.applyGasBuffer(BigInt(tx.gas_estimate));
1152
+ }
1132
1153
  }
1133
- return tx.gas_estimate ? BigInt(tx.gas_estimate) : 0n;
1154
+ return 0n;
1134
1155
  }
1135
1156
  /** Simulate a transaction via eth_call + eth_estimateGas */
1136
1157
  async simulate(tx) {
@@ -1253,6 +1274,31 @@ var Executor = class _Executor {
1253
1274
  }
1254
1275
  const publicClient = createPublicClient2({ transport: http2(rpcUrl) });
1255
1276
  const walletClient = createWalletClient({ account, transport: http2(rpcUrl) });
1277
+ if (tx.pre_txs && tx.pre_txs.length > 0) {
1278
+ for (const preTx of tx.pre_txs) {
1279
+ process.stderr.write(` Pre-tx: ${preTx.description}...
1280
+ `);
1281
+ const preGas = await this.estimateGasWithBuffer(rpcUrl, preTx, account.address);
1282
+ const preTxHash = await walletClient.sendTransaction({
1283
+ chain: null,
1284
+ to: preTx.to,
1285
+ data: preTx.data,
1286
+ value: preTx.value,
1287
+ gas: preGas > 0n ? preGas : void 0
1288
+ });
1289
+ const preTxUrl = this.explorerUrl ? `${this.explorerUrl}/tx/${preTxHash}` : void 0;
1290
+ process.stderr.write(` Pre-tx sent: ${preTxHash}
1291
+ `);
1292
+ if (preTxUrl) process.stderr.write(` Explorer: ${preTxUrl}
1293
+ `);
1294
+ const preReceipt = await publicClient.waitForTransactionReceipt({ hash: preTxHash });
1295
+ if (preReceipt.status !== "success") {
1296
+ throw new DefiError("TX_FAILED", `Pre-transaction failed: ${preTx.description}`);
1297
+ }
1298
+ process.stderr.write(` Pre-tx confirmed
1299
+ `);
1300
+ }
1301
+ }
1256
1302
  if (tx.approvals && tx.approvals.length > 0) {
1257
1303
  for (const approval of tx.approvals) {
1258
1304
  await this.checkAndApprove(
@@ -1290,20 +1336,37 @@ var Executor = class _Executor {
1290
1336
  process.stderr.write("Waiting for confirmation...\n");
1291
1337
  const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
1292
1338
  const status = receipt.status === "success" ? "confirmed" : "failed";
1339
+ let mintedTokenId;
1340
+ if (receipt.status === "success" && receipt.logs) {
1341
+ const TRANSFER_TOPIC = "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef";
1342
+ const ZERO_TOPIC = "0x0000000000000000000000000000000000000000000000000000000000000000";
1343
+ for (const log of receipt.logs) {
1344
+ if (log.topics.length >= 4 && log.topics[0] === TRANSFER_TOPIC && log.topics[1] === ZERO_TOPIC) {
1345
+ mintedTokenId = BigInt(log.topics[3]).toString();
1346
+ break;
1347
+ }
1348
+ }
1349
+ }
1350
+ const details = {
1351
+ to: tx.to,
1352
+ from: account.address,
1353
+ block_number: receipt.blockNumber?.toString(),
1354
+ gas_limit: gasLimit.toString(),
1355
+ gas_used: receipt.gasUsed?.toString(),
1356
+ explorer_url: txUrl,
1357
+ mode: "broadcast"
1358
+ };
1359
+ if (mintedTokenId) {
1360
+ details.minted_token_id = mintedTokenId;
1361
+ process.stderr.write(` Minted NFT tokenId: ${mintedTokenId}
1362
+ `);
1363
+ }
1293
1364
  return {
1294
1365
  tx_hash: txHash,
1295
1366
  status,
1296
1367
  gas_used: receipt.gasUsed ? Number(receipt.gasUsed) : void 0,
1297
1368
  description: tx.description,
1298
- details: {
1299
- to: tx.to,
1300
- from: account.address,
1301
- block_number: receipt.blockNumber?.toString(),
1302
- gas_limit: gasLimit.toString(),
1303
- gas_used: receipt.gasUsed?.toString(),
1304
- explorer_url: txUrl,
1305
- mode: "broadcast"
1306
- }
1369
+ details
1307
1370
  };
1308
1371
  }
1309
1372
  };
@@ -1847,32 +1910,45 @@ import { encodeFunctionData as encodeFunctionData32, parseAbi as parseAbi32, cre
1847
1910
  import { encodeFunctionData as encodeFunctionData42, parseAbi as parseAbi42, zeroAddress as zeroAddress2 } from "viem";
1848
1911
  import { encodeFunctionData as encodeFunctionData5, parseAbi as parseAbi5 } from "viem";
1849
1912
  import { encodeFunctionData as encodeFunctionData6, parseAbi as parseAbi6, decodeAbiParameters as decodeAbiParameters4 } from "viem";
1850
- import { encodeFunctionData as encodeFunctionData7, parseAbi as parseAbi7, zeroAddress as zeroAddress3 } from "viem";
1851
- import { createPublicClient as createPublicClient42, encodeFunctionData as encodeFunctionData8, http as http42, parseAbi as parseAbi8, zeroAddress as zeroAddress4 } from "viem";
1852
- import { encodeFunctionData as encodeFunctionData9, parseAbi as parseAbi9, createPublicClient as createPublicClient5, http as http5 } from "viem";
1913
+ import { encodeFunctionData as encodeFunctionData7, parseAbi as parseAbi7, createPublicClient as createPublicClient42, http as http42, zeroAddress as zeroAddress3 } from "viem";
1914
+ import { createPublicClient as createPublicClient5, decodeFunctionResult as decodeFunctionResult22, encodeFunctionData as encodeFunctionData8, http as http5, parseAbi as parseAbi8, zeroAddress as zeroAddress4 } from "viem";
1915
+ import { encodeFunctionData as encodeFunctionData9, parseAbi as parseAbi9, zeroAddress as zeroAddress5 } from "viem";
1916
+ import { createPublicClient as createPublicClient6, decodeFunctionResult as decodeFunctionResult3, encodeFunctionData as encodeFunctionData10, http as http6, parseAbi as parseAbi10, zeroAddress as zeroAddress6 } from "viem";
1917
+ import { encodeFunctionData as encodeFunctionData11, parseAbi as parseAbi11, createPublicClient as createPublicClient7, http as http7 } from "viem";
1853
1918
  import {
1854
- encodeFunctionData as encodeFunctionData10,
1855
- decodeFunctionResult as decodeFunctionResult22,
1856
- parseAbi as parseAbi10,
1857
- createPublicClient as createPublicClient6,
1858
- http as http6
1919
+ encodeFunctionData as encodeFunctionData12,
1920
+ decodeFunctionResult as decodeFunctionResult4,
1921
+ parseAbi as parseAbi12,
1922
+ createPublicClient as createPublicClient8,
1923
+ http as http8
1859
1924
  } from "viem";
1860
- import { createPublicClient as createPublicClient7, http as http7, parseAbi as parseAbi11, encodeFunctionData as encodeFunctionData11, decodeFunctionResult as decodeFunctionResult3, zeroAddress as zeroAddress5 } from "viem";
1861
- import { createPublicClient as createPublicClient8, http as http8, parseAbi as parseAbi12, encodeFunctionData as encodeFunctionData12, zeroAddress as zeroAddress6 } from "viem";
1862
- import { createPublicClient as createPublicClient9, http as http9, parseAbi as parseAbi13 } from "viem";
1863
- import { createPublicClient as createPublicClient10, http as http10, parseAbi as parseAbi14, encodeFunctionData as encodeFunctionData13 } from "viem";
1864
- import { createPublicClient as createPublicClient11, http as http11, parseAbi as parseAbi15, encodeFunctionData as encodeFunctionData14 } from "viem";
1865
- import { createPublicClient as createPublicClient12, http as http12, parseAbi as parseAbi16, encodeFunctionData as encodeFunctionData15 } from "viem";
1866
- import { parseAbi as parseAbi17, encodeFunctionData as encodeFunctionData16, decodeFunctionResult as decodeFunctionResult4, zeroAddress as zeroAddress7 } from "viem";
1867
- import { createPublicClient as createPublicClient13, http as http13, parseAbi as parseAbi18, encodeFunctionData as encodeFunctionData17, zeroAddress as zeroAddress8 } from "viem";
1868
- import { createPublicClient as createPublicClient14, http as http14, parseAbi as parseAbi19 } from "viem";
1869
- import { createPublicClient as createPublicClient15, http as http15, parseAbi as parseAbi20, encodeFunctionData as encodeFunctionData18 } from "viem";
1870
- import { parseAbi as parseAbi21, encodeFunctionData as encodeFunctionData19 } from "viem";
1871
- import { createPublicClient as createPublicClient16, http as http16, parseAbi as parseAbi222, encodeFunctionData as encodeFunctionData20, zeroAddress as zeroAddress9 } from "viem";
1872
- import { createPublicClient as createPublicClient17, http as http17, parseAbi as parseAbi23, encodeFunctionData as encodeFunctionData21, zeroAddress as zeroAddress10 } from "viem";
1925
+ import {
1926
+ decodeAbiParameters as decodeAbiParameters5,
1927
+ encodeFunctionData as encodeFunctionData13,
1928
+ encodeAbiParameters,
1929
+ http as http9,
1930
+ createPublicClient as createPublicClient9,
1931
+ keccak256,
1932
+ parseAbi as parseAbi13,
1933
+ decodeFunctionResult as decodeFunctionResult5,
1934
+ zeroAddress as zeroAddress7
1935
+ } from "viem";
1936
+ import { createPublicClient as createPublicClient10, http as http10, parseAbi as parseAbi14, encodeFunctionData as encodeFunctionData14, decodeFunctionResult as decodeFunctionResult6, zeroAddress as zeroAddress8 } from "viem";
1937
+ import { createPublicClient as createPublicClient11, http as http11, parseAbi as parseAbi15, encodeFunctionData as encodeFunctionData15, zeroAddress as zeroAddress9 } from "viem";
1938
+ import { createPublicClient as createPublicClient12, http as http12, parseAbi as parseAbi16 } from "viem";
1939
+ import { createPublicClient as createPublicClient13, http as http13, parseAbi as parseAbi17, encodeFunctionData as encodeFunctionData16 } from "viem";
1940
+ import { createPublicClient as createPublicClient14, http as http14, parseAbi as parseAbi18, encodeFunctionData as encodeFunctionData17 } from "viem";
1941
+ import { createPublicClient as createPublicClient15, http as http15, parseAbi as parseAbi19, encodeFunctionData as encodeFunctionData18 } from "viem";
1942
+ import { parseAbi as parseAbi20, encodeFunctionData as encodeFunctionData19, decodeFunctionResult as decodeFunctionResult7, zeroAddress as zeroAddress10 } from "viem";
1943
+ import { createPublicClient as createPublicClient16, http as http16, parseAbi as parseAbi21, encodeFunctionData as encodeFunctionData20, zeroAddress as zeroAddress11 } from "viem";
1944
+ import { createPublicClient as createPublicClient17, http as http17, parseAbi as parseAbi222 } from "viem";
1945
+ import { createPublicClient as createPublicClient18, http as http18, parseAbi as parseAbi23, encodeFunctionData as encodeFunctionData21 } from "viem";
1873
1946
  import { parseAbi as parseAbi24, encodeFunctionData as encodeFunctionData222 } from "viem";
1874
- import { parseAbi as parseAbi25, encodeFunctionData as encodeFunctionData23 } from "viem";
1875
- import { createPublicClient as createPublicClient18, http as http18, parseAbi as parseAbi26 } from "viem";
1947
+ import { createPublicClient as createPublicClient19, http as http19, parseAbi as parseAbi25, encodeFunctionData as encodeFunctionData23, zeroAddress as zeroAddress12 } from "viem";
1948
+ import { createPublicClient as createPublicClient20, http as http20, parseAbi as parseAbi26, encodeFunctionData as encodeFunctionData24, zeroAddress as zeroAddress13 } from "viem";
1949
+ import { parseAbi as parseAbi27, encodeFunctionData as encodeFunctionData25 } from "viem";
1950
+ import { parseAbi as parseAbi28, encodeFunctionData as encodeFunctionData26 } from "viem";
1951
+ import { createPublicClient as createPublicClient21, http as http21, parseAbi as parseAbi29 } from "viem";
1876
1952
  var DEFAULT_FEE = 3e3;
1877
1953
  var swapRouterAbi = parseAbi4([
1878
1954
  "struct ExactInputSingleParams { address tokenIn; address tokenOut; uint24 fee; address recipient; uint256 deadline; uint256 amountIn; uint256 amountOutMinimum; uint160 sqrtPriceLimitX96; }",
@@ -2324,6 +2400,22 @@ var UniswapV2Adapter = class {
2324
2400
  };
2325
2401
  }
2326
2402
  };
2403
+ function pctToTickDelta(pct) {
2404
+ return Math.round(Math.log(1 + pct / 100) / Math.log(1.0001));
2405
+ }
2406
+ function alignTickDown(tick, tickSpacing) {
2407
+ return Math.floor(tick / tickSpacing) * tickSpacing;
2408
+ }
2409
+ function alignTickUp(tick, tickSpacing) {
2410
+ return Math.ceil(tick / tickSpacing) * tickSpacing;
2411
+ }
2412
+ function rangeToTicks(currentTick, rangePct, tickSpacing) {
2413
+ const delta = pctToTickDelta(rangePct);
2414
+ return {
2415
+ tickLower: alignTickDown(currentTick - delta, tickSpacing),
2416
+ tickUpper: alignTickUp(currentTick + delta, tickSpacing)
2417
+ };
2418
+ }
2327
2419
  var abi2 = parseAbi32([
2328
2420
  "struct ExactInputSingleParams { address tokenIn; address tokenOut; address recipient; uint256 deadline; uint256 amountIn; uint256 amountOutMinimum; uint160 limitSqrtPrice; }",
2329
2421
  "function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut)"
@@ -2334,7 +2426,11 @@ var algebraQuoterAbi = parseAbi32([
2334
2426
  var algebraSingleQuoterAbi = parseAbi32([
2335
2427
  "function quoteExactInputSingle((address tokenIn, address tokenOut, uint256 amountIn, uint160 limitSqrtPrice) params) external returns (uint256 amountOut, uint256 amountIn, uint160 sqrtPriceX96After)"
2336
2428
  ]);
2337
- var algebraPositionManagerAbi = parseAbi32([
2429
+ var algebraIntegralPmAbi = parseAbi32([
2430
+ "struct MintParams { address token0; address token1; address deployer; int24 tickLower; int24 tickUpper; uint256 amount0Desired; uint256 amount1Desired; uint256 amount0Min; uint256 amount1Min; address recipient; uint256 deadline; }",
2431
+ "function mint(MintParams calldata params) external payable returns (uint256 tokenId, uint128 liquidity, uint256 amount0, uint256 amount1)"
2432
+ ]);
2433
+ var algebraV2PmAbi = parseAbi32([
2338
2434
  "struct MintParams { address token0; address token1; int24 tickLower; int24 tickUpper; uint256 amount0Desired; uint256 amount1Desired; uint256 amount0Min; uint256 amount1Min; address recipient; uint256 deadline; }",
2339
2435
  "function mint(MintParams calldata params) external payable returns (uint256 tokenId, uint128 liquidity, uint256 amount0, uint256 amount1)"
2340
2436
  ]);
@@ -2479,36 +2575,58 @@ var AlgebraV3Adapter = class {
2479
2575
  throw new DefiError("CONTRACT_ERROR", "Position manager address not configured");
2480
2576
  }
2481
2577
  const [token0, token1, rawAmount0, rawAmount1] = params.token_a.toLowerCase() < params.token_b.toLowerCase() ? [params.token_a, params.token_b, params.amount_a, params.amount_b] : [params.token_b, params.token_a, params.amount_b, params.amount_a];
2482
- const amount0 = rawAmount0 === 0n && rawAmount1 > 0n ? 1n : rawAmount0;
2483
- const amount1 = rawAmount1 === 0n && rawAmount0 > 0n ? 1n : rawAmount1;
2484
- const data = encodeFunctionData32({
2485
- abi: algebraPositionManagerAbi,
2578
+ let tickLower = params.tick_lower ?? -887220;
2579
+ let tickUpper = params.tick_upper ?? 887220;
2580
+ const isSingleSide = rawAmount0 === 0n || rawAmount1 === 0n;
2581
+ const needsAutoTick = params.range_pct !== void 0 || isSingleSide && !params.tick_lower && !params.tick_upper;
2582
+ if (needsAutoTick) {
2583
+ if (!this.rpcUrl) throw DefiError.rpcError("RPC URL required for auto tick detection");
2584
+ const poolAddr = params.pool;
2585
+ if (!poolAddr) throw new DefiError("CONTRACT_ERROR", "Pool address required (use --pool)");
2586
+ const client = createPublicClient32({ transport: http32(this.rpcUrl) });
2587
+ const algebraPoolAbi = parseAbi32([
2588
+ "function globalState() view returns (uint160 price, int24 tick, uint16 lastFee, uint8 pluginConfig, uint16 communityFee, bool unlocked)",
2589
+ "function tickSpacing() view returns (int24)"
2590
+ ]);
2591
+ const [globalState, spacing] = await Promise.all([
2592
+ client.readContract({ address: poolAddr, abi: algebraPoolAbi, functionName: "globalState" }),
2593
+ client.readContract({ address: poolAddr, abi: algebraPoolAbi, functionName: "tickSpacing" })
2594
+ ]);
2595
+ const currentTick = Number(globalState[1]);
2596
+ const tickSpace = Number(spacing);
2597
+ if (params.range_pct !== void 0) {
2598
+ const range = rangeToTicks(currentTick, params.range_pct, tickSpace);
2599
+ tickLower = range.tickLower;
2600
+ tickUpper = range.tickUpper;
2601
+ } else if (rawAmount0 > 0n && rawAmount1 === 0n) {
2602
+ tickLower = alignTickUp(currentTick + tickSpace, tickSpace);
2603
+ tickUpper = 887220;
2604
+ } else {
2605
+ tickLower = -887220;
2606
+ tickUpper = alignTickDown(currentTick - tickSpace, tickSpace);
2607
+ }
2608
+ }
2609
+ const amount0 = rawAmount0;
2610
+ const amount1 = rawAmount1;
2611
+ const data = this.useSingleQuoter ? encodeFunctionData32({
2612
+ abi: algebraV2PmAbi,
2486
2613
  functionName: "mint",
2487
- args: [
2488
- {
2489
- token0,
2490
- token1,
2491
- tickLower: -887220,
2492
- tickUpper: 887220,
2493
- amount0Desired: amount0,
2494
- amount1Desired: amount1,
2495
- amount0Min: 0n,
2496
- amount1Min: 0n,
2497
- recipient: params.recipient,
2498
- deadline: BigInt("18446744073709551615")
2499
- }
2500
- ]
2614
+ args: [{ token0, token1, tickLower, tickUpper, amount0Desired: amount0, amount1Desired: amount1, amount0Min: 0n, amount1Min: 0n, recipient: params.recipient, deadline: BigInt("18446744073709551615") }]
2615
+ }) : encodeFunctionData32({
2616
+ abi: algebraIntegralPmAbi,
2617
+ functionName: "mint",
2618
+ args: [{ token0, token1, deployer: zeroAddress, tickLower, tickUpper, amount0Desired: amount0, amount1Desired: amount1, amount0Min: 0n, amount1Min: 0n, recipient: params.recipient, deadline: BigInt("18446744073709551615") }]
2501
2619
  });
2620
+ const approvals = [];
2621
+ if (amount0 > 0n) approvals.push({ token: token0, spender: pm, amount: amount0 });
2622
+ if (amount1 > 0n) approvals.push({ token: token1, spender: pm, amount: amount1 });
2502
2623
  return {
2503
- description: `[${this.protocolName}] Add liquidity`,
2624
+ description: `[${this.protocolName}] Add liquidity [${tickLower}, ${tickUpper}]`,
2504
2625
  to: pm,
2505
2626
  data,
2506
2627
  value: 0n,
2507
2628
  gas_estimate: 5e5,
2508
- approvals: [
2509
- { token: token0, spender: pm, amount: amount0 },
2510
- { token: token1, spender: pm, amount: amount1 }
2511
- ]
2629
+ approvals
2512
2630
  };
2513
2631
  }
2514
2632
  async buildRemoveLiquidity(_params) {
@@ -2800,228 +2918,1105 @@ var SolidlyAdapter = class {
2800
2918
  };
2801
2919
  }
2802
2920
  };
2803
- var abi5 = parseAbi7([
2804
- "function swap(address fromToken, address toToken, uint256 fromAmount, uint256 minToAmount, address to, address rebateTo) external payable returns (uint256 realToAmount)"
2921
+ var thenaPmAbi = parseAbi7([
2922
+ "struct MintParams { address token0; address token1; int24 tickSpacing; int24 tickLower; int24 tickUpper; uint256 amount0Desired; uint256 amount1Desired; uint256 amount0Min; uint256 amount1Min; address recipient; uint256 deadline; uint160 sqrtPriceX96; }",
2923
+ "function mint(MintParams calldata params) external payable returns (uint256 tokenId, uint128 liquidity, uint256 amount0, uint256 amount1)"
2805
2924
  ]);
2806
- var WooFiAdapter = class {
2925
+ var thenaRouterAbi = parseAbi7([
2926
+ "struct ExactInputSingleParams { address tokenIn; address tokenOut; int24 tickSpacing; address recipient; uint256 deadline; uint256 amountIn; uint256 amountOutMinimum; uint160 sqrtPriceLimitX96; }",
2927
+ "function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut)"
2928
+ ]);
2929
+ var thenaPoolAbi = parseAbi7([
2930
+ "function slot0() view returns (uint160 sqrtPriceX96, int24 tick, uint16 observationIndex, uint16 observationCardinality, uint16 observationCardinalityNext, bool unlocked)",
2931
+ "function tickSpacing() view returns (int24)",
2932
+ "function token0() view returns (address)",
2933
+ "function token1() view returns (address)"
2934
+ ]);
2935
+ var thenaFactoryAbi = parseAbi7([
2936
+ "function getPool(address tokenA, address tokenB, int24 tickSpacing) view returns (address)"
2937
+ ]);
2938
+ var ThenaCLAdapter = class {
2807
2939
  protocolName;
2808
2940
  router;
2809
- constructor(entry, _rpcUrl) {
2941
+ positionManager;
2942
+ factory;
2943
+ rpcUrl;
2944
+ defaultTickSpacing;
2945
+ constructor(entry, rpcUrl) {
2810
2946
  this.protocolName = entry.name;
2811
2947
  const router = entry.contracts?.["router"];
2812
- if (!router) {
2813
- throw new DefiError("CONTRACT_ERROR", "Missing 'router' contract");
2814
- }
2948
+ if (!router) throw new DefiError("CONTRACT_ERROR", "Missing 'router' contract address");
2815
2949
  this.router = router;
2950
+ this.positionManager = entry.contracts?.["position_manager"];
2951
+ this.factory = entry.contracts?.["pool_factory"];
2952
+ this.rpcUrl = rpcUrl;
2953
+ this.defaultTickSpacing = 50;
2816
2954
  }
2817
2955
  name() {
2818
2956
  return this.protocolName;
2819
2957
  }
2820
2958
  async buildSwap(params) {
2821
- const minToAmount = 0n;
2822
2959
  const data = encodeFunctionData7({
2823
- abi: abi5,
2824
- functionName: "swap",
2825
- args: [
2826
- params.token_in,
2827
- params.token_out,
2828
- params.amount_in,
2829
- minToAmount,
2830
- params.recipient,
2831
- zeroAddress3
2832
- ]
2960
+ abi: thenaRouterAbi,
2961
+ functionName: "exactInputSingle",
2962
+ args: [{
2963
+ tokenIn: params.token_in,
2964
+ tokenOut: params.token_out,
2965
+ tickSpacing: this.defaultTickSpacing,
2966
+ recipient: params.recipient,
2967
+ deadline: BigInt(params.deadline ?? 18446744073709551615n),
2968
+ amountIn: params.amount_in,
2969
+ amountOutMinimum: 0n,
2970
+ sqrtPriceLimitX96: 0n
2971
+ }]
2833
2972
  });
2834
2973
  return {
2835
- description: `[${this.protocolName}] Swap ${params.amount_in} via WOOFi`,
2974
+ description: `[${this.protocolName}] Swap`,
2836
2975
  to: this.router,
2837
2976
  data,
2838
2977
  value: 0n,
2839
- gas_estimate: 2e5
2978
+ gas_estimate: 3e5,
2979
+ approvals: [{ token: params.token_in, spender: this.router, amount: params.amount_in }]
2840
2980
  };
2841
2981
  }
2842
2982
  async quote(_params) {
2843
- throw DefiError.unsupported(`[${this.protocolName}] quote requires RPC`);
2983
+ throw DefiError.unsupported(`[${this.protocolName}] quote not yet implemented \u2014 use swap router`);
2844
2984
  }
2845
- async buildAddLiquidity(_params) {
2846
- throw DefiError.unsupported(`[${this.protocolName}] WOOFi does not support LP positions via router`);
2985
+ async buildAddLiquidity(params) {
2986
+ const pm = this.positionManager;
2987
+ if (!pm) throw new DefiError("CONTRACT_ERROR", "Position manager not configured");
2988
+ if (!this.rpcUrl) throw DefiError.rpcError("RPC URL required");
2989
+ const [token0, token1, rawAmount0, rawAmount1] = params.token_a.toLowerCase() < params.token_b.toLowerCase() ? [params.token_a, params.token_b, params.amount_a, params.amount_b] : [params.token_b, params.token_a, params.amount_b, params.amount_a];
2990
+ const client = createPublicClient42({ transport: http42(this.rpcUrl) });
2991
+ const poolAddr = params.pool;
2992
+ let tickSpacing = this.defaultTickSpacing;
2993
+ let tickLower = params.tick_lower ?? 0;
2994
+ let tickUpper = params.tick_upper ?? 0;
2995
+ if (poolAddr || !params.tick_lower || !params.tick_upper) {
2996
+ let pool = poolAddr;
2997
+ if (!pool && this.factory) {
2998
+ pool = await client.readContract({
2999
+ address: this.factory,
3000
+ abi: thenaFactoryAbi,
3001
+ functionName: "getPool",
3002
+ args: [token0, token1, tickSpacing]
3003
+ });
3004
+ if (pool === zeroAddress3) throw new DefiError("CONTRACT_ERROR", "Pool not found");
3005
+ }
3006
+ if (pool) {
3007
+ const [slot0, ts] = await Promise.all([
3008
+ client.readContract({ address: pool, abi: thenaPoolAbi, functionName: "slot0" }),
3009
+ client.readContract({ address: pool, abi: thenaPoolAbi, functionName: "tickSpacing" })
3010
+ ]);
3011
+ const currentTick = Number(slot0[1]);
3012
+ tickSpacing = Number(ts);
3013
+ if (params.range_pct !== void 0) {
3014
+ const range = rangeToTicks(currentTick, params.range_pct, tickSpacing);
3015
+ tickLower = range.tickLower;
3016
+ tickUpper = range.tickUpper;
3017
+ } else if (!params.tick_lower && !params.tick_upper) {
3018
+ const isSingleSide = rawAmount0 === 0n || rawAmount1 === 0n;
3019
+ if (isSingleSide) {
3020
+ if (rawAmount0 > 0n) {
3021
+ tickLower = alignTickUp(currentTick + tickSpacing, tickSpacing);
3022
+ tickUpper = Math.floor(887272 / tickSpacing) * tickSpacing;
3023
+ } else {
3024
+ tickLower = Math.ceil(-887272 / tickSpacing) * tickSpacing;
3025
+ tickUpper = alignTickDown(currentTick - tickSpacing, tickSpacing);
3026
+ }
3027
+ } else {
3028
+ tickLower = Math.ceil(-887272 / tickSpacing) * tickSpacing;
3029
+ tickUpper = Math.floor(887272 / tickSpacing) * tickSpacing;
3030
+ }
3031
+ }
3032
+ }
3033
+ }
3034
+ if (params.tick_lower !== void 0) tickLower = params.tick_lower;
3035
+ if (params.tick_upper !== void 0) tickUpper = params.tick_upper;
3036
+ const data = encodeFunctionData7({
3037
+ abi: thenaPmAbi,
3038
+ functionName: "mint",
3039
+ args: [{
3040
+ token0,
3041
+ token1,
3042
+ tickSpacing,
3043
+ tickLower,
3044
+ tickUpper,
3045
+ amount0Desired: rawAmount0,
3046
+ amount1Desired: rawAmount1,
3047
+ amount0Min: 0n,
3048
+ amount1Min: 0n,
3049
+ recipient: params.recipient,
3050
+ deadline: BigInt("18446744073709551615"),
3051
+ sqrtPriceX96: 0n
3052
+ }]
3053
+ });
3054
+ const approvals = [];
3055
+ if (rawAmount0 > 0n) approvals.push({ token: token0, spender: pm, amount: rawAmount0 });
3056
+ if (rawAmount1 > 0n) approvals.push({ token: token1, spender: pm, amount: rawAmount1 });
3057
+ return {
3058
+ description: `[${this.protocolName}] Add liquidity [${tickLower}, ${tickUpper}]`,
3059
+ to: pm,
3060
+ data,
3061
+ value: 0n,
3062
+ gas_estimate: 7e5,
3063
+ approvals
3064
+ };
2847
3065
  }
2848
3066
  async buildRemoveLiquidity(_params) {
2849
- throw DefiError.unsupported(`[${this.protocolName}] WOOFi does not support LP positions via router`);
3067
+ throw DefiError.unsupported(`[${this.protocolName}] remove_liquidity requires tokenId`);
2850
3068
  }
2851
3069
  };
2852
- var gaugeAbi = parseAbi8([
2853
- "function deposit(uint256 amount) external",
2854
- "function depositFor(uint256 amount, uint256 tokenId) external",
2855
- "function withdraw(uint256 amount) external",
2856
- "function getReward(address account) external",
2857
- "function getReward(address account, address[] tokens) external",
2858
- "function earned(address account) external view returns (uint256)",
2859
- "function earned(address token, address account) external view returns (uint256)",
2860
- "function rewardRate() external view returns (uint256)",
2861
- "function totalSupply() external view returns (uint256)",
2862
- "function rewardsListLength() external view returns (uint256)",
2863
- "function isReward(address token) external view returns (bool)"
3070
+ var _addressDecodeAbi = parseAbi8(["function f() external view returns (address)"]);
3071
+ function decodeAddress(data) {
3072
+ if (!data) return null;
3073
+ try {
3074
+ return decodeFunctionResult22({ abi: _addressDecodeAbi, functionName: "f", data });
3075
+ } catch {
3076
+ return null;
3077
+ }
3078
+ }
3079
+ var _symbolDecodeAbi = parseAbi8(["function symbol() external view returns (string)"]);
3080
+ function decodeSymbol(data) {
3081
+ if (!data) return "?";
3082
+ try {
3083
+ return decodeFunctionResult22({ abi: _symbolDecodeAbi, functionName: "symbol", data });
3084
+ } catch {
3085
+ return "?";
3086
+ }
3087
+ }
3088
+ var gaugeManagerAbi = parseAbi8([
3089
+ "function gauges(address pool) view returns (address gauge)",
3090
+ "function isGauge(address gauge) view returns (bool)",
3091
+ "function isAlive(address gauge) view returns (bool)",
3092
+ "function claimRewards(address gauge, uint256[] tokenIds, uint8 redeemType) external"
3093
+ ]);
3094
+ var gaugeCLAbi = parseAbi8([
3095
+ "function deposit(uint256 tokenId) external",
3096
+ "function withdraw(uint256 tokenId, uint8 redeemType) external",
3097
+ "function earned(uint256 tokenId) view returns (uint256)",
3098
+ "function balanceOf(uint256 tokenId) view returns (uint256)",
3099
+ "function rewardToken() view returns (address)"
3100
+ ]);
3101
+ var nfpmAbi = parseAbi8([
3102
+ "function approve(address to, uint256 tokenId) external",
3103
+ "function getApproved(uint256 tokenId) view returns (address)"
2864
3104
  ]);
2865
3105
  var veAbi = parseAbi8([
2866
3106
  "function create_lock(uint256 value, uint256 lock_duration) external returns (uint256)",
2867
3107
  "function increase_amount(uint256 tokenId, uint256 value) external",
2868
3108
  "function increase_unlock_time(uint256 tokenId, uint256 lock_duration) external",
2869
- "function withdraw(uint256 tokenId) external",
2870
- "function balanceOfNFT(uint256 tokenId) external view returns (uint256)",
2871
- "function locked(uint256 tokenId) external view returns (uint256 amount, uint256 end)"
3109
+ "function withdraw(uint256 tokenId) external"
2872
3110
  ]);
2873
3111
  var voterAbi = parseAbi8([
2874
- "function vote(uint256 tokenId, address[] calldata pools, uint256[] calldata weights) external",
2875
- "function claimBribes(address[] calldata bribes, address[][] calldata tokens, uint256 tokenId) external",
2876
- "function claimFees(address[] calldata fees, address[][] calldata tokens, uint256 tokenId) external",
2877
- "function gauges(address pool) external view returns (address)"
3112
+ "function vote(uint256 tokenId, address[] pools, uint256[] weights) external",
3113
+ "function claimBribes(address[] bribes, address[][] tokens, uint256 tokenId) external",
3114
+ "function claimFees(address[] fees, address[][] tokens, uint256 tokenId) external"
2878
3115
  ]);
2879
- var SolidlyGaugeAdapter = class {
3116
+ var HybraGaugeAdapter = class {
2880
3117
  protocolName;
2881
- voter;
3118
+ gaugeManager;
2882
3119
  veToken;
3120
+ voter;
3121
+ positionManager;
3122
+ poolFactory;
2883
3123
  rpcUrl;
2884
3124
  constructor(entry, rpcUrl) {
2885
3125
  this.protocolName = entry.name;
2886
- const voter = entry.contracts?.["voter"];
2887
- if (!voter) {
2888
- throw new DefiError("CONTRACT_ERROR", "Missing 'voter' contract");
2889
- }
2890
- const veToken = entry.contracts?.["ve_token"];
2891
- if (!veToken) {
2892
- throw new DefiError("CONTRACT_ERROR", "Missing 've_token' contract");
2893
- }
2894
- this.voter = voter;
2895
- this.veToken = veToken;
3126
+ const gm = entry.contracts?.["gauge_manager"];
3127
+ if (!gm) throw new DefiError("CONTRACT_ERROR", "Missing 'gauge_manager' contract");
3128
+ this.gaugeManager = gm;
3129
+ const ve = entry.contracts?.["ve_token"];
3130
+ if (!ve) throw new DefiError("CONTRACT_ERROR", "Missing 've_token' contract");
3131
+ this.veToken = ve;
3132
+ this.voter = entry.contracts?.["voter"] ?? zeroAddress4;
3133
+ this.positionManager = entry.contracts?.["position_manager"] ?? zeroAddress4;
3134
+ this.poolFactory = entry.contracts?.["pool_factory"];
2896
3135
  this.rpcUrl = rpcUrl;
2897
3136
  }
2898
3137
  name() {
2899
3138
  return this.protocolName;
2900
3139
  }
2901
- // IGauge
2902
- async buildDeposit(gauge, amount, tokenId, lpToken) {
2903
- if (tokenId !== void 0) {
2904
- const data2 = encodeFunctionData8({
2905
- abi: gaugeAbi,
2906
- functionName: "depositFor",
2907
- args: [amount, tokenId]
3140
+ // ─── Gauge Discovery ──────────────────────────────────────
3141
+ async discoverGaugedPools() {
3142
+ if (!this.rpcUrl) throw DefiError.rpcError("RPC URL required for gauge discovery");
3143
+ if (!this.poolFactory) throw new DefiError("CONTRACT_ERROR", "Missing 'pool_factory' contract");
3144
+ const factoryAbi = parseAbi8([
3145
+ "function allPoolsLength() external view returns (uint256)",
3146
+ "function allPools(uint256) external view returns (address)"
3147
+ ]);
3148
+ const poolAbi2 = parseAbi8([
3149
+ "function token0() external view returns (address)",
3150
+ "function token1() external view returns (address)"
3151
+ ]);
3152
+ const erc20SymbolAbi = parseAbi8(["function symbol() external view returns (string)"]);
3153
+ const gaugesAbi = parseAbi8(["function gauges(address pool) view returns (address gauge)"]);
3154
+ const client = createPublicClient5({ transport: http5(this.rpcUrl) });
3155
+ let poolCount;
3156
+ try {
3157
+ poolCount = await client.readContract({
3158
+ address: this.poolFactory,
3159
+ abi: factoryAbi,
3160
+ functionName: "allPoolsLength"
2908
3161
  });
2909
- return {
2910
- description: `[${this.protocolName}] Deposit ${amount} LP to gauge (boost veNFT #${tokenId})`,
2911
- to: gauge,
2912
- data: data2,
2913
- value: 0n,
2914
- gas_estimate: 2e5,
2915
- approvals: lpToken ? [{ token: lpToken, spender: gauge, amount }] : void 0
2916
- };
3162
+ } catch {
3163
+ return [];
2917
3164
  }
2918
- const data = encodeFunctionData8({
2919
- abi: gaugeAbi,
2920
- functionName: "deposit",
2921
- args: [amount]
2922
- });
3165
+ const count = Number(poolCount);
3166
+ if (count === 0) return [];
3167
+ const poolAddressCalls = [];
3168
+ for (let i = 0; i < count; i++) {
3169
+ poolAddressCalls.push([
3170
+ this.poolFactory,
3171
+ encodeFunctionData8({ abi: factoryAbi, functionName: "allPools", args: [BigInt(i)] })
3172
+ ]);
3173
+ }
3174
+ const poolAddressResults = await multicallRead(this.rpcUrl, poolAddressCalls);
3175
+ const pools = poolAddressResults.map((r) => decodeAddress(r)).filter((a) => a !== null && a !== zeroAddress4);
3176
+ if (pools.length === 0) return [];
3177
+ const gaugeCalls = pools.map((pool) => [
3178
+ this.gaugeManager,
3179
+ encodeFunctionData8({ abi: gaugesAbi, functionName: "gauges", args: [pool] })
3180
+ ]);
3181
+ const gaugeResults = await multicallRead(this.rpcUrl, gaugeCalls);
3182
+ const gaugedPools = [];
3183
+ for (let i = 0; i < pools.length; i++) {
3184
+ const gauge = decodeAddress(gaugeResults[i] ?? null);
3185
+ if (gauge && gauge !== zeroAddress4) {
3186
+ gaugedPools.push({ pool: pools[i], gauge });
3187
+ }
3188
+ }
3189
+ if (gaugedPools.length === 0) return [];
3190
+ const tokenCalls = [];
3191
+ for (const { pool } of gaugedPools) {
3192
+ tokenCalls.push([pool, encodeFunctionData8({ abi: poolAbi2, functionName: "token0" })]);
3193
+ tokenCalls.push([pool, encodeFunctionData8({ abi: poolAbi2, functionName: "token1" })]);
3194
+ }
3195
+ const tokenResults = await multicallRead(this.rpcUrl, tokenCalls);
3196
+ const tokenAddrs = /* @__PURE__ */ new Set();
3197
+ for (let i = 0; i < gaugedPools.length; i++) {
3198
+ const t0 = decodeAddress(tokenResults[i * 2] ?? null);
3199
+ const t1 = decodeAddress(tokenResults[i * 2 + 1] ?? null);
3200
+ if (t0 && t0 !== zeroAddress4) tokenAddrs.add(t0);
3201
+ if (t1 && t1 !== zeroAddress4) tokenAddrs.add(t1);
3202
+ }
3203
+ const uniqueTokens = Array.from(tokenAddrs);
3204
+ const symbolCalls = uniqueTokens.map((t) => [
3205
+ t,
3206
+ encodeFunctionData8({ abi: erc20SymbolAbi, functionName: "symbol" })
3207
+ ]);
3208
+ const symbolResults = await multicallRead(this.rpcUrl, symbolCalls);
3209
+ const symbolMap = /* @__PURE__ */ new Map();
3210
+ for (let i = 0; i < uniqueTokens.length; i++) {
3211
+ symbolMap.set(uniqueTokens[i], decodeSymbol(symbolResults[i] ?? null));
3212
+ }
3213
+ const out = [];
3214
+ for (let i = 0; i < gaugedPools.length; i++) {
3215
+ const { pool, gauge } = gaugedPools[i];
3216
+ const t0 = decodeAddress(tokenResults[i * 2] ?? null);
3217
+ const t1 = decodeAddress(tokenResults[i * 2 + 1] ?? null);
3218
+ out.push({
3219
+ pool,
3220
+ gauge,
3221
+ token0: t0 ? symbolMap.get(t0) ?? t0.slice(0, 10) : "?",
3222
+ token1: t1 ? symbolMap.get(t1) ?? t1.slice(0, 10) : "?",
3223
+ type: "CL"
3224
+ });
3225
+ }
3226
+ return out;
3227
+ }
3228
+ // ─── Gauge Lookup ──────────────────────────────────────────
3229
+ async resolveGauge(pool) {
3230
+ if (!this.rpcUrl) throw DefiError.rpcError("RPC required");
3231
+ const client = createPublicClient5({ transport: http5(this.rpcUrl) });
3232
+ const gauge = await client.readContract({
3233
+ address: this.gaugeManager,
3234
+ abi: gaugeManagerAbi,
3235
+ functionName: "gauges",
3236
+ args: [pool]
3237
+ });
3238
+ if (gauge === zeroAddress4) throw new DefiError("CONTRACT_ERROR", `No gauge for pool ${pool}`);
3239
+ return gauge;
3240
+ }
3241
+ // ─── CL Gauge: NFT Deposit/Withdraw ──────────────────────────
3242
+ async buildDeposit(gauge, _amount, tokenId) {
3243
+ if (tokenId === void 0) throw new DefiError("CONTRACT_ERROR", "tokenId required for CL gauge deposit");
3244
+ const approveTx = {
3245
+ description: `[${this.protocolName}] Approve NFT #${tokenId} to gauge`,
3246
+ to: this.positionManager,
3247
+ data: encodeFunctionData8({ abi: nfpmAbi, functionName: "approve", args: [gauge, tokenId] }),
3248
+ value: 0n,
3249
+ gas_estimate: 8e4
3250
+ };
2923
3251
  return {
2924
- description: `[${this.protocolName}] Deposit ${amount} LP to gauge`,
3252
+ description: `[${this.protocolName}] Deposit NFT #${tokenId} to gauge`,
2925
3253
  to: gauge,
2926
- data,
3254
+ data: encodeFunctionData8({ abi: gaugeCLAbi, functionName: "deposit", args: [tokenId] }),
2927
3255
  value: 0n,
2928
- gas_estimate: 2e5,
2929
- approvals: lpToken ? [{ token: lpToken, spender: gauge, amount }] : void 0
3256
+ gas_estimate: 5e5,
3257
+ pre_txs: [approveTx]
2930
3258
  };
2931
3259
  }
2932
- async buildWithdraw(gauge, amount) {
2933
- const data = encodeFunctionData8({
2934
- abi: gaugeAbi,
2935
- functionName: "withdraw",
2936
- args: [amount]
2937
- });
3260
+ async buildWithdraw(gauge, _amount, tokenId) {
3261
+ if (tokenId === void 0) throw new DefiError("CONTRACT_ERROR", "tokenId required for CL gauge withdraw");
2938
3262
  return {
2939
- description: `[${this.protocolName}] Withdraw ${amount} LP from gauge`,
3263
+ description: `[${this.protocolName}] Withdraw NFT #${tokenId} from gauge`,
2940
3264
  to: gauge,
2941
- data,
3265
+ data: encodeFunctionData8({ abi: gaugeCLAbi, functionName: "withdraw", args: [tokenId, 1] }),
2942
3266
  value: 0n,
2943
- gas_estimate: 2e5
3267
+ gas_estimate: 1e6
2944
3268
  };
2945
3269
  }
2946
- async buildClaimRewards(gauge, account) {
2947
- if (account && this.rpcUrl) {
2948
- try {
2949
- const client = createPublicClient42({ transport: http42(this.rpcUrl) });
2950
- const listLen = await client.readContract({
2951
- address: gauge,
2952
- abi: gaugeAbi,
2953
- functionName: "rewardsListLength"
2954
- });
2955
- if (listLen > 0n) {
2956
- const data2 = encodeFunctionData8({
2957
- abi: gaugeAbi,
2958
- functionName: "getReward",
2959
- args: [account, []]
2960
- });
2961
- return {
2962
- description: `[${this.protocolName}] Claim gauge rewards`,
2963
- to: gauge,
2964
- data: data2,
2965
- value: 0n,
2966
- gas_estimate: 3e5
2967
- };
2968
- }
2969
- } catch {
2970
- }
2971
- }
2972
- const data = encodeFunctionData8({
2973
- abi: gaugeAbi,
2974
- functionName: "getReward",
2975
- args: [account ?? zeroAddress4]
2976
- });
3270
+ // ─── Claim: via GaugeManager ──────────────────────────────────
3271
+ async buildClaimRewards(gauge, _account) {
3272
+ throw DefiError.unsupported(`[${this.protocolName}] Use buildClaimRewardsByTokenId for CL gauges`);
3273
+ }
3274
+ async buildClaimRewardsByTokenId(gauge, tokenId) {
2977
3275
  return {
2978
- description: `[${this.protocolName}] Claim gauge rewards`,
2979
- to: gauge,
2980
- data,
3276
+ description: `[${this.protocolName}] Claim rewards for NFT #${tokenId}`,
3277
+ to: this.gaugeManager,
3278
+ data: encodeFunctionData8({
3279
+ abi: gaugeManagerAbi,
3280
+ functionName: "claimRewards",
3281
+ args: [gauge, [tokenId], 1]
3282
+ // redeemType=1
3283
+ }),
2981
3284
  value: 0n,
2982
- gas_estimate: 2e5
3285
+ gas_estimate: 1e6
2983
3286
  };
2984
3287
  }
2985
- async getPendingRewards(_gauge, _user) {
2986
- throw DefiError.unsupported(`[${this.protocolName}] get_pending_rewards requires RPC`);
3288
+ // ─── Pending Rewards ──────────────────────────────────────────
3289
+ async getPendingRewards(gauge, _user) {
3290
+ throw DefiError.unsupported(`[${this.protocolName}] Use getPendingRewardsByTokenId for CL gauges`);
2987
3291
  }
2988
- // IVoteEscrow
2989
- async buildCreateLock(amount, lockDuration) {
2990
- const data = encodeFunctionData8({
2991
- abi: veAbi,
2992
- functionName: "create_lock",
2993
- args: [amount, BigInt(lockDuration)]
3292
+ async getPendingRewardsByTokenId(gauge, tokenId) {
3293
+ if (!this.rpcUrl) throw DefiError.rpcError("RPC required");
3294
+ const client = createPublicClient5({ transport: http5(this.rpcUrl) });
3295
+ return await client.readContract({
3296
+ address: gauge,
3297
+ abi: gaugeCLAbi,
3298
+ functionName: "earned",
3299
+ args: [tokenId]
2994
3300
  });
3301
+ }
3302
+ // ─── VoteEscrow ──────────────────────────────────────────────
3303
+ async buildCreateLock(amount, lockDuration) {
2995
3304
  return {
2996
- description: `[${this.protocolName}] Create veNFT lock: ${amount} tokens for ${lockDuration}s`,
3305
+ description: `[${this.protocolName}] Create veNFT lock`,
2997
3306
  to: this.veToken,
2998
- data,
3307
+ data: encodeFunctionData8({ abi: veAbi, functionName: "create_lock", args: [amount, BigInt(lockDuration)] }),
2999
3308
  value: 0n,
3000
3309
  gas_estimate: 3e5
3001
3310
  };
3002
3311
  }
3003
3312
  async buildIncreaseAmount(tokenId, amount) {
3004
- const data = encodeFunctionData8({
3005
- abi: veAbi,
3006
- functionName: "increase_amount",
3007
- args: [tokenId, amount]
3008
- });
3009
3313
  return {
3010
- description: `[${this.protocolName}] Increase veNFT #${tokenId} by ${amount}`,
3314
+ description: `[${this.protocolName}] Increase veNFT #${tokenId}`,
3011
3315
  to: this.veToken,
3012
- data,
3316
+ data: encodeFunctionData8({ abi: veAbi, functionName: "increase_amount", args: [tokenId, amount] }),
3013
3317
  value: 0n,
3014
3318
  gas_estimate: 2e5
3015
3319
  };
3016
3320
  }
3017
3321
  async buildIncreaseUnlockTime(tokenId, lockDuration) {
3018
- const data = encodeFunctionData8({
3019
- abi: veAbi,
3020
- functionName: "increase_unlock_time",
3021
- args: [tokenId, BigInt(lockDuration)]
3022
- });
3023
3322
  return {
3024
- description: `[${this.protocolName}] Extend veNFT #${tokenId} lock by ${lockDuration}s`,
3323
+ description: `[${this.protocolName}] Extend veNFT #${tokenId} lock`,
3324
+ to: this.veToken,
3325
+ data: encodeFunctionData8({ abi: veAbi, functionName: "increase_unlock_time", args: [tokenId, BigInt(lockDuration)] }),
3326
+ value: 0n,
3327
+ gas_estimate: 2e5
3328
+ };
3329
+ }
3330
+ async buildWithdrawExpired(tokenId) {
3331
+ return {
3332
+ description: `[${this.protocolName}] Withdraw expired veNFT #${tokenId}`,
3333
+ to: this.veToken,
3334
+ data: encodeFunctionData8({ abi: veAbi, functionName: "withdraw", args: [tokenId] }),
3335
+ value: 0n,
3336
+ gas_estimate: 2e5
3337
+ };
3338
+ }
3339
+ // ─── Voter ──────────────────────────────────────────────────
3340
+ async buildVote(tokenId, pools, weights) {
3341
+ return {
3342
+ description: `[${this.protocolName}] Vote with veNFT #${tokenId}`,
3343
+ to: this.voter,
3344
+ data: encodeFunctionData8({ abi: voterAbi, functionName: "vote", args: [tokenId, pools, weights] }),
3345
+ value: 0n,
3346
+ gas_estimate: 5e5
3347
+ };
3348
+ }
3349
+ async buildClaimBribes(bribes, tokenId) {
3350
+ const tokensPerBribe = bribes.map(() => []);
3351
+ return {
3352
+ description: `[${this.protocolName}] Claim bribes for veNFT #${tokenId}`,
3353
+ to: this.voter,
3354
+ data: encodeFunctionData8({ abi: voterAbi, functionName: "claimBribes", args: [bribes, tokensPerBribe, tokenId] }),
3355
+ value: 0n,
3356
+ gas_estimate: 3e5
3357
+ };
3358
+ }
3359
+ async buildClaimFees(fees, tokenId) {
3360
+ const tokensPerFee = fees.map(() => []);
3361
+ return {
3362
+ description: `[${this.protocolName}] Claim fees for veNFT #${tokenId}`,
3363
+ to: this.voter,
3364
+ data: encodeFunctionData8({ abi: voterAbi, functionName: "claimFees", args: [fees, tokensPerFee, tokenId] }),
3365
+ value: 0n,
3366
+ gas_estimate: 3e5
3367
+ };
3368
+ }
3369
+ };
3370
+ var abi5 = parseAbi9([
3371
+ "function swap(address fromToken, address toToken, uint256 fromAmount, uint256 minToAmount, address to, address rebateTo) external payable returns (uint256 realToAmount)"
3372
+ ]);
3373
+ var WooFiAdapter = class {
3374
+ protocolName;
3375
+ router;
3376
+ constructor(entry, _rpcUrl) {
3377
+ this.protocolName = entry.name;
3378
+ const router = entry.contracts?.["router"];
3379
+ if (!router) {
3380
+ throw new DefiError("CONTRACT_ERROR", "Missing 'router' contract");
3381
+ }
3382
+ this.router = router;
3383
+ }
3384
+ name() {
3385
+ return this.protocolName;
3386
+ }
3387
+ async buildSwap(params) {
3388
+ const minToAmount = 0n;
3389
+ const data = encodeFunctionData9({
3390
+ abi: abi5,
3391
+ functionName: "swap",
3392
+ args: [
3393
+ params.token_in,
3394
+ params.token_out,
3395
+ params.amount_in,
3396
+ minToAmount,
3397
+ params.recipient,
3398
+ zeroAddress5
3399
+ ]
3400
+ });
3401
+ return {
3402
+ description: `[${this.protocolName}] Swap ${params.amount_in} via WOOFi`,
3403
+ to: this.router,
3404
+ data,
3405
+ value: 0n,
3406
+ gas_estimate: 2e5
3407
+ };
3408
+ }
3409
+ async quote(_params) {
3410
+ throw DefiError.unsupported(`[${this.protocolName}] quote requires RPC`);
3411
+ }
3412
+ async buildAddLiquidity(_params) {
3413
+ throw DefiError.unsupported(`[${this.protocolName}] WOOFi does not support LP positions via router`);
3414
+ }
3415
+ async buildRemoveLiquidity(_params) {
3416
+ throw DefiError.unsupported(`[${this.protocolName}] WOOFi does not support LP positions via router`);
3417
+ }
3418
+ };
3419
+ var gaugeAbi = parseAbi10([
3420
+ "function deposit(uint256 amount) external",
3421
+ "function depositFor(uint256 amount, uint256 tokenId) external",
3422
+ "function withdraw(uint256 amount) external",
3423
+ "function getReward() external",
3424
+ "function getReward(address account) external",
3425
+ "function getReward(address account, address[] tokens) external",
3426
+ "function getReward(uint256 tokenId) external",
3427
+ "function earned(address account) external view returns (uint256)",
3428
+ "function earned(address token, address account) external view returns (uint256)",
3429
+ "function earned(uint256 tokenId) external view returns (uint256)",
3430
+ "function rewardRate() external view returns (uint256)",
3431
+ "function rewardToken() external view returns (address)",
3432
+ "function totalSupply() external view returns (uint256)",
3433
+ "function rewardsListLength() external view returns (uint256)",
3434
+ "function rewardData(address token) external view returns (uint256 periodFinish, uint256 rewardRate, uint256 lastUpdateTime, uint256 rewardPerTokenStored)",
3435
+ "function nonfungiblePositionManager() external view returns (address)"
3436
+ ]);
3437
+ var veAbi2 = parseAbi10([
3438
+ "function create_lock(uint256 value, uint256 lock_duration) external returns (uint256)",
3439
+ "function increase_amount(uint256 tokenId, uint256 value) external",
3440
+ "function increase_unlock_time(uint256 tokenId, uint256 lock_duration) external",
3441
+ "function withdraw(uint256 tokenId) external",
3442
+ "function balanceOfNFT(uint256 tokenId) external view returns (uint256)",
3443
+ "function locked(uint256 tokenId) external view returns (uint256 amount, uint256 end)"
3444
+ ]);
3445
+ var voterAbi2 = parseAbi10([
3446
+ "function vote(uint256 tokenId, address[] calldata pools, uint256[] calldata weights) external",
3447
+ "function claimBribes(address[] calldata bribes, address[][] calldata tokens, uint256 tokenId) external",
3448
+ "function claimFees(address[] calldata fees, address[][] calldata tokens, uint256 tokenId) external",
3449
+ "function gauges(address pool) external view returns (address)",
3450
+ "function gaugeForPool(address pool) external view returns (address)",
3451
+ "function poolToGauge(address pool) external view returns (address)"
3452
+ ]);
3453
+ var _addressDecodeAbi2 = parseAbi10(["function f() external view returns (address)"]);
3454
+ function decodeAddress2(data) {
3455
+ if (!data) return null;
3456
+ try {
3457
+ return decodeFunctionResult3({ abi: _addressDecodeAbi2, functionName: "f", data });
3458
+ } catch {
3459
+ return null;
3460
+ }
3461
+ }
3462
+ var _symbolDecodeAbi2 = parseAbi10(["function symbol() external view returns (string)"]);
3463
+ function decodeSymbol2(data) {
3464
+ if (!data) return "?";
3465
+ try {
3466
+ return decodeFunctionResult3({ abi: _symbolDecodeAbi2, functionName: "symbol", data });
3467
+ } catch {
3468
+ return "?";
3469
+ }
3470
+ }
3471
+ var _boolDecodeAbi = parseAbi10(["function f() external view returns (bool)"]);
3472
+ function decodeBoolean(data) {
3473
+ try {
3474
+ return decodeFunctionResult3({ abi: _boolDecodeAbi, functionName: "f", data });
3475
+ } catch {
3476
+ return false;
3477
+ }
3478
+ }
3479
+ var HYPEREVM_TOKENS = {
3480
+ WHYPE: "0x5555555555555555555555555555555555555555",
3481
+ USDC: "0xb88339CB7199b77E23DB6E890353E22632Ba630f",
3482
+ USDT0: "0xB8CE59FC3717ada4C02eaDF9682A9e934F625ebb",
3483
+ UETH: "0xBe6727B535545C67d5cAa73dEa54865B92CF7907",
3484
+ UBTC: "0x9FDBdA0A5e284c32744D2f17Ee5c74B284993463",
3485
+ USDH: "0x111111a1a0667d36bD57c0A9f569b98057111111",
3486
+ USDe: "0x5d3a1Ff2b6BAb83b63cd9AD0787074081a52ef34",
3487
+ sUSDe: "0x211Cc4DD073734dA055fbF44a2b4667d5E5fE5d2",
3488
+ XAUt0: "0xf4D9235269a96aaDaFc9aDAe454a0618eBE37949",
3489
+ kHYPE: "0xfD739d4e423301CE9385c1fb8850539D657C296D",
3490
+ RAM: "0x555570a286F15EbDFE42B66eDE2f724Aa1AB5555",
3491
+ hyperRAM: "0xAAAE8378809bb8815c08D3C59Eb0c7D1529aD769"
3492
+ };
3493
+ var CL_TICK_SPACINGS = [1, 5, 10, 50, 100, 200];
3494
+ var SolidlyGaugeAdapter = class {
3495
+ protocolName;
3496
+ voter;
3497
+ veToken;
3498
+ rpcUrl;
3499
+ clFactory;
3500
+ v2Factory;
3501
+ constructor(entry, rpcUrl) {
3502
+ this.protocolName = entry.name;
3503
+ const voter = entry.contracts?.["voter"];
3504
+ if (!voter) {
3505
+ throw new DefiError("CONTRACT_ERROR", "Missing 'voter' contract");
3506
+ }
3507
+ const veToken = entry.contracts?.["ve_token"];
3508
+ if (!veToken) {
3509
+ throw new DefiError("CONTRACT_ERROR", "Missing 've_token' contract");
3510
+ }
3511
+ this.voter = voter;
3512
+ this.veToken = veToken;
3513
+ this.rpcUrl = rpcUrl;
3514
+ this.clFactory = entry.contracts?.["cl_factory"] ?? entry.contracts?.["factory"];
3515
+ this.v2Factory = entry.contracts?.["pair_factory"] ?? entry.contracts?.["factory"];
3516
+ }
3517
+ name() {
3518
+ return this.protocolName;
3519
+ }
3520
+ /** Scan V2 and CL factories for pools that have active emission gauges. */
3521
+ async discoverGaugedPools() {
3522
+ if (!this.rpcUrl) throw DefiError.rpcError("RPC URL required for gauge discovery");
3523
+ const results = [];
3524
+ await Promise.all([
3525
+ this._discoverV2GaugedPools(results),
3526
+ this._discoverCLGaugedPools(results)
3527
+ ]);
3528
+ return results;
3529
+ }
3530
+ async _discoverV2GaugedPools(out) {
3531
+ if (!this.rpcUrl || !this.v2Factory) return;
3532
+ const v2FactoryAbi = parseAbi10([
3533
+ "function allPairsLength() external view returns (uint256)",
3534
+ "function allPairs(uint256) external view returns (address)"
3535
+ ]);
3536
+ const pairAbi = parseAbi10([
3537
+ "function token0() external view returns (address)",
3538
+ "function token1() external view returns (address)",
3539
+ "function stable() external view returns (bool)"
3540
+ ]);
3541
+ const erc20SymbolAbi = parseAbi10(["function symbol() external view returns (string)"]);
3542
+ const client = createPublicClient6({ transport: http6(this.rpcUrl) });
3543
+ let pairCount;
3544
+ try {
3545
+ pairCount = await client.readContract({
3546
+ address: this.v2Factory,
3547
+ abi: v2FactoryAbi,
3548
+ functionName: "allPairsLength"
3549
+ });
3550
+ } catch {
3551
+ return;
3552
+ }
3553
+ const count = Number(pairCount);
3554
+ if (count === 0) return;
3555
+ const pairAddressCalls = [];
3556
+ for (let i = 0; i < count; i++) {
3557
+ pairAddressCalls.push([
3558
+ this.v2Factory,
3559
+ encodeFunctionData10({ abi: v2FactoryAbi, functionName: "allPairs", args: [BigInt(i)] })
3560
+ ]);
3561
+ }
3562
+ const pairAddressResults = await multicallRead(this.rpcUrl, pairAddressCalls);
3563
+ const pairs = pairAddressResults.map((r) => decodeAddress2(r)).filter((a) => a !== null && a !== zeroAddress6);
3564
+ if (pairs.length === 0) return;
3565
+ const gaugeForPoolAbi = parseAbi10(["function gaugeForPool(address) external view returns (address)"]);
3566
+ const poolToGaugeAbi = parseAbi10(["function poolToGauge(address) external view returns (address)"]);
3567
+ const gaugeCalls = pairs.map((pair) => [
3568
+ this.voter,
3569
+ encodeFunctionData10({ abi: gaugeForPoolAbi, functionName: "gaugeForPool", args: [pair] })
3570
+ ]);
3571
+ let gaugeResults = await multicallRead(this.rpcUrl, gaugeCalls);
3572
+ const allNullV2 = gaugeResults.every((r) => !r || decodeAddress2(r) === zeroAddress6 || decodeAddress2(r) === null);
3573
+ if (allNullV2) {
3574
+ const fallbackCalls = pairs.map((pair) => [
3575
+ this.voter,
3576
+ encodeFunctionData10({ abi: poolToGaugeAbi, functionName: "poolToGauge", args: [pair] })
3577
+ ]);
3578
+ gaugeResults = await multicallRead(this.rpcUrl, fallbackCalls);
3579
+ }
3580
+ const gaugedPairs = [];
3581
+ for (let i = 0; i < pairs.length; i++) {
3582
+ const gauge = decodeAddress2(gaugeResults[i] ?? null);
3583
+ if (gauge && gauge !== zeroAddress6) {
3584
+ gaugedPairs.push({ pair: pairs[i], gauge });
3585
+ }
3586
+ }
3587
+ if (gaugedPairs.length === 0) return;
3588
+ const metaCalls = [];
3589
+ for (const { pair } of gaugedPairs) {
3590
+ metaCalls.push([pair, encodeFunctionData10({ abi: pairAbi, functionName: "token0" })]);
3591
+ metaCalls.push([pair, encodeFunctionData10({ abi: pairAbi, functionName: "token1" })]);
3592
+ metaCalls.push([pair, encodeFunctionData10({ abi: pairAbi, functionName: "stable" })]);
3593
+ }
3594
+ const metaResults = await multicallRead(this.rpcUrl, metaCalls);
3595
+ const tokenAddrs = /* @__PURE__ */ new Set();
3596
+ for (let i = 0; i < gaugedPairs.length; i++) {
3597
+ const t0 = decodeAddress2(metaResults[i * 3] ?? null);
3598
+ const t1 = decodeAddress2(metaResults[i * 3 + 1] ?? null);
3599
+ if (t0 && t0 !== zeroAddress6) tokenAddrs.add(t0);
3600
+ if (t1 && t1 !== zeroAddress6) tokenAddrs.add(t1);
3601
+ }
3602
+ const uniqueTokens = Array.from(tokenAddrs);
3603
+ const symbolCalls = uniqueTokens.map((t) => [
3604
+ t,
3605
+ encodeFunctionData10({ abi: erc20SymbolAbi, functionName: "symbol" })
3606
+ ]);
3607
+ const symbolResults = await multicallRead(this.rpcUrl, symbolCalls);
3608
+ const symbolMap = /* @__PURE__ */ new Map();
3609
+ for (let i = 0; i < uniqueTokens.length; i++) {
3610
+ symbolMap.set(uniqueTokens[i], decodeSymbol2(symbolResults[i] ?? null));
3611
+ }
3612
+ for (let i = 0; i < gaugedPairs.length; i++) {
3613
+ const { pair, gauge } = gaugedPairs[i];
3614
+ const t0 = decodeAddress2(metaResults[i * 3] ?? null);
3615
+ const t1 = decodeAddress2(metaResults[i * 3 + 1] ?? null);
3616
+ const stableRaw = metaResults[i * 3 + 2];
3617
+ const stable = stableRaw ? decodeBoolean(stableRaw) : false;
3618
+ out.push({
3619
+ pool: pair,
3620
+ gauge,
3621
+ token0: t0 ? symbolMap.get(t0) ?? t0.slice(0, 10) : "?",
3622
+ token1: t1 ? symbolMap.get(t1) ?? t1.slice(0, 10) : "?",
3623
+ type: "V2",
3624
+ stable
3625
+ });
3626
+ }
3627
+ }
3628
+ async _discoverCLGaugedPools(out) {
3629
+ if (!this.rpcUrl || !this.clFactory) return;
3630
+ const clFactoryAbi = parseAbi10([
3631
+ "function getPool(address tokenA, address tokenB, int24 tickSpacing) external view returns (address pool)"
3632
+ ]);
3633
+ const algebraFactoryAbi2 = parseAbi10([
3634
+ "function poolByPair(address tokenA, address tokenB) external view returns (address pool)"
3635
+ ]);
3636
+ const poolAbi2 = parseAbi10([
3637
+ "function token0() external view returns (address)",
3638
+ "function token1() external view returns (address)"
3639
+ ]);
3640
+ const erc20SymbolAbi = parseAbi10(["function symbol() external view returns (string)"]);
3641
+ const gaugeForPoolAbi = parseAbi10(["function gaugeForPool(address) external view returns (address)"]);
3642
+ const poolToGaugeAbi = parseAbi10(["function poolToGauge(address) external view returns (address)"]);
3643
+ const tokenEntries = Object.entries(HYPEREVM_TOKENS);
3644
+ const tokenAddresses = tokenEntries.map(([, addr]) => addr);
3645
+ const pairs = [];
3646
+ for (let i = 0; i < tokenAddresses.length; i++) {
3647
+ for (let j = i + 1; j < tokenAddresses.length; j++) {
3648
+ pairs.push([tokenAddresses[i], tokenAddresses[j]]);
3649
+ }
3650
+ }
3651
+ const isAlgebra = await (async () => {
3652
+ try {
3653
+ const [result] = await multicallRead(this.rpcUrl, [[
3654
+ this.clFactory,
3655
+ encodeFunctionData10({ abi: algebraFactoryAbi2, functionName: "poolByPair", args: [tokenAddresses[0], tokenAddresses[1]] })
3656
+ ]]);
3657
+ return result !== null && result.length >= 66;
3658
+ } catch {
3659
+ return false;
3660
+ }
3661
+ })();
3662
+ const getPoolCalls = [];
3663
+ const callMeta = [];
3664
+ if (isAlgebra) {
3665
+ for (let p = 0; p < pairs.length; p++) {
3666
+ const [tokenA, tokenB] = pairs[p];
3667
+ getPoolCalls.push([
3668
+ this.clFactory,
3669
+ encodeFunctionData10({ abi: algebraFactoryAbi2, functionName: "poolByPair", args: [tokenA, tokenB] })
3670
+ ]);
3671
+ callMeta.push({ pairIdx: p, tickSpacing: 0 });
3672
+ }
3673
+ } else {
3674
+ for (let p = 0; p < pairs.length; p++) {
3675
+ const [tokenA, tokenB] = pairs[p];
3676
+ for (const ts of CL_TICK_SPACINGS) {
3677
+ getPoolCalls.push([
3678
+ this.clFactory,
3679
+ encodeFunctionData10({ abi: clFactoryAbi, functionName: "getPool", args: [tokenA, tokenB, ts] })
3680
+ ]);
3681
+ callMeta.push({ pairIdx: p, tickSpacing: ts });
3682
+ }
3683
+ }
3684
+ }
3685
+ const getPoolResults = await multicallRead(this.rpcUrl, getPoolCalls);
3686
+ const candidatePools = [];
3687
+ for (let i = 0; i < getPoolCalls.length; i++) {
3688
+ const pool = decodeAddress2(getPoolResults[i] ?? null);
3689
+ if (pool && pool !== zeroAddress6) {
3690
+ const { pairIdx, tickSpacing } = callMeta[i];
3691
+ const [tokenA, tokenB] = pairs[pairIdx];
3692
+ candidatePools.push({ pool, tokenA, tokenB, tickSpacing });
3693
+ }
3694
+ }
3695
+ if (candidatePools.length === 0) return;
3696
+ const gaugeCalls = candidatePools.map(({ pool }) => [
3697
+ this.voter,
3698
+ encodeFunctionData10({ abi: gaugeForPoolAbi, functionName: "gaugeForPool", args: [pool] })
3699
+ ]);
3700
+ let gaugeResults = await multicallRead(this.rpcUrl, gaugeCalls);
3701
+ const allNull = gaugeResults.every((r) => !r || decodeAddress2(r) === zeroAddress6 || decodeAddress2(r) === null);
3702
+ if (allNull) {
3703
+ const fallbackCalls = candidatePools.map(({ pool }) => [
3704
+ this.voter,
3705
+ encodeFunctionData10({ abi: poolToGaugeAbi, functionName: "poolToGauge", args: [pool] })
3706
+ ]);
3707
+ gaugeResults = await multicallRead(this.rpcUrl, fallbackCalls);
3708
+ }
3709
+ const gaugedCL = [];
3710
+ for (let i = 0; i < candidatePools.length; i++) {
3711
+ const gauge = decodeAddress2(gaugeResults[i] ?? null);
3712
+ if (gauge && gauge !== zeroAddress6) {
3713
+ gaugedCL.push({ ...candidatePools[i], gauge });
3714
+ }
3715
+ }
3716
+ if (gaugedCL.length === 0) return;
3717
+ const tokenAddrsInPools = /* @__PURE__ */ new Set();
3718
+ for (const { tokenA, tokenB } of gaugedCL) {
3719
+ tokenAddrsInPools.add(tokenA);
3720
+ tokenAddrsInPools.add(tokenB);
3721
+ }
3722
+ const uniqueTokens = Array.from(tokenAddrsInPools);
3723
+ const symbolCalls = uniqueTokens.map((t) => [
3724
+ t,
3725
+ encodeFunctionData10({ abi: erc20SymbolAbi, functionName: "symbol" })
3726
+ ]);
3727
+ const symbolResults = await multicallRead(this.rpcUrl, symbolCalls);
3728
+ const symbolMap = /* @__PURE__ */ new Map();
3729
+ for (let i = 0; i < uniqueTokens.length; i++) {
3730
+ symbolMap.set(uniqueTokens[i], decodeSymbol2(symbolResults[i] ?? null));
3731
+ }
3732
+ const poolTokenCalls = [];
3733
+ for (const { pool } of gaugedCL) {
3734
+ poolTokenCalls.push([pool, encodeFunctionData10({ abi: poolAbi2, functionName: "token0" })]);
3735
+ poolTokenCalls.push([pool, encodeFunctionData10({ abi: poolAbi2, functionName: "token1" })]);
3736
+ }
3737
+ const poolTokenResults = await multicallRead(this.rpcUrl, poolTokenCalls);
3738
+ for (let i = 0; i < gaugedCL.length; i++) {
3739
+ const { pool, gauge, tokenA, tokenB, tickSpacing } = gaugedCL[i];
3740
+ const rawT0 = decodeAddress2(poolTokenResults[i * 2] ?? null);
3741
+ const rawT1 = decodeAddress2(poolTokenResults[i * 2 + 1] ?? null);
3742
+ const t0 = rawT0 && rawT0 !== zeroAddress6 ? rawT0 : tokenA;
3743
+ const t1 = rawT1 && rawT1 !== zeroAddress6 ? rawT1 : tokenB;
3744
+ out.push({
3745
+ pool,
3746
+ gauge,
3747
+ token0: symbolMap.get(t0) ?? t0.slice(0, 10),
3748
+ token1: symbolMap.get(t1) ?? t1.slice(0, 10),
3749
+ type: "CL",
3750
+ tickSpacing
3751
+ });
3752
+ }
3753
+ }
3754
+ // IGauge
3755
+ async buildDeposit(gauge, amount, tokenId, lpToken) {
3756
+ if (tokenId !== void 0) {
3757
+ const data2 = encodeFunctionData10({
3758
+ abi: gaugeAbi,
3759
+ functionName: "depositFor",
3760
+ args: [amount, tokenId]
3761
+ });
3762
+ return {
3763
+ description: `[${this.protocolName}] Deposit ${amount} LP to gauge (boost veNFT #${tokenId})`,
3764
+ to: gauge,
3765
+ data: data2,
3766
+ value: 0n,
3767
+ gas_estimate: 2e5,
3768
+ approvals: lpToken ? [{ token: lpToken, spender: gauge, amount }] : void 0
3769
+ };
3770
+ }
3771
+ const data = encodeFunctionData10({
3772
+ abi: gaugeAbi,
3773
+ functionName: "deposit",
3774
+ args: [amount]
3775
+ });
3776
+ return {
3777
+ description: `[${this.protocolName}] Deposit ${amount} LP to gauge`,
3778
+ to: gauge,
3779
+ data,
3780
+ value: 0n,
3781
+ gas_estimate: 2e5,
3782
+ approvals: lpToken ? [{ token: lpToken, spender: gauge, amount }] : void 0
3783
+ };
3784
+ }
3785
+ async buildWithdraw(gauge, amount) {
3786
+ const data = encodeFunctionData10({
3787
+ abi: gaugeAbi,
3788
+ functionName: "withdraw",
3789
+ args: [amount]
3790
+ });
3791
+ return {
3792
+ description: `[${this.protocolName}] Withdraw ${amount} LP from gauge`,
3793
+ to: gauge,
3794
+ data,
3795
+ value: 0n,
3796
+ gas_estimate: 2e5
3797
+ };
3798
+ }
3799
+ /**
3800
+ * Resolve gauge address from a pool address via voter contract.
3801
+ * Tries gaugeForPool (Ramses), poolToGauge (NEST), gauges (classic Solidly).
3802
+ */
3803
+ async resolveGauge(pool) {
3804
+ if (!this.rpcUrl) throw DefiError.rpcError("RPC URL required for gauge lookup");
3805
+ const client = createPublicClient6({ transport: http6(this.rpcUrl) });
3806
+ for (const fn of ["gaugeForPool", "poolToGauge", "gauges"]) {
3807
+ try {
3808
+ const gauge = await client.readContract({
3809
+ address: this.voter,
3810
+ abi: voterAbi2,
3811
+ functionName: fn,
3812
+ args: [pool]
3813
+ });
3814
+ if (gauge !== zeroAddress6) return gauge;
3815
+ } catch {
3816
+ }
3817
+ }
3818
+ throw new DefiError("CONTRACT_ERROR", `[${this.protocolName}] No gauge found for pool ${pool}`);
3819
+ }
3820
+ /**
3821
+ * Discover reward tokens for a gauge.
3822
+ * Returns { tokens, multiToken } where multiToken indicates getReward(account, tokens[]) support.
3823
+ */
3824
+ async discoverRewardTokens(gauge) {
3825
+ if (!this.rpcUrl) return { tokens: [], multiToken: false };
3826
+ const client = createPublicClient6({ transport: http6(this.rpcUrl) });
3827
+ try {
3828
+ const len = await client.readContract({
3829
+ address: gauge,
3830
+ abi: gaugeAbi,
3831
+ functionName: "rewardsListLength"
3832
+ });
3833
+ if (Number(len) > 0) {
3834
+ const candidates = [
3835
+ "0x5555555555555555555555555555555555555555",
3836
+ // WHYPE
3837
+ "0x555570a286F15EbDFE42B66eDE2f724Aa1AB5555",
3838
+ // xRAM
3839
+ "0x067b0C72aa4C6Bd3BFEFfF443c536DCd6a25a9C8",
3840
+ // HYBR
3841
+ "0x07c57E32a3C29D5659bda1d3EFC2E7BF004E3035"
3842
+ // NEST token
3843
+ ];
3844
+ const found = [];
3845
+ for (const token of candidates) {
3846
+ try {
3847
+ const rd = await client.readContract({
3848
+ address: gauge,
3849
+ abi: gaugeAbi,
3850
+ functionName: "rewardData",
3851
+ args: [token]
3852
+ });
3853
+ if (rd[0] > 0n || rd[1] > 0n) found.push(token);
3854
+ } catch {
3855
+ }
3856
+ }
3857
+ if (found.length > 0) return { tokens: found, multiToken: true };
3858
+ return { tokens: [], multiToken: true };
3859
+ }
3860
+ } catch {
3861
+ }
3862
+ try {
3863
+ const rt = await client.readContract({
3864
+ address: gauge,
3865
+ abi: gaugeAbi,
3866
+ functionName: "rewardToken"
3867
+ });
3868
+ if (rt !== zeroAddress6) return { tokens: [rt], multiToken: false };
3869
+ } catch {
3870
+ }
3871
+ return { tokens: [], multiToken: false };
3872
+ }
3873
+ async buildClaimRewards(gauge, account) {
3874
+ if (!this.rpcUrl || !account) {
3875
+ const data2 = encodeFunctionData10({
3876
+ abi: gaugeAbi,
3877
+ functionName: "getReward",
3878
+ args: [account ?? zeroAddress6]
3879
+ });
3880
+ return { description: `[${this.protocolName}] Claim gauge rewards`, to: gauge, data: data2, value: 0n, gas_estimate: 2e5 };
3881
+ }
3882
+ const { tokens, multiToken } = await this.discoverRewardTokens(gauge);
3883
+ if (multiToken && tokens.length > 0) {
3884
+ const data2 = encodeFunctionData10({
3885
+ abi: gaugeAbi,
3886
+ functionName: "getReward",
3887
+ args: [account, tokens]
3888
+ });
3889
+ return {
3890
+ description: `[${this.protocolName}] Claim gauge rewards (${tokens.length} tokens)`,
3891
+ to: gauge,
3892
+ data: data2,
3893
+ value: 0n,
3894
+ gas_estimate: 3e5
3895
+ };
3896
+ }
3897
+ const data = encodeFunctionData10({
3898
+ abi: gaugeAbi,
3899
+ functionName: "getReward",
3900
+ args: []
3901
+ });
3902
+ return {
3903
+ description: `[${this.protocolName}] Claim gauge rewards`,
3904
+ to: gauge,
3905
+ data,
3906
+ value: 0n,
3907
+ gas_estimate: 2e5
3908
+ };
3909
+ }
3910
+ /**
3911
+ * Claim rewards for a CL gauge by NFT tokenId (Hybra V4 style).
3912
+ */
3913
+ async buildClaimRewardsByTokenId(gauge, tokenId) {
3914
+ const data = encodeFunctionData10({
3915
+ abi: gaugeAbi,
3916
+ functionName: "getReward",
3917
+ args: [tokenId]
3918
+ });
3919
+ return {
3920
+ description: `[${this.protocolName}] Claim gauge rewards for NFT #${tokenId}`,
3921
+ to: gauge,
3922
+ data,
3923
+ value: 0n,
3924
+ gas_estimate: 3e5
3925
+ };
3926
+ }
3927
+ async getPendingRewards(gauge, user) {
3928
+ if (!this.rpcUrl) throw DefiError.rpcError("RPC URL required");
3929
+ const client = createPublicClient6({ transport: http6(this.rpcUrl) });
3930
+ const results = [];
3931
+ const { tokens, multiToken } = await this.discoverRewardTokens(gauge);
3932
+ if (multiToken && tokens.length > 0) {
3933
+ for (const token of tokens) {
3934
+ try {
3935
+ const earned = await client.readContract({
3936
+ address: gauge,
3937
+ abi: gaugeAbi,
3938
+ functionName: "earned",
3939
+ args: [token, user]
3940
+ });
3941
+ results.push({ token, symbol: token.slice(0, 10), amount: earned });
3942
+ } catch {
3943
+ }
3944
+ }
3945
+ } else if (tokens.length > 0) {
3946
+ try {
3947
+ const earned = await client.readContract({
3948
+ address: gauge,
3949
+ abi: gaugeAbi,
3950
+ functionName: "earned",
3951
+ args: [user]
3952
+ });
3953
+ results.push({ token: tokens[0], symbol: tokens[0].slice(0, 10), amount: earned });
3954
+ } catch {
3955
+ }
3956
+ } else {
3957
+ try {
3958
+ const earned = await client.readContract({
3959
+ address: gauge,
3960
+ abi: gaugeAbi,
3961
+ functionName: "earned",
3962
+ args: [user]
3963
+ });
3964
+ results.push({ token: zeroAddress6, symbol: "unknown", amount: earned });
3965
+ } catch {
3966
+ }
3967
+ }
3968
+ return results;
3969
+ }
3970
+ /**
3971
+ * Get pending rewards for a CL gauge NFT position (Hybra V4 style).
3972
+ */
3973
+ async getPendingRewardsByTokenId(gauge, tokenId) {
3974
+ if (!this.rpcUrl) throw DefiError.rpcError("RPC URL required");
3975
+ const client = createPublicClient6({ transport: http6(this.rpcUrl) });
3976
+ return await client.readContract({
3977
+ address: gauge,
3978
+ abi: gaugeAbi,
3979
+ functionName: "earned",
3980
+ args: [tokenId]
3981
+ });
3982
+ }
3983
+ // IVoteEscrow
3984
+ async buildCreateLock(amount, lockDuration) {
3985
+ const data = encodeFunctionData10({
3986
+ abi: veAbi2,
3987
+ functionName: "create_lock",
3988
+ args: [amount, BigInt(lockDuration)]
3989
+ });
3990
+ return {
3991
+ description: `[${this.protocolName}] Create veNFT lock: ${amount} tokens for ${lockDuration}s`,
3992
+ to: this.veToken,
3993
+ data,
3994
+ value: 0n,
3995
+ gas_estimate: 3e5
3996
+ };
3997
+ }
3998
+ async buildIncreaseAmount(tokenId, amount) {
3999
+ const data = encodeFunctionData10({
4000
+ abi: veAbi2,
4001
+ functionName: "increase_amount",
4002
+ args: [tokenId, amount]
4003
+ });
4004
+ return {
4005
+ description: `[${this.protocolName}] Increase veNFT #${tokenId} by ${amount}`,
4006
+ to: this.veToken,
4007
+ data,
4008
+ value: 0n,
4009
+ gas_estimate: 2e5
4010
+ };
4011
+ }
4012
+ async buildIncreaseUnlockTime(tokenId, lockDuration) {
4013
+ const data = encodeFunctionData10({
4014
+ abi: veAbi2,
4015
+ functionName: "increase_unlock_time",
4016
+ args: [tokenId, BigInt(lockDuration)]
4017
+ });
4018
+ return {
4019
+ description: `[${this.protocolName}] Extend veNFT #${tokenId} lock by ${lockDuration}s`,
3025
4020
  to: this.veToken,
3026
4021
  data,
3027
4022
  value: 0n,
@@ -3029,8 +4024,8 @@ var SolidlyGaugeAdapter = class {
3029
4024
  };
3030
4025
  }
3031
4026
  async buildWithdrawExpired(tokenId) {
3032
- const data = encodeFunctionData8({
3033
- abi: veAbi,
4027
+ const data = encodeFunctionData10({
4028
+ abi: veAbi2,
3034
4029
  functionName: "withdraw",
3035
4030
  args: [tokenId]
3036
4031
  });
@@ -3044,8 +4039,8 @@ var SolidlyGaugeAdapter = class {
3044
4039
  }
3045
4040
  // IVoter
3046
4041
  async buildVote(tokenId, pools, weights) {
3047
- const data = encodeFunctionData8({
3048
- abi: voterAbi,
4042
+ const data = encodeFunctionData10({
4043
+ abi: voterAbi2,
3049
4044
  functionName: "vote",
3050
4045
  args: [tokenId, pools, weights]
3051
4046
  });
@@ -3059,8 +4054,8 @@ var SolidlyGaugeAdapter = class {
3059
4054
  }
3060
4055
  async buildClaimBribes(bribes, tokenId) {
3061
4056
  const tokensPerBribe = bribes.map(() => []);
3062
- const data = encodeFunctionData8({
3063
- abi: voterAbi,
4057
+ const data = encodeFunctionData10({
4058
+ abi: voterAbi2,
3064
4059
  functionName: "claimBribes",
3065
4060
  args: [bribes, tokensPerBribe, tokenId]
3066
4061
  });
@@ -3074,8 +4069,8 @@ var SolidlyGaugeAdapter = class {
3074
4069
  }
3075
4070
  async buildClaimFees(fees, tokenId) {
3076
4071
  const tokensPerFee = fees.map(() => []);
3077
- const data = encodeFunctionData8({
3078
- abi: voterAbi,
4072
+ const data = encodeFunctionData10({
4073
+ abi: voterAbi2,
3079
4074
  functionName: "claimFees",
3080
4075
  args: [fees, tokensPerFee, tokenId]
3081
4076
  });
@@ -3088,7 +4083,7 @@ var SolidlyGaugeAdapter = class {
3088
4083
  };
3089
4084
  }
3090
4085
  };
3091
- var masterchefAbi = parseAbi9([
4086
+ var masterchefAbi = parseAbi11([
3092
4087
  "function deposit(uint256 pid, uint256 amount) external",
3093
4088
  "function withdraw(uint256 pid, uint256 amount) external",
3094
4089
  "function claim(uint256[] calldata pids) external",
@@ -3119,7 +4114,7 @@ var MasterChefAdapter = class {
3119
4114
  */
3120
4115
  async buildDeposit(gauge, amount, tokenId) {
3121
4116
  const pid = tokenId ?? 0n;
3122
- const data = encodeFunctionData9({
4117
+ const data = encodeFunctionData11({
3123
4118
  abi: masterchefAbi,
3124
4119
  functionName: "deposit",
3125
4120
  args: [pid, amount]
@@ -3140,7 +4135,7 @@ var MasterChefAdapter = class {
3140
4135
  */
3141
4136
  async buildWithdraw(gauge, amount) {
3142
4137
  const pid = 0n;
3143
- const data = encodeFunctionData9({
4138
+ const data = encodeFunctionData11({
3144
4139
  abi: masterchefAbi,
3145
4140
  functionName: "withdraw",
3146
4141
  args: [pid, amount]
@@ -3155,7 +4150,7 @@ var MasterChefAdapter = class {
3155
4150
  }
3156
4151
  /** Withdraw LP tokens specifying a pid explicitly (MasterChef extension beyond IGauge). */
3157
4152
  async buildWithdrawPid(pid, amount) {
3158
- const data = encodeFunctionData9({
4153
+ const data = encodeFunctionData11({
3159
4154
  abi: masterchefAbi,
3160
4155
  functionName: "withdraw",
3161
4156
  args: [pid, amount]
@@ -3171,7 +4166,7 @@ var MasterChefAdapter = class {
3171
4166
  /** Claim pending MOE rewards. IGauge interface provides no pid — defaults to pid=0. */
3172
4167
  async buildClaimRewards(gauge) {
3173
4168
  const pid = 0n;
3174
- const data = encodeFunctionData9({
4169
+ const data = encodeFunctionData11({
3175
4170
  abi: masterchefAbi,
3176
4171
  functionName: "claim",
3177
4172
  args: [[pid]]
@@ -3186,7 +4181,7 @@ var MasterChefAdapter = class {
3186
4181
  }
3187
4182
  /** Claim pending MOE rewards for a specific pid (MasterChef extension beyond IGauge). */
3188
4183
  async buildClaimRewardsPid(pid) {
3189
- const data = encodeFunctionData9({
4184
+ const data = encodeFunctionData11({
3190
4185
  abi: masterchefAbi,
3191
4186
  functionName: "claim",
3192
4187
  args: [[pid]]
@@ -3204,7 +4199,7 @@ var MasterChefAdapter = class {
3204
4199
  if (!this.rpcUrl) {
3205
4200
  throw DefiError.unsupported(`[${this.protocolName}] getPendingRewards requires RPC`);
3206
4201
  }
3207
- const client = createPublicClient5({ transport: http5(this.rpcUrl) });
4202
+ const client = createPublicClient7({ transport: http7(this.rpcUrl) });
3208
4203
  const rewards = await client.readContract({
3209
4204
  address: this.masterchef,
3210
4205
  abi: masterchefAbi,
@@ -3218,16 +4213,16 @@ var MasterChefAdapter = class {
3218
4213
  }));
3219
4214
  }
3220
4215
  };
3221
- var lbRouterAbi = parseAbi10([
4216
+ var lbRouterAbi = parseAbi12([
3222
4217
  "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; }",
3223
4218
  "function addLiquidity(LiquidityParameters calldata liquidityParameters) external returns (uint256 amountXAdded, uint256 amountYAdded, uint256 amountXLeft, uint256 amountYLeft, uint256[] memory depositIds, uint256[] memory liquidityMinted)",
3224
4219
  "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)"
3225
4220
  ]);
3226
- var lbFactoryAbi = parseAbi10([
4221
+ var lbFactoryAbi = parseAbi12([
3227
4222
  "function getNumberOfLBPairs() external view returns (uint256)",
3228
4223
  "function getLBPairAtIndex(uint256 index) external view returns (address)"
3229
4224
  ]);
3230
- var lbPairAbi = parseAbi10([
4225
+ var lbPairAbi = parseAbi12([
3231
4226
  "function getLBHooksParameters() external view returns (bytes32)",
3232
4227
  "function getActiveId() external view returns (uint24)",
3233
4228
  "function getBinStep() external view returns (uint16)",
@@ -3236,7 +4231,7 @@ var lbPairAbi = parseAbi10([
3236
4231
  "function balanceOf(address account, uint256 id) external view returns (uint256)",
3237
4232
  "function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory)"
3238
4233
  ]);
3239
- var lbRewarderAbi = parseAbi10([
4234
+ var lbRewarderAbi = parseAbi12([
3240
4235
  "function getRewardToken() external view returns (address)",
3241
4236
  "function getRewardedRange() external view returns (uint256 minBinId, uint256 maxBinId)",
3242
4237
  "function getPendingRewards(address user, uint256[] calldata ids) external view returns (uint256 pendingRewards)",
@@ -3246,50 +4241,50 @@ var lbRewarderAbi = parseAbi10([
3246
4241
  "function getLBPair() external view returns (address)",
3247
4242
  "function getMasterChef() external view returns (address)"
3248
4243
  ]);
3249
- var masterChefAbi = parseAbi10([
4244
+ var masterChefAbi = parseAbi12([
3250
4245
  "function getMoePerSecond() external view returns (uint256)",
3251
4246
  "function getTreasuryShare() external view returns (uint256)",
3252
4247
  "function getStaticShare() external view returns (uint256)",
3253
4248
  "function getVeMoe() external view returns (address)"
3254
4249
  ]);
3255
- var veMoeAbi = parseAbi10([
4250
+ var veMoeAbi = parseAbi12([
3256
4251
  "function getWeight(uint256 pid) external view returns (uint256)",
3257
4252
  "function getTotalWeight() external view returns (uint256)",
3258
4253
  "function getTopPoolIds() external view returns (uint256[] memory)"
3259
4254
  ]);
3260
- var lbPairBinAbi = parseAbi10([
4255
+ var lbPairBinAbi = parseAbi12([
3261
4256
  "function getBin(uint24 id) external view returns (uint128 reserveX, uint128 reserveY)",
3262
4257
  "function getActiveId() external view returns (uint24)"
3263
4258
  ]);
3264
- var lbQuoterAbi2 = parseAbi10([
4259
+ var lbQuoterAbi2 = parseAbi12([
3265
4260
  "function findBestPathFromAmountIn(address[] calldata route, uint128 amountIn) external view returns ((address[] route, address[] pairs, uint256[] binSteps, uint256[] versions, uint128[] amounts, uint128[] virtualAmountsWithoutSlippage, uint128[] fees))"
3266
4261
  ]);
3267
- var erc20Abi2 = parseAbi10([
4262
+ var erc20Abi2 = parseAbi12([
3268
4263
  "function symbol() external view returns (string)"
3269
4264
  ]);
3270
- var _addressAbi = parseAbi10(["function f() external view returns (address)"]);
4265
+ var _addressAbi = parseAbi12(["function f() external view returns (address)"]);
3271
4266
  function decodeAddressResult(data) {
3272
4267
  if (!data) return null;
3273
4268
  try {
3274
- return decodeFunctionResult22({ abi: _addressAbi, functionName: "f", data });
4269
+ return decodeFunctionResult4({ abi: _addressAbi, functionName: "f", data });
3275
4270
  } catch {
3276
4271
  return null;
3277
4272
  }
3278
4273
  }
3279
- var _uint256Abi = parseAbi10(["function f() external view returns (uint256)"]);
4274
+ var _uint256Abi = parseAbi12(["function f() external view returns (uint256)"]);
3280
4275
  function decodeUint256Result(data) {
3281
4276
  if (!data) return null;
3282
4277
  try {
3283
- return decodeFunctionResult22({ abi: _uint256Abi, functionName: "f", data });
4278
+ return decodeFunctionResult4({ abi: _uint256Abi, functionName: "f", data });
3284
4279
  } catch {
3285
4280
  return null;
3286
4281
  }
3287
4282
  }
3288
- var _boolAbi = parseAbi10(["function f() external view returns (bool)"]);
4283
+ var _boolAbi = parseAbi12(["function f() external view returns (bool)"]);
3289
4284
  function decodeBoolResult(data) {
3290
4285
  if (!data) return null;
3291
4286
  try {
3292
- return decodeFunctionResult22({ abi: _boolAbi, functionName: "f", data });
4287
+ return decodeFunctionResult4({ abi: _boolAbi, functionName: "f", data });
3293
4288
  } catch {
3294
4289
  return null;
3295
4290
  }
@@ -3297,34 +4292,34 @@ function decodeBoolResult(data) {
3297
4292
  function decodeStringResult(data) {
3298
4293
  if (!data) return "?";
3299
4294
  try {
3300
- return decodeFunctionResult22({ abi: erc20Abi2, functionName: "symbol", data });
4295
+ return decodeFunctionResult4({ abi: erc20Abi2, functionName: "symbol", data });
3301
4296
  } catch {
3302
4297
  return "?";
3303
4298
  }
3304
4299
  }
3305
- var _rangeAbi = parseAbi10(["function f() external view returns (uint256 minBinId, uint256 maxBinId)"]);
4300
+ var _rangeAbi = parseAbi12(["function f() external view returns (uint256 minBinId, uint256 maxBinId)"]);
3306
4301
  function decodeRangeResult(data) {
3307
4302
  if (!data) return null;
3308
4303
  try {
3309
- return decodeFunctionResult22({ abi: _rangeAbi, functionName: "f", data });
4304
+ return decodeFunctionResult4({ abi: _rangeAbi, functionName: "f", data });
3310
4305
  } catch {
3311
4306
  return null;
3312
4307
  }
3313
4308
  }
3314
- var _binAbi = parseAbi10(["function f() external view returns (uint128 reserveX, uint128 reserveY)"]);
4309
+ var _binAbi = parseAbi12(["function f() external view returns (uint128 reserveX, uint128 reserveY)"]);
3315
4310
  function decodeBinResult(data) {
3316
4311
  if (!data) return null;
3317
4312
  try {
3318
- return decodeFunctionResult22({ abi: _binAbi, functionName: "f", data });
4313
+ return decodeFunctionResult4({ abi: _binAbi, functionName: "f", data });
3319
4314
  } catch {
3320
4315
  return null;
3321
4316
  }
3322
4317
  }
3323
- var _uint256ArrayAbi = parseAbi10(["function f() external view returns (uint256[] memory)"]);
4318
+ var _uint256ArrayAbi = parseAbi12(["function f() external view returns (uint256[] memory)"]);
3324
4319
  function decodeUint256ArrayResult(data) {
3325
4320
  if (!data) return null;
3326
4321
  try {
3327
- return decodeFunctionResult22({ abi: _uint256ArrayAbi, functionName: "f", data });
4322
+ return decodeFunctionResult4({ abi: _uint256ArrayAbi, functionName: "f", data });
3328
4323
  } catch {
3329
4324
  return null;
3330
4325
  }
@@ -3410,7 +4405,7 @@ var MerchantMoeLBAdapter = class {
3410
4405
  let activeIdDesired = params.activeIdDesired;
3411
4406
  if (activeIdDesired === void 0) {
3412
4407
  const rpcUrl = this.requireRpc();
3413
- const client = createPublicClient6({ transport: http6(rpcUrl) });
4408
+ const client = createPublicClient8({ transport: http8(rpcUrl) });
3414
4409
  const activeId = await client.readContract({
3415
4410
  address: params.pool,
3416
4411
  abi: lbPairAbi,
@@ -3423,7 +4418,7 @@ var MerchantMoeLBAdapter = class {
3423
4418
  deltaIds.push(d);
3424
4419
  }
3425
4420
  const { distributionX, distributionY } = buildUniformDistribution(deltaIds);
3426
- const data = encodeFunctionData10({
4421
+ const data = encodeFunctionData12({
3427
4422
  abi: lbRouterAbi,
3428
4423
  functionName: "addLiquidity",
3429
4424
  args: [
@@ -3463,7 +4458,7 @@ var MerchantMoeLBAdapter = class {
3463
4458
  */
3464
4459
  async buildRemoveLiquidity(params) {
3465
4460
  const deadline = params.deadline ?? BigInt("18446744073709551615");
3466
- const data = encodeFunctionData10({
4461
+ const data = encodeFunctionData12({
3467
4462
  abi: lbRouterAbi,
3468
4463
  functionName: "removeLiquidity",
3469
4464
  args: [
@@ -3492,7 +4487,7 @@ var MerchantMoeLBAdapter = class {
3492
4487
  */
3493
4488
  async autoDetectBins(pool) {
3494
4489
  const rpcUrl = this.requireRpc();
3495
- const client = createPublicClient6({ transport: http6(rpcUrl) });
4490
+ const client = createPublicClient8({ transport: http8(rpcUrl) });
3496
4491
  const hooksParams = await client.readContract({
3497
4492
  address: pool,
3498
4493
  abi: lbPairAbi,
@@ -3527,7 +4522,7 @@ var MerchantMoeLBAdapter = class {
3527
4522
  */
3528
4523
  async getPendingRewards(user, pool, binIds) {
3529
4524
  const rpcUrl = this.requireRpc();
3530
- const client = createPublicClient6({ transport: http6(rpcUrl) });
4525
+ const client = createPublicClient8({ transport: http8(rpcUrl) });
3531
4526
  const hooksParams = await client.readContract({
3532
4527
  address: pool,
3533
4528
  abi: lbPairAbi,
@@ -3576,7 +4571,7 @@ var MerchantMoeLBAdapter = class {
3576
4571
  */
3577
4572
  async buildClaimRewards(user, pool, binIds) {
3578
4573
  const rpcUrl = this.requireRpc();
3579
- const client = createPublicClient6({ transport: http6(rpcUrl) });
4574
+ const client = createPublicClient8({ transport: http8(rpcUrl) });
3580
4575
  const hooksParams = await client.readContract({
3581
4576
  address: pool,
3582
4577
  abi: lbPairAbi,
@@ -3598,7 +4593,7 @@ var MerchantMoeLBAdapter = class {
3598
4593
  resolvedBinIds = [];
3599
4594
  for (let b = min; b <= max; b++) resolvedBinIds.push(b);
3600
4595
  }
3601
- const data = encodeFunctionData10({
4596
+ const data = encodeFunctionData12({
3602
4597
  abi: lbRewarderAbi,
3603
4598
  functionName: "claim",
3604
4599
  args: [user, resolvedBinIds.map(BigInt)]
@@ -3626,7 +4621,7 @@ var MerchantMoeLBAdapter = class {
3626
4621
  */
3627
4622
  async discoverRewardedPools() {
3628
4623
  const rpcUrl = this.requireRpc();
3629
- const client = createPublicClient6({ transport: http6(rpcUrl) });
4624
+ const client = createPublicClient8({ transport: http8(rpcUrl) });
3630
4625
  const pairCount = await client.readContract({
3631
4626
  address: this.lbFactory,
3632
4627
  abi: lbFactoryAbi,
@@ -3636,14 +4631,14 @@ var MerchantMoeLBAdapter = class {
3636
4631
  if (count === 0) return [];
3637
4632
  const batch1Calls = Array.from({ length: count }, (_, i) => [
3638
4633
  this.lbFactory,
3639
- encodeFunctionData10({ abi: lbFactoryAbi, functionName: "getLBPairAtIndex", args: [BigInt(i)] })
4634
+ encodeFunctionData12({ abi: lbFactoryAbi, functionName: "getLBPairAtIndex", args: [BigInt(i)] })
3640
4635
  ]);
3641
4636
  const batch1Results = await multicallRead(rpcUrl, batch1Calls);
3642
4637
  const pairAddresses = batch1Results.map((r) => decodeAddressResult(r)).filter((a) => a !== null);
3643
4638
  if (pairAddresses.length === 0) return [];
3644
4639
  const batch2Calls = pairAddresses.map((pair) => [
3645
4640
  pair,
3646
- encodeFunctionData10({ abi: lbPairAbi, functionName: "getLBHooksParameters" })
4641
+ encodeFunctionData12({ abi: lbPairAbi, functionName: "getLBHooksParameters" })
3647
4642
  ]);
3648
4643
  const batch2Results = await multicallRead(rpcUrl, batch2Calls);
3649
4644
  const rewardedPairs = [];
@@ -3652,8 +4647,8 @@ var MerchantMoeLBAdapter = class {
3652
4647
  if (!raw) continue;
3653
4648
  let hooksBytes;
3654
4649
  try {
3655
- const _bytes32Abi = parseAbi10(["function f() external view returns (bytes32)"]);
3656
- hooksBytes = decodeFunctionResult22({ abi: _bytes32Abi, functionName: "f", data: raw });
4650
+ const _bytes32Abi = parseAbi12(["function f() external view returns (bytes32)"]);
4651
+ hooksBytes = decodeFunctionResult4({ abi: _bytes32Abi, functionName: "f", data: raw });
3657
4652
  } catch {
3658
4653
  continue;
3659
4654
  }
@@ -3665,17 +4660,17 @@ var MerchantMoeLBAdapter = class {
3665
4660
  if (rewardedPairs.length === 0) return [];
3666
4661
  const batch3Calls = [];
3667
4662
  for (const { rewarder } of rewardedPairs) {
3668
- batch3Calls.push([rewarder, encodeFunctionData10({ abi: lbRewarderAbi, functionName: "isStopped" })]);
3669
- batch3Calls.push([rewarder, encodeFunctionData10({ abi: lbRewarderAbi, functionName: "getRewardedRange" })]);
3670
- batch3Calls.push([rewarder, encodeFunctionData10({ abi: lbRewarderAbi, functionName: "getRewardToken" })]);
3671
- batch3Calls.push([rewarder, encodeFunctionData10({ abi: lbRewarderAbi, functionName: "getPid" })]);
3672
- batch3Calls.push([rewarder, encodeFunctionData10({ abi: lbRewarderAbi, functionName: "getMasterChef" })]);
4663
+ batch3Calls.push([rewarder, encodeFunctionData12({ abi: lbRewarderAbi, functionName: "isStopped" })]);
4664
+ batch3Calls.push([rewarder, encodeFunctionData12({ abi: lbRewarderAbi, functionName: "getRewardedRange" })]);
4665
+ batch3Calls.push([rewarder, encodeFunctionData12({ abi: lbRewarderAbi, functionName: "getRewardToken" })]);
4666
+ batch3Calls.push([rewarder, encodeFunctionData12({ abi: lbRewarderAbi, functionName: "getPid" })]);
4667
+ batch3Calls.push([rewarder, encodeFunctionData12({ abi: lbRewarderAbi, functionName: "getMasterChef" })]);
3673
4668
  }
3674
4669
  const batch3Results = await multicallRead(rpcUrl, batch3Calls);
3675
4670
  const batch4aCalls = [];
3676
4671
  for (const { pool } of rewardedPairs) {
3677
- batch4aCalls.push([pool, encodeFunctionData10({ abi: lbPairAbi, functionName: "getTokenX" })]);
3678
- batch4aCalls.push([pool, encodeFunctionData10({ abi: lbPairAbi, functionName: "getTokenY" })]);
4672
+ batch4aCalls.push([pool, encodeFunctionData12({ abi: lbPairAbi, functionName: "getTokenX" })]);
4673
+ batch4aCalls.push([pool, encodeFunctionData12({ abi: lbPairAbi, functionName: "getTokenY" })]);
3679
4674
  }
3680
4675
  const batch4aResults = await multicallRead(rpcUrl, batch4aCalls);
3681
4676
  const tokenXAddresses = [];
@@ -3689,7 +4684,7 @@ var MerchantMoeLBAdapter = class {
3689
4684
  );
3690
4685
  const batch4bCalls = uniqueTokens.map((token) => [
3691
4686
  token,
3692
- encodeFunctionData10({ abi: erc20Abi2, functionName: "symbol" })
4687
+ encodeFunctionData12({ abi: erc20Abi2, functionName: "symbol" })
3693
4688
  ]);
3694
4689
  const batch4bResults = await multicallRead(rpcUrl, batch4bCalls);
3695
4690
  const symbolMap = /* @__PURE__ */ new Map();
@@ -3720,11 +4715,11 @@ var MerchantMoeLBAdapter = class {
3720
4715
  functionName: "getVeMoe"
3721
4716
  });
3722
4717
  const batch5Calls = [
3723
- [masterChefAddr, encodeFunctionData10({ abi: masterChefAbi, functionName: "getMoePerSecond" })],
3724
- [masterChefAddr, encodeFunctionData10({ abi: masterChefAbi, functionName: "getTreasuryShare" })],
3725
- [masterChefAddr, encodeFunctionData10({ abi: masterChefAbi, functionName: "getStaticShare" })],
3726
- [veMoeAddr, encodeFunctionData10({ abi: veMoeAbi, functionName: "getTotalWeight" })],
3727
- [veMoeAddr, encodeFunctionData10({ abi: veMoeAbi, functionName: "getTopPoolIds" })]
4718
+ [masterChefAddr, encodeFunctionData12({ abi: masterChefAbi, functionName: "getMoePerSecond" })],
4719
+ [masterChefAddr, encodeFunctionData12({ abi: masterChefAbi, functionName: "getTreasuryShare" })],
4720
+ [masterChefAddr, encodeFunctionData12({ abi: masterChefAbi, functionName: "getStaticShare" })],
4721
+ [veMoeAddr, encodeFunctionData12({ abi: veMoeAbi, functionName: "getTotalWeight" })],
4722
+ [veMoeAddr, encodeFunctionData12({ abi: veMoeAbi, functionName: "getTopPoolIds" })]
3728
4723
  ];
3729
4724
  const batch5Results = await multicallRead(rpcUrl, batch5Calls);
3730
4725
  const moePerSecRaw = decodeUint256Result(batch5Results[0] ?? null) ?? 0n;
@@ -3741,7 +4736,7 @@ var MerchantMoeLBAdapter = class {
3741
4736
  if (veMoeAddr && rewardedPairs.length > 0) {
3742
4737
  const batch6Calls = poolData.map((d) => [
3743
4738
  veMoeAddr,
3744
- encodeFunctionData10({ abi: veMoeAbi, functionName: "getWeight", args: [BigInt(d.pid)] })
4739
+ encodeFunctionData12({ abi: veMoeAbi, functionName: "getWeight", args: [BigInt(d.pid)] })
3745
4740
  ]);
3746
4741
  const batch6Results = await multicallRead(rpcUrl, batch6Calls);
3747
4742
  for (let i = 0; i < poolData.length; i++) {
@@ -3788,7 +4783,7 @@ var MerchantMoeLBAdapter = class {
3788
4783
  if (binRequests.length > 0) {
3789
4784
  const batch7Calls = binRequests.map(({ poolIdx, binId }) => [
3790
4785
  rewardedPairs[poolIdx].pool,
3791
- encodeFunctionData10({ abi: lbPairBinAbi, functionName: "getBin", args: [binId] })
4786
+ encodeFunctionData12({ abi: lbPairBinAbi, functionName: "getBin", args: [binId] })
3792
4787
  ]);
3793
4788
  const batch7Results = await multicallRead(rpcUrl, batch7Calls);
3794
4789
  for (let j = 0; j < binRequests.length; j++) {
@@ -3874,26 +4869,460 @@ var MerchantMoeLBAdapter = class {
3874
4869
  }
3875
4870
  return results;
3876
4871
  }
3877
- /**
3878
- * Get a user's LB positions (bin balances) across a range of bin IDs.
3879
- * If binIds is omitted, auto-detects from the rewarder's rewarded range (or active ± 50).
3880
- */
3881
- async getUserPositions(user, pool, binIds) {
3882
- const rpcUrl = this.requireRpc();
3883
- const client = createPublicClient6({ transport: http6(rpcUrl) });
3884
- const resolvedBinIds = binIds && binIds.length > 0 ? binIds : await this.autoDetectBins(pool);
3885
- const accounts = resolvedBinIds.map(() => user);
3886
- const ids = resolvedBinIds.map(BigInt);
3887
- const balances = await client.readContract({
3888
- address: pool,
3889
- abi: lbPairAbi,
3890
- functionName: "balanceOfBatch",
3891
- args: [accounts, ids]
3892
- });
3893
- return resolvedBinIds.map((binId, i) => ({ binId, balance: balances[i] ?? 0n })).filter((p) => p.balance > 0n);
3894
- }
4872
+ /**
4873
+ * Get a user's LB positions (bin balances) across a range of bin IDs.
4874
+ * If binIds is omitted, auto-detects from the rewarder's rewarded range (or active ± 50).
4875
+ */
4876
+ async getUserPositions(user, pool, binIds) {
4877
+ const rpcUrl = this.requireRpc();
4878
+ const client = createPublicClient8({ transport: http8(rpcUrl) });
4879
+ const resolvedBinIds = binIds && binIds.length > 0 ? binIds : await this.autoDetectBins(pool);
4880
+ const accounts = resolvedBinIds.map(() => user);
4881
+ const ids = resolvedBinIds.map(BigInt);
4882
+ const balances = await client.readContract({
4883
+ address: pool,
4884
+ abi: lbPairAbi,
4885
+ functionName: "balanceOfBatch",
4886
+ args: [accounts, ids]
4887
+ });
4888
+ return resolvedBinIds.map((binId, i) => ({ binId, balance: balances[i] ?? 0n })).filter((p) => p.balance > 0n);
4889
+ }
4890
+ };
4891
+ var KITTEN_TOKEN = "0x618275f8efe54c2afa87bfb9f210a52f0ff89364";
4892
+ var WHYPE_TOKEN = "0x5555555555555555555555555555555555555555";
4893
+ var MAX_NONCE_SCAN = 60;
4894
+ var HYPEREVM_TOKENS2 = [
4895
+ "0x5555555555555555555555555555555555555555",
4896
+ // WHYPE
4897
+ "0xb88339CB7199b77E23DB6E890353E22632Ba630f",
4898
+ // USDC
4899
+ "0xB8CE59FC3717ada4C02eaDF9682A9e934F625ebb",
4900
+ // USDT0
4901
+ "0xBe6727B535545C67d5cAa73dEa54865B92CF7907",
4902
+ // UETH
4903
+ "0x9FDBdA0A5e284c32744D2f17Ee5c74B284993463",
4904
+ // UBTC
4905
+ "0x111111a1a0667d36bD57c0A9f569b98057111111",
4906
+ // USDH
4907
+ "0x5d3a1Ff2b6BAb83b63cd9AD0787074081a52ef34",
4908
+ // USDe
4909
+ "0x211Cc4DD073734dA055fbF44a2b4667d5E5fE5d2",
4910
+ // sUSDe
4911
+ "0xf4D9235269a96aaDaFc9aDAe454a0618eBE37949",
4912
+ // XAUt0
4913
+ "0xfD739d4e423301CE9385c1fb8850539D657C296D",
4914
+ // kHYPE
4915
+ KITTEN_TOKEN
4916
+ // KITTEN
4917
+ ];
4918
+ var farmingCenterAbi = parseAbi13([
4919
+ "function multicall(bytes[] calldata data) external payable returns (bytes[] memory results)",
4920
+ "function enterFarming((address rewardToken, address bonusRewardToken, address pool, uint256 nonce) key, uint256 tokenId) external",
4921
+ "function exitFarming((address rewardToken, address bonusRewardToken, address pool, uint256 nonce) key, uint256 tokenId) external",
4922
+ "function collectRewards((address rewardToken, address bonusRewardToken, address pool, uint256 nonce) key, uint256 tokenId) external",
4923
+ "function claimReward(address rewardToken, address to, uint128 amountRequested) external returns (uint256 reward)"
4924
+ ]);
4925
+ var positionManagerAbi2 = parseAbi13([
4926
+ "function approveForFarming(uint256 tokenId, bool approve, address farmingAddress) external",
4927
+ "function farmingApprovals(uint256 tokenId) external view returns (address)"
4928
+ ]);
4929
+ var eternalFarmingAbi = parseAbi13([
4930
+ "function incentives(bytes32 incentiveId) external view returns (uint256 totalReward, uint256 bonusReward, address virtualPoolAddress, uint24 minimalPositionWidth, bool deactivated, address pluginAddress)",
4931
+ "function getRewardInfo((address rewardToken, address bonusRewardToken, address pool, uint256 nonce) key, uint256 tokenId) external view returns (uint256 reward, uint256 bonusReward)"
4932
+ ]);
4933
+ var algebraFactoryAbi = parseAbi13([
4934
+ "function poolByPair(address tokenA, address tokenB) external view returns (address pool)"
4935
+ ]);
4936
+ var _addressDecodeAbi3 = parseAbi13(["function f() external view returns (address)"]);
4937
+ function decodeAddress3(data) {
4938
+ if (!data) return null;
4939
+ try {
4940
+ return decodeFunctionResult5({ abi: _addressDecodeAbi3, functionName: "f", data });
4941
+ } catch {
4942
+ return null;
4943
+ }
4944
+ }
4945
+ function incentiveId(key) {
4946
+ return keccak256(
4947
+ encodeAbiParameters(
4948
+ [
4949
+ { name: "rewardToken", type: "address" },
4950
+ { name: "bonusRewardToken", type: "address" },
4951
+ { name: "pool", type: "address" },
4952
+ { name: "nonce", type: "uint256" }
4953
+ ],
4954
+ [key.rewardToken, key.bonusRewardToken, key.pool, key.nonce]
4955
+ )
4956
+ );
4957
+ }
4958
+ function encodeEnterFarming(key, tokenId) {
4959
+ return encodeFunctionData13({
4960
+ abi: farmingCenterAbi,
4961
+ functionName: "enterFarming",
4962
+ args: [key, tokenId]
4963
+ });
4964
+ }
4965
+ function encodeExitFarming(key, tokenId) {
4966
+ return encodeFunctionData13({
4967
+ abi: farmingCenterAbi,
4968
+ functionName: "exitFarming",
4969
+ args: [key, tokenId]
4970
+ });
4971
+ }
4972
+ function encodeCollectRewards(key, tokenId) {
4973
+ return encodeFunctionData13({
4974
+ abi: farmingCenterAbi,
4975
+ functionName: "collectRewards",
4976
+ args: [key, tokenId]
4977
+ });
4978
+ }
4979
+ function encodeClaimReward(rewardToken, to) {
4980
+ return encodeFunctionData13({
4981
+ abi: farmingCenterAbi,
4982
+ functionName: "claimReward",
4983
+ args: [rewardToken, to, 2n ** 128n - 1n]
4984
+ // max uint128
4985
+ });
4986
+ }
4987
+ function encodeMulticall(calls) {
4988
+ return encodeFunctionData13({
4989
+ abi: farmingCenterAbi,
4990
+ functionName: "multicall",
4991
+ args: [calls]
4992
+ });
4993
+ }
4994
+ var nonceCache = /* @__PURE__ */ new Map();
4995
+ var KittenSwapFarmingAdapter = class {
4996
+ protocolName;
4997
+ farmingCenter;
4998
+ eternalFarming;
4999
+ positionManager;
5000
+ rpcUrl;
5001
+ factory;
5002
+ constructor(protocolName, farmingCenter, eternalFarming, positionManager, rpcUrl, factory) {
5003
+ this.protocolName = protocolName;
5004
+ this.farmingCenter = farmingCenter;
5005
+ this.eternalFarming = eternalFarming;
5006
+ this.positionManager = positionManager;
5007
+ this.rpcUrl = rpcUrl;
5008
+ this.factory = factory;
5009
+ }
5010
+ name() {
5011
+ return this.protocolName;
5012
+ }
5013
+ /**
5014
+ * Discover the active IncentiveKey for a given pool.
5015
+ * 1. Check runtime cache
5016
+ * 2. Batch-query nonces 0-60 via single multicall (61 calls)
5017
+ * 3. Return first non-zero incentive (totalReward > 0 and not deactivated)
5018
+ */
5019
+ async discoverIncentiveKey(pool) {
5020
+ const poolLc = pool.toLowerCase();
5021
+ if (nonceCache.has(poolLc)) {
5022
+ return {
5023
+ rewardToken: KITTEN_TOKEN,
5024
+ bonusRewardToken: WHYPE_TOKEN,
5025
+ pool,
5026
+ nonce: nonceCache.get(poolLc)
5027
+ };
5028
+ }
5029
+ const calls = [];
5030
+ const nonces = [];
5031
+ for (let n = 0; n <= MAX_NONCE_SCAN; n++) {
5032
+ const nonce = BigInt(n);
5033
+ nonces.push(nonce);
5034
+ const key = {
5035
+ rewardToken: KITTEN_TOKEN,
5036
+ bonusRewardToken: WHYPE_TOKEN,
5037
+ pool,
5038
+ nonce
5039
+ };
5040
+ calls.push([
5041
+ this.eternalFarming,
5042
+ encodeFunctionData13({
5043
+ abi: eternalFarmingAbi,
5044
+ functionName: "incentives",
5045
+ args: [incentiveId(key)]
5046
+ })
5047
+ ]);
5048
+ }
5049
+ const results = await multicallRead(this.rpcUrl, calls);
5050
+ for (let i = 0; i < results.length; i++) {
5051
+ const data = results[i];
5052
+ if (!data || data.length < 66) continue;
5053
+ try {
5054
+ const decoded = decodeAbiParameters5(
5055
+ [
5056
+ { name: "totalReward", type: "uint256" },
5057
+ { name: "bonusReward", type: "uint256" },
5058
+ { name: "virtualPoolAddress", type: "address" },
5059
+ { name: "minimalPositionWidth", type: "uint24" },
5060
+ { name: "deactivated", type: "bool" },
5061
+ { name: "pluginAddress", type: "address" }
5062
+ ],
5063
+ data
5064
+ );
5065
+ const totalReward = decoded[0];
5066
+ const deactivated = decoded[4];
5067
+ if (totalReward > 0n && !deactivated) {
5068
+ const nonce = nonces[i];
5069
+ nonceCache.set(poolLc, nonce);
5070
+ return {
5071
+ rewardToken: KITTEN_TOKEN,
5072
+ bonusRewardToken: WHYPE_TOKEN,
5073
+ pool,
5074
+ nonce
5075
+ };
5076
+ }
5077
+ } catch {
5078
+ }
5079
+ }
5080
+ return null;
5081
+ }
5082
+ /**
5083
+ * Build approveForFarming tx on the PositionManager.
5084
+ * Required before enterFarming if not already approved.
5085
+ */
5086
+ async buildApproveForFarming(tokenId) {
5087
+ const client = createPublicClient9({ transport: http9(this.rpcUrl) });
5088
+ const currentApproval = await client.readContract({
5089
+ address: this.positionManager,
5090
+ abi: positionManagerAbi2,
5091
+ functionName: "farmingApprovals",
5092
+ args: [tokenId]
5093
+ });
5094
+ if (currentApproval.toLowerCase() === this.farmingCenter.toLowerCase()) {
5095
+ return null;
5096
+ }
5097
+ return {
5098
+ description: `[${this.protocolName}] Approve NFT #${tokenId} for farming`,
5099
+ to: this.positionManager,
5100
+ data: encodeFunctionData13({
5101
+ abi: positionManagerAbi2,
5102
+ functionName: "approveForFarming",
5103
+ args: [tokenId, true, this.farmingCenter]
5104
+ }),
5105
+ value: 0n,
5106
+ gas_estimate: 6e4
5107
+ };
5108
+ }
5109
+ /**
5110
+ * Build enterFarming tx for a position NFT.
5111
+ * Checks farming approval first and returns pre_txs if needed.
5112
+ */
5113
+ async buildEnterFarming(tokenId, pool, _owner) {
5114
+ const key = await this.discoverIncentiveKey(pool);
5115
+ if (!key) {
5116
+ throw new DefiError(
5117
+ "CONTRACT_ERROR",
5118
+ `[${this.protocolName}] No active incentive found for pool ${pool}`
5119
+ );
5120
+ }
5121
+ const approveTx = await this.buildApproveForFarming(tokenId);
5122
+ return {
5123
+ description: `[${this.protocolName}] Enter farming for NFT #${tokenId} in pool ${pool}`,
5124
+ to: this.farmingCenter,
5125
+ data: encodeEnterFarming(key, tokenId),
5126
+ value: 0n,
5127
+ gas_estimate: 4e5,
5128
+ pre_txs: approveTx ? [approveTx] : void 0
5129
+ };
5130
+ }
5131
+ /**
5132
+ * Build a tx that exits farming for a position NFT (unstakes).
5133
+ */
5134
+ async buildExitFarming(tokenId, pool) {
5135
+ const key = await this.discoverIncentiveKey(pool);
5136
+ if (!key) {
5137
+ throw new DefiError(
5138
+ "CONTRACT_ERROR",
5139
+ `[${this.protocolName}] No active incentive found for pool ${pool}`
5140
+ );
5141
+ }
5142
+ return {
5143
+ description: `[${this.protocolName}] Exit farming for NFT #${tokenId} in pool ${pool}`,
5144
+ to: this.farmingCenter,
5145
+ data: encodeExitFarming(key, tokenId),
5146
+ value: 0n,
5147
+ gas_estimate: 3e5
5148
+ };
5149
+ }
5150
+ /**
5151
+ * Build a multicall tx that collects rewards for a staked position and claims them.
5152
+ * Pattern: multicall([collectRewards(key, tokenId), claimReward(KITTEN, owner, max), claimReward(WHYPE, owner, max)])
5153
+ */
5154
+ async buildCollectRewards(tokenId, pool, owner) {
5155
+ const key = await this.discoverIncentiveKey(pool);
5156
+ if (!key) {
5157
+ throw new DefiError(
5158
+ "CONTRACT_ERROR",
5159
+ `[${this.protocolName}] No active incentive found for pool ${pool}`
5160
+ );
5161
+ }
5162
+ const calls = [
5163
+ encodeCollectRewards(key, tokenId),
5164
+ encodeClaimReward(KITTEN_TOKEN, owner),
5165
+ encodeClaimReward(WHYPE_TOKEN, owner)
5166
+ ];
5167
+ return {
5168
+ description: `[${this.protocolName}] Collect + claim rewards for NFT #${tokenId} in pool ${pool}`,
5169
+ to: this.farmingCenter,
5170
+ data: encodeMulticall(calls),
5171
+ value: 0n,
5172
+ gas_estimate: 4e5
5173
+ };
5174
+ }
5175
+ /**
5176
+ * Build a tx that only claims already-accumulated rewards (no position change needed).
5177
+ */
5178
+ async buildClaimReward(owner) {
5179
+ const calls = [
5180
+ encodeClaimReward(KITTEN_TOKEN, owner),
5181
+ encodeClaimReward(WHYPE_TOKEN, owner)
5182
+ ];
5183
+ return {
5184
+ description: `[${this.protocolName}] Claim KITTEN + WHYPE farming rewards to ${owner}`,
5185
+ to: this.farmingCenter,
5186
+ data: encodeMulticall(calls),
5187
+ value: 0n,
5188
+ gas_estimate: 2e5
5189
+ };
5190
+ }
5191
+ /**
5192
+ * Query pending rewards for a staked position NFT.
5193
+ */
5194
+ async getPendingRewards(tokenId, pool) {
5195
+ const key = await this.discoverIncentiveKey(pool);
5196
+ if (!key) {
5197
+ return { reward: 0n, bonusReward: 0n };
5198
+ }
5199
+ const client = createPublicClient9({ transport: http9(this.rpcUrl) });
5200
+ const result = await client.readContract({
5201
+ address: this.eternalFarming,
5202
+ abi: eternalFarmingAbi,
5203
+ functionName: "getRewardInfo",
5204
+ args: [key, tokenId]
5205
+ });
5206
+ return { reward: result[0], bonusReward: result[1] };
5207
+ }
5208
+ /**
5209
+ * Discover all KittenSwap pools with active farming incentives.
5210
+ *
5211
+ * Steps:
5212
+ * 1. Generate all unique token pair combos from HYPEREVM_TOKENS (includes KITTEN)
5213
+ * 2. Batch poolByPair calls via multicall against the Algebra factory
5214
+ * 3. For each found pool, batch-scan nonces 0-60 via multicall
5215
+ * 4. Return enriched FarmingPool[] for pools with active incentives
5216
+ */
5217
+ async discoverFarmingPools() {
5218
+ if (!this.factory) {
5219
+ return [];
5220
+ }
5221
+ const pairs = [];
5222
+ for (let i = 0; i < HYPEREVM_TOKENS2.length; i++) {
5223
+ for (let j = i + 1; j < HYPEREVM_TOKENS2.length; j++) {
5224
+ pairs.push([HYPEREVM_TOKENS2[i], HYPEREVM_TOKENS2[j]]);
5225
+ }
5226
+ }
5227
+ const poolByPairCalls = pairs.map(([tokenA, tokenB]) => [
5228
+ this.factory,
5229
+ encodeFunctionData13({
5230
+ abi: algebraFactoryAbi,
5231
+ functionName: "poolByPair",
5232
+ args: [tokenA, tokenB]
5233
+ })
5234
+ ]);
5235
+ const poolResults = await multicallRead(this.rpcUrl, poolByPairCalls);
5236
+ const poolSet = /* @__PURE__ */ new Set();
5237
+ for (const data of poolResults) {
5238
+ const addr = decodeAddress3(data);
5239
+ if (addr && addr !== zeroAddress7) {
5240
+ poolSet.add(addr.toLowerCase());
5241
+ }
5242
+ }
5243
+ if (poolSet.size === 0) return [];
5244
+ const pools = Array.from(poolSet);
5245
+ const NONCE_COUNT = MAX_NONCE_SCAN + 1;
5246
+ const allNonceCalls = [];
5247
+ for (const pool of pools) {
5248
+ for (let n = 0; n <= MAX_NONCE_SCAN; n++) {
5249
+ const key = {
5250
+ rewardToken: KITTEN_TOKEN,
5251
+ bonusRewardToken: WHYPE_TOKEN,
5252
+ pool,
5253
+ nonce: BigInt(n)
5254
+ };
5255
+ allNonceCalls.push([
5256
+ this.eternalFarming,
5257
+ encodeFunctionData13({
5258
+ abi: eternalFarmingAbi,
5259
+ functionName: "incentives",
5260
+ args: [incentiveId(key)]
5261
+ })
5262
+ ]);
5263
+ }
5264
+ }
5265
+ const allNonceResults = await multicallRead(this.rpcUrl, allNonceCalls);
5266
+ const results = [];
5267
+ for (let pi = 0; pi < pools.length; pi++) {
5268
+ const pool = pools[pi];
5269
+ const poolLc = pool.toLowerCase();
5270
+ const base = pi * NONCE_COUNT;
5271
+ let bestKey = null;
5272
+ let bestTotalReward = 0n;
5273
+ let bestBonusReward = 0n;
5274
+ let bestActive = false;
5275
+ for (let n = 0; n <= MAX_NONCE_SCAN; n++) {
5276
+ const data = allNonceResults[base + n];
5277
+ if (!data || data.length < 66) continue;
5278
+ try {
5279
+ const decoded = decodeAbiParameters5(
5280
+ [
5281
+ { name: "totalReward", type: "uint256" },
5282
+ { name: "bonusReward", type: "uint256" },
5283
+ { name: "virtualPoolAddress", type: "address" },
5284
+ { name: "minimalPositionWidth", type: "uint24" },
5285
+ { name: "deactivated", type: "bool" },
5286
+ { name: "pluginAddress", type: "address" }
5287
+ ],
5288
+ data
5289
+ );
5290
+ const totalReward = decoded[0];
5291
+ const bonusReward = decoded[1];
5292
+ const deactivated = decoded[4];
5293
+ if (totalReward > 0n) {
5294
+ const nonce = BigInt(n);
5295
+ const isActive = !deactivated;
5296
+ if (!bestKey || isActive && !bestActive || isActive === bestActive && nonce > bestKey.nonce) {
5297
+ bestKey = {
5298
+ rewardToken: KITTEN_TOKEN,
5299
+ bonusRewardToken: WHYPE_TOKEN,
5300
+ pool,
5301
+ nonce
5302
+ };
5303
+ bestTotalReward = totalReward;
5304
+ bestBonusReward = bonusReward;
5305
+ bestActive = isActive;
5306
+ }
5307
+ }
5308
+ } catch {
5309
+ }
5310
+ }
5311
+ if (bestKey) {
5312
+ nonceCache.set(poolLc, bestKey.nonce);
5313
+ results.push({
5314
+ pool,
5315
+ key: bestKey,
5316
+ totalReward: bestTotalReward,
5317
+ bonusReward: bestBonusReward,
5318
+ active: bestActive
5319
+ });
5320
+ }
5321
+ }
5322
+ return results;
5323
+ }
3895
5324
  };
3896
- var POOL_ABI = parseAbi11([
5325
+ var POOL_ABI = parseAbi14([
3897
5326
  "function supply(address asset, uint256 amount, address onBehalfOf, uint16 referralCode) external",
3898
5327
  "function borrow(address asset, uint256 amount, uint256 interestRateMode, uint16 referralCode, address onBehalfOf) external",
3899
5328
  "function repay(address asset, uint256 amount, uint256 interestRateMode, address onBehalfOf) external returns (uint256)",
@@ -3901,27 +5330,27 @@ var POOL_ABI = parseAbi11([
3901
5330
  "function getUserAccountData(address user) external view returns (uint256 totalCollateralBase, uint256 totalDebtBase, uint256 availableBorrowsBase, uint256 currentLiquidationThreshold, uint256 ltv, uint256 healthFactor)",
3902
5331
  "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)"
3903
5332
  ]);
3904
- var ERC20_ABI2 = parseAbi11([
5333
+ var ERC20_ABI2 = parseAbi14([
3905
5334
  "function totalSupply() external view returns (uint256)"
3906
5335
  ]);
3907
- var INCENTIVES_ABI = parseAbi11([
5336
+ var INCENTIVES_ABI = parseAbi14([
3908
5337
  "function getIncentivesController() external view returns (address)"
3909
5338
  ]);
3910
- var REWARDS_CONTROLLER_ABI = parseAbi11([
5339
+ var REWARDS_CONTROLLER_ABI = parseAbi14([
3911
5340
  "function getRewardsByAsset(address asset) external view returns (address[])",
3912
5341
  "function getRewardsData(address asset, address reward) external view returns (uint256 index, uint256 emissionsPerSecond, uint256 lastUpdateTimestamp, uint256 distributionEnd)"
3913
5342
  ]);
3914
- var POOL_PROVIDER_ABI = parseAbi11([
5343
+ var POOL_PROVIDER_ABI = parseAbi14([
3915
5344
  "function ADDRESSES_PROVIDER() external view returns (address)"
3916
5345
  ]);
3917
- var ADDRESSES_PROVIDER_ABI = parseAbi11([
5346
+ var ADDRESSES_PROVIDER_ABI = parseAbi14([
3918
5347
  "function getPriceOracle() external view returns (address)"
3919
5348
  ]);
3920
- var ORACLE_ABI = parseAbi11([
5349
+ var ORACLE_ABI = parseAbi14([
3921
5350
  "function getAssetPrice(address asset) external view returns (uint256)",
3922
5351
  "function BASE_CURRENCY_UNIT() external view returns (uint256)"
3923
5352
  ]);
3924
- var ERC20_DECIMALS_ABI = parseAbi11([
5353
+ var ERC20_DECIMALS_ABI = parseAbi14([
3925
5354
  "function decimals() external view returns (uint8)"
3926
5355
  ]);
3927
5356
  function u256ToF64(v) {
@@ -3929,14 +5358,14 @@ function u256ToF64(v) {
3929
5358
  if (v > MAX_U128) return Infinity;
3930
5359
  return Number(v);
3931
5360
  }
3932
- function decodeAddress(data) {
5361
+ function decodeAddress4(data) {
3933
5362
  if (!data || data.length < 66) return null;
3934
5363
  return `0x${data.slice(26, 66)}`;
3935
5364
  }
3936
5365
  function decodeAddressArray(data) {
3937
5366
  if (!data) return [];
3938
5367
  try {
3939
- return decodeFunctionResult3({
5368
+ return decodeFunctionResult6({
3940
5369
  abi: REWARDS_CONTROLLER_ABI,
3941
5370
  functionName: "getRewardsByAsset",
3942
5371
  data
@@ -3948,7 +5377,7 @@ function decodeAddressArray(data) {
3948
5377
  function decodeReserveData(data) {
3949
5378
  if (!data) return null;
3950
5379
  try {
3951
- return decodeFunctionResult3({
5380
+ return decodeFunctionResult6({
3952
5381
  abi: POOL_ABI,
3953
5382
  functionName: "getReserveData",
3954
5383
  data
@@ -3960,7 +5389,7 @@ function decodeReserveData(data) {
3960
5389
  function decodeRewardsData(data) {
3961
5390
  if (!data) return null;
3962
5391
  try {
3963
- return decodeFunctionResult3({
5392
+ return decodeFunctionResult6({
3964
5393
  abi: REWARDS_CONTROLLER_ABI,
3965
5394
  functionName: "getRewardsData",
3966
5395
  data
@@ -3984,7 +5413,7 @@ var AaveV3Adapter = class {
3984
5413
  return this.protocolName;
3985
5414
  }
3986
5415
  async buildSupply(params) {
3987
- const data = encodeFunctionData11({
5416
+ const data = encodeFunctionData14({
3988
5417
  abi: POOL_ABI,
3989
5418
  functionName: "supply",
3990
5419
  args: [params.asset, params.amount, params.on_behalf_of, 0]
@@ -4000,7 +5429,7 @@ var AaveV3Adapter = class {
4000
5429
  }
4001
5430
  async buildBorrow(params) {
4002
5431
  const rateMode = params.interest_rate_mode === InterestRateMode.Stable ? 1n : 2n;
4003
- const data = encodeFunctionData11({
5432
+ const data = encodeFunctionData14({
4004
5433
  abi: POOL_ABI,
4005
5434
  functionName: "borrow",
4006
5435
  args: [params.asset, params.amount, rateMode, 0, params.on_behalf_of]
@@ -4015,7 +5444,7 @@ var AaveV3Adapter = class {
4015
5444
  }
4016
5445
  async buildRepay(params) {
4017
5446
  const rateMode = params.interest_rate_mode === InterestRateMode.Stable ? 1n : 2n;
4018
- const data = encodeFunctionData11({
5447
+ const data = encodeFunctionData14({
4019
5448
  abi: POOL_ABI,
4020
5449
  functionName: "repay",
4021
5450
  args: [params.asset, params.amount, rateMode, params.on_behalf_of]
@@ -4030,7 +5459,7 @@ var AaveV3Adapter = class {
4030
5459
  };
4031
5460
  }
4032
5461
  async buildWithdraw(params) {
4033
- const data = encodeFunctionData11({
5462
+ const data = encodeFunctionData14({
4034
5463
  abi: POOL_ABI,
4035
5464
  functionName: "withdraw",
4036
5465
  args: [params.asset, params.amount, params.to]
@@ -4045,7 +5474,7 @@ var AaveV3Adapter = class {
4045
5474
  }
4046
5475
  async getRates(asset) {
4047
5476
  if (!this.rpcUrl) throw DefiError.rpcError("No RPC URL configured");
4048
- const reserveCallData = encodeFunctionData11({
5477
+ const reserveCallData = encodeFunctionData14({
4049
5478
  abi: POOL_ABI,
4050
5479
  functionName: "getReserveData",
4051
5480
  args: [asset]
@@ -4072,8 +5501,8 @@ var AaveV3Adapter = class {
4072
5501
  const aTokenAddress = result[8];
4073
5502
  const variableDebtTokenAddress = result[10];
4074
5503
  const [supplyRaw, borrowRaw] = await multicallRead(this.rpcUrl, [
4075
- [aTokenAddress, encodeFunctionData11({ abi: ERC20_ABI2, functionName: "totalSupply" })],
4076
- [variableDebtTokenAddress, encodeFunctionData11({ abi: ERC20_ABI2, functionName: "totalSupply" })]
5504
+ [aTokenAddress, encodeFunctionData14({ abi: ERC20_ABI2, functionName: "totalSupply" })],
5505
+ [variableDebtTokenAddress, encodeFunctionData14({ abi: ERC20_ABI2, functionName: "totalSupply" })]
4077
5506
  ]);
4078
5507
  const totalSupply = decodeU256(supplyRaw ?? null);
4079
5508
  const totalBorrow = decodeU256(borrowRaw ?? null);
@@ -4084,24 +5513,24 @@ var AaveV3Adapter = class {
4084
5513
  const borrowEmissions = [];
4085
5514
  try {
4086
5515
  const [controllerRaw] = await multicallRead(this.rpcUrl, [
4087
- [aTokenAddress, encodeFunctionData11({ abi: INCENTIVES_ABI, functionName: "getIncentivesController" })]
5516
+ [aTokenAddress, encodeFunctionData14({ abi: INCENTIVES_ABI, functionName: "getIncentivesController" })]
4088
5517
  ]);
4089
- const controllerAddr = decodeAddress(controllerRaw ?? null);
4090
- if (controllerAddr && controllerAddr !== zeroAddress5) {
5518
+ const controllerAddr = decodeAddress4(controllerRaw ?? null);
5519
+ if (controllerAddr && controllerAddr !== zeroAddress8) {
4091
5520
  const [supplyRewardsRaw, borrowRewardsRaw] = await multicallRead(this.rpcUrl, [
4092
- [controllerAddr, encodeFunctionData11({ abi: REWARDS_CONTROLLER_ABI, functionName: "getRewardsByAsset", args: [aTokenAddress] })],
4093
- [controllerAddr, encodeFunctionData11({ abi: REWARDS_CONTROLLER_ABI, functionName: "getRewardsByAsset", args: [variableDebtTokenAddress] })]
5521
+ [controllerAddr, encodeFunctionData14({ abi: REWARDS_CONTROLLER_ABI, functionName: "getRewardsByAsset", args: [aTokenAddress] })],
5522
+ [controllerAddr, encodeFunctionData14({ abi: REWARDS_CONTROLLER_ABI, functionName: "getRewardsByAsset", args: [variableDebtTokenAddress] })]
4094
5523
  ]);
4095
5524
  const supplyRewards = decodeAddressArray(supplyRewardsRaw ?? null);
4096
5525
  const borrowRewards = decodeAddressArray(borrowRewardsRaw ?? null);
4097
5526
  const rewardsDataCalls = [
4098
5527
  ...supplyRewards.map((reward) => [
4099
5528
  controllerAddr,
4100
- encodeFunctionData11({ abi: REWARDS_CONTROLLER_ABI, functionName: "getRewardsData", args: [aTokenAddress, reward] })
5529
+ encodeFunctionData14({ abi: REWARDS_CONTROLLER_ABI, functionName: "getRewardsData", args: [aTokenAddress, reward] })
4101
5530
  ]),
4102
5531
  ...borrowRewards.map((reward) => [
4103
5532
  controllerAddr,
4104
- encodeFunctionData11({ abi: REWARDS_CONTROLLER_ABI, functionName: "getRewardsData", args: [variableDebtTokenAddress, reward] })
5533
+ encodeFunctionData14({ abi: REWARDS_CONTROLLER_ABI, functionName: "getRewardsData", args: [variableDebtTokenAddress, reward] })
4105
5534
  ])
4106
5535
  ];
4107
5536
  if (rewardsDataCalls.length > 0) {
@@ -4133,19 +5562,19 @@ var AaveV3Adapter = class {
4133
5562
  if ((hasSupplyRewards || hasBorrowRewards) && totalSupply > 0n) {
4134
5563
  try {
4135
5564
  const [providerRaw] = await multicallRead(this.rpcUrl, [
4136
- [this.pool, encodeFunctionData11({ abi: POOL_PROVIDER_ABI, functionName: "ADDRESSES_PROVIDER" })]
5565
+ [this.pool, encodeFunctionData14({ abi: POOL_PROVIDER_ABI, functionName: "ADDRESSES_PROVIDER" })]
4137
5566
  ]);
4138
- const providerAddr = decodeAddress(providerRaw ?? null);
5567
+ const providerAddr = decodeAddress4(providerRaw ?? null);
4139
5568
  if (!providerAddr) throw new Error("No provider address");
4140
5569
  const [oracleRaw] = await multicallRead(this.rpcUrl, [
4141
- [providerAddr, encodeFunctionData11({ abi: ADDRESSES_PROVIDER_ABI, functionName: "getPriceOracle" })]
5570
+ [providerAddr, encodeFunctionData14({ abi: ADDRESSES_PROVIDER_ABI, functionName: "getPriceOracle" })]
4142
5571
  ]);
4143
- const oracleAddr = decodeAddress(oracleRaw ?? null);
5572
+ const oracleAddr = decodeAddress4(oracleRaw ?? null);
4144
5573
  if (!oracleAddr) throw new Error("No oracle address");
4145
5574
  const [assetPriceRaw, baseCurrencyUnitRaw, assetDecimalsRaw] = await multicallRead(this.rpcUrl, [
4146
- [oracleAddr, encodeFunctionData11({ abi: ORACLE_ABI, functionName: "getAssetPrice", args: [asset] })],
4147
- [oracleAddr, encodeFunctionData11({ abi: ORACLE_ABI, functionName: "BASE_CURRENCY_UNIT" })],
4148
- [asset, encodeFunctionData11({ abi: ERC20_DECIMALS_ABI, functionName: "decimals" })]
5575
+ [oracleAddr, encodeFunctionData14({ abi: ORACLE_ABI, functionName: "getAssetPrice", args: [asset] })],
5576
+ [oracleAddr, encodeFunctionData14({ abi: ORACLE_ABI, functionName: "BASE_CURRENCY_UNIT" })],
5577
+ [asset, encodeFunctionData14({ abi: ERC20_DECIMALS_ABI, functionName: "decimals" })]
4149
5578
  ]);
4150
5579
  const assetPrice = decodeU256(assetPriceRaw ?? null);
4151
5580
  const baseCurrencyUnit = decodeU256(baseCurrencyUnitRaw ?? null);
@@ -4155,8 +5584,8 @@ var AaveV3Adapter = class {
4155
5584
  const assetDecimalsDivisor = 10 ** assetDecimals;
4156
5585
  const allRewardTokens = Array.from(/* @__PURE__ */ new Set([...supplyRewardTokens, ...borrowRewardTokens]));
4157
5586
  const rewardPriceCalls = allRewardTokens.flatMap((token) => [
4158
- [oracleAddr, encodeFunctionData11({ abi: ORACLE_ABI, functionName: "getAssetPrice", args: [token] })],
4159
- [token, encodeFunctionData11({ abi: ERC20_DECIMALS_ABI, functionName: "decimals" })]
5587
+ [oracleAddr, encodeFunctionData14({ abi: ORACLE_ABI, functionName: "getAssetPrice", args: [token] })],
5588
+ [token, encodeFunctionData14({ abi: ERC20_DECIMALS_ABI, functionName: "decimals" })]
4160
5589
  ]);
4161
5590
  const rewardPriceResults = rewardPriceCalls.length > 0 ? await multicallRead(this.rpcUrl, rewardPriceCalls) : [];
4162
5591
  const rewardPriceMap = /* @__PURE__ */ new Map();
@@ -4229,7 +5658,7 @@ var AaveV3Adapter = class {
4229
5658
  }
4230
5659
  async getUserPosition(user) {
4231
5660
  if (!this.rpcUrl) throw DefiError.rpcError("No RPC URL configured");
4232
- const client = createPublicClient7({ transport: http7(this.rpcUrl) });
5661
+ const client = createPublicClient10({ transport: http10(this.rpcUrl) });
4233
5662
  const result = await client.readContract({
4234
5663
  address: this.pool,
4235
5664
  abi: POOL_ABI,
@@ -4244,8 +5673,8 @@ var AaveV3Adapter = class {
4244
5673
  const collateralUsd = u256ToF64(totalCollateralBase) / 1e8;
4245
5674
  const debtUsd = u256ToF64(totalDebtBase) / 1e8;
4246
5675
  const ltvBps = u256ToF64(ltv);
4247
- const supplies = collateralUsd > 0 ? [{ asset: zeroAddress5, symbol: "Total Collateral", amount: totalCollateralBase, value_usd: collateralUsd }] : [];
4248
- const borrows = debtUsd > 0 ? [{ asset: zeroAddress5, symbol: "Total Debt", amount: totalDebtBase, value_usd: debtUsd }] : [];
5676
+ const supplies = collateralUsd > 0 ? [{ asset: zeroAddress8, symbol: "Total Collateral", amount: totalCollateralBase, value_usd: collateralUsd }] : [];
5677
+ const borrows = debtUsd > 0 ? [{ asset: zeroAddress8, symbol: "Total Debt", amount: totalDebtBase, value_usd: debtUsd }] : [];
4249
5678
  return {
4250
5679
  protocol: this.protocolName,
4251
5680
  user,
@@ -4256,7 +5685,7 @@ var AaveV3Adapter = class {
4256
5685
  };
4257
5686
  }
4258
5687
  };
4259
- var POOL_ABI2 = parseAbi12([
5688
+ var POOL_ABI2 = parseAbi15([
4260
5689
  "function deposit(address asset, uint256 amount, address onBehalfOf, uint16 referralCode) external",
4261
5690
  "function borrow(address asset, uint256 amount, uint256 interestRateMode, uint16 referralCode, address onBehalfOf) external",
4262
5691
  "function repay(address asset, uint256 amount, uint256 rateMode, address onBehalfOf) external returns (uint256)",
@@ -4269,7 +5698,7 @@ var POOL_ABI2 = parseAbi12([
4269
5698
  // [9]=variableDebtTokenAddress, [10]=interestRateStrategyAddress, [11]=id
4270
5699
  "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)"
4271
5700
  ]);
4272
- var ERC20_ABI22 = parseAbi12([
5701
+ var ERC20_ABI22 = parseAbi15([
4273
5702
  "function totalSupply() external view returns (uint256)"
4274
5703
  ]);
4275
5704
  function u256ToF642(v) {
@@ -4292,7 +5721,7 @@ var AaveV2Adapter = class {
4292
5721
  return this.protocolName;
4293
5722
  }
4294
5723
  async buildSupply(params) {
4295
- const data = encodeFunctionData12({
5724
+ const data = encodeFunctionData15({
4296
5725
  abi: POOL_ABI2,
4297
5726
  functionName: "deposit",
4298
5727
  args: [params.asset, params.amount, params.on_behalf_of, 0]
@@ -4308,7 +5737,7 @@ var AaveV2Adapter = class {
4308
5737
  }
4309
5738
  async buildBorrow(params) {
4310
5739
  const rateMode = params.interest_rate_mode === InterestRateMode.Stable ? 1n : 2n;
4311
- const data = encodeFunctionData12({
5740
+ const data = encodeFunctionData15({
4312
5741
  abi: POOL_ABI2,
4313
5742
  functionName: "borrow",
4314
5743
  args: [params.asset, params.amount, rateMode, 0, params.on_behalf_of]
@@ -4323,7 +5752,7 @@ var AaveV2Adapter = class {
4323
5752
  }
4324
5753
  async buildRepay(params) {
4325
5754
  const rateMode = params.interest_rate_mode === InterestRateMode.Stable ? 1n : 2n;
4326
- const data = encodeFunctionData12({
5755
+ const data = encodeFunctionData15({
4327
5756
  abi: POOL_ABI2,
4328
5757
  functionName: "repay",
4329
5758
  args: [params.asset, params.amount, rateMode, params.on_behalf_of]
@@ -4338,7 +5767,7 @@ var AaveV2Adapter = class {
4338
5767
  };
4339
5768
  }
4340
5769
  async buildWithdraw(params) {
4341
- const data = encodeFunctionData12({
5770
+ const data = encodeFunctionData15({
4342
5771
  abi: POOL_ABI2,
4343
5772
  functionName: "withdraw",
4344
5773
  args: [params.asset, params.amount, params.to]
@@ -4353,7 +5782,7 @@ var AaveV2Adapter = class {
4353
5782
  }
4354
5783
  async getRates(asset) {
4355
5784
  if (!this.rpcUrl) throw DefiError.rpcError("No RPC URL configured");
4356
- const client = createPublicClient8({ transport: http8(this.rpcUrl) });
5785
+ const client = createPublicClient11({ transport: http11(this.rpcUrl) });
4357
5786
  const result = await client.readContract({
4358
5787
  address: this.pool,
4359
5788
  abi: POOL_ABI2,
@@ -4399,7 +5828,7 @@ var AaveV2Adapter = class {
4399
5828
  }
4400
5829
  async getUserPosition(user) {
4401
5830
  if (!this.rpcUrl) throw DefiError.rpcError("No RPC URL configured");
4402
- const client = createPublicClient8({ transport: http8(this.rpcUrl) });
5831
+ const client = createPublicClient11({ transport: http11(this.rpcUrl) });
4403
5832
  const result = await client.readContract({
4404
5833
  address: this.pool,
4405
5834
  abi: POOL_ABI2,
@@ -4414,8 +5843,8 @@ var AaveV2Adapter = class {
4414
5843
  const collateralUsd = u256ToF642(totalCollateralBase) / 1e18;
4415
5844
  const debtUsd = u256ToF642(totalDebtBase) / 1e18;
4416
5845
  const ltvBps = u256ToF642(ltv);
4417
- const supplies = collateralUsd > 0 ? [{ asset: zeroAddress6, symbol: "Total Collateral", amount: totalCollateralBase, value_usd: collateralUsd }] : [];
4418
- const borrows = debtUsd > 0 ? [{ asset: zeroAddress6, symbol: "Total Debt", amount: totalDebtBase, value_usd: debtUsd }] : [];
5846
+ const supplies = collateralUsd > 0 ? [{ asset: zeroAddress9, symbol: "Total Collateral", amount: totalCollateralBase, value_usd: collateralUsd }] : [];
5847
+ const borrows = debtUsd > 0 ? [{ asset: zeroAddress9, symbol: "Total Debt", amount: totalDebtBase, value_usd: debtUsd }] : [];
4419
5848
  return {
4420
5849
  protocol: this.protocolName,
4421
5850
  user,
@@ -4426,7 +5855,7 @@ var AaveV2Adapter = class {
4426
5855
  };
4427
5856
  }
4428
5857
  };
4429
- var ORACLE_ABI2 = parseAbi13([
5858
+ var ORACLE_ABI2 = parseAbi16([
4430
5859
  "function getAssetPrice(address asset) external view returns (uint256)",
4431
5860
  "function getAssetsPrices(address[] calldata assets) external view returns (uint256[] memory)",
4432
5861
  "function BASE_CURRENCY_UNIT() external view returns (uint256)"
@@ -4447,7 +5876,7 @@ var AaveOracleAdapter = class {
4447
5876
  return this.protocolName;
4448
5877
  }
4449
5878
  async getPrice(asset) {
4450
- const client = createPublicClient9({ transport: http9(this.rpcUrl) });
5879
+ const client = createPublicClient12({ transport: http12(this.rpcUrl) });
4451
5880
  const baseUnit = await client.readContract({
4452
5881
  address: this.oracle,
4453
5882
  abi: ORACLE_ABI2,
@@ -4474,7 +5903,7 @@ var AaveOracleAdapter = class {
4474
5903
  };
4475
5904
  }
4476
5905
  async getPrices(assets) {
4477
- const client = createPublicClient9({ transport: http9(this.rpcUrl) });
5906
+ const client = createPublicClient12({ transport: http12(this.rpcUrl) });
4478
5907
  const baseUnit = await client.readContract({
4479
5908
  address: this.oracle,
4480
5909
  abi: ORACLE_ABI2,
@@ -4503,7 +5932,7 @@ var AaveOracleAdapter = class {
4503
5932
  });
4504
5933
  }
4505
5934
  };
4506
- var CTOKEN_ABI = parseAbi14([
5935
+ var CTOKEN_ABI = parseAbi17([
4507
5936
  "function supplyRatePerBlock() external view returns (uint256)",
4508
5937
  "function borrowRatePerBlock() external view returns (uint256)",
4509
5938
  "function totalSupply() external view returns (uint256)",
@@ -4530,7 +5959,7 @@ var CompoundV2Adapter = class {
4530
5959
  return this.protocolName;
4531
5960
  }
4532
5961
  async buildSupply(params) {
4533
- const data = encodeFunctionData13({
5962
+ const data = encodeFunctionData16({
4534
5963
  abi: CTOKEN_ABI,
4535
5964
  functionName: "mint",
4536
5965
  args: [params.amount]
@@ -4544,7 +5973,7 @@ var CompoundV2Adapter = class {
4544
5973
  };
4545
5974
  }
4546
5975
  async buildBorrow(params) {
4547
- const data = encodeFunctionData13({
5976
+ const data = encodeFunctionData16({
4548
5977
  abi: CTOKEN_ABI,
4549
5978
  functionName: "borrow",
4550
5979
  args: [params.amount]
@@ -4558,7 +5987,7 @@ var CompoundV2Adapter = class {
4558
5987
  };
4559
5988
  }
4560
5989
  async buildRepay(params) {
4561
- const data = encodeFunctionData13({
5990
+ const data = encodeFunctionData16({
4562
5991
  abi: CTOKEN_ABI,
4563
5992
  functionName: "repayBorrow",
4564
5993
  args: [params.amount]
@@ -4572,7 +6001,7 @@ var CompoundV2Adapter = class {
4572
6001
  };
4573
6002
  }
4574
6003
  async buildWithdraw(params) {
4575
- const data = encodeFunctionData13({
6004
+ const data = encodeFunctionData16({
4576
6005
  abi: CTOKEN_ABI,
4577
6006
  functionName: "redeem",
4578
6007
  args: [params.amount]
@@ -4587,7 +6016,7 @@ var CompoundV2Adapter = class {
4587
6016
  }
4588
6017
  async getRates(asset) {
4589
6018
  if (!this.rpcUrl) throw DefiError.rpcError("No RPC URL configured");
4590
- const client = createPublicClient10({ transport: http10(this.rpcUrl) });
6019
+ const client = createPublicClient13({ transport: http13(this.rpcUrl) });
4591
6020
  const [supplyRate, borrowRate, totalSupply, totalBorrows] = await Promise.all([
4592
6021
  client.readContract({ address: this.defaultVtoken, abi: CTOKEN_ABI, functionName: "supplyRatePerBlock" }).catch((e) => {
4593
6022
  throw DefiError.rpcError(`[${this.protocolName}] supplyRatePerBlock failed: ${e}`);
@@ -4621,7 +6050,7 @@ var CompoundV2Adapter = class {
4621
6050
  );
4622
6051
  }
4623
6052
  };
4624
- var COMET_ABI = parseAbi15([
6053
+ var COMET_ABI = parseAbi18([
4625
6054
  "function getUtilization() external view returns (uint256)",
4626
6055
  "function getSupplyRate(uint256 utilization) external view returns (uint64)",
4627
6056
  "function getBorrowRate(uint256 utilization) external view returns (uint64)",
@@ -4647,7 +6076,7 @@ var CompoundV3Adapter = class {
4647
6076
  return this.protocolName;
4648
6077
  }
4649
6078
  async buildSupply(params) {
4650
- const data = encodeFunctionData14({
6079
+ const data = encodeFunctionData17({
4651
6080
  abi: COMET_ABI,
4652
6081
  functionName: "supply",
4653
6082
  args: [params.asset, params.amount]
@@ -4661,7 +6090,7 @@ var CompoundV3Adapter = class {
4661
6090
  };
4662
6091
  }
4663
6092
  async buildBorrow(params) {
4664
- const data = encodeFunctionData14({
6093
+ const data = encodeFunctionData17({
4665
6094
  abi: COMET_ABI,
4666
6095
  functionName: "withdraw",
4667
6096
  args: [params.asset, params.amount]
@@ -4675,7 +6104,7 @@ var CompoundV3Adapter = class {
4675
6104
  };
4676
6105
  }
4677
6106
  async buildRepay(params) {
4678
- const data = encodeFunctionData14({
6107
+ const data = encodeFunctionData17({
4679
6108
  abi: COMET_ABI,
4680
6109
  functionName: "supply",
4681
6110
  args: [params.asset, params.amount]
@@ -4689,7 +6118,7 @@ var CompoundV3Adapter = class {
4689
6118
  };
4690
6119
  }
4691
6120
  async buildWithdraw(params) {
4692
- const data = encodeFunctionData14({
6121
+ const data = encodeFunctionData17({
4693
6122
  abi: COMET_ABI,
4694
6123
  functionName: "withdraw",
4695
6124
  args: [params.asset, params.amount]
@@ -4704,7 +6133,7 @@ var CompoundV3Adapter = class {
4704
6133
  }
4705
6134
  async getRates(asset) {
4706
6135
  if (!this.rpcUrl) throw DefiError.rpcError("No RPC URL configured");
4707
- const client = createPublicClient11({ transport: http11(this.rpcUrl) });
6136
+ const client = createPublicClient14({ transport: http14(this.rpcUrl) });
4708
6137
  const utilization = await client.readContract({
4709
6138
  address: this.comet,
4710
6139
  abi: COMET_ABI,
@@ -4743,7 +6172,7 @@ var CompoundV3Adapter = class {
4743
6172
  );
4744
6173
  }
4745
6174
  };
4746
- var EULER_VAULT_ABI = parseAbi16([
6175
+ var EULER_VAULT_ABI = parseAbi19([
4747
6176
  "function deposit(uint256 amount, address receiver) external returns (uint256)",
4748
6177
  "function withdraw(uint256 amount, address receiver, address owner) external returns (uint256)",
4749
6178
  "function borrow(uint256 amount, address receiver) external returns (uint256)",
@@ -4769,7 +6198,7 @@ var EulerV2Adapter = class {
4769
6198
  return this.protocolName;
4770
6199
  }
4771
6200
  async buildSupply(params) {
4772
- const data = encodeFunctionData15({
6201
+ const data = encodeFunctionData18({
4773
6202
  abi: EULER_VAULT_ABI,
4774
6203
  functionName: "deposit",
4775
6204
  args: [params.amount, params.on_behalf_of]
@@ -4783,7 +6212,7 @@ var EulerV2Adapter = class {
4783
6212
  };
4784
6213
  }
4785
6214
  async buildBorrow(params) {
4786
- const data = encodeFunctionData15({
6215
+ const data = encodeFunctionData18({
4787
6216
  abi: EULER_VAULT_ABI,
4788
6217
  functionName: "borrow",
4789
6218
  args: [params.amount, params.on_behalf_of]
@@ -4797,7 +6226,7 @@ var EulerV2Adapter = class {
4797
6226
  };
4798
6227
  }
4799
6228
  async buildRepay(params) {
4800
- const data = encodeFunctionData15({
6229
+ const data = encodeFunctionData18({
4801
6230
  abi: EULER_VAULT_ABI,
4802
6231
  functionName: "repay",
4803
6232
  args: [params.amount, params.on_behalf_of]
@@ -4811,7 +6240,7 @@ var EulerV2Adapter = class {
4811
6240
  };
4812
6241
  }
4813
6242
  async buildWithdraw(params) {
4814
- const data = encodeFunctionData15({
6243
+ const data = encodeFunctionData18({
4815
6244
  abi: EULER_VAULT_ABI,
4816
6245
  functionName: "withdraw",
4817
6246
  args: [params.amount, params.to, params.to]
@@ -4826,7 +6255,7 @@ var EulerV2Adapter = class {
4826
6255
  }
4827
6256
  async getRates(asset) {
4828
6257
  if (!this.rpcUrl) throw DefiError.rpcError("No RPC URL configured");
4829
- const client = createPublicClient12({ transport: http12(this.rpcUrl) });
6258
+ const client = createPublicClient15({ transport: http15(this.rpcUrl) });
4830
6259
  const [totalSupply, totalBorrows, interestRate] = await Promise.all([
4831
6260
  client.readContract({ address: this.euler, abi: EULER_VAULT_ABI, functionName: "totalSupply" }).catch((e) => {
4832
6261
  throw DefiError.rpcError(`[${this.protocolName}] totalSupply failed: ${e}`);
@@ -4860,7 +6289,7 @@ var EulerV2Adapter = class {
4860
6289
  );
4861
6290
  }
4862
6291
  };
4863
- var MORPHO_ABI = parseAbi17([
6292
+ var MORPHO_ABI = parseAbi20([
4864
6293
  "function market(bytes32 id) external view returns (uint128 totalSupplyAssets, uint128 totalSupplyShares, uint128 totalBorrowAssets, uint128 totalBorrowShares, uint128 lastUpdate, uint128 fee)",
4865
6294
  "function idToMarketParams(bytes32 id) external view returns (address loanToken, address collateralToken, address oracle, address irm, uint256 lltv)",
4866
6295
  "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)",
@@ -4868,29 +6297,29 @@ var MORPHO_ABI = parseAbi17([
4868
6297
  "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)",
4869
6298
  "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)"
4870
6299
  ]);
4871
- var META_MORPHO_ABI = parseAbi17([
6300
+ var META_MORPHO_ABI = parseAbi20([
4872
6301
  "function supplyQueueLength() external view returns (uint256)",
4873
6302
  "function supplyQueue(uint256 index) external view returns (bytes32)",
4874
6303
  "function totalAssets() external view returns (uint256)",
4875
6304
  "function totalSupply() external view returns (uint256)"
4876
6305
  ]);
4877
- var IRM_ABI = parseAbi17([
6306
+ var IRM_ABI = parseAbi20([
4878
6307
  "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)"
4879
6308
  ]);
4880
6309
  var SECONDS_PER_YEAR3 = 365.25 * 24 * 3600;
4881
- function defaultMarketParams(loanToken = zeroAddress7) {
6310
+ function defaultMarketParams(loanToken = zeroAddress10) {
4882
6311
  return {
4883
6312
  loanToken,
4884
- collateralToken: zeroAddress7,
4885
- oracle: zeroAddress7,
4886
- irm: zeroAddress7,
6313
+ collateralToken: zeroAddress10,
6314
+ oracle: zeroAddress10,
6315
+ irm: zeroAddress10,
4887
6316
  lltv: 0n
4888
6317
  };
4889
6318
  }
4890
6319
  function decodeMarket(data) {
4891
6320
  if (!data) return null;
4892
6321
  try {
4893
- return decodeFunctionResult4({
6322
+ return decodeFunctionResult7({
4894
6323
  abi: MORPHO_ABI,
4895
6324
  functionName: "market",
4896
6325
  data
@@ -4902,7 +6331,7 @@ function decodeMarket(data) {
4902
6331
  function decodeMarketParams(data) {
4903
6332
  if (!data) return null;
4904
6333
  try {
4905
- return decodeFunctionResult4({
6334
+ return decodeFunctionResult7({
4906
6335
  abi: MORPHO_ABI,
4907
6336
  functionName: "idToMarketParams",
4908
6337
  data
@@ -4930,7 +6359,7 @@ var MorphoBlueAdapter = class {
4930
6359
  }
4931
6360
  async buildSupply(params) {
4932
6361
  const market = defaultMarketParams(params.asset);
4933
- const data = encodeFunctionData16({
6362
+ const data = encodeFunctionData19({
4934
6363
  abi: MORPHO_ABI,
4935
6364
  functionName: "supply",
4936
6365
  args: [market, params.amount, 0n, params.on_behalf_of, "0x"]
@@ -4945,7 +6374,7 @@ var MorphoBlueAdapter = class {
4945
6374
  }
4946
6375
  async buildBorrow(params) {
4947
6376
  const market = defaultMarketParams(params.asset);
4948
- const data = encodeFunctionData16({
6377
+ const data = encodeFunctionData19({
4949
6378
  abi: MORPHO_ABI,
4950
6379
  functionName: "borrow",
4951
6380
  args: [market, params.amount, 0n, params.on_behalf_of, params.on_behalf_of]
@@ -4960,7 +6389,7 @@ var MorphoBlueAdapter = class {
4960
6389
  }
4961
6390
  async buildRepay(params) {
4962
6391
  const market = defaultMarketParams(params.asset);
4963
- const data = encodeFunctionData16({
6392
+ const data = encodeFunctionData19({
4964
6393
  abi: MORPHO_ABI,
4965
6394
  functionName: "repay",
4966
6395
  args: [market, params.amount, 0n, params.on_behalf_of, "0x"]
@@ -4975,7 +6404,7 @@ var MorphoBlueAdapter = class {
4975
6404
  }
4976
6405
  async buildWithdraw(params) {
4977
6406
  const market = defaultMarketParams(params.asset);
4978
- const data = encodeFunctionData16({
6407
+ const data = encodeFunctionData19({
4979
6408
  abi: MORPHO_ABI,
4980
6409
  functionName: "withdraw",
4981
6410
  args: [market, params.amount, 0n, params.to, params.to]
@@ -4994,7 +6423,7 @@ var MorphoBlueAdapter = class {
4994
6423
  throw DefiError.contractError(`[${this.protocolName}] No MetaMorpho vault configured for rate query`);
4995
6424
  }
4996
6425
  const [queueLenRaw] = await multicallRead(this.rpcUrl, [
4997
- [this.defaultVault, encodeFunctionData16({ abi: META_MORPHO_ABI, functionName: "supplyQueueLength" })]
6426
+ [this.defaultVault, encodeFunctionData19({ abi: META_MORPHO_ABI, functionName: "supplyQueueLength" })]
4998
6427
  ]).catch((e) => {
4999
6428
  throw DefiError.rpcError(`[${this.protocolName}] supplyQueueLength failed: ${e}`);
5000
6429
  });
@@ -5011,7 +6440,7 @@ var MorphoBlueAdapter = class {
5011
6440
  };
5012
6441
  }
5013
6442
  const [marketIdRaw] = await multicallRead(this.rpcUrl, [
5014
- [this.defaultVault, encodeFunctionData16({ abi: META_MORPHO_ABI, functionName: "supplyQueue", args: [0n] })]
6443
+ [this.defaultVault, encodeFunctionData19({ abi: META_MORPHO_ABI, functionName: "supplyQueue", args: [0n] })]
5015
6444
  ]).catch((e) => {
5016
6445
  throw DefiError.rpcError(`[${this.protocolName}] supplyQueue(0) failed: ${e}`);
5017
6446
  });
@@ -5020,8 +6449,8 @@ var MorphoBlueAdapter = class {
5020
6449
  }
5021
6450
  const marketId = marketIdRaw.slice(0, 66);
5022
6451
  const [marketRaw, paramsRaw] = await multicallRead(this.rpcUrl, [
5023
- [this.morpho, encodeFunctionData16({ abi: MORPHO_ABI, functionName: "market", args: [marketId] })],
5024
- [this.morpho, encodeFunctionData16({ abi: MORPHO_ABI, functionName: "idToMarketParams", args: [marketId] })]
6452
+ [this.morpho, encodeFunctionData19({ abi: MORPHO_ABI, functionName: "market", args: [marketId] })],
6453
+ [this.morpho, encodeFunctionData19({ abi: MORPHO_ABI, functionName: "idToMarketParams", args: [marketId] })]
5025
6454
  ]).catch((e) => {
5026
6455
  throw DefiError.rpcError(`[${this.protocolName}] market/idToMarketParams failed: ${e}`);
5027
6456
  });
@@ -5038,7 +6467,7 @@ var MorphoBlueAdapter = class {
5038
6467
  const irmMarket = { totalSupplyAssets, totalSupplyShares, totalBorrowAssets, totalBorrowShares, lastUpdate, fee };
5039
6468
  const borrowRatePerSec = await (async () => {
5040
6469
  const [borrowRateRaw] = await multicallRead(this.rpcUrl, [
5041
- [irm, encodeFunctionData16({ abi: IRM_ABI, functionName: "borrowRateView", args: [irmMarketParams, irmMarket] })]
6470
+ [irm, encodeFunctionData19({ abi: IRM_ABI, functionName: "borrowRateView", args: [irmMarketParams, irmMarket] })]
5042
6471
  ]).catch((e) => {
5043
6472
  throw DefiError.rpcError(`[${this.protocolName}] borrowRateView failed: ${e}`);
5044
6473
  });
@@ -5064,18 +6493,18 @@ var MorphoBlueAdapter = class {
5064
6493
  );
5065
6494
  }
5066
6495
  };
5067
- var BORROWER_OPS_ABI = parseAbi18([
6496
+ var BORROWER_OPS_ABI = parseAbi21([
5068
6497
  "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)",
5069
6498
  "function adjustTrove(uint256 _troveId, uint256 _collChange, bool _isCollIncrease, uint256 _debtChange, bool _isDebtIncrease, uint256 _upperHint, uint256 _lowerHint, uint256 _maxUpfrontFee) external",
5070
6499
  "function closeTrove(uint256 _troveId) external"
5071
6500
  ]);
5072
- var TROVE_MANAGER_ABI = parseAbi18([
6501
+ var TROVE_MANAGER_ABI = parseAbi21([
5073
6502
  "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)"
5074
6503
  ]);
5075
- var HINT_HELPERS_ABI = parseAbi18([
6504
+ var HINT_HELPERS_ABI = parseAbi21([
5076
6505
  "function getApproxHint(uint256 _collIndex, uint256 _interestRate, uint256 _numTrials, uint256 _inputRandomSeed) external view returns (uint256 hintId, uint256 diff, uint256 latestRandomSeed)"
5077
6506
  ]);
5078
- var SORTED_TROVES_ABI = parseAbi18([
6507
+ var SORTED_TROVES_ABI = parseAbi21([
5079
6508
  "function findInsertPosition(uint256 _annualInterestRate, uint256 _prevId, uint256 _nextId) external view returns (uint256 prevId, uint256 nextId)"
5080
6509
  ]);
5081
6510
  var FelixCdpAdapter = class {
@@ -5103,7 +6532,7 @@ var FelixCdpAdapter = class {
5103
6532
  if (!this.hintHelpers || !this.sortedTroves || !this.rpcUrl) {
5104
6533
  return [0n, 0n];
5105
6534
  }
5106
- const client = createPublicClient13({ transport: http13(this.rpcUrl) });
6535
+ const client = createPublicClient16({ transport: http16(this.rpcUrl) });
5107
6536
  const approxResult = await client.readContract({
5108
6537
  address: this.hintHelpers,
5109
6538
  abi: HINT_HELPERS_ABI,
@@ -5126,7 +6555,7 @@ var FelixCdpAdapter = class {
5126
6555
  const interestRate = 50000000000000000n;
5127
6556
  const [upperHint, lowerHint] = await this.getHints(interestRate);
5128
6557
  const hasHints = upperHint !== 0n || lowerHint !== 0n;
5129
- const data = encodeFunctionData17({
6558
+ const data = encodeFunctionData20({
5130
6559
  abi: BORROWER_OPS_ABI,
5131
6560
  functionName: "openTrove",
5132
6561
  args: [
@@ -5155,7 +6584,7 @@ var FelixCdpAdapter = class {
5155
6584
  async buildAdjust(params) {
5156
6585
  const collChange = params.collateral_delta ?? 0n;
5157
6586
  const debtChange = params.debt_delta ?? 0n;
5158
- const data = encodeFunctionData17({
6587
+ const data = encodeFunctionData20({
5159
6588
  abi: BORROWER_OPS_ABI,
5160
6589
  functionName: "adjustTrove",
5161
6590
  args: [
@@ -5178,7 +6607,7 @@ var FelixCdpAdapter = class {
5178
6607
  };
5179
6608
  }
5180
6609
  async buildClose(params) {
5181
- const data = encodeFunctionData17({
6610
+ const data = encodeFunctionData20({
5182
6611
  abi: BORROWER_OPS_ABI,
5183
6612
  functionName: "closeTrove",
5184
6613
  args: [params.cdp_id]
@@ -5194,7 +6623,7 @@ var FelixCdpAdapter = class {
5194
6623
  async getCdpInfo(cdpId) {
5195
6624
  if (!this.rpcUrl) throw DefiError.rpcError(`[${this.protocolName}] getCdpInfo requires RPC \u2014 set HYPEREVM_RPC_URL`);
5196
6625
  if (!this.troveManager) throw DefiError.contractError(`[${this.protocolName}] trove_manager contract not configured`);
5197
- const client = createPublicClient13({ transport: http13(this.rpcUrl) });
6626
+ const client = createPublicClient16({ transport: http16(this.rpcUrl) });
5198
6627
  const data = await client.readContract({
5199
6628
  address: this.troveManager,
5200
6629
  abi: TROVE_MANAGER_ABI,
@@ -5212,13 +6641,13 @@ var FelixCdpAdapter = class {
5212
6641
  protocol: this.protocolName,
5213
6642
  cdp_id: cdpId,
5214
6643
  collateral: {
5215
- token: zeroAddress8,
6644
+ token: zeroAddress11,
5216
6645
  symbol: "WHYPE",
5217
6646
  amount: entireColl,
5218
6647
  decimals: 18
5219
6648
  },
5220
6649
  debt: {
5221
- token: zeroAddress8,
6650
+ token: zeroAddress11,
5222
6651
  symbol: "feUSD",
5223
6652
  amount: entireDebt,
5224
6653
  decimals: 18
@@ -5227,7 +6656,7 @@ var FelixCdpAdapter = class {
5227
6656
  };
5228
6657
  }
5229
6658
  };
5230
- var PRICE_FEED_ABI = parseAbi19([
6659
+ var PRICE_FEED_ABI = parseAbi222([
5231
6660
  "function fetchPrice() external view returns (uint256 price, bool isNewOracleFailureDetected)",
5232
6661
  "function lastGoodPrice() external view returns (uint256)"
5233
6662
  ]);
@@ -5253,7 +6682,7 @@ var FelixOracleAdapter = class {
5253
6682
  if (asset !== this.asset && this.asset !== "0x0000000000000000000000000000000000000000") {
5254
6683
  throw DefiError.unsupported(`[${this.protocolName}] Felix PriceFeed only supports asset ${this.asset}`);
5255
6684
  }
5256
- const client = createPublicClient14({ transport: http14(this.rpcUrl) });
6685
+ const client = createPublicClient17({ transport: http17(this.rpcUrl) });
5257
6686
  let priceVal;
5258
6687
  try {
5259
6688
  const result = await client.readContract({
@@ -5292,7 +6721,7 @@ var FelixOracleAdapter = class {
5292
6721
  return results;
5293
6722
  }
5294
6723
  };
5295
- var ERC4626_ABI = parseAbi20([
6724
+ var ERC4626_ABI = parseAbi23([
5296
6725
  "function asset() external view returns (address)",
5297
6726
  "function totalAssets() external view returns (uint256)",
5298
6727
  "function totalSupply() external view returns (uint256)",
@@ -5316,7 +6745,7 @@ var ERC4626VaultAdapter = class {
5316
6745
  return this.protocolName;
5317
6746
  }
5318
6747
  async buildDeposit(assets, receiver) {
5319
- const data = encodeFunctionData18({
6748
+ const data = encodeFunctionData21({
5320
6749
  abi: ERC4626_ABI,
5321
6750
  functionName: "deposit",
5322
6751
  args: [assets, receiver]
@@ -5330,7 +6759,7 @@ var ERC4626VaultAdapter = class {
5330
6759
  };
5331
6760
  }
5332
6761
  async buildWithdraw(assets, receiver, owner) {
5333
- const data = encodeFunctionData18({
6762
+ const data = encodeFunctionData21({
5334
6763
  abi: ERC4626_ABI,
5335
6764
  functionName: "withdraw",
5336
6765
  args: [assets, receiver, owner]
@@ -5345,7 +6774,7 @@ var ERC4626VaultAdapter = class {
5345
6774
  }
5346
6775
  async totalAssets() {
5347
6776
  if (!this.rpcUrl) throw DefiError.rpcError("No RPC URL configured");
5348
- const client = createPublicClient15({ transport: http15(this.rpcUrl) });
6777
+ const client = createPublicClient18({ transport: http18(this.rpcUrl) });
5349
6778
  return client.readContract({
5350
6779
  address: this.vaultAddress,
5351
6780
  abi: ERC4626_ABI,
@@ -5356,7 +6785,7 @@ var ERC4626VaultAdapter = class {
5356
6785
  }
5357
6786
  async convertToShares(assets) {
5358
6787
  if (!this.rpcUrl) throw DefiError.rpcError("No RPC URL configured");
5359
- const client = createPublicClient15({ transport: http15(this.rpcUrl) });
6788
+ const client = createPublicClient18({ transport: http18(this.rpcUrl) });
5360
6789
  return client.readContract({
5361
6790
  address: this.vaultAddress,
5362
6791
  abi: ERC4626_ABI,
@@ -5368,7 +6797,7 @@ var ERC4626VaultAdapter = class {
5368
6797
  }
5369
6798
  async convertToAssets(shares) {
5370
6799
  if (!this.rpcUrl) throw DefiError.rpcError("No RPC URL configured");
5371
- const client = createPublicClient15({ transport: http15(this.rpcUrl) });
6800
+ const client = createPublicClient18({ transport: http18(this.rpcUrl) });
5372
6801
  return client.readContract({
5373
6802
  address: this.vaultAddress,
5374
6803
  abi: ERC4626_ABI,
@@ -5380,7 +6809,7 @@ var ERC4626VaultAdapter = class {
5380
6809
  }
5381
6810
  async getVaultInfo() {
5382
6811
  if (!this.rpcUrl) throw DefiError.rpcError("No RPC URL configured");
5383
- const client = createPublicClient15({ transport: http15(this.rpcUrl) });
6812
+ const client = createPublicClient18({ transport: http18(this.rpcUrl) });
5384
6813
  const [totalAssets, totalSupply, asset] = await Promise.all([
5385
6814
  client.readContract({ address: this.vaultAddress, abi: ERC4626_ABI, functionName: "totalAssets" }).catch((e) => {
5386
6815
  throw DefiError.rpcError(`[${this.protocolName}] totalAssets failed: ${e}`);
@@ -5401,7 +6830,7 @@ var ERC4626VaultAdapter = class {
5401
6830
  };
5402
6831
  }
5403
6832
  };
5404
- var GENERIC_LST_ABI = parseAbi21([
6833
+ var GENERIC_LST_ABI = parseAbi24([
5405
6834
  "function stake() external payable returns (uint256)",
5406
6835
  "function unstake(uint256 amount) external returns (uint256)"
5407
6836
  ]);
@@ -5418,7 +6847,7 @@ var GenericLstAdapter = class {
5418
6847
  return this.protocolName;
5419
6848
  }
5420
6849
  async buildStake(params) {
5421
- const data = encodeFunctionData19({ abi: GENERIC_LST_ABI, functionName: "stake" });
6850
+ const data = encodeFunctionData222({ abi: GENERIC_LST_ABI, functionName: "stake" });
5422
6851
  return {
5423
6852
  description: `[${this.protocolName}] Stake ${params.amount} HYPE`,
5424
6853
  to: this.staking,
@@ -5428,7 +6857,7 @@ var GenericLstAdapter = class {
5428
6857
  };
5429
6858
  }
5430
6859
  async buildUnstake(params) {
5431
- const data = encodeFunctionData19({
6860
+ const data = encodeFunctionData222({
5432
6861
  abi: GENERIC_LST_ABI,
5433
6862
  functionName: "unstake",
5434
6863
  args: [params.amount]
@@ -5445,11 +6874,11 @@ var GenericLstAdapter = class {
5445
6874
  throw DefiError.unsupported(`[${this.protocolName}] getInfo requires RPC`);
5446
6875
  }
5447
6876
  };
5448
- var STHYPE_ABI = parseAbi222([
6877
+ var STHYPE_ABI = parseAbi25([
5449
6878
  "function submit(address referral) external payable returns (uint256)",
5450
6879
  "function requestWithdrawals(uint256[] amounts, address owner) external returns (uint256[] requestIds)"
5451
6880
  ]);
5452
- var ERC20_ABI3 = parseAbi222([
6881
+ var ERC20_ABI3 = parseAbi25([
5453
6882
  "function totalSupply() external view returns (uint256)"
5454
6883
  ]);
5455
6884
  var StHypeAdapter = class {
@@ -5469,10 +6898,10 @@ var StHypeAdapter = class {
5469
6898
  return this.protocolName;
5470
6899
  }
5471
6900
  async buildStake(params) {
5472
- const data = encodeFunctionData20({
6901
+ const data = encodeFunctionData23({
5473
6902
  abi: STHYPE_ABI,
5474
6903
  functionName: "submit",
5475
- args: [zeroAddress9]
6904
+ args: [zeroAddress12]
5476
6905
  });
5477
6906
  return {
5478
6907
  description: `[${this.protocolName}] Stake ${params.amount} HYPE for stHYPE`,
@@ -5483,7 +6912,7 @@ var StHypeAdapter = class {
5483
6912
  };
5484
6913
  }
5485
6914
  async buildUnstake(params) {
5486
- const data = encodeFunctionData20({
6915
+ const data = encodeFunctionData23({
5487
6916
  abi: STHYPE_ABI,
5488
6917
  functionName: "requestWithdrawals",
5489
6918
  args: [[params.amount], params.recipient]
@@ -5498,7 +6927,7 @@ var StHypeAdapter = class {
5498
6927
  }
5499
6928
  async getInfo() {
5500
6929
  if (!this.rpcUrl) throw DefiError.rpcError("No RPC URL configured");
5501
- const client = createPublicClient16({ transport: http16(this.rpcUrl) });
6930
+ const client = createPublicClient19({ transport: http19(this.rpcUrl) });
5502
6931
  const tokenAddr = this.sthypeToken ?? this.staking;
5503
6932
  const totalSupply = await client.readContract({
5504
6933
  address: tokenAddr,
@@ -5509,19 +6938,19 @@ var StHypeAdapter = class {
5509
6938
  });
5510
6939
  return {
5511
6940
  protocol: this.protocolName,
5512
- staked_token: zeroAddress9,
6941
+ staked_token: zeroAddress12,
5513
6942
  liquid_token: tokenAddr,
5514
6943
  exchange_rate: 1,
5515
6944
  total_staked: totalSupply
5516
6945
  };
5517
6946
  }
5518
6947
  };
5519
- var KINETIQ_ABI = parseAbi23([
6948
+ var KINETIQ_ABI = parseAbi26([
5520
6949
  "function stake() external payable returns (uint256)",
5521
6950
  "function requestUnstake(uint256 amount) external returns (uint256)",
5522
6951
  "function totalStaked() external view returns (uint256)"
5523
6952
  ]);
5524
- var ORACLE_ABI3 = parseAbi23([
6953
+ var ORACLE_ABI3 = parseAbi26([
5525
6954
  "function getAssetPrice(address asset) external view returns (uint256)"
5526
6955
  ]);
5527
6956
  var WHYPE = "0x5555555555555555555555555555555555555555";
@@ -5543,7 +6972,7 @@ var KinetiqAdapter = class {
5543
6972
  return this.protocolName;
5544
6973
  }
5545
6974
  async buildStake(params) {
5546
- const data = encodeFunctionData21({ abi: KINETIQ_ABI, functionName: "stake" });
6975
+ const data = encodeFunctionData24({ abi: KINETIQ_ABI, functionName: "stake" });
5547
6976
  return {
5548
6977
  description: `[${this.protocolName}] Stake ${params.amount} HYPE for kHYPE`,
5549
6978
  to: this.staking,
@@ -5553,7 +6982,7 @@ var KinetiqAdapter = class {
5553
6982
  };
5554
6983
  }
5555
6984
  async buildUnstake(params) {
5556
- const data = encodeFunctionData21({
6985
+ const data = encodeFunctionData24({
5557
6986
  abi: KINETIQ_ABI,
5558
6987
  functionName: "requestUnstake",
5559
6988
  args: [params.amount]
@@ -5568,7 +6997,7 @@ var KinetiqAdapter = class {
5568
6997
  }
5569
6998
  async getInfo() {
5570
6999
  if (!this.rpcUrl) throw DefiError.rpcError("No RPC URL configured");
5571
- const client = createPublicClient17({ transport: http17(this.rpcUrl) });
7000
+ const client = createPublicClient20({ transport: http20(this.rpcUrl) });
5572
7001
  const totalStaked = await client.readContract({
5573
7002
  address: this.staking,
5574
7003
  abi: KINETIQ_ABI,
@@ -5583,22 +7012,22 @@ var KinetiqAdapter = class {
5583
7012
  const rateF64 = hypePrice > 0n && khypePrice > 0n ? Number(khypePrice * 10n ** 18n / hypePrice) / 1e18 : 1;
5584
7013
  return {
5585
7014
  protocol: this.protocolName,
5586
- staked_token: zeroAddress10,
7015
+ staked_token: zeroAddress13,
5587
7016
  liquid_token: this.liquidToken,
5588
7017
  exchange_rate: rateF64,
5589
7018
  total_staked: totalStaked
5590
7019
  };
5591
7020
  }
5592
7021
  };
5593
- var HLP_ABI = parseAbi24([
7022
+ var HLP_ABI = parseAbi27([
5594
7023
  "function deposit(uint256 amount) external returns (uint256)",
5595
7024
  "function withdraw(uint256 shares) external returns (uint256)"
5596
7025
  ]);
5597
- var RYSK_ABI = parseAbi25([
7026
+ var RYSK_ABI = parseAbi28([
5598
7027
  "function openOption(address underlying, uint256 strikePrice, uint256 expiry, bool isCall, uint256 amount) external returns (uint256 premium)",
5599
7028
  "function closeOption(address underlying, uint256 strikePrice, uint256 expiry, bool isCall, uint256 amount) external returns (uint256 payout)"
5600
7029
  ]);
5601
- var ERC721_ABI = parseAbi26([
7030
+ var ERC721_ABI = parseAbi29([
5602
7031
  "function name() returns (string)",
5603
7032
  "function symbol() returns (string)",
5604
7033
  "function totalSupply() returns (uint256)",
@@ -5618,7 +7047,7 @@ var ERC721Adapter = class {
5618
7047
  }
5619
7048
  async getCollectionInfo(collection) {
5620
7049
  if (!this.rpcUrl) throw DefiError.rpcError("No RPC URL configured");
5621
- const client = createPublicClient18({ transport: http18(this.rpcUrl) });
7050
+ const client = createPublicClient21({ transport: http21(this.rpcUrl) });
5622
7051
  const [collectionName, symbol, totalSupply] = await Promise.all([
5623
7052
  client.readContract({ address: collection, abi: ERC721_ABI, functionName: "name" }).catch((e) => {
5624
7053
  throw DefiError.rpcError(`[${this.protocolName}] name failed: ${e}`);
@@ -5637,7 +7066,7 @@ var ERC721Adapter = class {
5637
7066
  }
5638
7067
  async getTokenInfo(collection, tokenId) {
5639
7068
  if (!this.rpcUrl) throw DefiError.rpcError("No RPC URL configured");
5640
- const client = createPublicClient18({ transport: http18(this.rpcUrl) });
7069
+ const client = createPublicClient21({ transport: http21(this.rpcUrl) });
5641
7070
  const [owner, tokenUri] = await Promise.all([
5642
7071
  client.readContract({ address: collection, abi: ERC721_ABI, functionName: "ownerOf", args: [tokenId] }).catch((e) => {
5643
7072
  throw DefiError.rpcError(`[${this.protocolName}] ownerOf failed: ${e}`);
@@ -5653,7 +7082,7 @@ var ERC721Adapter = class {
5653
7082
  }
5654
7083
  async getBalance(owner, collection) {
5655
7084
  if (!this.rpcUrl) throw DefiError.rpcError("No RPC URL configured");
5656
- const client = createPublicClient18({ transport: http18(this.rpcUrl) });
7085
+ const client = createPublicClient21({ transport: http21(this.rpcUrl) });
5657
7086
  return client.readContract({ address: collection, abi: ERC721_ABI, functionName: "balanceOf", args: [owner] }).catch((e) => {
5658
7087
  throw DefiError.rpcError(`[${this.protocolName}] balanceOf failed: ${e}`);
5659
7088
  });
@@ -5674,6 +7103,8 @@ function createDex(entry, rpcUrl) {
5674
7103
  case "solidly_v2":
5675
7104
  case "solidly_cl":
5676
7105
  return new SolidlyAdapter(entry, rpcUrl);
7106
+ case "hybra":
7107
+ return new ThenaCLAdapter(entry, rpcUrl);
5677
7108
  case "curve_stableswap":
5678
7109
  return new CurveStableSwapAdapter(entry);
5679
7110
  case "balancer_v3":
@@ -5734,11 +7165,13 @@ function createLiquidStaking(entry, rpcUrl) {
5734
7165
  }
5735
7166
  }
5736
7167
  function createGauge(entry, rpcUrl) {
7168
+ if (entry.interface === "hybra" || entry.contracts?.["gauge_manager"]) {
7169
+ return new HybraGaugeAdapter(entry, rpcUrl);
7170
+ }
5737
7171
  switch (entry.interface) {
5738
7172
  case "solidly_v2":
5739
7173
  case "solidly_cl":
5740
7174
  case "algebra_v3":
5741
- case "hybra":
5742
7175
  return new SolidlyGaugeAdapter(entry, rpcUrl);
5743
7176
  default:
5744
7177
  throw DefiError.unsupported(`Gauge interface '${entry.interface}' not supported`);
@@ -5777,6 +7210,22 @@ function createOracleFromCdp(entry, _asset, rpcUrl) {
5777
7210
  function createMerchantMoeLB(entry, rpcUrl) {
5778
7211
  return new MerchantMoeLBAdapter(entry, rpcUrl);
5779
7212
  }
7213
+ function createKittenSwapFarming(entry, rpcUrl) {
7214
+ const farmingCenter = entry.contracts?.["farming_center"];
7215
+ if (!farmingCenter) {
7216
+ throw new DefiError("CONTRACT_ERROR", `[${entry.name}] Missing 'farming_center' contract address`);
7217
+ }
7218
+ const eternalFarming = entry.contracts?.["eternal_farming"];
7219
+ if (!eternalFarming) {
7220
+ throw new DefiError("CONTRACT_ERROR", `[${entry.name}] Missing 'eternal_farming' contract address`);
7221
+ }
7222
+ const positionManager = entry.contracts?.["position_manager"];
7223
+ if (!positionManager) {
7224
+ throw new DefiError("CONTRACT_ERROR", `[${entry.name}] Missing 'position_manager' contract address`);
7225
+ }
7226
+ const factory = entry.contracts?.["factory"];
7227
+ return new KittenSwapFarmingAdapter(entry.name, farmingCenter, eternalFarming, positionManager, rpcUrl, factory);
7228
+ }
5780
7229
  var DexSpotPrice = class {
5781
7230
  /**
5782
7231
  * Get the spot price for `token` denominated in `quoteToken` (e.g. USDC).
@@ -5849,7 +7298,7 @@ function registerDex(parent, getOpts, makeExecutor2) {
5849
7298
  const result = await executor.execute(tx);
5850
7299
  printOutput(result, getOpts());
5851
7300
  });
5852
- dex.command("lp-add").description("Add liquidity to a pool").requiredOption("--protocol <protocol>", "Protocol slug").requiredOption("--token-a <token>", "First token symbol or address").requiredOption("--token-b <token>", "Second token symbol or address").requiredOption("--amount-a <amount>", "Amount of token A in wei").requiredOption("--amount-b <amount>", "Amount of token B in wei").option("--recipient <address>", "Recipient address").action(async (opts) => {
7301
+ dex.command("lp-add").description("Add liquidity to a pool").requiredOption("--protocol <protocol>", "Protocol slug").requiredOption("--token-a <token>", "First token symbol or address").requiredOption("--token-b <token>", "Second token symbol or address").requiredOption("--amount-a <amount>", "Amount of token A in wei").requiredOption("--amount-b <amount>", "Amount of token B in wei").option("--recipient <address>", "Recipient address").option("--tick-lower <tick>", "Lower tick for concentrated LP (default: full range)").option("--tick-upper <tick>", "Upper tick for concentrated LP (default: full range)").option("--range <percent>", "\xB1N% concentrated range around current price (e.g. --range 2 for \xB12%)").option("--pool <name_or_address>", "Pool name (e.g. WHYPE/USDC) or address").action(async (opts) => {
5853
7302
  const executor = makeExecutor2();
5854
7303
  const chainName = parent.opts().chain ?? "hyperevm";
5855
7304
  const registry = Registry.loadEmbedded();
@@ -5859,13 +7308,26 @@ function registerDex(parent, getOpts, makeExecutor2) {
5859
7308
  const tokenA = opts.tokenA.startsWith("0x") ? opts.tokenA : registry.resolveToken(chainName, opts.tokenA).address;
5860
7309
  const tokenB = opts.tokenB.startsWith("0x") ? opts.tokenB : registry.resolveToken(chainName, opts.tokenB).address;
5861
7310
  const recipient = opts.recipient ?? process.env.DEFI_WALLET_ADDRESS ?? "0x0000000000000000000000000000000000000001";
7311
+ let poolAddr;
7312
+ if (opts.pool) {
7313
+ if (opts.pool.startsWith("0x")) {
7314
+ poolAddr = opts.pool;
7315
+ } else {
7316
+ const poolInfo = registry.resolvePool(opts.protocol, opts.pool);
7317
+ poolAddr = poolInfo.address;
7318
+ }
7319
+ }
5862
7320
  const tx = await adapter.buildAddLiquidity({
5863
7321
  protocol: protocol.name,
5864
7322
  token_a: tokenA,
5865
7323
  token_b: tokenB,
5866
7324
  amount_a: BigInt(opts.amountA),
5867
7325
  amount_b: BigInt(opts.amountB),
5868
- recipient
7326
+ recipient,
7327
+ tick_lower: opts.tickLower !== void 0 ? parseInt(opts.tickLower) : void 0,
7328
+ tick_upper: opts.tickUpper !== void 0 ? parseInt(opts.tickUpper) : void 0,
7329
+ range_pct: opts.range !== void 0 ? parseFloat(opts.range) : void 0,
7330
+ pool: poolAddr
5869
7331
  });
5870
7332
  const result = await executor.execute(tx);
5871
7333
  printOutput(result, getOpts());
@@ -5914,57 +7376,96 @@ function registerDex(parent, getOpts, makeExecutor2) {
5914
7376
 
5915
7377
  // src/commands/gauge.ts
5916
7378
  import { privateKeyToAccount as privateKeyToAccount2 } from "viem/accounts";
7379
+ function resolveAccount() {
7380
+ const walletAddr = process.env["DEFI_WALLET_ADDRESS"];
7381
+ if (walletAddr) return walletAddr;
7382
+ const privateKey = process.env["DEFI_PRIVATE_KEY"];
7383
+ if (privateKey) return privateKeyToAccount2(privateKey).address;
7384
+ return void 0;
7385
+ }
5917
7386
  function registerGauge(parent, getOpts, makeExecutor2) {
5918
- const gauge = parent.command("gauge").description("Gauge operations: deposit, withdraw, claim, lock, vote (ve(3,3))");
5919
- gauge.command("deposit").description("Deposit LP tokens into a gauge").requiredOption("--protocol <protocol>", "Protocol slug").requiredOption("--gauge <address>", "Gauge contract address").requiredOption("--amount <amount>", "LP token amount in wei").option("--ve-nft <tokenId>", "veNFT token ID for boosted rewards").action(async (opts) => {
5920
- const executor = makeExecutor2();
7387
+ const gauge = parent.command("gauge").description("Gauge operations: find, deposit, withdraw, claim, earned");
7388
+ gauge.command("discover").description("Find all pools with emission gauges (scans V2 + CL factories)").requiredOption("--protocol <protocol>", "Protocol slug").action(async (opts) => {
7389
+ const chainName = parent.opts().chain ?? "hyperevm";
5921
7390
  const registry = Registry.loadEmbedded();
7391
+ const chain = registry.getChain(chainName);
5922
7392
  const protocol = registry.getProtocol(opts.protocol);
5923
- const adapter = createGauge(protocol);
5924
- const tokenId = opts.veNft ? BigInt(opts.veNft) : void 0;
5925
- const tx = await adapter.buildDeposit(opts.gauge, BigInt(opts.amount), tokenId);
5926
- const result = await executor.execute(tx);
5927
- printOutput(result, getOpts());
7393
+ const adapter = createGauge(protocol, chain.effectiveRpcUrl());
7394
+ if (!adapter.discoverGaugedPools) throw new Error(`${protocol.name} does not support gauge discovery`);
7395
+ const pools = await adapter.discoverGaugedPools();
7396
+ printOutput(pools, getOpts());
5928
7397
  });
5929
- gauge.command("withdraw").description("Withdraw LP tokens from a gauge").requiredOption("--protocol <protocol>", "Protocol slug").requiredOption("--gauge <address>", "Gauge contract address").requiredOption("--amount <amount>", "LP token amount in wei").action(async (opts) => {
5930
- const executor = makeExecutor2();
7398
+ gauge.command("find").description("Find gauge address for a pool via voter contract").requiredOption("--protocol <protocol>", "Protocol slug").requiredOption("--pool <address>", "Pool address").action(async (opts) => {
7399
+ const chainName = parent.opts().chain ?? "hyperevm";
5931
7400
  const registry = Registry.loadEmbedded();
7401
+ const chain = registry.getChain(chainName);
5932
7402
  const protocol = registry.getProtocol(opts.protocol);
5933
- const adapter = createGauge(protocol);
5934
- const tx = await adapter.buildWithdraw(opts.gauge, BigInt(opts.amount));
5935
- const result = await executor.execute(tx);
5936
- printOutput(result, getOpts());
7403
+ const adapter = createGauge(protocol, chain.effectiveRpcUrl());
7404
+ if (!adapter.resolveGauge) throw new Error(`${protocol.name} does not support gauge lookup`);
7405
+ const gaugeAddr = await adapter.resolveGauge(opts.pool);
7406
+ printOutput({ pool: opts.pool, gauge: gaugeAddr, protocol: protocol.name }, getOpts());
7407
+ });
7408
+ gauge.command("earned").description("Check pending rewards for a gauge").requiredOption("--protocol <protocol>", "Protocol slug").requiredOption("--gauge <address>", "Gauge contract address").option("--token-id <id>", "NFT tokenId (for CL gauges like Hybra)").action(async (opts) => {
7409
+ const chainName = parent.opts().chain ?? "hyperevm";
7410
+ const registry = Registry.loadEmbedded();
7411
+ const chain = registry.getChain(chainName);
7412
+ const protocol = registry.getProtocol(opts.protocol);
7413
+ const adapter = createGauge(protocol, chain.effectiveRpcUrl());
7414
+ if (opts.tokenId) {
7415
+ if (!adapter.getPendingRewardsByTokenId) throw new Error(`${protocol.name} does not support NFT rewards`);
7416
+ const earned = await adapter.getPendingRewardsByTokenId(opts.gauge, BigInt(opts.tokenId));
7417
+ printOutput({ gauge: opts.gauge, token_id: opts.tokenId, earned: earned.toString() }, getOpts());
7418
+ } else {
7419
+ const account = resolveAccount();
7420
+ if (!account) throw new Error("DEFI_WALLET_ADDRESS or DEFI_PRIVATE_KEY required");
7421
+ const rewards = await adapter.getPendingRewards(opts.gauge, account);
7422
+ printOutput(rewards.map((r) => ({ token: r.token, amount: r.amount.toString() })), getOpts());
7423
+ }
5937
7424
  });
5938
- gauge.command("claim").description("Claim earned rewards from a gauge").requiredOption("--protocol <protocol>", "Protocol slug").requiredOption("--gauge <address>", "Gauge contract address").action(async (opts) => {
7425
+ gauge.command("deposit").description("Deposit LP tokens or NFT into a gauge").requiredOption("--protocol <protocol>", "Protocol slug").requiredOption("--gauge <address>", "Gauge contract address").option("--amount <amount>", "LP token amount in wei (for V2 gauges)").option("--token-id <id>", "NFT tokenId (for CL gauges like Hybra)").action(async (opts) => {
5939
7426
  const executor = makeExecutor2();
7427
+ const chainName = parent.opts().chain ?? "hyperevm";
5940
7428
  const registry = Registry.loadEmbedded();
7429
+ const chain = registry.getChain(chainName);
5941
7430
  const protocol = registry.getProtocol(opts.protocol);
5942
- const adapter = createGauge(protocol, executor.rpcUrl);
5943
- const privateKey = process.env["DEFI_PRIVATE_KEY"];
5944
- const account = privateKey ? privateKeyToAccount2(privateKey).address : void 0;
5945
- const tx = await adapter.buildClaimRewards(opts.gauge, account);
7431
+ const adapter = createGauge(protocol, chain.effectiveRpcUrl());
7432
+ const amount = opts.amount ? BigInt(opts.amount) : 0n;
7433
+ const tokenId = opts.tokenId ? BigInt(opts.tokenId) : void 0;
7434
+ const tx = await adapter.buildDeposit(opts.gauge, amount, tokenId);
5946
7435
  const result = await executor.execute(tx);
5947
7436
  printOutput(result, getOpts());
5948
7437
  });
5949
- gauge.command("lock").description("Create a veNFT lock").requiredOption("--protocol <protocol>", "Protocol slug").requiredOption("--amount <amount>", "Amount to lock in wei").option("--days <days>", "Lock duration in days", "365").action(async (opts) => {
7438
+ gauge.command("withdraw").description("Withdraw LP tokens or NFT from a gauge").requiredOption("--protocol <protocol>", "Protocol slug").requiredOption("--gauge <address>", "Gauge contract address").option("--amount <amount>", "LP token amount in wei (for V2 gauges)").option("--token-id <id>", "NFT tokenId (for CL gauges like Hybra)").action(async (opts) => {
5950
7439
  const executor = makeExecutor2();
7440
+ const chainName = parent.opts().chain ?? "hyperevm";
5951
7441
  const registry = Registry.loadEmbedded();
7442
+ const chain = registry.getChain(chainName);
5952
7443
  const protocol = registry.getProtocol(opts.protocol);
5953
- const adapter = createGauge(protocol);
5954
- const tx = await adapter.buildCreateLock(BigInt(opts.amount), parseInt(opts.days) * 86400);
7444
+ const adapter = createGauge(protocol, chain.effectiveRpcUrl());
7445
+ const amount = opts.amount ? BigInt(opts.amount) : 0n;
7446
+ const tokenId = opts.tokenId ? BigInt(opts.tokenId) : void 0;
7447
+ const tx = await adapter.buildWithdraw(opts.gauge, amount, tokenId);
5955
7448
  const result = await executor.execute(tx);
5956
7449
  printOutput(result, getOpts());
5957
7450
  });
5958
- gauge.command("vote").description("Vote on gauge emissions with veNFT").requiredOption("--protocol <protocol>", "Protocol slug").requiredOption("--ve-nft <tokenId>", "veNFT token ID").requiredOption("--pools <pools>", "Pool addresses (comma-separated)").requiredOption("--weights <weights>", "Vote weights (comma-separated)").action(async (opts) => {
7451
+ gauge.command("claim").description("Claim earned rewards from a gauge").requiredOption("--protocol <protocol>", "Protocol slug").requiredOption("--gauge <address>", "Gauge contract address").option("--token-id <id>", "NFT tokenId (for CL gauges like Hybra)").action(async (opts) => {
5959
7452
  const executor = makeExecutor2();
7453
+ const chainName = parent.opts().chain ?? "hyperevm";
5960
7454
  const registry = Registry.loadEmbedded();
7455
+ const chain = registry.getChain(chainName);
5961
7456
  const protocol = registry.getProtocol(opts.protocol);
5962
- const adapter = createGauge(protocol);
5963
- const pools = opts.pools.split(",");
5964
- const weights = opts.weights.split(",").map((w) => BigInt(w));
5965
- const tx = await adapter.buildVote(BigInt(opts.veNft), pools, weights);
5966
- const result = await executor.execute(tx);
5967
- printOutput(result, getOpts());
7457
+ const adapter = createGauge(protocol, chain.effectiveRpcUrl());
7458
+ if (opts.tokenId) {
7459
+ if (!adapter.buildClaimRewardsByTokenId) throw new Error(`${protocol.name} does not support NFT claim`);
7460
+ const tx = await adapter.buildClaimRewardsByTokenId(opts.gauge, BigInt(opts.tokenId));
7461
+ const result = await executor.execute(tx);
7462
+ printOutput(result, getOpts());
7463
+ } else {
7464
+ const account = resolveAccount();
7465
+ const tx = await adapter.buildClaimRewards(opts.gauge, account);
7466
+ const result = await executor.execute(tx);
7467
+ printOutput(result, getOpts());
7468
+ }
5968
7469
  });
5969
7470
  }
5970
7471
 
@@ -6211,9 +7712,7 @@ function resolveAsset(registry, chain, asset) {
6211
7712
  return registry.resolveToken(chain, asset).address;
6212
7713
  }
6213
7714
  async function collectLendingRates(registry, chainName, rpc, assetAddr) {
6214
- const protos = registry.getProtocolsForChain(chainName).filter(
6215
- (p) => p.category === ProtocolCategory.Lending && (p.interface === "aave_v3" || p.interface === "aave_v3_isolated")
6216
- );
7715
+ const protos = registry.getProtocolsForChain(chainName).filter((p) => p.category === ProtocolCategory.Lending);
6217
7716
  const results = [];
6218
7717
  let first = true;
6219
7718
  for (const proto of protos) {
@@ -6301,7 +7800,7 @@ async function runYieldScan(registry, asset, output) {
6301
7800
  } catch {
6302
7801
  return [];
6303
7802
  }
6304
- const protos = registry.getProtocolsForChain(chainName).filter((p) => p.category === ProtocolCategory.Lending && p.interface === "aave_v3");
7803
+ const protos = registry.getProtocolsForChain(chainName).filter((p) => p.category === ProtocolCategory.Lending);
6305
7804
  if (protos.length === 0) return [];
6306
7805
  const rpc = chain.effectiveRpcUrl();
6307
7806
  const rates = [];
@@ -6384,7 +7883,7 @@ async function scanRatesForExecute(registry, asset) {
6384
7883
  } catch {
6385
7884
  return [];
6386
7885
  }
6387
- const protos = registry.getProtocolsForChain(chainName).filter((p) => p.category === ProtocolCategory.Lending && p.interface === "aave_v3");
7886
+ const protos = registry.getProtocolsForChain(chainName).filter((p) => p.category === ProtocolCategory.Lending);
6388
7887
  if (protos.length === 0) return [];
6389
7888
  const rpc = chain.effectiveRpcUrl();
6390
7889
  const rates = [];
@@ -6416,7 +7915,26 @@ async function scanRatesForExecute(registry, asset) {
6416
7915
  }
6417
7916
  function registerYield(parent, getOpts, makeExecutor2) {
6418
7917
  const yieldCmd = parent.command("yield").description("Yield operations: compare, scan, optimize, execute");
6419
- yieldCmd.command("compare").description("Compare lending rates across protocols for an asset").requiredOption("--asset <token>", "Token symbol or address").action(async (opts) => {
7918
+ yieldCmd.option("--asset <token>", "Token symbol or address", "USDC").action(async (opts) => {
7919
+ try {
7920
+ const registry = Registry.loadEmbedded();
7921
+ const chainName = (parent.opts().chain ?? "hyperevm").toLowerCase();
7922
+ const chain = registry.getChain(chainName);
7923
+ const rpc = chain.effectiveRpcUrl();
7924
+ const assetAddr = resolveAsset(registry, chainName, opts.asset);
7925
+ const results = await collectLendingRates(registry, chainName, rpc, assetAddr);
7926
+ results.sort((a, b) => b.supply_apy - a.supply_apy);
7927
+ const bestSupply = results[0]?.protocol ?? null;
7928
+ const bestBorrow = results.reduce((best, r) => {
7929
+ if (!best || r.borrow_variable_apy < best.borrow_variable_apy) return r;
7930
+ return best;
7931
+ }, null)?.protocol ?? null;
7932
+ printOutput({ asset: opts.asset, chain: chainName, rates: results, best_supply: bestSupply, best_borrow: bestBorrow }, getOpts());
7933
+ } catch (err) {
7934
+ printOutput({ error: String(err) }, getOpts());
7935
+ }
7936
+ });
7937
+ yieldCmd.command("compare").description("Compare lending rates across protocols for an asset").option("--asset <token>", "Token symbol or address", "USDC").action(async (opts) => {
6420
7938
  try {
6421
7939
  const registry = Registry.loadEmbedded();
6422
7940
  const chainName = (parent.opts().chain ?? "hyperevm").toLowerCase();
@@ -6592,7 +8110,7 @@ function registerYield(parent, getOpts, makeExecutor2) {
6592
8110
  return;
6593
8111
  }
6594
8112
  } else {
6595
- const candidates = registry.getProtocolsForChain(chainName).filter((p) => p.category === ProtocolCategory.Lending && p.interface === "aave_v3");
8113
+ const candidates = registry.getProtocolsForChain(chainName).filter((p) => p.category === ProtocolCategory.Lending);
6596
8114
  if (candidates.length === 0) {
6597
8115
  printOutput({ error: `No aave_v3 lending protocol found on ${chainName}` }, getOpts());
6598
8116
  process.exit(1);
@@ -6784,20 +8302,20 @@ function registerYield(parent, getOpts, makeExecutor2) {
6784
8302
  }
6785
8303
 
6786
8304
  // src/commands/portfolio.ts
6787
- import { encodeFunctionData as encodeFunctionData25, parseAbi as parseAbi28 } from "viem";
8305
+ import { encodeFunctionData as encodeFunctionData28, parseAbi as parseAbi31 } from "viem";
6788
8306
 
6789
8307
  // src/portfolio-tracker.ts
6790
8308
  import { mkdirSync, writeFileSync, readdirSync as readdirSync2, readFileSync as readFileSync2, existsSync as existsSync2 } from "fs";
6791
8309
  import { homedir } from "os";
6792
8310
  import { resolve as resolve2 } from "path";
6793
- import { encodeFunctionData as encodeFunctionData24, parseAbi as parseAbi27 } from "viem";
6794
- var ERC20_ABI4 = parseAbi27([
8311
+ import { encodeFunctionData as encodeFunctionData27, parseAbi as parseAbi30 } from "viem";
8312
+ var ERC20_ABI4 = parseAbi30([
6795
8313
  "function balanceOf(address owner) external view returns (uint256)"
6796
8314
  ]);
6797
- var ORACLE_ABI4 = parseAbi27([
8315
+ var ORACLE_ABI4 = parseAbi30([
6798
8316
  "function getAssetPrice(address asset) external view returns (uint256)"
6799
8317
  ]);
6800
- var POOL_ABI3 = parseAbi27([
8318
+ var POOL_ABI3 = parseAbi30([
6801
8319
  "function getUserAccountData(address user) external view returns (uint256 totalCollateralBase, uint256 totalDebtBase, uint256 availableBorrowsBase, uint256 currentLiquidationThreshold, uint256 ltv, uint256 healthFactor)"
6802
8320
  ]);
6803
8321
  function decodeU256Word(data, wordOffset = 0) {
@@ -6826,7 +8344,7 @@ async function takeSnapshot(chainName, wallet, registry) {
6826
8344
  tokenEntries.push({ symbol: t.symbol, address: entry.address, decimals: entry.decimals });
6827
8345
  calls.push([
6828
8346
  entry.address,
6829
- encodeFunctionData24({ abi: ERC20_ABI4, functionName: "balanceOf", args: [user] })
8347
+ encodeFunctionData27({ abi: ERC20_ABI4, functionName: "balanceOf", args: [user] })
6830
8348
  ]);
6831
8349
  callLabels.push(`balance:${t.symbol}`);
6832
8350
  }
@@ -6834,7 +8352,7 @@ async function takeSnapshot(chainName, wallet, registry) {
6834
8352
  for (const p of lendingProtocols) {
6835
8353
  calls.push([
6836
8354
  p.contracts["pool"],
6837
- encodeFunctionData24({ abi: POOL_ABI3, functionName: "getUserAccountData", args: [user] })
8355
+ encodeFunctionData27({ abi: POOL_ABI3, functionName: "getUserAccountData", args: [user] })
6838
8356
  ]);
6839
8357
  callLabels.push(`lending:${p.name}`);
6840
8358
  }
@@ -6844,7 +8362,7 @@ async function takeSnapshot(chainName, wallet, registry) {
6844
8362
  if (oracleAddr) {
6845
8363
  calls.push([
6846
8364
  oracleAddr,
6847
- encodeFunctionData24({ abi: ORACLE_ABI4, functionName: "getAssetPrice", args: [wrappedNative] })
8365
+ encodeFunctionData27({ abi: ORACLE_ABI4, functionName: "getAssetPrice", args: [wrappedNative] })
6848
8366
  ]);
6849
8367
  callLabels.push("price:native");
6850
8368
  }
@@ -6982,13 +8500,13 @@ function calculatePnL(current, previous) {
6982
8500
  }
6983
8501
 
6984
8502
  // src/commands/portfolio.ts
6985
- var ERC20_ABI5 = parseAbi28([
8503
+ var ERC20_ABI5 = parseAbi31([
6986
8504
  "function balanceOf(address owner) external view returns (uint256)"
6987
8505
  ]);
6988
- var POOL_ABI4 = parseAbi28([
8506
+ var POOL_ABI4 = parseAbi31([
6989
8507
  "function getUserAccountData(address user) external view returns (uint256 totalCollateralBase, uint256 totalDebtBase, uint256 availableBorrowsBase, uint256 currentLiquidationThreshold, uint256 ltv, uint256 healthFactor)"
6990
8508
  ]);
6991
- var ORACLE_ABI5 = parseAbi28([
8509
+ var ORACLE_ABI5 = parseAbi31([
6992
8510
  "function getAssetPrice(address asset) external view returns (uint256)"
6993
8511
  ]);
6994
8512
  function decodeU2562(data, wordOffset = 0) {
@@ -7028,7 +8546,7 @@ function registerPortfolio(parent, getOpts) {
7028
8546
  if (entry.address === "0x0000000000000000000000000000000000000000") continue;
7029
8547
  calls.push([
7030
8548
  entry.address,
7031
- encodeFunctionData25({ abi: ERC20_ABI5, functionName: "balanceOf", args: [user] })
8549
+ encodeFunctionData28({ abi: ERC20_ABI5, functionName: "balanceOf", args: [user] })
7032
8550
  ]);
7033
8551
  callLabels.push(`balance:${symbol}`);
7034
8552
  }
@@ -7036,7 +8554,7 @@ function registerPortfolio(parent, getOpts) {
7036
8554
  for (const p of lendingProtocols) {
7037
8555
  calls.push([
7038
8556
  p.contracts["pool"],
7039
- encodeFunctionData25({ abi: POOL_ABI4, functionName: "getUserAccountData", args: [user] })
8557
+ encodeFunctionData28({ abi: POOL_ABI4, functionName: "getUserAccountData", args: [user] })
7040
8558
  ]);
7041
8559
  callLabels.push(`lending:${p.name}`);
7042
8560
  }
@@ -7046,7 +8564,7 @@ function registerPortfolio(parent, getOpts) {
7046
8564
  if (oracleAddr) {
7047
8565
  calls.push([
7048
8566
  oracleAddr,
7049
- encodeFunctionData25({ abi: ORACLE_ABI5, functionName: "getAssetPrice", args: [wrappedNative] })
8567
+ encodeFunctionData28({ abi: ORACLE_ABI5, functionName: "getAssetPrice", args: [wrappedNative] })
7050
8568
  ]);
7051
8569
  callLabels.push("price:native");
7052
8570
  }
@@ -7408,14 +8926,14 @@ function registerAlert(parent, getOpts) {
7408
8926
  }
7409
8927
 
7410
8928
  // src/commands/scan.ts
7411
- import { encodeFunctionData as encodeFunctionData26, parseAbi as parseAbi29 } from "viem";
7412
- var AAVE_ORACLE_ABI = parseAbi29([
8929
+ import { encodeFunctionData as encodeFunctionData29, parseAbi as parseAbi33 } from "viem";
8930
+ var AAVE_ORACLE_ABI = parseAbi33([
7413
8931
  "function getAssetPrice(address asset) external view returns (uint256)"
7414
8932
  ]);
7415
- var UNIV2_ROUTER_ABI = parseAbi29([
8933
+ var UNIV2_ROUTER_ABI = parseAbi33([
7416
8934
  "function getAmountsOut(uint256 amountIn, address[] calldata path) external view returns (uint256[] memory)"
7417
8935
  ]);
7418
- var VTOKEN_ABI = parseAbi29([
8936
+ var VTOKEN_ABI = parseAbi33([
7419
8937
  "function exchangeRateStored() external view returns (uint256)"
7420
8938
  ]);
7421
8939
  var STABLECOINS = /* @__PURE__ */ new Set(["USDC", "USDT", "DAI", "USDT0"]);
@@ -7525,7 +9043,7 @@ function registerScan(parent, getOpts) {
7525
9043
  callTypes.push({ kind: "oracle", oracle: oracle.name, token: token.symbol, oracleDecimals: oracle.decimals });
7526
9044
  calls.push([
7527
9045
  oracle.addr,
7528
- encodeFunctionData26({ abi: AAVE_ORACLE_ABI, functionName: "getAssetPrice", args: [token.address] })
9046
+ encodeFunctionData29({ abi: AAVE_ORACLE_ABI, functionName: "getAssetPrice", args: [token.address] })
7529
9047
  ]);
7530
9048
  }
7531
9049
  }
@@ -7536,7 +9054,7 @@ function registerScan(parent, getOpts) {
7536
9054
  callTypes.push({ kind: "dex", token: token.symbol, outDecimals: quoteStable.decimals });
7537
9055
  calls.push([
7538
9056
  dexRouter,
7539
- encodeFunctionData26({ abi: UNIV2_ROUTER_ABI, functionName: "getAmountsOut", args: [amountIn, path] })
9057
+ encodeFunctionData29({ abi: UNIV2_ROUTER_ABI, functionName: "getAmountsOut", args: [amountIn, path] })
7540
9058
  ]);
7541
9059
  }
7542
9060
  }
@@ -7545,7 +9063,7 @@ function registerScan(parent, getOpts) {
7545
9063
  callTypes.push({ kind: "stable", from: "USDC", to: "USDT", outDecimals: usdt.decimals });
7546
9064
  calls.push([
7547
9065
  dexRouter,
7548
- encodeFunctionData26({
9066
+ encodeFunctionData29({
7549
9067
  abi: UNIV2_ROUTER_ABI,
7550
9068
  functionName: "getAmountsOut",
7551
9069
  args: [BigInt(10) ** BigInt(usdc.decimals), [usdc.address, usdt.address]]
@@ -7554,7 +9072,7 @@ function registerScan(parent, getOpts) {
7554
9072
  callTypes.push({ kind: "stable", from: "USDT", to: "USDC", outDecimals: usdc.decimals });
7555
9073
  calls.push([
7556
9074
  dexRouter,
7557
- encodeFunctionData26({
9075
+ encodeFunctionData29({
7558
9076
  abi: UNIV2_ROUTER_ABI,
7559
9077
  functionName: "getAmountsOut",
7560
9078
  args: [BigInt(10) ** BigInt(usdt.decimals), [usdt.address, usdc.address]]
@@ -7565,7 +9083,7 @@ function registerScan(parent, getOpts) {
7565
9083
  for (const fork of compoundForks) {
7566
9084
  for (const { key, addr } of fork.vtokens) {
7567
9085
  callTypes.push({ kind: "exchangeRate", protocol: fork.name, vtoken: key });
7568
- calls.push([addr, encodeFunctionData26({ abi: VTOKEN_ABI, functionName: "exchangeRateStored", args: [] })]);
9086
+ calls.push([addr, encodeFunctionData29({ abi: VTOKEN_ABI, functionName: "exchangeRateStored", args: [] })]);
7569
9087
  }
7570
9088
  }
7571
9089
  }
@@ -7783,22 +9301,22 @@ async function runAllChains(registry, patterns, oracleThreshold, stableThreshold
7783
9301
  for (const oracle of oracles) {
7784
9302
  for (const token of scanTokens) {
7785
9303
  cts.push({ kind: "oracle", oracle: oracle.name, token: token.symbol, dec: oracle.decimals });
7786
- calls.push([oracle.addr, encodeFunctionData26({ abi: AAVE_ORACLE_ABI, functionName: "getAssetPrice", args: [token.address] })]);
9304
+ calls.push([oracle.addr, encodeFunctionData29({ abi: AAVE_ORACLE_ABI, functionName: "getAssetPrice", args: [token.address] })]);
7787
9305
  }
7788
9306
  }
7789
9307
  if (dexRouter) {
7790
9308
  for (const token of scanTokens) {
7791
9309
  const path = wrappedNative && token.address.toLowerCase() === wrappedNative.toLowerCase() ? [token.address, quoteStable.address] : wrappedNative ? [token.address, wrappedNative, quoteStable.address] : [token.address, quoteStable.address];
7792
9310
  cts.push({ kind: "dex", token: token.symbol, dec: quoteStable.decimals });
7793
- calls.push([dexRouter, encodeFunctionData26({ abi: UNIV2_ROUTER_ABI, functionName: "getAmountsOut", args: [BigInt(10) ** BigInt(token.decimals), path] })]);
9311
+ calls.push([dexRouter, encodeFunctionData29({ abi: UNIV2_ROUTER_ABI, functionName: "getAmountsOut", args: [BigInt(10) ** BigInt(token.decimals), path] })]);
7794
9312
  }
7795
9313
  }
7796
9314
  }
7797
9315
  if (doStable && usdc && usdt && dexRouter) {
7798
9316
  cts.push({ kind: "stable", from: "USDC", to: "USDT", dec: usdt.decimals });
7799
- calls.push([dexRouter, encodeFunctionData26({ abi: UNIV2_ROUTER_ABI, functionName: "getAmountsOut", args: [BigInt(10) ** BigInt(usdc.decimals), [usdc.address, usdt.address]] })]);
9317
+ calls.push([dexRouter, encodeFunctionData29({ abi: UNIV2_ROUTER_ABI, functionName: "getAmountsOut", args: [BigInt(10) ** BigInt(usdc.decimals), [usdc.address, usdt.address]] })]);
7800
9318
  cts.push({ kind: "stable", from: "USDT", to: "USDC", dec: usdc.decimals });
7801
- calls.push([dexRouter, encodeFunctionData26({ abi: UNIV2_ROUTER_ABI, functionName: "getAmountsOut", args: [BigInt(10) ** BigInt(usdt.decimals), [usdt.address, usdc.address]] })]);
9319
+ calls.push([dexRouter, encodeFunctionData29({ abi: UNIV2_ROUTER_ABI, functionName: "getAmountsOut", args: [BigInt(10) ** BigInt(usdt.decimals), [usdt.address, usdc.address]] })]);
7802
9320
  }
7803
9321
  if (calls.length === 0) return null;
7804
9322
  const ct0 = Date.now();
@@ -7926,14 +9444,14 @@ function registerArb(parent, getOpts, makeExecutor2) {
7926
9444
  }
7927
9445
 
7928
9446
  // src/commands/positions.ts
7929
- import { encodeFunctionData as encodeFunctionData27, parseAbi as parseAbi30 } from "viem";
7930
- var ERC20_ABI6 = parseAbi30([
9447
+ import { encodeFunctionData as encodeFunctionData30, parseAbi as parseAbi34 } from "viem";
9448
+ var ERC20_ABI6 = parseAbi34([
7931
9449
  "function balanceOf(address owner) external view returns (uint256)"
7932
9450
  ]);
7933
- var POOL_ABI5 = parseAbi30([
9451
+ var POOL_ABI5 = parseAbi34([
7934
9452
  "function getUserAccountData(address user) external view returns (uint256 totalCollateralBase, uint256 totalDebtBase, uint256 availableBorrowsBase, uint256 currentLiquidationThreshold, uint256 ltv, uint256 healthFactor)"
7935
9453
  ]);
7936
- var ORACLE_ABI6 = parseAbi30([
9454
+ var ORACLE_ABI6 = parseAbi34([
7937
9455
  "function getAssetPrice(address asset) external view returns (uint256)"
7938
9456
  ]);
7939
9457
  function round22(x) {
@@ -7962,7 +9480,7 @@ async function scanSingleChain(chainName, rpc, user, tokens, lendingPools, oracl
7962
9480
  callTypes.push({ kind: "token", symbol: token.symbol, decimals: token.decimals });
7963
9481
  calls.push([
7964
9482
  token.address,
7965
- encodeFunctionData27({ abi: ERC20_ABI6, functionName: "balanceOf", args: [user] })
9483
+ encodeFunctionData30({ abi: ERC20_ABI6, functionName: "balanceOf", args: [user] })
7966
9484
  ]);
7967
9485
  }
7968
9486
  }
@@ -7970,14 +9488,14 @@ async function scanSingleChain(chainName, rpc, user, tokens, lendingPools, oracl
7970
9488
  callTypes.push({ kind: "lending", protocol: name, iface });
7971
9489
  calls.push([
7972
9490
  pool,
7973
- encodeFunctionData27({ abi: POOL_ABI5, functionName: "getUserAccountData", args: [user] })
9491
+ encodeFunctionData30({ abi: POOL_ABI5, functionName: "getUserAccountData", args: [user] })
7974
9492
  ]);
7975
9493
  }
7976
9494
  if (oracleAddr) {
7977
9495
  callTypes.push({ kind: "native_price" });
7978
9496
  calls.push([
7979
9497
  oracleAddr,
7980
- encodeFunctionData27({ abi: ORACLE_ABI6, functionName: "getAssetPrice", args: [wrappedNative] })
9498
+ encodeFunctionData30({ abi: ORACLE_ABI6, functionName: "getAssetPrice", args: [wrappedNative] })
7981
9499
  ]);
7982
9500
  }
7983
9501
  if (calls.length === 0) return null;
@@ -8270,14 +9788,14 @@ function registerPrice(parent, getOpts) {
8270
9788
  }
8271
9789
 
8272
9790
  // src/commands/wallet.ts
8273
- import { createPublicClient as createPublicClient19, http as http19, formatEther } from "viem";
9791
+ import { createPublicClient as createPublicClient23, http as http23, formatEther } from "viem";
8274
9792
  function registerWallet(parent, getOpts) {
8275
9793
  const wallet = parent.command("wallet").description("Wallet management");
8276
9794
  wallet.command("balance").description("Show native token balance").requiredOption("--address <address>", "Wallet address to query").action(async (opts) => {
8277
9795
  const chainName = parent.opts().chain ?? "hyperevm";
8278
9796
  const registry = Registry.loadEmbedded();
8279
9797
  const chain = registry.getChain(chainName);
8280
- const client = createPublicClient19({ transport: http19(chain.effectiveRpcUrl()) });
9798
+ const client = createPublicClient23({ transport: http23(chain.effectiveRpcUrl()) });
8281
9799
  const balance = await client.getBalance({ address: opts.address });
8282
9800
  printOutput({
8283
9801
  chain: chain.name,
@@ -8294,14 +9812,14 @@ function registerWallet(parent, getOpts) {
8294
9812
  }
8295
9813
 
8296
9814
  // src/commands/token.ts
8297
- import { createPublicClient as createPublicClient20, http as http20, maxUint256 } from "viem";
9815
+ import { createPublicClient as createPublicClient24, http as http24, maxUint256 } from "viem";
8298
9816
  function registerToken(parent, getOpts, makeExecutor2) {
8299
9817
  const token = parent.command("token").description("Token operations: approve, allowance, transfer, balance");
8300
9818
  token.command("balance").description("Query token balance for an address").requiredOption("--token <token>", "Token symbol or address").requiredOption("--owner <address>", "Wallet address to query").action(async (opts) => {
8301
9819
  const chainName = parent.opts().chain ?? "hyperevm";
8302
9820
  const registry = Registry.loadEmbedded();
8303
9821
  const chain = registry.getChain(chainName);
8304
- const client = createPublicClient20({ transport: http20(chain.effectiveRpcUrl()) });
9822
+ const client = createPublicClient24({ transport: http24(chain.effectiveRpcUrl()) });
8305
9823
  const tokenAddr = opts.token.startsWith("0x") ? opts.token : registry.resolveToken(chainName, opts.token).address;
8306
9824
  const [balance, symbol, decimals] = await Promise.all([
8307
9825
  client.readContract({ address: tokenAddr, abi: erc20Abi, functionName: "balanceOf", args: [opts.owner] }),
@@ -8330,7 +9848,7 @@ function registerToken(parent, getOpts, makeExecutor2) {
8330
9848
  const chainName = parent.opts().chain ?? "hyperevm";
8331
9849
  const registry = Registry.loadEmbedded();
8332
9850
  const chain = registry.getChain(chainName);
8333
- const client = createPublicClient20({ transport: http20(chain.effectiveRpcUrl()) });
9851
+ const client = createPublicClient24({ transport: http24(chain.effectiveRpcUrl()) });
8334
9852
  const tokenAddr = opts.token.startsWith("0x") ? opts.token : registry.resolveToken(chainName, opts.token).address;
8335
9853
  const allowance = await client.readContract({
8336
9854
  address: tokenAddr,
@@ -8352,8 +9870,8 @@ function registerToken(parent, getOpts, makeExecutor2) {
8352
9870
  }
8353
9871
 
8354
9872
  // src/commands/whales.ts
8355
- import { encodeFunctionData as encodeFunctionData28, parseAbi as parseAbi31 } from "viem";
8356
- var POOL_ABI6 = parseAbi31([
9873
+ import { encodeFunctionData as encodeFunctionData31, parseAbi as parseAbi35 } from "viem";
9874
+ var POOL_ABI6 = parseAbi35([
8357
9875
  "function getUserAccountData(address user) external view returns (uint256 totalCollateralBase, uint256 totalDebtBase, uint256 availableBorrowsBase, uint256 currentLiquidationThreshold, uint256 ltv, uint256 healthFactor)"
8358
9876
  ]);
8359
9877
  function round24(x) {
@@ -8464,7 +9982,7 @@ function registerWhales(parent, getOpts) {
8464
9982
  for (const { pool } of lendingPools) {
8465
9983
  calls.push([
8466
9984
  pool,
8467
- encodeFunctionData28({ abi: POOL_ABI6, functionName: "getUserAccountData", args: [whale.address] })
9985
+ encodeFunctionData31({ abi: POOL_ABI6, functionName: "getUserAccountData", args: [whale.address] })
8468
9986
  ]);
8469
9987
  }
8470
9988
  }
@@ -8892,11 +10410,11 @@ function registerBridge(parent, getOpts) {
8892
10410
  const amountUsdc = Number(BigInt(opts.amount)) / 1e6;
8893
10411
  const { fee, maxFeeSubunits } = await getCctpFeeEstimate(srcDomain, dstDomain, amountUsdc);
8894
10412
  const recipientPadded = `0x${"0".repeat(24)}${recipient.replace("0x", "").toLowerCase()}`;
8895
- const { encodeFunctionData: encodeFunctionData29, parseAbi: parseAbi33 } = await import("viem");
8896
- const tokenMessengerAbi = parseAbi33([
10413
+ const { encodeFunctionData: encodeFunctionData33, parseAbi: parseAbi36 } = await import("viem");
10414
+ const tokenMessengerAbi = parseAbi36([
8897
10415
  "function depositForBurn(uint256 amount, uint32 destinationDomain, bytes32 mintRecipient, address burnToken, bytes32 destinationCaller, uint256 maxFee, uint32 minFinalityThreshold) external returns (uint64 nonce)"
8898
10416
  ]);
8899
- const data = encodeFunctionData29({
10417
+ const data = encodeFunctionData33({
8900
10418
  abi: tokenMessengerAbi,
8901
10419
  functionName: "depositForBurn",
8902
10420
  args: [
@@ -9089,6 +10607,124 @@ function registerFarm(parent, getOpts, makeExecutor2) {
9089
10607
  });
9090
10608
  }
9091
10609
 
10610
+ // src/commands/farming.ts
10611
+ import { privateKeyToAccount as privateKeyToAccount3 } from "viem/accounts";
10612
+ function registerFarming(parent, getOpts, makeExecutor2) {
10613
+ const farming = parent.command("farming").description("Algebra eternal farming operations (KittenSwap): enter, exit, collect rewards, claim, discover");
10614
+ farming.command("enter").description("Enter farming: stake an NFT position to start earning rewards").requiredOption("--protocol <protocol>", "Protocol slug (e.g. kittenswap)").requiredOption("--pool <address>", "Pool address").requiredOption("--token-id <id>", "NFT position token ID").option("--owner <address>", "Owner address to receive claimed rewards (defaults to DEFI_WALLET_ADDRESS or private key address)").action(async (opts) => {
10615
+ const executor = makeExecutor2();
10616
+ const registry = Registry.loadEmbedded();
10617
+ const protocol = registry.getProtocol(opts.protocol);
10618
+ const chainName = parent.opts().chain;
10619
+ const chain = registry.getChain(chainName ?? "hyperevm");
10620
+ const rpcUrl = chain.effectiveRpcUrl();
10621
+ const adapter = createKittenSwapFarming(protocol, rpcUrl);
10622
+ const owner = resolveOwner(opts.owner);
10623
+ const tx = await adapter.buildEnterFarming(
10624
+ BigInt(opts.tokenId),
10625
+ opts.pool,
10626
+ owner
10627
+ );
10628
+ const result = await executor.execute(tx);
10629
+ printOutput(result, getOpts());
10630
+ });
10631
+ farming.command("exit").description("Exit farming: unstake an NFT position").requiredOption("--protocol <protocol>", "Protocol slug (e.g. kittenswap)").requiredOption("--pool <address>", "Pool address").requiredOption("--token-id <id>", "NFT position token ID").action(async (opts) => {
10632
+ const executor = makeExecutor2();
10633
+ const registry = Registry.loadEmbedded();
10634
+ const protocol = registry.getProtocol(opts.protocol);
10635
+ const chainName = parent.opts().chain;
10636
+ const chain = registry.getChain(chainName ?? "hyperevm");
10637
+ const rpcUrl = chain.effectiveRpcUrl();
10638
+ const adapter = createKittenSwapFarming(protocol, rpcUrl);
10639
+ const tx = await adapter.buildExitFarming(
10640
+ BigInt(opts.tokenId),
10641
+ opts.pool
10642
+ );
10643
+ const result = await executor.execute(tx);
10644
+ printOutput(result, getOpts());
10645
+ });
10646
+ farming.command("rewards").description("Collect + claim farming rewards for a staked position (collectRewards + claimReward multicall)").requiredOption("--protocol <protocol>", "Protocol slug (e.g. kittenswap)").requiredOption("--pool <address>", "Pool address").requiredOption("--token-id <id>", "NFT position token ID").option("--owner <address>", "Owner address to receive claimed rewards (defaults to DEFI_WALLET_ADDRESS or private key address)").action(async (opts) => {
10647
+ const executor = makeExecutor2();
10648
+ const registry = Registry.loadEmbedded();
10649
+ const protocol = registry.getProtocol(opts.protocol);
10650
+ const chainName = parent.opts().chain;
10651
+ const chain = registry.getChain(chainName ?? "hyperevm");
10652
+ const rpcUrl = chain.effectiveRpcUrl();
10653
+ const adapter = createKittenSwapFarming(protocol, rpcUrl);
10654
+ const owner = resolveOwner(opts.owner);
10655
+ const tx = await adapter.buildCollectRewards(
10656
+ BigInt(opts.tokenId),
10657
+ opts.pool,
10658
+ owner
10659
+ );
10660
+ const result = await executor.execute(tx);
10661
+ printOutput(result, getOpts());
10662
+ });
10663
+ farming.command("claim").description("Claim accumulated farming rewards (KITTEN + WHYPE) without changing position").requiredOption("--protocol <protocol>", "Protocol slug (e.g. kittenswap)").option("--owner <address>", "Owner address to receive rewards (defaults to DEFI_WALLET_ADDRESS or private key address)").action(async (opts) => {
10664
+ const executor = makeExecutor2();
10665
+ const registry = Registry.loadEmbedded();
10666
+ const protocol = registry.getProtocol(opts.protocol);
10667
+ const chainName = parent.opts().chain;
10668
+ const chain = registry.getChain(chainName ?? "hyperevm");
10669
+ const rpcUrl = chain.effectiveRpcUrl();
10670
+ const adapter = createKittenSwapFarming(protocol, rpcUrl);
10671
+ const owner = resolveOwner(opts.owner);
10672
+ const tx = await adapter.buildClaimReward(owner);
10673
+ const result = await executor.execute(tx);
10674
+ printOutput(result, getOpts());
10675
+ });
10676
+ farming.command("pending").description("Query pending farming rewards for a position (read-only)").requiredOption("--protocol <protocol>", "Protocol slug (e.g. kittenswap)").requiredOption("--pool <address>", "Pool address").requiredOption("--token-id <id>", "NFT position token ID").action(async (opts) => {
10677
+ const registry = Registry.loadEmbedded();
10678
+ const protocol = registry.getProtocol(opts.protocol);
10679
+ const chainName = parent.opts().chain;
10680
+ const chain = registry.getChain(chainName ?? "hyperevm");
10681
+ const rpcUrl = chain.effectiveRpcUrl();
10682
+ const adapter = createKittenSwapFarming(protocol, rpcUrl);
10683
+ const rewards = await adapter.getPendingRewards(
10684
+ BigInt(opts.tokenId),
10685
+ opts.pool
10686
+ );
10687
+ printOutput(
10688
+ {
10689
+ tokenId: opts.tokenId,
10690
+ pool: opts.pool,
10691
+ reward_kitten: rewards.reward.toString(),
10692
+ bonus_reward_whype: rewards.bonusReward.toString()
10693
+ },
10694
+ getOpts()
10695
+ );
10696
+ });
10697
+ farming.command("discover").description("Discover all pools with active KittenSwap farming incentives").requiredOption("--protocol <protocol>", "Protocol slug (e.g. kittenswap)").action(async (opts) => {
10698
+ const registry = Registry.loadEmbedded();
10699
+ const protocol = registry.getProtocol(opts.protocol);
10700
+ const chainName = parent.opts().chain;
10701
+ const chain = registry.getChain(chainName ?? "hyperevm");
10702
+ const rpcUrl = chain.effectiveRpcUrl();
10703
+ const adapter = createKittenSwapFarming(protocol, rpcUrl);
10704
+ const pools = await adapter.discoverFarmingPools();
10705
+ const output = pools.map((p) => ({
10706
+ pool: p.pool,
10707
+ nonce: p.key.nonce.toString(),
10708
+ total_reward: p.totalReward.toString(),
10709
+ bonus_reward: p.bonusReward.toString(),
10710
+ active: p.active
10711
+ }));
10712
+ printOutput(output, getOpts());
10713
+ });
10714
+ }
10715
+ function resolveOwner(optOwner) {
10716
+ if (optOwner) return optOwner;
10717
+ const walletAddr = process.env["DEFI_WALLET_ADDRESS"];
10718
+ if (walletAddr) return walletAddr;
10719
+ const privateKey = process.env["DEFI_PRIVATE_KEY"];
10720
+ if (privateKey) {
10721
+ return privateKeyToAccount3(privateKey).address;
10722
+ }
10723
+ throw new Error(
10724
+ "--owner, DEFI_WALLET_ADDRESS, or DEFI_PRIVATE_KEY is required to resolve reward recipient"
10725
+ );
10726
+ }
10727
+
9092
10728
  // src/commands/setup.ts
9093
10729
  import pc2 from "picocolors";
9094
10730
  import { createInterface } from "readline";
@@ -9137,8 +10773,8 @@ function isValidPrivateKey(s) {
9137
10773
  }
9138
10774
  async function deriveAddress(privateKey) {
9139
10775
  try {
9140
- const { privateKeyToAccount: privateKeyToAccount3 } = await import("viem/accounts");
9141
- const account = privateKeyToAccount3(privateKey);
10776
+ const { privateKeyToAccount: privateKeyToAccount4 } = await import("viem/accounts");
10777
+ const account = privateKeyToAccount4(privateKey);
9142
10778
  return account.address;
9143
10779
  } catch {
9144
10780
  return null;
@@ -9345,7 +10981,7 @@ var BANNER = `
9345
10981
  \u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551
9346
10982
  \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D
9347
10983
 
9348
- 2 chains \xB7 30 protocols \xB7 by HypurrQuant
10984
+ 2 chains \xB7 23 protocols \xB7 by HypurrQuant
9349
10985
 
9350
10986
  Scan exploits, swap tokens, bridge assets, track whales,
9351
10987
  compare yields \u2014 all from your terminal.
@@ -9385,6 +11021,7 @@ registerSwap(program, getOutputMode, makeExecutor);
9385
11021
  registerBridge(program, getOutputMode);
9386
11022
  registerNft(program, getOutputMode);
9387
11023
  registerFarm(program, getOutputMode, makeExecutor);
11024
+ registerFarming(program, getOutputMode, makeExecutor);
9388
11025
  registerLB(program, getOutputMode, makeExecutor);
9389
11026
  registerSetup(program);
9390
11027
  program.command("agent").description("Agent mode: read JSON commands from stdin (for AI agents)").action(async () => {