@hypurrquant/defi-cli 0.2.4 → 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/config/tokens/hyperevm.toml +1 -1
- package/dist/index.js +1335 -363
- package/dist/index.js.map +1 -1
- package/dist/main.js +1321 -352
- package/dist/main.js.map +1 -1
- package/dist/mcp-server.js +1160 -299
- 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; }",
|
|
@@ -1542,7 +1711,8 @@ var init_dist3 = __esm({
|
|
|
1542
1711
|
to: this.router,
|
|
1543
1712
|
data,
|
|
1544
1713
|
value: 0n,
|
|
1545
|
-
gas_estimate: 2e5
|
|
1714
|
+
gas_estimate: 2e5,
|
|
1715
|
+
approvals: [{ token: params.token_in, spender: this.router, amount: params.amount_in }]
|
|
1546
1716
|
};
|
|
1547
1717
|
}
|
|
1548
1718
|
async quote(params) {
|
|
@@ -1712,7 +1882,11 @@ var init_dist3 = __esm({
|
|
|
1712
1882
|
to: pm,
|
|
1713
1883
|
data,
|
|
1714
1884
|
value: 0n,
|
|
1715
|
-
gas_estimate: 5e5
|
|
1885
|
+
gas_estimate: 5e5,
|
|
1886
|
+
approvals: [
|
|
1887
|
+
{ token: token0, spender: pm, amount: amount0 },
|
|
1888
|
+
{ token: token1, spender: pm, amount: amount1 }
|
|
1889
|
+
]
|
|
1716
1890
|
};
|
|
1717
1891
|
}
|
|
1718
1892
|
async buildRemoveLiquidity(_params) {
|
|
@@ -1771,7 +1945,8 @@ var init_dist3 = __esm({
|
|
|
1771
1945
|
to: this.router,
|
|
1772
1946
|
data,
|
|
1773
1947
|
value: 0n,
|
|
1774
|
-
gas_estimate: 15e4
|
|
1948
|
+
gas_estimate: 15e4,
|
|
1949
|
+
approvals: [{ token: params.token_in, spender: this.router, amount: params.amount_in }]
|
|
1775
1950
|
};
|
|
1776
1951
|
}
|
|
1777
1952
|
async quote(params) {
|
|
@@ -1890,7 +2065,11 @@ var init_dist3 = __esm({
|
|
|
1890
2065
|
to: this.router,
|
|
1891
2066
|
data,
|
|
1892
2067
|
value: 0n,
|
|
1893
|
-
gas_estimate: 3e5
|
|
2068
|
+
gas_estimate: 3e5,
|
|
2069
|
+
approvals: [
|
|
2070
|
+
{ token: params.token_a, spender: this.router, amount: params.amount_a },
|
|
2071
|
+
{ token: params.token_b, spender: this.router, amount: params.amount_b }
|
|
2072
|
+
]
|
|
1894
2073
|
};
|
|
1895
2074
|
}
|
|
1896
2075
|
async buildRemoveLiquidity(params) {
|
|
@@ -1977,7 +2156,8 @@ var init_dist3 = __esm({
|
|
|
1977
2156
|
to: this.router,
|
|
1978
2157
|
data,
|
|
1979
2158
|
value: 0n,
|
|
1980
|
-
gas_estimate: 25e4
|
|
2159
|
+
gas_estimate: 25e4,
|
|
2160
|
+
approvals: [{ token: params.token_in, spender: this.router, amount: params.amount_in }]
|
|
1981
2161
|
};
|
|
1982
2162
|
}
|
|
1983
2163
|
async quote(params) {
|
|
@@ -2095,7 +2275,11 @@ var init_dist3 = __esm({
|
|
|
2095
2275
|
to: pm,
|
|
2096
2276
|
data,
|
|
2097
2277
|
value: 0n,
|
|
2098
|
-
gas_estimate: 5e5
|
|
2278
|
+
gas_estimate: 5e5,
|
|
2279
|
+
approvals: [
|
|
2280
|
+
{ token: token0, spender: pm, amount: amount0 },
|
|
2281
|
+
{ token: token1, spender: pm, amount: amount1 }
|
|
2282
|
+
]
|
|
2099
2283
|
};
|
|
2100
2284
|
}
|
|
2101
2285
|
async buildRemoveLiquidity(_params) {
|
|
@@ -2272,18 +2456,10 @@ var init_dist3 = __esm({
|
|
|
2272
2456
|
to: this.router,
|
|
2273
2457
|
data,
|
|
2274
2458
|
value: 0n,
|
|
2275
|
-
gas_estimate: 2e5
|
|
2459
|
+
gas_estimate: 2e5,
|
|
2460
|
+
approvals: [{ token: params.token_in, spender: this.router, amount: params.amount_in }]
|
|
2276
2461
|
};
|
|
2277
2462
|
}
|
|
2278
|
-
async callGetAmountsOut(client, callData) {
|
|
2279
|
-
const result = await client.call({ to: this.router, data: callData });
|
|
2280
|
-
if (!result.data) return 0n;
|
|
2281
|
-
const [amounts] = decodeAbiParameters4(
|
|
2282
|
-
[{ name: "amounts", type: "uint256[]" }],
|
|
2283
|
-
result.data
|
|
2284
|
-
);
|
|
2285
|
-
return amounts.length >= 2 ? amounts[amounts.length - 1] : 0n;
|
|
2286
|
-
}
|
|
2287
2463
|
encodeV1(params, stable) {
|
|
2288
2464
|
return encodeFunctionData6({
|
|
2289
2465
|
abi: abi4,
|
|
@@ -2300,7 +2476,6 @@ var init_dist3 = __esm({
|
|
|
2300
2476
|
}
|
|
2301
2477
|
async quote(params) {
|
|
2302
2478
|
if (!this.rpcUrl) throw DefiError.rpcError("No RPC URL configured");
|
|
2303
|
-
const client = createPublicClient4({ transport: http4(this.rpcUrl) });
|
|
2304
2479
|
const candidates = [
|
|
2305
2480
|
{ callData: this.encodeV1(params, false), stable: false },
|
|
2306
2481
|
{ callData: this.encodeV1(params, true), stable: true }
|
|
@@ -2311,16 +2486,26 @@ var init_dist3 = __esm({
|
|
|
2311
2486
|
{ callData: this.encodeV2(params, true), stable: true }
|
|
2312
2487
|
);
|
|
2313
2488
|
}
|
|
2314
|
-
const
|
|
2315
|
-
|
|
2489
|
+
const rawResults = await multicallRead(
|
|
2490
|
+
this.rpcUrl,
|
|
2491
|
+
candidates.map((c) => [this.router, c.callData])
|
|
2316
2492
|
);
|
|
2317
2493
|
let bestOut = 0n;
|
|
2318
2494
|
let bestStable = false;
|
|
2319
|
-
for (let i = 0; i <
|
|
2320
|
-
const
|
|
2321
|
-
if (
|
|
2322
|
-
|
|
2323
|
-
|
|
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 {
|
|
2324
2509
|
}
|
|
2325
2510
|
}
|
|
2326
2511
|
if (bestOut === 0n) {
|
|
@@ -2355,7 +2540,11 @@ var init_dist3 = __esm({
|
|
|
2355
2540
|
to: this.router,
|
|
2356
2541
|
data,
|
|
2357
2542
|
value: 0n,
|
|
2358
|
-
gas_estimate: 35e4
|
|
2543
|
+
gas_estimate: 35e4,
|
|
2544
|
+
approvals: [
|
|
2545
|
+
{ token: params.token_a, spender: this.router, amount: params.amount_a },
|
|
2546
|
+
{ token: params.token_b, spender: this.router, amount: params.amount_b }
|
|
2547
|
+
]
|
|
2359
2548
|
};
|
|
2360
2549
|
}
|
|
2361
2550
|
async buildRemoveLiquidity(params) {
|
|
@@ -2481,7 +2670,7 @@ var init_dist3 = __esm({
|
|
|
2481
2670
|
return this.protocolName;
|
|
2482
2671
|
}
|
|
2483
2672
|
// IGauge
|
|
2484
|
-
async buildDeposit(gauge, amount, tokenId) {
|
|
2673
|
+
async buildDeposit(gauge, amount, tokenId, lpToken) {
|
|
2485
2674
|
if (tokenId !== void 0) {
|
|
2486
2675
|
const data2 = encodeFunctionData8({
|
|
2487
2676
|
abi: gaugeAbi,
|
|
@@ -2493,7 +2682,8 @@ var init_dist3 = __esm({
|
|
|
2493
2682
|
to: gauge,
|
|
2494
2683
|
data: data2,
|
|
2495
2684
|
value: 0n,
|
|
2496
|
-
gas_estimate: 2e5
|
|
2685
|
+
gas_estimate: 2e5,
|
|
2686
|
+
approvals: lpToken ? [{ token: lpToken, spender: gauge, amount }] : void 0
|
|
2497
2687
|
};
|
|
2498
2688
|
}
|
|
2499
2689
|
const data = encodeFunctionData8({
|
|
@@ -2506,7 +2696,8 @@ var init_dist3 = __esm({
|
|
|
2506
2696
|
to: gauge,
|
|
2507
2697
|
data,
|
|
2508
2698
|
value: 0n,
|
|
2509
|
-
gas_estimate: 2e5
|
|
2699
|
+
gas_estimate: 2e5,
|
|
2700
|
+
approvals: lpToken ? [{ token: lpToken, spender: gauge, amount }] : void 0
|
|
2510
2701
|
};
|
|
2511
2702
|
}
|
|
2512
2703
|
async buildWithdraw(gauge, amount) {
|
|
@@ -2526,7 +2717,7 @@ var init_dist3 = __esm({
|
|
|
2526
2717
|
async buildClaimRewards(gauge, account) {
|
|
2527
2718
|
if (account && this.rpcUrl) {
|
|
2528
2719
|
try {
|
|
2529
|
-
const client =
|
|
2720
|
+
const client = createPublicClient4({ transport: http4(this.rpcUrl) });
|
|
2530
2721
|
const listLen = await client.readContract({
|
|
2531
2722
|
address: gauge,
|
|
2532
2723
|
abi: gaugeAbi,
|
|
@@ -2784,7 +2975,7 @@ var init_dist3 = __esm({
|
|
|
2784
2975
|
if (!this.rpcUrl) {
|
|
2785
2976
|
throw DefiError.unsupported(`[${this.protocolName}] getPendingRewards requires RPC`);
|
|
2786
2977
|
}
|
|
2787
|
-
const client =
|
|
2978
|
+
const client = createPublicClient5({ transport: http5(this.rpcUrl) });
|
|
2788
2979
|
const rewards = await client.readContract({
|
|
2789
2980
|
address: this.masterchef,
|
|
2790
2981
|
abi: masterchefAbi,
|
|
@@ -2798,7 +2989,591 @@ var init_dist3 = __esm({
|
|
|
2798
2989
|
}));
|
|
2799
2990
|
}
|
|
2800
2991
|
};
|
|
2801
|
-
|
|
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([
|
|
2802
3577
|
"function supply(address asset, uint256 amount, address onBehalfOf, uint16 referralCode) external",
|
|
2803
3578
|
"function borrow(address asset, uint256 amount, uint256 interestRateMode, uint16 referralCode, address onBehalfOf) external",
|
|
2804
3579
|
"function repay(address asset, uint256 amount, uint256 interestRateMode, address onBehalfOf) external returns (uint256)",
|
|
@@ -2806,27 +3581,27 @@ var init_dist3 = __esm({
|
|
|
2806
3581
|
"function getUserAccountData(address user) external view returns (uint256 totalCollateralBase, uint256 totalDebtBase, uint256 availableBorrowsBase, uint256 currentLiquidationThreshold, uint256 ltv, uint256 healthFactor)",
|
|
2807
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)"
|
|
2808
3583
|
]);
|
|
2809
|
-
ERC20_ABI =
|
|
3584
|
+
ERC20_ABI = parseAbi11([
|
|
2810
3585
|
"function totalSupply() external view returns (uint256)"
|
|
2811
3586
|
]);
|
|
2812
|
-
INCENTIVES_ABI =
|
|
3587
|
+
INCENTIVES_ABI = parseAbi11([
|
|
2813
3588
|
"function getIncentivesController() external view returns (address)"
|
|
2814
3589
|
]);
|
|
2815
|
-
REWARDS_CONTROLLER_ABI =
|
|
3590
|
+
REWARDS_CONTROLLER_ABI = parseAbi11([
|
|
2816
3591
|
"function getRewardsByAsset(address asset) external view returns (address[])",
|
|
2817
3592
|
"function getRewardsData(address asset, address reward) external view returns (uint256 index, uint256 emissionsPerSecond, uint256 lastUpdateTimestamp, uint256 distributionEnd)"
|
|
2818
3593
|
]);
|
|
2819
|
-
POOL_PROVIDER_ABI =
|
|
3594
|
+
POOL_PROVIDER_ABI = parseAbi11([
|
|
2820
3595
|
"function ADDRESSES_PROVIDER() external view returns (address)"
|
|
2821
3596
|
]);
|
|
2822
|
-
ADDRESSES_PROVIDER_ABI =
|
|
3597
|
+
ADDRESSES_PROVIDER_ABI = parseAbi11([
|
|
2823
3598
|
"function getPriceOracle() external view returns (address)"
|
|
2824
3599
|
]);
|
|
2825
|
-
ORACLE_ABI =
|
|
3600
|
+
ORACLE_ABI = parseAbi11([
|
|
2826
3601
|
"function getAssetPrice(address asset) external view returns (uint256)",
|
|
2827
3602
|
"function BASE_CURRENCY_UNIT() external view returns (uint256)"
|
|
2828
3603
|
]);
|
|
2829
|
-
ERC20_DECIMALS_ABI =
|
|
3604
|
+
ERC20_DECIMALS_ABI = parseAbi11([
|
|
2830
3605
|
"function decimals() external view returns (uint8)"
|
|
2831
3606
|
]);
|
|
2832
3607
|
AaveV3Adapter = class {
|
|
@@ -2844,7 +3619,7 @@ var init_dist3 = __esm({
|
|
|
2844
3619
|
return this.protocolName;
|
|
2845
3620
|
}
|
|
2846
3621
|
async buildSupply(params) {
|
|
2847
|
-
const data =
|
|
3622
|
+
const data = encodeFunctionData11({
|
|
2848
3623
|
abi: POOL_ABI,
|
|
2849
3624
|
functionName: "supply",
|
|
2850
3625
|
args: [params.asset, params.amount, params.on_behalf_of, 0]
|
|
@@ -2854,12 +3629,13 @@ var init_dist3 = __esm({
|
|
|
2854
3629
|
to: this.pool,
|
|
2855
3630
|
data,
|
|
2856
3631
|
value: 0n,
|
|
2857
|
-
gas_estimate: 3e5
|
|
3632
|
+
gas_estimate: 3e5,
|
|
3633
|
+
approvals: [{ token: params.asset, spender: this.pool, amount: params.amount }]
|
|
2858
3634
|
};
|
|
2859
3635
|
}
|
|
2860
3636
|
async buildBorrow(params) {
|
|
2861
3637
|
const rateMode = params.interest_rate_mode === InterestRateMode.Stable ? 1n : 2n;
|
|
2862
|
-
const data =
|
|
3638
|
+
const data = encodeFunctionData11({
|
|
2863
3639
|
abi: POOL_ABI,
|
|
2864
3640
|
functionName: "borrow",
|
|
2865
3641
|
args: [params.asset, params.amount, rateMode, 0, params.on_behalf_of]
|
|
@@ -2874,7 +3650,7 @@ var init_dist3 = __esm({
|
|
|
2874
3650
|
}
|
|
2875
3651
|
async buildRepay(params) {
|
|
2876
3652
|
const rateMode = params.interest_rate_mode === InterestRateMode.Stable ? 1n : 2n;
|
|
2877
|
-
const data =
|
|
3653
|
+
const data = encodeFunctionData11({
|
|
2878
3654
|
abi: POOL_ABI,
|
|
2879
3655
|
functionName: "repay",
|
|
2880
3656
|
args: [params.asset, params.amount, rateMode, params.on_behalf_of]
|
|
@@ -2884,11 +3660,12 @@ var init_dist3 = __esm({
|
|
|
2884
3660
|
to: this.pool,
|
|
2885
3661
|
data,
|
|
2886
3662
|
value: 0n,
|
|
2887
|
-
gas_estimate: 3e5
|
|
3663
|
+
gas_estimate: 3e5,
|
|
3664
|
+
approvals: [{ token: params.asset, spender: this.pool, amount: params.amount }]
|
|
2888
3665
|
};
|
|
2889
3666
|
}
|
|
2890
3667
|
async buildWithdraw(params) {
|
|
2891
|
-
const data =
|
|
3668
|
+
const data = encodeFunctionData11({
|
|
2892
3669
|
abi: POOL_ABI,
|
|
2893
3670
|
functionName: "withdraw",
|
|
2894
3671
|
args: [params.asset, params.amount, params.to]
|
|
@@ -2903,15 +3680,21 @@ var init_dist3 = __esm({
|
|
|
2903
3680
|
}
|
|
2904
3681
|
async getRates(asset) {
|
|
2905
3682
|
if (!this.rpcUrl) throw DefiError.rpcError("No RPC URL configured");
|
|
2906
|
-
const
|
|
2907
|
-
const result = await client.readContract({
|
|
2908
|
-
address: this.pool,
|
|
3683
|
+
const reserveCallData = encodeFunctionData11({
|
|
2909
3684
|
abi: POOL_ABI,
|
|
2910
3685
|
functionName: "getReserveData",
|
|
2911
3686
|
args: [asset]
|
|
2912
|
-
})
|
|
3687
|
+
});
|
|
3688
|
+
const [reserveRaw] = await multicallRead(this.rpcUrl, [
|
|
3689
|
+
[this.pool, reserveCallData]
|
|
3690
|
+
]).catch((e) => {
|
|
2913
3691
|
throw DefiError.rpcError(`[${this.protocolName}] getReserveData failed: ${e}`);
|
|
2914
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;
|
|
2915
3698
|
const RAY = 1e27;
|
|
2916
3699
|
const SECONDS_PER_YEAR4 = 31536e3;
|
|
2917
3700
|
const toApy = (rayRate) => {
|
|
@@ -2923,74 +3706,56 @@ var init_dist3 = __esm({
|
|
|
2923
3706
|
const stableRate = toApy(result[5]);
|
|
2924
3707
|
const aTokenAddress = result[8];
|
|
2925
3708
|
const variableDebtTokenAddress = result[10];
|
|
2926
|
-
const [
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
abi: ERC20_ABI,
|
|
2930
|
-
functionName: "totalSupply"
|
|
2931
|
-
}).catch(() => 0n),
|
|
2932
|
-
client.readContract({
|
|
2933
|
-
address: variableDebtTokenAddress,
|
|
2934
|
-
abi: ERC20_ABI,
|
|
2935
|
-
functionName: "totalSupply"
|
|
2936
|
-
}).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" })]
|
|
2937
3712
|
]);
|
|
3713
|
+
const totalSupply = decodeU256(supplyRaw ?? null);
|
|
3714
|
+
const totalBorrow = decodeU256(borrowRaw ?? null);
|
|
2938
3715
|
const utilization = totalSupply > 0n ? Number(totalBorrow * 10000n / totalSupply) / 100 : 0;
|
|
2939
3716
|
const supplyRewardTokens = [];
|
|
2940
3717
|
const borrowRewardTokens = [];
|
|
2941
3718
|
const supplyEmissions = [];
|
|
2942
3719
|
const borrowEmissions = [];
|
|
2943
3720
|
try {
|
|
2944
|
-
const
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
});
|
|
3721
|
+
const [controllerRaw] = await multicallRead(this.rpcUrl, [
|
|
3722
|
+
[aTokenAddress, encodeFunctionData11({ abi: INCENTIVES_ABI, functionName: "getIncentivesController" })]
|
|
3723
|
+
]);
|
|
3724
|
+
const controllerAddr = decodeAddress(controllerRaw ?? null);
|
|
2949
3725
|
if (controllerAddr && controllerAddr !== zeroAddress5) {
|
|
2950
|
-
const [
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
abi: REWARDS_CONTROLLER_ABI,
|
|
2954
|
-
functionName: "getRewardsByAsset",
|
|
2955
|
-
args: [aTokenAddress]
|
|
2956
|
-
}).catch(() => []),
|
|
2957
|
-
client.readContract({
|
|
2958
|
-
address: controllerAddr,
|
|
2959
|
-
abi: REWARDS_CONTROLLER_ABI,
|
|
2960
|
-
functionName: "getRewardsByAsset",
|
|
2961
|
-
args: [variableDebtTokenAddress]
|
|
2962
|
-
}).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] })]
|
|
2963
3729
|
]);
|
|
2964
|
-
const
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
|
|
2969
|
-
args: [aTokenAddress, reward]
|
|
2970
|
-
|
|
2971
|
-
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
|
|
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
|
+
}
|
|
2978
3752
|
}
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
args: [variableDebtTokenAddress, reward]
|
|
2986
|
-
}).catch(() => null)
|
|
2987
|
-
);
|
|
2988
|
-
const borrowData = await Promise.all(borrowDataPromises);
|
|
2989
|
-
for (let i = 0; i < borrowRewards.length; i++) {
|
|
2990
|
-
const data = borrowData[i];
|
|
2991
|
-
if (data && data[1] > 0n) {
|
|
2992
|
-
borrowRewardTokens.push(borrowRewards[i]);
|
|
2993
|
-
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
|
+
}
|
|
2994
3759
|
}
|
|
2995
3760
|
}
|
|
2996
3761
|
}
|
|
@@ -3002,55 +3767,49 @@ var init_dist3 = __esm({
|
|
|
3002
3767
|
const hasBorrowRewards = borrowRewardTokens.length > 0;
|
|
3003
3768
|
if ((hasSupplyRewards || hasBorrowRewards) && totalSupply > 0n) {
|
|
3004
3769
|
try {
|
|
3005
|
-
const
|
|
3006
|
-
|
|
3007
|
-
abi: POOL_PROVIDER_ABI,
|
|
3008
|
-
functionName: "ADDRESSES_PROVIDER"
|
|
3009
|
-
});
|
|
3010
|
-
const oracleAddr = await client.readContract({
|
|
3011
|
-
address: providerAddr,
|
|
3012
|
-
abi: ADDRESSES_PROVIDER_ABI,
|
|
3013
|
-
functionName: "getPriceOracle"
|
|
3014
|
-
});
|
|
3015
|
-
const [assetPrice, baseCurrencyUnit, assetDecimals] = await Promise.all([
|
|
3016
|
-
client.readContract({
|
|
3017
|
-
address: oracleAddr,
|
|
3018
|
-
abi: ORACLE_ABI,
|
|
3019
|
-
functionName: "getAssetPrice",
|
|
3020
|
-
args: [asset]
|
|
3021
|
-
}),
|
|
3022
|
-
client.readContract({
|
|
3023
|
-
address: oracleAddr,
|
|
3024
|
-
abi: ORACLE_ABI,
|
|
3025
|
-
functionName: "BASE_CURRENCY_UNIT"
|
|
3026
|
-
}),
|
|
3027
|
-
client.readContract({
|
|
3028
|
-
address: asset,
|
|
3029
|
-
abi: ERC20_DECIMALS_ABI,
|
|
3030
|
-
functionName: "decimals"
|
|
3031
|
-
}).catch(() => 18)
|
|
3770
|
+
const [providerRaw] = await multicallRead(this.rpcUrl, [
|
|
3771
|
+
[this.pool, encodeFunctionData11({ abi: POOL_PROVIDER_ABI, functionName: "ADDRESSES_PROVIDER" })]
|
|
3032
3772
|
]);
|
|
3033
|
-
const
|
|
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" })]
|
|
3777
|
+
]);
|
|
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;
|
|
3034
3789
|
const assetPriceF = Number(assetPrice) / priceUnit;
|
|
3035
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
|
+
}
|
|
3036
3805
|
if (hasSupplyRewards) {
|
|
3037
3806
|
let totalSupplyIncentiveUsdPerYear = 0;
|
|
3038
3807
|
const totalSupplyUsd = Number(totalSupply) / assetDecimalsDivisor * assetPriceF;
|
|
3039
3808
|
for (let i = 0; i < supplyRewardTokens.length; i++) {
|
|
3040
3809
|
const emissionPerSec = BigInt(supplyEmissions[i]);
|
|
3041
|
-
const
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
abi: ORACLE_ABI,
|
|
3045
|
-
functionName: "getAssetPrice",
|
|
3046
|
-
args: [supplyRewardTokens[i]]
|
|
3047
|
-
}).catch(() => 0n),
|
|
3048
|
-
client.readContract({
|
|
3049
|
-
address: supplyRewardTokens[i],
|
|
3050
|
-
abi: ERC20_DECIMALS_ABI,
|
|
3051
|
-
functionName: "decimals"
|
|
3052
|
-
}).catch(() => 18)
|
|
3053
|
-
]);
|
|
3810
|
+
const entry = rewardPriceMap.get(supplyRewardTokens[i].toLowerCase());
|
|
3811
|
+
const rewardPrice = entry?.price ?? 0n;
|
|
3812
|
+
const rewardDecimals = entry?.decimals ?? 18;
|
|
3054
3813
|
if (rewardPrice > 0n) {
|
|
3055
3814
|
const rewardPriceF = Number(rewardPrice) / priceUnit;
|
|
3056
3815
|
const emissionPerYear = Number(emissionPerSec) / 10 ** rewardDecimals * SECONDS_PER_YEAR4;
|
|
@@ -3066,19 +3825,9 @@ var init_dist3 = __esm({
|
|
|
3066
3825
|
const totalBorrowUsd = Number(totalBorrow) / assetDecimalsDivisor * assetPriceF;
|
|
3067
3826
|
for (let i = 0; i < borrowRewardTokens.length; i++) {
|
|
3068
3827
|
const emissionPerSec = BigInt(borrowEmissions[i]);
|
|
3069
|
-
const
|
|
3070
|
-
|
|
3071
|
-
|
|
3072
|
-
abi: ORACLE_ABI,
|
|
3073
|
-
functionName: "getAssetPrice",
|
|
3074
|
-
args: [borrowRewardTokens[i]]
|
|
3075
|
-
}).catch(() => 0n),
|
|
3076
|
-
client.readContract({
|
|
3077
|
-
address: borrowRewardTokens[i],
|
|
3078
|
-
abi: ERC20_DECIMALS_ABI,
|
|
3079
|
-
functionName: "decimals"
|
|
3080
|
-
}).catch(() => 18)
|
|
3081
|
-
]);
|
|
3828
|
+
const entry = rewardPriceMap.get(borrowRewardTokens[i].toLowerCase());
|
|
3829
|
+
const rewardPrice = entry?.price ?? 0n;
|
|
3830
|
+
const rewardDecimals = entry?.decimals ?? 18;
|
|
3082
3831
|
if (rewardPrice > 0n) {
|
|
3083
3832
|
const rewardPriceF = Number(rewardPrice) / priceUnit;
|
|
3084
3833
|
const emissionPerYear = Number(emissionPerSec) / 10 ** rewardDecimals * SECONDS_PER_YEAR4;
|
|
@@ -3142,7 +3891,7 @@ var init_dist3 = __esm({
|
|
|
3142
3891
|
};
|
|
3143
3892
|
}
|
|
3144
3893
|
};
|
|
3145
|
-
POOL_ABI2 =
|
|
3894
|
+
POOL_ABI2 = parseAbi12([
|
|
3146
3895
|
"function deposit(address asset, uint256 amount, address onBehalfOf, uint16 referralCode) external",
|
|
3147
3896
|
"function borrow(address asset, uint256 amount, uint256 interestRateMode, uint16 referralCode, address onBehalfOf) external",
|
|
3148
3897
|
"function repay(address asset, uint256 amount, uint256 rateMode, address onBehalfOf) external returns (uint256)",
|
|
@@ -3155,7 +3904,7 @@ var init_dist3 = __esm({
|
|
|
3155
3904
|
// [9]=variableDebtTokenAddress, [10]=interestRateStrategyAddress, [11]=id
|
|
3156
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)"
|
|
3157
3906
|
]);
|
|
3158
|
-
ERC20_ABI2 =
|
|
3907
|
+
ERC20_ABI2 = parseAbi12([
|
|
3159
3908
|
"function totalSupply() external view returns (uint256)"
|
|
3160
3909
|
]);
|
|
3161
3910
|
AaveV2Adapter = class {
|
|
@@ -3173,7 +3922,7 @@ var init_dist3 = __esm({
|
|
|
3173
3922
|
return this.protocolName;
|
|
3174
3923
|
}
|
|
3175
3924
|
async buildSupply(params) {
|
|
3176
|
-
const data =
|
|
3925
|
+
const data = encodeFunctionData12({
|
|
3177
3926
|
abi: POOL_ABI2,
|
|
3178
3927
|
functionName: "deposit",
|
|
3179
3928
|
args: [params.asset, params.amount, params.on_behalf_of, 0]
|
|
@@ -3183,12 +3932,13 @@ var init_dist3 = __esm({
|
|
|
3183
3932
|
to: this.pool,
|
|
3184
3933
|
data,
|
|
3185
3934
|
value: 0n,
|
|
3186
|
-
gas_estimate: 3e5
|
|
3935
|
+
gas_estimate: 3e5,
|
|
3936
|
+
approvals: [{ token: params.asset, spender: this.pool, amount: params.amount }]
|
|
3187
3937
|
};
|
|
3188
3938
|
}
|
|
3189
3939
|
async buildBorrow(params) {
|
|
3190
3940
|
const rateMode = params.interest_rate_mode === InterestRateMode.Stable ? 1n : 2n;
|
|
3191
|
-
const data =
|
|
3941
|
+
const data = encodeFunctionData12({
|
|
3192
3942
|
abi: POOL_ABI2,
|
|
3193
3943
|
functionName: "borrow",
|
|
3194
3944
|
args: [params.asset, params.amount, rateMode, 0, params.on_behalf_of]
|
|
@@ -3203,7 +3953,7 @@ var init_dist3 = __esm({
|
|
|
3203
3953
|
}
|
|
3204
3954
|
async buildRepay(params) {
|
|
3205
3955
|
const rateMode = params.interest_rate_mode === InterestRateMode.Stable ? 1n : 2n;
|
|
3206
|
-
const data =
|
|
3956
|
+
const data = encodeFunctionData12({
|
|
3207
3957
|
abi: POOL_ABI2,
|
|
3208
3958
|
functionName: "repay",
|
|
3209
3959
|
args: [params.asset, params.amount, rateMode, params.on_behalf_of]
|
|
@@ -3213,11 +3963,12 @@ var init_dist3 = __esm({
|
|
|
3213
3963
|
to: this.pool,
|
|
3214
3964
|
data,
|
|
3215
3965
|
value: 0n,
|
|
3216
|
-
gas_estimate: 3e5
|
|
3966
|
+
gas_estimate: 3e5,
|
|
3967
|
+
approvals: [{ token: params.asset, spender: this.pool, amount: params.amount }]
|
|
3217
3968
|
};
|
|
3218
3969
|
}
|
|
3219
3970
|
async buildWithdraw(params) {
|
|
3220
|
-
const data =
|
|
3971
|
+
const data = encodeFunctionData12({
|
|
3221
3972
|
abi: POOL_ABI2,
|
|
3222
3973
|
functionName: "withdraw",
|
|
3223
3974
|
args: [params.asset, params.amount, params.to]
|
|
@@ -3305,7 +4056,7 @@ var init_dist3 = __esm({
|
|
|
3305
4056
|
};
|
|
3306
4057
|
}
|
|
3307
4058
|
};
|
|
3308
|
-
ORACLE_ABI2 =
|
|
4059
|
+
ORACLE_ABI2 = parseAbi13([
|
|
3309
4060
|
"function getAssetPrice(address asset) external view returns (uint256)",
|
|
3310
4061
|
"function getAssetsPrices(address[] calldata assets) external view returns (uint256[] memory)",
|
|
3311
4062
|
"function BASE_CURRENCY_UNIT() external view returns (uint256)"
|
|
@@ -3382,7 +4133,7 @@ var init_dist3 = __esm({
|
|
|
3382
4133
|
});
|
|
3383
4134
|
}
|
|
3384
4135
|
};
|
|
3385
|
-
CTOKEN_ABI =
|
|
4136
|
+
CTOKEN_ABI = parseAbi14([
|
|
3386
4137
|
"function supplyRatePerBlock() external view returns (uint256)",
|
|
3387
4138
|
"function borrowRatePerBlock() external view returns (uint256)",
|
|
3388
4139
|
"function totalSupply() external view returns (uint256)",
|
|
@@ -3409,7 +4160,7 @@ var init_dist3 = __esm({
|
|
|
3409
4160
|
return this.protocolName;
|
|
3410
4161
|
}
|
|
3411
4162
|
async buildSupply(params) {
|
|
3412
|
-
const data =
|
|
4163
|
+
const data = encodeFunctionData13({
|
|
3413
4164
|
abi: CTOKEN_ABI,
|
|
3414
4165
|
functionName: "mint",
|
|
3415
4166
|
args: [params.amount]
|
|
@@ -3423,7 +4174,7 @@ var init_dist3 = __esm({
|
|
|
3423
4174
|
};
|
|
3424
4175
|
}
|
|
3425
4176
|
async buildBorrow(params) {
|
|
3426
|
-
const data =
|
|
4177
|
+
const data = encodeFunctionData13({
|
|
3427
4178
|
abi: CTOKEN_ABI,
|
|
3428
4179
|
functionName: "borrow",
|
|
3429
4180
|
args: [params.amount]
|
|
@@ -3437,7 +4188,7 @@ var init_dist3 = __esm({
|
|
|
3437
4188
|
};
|
|
3438
4189
|
}
|
|
3439
4190
|
async buildRepay(params) {
|
|
3440
|
-
const data =
|
|
4191
|
+
const data = encodeFunctionData13({
|
|
3441
4192
|
abi: CTOKEN_ABI,
|
|
3442
4193
|
functionName: "repayBorrow",
|
|
3443
4194
|
args: [params.amount]
|
|
@@ -3451,7 +4202,7 @@ var init_dist3 = __esm({
|
|
|
3451
4202
|
};
|
|
3452
4203
|
}
|
|
3453
4204
|
async buildWithdraw(params) {
|
|
3454
|
-
const data =
|
|
4205
|
+
const data = encodeFunctionData13({
|
|
3455
4206
|
abi: CTOKEN_ABI,
|
|
3456
4207
|
functionName: "redeem",
|
|
3457
4208
|
args: [params.amount]
|
|
@@ -3500,7 +4251,7 @@ var init_dist3 = __esm({
|
|
|
3500
4251
|
);
|
|
3501
4252
|
}
|
|
3502
4253
|
};
|
|
3503
|
-
COMET_ABI =
|
|
4254
|
+
COMET_ABI = parseAbi15([
|
|
3504
4255
|
"function getUtilization() external view returns (uint256)",
|
|
3505
4256
|
"function getSupplyRate(uint256 utilization) external view returns (uint64)",
|
|
3506
4257
|
"function getBorrowRate(uint256 utilization) external view returns (uint64)",
|
|
@@ -3526,7 +4277,7 @@ var init_dist3 = __esm({
|
|
|
3526
4277
|
return this.protocolName;
|
|
3527
4278
|
}
|
|
3528
4279
|
async buildSupply(params) {
|
|
3529
|
-
const data =
|
|
4280
|
+
const data = encodeFunctionData14({
|
|
3530
4281
|
abi: COMET_ABI,
|
|
3531
4282
|
functionName: "supply",
|
|
3532
4283
|
args: [params.asset, params.amount]
|
|
@@ -3540,7 +4291,7 @@ var init_dist3 = __esm({
|
|
|
3540
4291
|
};
|
|
3541
4292
|
}
|
|
3542
4293
|
async buildBorrow(params) {
|
|
3543
|
-
const data =
|
|
4294
|
+
const data = encodeFunctionData14({
|
|
3544
4295
|
abi: COMET_ABI,
|
|
3545
4296
|
functionName: "withdraw",
|
|
3546
4297
|
args: [params.asset, params.amount]
|
|
@@ -3554,7 +4305,7 @@ var init_dist3 = __esm({
|
|
|
3554
4305
|
};
|
|
3555
4306
|
}
|
|
3556
4307
|
async buildRepay(params) {
|
|
3557
|
-
const data =
|
|
4308
|
+
const data = encodeFunctionData14({
|
|
3558
4309
|
abi: COMET_ABI,
|
|
3559
4310
|
functionName: "supply",
|
|
3560
4311
|
args: [params.asset, params.amount]
|
|
@@ -3568,7 +4319,7 @@ var init_dist3 = __esm({
|
|
|
3568
4319
|
};
|
|
3569
4320
|
}
|
|
3570
4321
|
async buildWithdraw(params) {
|
|
3571
|
-
const data =
|
|
4322
|
+
const data = encodeFunctionData14({
|
|
3572
4323
|
abi: COMET_ABI,
|
|
3573
4324
|
functionName: "withdraw",
|
|
3574
4325
|
args: [params.asset, params.amount]
|
|
@@ -3622,7 +4373,7 @@ var init_dist3 = __esm({
|
|
|
3622
4373
|
);
|
|
3623
4374
|
}
|
|
3624
4375
|
};
|
|
3625
|
-
EULER_VAULT_ABI =
|
|
4376
|
+
EULER_VAULT_ABI = parseAbi16([
|
|
3626
4377
|
"function deposit(uint256 amount, address receiver) external returns (uint256)",
|
|
3627
4378
|
"function withdraw(uint256 amount, address receiver, address owner) external returns (uint256)",
|
|
3628
4379
|
"function borrow(uint256 amount, address receiver) external returns (uint256)",
|
|
@@ -3648,7 +4399,7 @@ var init_dist3 = __esm({
|
|
|
3648
4399
|
return this.protocolName;
|
|
3649
4400
|
}
|
|
3650
4401
|
async buildSupply(params) {
|
|
3651
|
-
const data =
|
|
4402
|
+
const data = encodeFunctionData15({
|
|
3652
4403
|
abi: EULER_VAULT_ABI,
|
|
3653
4404
|
functionName: "deposit",
|
|
3654
4405
|
args: [params.amount, params.on_behalf_of]
|
|
@@ -3662,7 +4413,7 @@ var init_dist3 = __esm({
|
|
|
3662
4413
|
};
|
|
3663
4414
|
}
|
|
3664
4415
|
async buildBorrow(params) {
|
|
3665
|
-
const data =
|
|
4416
|
+
const data = encodeFunctionData15({
|
|
3666
4417
|
abi: EULER_VAULT_ABI,
|
|
3667
4418
|
functionName: "borrow",
|
|
3668
4419
|
args: [params.amount, params.on_behalf_of]
|
|
@@ -3676,7 +4427,7 @@ var init_dist3 = __esm({
|
|
|
3676
4427
|
};
|
|
3677
4428
|
}
|
|
3678
4429
|
async buildRepay(params) {
|
|
3679
|
-
const data =
|
|
4430
|
+
const data = encodeFunctionData15({
|
|
3680
4431
|
abi: EULER_VAULT_ABI,
|
|
3681
4432
|
functionName: "repay",
|
|
3682
4433
|
args: [params.amount, params.on_behalf_of]
|
|
@@ -3690,7 +4441,7 @@ var init_dist3 = __esm({
|
|
|
3690
4441
|
};
|
|
3691
4442
|
}
|
|
3692
4443
|
async buildWithdraw(params) {
|
|
3693
|
-
const data =
|
|
4444
|
+
const data = encodeFunctionData15({
|
|
3694
4445
|
abi: EULER_VAULT_ABI,
|
|
3695
4446
|
functionName: "withdraw",
|
|
3696
4447
|
args: [params.amount, params.to, params.to]
|
|
@@ -3739,7 +4490,7 @@ var init_dist3 = __esm({
|
|
|
3739
4490
|
);
|
|
3740
4491
|
}
|
|
3741
4492
|
};
|
|
3742
|
-
MORPHO_ABI =
|
|
4493
|
+
MORPHO_ABI = parseAbi17([
|
|
3743
4494
|
"function market(bytes32 id) external view returns (uint128 totalSupplyAssets, uint128 totalSupplyShares, uint128 totalBorrowAssets, uint128 totalBorrowShares, uint128 lastUpdate, uint128 fee)",
|
|
3744
4495
|
"function idToMarketParams(bytes32 id) external view returns (address loanToken, address collateralToken, address oracle, address irm, uint256 lltv)",
|
|
3745
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)",
|
|
@@ -3747,13 +4498,13 @@ var init_dist3 = __esm({
|
|
|
3747
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)",
|
|
3748
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)"
|
|
3749
4500
|
]);
|
|
3750
|
-
META_MORPHO_ABI =
|
|
4501
|
+
META_MORPHO_ABI = parseAbi17([
|
|
3751
4502
|
"function supplyQueueLength() external view returns (uint256)",
|
|
3752
4503
|
"function supplyQueue(uint256 index) external view returns (bytes32)",
|
|
3753
4504
|
"function totalAssets() external view returns (uint256)",
|
|
3754
4505
|
"function totalSupply() external view returns (uint256)"
|
|
3755
4506
|
]);
|
|
3756
|
-
IRM_ABI =
|
|
4507
|
+
IRM_ABI = parseAbi17([
|
|
3757
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)"
|
|
3758
4509
|
]);
|
|
3759
4510
|
SECONDS_PER_YEAR3 = 365.25 * 24 * 3600;
|
|
@@ -3776,7 +4527,7 @@ var init_dist3 = __esm({
|
|
|
3776
4527
|
}
|
|
3777
4528
|
async buildSupply(params) {
|
|
3778
4529
|
const market = defaultMarketParams(params.asset);
|
|
3779
|
-
const data =
|
|
4530
|
+
const data = encodeFunctionData16({
|
|
3780
4531
|
abi: MORPHO_ABI,
|
|
3781
4532
|
functionName: "supply",
|
|
3782
4533
|
args: [market, params.amount, 0n, params.on_behalf_of, "0x"]
|
|
@@ -3791,7 +4542,7 @@ var init_dist3 = __esm({
|
|
|
3791
4542
|
}
|
|
3792
4543
|
async buildBorrow(params) {
|
|
3793
4544
|
const market = defaultMarketParams(params.asset);
|
|
3794
|
-
const data =
|
|
4545
|
+
const data = encodeFunctionData16({
|
|
3795
4546
|
abi: MORPHO_ABI,
|
|
3796
4547
|
functionName: "borrow",
|
|
3797
4548
|
args: [market, params.amount, 0n, params.on_behalf_of, params.on_behalf_of]
|
|
@@ -3806,7 +4557,7 @@ var init_dist3 = __esm({
|
|
|
3806
4557
|
}
|
|
3807
4558
|
async buildRepay(params) {
|
|
3808
4559
|
const market = defaultMarketParams(params.asset);
|
|
3809
|
-
const data =
|
|
4560
|
+
const data = encodeFunctionData16({
|
|
3810
4561
|
abi: MORPHO_ABI,
|
|
3811
4562
|
functionName: "repay",
|
|
3812
4563
|
args: [market, params.amount, 0n, params.on_behalf_of, "0x"]
|
|
@@ -3821,7 +4572,7 @@ var init_dist3 = __esm({
|
|
|
3821
4572
|
}
|
|
3822
4573
|
async buildWithdraw(params) {
|
|
3823
4574
|
const market = defaultMarketParams(params.asset);
|
|
3824
|
-
const data =
|
|
4575
|
+
const data = encodeFunctionData16({
|
|
3825
4576
|
abi: MORPHO_ABI,
|
|
3826
4577
|
functionName: "withdraw",
|
|
3827
4578
|
args: [market, params.amount, 0n, params.to, params.to]
|
|
@@ -3839,14 +4590,12 @@ var init_dist3 = __esm({
|
|
|
3839
4590
|
if (!this.defaultVault) {
|
|
3840
4591
|
throw DefiError.contractError(`[${this.protocolName}] No MetaMorpho vault configured for rate query`);
|
|
3841
4592
|
}
|
|
3842
|
-
const
|
|
3843
|
-
|
|
3844
|
-
|
|
3845
|
-
abi: META_MORPHO_ABI,
|
|
3846
|
-
functionName: "supplyQueueLength"
|
|
3847
|
-
}).catch((e) => {
|
|
4593
|
+
const [queueLenRaw] = await multicallRead(this.rpcUrl, [
|
|
4594
|
+
[this.defaultVault, encodeFunctionData16({ abi: META_MORPHO_ABI, functionName: "supplyQueueLength" })]
|
|
4595
|
+
]).catch((e) => {
|
|
3848
4596
|
throw DefiError.rpcError(`[${this.protocolName}] supplyQueueLength failed: ${e}`);
|
|
3849
4597
|
});
|
|
4598
|
+
const queueLen = decodeU256(queueLenRaw ?? null);
|
|
3850
4599
|
if (queueLen === 0n) {
|
|
3851
4600
|
return {
|
|
3852
4601
|
protocol: this.protocolName,
|
|
@@ -3858,45 +4607,40 @@ var init_dist3 = __esm({
|
|
|
3858
4607
|
total_borrow: 0n
|
|
3859
4608
|
};
|
|
3860
4609
|
}
|
|
3861
|
-
const
|
|
3862
|
-
|
|
3863
|
-
|
|
3864
|
-
functionName: "supplyQueue",
|
|
3865
|
-
args: [0n]
|
|
3866
|
-
}).catch((e) => {
|
|
4610
|
+
const [marketIdRaw] = await multicallRead(this.rpcUrl, [
|
|
4611
|
+
[this.defaultVault, encodeFunctionData16({ abi: META_MORPHO_ABI, functionName: "supplyQueue", args: [0n] })]
|
|
4612
|
+
]).catch((e) => {
|
|
3867
4613
|
throw DefiError.rpcError(`[${this.protocolName}] supplyQueue(0) failed: ${e}`);
|
|
3868
4614
|
});
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
|
|
3872
|
-
|
|
3873
|
-
|
|
3874
|
-
|
|
3875
|
-
|
|
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}`);
|
|
3876
4624
|
});
|
|
3877
|
-
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;
|
|
3878
4631
|
const supplyF = Number(totalSupplyAssets);
|
|
3879
4632
|
const borrowF = Number(totalBorrowAssets);
|
|
3880
4633
|
const util = supplyF > 0 ? borrowF / supplyF : 0;
|
|
3881
|
-
const params2 = await client.readContract({
|
|
3882
|
-
address: this.morpho,
|
|
3883
|
-
abi: MORPHO_ABI,
|
|
3884
|
-
functionName: "idToMarketParams",
|
|
3885
|
-
args: [marketId]
|
|
3886
|
-
}).catch((e) => {
|
|
3887
|
-
throw DefiError.rpcError(`[${this.protocolName}] idToMarketParams failed: ${e}`);
|
|
3888
|
-
});
|
|
3889
|
-
const [loanToken, collateralToken, oracle, irm, lltv] = params2;
|
|
3890
4634
|
const irmMarketParams = { loanToken, collateralToken, oracle, irm, lltv };
|
|
3891
4635
|
const irmMarket = { totalSupplyAssets, totalSupplyShares, totalBorrowAssets, totalBorrowShares, lastUpdate, fee };
|
|
3892
|
-
const borrowRatePerSec = await
|
|
3893
|
-
|
|
3894
|
-
|
|
3895
|
-
|
|
3896
|
-
|
|
3897
|
-
|
|
3898
|
-
|
|
3899
|
-
});
|
|
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
|
+
})();
|
|
3900
4644
|
const ratePerSec = Number(borrowRatePerSec) / 1e18;
|
|
3901
4645
|
const borrowApy = ratePerSec * SECONDS_PER_YEAR3 * 100;
|
|
3902
4646
|
const feePct = Number(fee) / 1e18;
|
|
@@ -3917,18 +4661,18 @@ var init_dist3 = __esm({
|
|
|
3917
4661
|
);
|
|
3918
4662
|
}
|
|
3919
4663
|
};
|
|
3920
|
-
BORROWER_OPS_ABI =
|
|
4664
|
+
BORROWER_OPS_ABI = parseAbi18([
|
|
3921
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)",
|
|
3922
4666
|
"function adjustTrove(uint256 _troveId, uint256 _collChange, bool _isCollIncrease, uint256 _debtChange, bool _isDebtIncrease, uint256 _upperHint, uint256 _lowerHint, uint256 _maxUpfrontFee) external",
|
|
3923
4667
|
"function closeTrove(uint256 _troveId) external"
|
|
3924
4668
|
]);
|
|
3925
|
-
TROVE_MANAGER_ABI =
|
|
4669
|
+
TROVE_MANAGER_ABI = parseAbi18([
|
|
3926
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)"
|
|
3927
4671
|
]);
|
|
3928
|
-
HINT_HELPERS_ABI =
|
|
4672
|
+
HINT_HELPERS_ABI = parseAbi18([
|
|
3929
4673
|
"function getApproxHint(uint256 _collIndex, uint256 _interestRate, uint256 _numTrials, uint256 _inputRandomSeed) external view returns (uint256 hintId, uint256 diff, uint256 latestRandomSeed)"
|
|
3930
4674
|
]);
|
|
3931
|
-
SORTED_TROVES_ABI =
|
|
4675
|
+
SORTED_TROVES_ABI = parseAbi18([
|
|
3932
4676
|
"function findInsertPosition(uint256 _annualInterestRate, uint256 _prevId, uint256 _nextId) external view returns (uint256 prevId, uint256 nextId)"
|
|
3933
4677
|
]);
|
|
3934
4678
|
FelixCdpAdapter = class {
|
|
@@ -3956,7 +4700,7 @@ var init_dist3 = __esm({
|
|
|
3956
4700
|
if (!this.hintHelpers || !this.sortedTroves || !this.rpcUrl) {
|
|
3957
4701
|
return [0n, 0n];
|
|
3958
4702
|
}
|
|
3959
|
-
const client =
|
|
4703
|
+
const client = createPublicClient13({ transport: http13(this.rpcUrl) });
|
|
3960
4704
|
const approxResult = await client.readContract({
|
|
3961
4705
|
address: this.hintHelpers,
|
|
3962
4706
|
abi: HINT_HELPERS_ABI,
|
|
@@ -3979,7 +4723,7 @@ var init_dist3 = __esm({
|
|
|
3979
4723
|
const interestRate = 50000000000000000n;
|
|
3980
4724
|
const [upperHint, lowerHint] = await this.getHints(interestRate);
|
|
3981
4725
|
const hasHints = upperHint !== 0n || lowerHint !== 0n;
|
|
3982
|
-
const data =
|
|
4726
|
+
const data = encodeFunctionData17({
|
|
3983
4727
|
abi: BORROWER_OPS_ABI,
|
|
3984
4728
|
functionName: "openTrove",
|
|
3985
4729
|
args: [
|
|
@@ -4008,7 +4752,7 @@ var init_dist3 = __esm({
|
|
|
4008
4752
|
async buildAdjust(params) {
|
|
4009
4753
|
const collChange = params.collateral_delta ?? 0n;
|
|
4010
4754
|
const debtChange = params.debt_delta ?? 0n;
|
|
4011
|
-
const data =
|
|
4755
|
+
const data = encodeFunctionData17({
|
|
4012
4756
|
abi: BORROWER_OPS_ABI,
|
|
4013
4757
|
functionName: "adjustTrove",
|
|
4014
4758
|
args: [
|
|
@@ -4031,7 +4775,7 @@ var init_dist3 = __esm({
|
|
|
4031
4775
|
};
|
|
4032
4776
|
}
|
|
4033
4777
|
async buildClose(params) {
|
|
4034
|
-
const data =
|
|
4778
|
+
const data = encodeFunctionData17({
|
|
4035
4779
|
abi: BORROWER_OPS_ABI,
|
|
4036
4780
|
functionName: "closeTrove",
|
|
4037
4781
|
args: [params.cdp_id]
|
|
@@ -4047,7 +4791,7 @@ var init_dist3 = __esm({
|
|
|
4047
4791
|
async getCdpInfo(cdpId) {
|
|
4048
4792
|
if (!this.rpcUrl) throw DefiError.rpcError(`[${this.protocolName}] getCdpInfo requires RPC \u2014 set HYPEREVM_RPC_URL`);
|
|
4049
4793
|
if (!this.troveManager) throw DefiError.contractError(`[${this.protocolName}] trove_manager contract not configured`);
|
|
4050
|
-
const client =
|
|
4794
|
+
const client = createPublicClient13({ transport: http13(this.rpcUrl) });
|
|
4051
4795
|
const data = await client.readContract({
|
|
4052
4796
|
address: this.troveManager,
|
|
4053
4797
|
abi: TROVE_MANAGER_ABI,
|
|
@@ -4080,7 +4824,7 @@ var init_dist3 = __esm({
|
|
|
4080
4824
|
};
|
|
4081
4825
|
}
|
|
4082
4826
|
};
|
|
4083
|
-
PRICE_FEED_ABI =
|
|
4827
|
+
PRICE_FEED_ABI = parseAbi19([
|
|
4084
4828
|
"function fetchPrice() external view returns (uint256 price, bool isNewOracleFailureDetected)",
|
|
4085
4829
|
"function lastGoodPrice() external view returns (uint256)"
|
|
4086
4830
|
]);
|
|
@@ -4106,7 +4850,7 @@ var init_dist3 = __esm({
|
|
|
4106
4850
|
if (asset !== this.asset && this.asset !== "0x0000000000000000000000000000000000000000") {
|
|
4107
4851
|
throw DefiError.unsupported(`[${this.protocolName}] Felix PriceFeed only supports asset ${this.asset}`);
|
|
4108
4852
|
}
|
|
4109
|
-
const client =
|
|
4853
|
+
const client = createPublicClient14({ transport: http14(this.rpcUrl) });
|
|
4110
4854
|
let priceVal;
|
|
4111
4855
|
try {
|
|
4112
4856
|
const result = await client.readContract({
|
|
@@ -4145,7 +4889,7 @@ var init_dist3 = __esm({
|
|
|
4145
4889
|
return results;
|
|
4146
4890
|
}
|
|
4147
4891
|
};
|
|
4148
|
-
ERC4626_ABI =
|
|
4892
|
+
ERC4626_ABI = parseAbi20([
|
|
4149
4893
|
"function asset() external view returns (address)",
|
|
4150
4894
|
"function totalAssets() external view returns (uint256)",
|
|
4151
4895
|
"function totalSupply() external view returns (uint256)",
|
|
@@ -4169,7 +4913,7 @@ var init_dist3 = __esm({
|
|
|
4169
4913
|
return this.protocolName;
|
|
4170
4914
|
}
|
|
4171
4915
|
async buildDeposit(assets, receiver) {
|
|
4172
|
-
const data =
|
|
4916
|
+
const data = encodeFunctionData18({
|
|
4173
4917
|
abi: ERC4626_ABI,
|
|
4174
4918
|
functionName: "deposit",
|
|
4175
4919
|
args: [assets, receiver]
|
|
@@ -4183,7 +4927,7 @@ var init_dist3 = __esm({
|
|
|
4183
4927
|
};
|
|
4184
4928
|
}
|
|
4185
4929
|
async buildWithdraw(assets, receiver, owner) {
|
|
4186
|
-
const data =
|
|
4930
|
+
const data = encodeFunctionData18({
|
|
4187
4931
|
abi: ERC4626_ABI,
|
|
4188
4932
|
functionName: "withdraw",
|
|
4189
4933
|
args: [assets, receiver, owner]
|
|
@@ -4198,7 +4942,7 @@ var init_dist3 = __esm({
|
|
|
4198
4942
|
}
|
|
4199
4943
|
async totalAssets() {
|
|
4200
4944
|
if (!this.rpcUrl) throw DefiError.rpcError("No RPC URL configured");
|
|
4201
|
-
const client =
|
|
4945
|
+
const client = createPublicClient15({ transport: http15(this.rpcUrl) });
|
|
4202
4946
|
return client.readContract({
|
|
4203
4947
|
address: this.vaultAddress,
|
|
4204
4948
|
abi: ERC4626_ABI,
|
|
@@ -4209,7 +4953,7 @@ var init_dist3 = __esm({
|
|
|
4209
4953
|
}
|
|
4210
4954
|
async convertToShares(assets) {
|
|
4211
4955
|
if (!this.rpcUrl) throw DefiError.rpcError("No RPC URL configured");
|
|
4212
|
-
const client =
|
|
4956
|
+
const client = createPublicClient15({ transport: http15(this.rpcUrl) });
|
|
4213
4957
|
return client.readContract({
|
|
4214
4958
|
address: this.vaultAddress,
|
|
4215
4959
|
abi: ERC4626_ABI,
|
|
@@ -4221,7 +4965,7 @@ var init_dist3 = __esm({
|
|
|
4221
4965
|
}
|
|
4222
4966
|
async convertToAssets(shares) {
|
|
4223
4967
|
if (!this.rpcUrl) throw DefiError.rpcError("No RPC URL configured");
|
|
4224
|
-
const client =
|
|
4968
|
+
const client = createPublicClient15({ transport: http15(this.rpcUrl) });
|
|
4225
4969
|
return client.readContract({
|
|
4226
4970
|
address: this.vaultAddress,
|
|
4227
4971
|
abi: ERC4626_ABI,
|
|
@@ -4233,7 +4977,7 @@ var init_dist3 = __esm({
|
|
|
4233
4977
|
}
|
|
4234
4978
|
async getVaultInfo() {
|
|
4235
4979
|
if (!this.rpcUrl) throw DefiError.rpcError("No RPC URL configured");
|
|
4236
|
-
const client =
|
|
4980
|
+
const client = createPublicClient15({ transport: http15(this.rpcUrl) });
|
|
4237
4981
|
const [totalAssets, totalSupply, asset] = await Promise.all([
|
|
4238
4982
|
client.readContract({ address: this.vaultAddress, abi: ERC4626_ABI, functionName: "totalAssets" }).catch((e) => {
|
|
4239
4983
|
throw DefiError.rpcError(`[${this.protocolName}] totalAssets failed: ${e}`);
|
|
@@ -4254,7 +4998,7 @@ var init_dist3 = __esm({
|
|
|
4254
4998
|
};
|
|
4255
4999
|
}
|
|
4256
5000
|
};
|
|
4257
|
-
GENERIC_LST_ABI =
|
|
5001
|
+
GENERIC_LST_ABI = parseAbi21([
|
|
4258
5002
|
"function stake() external payable returns (uint256)",
|
|
4259
5003
|
"function unstake(uint256 amount) external returns (uint256)"
|
|
4260
5004
|
]);
|
|
@@ -4271,7 +5015,7 @@ var init_dist3 = __esm({
|
|
|
4271
5015
|
return this.protocolName;
|
|
4272
5016
|
}
|
|
4273
5017
|
async buildStake(params) {
|
|
4274
|
-
const data =
|
|
5018
|
+
const data = encodeFunctionData19({ abi: GENERIC_LST_ABI, functionName: "stake" });
|
|
4275
5019
|
return {
|
|
4276
5020
|
description: `[${this.protocolName}] Stake ${params.amount} HYPE`,
|
|
4277
5021
|
to: this.staking,
|
|
@@ -4281,7 +5025,7 @@ var init_dist3 = __esm({
|
|
|
4281
5025
|
};
|
|
4282
5026
|
}
|
|
4283
5027
|
async buildUnstake(params) {
|
|
4284
|
-
const data =
|
|
5028
|
+
const data = encodeFunctionData19({
|
|
4285
5029
|
abi: GENERIC_LST_ABI,
|
|
4286
5030
|
functionName: "unstake",
|
|
4287
5031
|
args: [params.amount]
|
|
@@ -4298,11 +5042,11 @@ var init_dist3 = __esm({
|
|
|
4298
5042
|
throw DefiError.unsupported(`[${this.protocolName}] getInfo requires RPC`);
|
|
4299
5043
|
}
|
|
4300
5044
|
};
|
|
4301
|
-
STHYPE_ABI =
|
|
5045
|
+
STHYPE_ABI = parseAbi222([
|
|
4302
5046
|
"function submit(address referral) external payable returns (uint256)",
|
|
4303
5047
|
"function requestWithdrawals(uint256[] amounts, address owner) external returns (uint256[] requestIds)"
|
|
4304
5048
|
]);
|
|
4305
|
-
ERC20_ABI3 =
|
|
5049
|
+
ERC20_ABI3 = parseAbi222([
|
|
4306
5050
|
"function totalSupply() external view returns (uint256)"
|
|
4307
5051
|
]);
|
|
4308
5052
|
StHypeAdapter = class {
|
|
@@ -4322,7 +5066,7 @@ var init_dist3 = __esm({
|
|
|
4322
5066
|
return this.protocolName;
|
|
4323
5067
|
}
|
|
4324
5068
|
async buildStake(params) {
|
|
4325
|
-
const data =
|
|
5069
|
+
const data = encodeFunctionData20({
|
|
4326
5070
|
abi: STHYPE_ABI,
|
|
4327
5071
|
functionName: "submit",
|
|
4328
5072
|
args: [zeroAddress9]
|
|
@@ -4336,7 +5080,7 @@ var init_dist3 = __esm({
|
|
|
4336
5080
|
};
|
|
4337
5081
|
}
|
|
4338
5082
|
async buildUnstake(params) {
|
|
4339
|
-
const data =
|
|
5083
|
+
const data = encodeFunctionData20({
|
|
4340
5084
|
abi: STHYPE_ABI,
|
|
4341
5085
|
functionName: "requestWithdrawals",
|
|
4342
5086
|
args: [[params.amount], params.recipient]
|
|
@@ -4351,7 +5095,7 @@ var init_dist3 = __esm({
|
|
|
4351
5095
|
}
|
|
4352
5096
|
async getInfo() {
|
|
4353
5097
|
if (!this.rpcUrl) throw DefiError.rpcError("No RPC URL configured");
|
|
4354
|
-
const client =
|
|
5098
|
+
const client = createPublicClient16({ transport: http16(this.rpcUrl) });
|
|
4355
5099
|
const tokenAddr = this.sthypeToken ?? this.staking;
|
|
4356
5100
|
const totalSupply = await client.readContract({
|
|
4357
5101
|
address: tokenAddr,
|
|
@@ -4369,12 +5113,12 @@ var init_dist3 = __esm({
|
|
|
4369
5113
|
};
|
|
4370
5114
|
}
|
|
4371
5115
|
};
|
|
4372
|
-
KINETIQ_ABI =
|
|
5116
|
+
KINETIQ_ABI = parseAbi23([
|
|
4373
5117
|
"function stake() external payable returns (uint256)",
|
|
4374
5118
|
"function requestUnstake(uint256 amount) external returns (uint256)",
|
|
4375
5119
|
"function totalStaked() external view returns (uint256)"
|
|
4376
5120
|
]);
|
|
4377
|
-
ORACLE_ABI3 =
|
|
5121
|
+
ORACLE_ABI3 = parseAbi23([
|
|
4378
5122
|
"function getAssetPrice(address asset) external view returns (uint256)"
|
|
4379
5123
|
]);
|
|
4380
5124
|
WHYPE = "0x5555555555555555555555555555555555555555";
|
|
@@ -4396,7 +5140,7 @@ var init_dist3 = __esm({
|
|
|
4396
5140
|
return this.protocolName;
|
|
4397
5141
|
}
|
|
4398
5142
|
async buildStake(params) {
|
|
4399
|
-
const data =
|
|
5143
|
+
const data = encodeFunctionData21({ abi: KINETIQ_ABI, functionName: "stake" });
|
|
4400
5144
|
return {
|
|
4401
5145
|
description: `[${this.protocolName}] Stake ${params.amount} HYPE for kHYPE`,
|
|
4402
5146
|
to: this.staking,
|
|
@@ -4406,7 +5150,7 @@ var init_dist3 = __esm({
|
|
|
4406
5150
|
};
|
|
4407
5151
|
}
|
|
4408
5152
|
async buildUnstake(params) {
|
|
4409
|
-
const data =
|
|
5153
|
+
const data = encodeFunctionData21({
|
|
4410
5154
|
abi: KINETIQ_ABI,
|
|
4411
5155
|
functionName: "requestUnstake",
|
|
4412
5156
|
args: [params.amount]
|
|
@@ -4421,7 +5165,7 @@ var init_dist3 = __esm({
|
|
|
4421
5165
|
}
|
|
4422
5166
|
async getInfo() {
|
|
4423
5167
|
if (!this.rpcUrl) throw DefiError.rpcError("No RPC URL configured");
|
|
4424
|
-
const client =
|
|
5168
|
+
const client = createPublicClient17({ transport: http17(this.rpcUrl) });
|
|
4425
5169
|
const totalStaked = await client.readContract({
|
|
4426
5170
|
address: this.staking,
|
|
4427
5171
|
abi: KINETIQ_ABI,
|
|
@@ -4492,7 +5236,7 @@ var init_dist3 = __esm({
|
|
|
4492
5236
|
);
|
|
4493
5237
|
}
|
|
4494
5238
|
};
|
|
4495
|
-
HLP_ABI =
|
|
5239
|
+
HLP_ABI = parseAbi24([
|
|
4496
5240
|
"function deposit(uint256 amount) external returns (uint256)",
|
|
4497
5241
|
"function withdraw(uint256 shares) external returns (uint256)"
|
|
4498
5242
|
]);
|
|
@@ -4509,7 +5253,7 @@ var init_dist3 = __esm({
|
|
|
4509
5253
|
return this.protocolName;
|
|
4510
5254
|
}
|
|
4511
5255
|
async buildOpenPosition(params) {
|
|
4512
|
-
const data =
|
|
5256
|
+
const data = encodeFunctionData222({
|
|
4513
5257
|
abi: HLP_ABI,
|
|
4514
5258
|
functionName: "deposit",
|
|
4515
5259
|
args: [params.collateral]
|
|
@@ -4523,7 +5267,7 @@ var init_dist3 = __esm({
|
|
|
4523
5267
|
};
|
|
4524
5268
|
}
|
|
4525
5269
|
async buildClosePosition(params) {
|
|
4526
|
-
const data =
|
|
5270
|
+
const data = encodeFunctionData222({
|
|
4527
5271
|
abi: HLP_ABI,
|
|
4528
5272
|
functionName: "withdraw",
|
|
4529
5273
|
args: [params.size]
|
|
@@ -4558,7 +5302,7 @@ var init_dist3 = __esm({
|
|
|
4558
5302
|
);
|
|
4559
5303
|
}
|
|
4560
5304
|
};
|
|
4561
|
-
RYSK_ABI =
|
|
5305
|
+
RYSK_ABI = parseAbi25([
|
|
4562
5306
|
"function openOption(address underlying, uint256 strikePrice, uint256 expiry, bool isCall, uint256 amount) external returns (uint256 premium)",
|
|
4563
5307
|
"function closeOption(address underlying, uint256 strikePrice, uint256 expiry, bool isCall, uint256 amount) external returns (uint256 payout)"
|
|
4564
5308
|
]);
|
|
@@ -4575,7 +5319,7 @@ var init_dist3 = __esm({
|
|
|
4575
5319
|
return this.protocolName;
|
|
4576
5320
|
}
|
|
4577
5321
|
async buildBuy(params) {
|
|
4578
|
-
const data =
|
|
5322
|
+
const data = encodeFunctionData23({
|
|
4579
5323
|
abi: RYSK_ABI,
|
|
4580
5324
|
functionName: "openOption",
|
|
4581
5325
|
args: [
|
|
@@ -4595,7 +5339,7 @@ var init_dist3 = __esm({
|
|
|
4595
5339
|
};
|
|
4596
5340
|
}
|
|
4597
5341
|
async buildSell(params) {
|
|
4598
|
-
const data =
|
|
5342
|
+
const data = encodeFunctionData23({
|
|
4599
5343
|
abi: RYSK_ABI,
|
|
4600
5344
|
functionName: "closeOption",
|
|
4601
5345
|
args: [
|
|
@@ -4636,7 +5380,7 @@ var init_dist3 = __esm({
|
|
|
4636
5380
|
);
|
|
4637
5381
|
}
|
|
4638
5382
|
};
|
|
4639
|
-
ERC721_ABI =
|
|
5383
|
+
ERC721_ABI = parseAbi26([
|
|
4640
5384
|
"function name() returns (string)",
|
|
4641
5385
|
"function symbol() returns (string)",
|
|
4642
5386
|
"function totalSupply() returns (uint256)",
|
|
@@ -4656,7 +5400,7 @@ var init_dist3 = __esm({
|
|
|
4656
5400
|
}
|
|
4657
5401
|
async getCollectionInfo(collection) {
|
|
4658
5402
|
if (!this.rpcUrl) throw DefiError.rpcError("No RPC URL configured");
|
|
4659
|
-
const client =
|
|
5403
|
+
const client = createPublicClient18({ transport: http18(this.rpcUrl) });
|
|
4660
5404
|
const [collectionName, symbol, totalSupply] = await Promise.all([
|
|
4661
5405
|
client.readContract({ address: collection, abi: ERC721_ABI, functionName: "name" }).catch((e) => {
|
|
4662
5406
|
throw DefiError.rpcError(`[${this.protocolName}] name failed: ${e}`);
|
|
@@ -4675,7 +5419,7 @@ var init_dist3 = __esm({
|
|
|
4675
5419
|
}
|
|
4676
5420
|
async getTokenInfo(collection, tokenId) {
|
|
4677
5421
|
if (!this.rpcUrl) throw DefiError.rpcError("No RPC URL configured");
|
|
4678
|
-
const client =
|
|
5422
|
+
const client = createPublicClient18({ transport: http18(this.rpcUrl) });
|
|
4679
5423
|
const [owner, tokenUri] = await Promise.all([
|
|
4680
5424
|
client.readContract({ address: collection, abi: ERC721_ABI, functionName: "ownerOf", args: [tokenId] }).catch((e) => {
|
|
4681
5425
|
throw DefiError.rpcError(`[${this.protocolName}] ownerOf failed: ${e}`);
|
|
@@ -4691,7 +5435,7 @@ var init_dist3 = __esm({
|
|
|
4691
5435
|
}
|
|
4692
5436
|
async getBalance(owner, collection) {
|
|
4693
5437
|
if (!this.rpcUrl) throw DefiError.rpcError("No RPC URL configured");
|
|
4694
|
-
const client =
|
|
5438
|
+
const client = createPublicClient18({ transport: http18(this.rpcUrl) });
|
|
4695
5439
|
return client.readContract({ address: collection, abi: ERC721_ABI, functionName: "balanceOf", args: [owner] }).catch((e) => {
|
|
4696
5440
|
throw DefiError.rpcError(`[${this.protocolName}] balanceOf failed: ${e}`);
|
|
4697
5441
|
});
|
|
@@ -4747,10 +5491,16 @@ import { z } from "zod";
|
|
|
4747
5491
|
|
|
4748
5492
|
// src/executor.ts
|
|
4749
5493
|
init_dist2();
|
|
4750
|
-
|
|
5494
|
+
init_dist2();
|
|
5495
|
+
import { createPublicClient as createPublicClient19, createWalletClient, http as http19, parseAbi as parseAbi27, encodeFunctionData as encodeFunctionData24 } from "viem";
|
|
4751
5496
|
import { privateKeyToAccount } from "viem/accounts";
|
|
5497
|
+
var ERC20_ABI4 = parseAbi27([
|
|
5498
|
+
"function allowance(address owner, address spender) external view returns (uint256)",
|
|
5499
|
+
"function approve(address spender, uint256 amount) external returns (bool)"
|
|
5500
|
+
]);
|
|
4752
5501
|
var GAS_BUFFER_BPS = 12000n;
|
|
4753
|
-
var DEFAULT_PRIORITY_FEE_WEI =
|
|
5502
|
+
var DEFAULT_PRIORITY_FEE_WEI = 20000000000n;
|
|
5503
|
+
var MAX_GAS_LIMIT = 5000000000n;
|
|
4754
5504
|
var Executor = class _Executor {
|
|
4755
5505
|
dryRun;
|
|
4756
5506
|
rpcUrl;
|
|
@@ -4764,10 +5514,66 @@ var Executor = class _Executor {
|
|
|
4764
5514
|
static applyGasBuffer(gas) {
|
|
4765
5515
|
return gas * GAS_BUFFER_BPS / 10000n;
|
|
4766
5516
|
}
|
|
5517
|
+
/**
|
|
5518
|
+
* Check allowance for a single token/spender pair and send an approve tx if needed.
|
|
5519
|
+
* Only called in broadcast mode (not dry-run).
|
|
5520
|
+
*/
|
|
5521
|
+
async checkAndApprove(token, spender, amount, owner, publicClient, walletClient) {
|
|
5522
|
+
const allowance = await publicClient.readContract({
|
|
5523
|
+
address: token,
|
|
5524
|
+
abi: ERC20_ABI4,
|
|
5525
|
+
functionName: "allowance",
|
|
5526
|
+
args: [owner, spender]
|
|
5527
|
+
});
|
|
5528
|
+
if (allowance >= amount) return;
|
|
5529
|
+
process.stderr.write(
|
|
5530
|
+
` Approving ${amount} of ${token} for ${spender}...
|
|
5531
|
+
`
|
|
5532
|
+
);
|
|
5533
|
+
const approveData = encodeFunctionData24({
|
|
5534
|
+
abi: ERC20_ABI4,
|
|
5535
|
+
functionName: "approve",
|
|
5536
|
+
args: [spender, amount]
|
|
5537
|
+
});
|
|
5538
|
+
const rpcUrl = this.rpcUrl;
|
|
5539
|
+
const gasLimit = await (async () => {
|
|
5540
|
+
try {
|
|
5541
|
+
const estimated = await publicClient.estimateGas({
|
|
5542
|
+
to: token,
|
|
5543
|
+
data: approveData,
|
|
5544
|
+
account: owner
|
|
5545
|
+
});
|
|
5546
|
+
const buffered = _Executor.applyGasBuffer(estimated);
|
|
5547
|
+
return buffered > MAX_GAS_LIMIT ? MAX_GAS_LIMIT : buffered;
|
|
5548
|
+
} catch {
|
|
5549
|
+
return 80000n;
|
|
5550
|
+
}
|
|
5551
|
+
})();
|
|
5552
|
+
const [maxFeePerGas, maxPriorityFeePerGas] = await this.fetchEip1559Fees(rpcUrl);
|
|
5553
|
+
const approveTxHash = await walletClient.sendTransaction({
|
|
5554
|
+
chain: null,
|
|
5555
|
+
account: walletClient.account,
|
|
5556
|
+
to: token,
|
|
5557
|
+
data: approveData,
|
|
5558
|
+
gas: gasLimit > 0n ? gasLimit : void 0,
|
|
5559
|
+
maxFeePerGas: maxFeePerGas > 0n ? maxFeePerGas : void 0,
|
|
5560
|
+
maxPriorityFeePerGas: maxPriorityFeePerGas > 0n ? maxPriorityFeePerGas : void 0
|
|
5561
|
+
});
|
|
5562
|
+
const approveTxUrl = this.explorerUrl ? `${this.explorerUrl}/tx/${approveTxHash}` : void 0;
|
|
5563
|
+
process.stderr.write(` Approve tx: ${approveTxHash}
|
|
5564
|
+
`);
|
|
5565
|
+
if (approveTxUrl) process.stderr.write(` Explorer: ${approveTxUrl}
|
|
5566
|
+
`);
|
|
5567
|
+
await publicClient.waitForTransactionReceipt({ hash: approveTxHash });
|
|
5568
|
+
process.stderr.write(
|
|
5569
|
+
` Approved ${amount} of ${token} for ${spender}
|
|
5570
|
+
`
|
|
5571
|
+
);
|
|
5572
|
+
}
|
|
4767
5573
|
/** Fetch EIP-1559 fee params from the network. Returns [maxFeePerGas, maxPriorityFeePerGas]. */
|
|
4768
5574
|
async fetchEip1559Fees(rpcUrl) {
|
|
4769
5575
|
try {
|
|
4770
|
-
const client =
|
|
5576
|
+
const client = createPublicClient19({ transport: http19(rpcUrl) });
|
|
4771
5577
|
const gasPrice = await client.getGasPrice();
|
|
4772
5578
|
let priorityFee = DEFAULT_PRIORITY_FEE_WEI;
|
|
4773
5579
|
try {
|
|
@@ -4783,14 +5589,17 @@ var Executor = class _Executor {
|
|
|
4783
5589
|
/** Estimate gas dynamically with buffer, falling back to a hardcoded estimate */
|
|
4784
5590
|
async estimateGasWithBuffer(rpcUrl, tx, from) {
|
|
4785
5591
|
try {
|
|
4786
|
-
const client =
|
|
5592
|
+
const client = createPublicClient19({ transport: http19(rpcUrl) });
|
|
4787
5593
|
const estimated = await client.estimateGas({
|
|
4788
5594
|
to: tx.to,
|
|
4789
5595
|
data: tx.data,
|
|
4790
5596
|
value: tx.value,
|
|
4791
5597
|
account: from
|
|
4792
5598
|
});
|
|
4793
|
-
if (estimated > 0n)
|
|
5599
|
+
if (estimated > 0n) {
|
|
5600
|
+
const buffered = _Executor.applyGasBuffer(estimated);
|
|
5601
|
+
return buffered > MAX_GAS_LIMIT ? MAX_GAS_LIMIT : buffered;
|
|
5602
|
+
}
|
|
4794
5603
|
} catch {
|
|
4795
5604
|
}
|
|
4796
5605
|
return tx.gas_estimate ? BigInt(tx.gas_estimate) : 0n;
|
|
@@ -4801,9 +5610,49 @@ var Executor = class _Executor {
|
|
|
4801
5610
|
if (!rpcUrl) {
|
|
4802
5611
|
throw DefiError.rpcError("No RPC URL \u2014 cannot simulate. Set HYPEREVM_RPC_URL.");
|
|
4803
5612
|
}
|
|
4804
|
-
const client =
|
|
5613
|
+
const client = createPublicClient19({ transport: http19(rpcUrl) });
|
|
4805
5614
|
const privateKey = process.env["DEFI_PRIVATE_KEY"];
|
|
4806
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
|
+
}
|
|
4807
5656
|
try {
|
|
4808
5657
|
await client.call({ to: tx.to, data: tx.data, value: tx.value, account: from });
|
|
4809
5658
|
const gasEstimate = await this.estimateGasWithBuffer(rpcUrl, tx, from);
|
|
@@ -4874,8 +5723,20 @@ var Executor = class _Executor {
|
|
|
4874
5723
|
if (!rpcUrl) {
|
|
4875
5724
|
throw DefiError.rpcError("No RPC URL configured for broadcasting");
|
|
4876
5725
|
}
|
|
4877
|
-
const publicClient =
|
|
4878
|
-
const walletClient = createWalletClient({ account, transport:
|
|
5726
|
+
const publicClient = createPublicClient19({ transport: http19(rpcUrl) });
|
|
5727
|
+
const walletClient = createWalletClient({ account, transport: http19(rpcUrl) });
|
|
5728
|
+
if (tx.approvals && tx.approvals.length > 0) {
|
|
5729
|
+
for (const approval of tx.approvals) {
|
|
5730
|
+
await this.checkAndApprove(
|
|
5731
|
+
approval.token,
|
|
5732
|
+
approval.spender,
|
|
5733
|
+
approval.amount,
|
|
5734
|
+
account.address,
|
|
5735
|
+
publicClient,
|
|
5736
|
+
walletClient
|
|
5737
|
+
);
|
|
5738
|
+
}
|
|
5739
|
+
}
|
|
4879
5740
|
const gasLimit = await this.estimateGasWithBuffer(rpcUrl, tx, account.address);
|
|
4880
5741
|
const [maxFeePerGas, maxPriorityFeePerGas] = await this.fetchEip1559Fees(rpcUrl);
|
|
4881
5742
|
process.stderr.write(`Broadcasting transaction to ${rpcUrl}...
|
|
@@ -5502,8 +6363,8 @@ server.tool(
|
|
|
5502
6363
|
const user = address;
|
|
5503
6364
|
const { ProtocolCategory: ProtocolCategory2, multicallRead: multicallRead2 } = await Promise.resolve().then(() => (init_dist2(), dist_exports));
|
|
5504
6365
|
const { createLending: _createLending } = await Promise.resolve().then(() => (init_dist3(), dist_exports2));
|
|
5505
|
-
const { encodeFunctionData:
|
|
5506
|
-
const POOL_ABI3 =
|
|
6366
|
+
const { encodeFunctionData: encodeFunctionData25, parseAbi: parseAbi28 } = await import("viem");
|
|
6367
|
+
const POOL_ABI3 = parseAbi28([
|
|
5507
6368
|
"function getUserAccountData(address user) external view returns (uint256 totalCollateralBase, uint256 totalDebtBase, uint256 availableBorrowsBase, uint256 currentLiquidationThreshold, uint256 ltv, uint256 healthFactor)"
|
|
5508
6369
|
]);
|
|
5509
6370
|
const lendingProtos = registry.getProtocolsForChain(chainName).filter((p) => p.category === ProtocolCategory2.Lending);
|
|
@@ -5512,7 +6373,7 @@ server.tool(
|
|
|
5512
6373
|
const poolAddr = p.contracts?.pool;
|
|
5513
6374
|
if (!poolAddr) continue;
|
|
5514
6375
|
try {
|
|
5515
|
-
const callData =
|
|
6376
|
+
const callData = encodeFunctionData25({ abi: POOL_ABI3, functionName: "getUserAccountData", args: [user] });
|
|
5516
6377
|
const results = await multicallRead2(rpcUrl, [[poolAddr, callData]]);
|
|
5517
6378
|
const raw = results[0];
|
|
5518
6379
|
if (!raw || raw.length < 2 + 6 * 64) continue;
|