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