@oydual31/more-vaults-sdk 0.4.2 → 0.6.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/README.md +94 -0
- package/dist/{spokeRoutes-B8Lnk-t4.d.cts → curatorBridge-CNs59kT9.d.cts} +222 -1
- package/dist/{spokeRoutes-B8Lnk-t4.d.ts → curatorBridge-CNs59kT9.d.ts} +222 -1
- package/dist/ethers/index.cjs +328 -3
- package/dist/ethers/index.cjs.map +1 -1
- package/dist/ethers/index.d.cts +279 -1
- package/dist/ethers/index.d.ts +279 -1
- package/dist/ethers/index.js +318 -5
- package/dist/ethers/index.js.map +1 -1
- package/dist/react/index.cjs +375 -0
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +266 -2
- package/dist/react/index.d.ts +266 -2
- package/dist/react/index.js +372 -2
- package/dist/react/index.js.map +1 -1
- package/dist/viem/index.cjs +377 -0
- package/dist/viem/index.cjs.map +1 -1
- package/dist/viem/index.d.cts +261 -3
- package/dist/viem/index.d.ts +261 -3
- package/dist/viem/index.js +367 -2
- package/dist/viem/index.js.map +1 -1
- package/package.json +1 -1
- package/src/ethers/abis.ts +24 -0
- package/src/ethers/curatorBridge.ts +235 -0
- package/src/ethers/curatorSubVaults.ts +443 -0
- package/src/ethers/index.ts +26 -0
- package/src/ethers/types.ts +99 -0
- package/src/react/index.ts +14 -0
- package/src/react/useCuratorBridgeQuote.ts +43 -0
- package/src/react/useERC7540RequestStatus.ts +43 -0
- package/src/react/useExecuteBridge.ts +50 -0
- package/src/react/useSubVaultPositions.ts +35 -0
- package/src/react/useVaultPortfolio.ts +35 -0
- package/src/viem/abis.ts +24 -0
- package/src/viem/curatorBridge.ts +288 -0
- package/src/viem/curatorSubVaults.ts +514 -0
- package/src/viem/index.ts +23 -0
- package/src/viem/types.ts +100 -0
package/dist/ethers/index.cjs
CHANGED
|
@@ -513,6 +513,23 @@ var REGISTRY_ABI = [
|
|
|
513
513
|
"function isBridgeAllowed(address bridge) view returns (bool)",
|
|
514
514
|
"function getAllowedFacets() view returns (address[])"
|
|
515
515
|
];
|
|
516
|
+
var SUB_VAULT_ABI = [
|
|
517
|
+
// ConfigurationFacet reads — called on the MoreVaults diamond proxy
|
|
518
|
+
"function tokensHeld(bytes32 id) view returns (address[])",
|
|
519
|
+
"function lockedTokensAmountOfAsset(address asset) view returns (uint256)",
|
|
520
|
+
// ERC4626 standard reads — called on the sub-vault contract
|
|
521
|
+
"function convertToAssets(uint256 shares) view returns (uint256)",
|
|
522
|
+
"function convertToShares(uint256 assets) view returns (uint256)",
|
|
523
|
+
"function previewDeposit(uint256 assets) view returns (uint256)",
|
|
524
|
+
"function previewRedeem(uint256 shares) view returns (uint256)",
|
|
525
|
+
"function maxDeposit(address receiver) view returns (uint256)",
|
|
526
|
+
"function maxRedeem(address owner) view returns (uint256)",
|
|
527
|
+
// ERC7540 async reads — called on the sub-vault contract
|
|
528
|
+
"function pendingDepositRequest(uint256 requestId, address controller) view returns (uint256)",
|
|
529
|
+
"function claimableDepositRequest(uint256 requestId, address controller) view returns (uint256)",
|
|
530
|
+
"function pendingRedeemRequest(uint256 requestId, address controller) view returns (uint256)",
|
|
531
|
+
"function claimableRedeemRequest(uint256 requestId, address controller) view returns (uint256)"
|
|
532
|
+
];
|
|
516
533
|
|
|
517
534
|
// src/ethers/errors.ts
|
|
518
535
|
var MoreVaultsError = class extends Error {
|
|
@@ -1752,11 +1769,11 @@ async function canDeposit(provider, vault, user) {
|
|
|
1752
1769
|
return { allowed: true, reason: "ok" };
|
|
1753
1770
|
}
|
|
1754
1771
|
async function getVaultMetadata(provider, vault) {
|
|
1755
|
-
const
|
|
1756
|
-
const
|
|
1772
|
+
const MULTICALL3_ADDRESS5 = "0xcA11bde05977b3631167028862bE2a173976CA11";
|
|
1773
|
+
const MULTICALL3_ABI5 = [
|
|
1757
1774
|
"function aggregate3(tuple(address target, bool allowFailure, bytes callData)[] calls) payable returns (tuple(bool success, bytes returnData)[] returnData)"
|
|
1758
1775
|
];
|
|
1759
|
-
const mc = new ethers.Contract(
|
|
1776
|
+
const mc = new ethers.Contract(MULTICALL3_ADDRESS5, MULTICALL3_ABI5, provider);
|
|
1760
1777
|
const metaIface = new ethers.Interface(METADATA_ABI);
|
|
1761
1778
|
const vaultIface = new ethers.Interface(VAULT_ABI);
|
|
1762
1779
|
const b1Calls = [
|
|
@@ -2298,6 +2315,302 @@ function buildUniswapV3Swap(params) {
|
|
|
2298
2315
|
}
|
|
2299
2316
|
};
|
|
2300
2317
|
}
|
|
2318
|
+
function encodeBridgeParams(params) {
|
|
2319
|
+
const coder = ethers.AbiCoder.defaultAbiCoder();
|
|
2320
|
+
return coder.encode(
|
|
2321
|
+
["address", "uint32", "uint256", "address", "address"],
|
|
2322
|
+
[
|
|
2323
|
+
ethers.getAddress(params.oftToken),
|
|
2324
|
+
params.dstEid,
|
|
2325
|
+
params.amount,
|
|
2326
|
+
ethers.getAddress(params.dstVault),
|
|
2327
|
+
ethers.getAddress(params.refundAddress)
|
|
2328
|
+
]
|
|
2329
|
+
);
|
|
2330
|
+
}
|
|
2331
|
+
function encodeBridgeParamsForQuote(params) {
|
|
2332
|
+
const coder = ethers.AbiCoder.defaultAbiCoder();
|
|
2333
|
+
return coder.encode(
|
|
2334
|
+
["address", "uint32", "uint256", "address"],
|
|
2335
|
+
[
|
|
2336
|
+
ethers.getAddress(params.oftToken),
|
|
2337
|
+
params.dstEid,
|
|
2338
|
+
params.amount,
|
|
2339
|
+
ethers.getAddress(params.dstVault)
|
|
2340
|
+
]
|
|
2341
|
+
);
|
|
2342
|
+
}
|
|
2343
|
+
function findBridgeRoute(srcChainId, dstChainId, tokenAddress) {
|
|
2344
|
+
const normalizedToken = ethers.getAddress(tokenAddress);
|
|
2345
|
+
for (const [symbol, chains] of Object.entries(OFT_ROUTES)) {
|
|
2346
|
+
const srcEntry = chains[srcChainId];
|
|
2347
|
+
const dstEntry = chains[dstChainId];
|
|
2348
|
+
if (!srcEntry || !dstEntry) continue;
|
|
2349
|
+
const srcToken = ethers.getAddress(srcEntry.token);
|
|
2350
|
+
const srcOft = ethers.getAddress(srcEntry.oft);
|
|
2351
|
+
if (srcToken === normalizedToken || srcOft === normalizedToken) {
|
|
2352
|
+
return {
|
|
2353
|
+
oftSrc: srcOft,
|
|
2354
|
+
oftDst: ethers.getAddress(dstEntry.oft),
|
|
2355
|
+
symbol
|
|
2356
|
+
};
|
|
2357
|
+
}
|
|
2358
|
+
}
|
|
2359
|
+
return null;
|
|
2360
|
+
}
|
|
2361
|
+
async function quoteCuratorBridgeFee(provider, vault, params) {
|
|
2362
|
+
const status = await getCuratorVaultStatus(provider, vault);
|
|
2363
|
+
const lzAdapter = status.lzAdapter;
|
|
2364
|
+
const bridgeSpecificParams = encodeBridgeParamsForQuote(params);
|
|
2365
|
+
const adapterContract = new ethers.Contract(lzAdapter, LZ_ADAPTER_ABI, provider);
|
|
2366
|
+
const nativeFee = await adapterContract.quoteBridgeFee.staticCall(
|
|
2367
|
+
bridgeSpecificParams
|
|
2368
|
+
);
|
|
2369
|
+
return nativeFee;
|
|
2370
|
+
}
|
|
2371
|
+
async function executeCuratorBridge(signer, vault, token, params) {
|
|
2372
|
+
const provider = signer.provider;
|
|
2373
|
+
const status = await getCuratorVaultStatus(provider, vault);
|
|
2374
|
+
const lzAdapter = status.lzAdapter;
|
|
2375
|
+
const fee = await quoteCuratorBridgeFee(provider, vault, params);
|
|
2376
|
+
const bridgeSpecificParams = encodeBridgeParams(params);
|
|
2377
|
+
const vaultContract = new ethers.Contract(vault, BRIDGE_FACET_ABI, signer);
|
|
2378
|
+
const tx = await vaultContract.executeBridging(
|
|
2379
|
+
ethers.getAddress(lzAdapter),
|
|
2380
|
+
ethers.getAddress(token),
|
|
2381
|
+
params.amount,
|
|
2382
|
+
bridgeSpecificParams,
|
|
2383
|
+
{ value: fee }
|
|
2384
|
+
);
|
|
2385
|
+
return tx.wait();
|
|
2386
|
+
}
|
|
2387
|
+
var MULTICALL3_ADDRESS4 = "0xcA11bde05977b3631167028862bE2a173976CA11";
|
|
2388
|
+
var MULTICALL3_ABI4 = [
|
|
2389
|
+
"function aggregate3(tuple(address target, bool allowFailure, bytes callData)[] calls) payable returns (tuple(bool success, bytes returnData)[] returnData)"
|
|
2390
|
+
];
|
|
2391
|
+
var ERC4626_ID = ethers.ethers.keccak256(ethers.ethers.toUtf8Bytes("ERC4626_ID"));
|
|
2392
|
+
var ERC7540_ID = ethers.ethers.keccak256(ethers.ethers.toUtf8Bytes("ERC7540_ID"));
|
|
2393
|
+
async function getSubVaultPositions(provider, vault) {
|
|
2394
|
+
const subVaultIface = new ethers.Interface(SUB_VAULT_ABI);
|
|
2395
|
+
const vaultContract = new ethers.Contract(vault, SUB_VAULT_ABI, provider);
|
|
2396
|
+
const [erc4626Raw, erc7540Raw] = await Promise.all([
|
|
2397
|
+
vaultContract.tokensHeld(ERC4626_ID).catch(() => []),
|
|
2398
|
+
vaultContract.tokensHeld(ERC7540_ID).catch(() => [])
|
|
2399
|
+
]);
|
|
2400
|
+
const allSubVaults = [
|
|
2401
|
+
...erc4626Raw.map((a) => ({ address: a, type: "erc4626" })),
|
|
2402
|
+
...erc7540Raw.map((a) => ({ address: a, type: "erc7540" }))
|
|
2403
|
+
];
|
|
2404
|
+
if (allSubVaults.length === 0) return [];
|
|
2405
|
+
const mc = new ethers.Contract(MULTICALL3_ADDRESS4, MULTICALL3_ABI4, provider);
|
|
2406
|
+
const erc20Iface = new ethers.Interface(ERC20_ABI);
|
|
2407
|
+
const metaIface = new ethers.Interface(METADATA_ABI);
|
|
2408
|
+
const vaultIface = new ethers.Interface(VAULT_ABI);
|
|
2409
|
+
const PER_SV = 5;
|
|
2410
|
+
const subVaultCalls = allSubVaults.flatMap(({ address: sv }) => [
|
|
2411
|
+
{ target: sv, allowFailure: true, callData: erc20Iface.encodeFunctionData("balanceOf", [vault]) },
|
|
2412
|
+
{ target: sv, allowFailure: true, callData: vaultIface.encodeFunctionData("asset") },
|
|
2413
|
+
{ target: sv, allowFailure: true, callData: metaIface.encodeFunctionData("name") },
|
|
2414
|
+
{ target: sv, allowFailure: true, callData: metaIface.encodeFunctionData("symbol") },
|
|
2415
|
+
{ target: sv, allowFailure: true, callData: metaIface.encodeFunctionData("decimals") }
|
|
2416
|
+
]);
|
|
2417
|
+
const subVaultResults = await mc.aggregate3.staticCall(subVaultCalls);
|
|
2418
|
+
const partials = allSubVaults.map(({ address: sv, type }, i) => {
|
|
2419
|
+
const base = i * PER_SV;
|
|
2420
|
+
const sharesBalance = subVaultResults[base].success ? erc20Iface.decodeFunctionResult("balanceOf", subVaultResults[base].returnData)[0] : 0n;
|
|
2421
|
+
const underlyingAsset = subVaultResults[base + 1].success ? vaultIface.decodeFunctionResult("asset", subVaultResults[base + 1].returnData)[0] : ethers.ethers.ZeroAddress;
|
|
2422
|
+
const name = subVaultResults[base + 2].success ? metaIface.decodeFunctionResult("name", subVaultResults[base + 2].returnData)[0] : "";
|
|
2423
|
+
const symbol = subVaultResults[base + 3].success ? metaIface.decodeFunctionResult("symbol", subVaultResults[base + 3].returnData)[0] : "";
|
|
2424
|
+
const decimals = subVaultResults[base + 4].success ? Number(metaIface.decodeFunctionResult("decimals", subVaultResults[base + 4].returnData)[0]) : 18;
|
|
2425
|
+
return { address: sv, type, sharesBalance, underlyingAsset, name, symbol, decimals };
|
|
2426
|
+
});
|
|
2427
|
+
const active = partials.filter((p) => p.sharesBalance > 0n);
|
|
2428
|
+
if (active.length === 0) return [];
|
|
2429
|
+
const PER_ACTIVE = 4;
|
|
2430
|
+
const activeCalls = active.flatMap(({ address: sv, sharesBalance, underlyingAsset }) => [
|
|
2431
|
+
{ target: sv, allowFailure: true, callData: subVaultIface.encodeFunctionData("convertToAssets", [sharesBalance]) },
|
|
2432
|
+
{ target: underlyingAsset, allowFailure: true, callData: metaIface.encodeFunctionData("name") },
|
|
2433
|
+
{ target: underlyingAsset, allowFailure: true, callData: metaIface.encodeFunctionData("symbol") },
|
|
2434
|
+
{ target: underlyingAsset, allowFailure: true, callData: metaIface.encodeFunctionData("decimals") }
|
|
2435
|
+
]);
|
|
2436
|
+
const activeResults = await mc.aggregate3.staticCall(activeCalls);
|
|
2437
|
+
return active.map((p, i) => {
|
|
2438
|
+
const base = i * PER_ACTIVE;
|
|
2439
|
+
const underlyingValue = activeResults[base].success ? subVaultIface.decodeFunctionResult("convertToAssets", activeResults[base].returnData)[0] : 0n;
|
|
2440
|
+
const underlyingSymbol = activeResults[base + 2].success ? metaIface.decodeFunctionResult("symbol", activeResults[base + 2].returnData)[0] : "";
|
|
2441
|
+
const underlyingDecimals = activeResults[base + 3].success ? Number(metaIface.decodeFunctionResult("decimals", activeResults[base + 3].returnData)[0]) : 18;
|
|
2442
|
+
return {
|
|
2443
|
+
address: p.address,
|
|
2444
|
+
type: p.type,
|
|
2445
|
+
name: p.name,
|
|
2446
|
+
symbol: p.symbol,
|
|
2447
|
+
decimals: p.decimals,
|
|
2448
|
+
sharesBalance: p.sharesBalance,
|
|
2449
|
+
underlyingValue,
|
|
2450
|
+
underlyingAsset: p.underlyingAsset,
|
|
2451
|
+
underlyingSymbol,
|
|
2452
|
+
underlyingDecimals
|
|
2453
|
+
};
|
|
2454
|
+
});
|
|
2455
|
+
}
|
|
2456
|
+
async function detectSubVaultType(provider, subVault) {
|
|
2457
|
+
const mc = new ethers.Contract(MULTICALL3_ADDRESS4, MULTICALL3_ABI4, provider);
|
|
2458
|
+
const subVaultIface = new ethers.Interface(SUB_VAULT_ABI);
|
|
2459
|
+
const calls = [
|
|
2460
|
+
{
|
|
2461
|
+
target: subVault,
|
|
2462
|
+
allowFailure: true,
|
|
2463
|
+
callData: subVaultIface.encodeFunctionData("pendingDepositRequest", [0n, ethers.ethers.ZeroAddress])
|
|
2464
|
+
},
|
|
2465
|
+
{
|
|
2466
|
+
target: subVault,
|
|
2467
|
+
allowFailure: true,
|
|
2468
|
+
callData: subVaultIface.encodeFunctionData("convertToAssets", [0n])
|
|
2469
|
+
}
|
|
2470
|
+
];
|
|
2471
|
+
const results = await mc.aggregate3.staticCall(calls);
|
|
2472
|
+
if (results[0].success) return "erc7540";
|
|
2473
|
+
if (results[1].success) return "erc4626";
|
|
2474
|
+
return null;
|
|
2475
|
+
}
|
|
2476
|
+
async function getSubVaultInfo(provider, vault, subVault) {
|
|
2477
|
+
const mc = new ethers.Contract(MULTICALL3_ADDRESS4, MULTICALL3_ABI4, provider);
|
|
2478
|
+
const subVaultIface = new ethers.Interface(SUB_VAULT_ABI);
|
|
2479
|
+
const metaIface = new ethers.Interface(METADATA_ABI);
|
|
2480
|
+
const vaultIface = new ethers.Interface(VAULT_ABI);
|
|
2481
|
+
new ethers.Interface(REGISTRY_ABI);
|
|
2482
|
+
new ethers.Interface(VAULT_ANALYSIS_ABI);
|
|
2483
|
+
const [type, basicResults] = await Promise.all([
|
|
2484
|
+
detectSubVaultType(provider, subVault),
|
|
2485
|
+
mc.aggregate3.staticCall([
|
|
2486
|
+
{ target: subVault, allowFailure: true, callData: metaIface.encodeFunctionData("name") },
|
|
2487
|
+
{ target: subVault, allowFailure: true, callData: metaIface.encodeFunctionData("symbol") },
|
|
2488
|
+
{ target: subVault, allowFailure: true, callData: metaIface.encodeFunctionData("decimals") },
|
|
2489
|
+
{ target: subVault, allowFailure: true, callData: vaultIface.encodeFunctionData("asset") },
|
|
2490
|
+
{ target: subVault, allowFailure: true, callData: subVaultIface.encodeFunctionData("maxDeposit", [vault]) }
|
|
2491
|
+
])
|
|
2492
|
+
]);
|
|
2493
|
+
const name = basicResults[0].success ? metaIface.decodeFunctionResult("name", basicResults[0].returnData)[0] : "";
|
|
2494
|
+
const symbol = basicResults[1].success ? metaIface.decodeFunctionResult("symbol", basicResults[1].returnData)[0] : "";
|
|
2495
|
+
const decimals = basicResults[2].success ? Number(metaIface.decodeFunctionResult("decimals", basicResults[2].returnData)[0]) : 18;
|
|
2496
|
+
const underlying = basicResults[3].success ? vaultIface.decodeFunctionResult("asset", basicResults[3].returnData)[0] : ethers.ethers.ZeroAddress;
|
|
2497
|
+
const maxDeposit = basicResults[4].success ? subVaultIface.decodeFunctionResult("maxDeposit", basicResults[4].returnData)[0] : 0n;
|
|
2498
|
+
const [underlyingResults, registryRaw] = await Promise.all([
|
|
2499
|
+
mc.aggregate3.staticCall([
|
|
2500
|
+
{ target: underlying, allowFailure: true, callData: metaIface.encodeFunctionData("symbol") },
|
|
2501
|
+
{ target: underlying, allowFailure: true, callData: metaIface.encodeFunctionData("decimals") }
|
|
2502
|
+
]),
|
|
2503
|
+
new ethers.Contract(vault, VAULT_ANALYSIS_ABI, provider).moreVaultsRegistry().catch(() => null)
|
|
2504
|
+
]);
|
|
2505
|
+
const underlyingSymbol = underlyingResults[0].success ? metaIface.decodeFunctionResult("symbol", underlyingResults[0].returnData)[0] : "";
|
|
2506
|
+
const underlyingDecimals = underlyingResults[1].success ? Number(metaIface.decodeFunctionResult("decimals", underlyingResults[1].returnData)[0]) : 18;
|
|
2507
|
+
let isWhitelisted = false;
|
|
2508
|
+
if (registryRaw) {
|
|
2509
|
+
const whitelistResult = await new ethers.Contract(registryRaw, REGISTRY_ABI, provider).isWhitelisted(subVault).catch(() => false);
|
|
2510
|
+
isWhitelisted = whitelistResult;
|
|
2511
|
+
}
|
|
2512
|
+
return {
|
|
2513
|
+
address: subVault,
|
|
2514
|
+
type: type ?? "erc4626",
|
|
2515
|
+
name,
|
|
2516
|
+
symbol,
|
|
2517
|
+
decimals,
|
|
2518
|
+
underlyingAsset: underlying,
|
|
2519
|
+
underlyingSymbol,
|
|
2520
|
+
underlyingDecimals,
|
|
2521
|
+
maxDeposit,
|
|
2522
|
+
isWhitelisted
|
|
2523
|
+
};
|
|
2524
|
+
}
|
|
2525
|
+
async function getERC7540RequestStatus(provider, vault, subVault) {
|
|
2526
|
+
const mc = new ethers.Contract(MULTICALL3_ADDRESS4, MULTICALL3_ABI4, provider);
|
|
2527
|
+
const subVaultIface = new ethers.Interface(SUB_VAULT_ABI);
|
|
2528
|
+
const calls = [
|
|
2529
|
+
{ target: subVault, allowFailure: true, callData: subVaultIface.encodeFunctionData("pendingDepositRequest", [0n, vault]) },
|
|
2530
|
+
{ target: subVault, allowFailure: true, callData: subVaultIface.encodeFunctionData("claimableDepositRequest", [0n, vault]) },
|
|
2531
|
+
{ target: subVault, allowFailure: true, callData: subVaultIface.encodeFunctionData("pendingRedeemRequest", [0n, vault]) },
|
|
2532
|
+
{ target: subVault, allowFailure: true, callData: subVaultIface.encodeFunctionData("claimableRedeemRequest", [0n, vault]) }
|
|
2533
|
+
];
|
|
2534
|
+
const results = await mc.aggregate3.staticCall(calls);
|
|
2535
|
+
const pendingDeposit = results[0].success ? subVaultIface.decodeFunctionResult("pendingDepositRequest", results[0].returnData)[0] : 0n;
|
|
2536
|
+
const claimableDeposit = results[1].success ? subVaultIface.decodeFunctionResult("claimableDepositRequest", results[1].returnData)[0] : 0n;
|
|
2537
|
+
const pendingRedeem = results[2].success ? subVaultIface.decodeFunctionResult("pendingRedeemRequest", results[2].returnData)[0] : 0n;
|
|
2538
|
+
const claimableRedeem = results[3].success ? subVaultIface.decodeFunctionResult("claimableRedeemRequest", results[3].returnData)[0] : 0n;
|
|
2539
|
+
return {
|
|
2540
|
+
subVault,
|
|
2541
|
+
pendingDeposit,
|
|
2542
|
+
claimableDeposit,
|
|
2543
|
+
pendingRedeem,
|
|
2544
|
+
claimableRedeem,
|
|
2545
|
+
canFinalizeDeposit: claimableDeposit > 0n,
|
|
2546
|
+
canFinalizeRedeem: claimableRedeem > 0n
|
|
2547
|
+
};
|
|
2548
|
+
}
|
|
2549
|
+
async function previewSubVaultDeposit(provider, subVault, assets) {
|
|
2550
|
+
const contract = new ethers.Contract(subVault, SUB_VAULT_ABI, provider);
|
|
2551
|
+
return await contract.previewDeposit(assets);
|
|
2552
|
+
}
|
|
2553
|
+
async function previewSubVaultRedeem(provider, subVault, shares) {
|
|
2554
|
+
const contract = new ethers.Contract(subVault, SUB_VAULT_ABI, provider);
|
|
2555
|
+
return await contract.previewRedeem(shares);
|
|
2556
|
+
}
|
|
2557
|
+
async function getVaultPortfolio(provider, vault) {
|
|
2558
|
+
const mc = new ethers.Contract(MULTICALL3_ADDRESS4, MULTICALL3_ABI4, provider);
|
|
2559
|
+
new ethers.Interface(SUB_VAULT_ABI);
|
|
2560
|
+
new ethers.Interface(VAULT_ANALYSIS_ABI);
|
|
2561
|
+
const vaultIface = new ethers.Interface(VAULT_ABI);
|
|
2562
|
+
const erc20Iface = new ethers.Interface(ERC20_ABI);
|
|
2563
|
+
const metaIface = new ethers.Interface(METADATA_ABI);
|
|
2564
|
+
const [availableRaw, subVaultPositions, vaultTotals] = await Promise.all([
|
|
2565
|
+
new ethers.Contract(vault, VAULT_ANALYSIS_ABI, provider).getAvailableAssets().catch(() => []),
|
|
2566
|
+
getSubVaultPositions(provider, vault),
|
|
2567
|
+
mc.aggregate3.staticCall([
|
|
2568
|
+
{ target: vault, allowFailure: true, callData: vaultIface.encodeFunctionData("totalAssets") },
|
|
2569
|
+
{ target: vault, allowFailure: true, callData: vaultIface.encodeFunctionData("totalSupply") },
|
|
2570
|
+
{ target: vault, allowFailure: true, callData: vaultIface.encodeFunctionData("asset") }
|
|
2571
|
+
])
|
|
2572
|
+
]);
|
|
2573
|
+
const totalAssets = vaultTotals[0].success ? vaultIface.decodeFunctionResult("totalAssets", vaultTotals[0].returnData)[0] : 0n;
|
|
2574
|
+
const totalSupply = vaultTotals[1].success ? vaultIface.decodeFunctionResult("totalSupply", vaultTotals[1].returnData)[0] : 0n;
|
|
2575
|
+
const underlyingAsset = vaultTotals[2].success ? vaultIface.decodeFunctionResult("asset", vaultTotals[2].returnData)[0] : ethers.ethers.ZeroAddress;
|
|
2576
|
+
const subVaultAddressSet = new Set(subVaultPositions.map((p) => p.address.toLowerCase()));
|
|
2577
|
+
const liquidAddresses = availableRaw.filter(
|
|
2578
|
+
(addr) => !subVaultAddressSet.has(addr.toLowerCase())
|
|
2579
|
+
);
|
|
2580
|
+
const PER_ASSET = 4;
|
|
2581
|
+
let liquidAssets = [];
|
|
2582
|
+
if (liquidAddresses.length > 0) {
|
|
2583
|
+
const liquidCalls = liquidAddresses.flatMap((addr) => [
|
|
2584
|
+
{ target: addr, allowFailure: true, callData: erc20Iface.encodeFunctionData("balanceOf", [vault]) },
|
|
2585
|
+
{ target: addr, allowFailure: true, callData: metaIface.encodeFunctionData("name") },
|
|
2586
|
+
{ target: addr, allowFailure: true, callData: metaIface.encodeFunctionData("symbol") },
|
|
2587
|
+
{ target: addr, allowFailure: true, callData: metaIface.encodeFunctionData("decimals") }
|
|
2588
|
+
]);
|
|
2589
|
+
const liquidResults = await mc.aggregate3.staticCall(liquidCalls);
|
|
2590
|
+
liquidAssets = liquidAddresses.map((addr, i) => {
|
|
2591
|
+
const base = i * PER_ASSET;
|
|
2592
|
+
const balance = liquidResults[base].success ? erc20Iface.decodeFunctionResult("balanceOf", liquidResults[base].returnData)[0] : 0n;
|
|
2593
|
+
const name = liquidResults[base + 1].success ? metaIface.decodeFunctionResult("name", liquidResults[base + 1].returnData)[0] : "";
|
|
2594
|
+
const symbol = liquidResults[base + 2].success ? metaIface.decodeFunctionResult("symbol", liquidResults[base + 2].returnData)[0] : "";
|
|
2595
|
+
const decimals = liquidResults[base + 3].success ? Number(metaIface.decodeFunctionResult("decimals", liquidResults[base + 3].returnData)[0]) : 18;
|
|
2596
|
+
return { address: addr, name, symbol, decimals, balance };
|
|
2597
|
+
});
|
|
2598
|
+
}
|
|
2599
|
+
const lockedAssets = await new ethers.Contract(vault, SUB_VAULT_ABI, provider).lockedTokensAmountOfAsset(underlyingAsset).catch(() => 0n);
|
|
2600
|
+
const subVaultTotal = subVaultPositions.reduce((sum, p) => sum + p.underlyingValue, 0n);
|
|
2601
|
+
const underlyingBalance = liquidAssets.find(
|
|
2602
|
+
(a) => a.address.toLowerCase() === underlyingAsset.toLowerCase()
|
|
2603
|
+
)?.balance ?? 0n;
|
|
2604
|
+
const totalValue = underlyingBalance + subVaultTotal;
|
|
2605
|
+
return {
|
|
2606
|
+
liquidAssets,
|
|
2607
|
+
subVaultPositions,
|
|
2608
|
+
totalValue,
|
|
2609
|
+
totalAssets,
|
|
2610
|
+
totalSupply,
|
|
2611
|
+
lockedAssets
|
|
2612
|
+
};
|
|
2613
|
+
}
|
|
2301
2614
|
|
|
2302
2615
|
// src/ethers/distribution.ts
|
|
2303
2616
|
async function getVaultDistribution(hubProvider, vault, spokeProviders) {
|
|
@@ -2569,6 +2882,7 @@ exports.OFT_ABI = OFT_ABI;
|
|
|
2569
2882
|
exports.OFT_ROUTES = OFT_ROUTES;
|
|
2570
2883
|
exports.OMNI_FACTORY_ADDRESS = OMNI_FACTORY_ADDRESS;
|
|
2571
2884
|
exports.REGISTRY_ABI = REGISTRY_ABI;
|
|
2885
|
+
exports.SUB_VAULT_ABI = SUB_VAULT_ABI;
|
|
2572
2886
|
exports.UNISWAP_V3_ROUTERS = UNISWAP_V3_ROUTERS;
|
|
2573
2887
|
exports.VAULT_ABI = VAULT_ABI;
|
|
2574
2888
|
exports.VAULT_ANALYSIS_ABI = VAULT_ANALYSIS_ABI;
|
|
@@ -2588,21 +2902,28 @@ exports.depositFromSpokeAsync = depositFromSpokeAsync;
|
|
|
2588
2902
|
exports.depositMultiAsset = depositMultiAsset;
|
|
2589
2903
|
exports.depositSimple = depositSimple;
|
|
2590
2904
|
exports.detectStargateOft = detectStargateOft;
|
|
2905
|
+
exports.detectSubVaultType = detectSubVaultType;
|
|
2591
2906
|
exports.discoverVaultTopology = discoverVaultTopology;
|
|
2907
|
+
exports.encodeBridgeParams = encodeBridgeParams;
|
|
2592
2908
|
exports.encodeCuratorAction = encodeCuratorAction;
|
|
2593
2909
|
exports.encodeUniswapV3SwapCalldata = encodeUniswapV3SwapCalldata;
|
|
2594
2910
|
exports.ensureAllowance = ensureAllowance;
|
|
2595
2911
|
exports.executeActions = executeActions;
|
|
2596
2912
|
exports.executeCompose = executeCompose;
|
|
2913
|
+
exports.executeCuratorBridge = executeCuratorBridge;
|
|
2914
|
+
exports.findBridgeRoute = findBridgeRoute;
|
|
2597
2915
|
exports.getAllVaultChainIds = getAllVaultChainIds;
|
|
2598
2916
|
exports.getAsyncRequestStatus = getAsyncRequestStatus;
|
|
2599
2917
|
exports.getAsyncRequestStatusLabel = getAsyncRequestStatusLabel;
|
|
2600
2918
|
exports.getCuratorVaultStatus = getCuratorVaultStatus;
|
|
2919
|
+
exports.getERC7540RequestStatus = getERC7540RequestStatus;
|
|
2601
2920
|
exports.getFullVaultTopology = getFullVaultTopology;
|
|
2602
2921
|
exports.getInboundRoutes = getInboundRoutes;
|
|
2603
2922
|
exports.getMaxWithdrawable = getMaxWithdrawable;
|
|
2604
2923
|
exports.getOutboundRoutes = getOutboundRoutes;
|
|
2605
2924
|
exports.getPendingActions = getPendingActions;
|
|
2925
|
+
exports.getSubVaultInfo = getSubVaultInfo;
|
|
2926
|
+
exports.getSubVaultPositions = getSubVaultPositions;
|
|
2606
2927
|
exports.getUserBalances = getUserBalances;
|
|
2607
2928
|
exports.getUserBalancesForRoutes = getUserBalancesForRoutes;
|
|
2608
2929
|
exports.getUserPosition = getUserPosition;
|
|
@@ -2612,6 +2933,7 @@ exports.getVaultAssetBreakdown = getVaultAssetBreakdown;
|
|
|
2612
2933
|
exports.getVaultDistribution = getVaultDistribution;
|
|
2613
2934
|
exports.getVaultDistributionWithTopology = getVaultDistributionWithTopology;
|
|
2614
2935
|
exports.getVaultMetadata = getVaultMetadata;
|
|
2936
|
+
exports.getVaultPortfolio = getVaultPortfolio;
|
|
2615
2937
|
exports.getVaultStatus = getVaultStatus;
|
|
2616
2938
|
exports.getVaultSummary = getVaultSummary;
|
|
2617
2939
|
exports.getVaultTopology = getVaultTopology;
|
|
@@ -2627,7 +2949,10 @@ exports.preflightSpokeRedeem = preflightSpokeRedeem;
|
|
|
2627
2949
|
exports.preflightSync = preflightSync;
|
|
2628
2950
|
exports.previewDeposit = previewDeposit;
|
|
2629
2951
|
exports.previewRedeem = previewRedeem;
|
|
2952
|
+
exports.previewSubVaultDeposit = previewSubVaultDeposit;
|
|
2953
|
+
exports.previewSubVaultRedeem = previewSubVaultRedeem;
|
|
2630
2954
|
exports.quoteComposeFee = quoteComposeFee;
|
|
2955
|
+
exports.quoteCuratorBridgeFee = quoteCuratorBridgeFee;
|
|
2631
2956
|
exports.quoteDepositFromSpokeFee = quoteDepositFromSpokeFee;
|
|
2632
2957
|
exports.quoteLzFee = quoteLzFee;
|
|
2633
2958
|
exports.quoteRouteDepositFee = quoteRouteDepositFee;
|