@hypurrquant/defi-cli 0.4.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +38 -39
- package/dist/index.js +346 -101
- package/dist/index.js.map +1 -1
- package/dist/main.js +346 -101
- package/dist/main.js.map +1 -1
- package/dist/mcp-server.js +104 -21
- package/dist/mcp-server.js.map +1 -1
- package/package.json +2 -1
- package/skills/defi-cli/SKILL.md +181 -0
- package/skills/defi-cli/package.json +38 -0
- package/skills/defi-cli/references/commands.md +162 -0
- package/skills/defi-cli/references/protocols.md +115 -0
- package/skills/defi-cli/scripts/exploit-scan.sh +10 -0
- package/skills/defi-cli/scripts/portfolio-snapshot.sh +19 -0
- package/skills/defi-cli/scripts/preflight.sh +14 -0
- package/skills/defi-cli/scripts/yield-scan.sh +10 -0
package/dist/mcp-server.js
CHANGED
|
@@ -3312,7 +3312,8 @@ var init_dist2 = __esm({
|
|
|
3312
3312
|
"function findBestPathFromAmountIn(address[] calldata route, uint128 amountIn) external view returns ((address[] route, address[] pairs, uint256[] binSteps, uint256[] versions, uint128[] amounts, uint128[] virtualAmountsWithoutSlippage, uint128[] fees))"
|
|
3313
3313
|
]);
|
|
3314
3314
|
erc20Abi2 = parseAbi12([
|
|
3315
|
-
"function symbol() external view returns (string)"
|
|
3315
|
+
"function symbol() external view returns (string)",
|
|
3316
|
+
"function balanceOf(address account) external view returns (uint256)"
|
|
3316
3317
|
]);
|
|
3317
3318
|
_addressAbi = parseAbi12(["function f() external view returns (address)"]);
|
|
3318
3319
|
_uint256Abi = parseAbi12(["function f() external view returns (uint256)"]);
|
|
@@ -3729,6 +3730,74 @@ var init_dist2 = __esm({
|
|
|
3729
3730
|
} catch {
|
|
3730
3731
|
}
|
|
3731
3732
|
}
|
|
3733
|
+
const stableSymbols = /* @__PURE__ */ new Set(["USDT", "USDC", "USDT0", "MUSD", "AUSD", "USDY", "FDUSD", "USDe", "sUSDe"]);
|
|
3734
|
+
const mntSymbols = /* @__PURE__ */ new Set(["WMNT", "MNT"]);
|
|
3735
|
+
const moeSymbols = /* @__PURE__ */ new Set(["MOE"]);
|
|
3736
|
+
const sixDecimalStables = /* @__PURE__ */ new Set(["USDT", "USDC", "USDT0", "FDUSD"]);
|
|
3737
|
+
const tokenPriceMap = /* @__PURE__ */ new Map();
|
|
3738
|
+
const tokenDecimalsMap = /* @__PURE__ */ new Map();
|
|
3739
|
+
for (const [addr, sym] of symbolMap) {
|
|
3740
|
+
const key = addr.toLowerCase();
|
|
3741
|
+
if (stableSymbols.has(sym)) {
|
|
3742
|
+
tokenPriceMap.set(key, 1);
|
|
3743
|
+
tokenDecimalsMap.set(key, sixDecimalStables.has(sym) ? 6 : 18);
|
|
3744
|
+
} else if (mntSymbols.has(sym)) {
|
|
3745
|
+
tokenPriceMap.set(key, wmntPriceUsd);
|
|
3746
|
+
tokenDecimalsMap.set(key, 18);
|
|
3747
|
+
} else if (moeSymbols.has(sym)) {
|
|
3748
|
+
tokenPriceMap.set(key, moePriceUsd);
|
|
3749
|
+
tokenDecimalsMap.set(key, 18);
|
|
3750
|
+
}
|
|
3751
|
+
}
|
|
3752
|
+
const unknownTokenAddrs = [];
|
|
3753
|
+
for (let i = 0; i < rewardedPairs.length; i++) {
|
|
3754
|
+
for (const addr of [tokenXAddresses[i], tokenYAddresses[i]]) {
|
|
3755
|
+
if (addr && !tokenPriceMap.has(addr.toLowerCase())) {
|
|
3756
|
+
if (!unknownTokenAddrs.some((a) => a.toLowerCase() === addr.toLowerCase())) {
|
|
3757
|
+
unknownTokenAddrs.push(addr);
|
|
3758
|
+
}
|
|
3759
|
+
}
|
|
3760
|
+
}
|
|
3761
|
+
}
|
|
3762
|
+
if (unknownTokenAddrs.length > 0 && this.lbQuoter && this.wmnt && wmntPriceUsd > 0) {
|
|
3763
|
+
const erc20DecimalsAbi = parseAbi12(["function decimals() external view returns (uint8)"]);
|
|
3764
|
+
const decCalls = unknownTokenAddrs.map((addr) => [
|
|
3765
|
+
addr,
|
|
3766
|
+
encodeFunctionData12({ abi: erc20DecimalsAbi, functionName: "decimals" })
|
|
3767
|
+
]);
|
|
3768
|
+
const decResults = await multicallRead(rpcUrl, decCalls).catch(() => []);
|
|
3769
|
+
for (let i = 0; i < unknownTokenAddrs.length; i++) {
|
|
3770
|
+
const dec = decResults[i] ? Number(decodeUint256Result(decResults[i]) ?? 18n) : 18;
|
|
3771
|
+
tokenDecimalsMap.set(unknownTokenAddrs[i].toLowerCase(), dec);
|
|
3772
|
+
}
|
|
3773
|
+
const quotePromises = unknownTokenAddrs.map(async (tokenAddr) => {
|
|
3774
|
+
try {
|
|
3775
|
+
const dec = tokenDecimalsMap.get(tokenAddr.toLowerCase()) ?? 18;
|
|
3776
|
+
const quoteUnit = 10n ** BigInt(Math.max(dec - 2, 0));
|
|
3777
|
+
const quote = await client.readContract({
|
|
3778
|
+
address: this.lbQuoter,
|
|
3779
|
+
abi: lbQuoterAbi2,
|
|
3780
|
+
functionName: "findBestPathFromAmountIn",
|
|
3781
|
+
args: [[tokenAddr, this.wmnt], quoteUnit]
|
|
3782
|
+
});
|
|
3783
|
+
const amountOut = quote.amounts?.at(-1) ?? 0n;
|
|
3784
|
+
const priceInWmnt = Number(amountOut) / 1e18 * (10 ** dec / Number(quoteUnit));
|
|
3785
|
+
return { addr: tokenAddr, price: priceInWmnt * wmntPriceUsd };
|
|
3786
|
+
} catch {
|
|
3787
|
+
return { addr: tokenAddr, price: 0 };
|
|
3788
|
+
}
|
|
3789
|
+
});
|
|
3790
|
+
const priceResults = await Promise.all(quotePromises);
|
|
3791
|
+
for (const { addr, price } of priceResults) {
|
|
3792
|
+
if (price > 0) tokenPriceMap.set(addr.toLowerCase(), price);
|
|
3793
|
+
}
|
|
3794
|
+
}
|
|
3795
|
+
const getTokenPriceUsd = (_sym, addr) => {
|
|
3796
|
+
return tokenPriceMap.get(addr.toLowerCase()) ?? 0;
|
|
3797
|
+
};
|
|
3798
|
+
const getTokenDecimals = (_sym, addr) => {
|
|
3799
|
+
return tokenDecimalsMap.get(addr.toLowerCase()) ?? 18;
|
|
3800
|
+
};
|
|
3732
3801
|
const binRequests = [];
|
|
3733
3802
|
for (let i = 0; i < rewardedPairs.length; i++) {
|
|
3734
3803
|
const range = poolData[i].range;
|
|
@@ -3759,19 +3828,23 @@ var init_dist2 = __esm({
|
|
|
3759
3828
|
binReservesY.get(poolIdx).set(binId, decoded[1]);
|
|
3760
3829
|
}
|
|
3761
3830
|
}
|
|
3762
|
-
const
|
|
3763
|
-
const
|
|
3764
|
-
|
|
3765
|
-
|
|
3766
|
-
|
|
3767
|
-
|
|
3768
|
-
|
|
3769
|
-
|
|
3770
|
-
|
|
3771
|
-
|
|
3772
|
-
|
|
3773
|
-
|
|
3774
|
-
|
|
3831
|
+
const poolBalanceX = /* @__PURE__ */ new Map();
|
|
3832
|
+
const poolBalanceY = /* @__PURE__ */ new Map();
|
|
3833
|
+
{
|
|
3834
|
+
const balCalls = [];
|
|
3835
|
+
for (let i = 0; i < rewardedPairs.length; i++) {
|
|
3836
|
+
const tx = tokenXAddresses[i];
|
|
3837
|
+
const ty = tokenYAddresses[i];
|
|
3838
|
+
const pool = rewardedPairs[i].pool;
|
|
3839
|
+
balCalls.push([tx ?? "0x0000000000000000000000000000000000000000", encodeFunctionData12({ abi: erc20Abi2, functionName: "balanceOf", args: [pool] })]);
|
|
3840
|
+
balCalls.push([ty ?? "0x0000000000000000000000000000000000000000", encodeFunctionData12({ abi: erc20Abi2, functionName: "balanceOf", args: [pool] })]);
|
|
3841
|
+
}
|
|
3842
|
+
const balResults = await multicallRead(rpcUrl, balCalls).catch(() => []);
|
|
3843
|
+
for (let i = 0; i < rewardedPairs.length; i++) {
|
|
3844
|
+
poolBalanceX.set(i, decodeUint256Result(balResults[i * 2] ?? null) ?? 0n);
|
|
3845
|
+
poolBalanceY.set(i, decodeUint256Result(balResults[i * 2 + 1] ?? null) ?? 0n);
|
|
3846
|
+
}
|
|
3847
|
+
}
|
|
3775
3848
|
const results = [];
|
|
3776
3849
|
for (let i = 0; i < rewardedPairs.length; i++) {
|
|
3777
3850
|
const { pool, rewarder } = rewardedPairs[i];
|
|
@@ -3796,18 +3869,25 @@ var init_dist2 = __esm({
|
|
|
3796
3869
|
const maxBin = Number(range[1]);
|
|
3797
3870
|
rewardedBins = maxBin - minBin + 1;
|
|
3798
3871
|
if (rxMap && ryMap) {
|
|
3799
|
-
const
|
|
3800
|
-
const
|
|
3801
|
-
const
|
|
3802
|
-
const
|
|
3872
|
+
const priceX2 = getTokenPriceUsd(symX, tokenX);
|
|
3873
|
+
const priceY2 = getTokenPriceUsd(symY, tokenY);
|
|
3874
|
+
const decX2 = getTokenDecimals(symX, tokenX);
|
|
3875
|
+
const decY2 = getTokenDecimals(symY, tokenY);
|
|
3803
3876
|
for (let b = minBin; b <= maxBin; b++) {
|
|
3804
3877
|
const rx = rxMap.get(b) ?? 0n;
|
|
3805
3878
|
const ry = ryMap.get(b) ?? 0n;
|
|
3806
|
-
rangeTvlUsd += Number(rx) / 10 **
|
|
3807
|
-
rangeTvlUsd += Number(ry) / 10 **
|
|
3879
|
+
rangeTvlUsd += Number(rx) / 10 ** decX2 * priceX2;
|
|
3880
|
+
rangeTvlUsd += Number(ry) / 10 ** decY2 * priceY2;
|
|
3808
3881
|
}
|
|
3809
3882
|
}
|
|
3810
3883
|
}
|
|
3884
|
+
const priceX = getTokenPriceUsd(symX, tokenX);
|
|
3885
|
+
const priceY = getTokenPriceUsd(symY, tokenY);
|
|
3886
|
+
const decX = getTokenDecimals(symX, tokenX);
|
|
3887
|
+
const decY = getTokenDecimals(symY, tokenY);
|
|
3888
|
+
const fullBalX = poolBalanceX.get(i) ?? 0n;
|
|
3889
|
+
const fullBalY = poolBalanceY.get(i) ?? 0n;
|
|
3890
|
+
const poolTvlUsd = Number(fullBalX) / 10 ** decX * priceX + Number(fullBalY) / 10 ** decY * priceY;
|
|
3811
3891
|
const aprPercent = rangeTvlUsd > 0 && moePriceUsd > 0 ? poolMoePerDay * moePriceUsd * 365 / rangeTvlUsd * 100 : 0;
|
|
3812
3892
|
results.push({
|
|
3813
3893
|
pool,
|
|
@@ -3824,8 +3904,11 @@ var init_dist2 = __esm({
|
|
|
3824
3904
|
isTopPool,
|
|
3825
3905
|
moePerDay: poolMoePerDay,
|
|
3826
3906
|
rangeTvlUsd,
|
|
3907
|
+
poolTvlUsd,
|
|
3827
3908
|
aprPercent,
|
|
3828
|
-
rewardedBins
|
|
3909
|
+
rewardedBins,
|
|
3910
|
+
totalMoePerDay: moePerDay,
|
|
3911
|
+
moePriceUsd
|
|
3829
3912
|
});
|
|
3830
3913
|
}
|
|
3831
3914
|
return results;
|