@lagoon-protocol/lagoon-mcp 0.2.13 → 0.2.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cache/index.d.ts +2 -0
- package/dist/cache/index.d.ts.map +1 -1
- package/dist/cache/index.js +2 -0
- package/dist/cache/index.js.map +1 -1
- package/dist/graphql/fragments/composition.fragment.d.ts +49 -0
- package/dist/graphql/fragments/composition.fragment.d.ts.map +1 -0
- package/dist/graphql/fragments/composition.fragment.js +50 -0
- package/dist/graphql/fragments/composition.fragment.js.map +1 -0
- package/dist/graphql/fragments/index.d.ts +1 -0
- package/dist/graphql/fragments/index.d.ts.map +1 -1
- package/dist/graphql/fragments/index.js +2 -0
- package/dist/graphql/fragments/index.js.map +1 -1
- package/dist/graphql/queries/composition.queries.d.ts +22 -0
- package/dist/graphql/queries/composition.queries.d.ts.map +1 -0
- package/dist/graphql/queries/composition.queries.js +30 -0
- package/dist/graphql/queries/composition.queries.js.map +1 -0
- package/dist/graphql/queries/index.d.ts +1 -0
- package/dist/graphql/queries/index.d.ts.map +1 -1
- package/dist/graphql/queries/index.js +2 -0
- package/dist/graphql/queries/index.js.map +1 -1
- package/dist/graphql/queries/portfolio.queries.d.ts +17 -0
- package/dist/graphql/queries/portfolio.queries.d.ts.map +1 -1
- package/dist/graphql/queries/portfolio.queries.js +25 -1
- package/dist/graphql/queries/portfolio.queries.js.map +1 -1
- package/dist/graphql/queries/risk.queries.d.ts +1 -1
- package/dist/graphql/queries/risk.queries.d.ts.map +1 -1
- package/dist/graphql/queries/risk.queries.js +7 -1
- package/dist/graphql/queries/risk.queries.js.map +1 -1
- package/dist/prompts/financial-analysis.d.ts.map +1 -1
- package/dist/prompts/financial-analysis.js +87 -7
- package/dist/prompts/financial-analysis.js.map +1 -1
- package/dist/server.js +1 -1
- package/dist/services/analytics/risk.service.d.ts +12 -0
- package/dist/services/analytics/risk.service.d.ts.map +1 -1
- package/dist/services/analytics/risk.service.js +26 -0
- package/dist/services/analytics/risk.service.js.map +1 -1
- package/dist/skills/portfolio-review.d.ts.map +1 -1
- package/dist/skills/portfolio-review.js +80 -4
- package/dist/skills/portfolio-review.js.map +1 -1
- package/dist/skills/risk-expert.d.ts.map +1 -1
- package/dist/skills/risk-expert.js +76 -10
- package/dist/skills/risk-expert.js.map +1 -1
- package/dist/tools/compare-vaults.d.ts.map +1 -1
- package/dist/tools/compare-vaults.js +75 -1
- package/dist/tools/compare-vaults.js.map +1 -1
- package/dist/tools/registry.d.ts.map +1 -1
- package/dist/tools/registry.js +15 -1
- package/dist/tools/registry.js.map +1 -1
- package/dist/tools/user-portfolio.d.ts.map +1 -1
- package/dist/tools/user-portfolio.js +97 -1
- package/dist/tools/user-portfolio.js.map +1 -1
- package/dist/tools/vault-composition.d.ts +27 -0
- package/dist/tools/vault-composition.d.ts.map +1 -0
- package/dist/tools/vault-composition.js +146 -0
- package/dist/tools/vault-composition.js.map +1 -0
- package/dist/utils/risk-scoring.d.ts +33 -0
- package/dist/utils/risk-scoring.d.ts.map +1 -1
- package/dist/utils/risk-scoring.js +73 -14
- package/dist/utils/risk-scoring.js.map +1 -1
- package/dist/utils/validators.d.ts +8 -0
- package/dist/utils/validators.d.ts.map +1 -1
- package/dist/utils/validators.js +4 -0
- package/dist/utils/validators.js.map +1 -1
- package/package.json +1 -1
package/dist/tools/registry.js
CHANGED
|
@@ -20,8 +20,9 @@ import { createExecuteAnalyzeRisk } from './analyze-risk.js';
|
|
|
20
20
|
import { createExecutePredictYield } from './predict-yield.js';
|
|
21
21
|
import { createExecuteOptimizePortfolio } from './optimize-portfolio.js';
|
|
22
22
|
import { createExecuteSimulateVault, simulateVaultInputSchema } from './simulate-vault.js';
|
|
23
|
+
import { createExecuteGetVaultComposition } from './vault-composition.js';
|
|
23
24
|
// Input schemas
|
|
24
|
-
import { queryGraphQLInputSchema, getVaultDataInputSchema, getUserPortfolioInputSchema, searchVaultsInputSchema, getVaultPerformanceInputSchema, getTransactionsInputSchema, compareVaultsInputSchema, priceHistoryInputSchema, exportDataInputSchema, analyzeRiskInputSchema, predictYieldInputSchema, optimizePortfolioInputSchema, } from '../utils/validators.js';
|
|
25
|
+
import { queryGraphQLInputSchema, getVaultDataInputSchema, getUserPortfolioInputSchema, searchVaultsInputSchema, getVaultPerformanceInputSchema, getTransactionsInputSchema, compareVaultsInputSchema, priceHistoryInputSchema, exportDataInputSchema, analyzeRiskInputSchema, predictYieldInputSchema, optimizePortfolioInputSchema, getVaultCompositionInputSchema, } from '../utils/validators.js';
|
|
25
26
|
// Tool utilities
|
|
26
27
|
import { createToolHandler } from '../utils/tool-handler.js';
|
|
27
28
|
/**
|
|
@@ -203,6 +204,19 @@ export const TOOL_REGISTRY = [
|
|
|
203
204
|
schema: simulateVaultInputSchema,
|
|
204
205
|
executorFactory: createExecuteSimulateVault,
|
|
205
206
|
},
|
|
207
|
+
{
|
|
208
|
+
name: 'get_vault_composition',
|
|
209
|
+
description: 'Fetch vault protocol and token composition with diversification analysis. ' +
|
|
210
|
+
'Returns breakdown by protocol (e.g., Aave, Morpho, Compound) and by position/token. ' +
|
|
211
|
+
'Calculates HHI (Herfindahl-Hirschman Index) for diversification scoring. ' +
|
|
212
|
+
'Diversification levels: High (HHI < 0.15), Medium (0.15-0.25), Low (> 0.25). ' +
|
|
213
|
+
'Small allocations (<1%) are grouped into "Other" category with details. ' +
|
|
214
|
+
'Best for: understanding protocol exposure, identifying concentration risks, portfolio composition analysis. ' +
|
|
215
|
+
'Performance: ~300-500 tokens per vault. ' +
|
|
216
|
+
'Features 15-minute caching (backend caches Octav API data for 6 hours).',
|
|
217
|
+
schema: getVaultCompositionInputSchema,
|
|
218
|
+
executorFactory: createExecuteGetVaultComposition,
|
|
219
|
+
},
|
|
206
220
|
];
|
|
207
221
|
/**
|
|
208
222
|
* Extract the raw shape from a Zod schema, handling ZodEffects wrappers.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/tools/registry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAa,SAAS,EAAe,UAAU,EAAE,MAAM,KAAK,CAAC;AAEpE,yBAAyB;AACzB,OAAO,EAAE,0BAA0B,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAC3F,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAC5D,OAAO,EAAE,6BAA6B,EAAE,MAAM,qBAAqB,CAAC;AACpE,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,gCAAgC,EAAE,MAAM,wBAAwB,CAAC;AAC1E,OAAO,EAAE,4BAA4B,EAAE,MAAM,uBAAuB,CAAC;AACrE,OAAO,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,EAAE,4BAA4B,EAAE,MAAM,wBAAwB,CAAC;AACtE,OAAO,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,8BAA8B,EAAE,MAAM,yBAAyB,CAAC;AACzE,OAAO,EAAE,0BAA0B,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/tools/registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user-portfolio.d.ts","sourceRoot":"","sources":["../../src/tools/user-portfolio.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"user-portfolio.d.ts","sourceRoot":"","sources":["../../src/tools/user-portfolio.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAS/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAuPxD;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAC3C,SAAS,EAAE,gBAAgB,GAC1B,CAAC,KAAK,EAAE,qBAAqB,KAAK,OAAO,CAAC,cAAc,CAAC,CAoI3D"}
|
|
@@ -18,10 +18,78 @@
|
|
|
18
18
|
* - Cache tags: [CacheTag.PORTFOLIO] for invalidation
|
|
19
19
|
*/
|
|
20
20
|
import { getToolDisclaimer } from '../utils/disclaimers.js';
|
|
21
|
-
import { createGetUserPortfolioQuery } from '../graphql/queries/portfolio.queries.js';
|
|
21
|
+
import { createGetUserPortfolioQuery, SINGLE_VAULT_COMPOSITION_QUERY, } from '../graphql/queries/portfolio.queries.js';
|
|
22
22
|
import { executeToolWithCache } from '../utils/execute-tool-with-cache.js';
|
|
23
23
|
import { CacheTag } from '../core/cache-invalidation.js';
|
|
24
24
|
import { cacheKeys, cacheTTL, generateCacheKey } from '../cache/index.js';
|
|
25
|
+
/**
|
|
26
|
+
* Aggregate composition data across all portfolio positions
|
|
27
|
+
*
|
|
28
|
+
* Calculates portfolio-wide protocol exposure weighted by position size,
|
|
29
|
+
* portfolio-level HHI, and detects accidental concentration across vaults.
|
|
30
|
+
*
|
|
31
|
+
* @param vaultCompositions - Array of vault compositions with position values
|
|
32
|
+
* @param totalPortfolioValue - Total portfolio value in USD
|
|
33
|
+
* @returns Portfolio composition summary with diversification metrics
|
|
34
|
+
*/
|
|
35
|
+
function aggregatePortfolioComposition(vaultCompositions, totalPortfolioValue) {
|
|
36
|
+
// Track protocol exposure across all vaults
|
|
37
|
+
const protocolExposureMap = new Map();
|
|
38
|
+
// Aggregate weighted exposure from each vault
|
|
39
|
+
for (const entry of vaultCompositions) {
|
|
40
|
+
for (const comp of entry.compositions) {
|
|
41
|
+
// Weight the protocol exposure by position size
|
|
42
|
+
const weightedExposure = (comp.repartition / 100) * entry.positionValueUsd;
|
|
43
|
+
const existing = protocolExposureMap.get(comp.protocol);
|
|
44
|
+
if (existing) {
|
|
45
|
+
existing.valueUsd += weightedExposure;
|
|
46
|
+
if (!existing.vaultAddresses.includes(entry.vaultAddress)) {
|
|
47
|
+
existing.vaultAddresses.push(entry.vaultAddress);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
protocolExposureMap.set(comp.protocol, {
|
|
52
|
+
valueUsd: weightedExposure,
|
|
53
|
+
vaultAddresses: [entry.vaultAddress],
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// Convert to array and calculate repartition percentages
|
|
59
|
+
const exposures = Array.from(protocolExposureMap.entries())
|
|
60
|
+
.map(([protocol, data]) => ({
|
|
61
|
+
protocol,
|
|
62
|
+
valueUsd: data.valueUsd,
|
|
63
|
+
repartition: totalPortfolioValue > 0 ? (data.valueUsd / totalPortfolioValue) * 100 : 0,
|
|
64
|
+
vaultCount: data.vaultAddresses.length,
|
|
65
|
+
}))
|
|
66
|
+
.sort((a, b) => b.repartition - a.repartition);
|
|
67
|
+
// Calculate portfolio-level HHI
|
|
68
|
+
const portfolioHHI = exposures.reduce((sum, e) => sum + Math.pow(e.repartition / 100, 2), 0);
|
|
69
|
+
// Determine diversification level
|
|
70
|
+
const diversificationLevel = portfolioHHI < 0.15 ? 'High' : portfolioHHI < 0.25 ? 'Medium' : 'Low';
|
|
71
|
+
// Detect accidental concentration (same protocol in 3+ vaults with >20% total exposure)
|
|
72
|
+
const accidentalConcentration = [];
|
|
73
|
+
for (const [protocol, data] of protocolExposureMap.entries()) {
|
|
74
|
+
const totalExposure = totalPortfolioValue > 0 ? (data.valueUsd / totalPortfolioValue) * 100 : 0;
|
|
75
|
+
if (data.vaultAddresses.length >= 3 && totalExposure >= 20) {
|
|
76
|
+
accidentalConcentration.push({
|
|
77
|
+
protocol,
|
|
78
|
+
vaultCount: data.vaultAddresses.length,
|
|
79
|
+
totalExposure,
|
|
80
|
+
vaultAddresses: data.vaultAddresses,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
protocolExposure: exposures.slice(0, 10), // Top 10 protocols
|
|
86
|
+
portfolioHHI,
|
|
87
|
+
diversificationLevel,
|
|
88
|
+
topProtocol: exposures[0]?.protocol || null,
|
|
89
|
+
topProtocolPercent: exposures[0]?.repartition || null,
|
|
90
|
+
accidentalConcentration,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
25
93
|
/**
|
|
26
94
|
* Transform raw GraphQL response into aggregated portfolio
|
|
27
95
|
*/
|
|
@@ -112,6 +180,7 @@ export function createExecuteGetUserPortfolio(container) {
|
|
|
112
180
|
const result = await executor(input);
|
|
113
181
|
// Post-process response to add flat chainId field for easier Claude extraction
|
|
114
182
|
// Also cache individual vaults for reuse by vault_data tool
|
|
183
|
+
// And fetch composition data for portfolio-level diversification analysis
|
|
115
184
|
if (!result.isError && result.content[0]?.type === 'text') {
|
|
116
185
|
try {
|
|
117
186
|
const responseData = JSON.parse(result.content[0].text);
|
|
@@ -133,6 +202,33 @@ export function createExecuteGetUserPortfolio(container) {
|
|
|
133
202
|
}
|
|
134
203
|
}
|
|
135
204
|
});
|
|
205
|
+
// Fetch composition data for each vault in parallel
|
|
206
|
+
// This enables portfolio-wide diversification analysis
|
|
207
|
+
const compositionPromises = positions.map(async (position) => {
|
|
208
|
+
try {
|
|
209
|
+
const compResponse = await container.graphqlClient.request(SINGLE_VAULT_COMPOSITION_QUERY, { vaultAddress: position.vaultAddress });
|
|
210
|
+
if (compResponse.vaultComposition?.compositions) {
|
|
211
|
+
return {
|
|
212
|
+
vaultAddress: position.vaultAddress,
|
|
213
|
+
positionValueUsd: parseFloat(position.sharesUsd || '0'),
|
|
214
|
+
compositions: compResponse.vaultComposition.compositions,
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
return null;
|
|
218
|
+
}
|
|
219
|
+
catch {
|
|
220
|
+
// If composition fetch fails for a vault, skip it
|
|
221
|
+
return null;
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
// Wait for all composition fetches (with timeout protection)
|
|
225
|
+
const compositionResults = await Promise.all(compositionPromises);
|
|
226
|
+
const validCompositions = compositionResults.filter((c) => c !== null);
|
|
227
|
+
// If we have composition data, calculate portfolio-level diversification
|
|
228
|
+
if (validCompositions.length > 0) {
|
|
229
|
+
const totalPortfolioValue = parseFloat(responseData.totalValueUsd || '0');
|
|
230
|
+
responseData.compositionSummary = aggregatePortfolioComposition(validCompositions, totalPortfolioValue);
|
|
231
|
+
}
|
|
136
232
|
// Update the result content with enriched data
|
|
137
233
|
result.content[0].text = JSON.stringify(responseData);
|
|
138
234
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user-portfolio.js","sourceRoot":"","sources":["../../src/tools/user-portfolio.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAIH,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAE5D,OAAO,
|
|
1
|
+
{"version":3,"file":"user-portfolio.js","sourceRoot":"","sources":["../../src/tools/user-portfolio.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* get_vault_composition Tool
|
|
3
|
+
*
|
|
4
|
+
* Fetch vault protocol and token composition with diversification analysis.
|
|
5
|
+
* Provides breakdown by protocol and by position/token.
|
|
6
|
+
*
|
|
7
|
+
* Use cases:
|
|
8
|
+
* - Understanding vault protocol exposure
|
|
9
|
+
* - Analyzing diversification levels via HHI score
|
|
10
|
+
* - Identifying concentration risks
|
|
11
|
+
* - Portfolio composition visualization
|
|
12
|
+
*
|
|
13
|
+
* Cache strategy:
|
|
14
|
+
* - 15-minute TTL aligned with vault data freshness
|
|
15
|
+
* - Cache key: composition:{address}
|
|
16
|
+
*/
|
|
17
|
+
import { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
|
|
18
|
+
import { GetVaultCompositionInput } from '../utils/validators.js';
|
|
19
|
+
import { ServiceContainer } from '../core/container.js';
|
|
20
|
+
/**
|
|
21
|
+
* Create the executeGetVaultComposition function with DI container
|
|
22
|
+
*
|
|
23
|
+
* @param container - Service container with dependencies
|
|
24
|
+
* @returns Configured tool executor function
|
|
25
|
+
*/
|
|
26
|
+
export declare function createExecuteGetVaultComposition(container: ServiceContainer): (input: GetVaultCompositionInput) => Promise<CallToolResult>;
|
|
27
|
+
//# sourceMappingURL=vault-composition.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vault-composition.d.ts","sourceRoot":"","sources":["../../src/tools/vault-composition.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACpE,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAKlE,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AA2HxD;;;;;GAKG;AACH,wBAAgB,gCAAgC,CAC9C,SAAS,EAAE,gBAAgB,GAC1B,CAAC,KAAK,EAAE,wBAAwB,KAAK,OAAO,CAAC,cAAc,CAAC,CAqD9D"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* get_vault_composition Tool
|
|
3
|
+
*
|
|
4
|
+
* Fetch vault protocol and token composition with diversification analysis.
|
|
5
|
+
* Provides breakdown by protocol and by position/token.
|
|
6
|
+
*
|
|
7
|
+
* Use cases:
|
|
8
|
+
* - Understanding vault protocol exposure
|
|
9
|
+
* - Analyzing diversification levels via HHI score
|
|
10
|
+
* - Identifying concentration risks
|
|
11
|
+
* - Portfolio composition visualization
|
|
12
|
+
*
|
|
13
|
+
* Cache strategy:
|
|
14
|
+
* - 15-minute TTL aligned with vault data freshness
|
|
15
|
+
* - Cache key: composition:{address}
|
|
16
|
+
*/
|
|
17
|
+
import { getToolDisclaimer } from '../utils/disclaimers.js';
|
|
18
|
+
import { GET_VAULT_COMPOSITION_QUERY } from '../graphql/queries/index.js';
|
|
19
|
+
import { executeToolWithCache } from '../utils/execute-tool-with-cache.js';
|
|
20
|
+
import { CacheTag } from '../core/cache-invalidation.js';
|
|
21
|
+
import { cacheKeys, cacheTTL } from '../cache/index.js';
|
|
22
|
+
import { createSuccessResponse } from '../utils/tool-response.js';
|
|
23
|
+
/**
|
|
24
|
+
* HHI (Herfindahl-Hirschman Index) calculation for diversification analysis
|
|
25
|
+
* Lower HHI = more diversified, Higher HHI = more concentrated
|
|
26
|
+
*
|
|
27
|
+
* HHI ranges (using market concentration thresholds):
|
|
28
|
+
* - < 0.15: High diversification (well-diversified)
|
|
29
|
+
* - 0.15 - 0.25: Moderate concentration
|
|
30
|
+
* - > 0.25: High concentration
|
|
31
|
+
*
|
|
32
|
+
* @param compositions - Array of protocol compositions with repartition percentages
|
|
33
|
+
* @returns HHI score between 0 and 1
|
|
34
|
+
*/
|
|
35
|
+
function calculateHHI(compositions) {
|
|
36
|
+
if (compositions.length === 0)
|
|
37
|
+
return 0;
|
|
38
|
+
// HHI = sum of squared market shares (repartition is already in percentage, divide by 100)
|
|
39
|
+
return compositions.reduce((sum, c) => sum + Math.pow(c.repartition / 100, 2), 0);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Get diversification level label based on HHI score
|
|
43
|
+
*/
|
|
44
|
+
function getDiversificationLevel(hhi) {
|
|
45
|
+
if (hhi < 0.15)
|
|
46
|
+
return 'High';
|
|
47
|
+
if (hhi < 0.25)
|
|
48
|
+
return 'Medium';
|
|
49
|
+
return 'Low';
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Transform raw composition data into enhanced response with analysis
|
|
53
|
+
*/
|
|
54
|
+
function transformToEnhancedResponse(data, vaultAddress) {
|
|
55
|
+
const composition = data.vaultComposition;
|
|
56
|
+
if (!composition) {
|
|
57
|
+
return {
|
|
58
|
+
vaultAddress,
|
|
59
|
+
compositions: [],
|
|
60
|
+
tokenCompositions: [],
|
|
61
|
+
analysis: {
|
|
62
|
+
protocolCount: 0,
|
|
63
|
+
positionCount: 0,
|
|
64
|
+
hhi: 0,
|
|
65
|
+
diversificationLevel: 'High',
|
|
66
|
+
topProtocol: null,
|
|
67
|
+
topProtocolPercent: null,
|
|
68
|
+
hasOtherCategory: false,
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
const { compositions, tokenCompositions } = composition;
|
|
73
|
+
// Calculate HHI from protocol compositions (excluding "Other" for accurate HHI)
|
|
74
|
+
const mainCompositions = compositions.filter((c) => c.protocol !== 'Other');
|
|
75
|
+
const hhi = calculateHHI(mainCompositions);
|
|
76
|
+
const diversificationLevel = getDiversificationLevel(hhi);
|
|
77
|
+
// Find top protocol
|
|
78
|
+
const topProtocol = mainCompositions.length > 0
|
|
79
|
+
? mainCompositions.reduce((max, c) => (c.repartition > max.repartition ? c : max))
|
|
80
|
+
: null;
|
|
81
|
+
// Check for "Other" category
|
|
82
|
+
const hasOtherCategory = compositions.some((c) => c.protocol === 'Other');
|
|
83
|
+
return {
|
|
84
|
+
vaultAddress,
|
|
85
|
+
compositions,
|
|
86
|
+
tokenCompositions,
|
|
87
|
+
analysis: {
|
|
88
|
+
protocolCount: mainCompositions.length,
|
|
89
|
+
positionCount: tokenCompositions.filter((t) => t.symbol !== 'Other').length,
|
|
90
|
+
hhi: parseFloat(hhi.toFixed(4)),
|
|
91
|
+
diversificationLevel,
|
|
92
|
+
topProtocol: topProtocol?.protocol ?? null,
|
|
93
|
+
topProtocolPercent: topProtocol?.repartition ?? null,
|
|
94
|
+
hasOtherCategory,
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Create the executeGetVaultComposition function with DI container
|
|
100
|
+
*
|
|
101
|
+
* @param container - Service container with dependencies
|
|
102
|
+
* @returns Configured tool executor function
|
|
103
|
+
*/
|
|
104
|
+
export function createExecuteGetVaultComposition(container) {
|
|
105
|
+
return async (input) => {
|
|
106
|
+
// Check fragment-level cache first
|
|
107
|
+
const fragmentCacheKey = cacheKeys.composition(input.vaultAddress);
|
|
108
|
+
const cachedComposition = container.cache.get(fragmentCacheKey);
|
|
109
|
+
if (cachedComposition) {
|
|
110
|
+
return createSuccessResponse(cachedComposition);
|
|
111
|
+
}
|
|
112
|
+
// Capture vaultAddress for use in transformResult closure
|
|
113
|
+
const vaultAddress = input.vaultAddress;
|
|
114
|
+
// Cache miss - execute GraphQL query with standard caching
|
|
115
|
+
const executor = executeToolWithCache({
|
|
116
|
+
container,
|
|
117
|
+
cacheKey: () => cacheKeys.composition(vaultAddress),
|
|
118
|
+
cacheTTL: cacheTTL.composition,
|
|
119
|
+
query: GET_VAULT_COMPOSITION_QUERY,
|
|
120
|
+
variables: (toolInput) => ({
|
|
121
|
+
vaultAddress: toolInput.vaultAddress,
|
|
122
|
+
}),
|
|
123
|
+
validateResult: (data) => {
|
|
124
|
+
// Composition might be null if vault doesn't have data yet - that's okay
|
|
125
|
+
return {
|
|
126
|
+
valid: true,
|
|
127
|
+
message: data.vaultComposition
|
|
128
|
+
? undefined
|
|
129
|
+
: 'No composition data available for this vault',
|
|
130
|
+
isError: false,
|
|
131
|
+
};
|
|
132
|
+
},
|
|
133
|
+
transformResult: (data) => transformToEnhancedResponse(data, vaultAddress),
|
|
134
|
+
toolName: 'get_vault_composition',
|
|
135
|
+
});
|
|
136
|
+
// Register cache tags for invalidation
|
|
137
|
+
container.cacheInvalidator.register(fragmentCacheKey, [CacheTag.VAULT]);
|
|
138
|
+
const result = await executor(input);
|
|
139
|
+
// Add legal disclaimer to output
|
|
140
|
+
if (!result.isError && result.content[0]?.type === 'text') {
|
|
141
|
+
result.content[0].text = result.content[0].text + getToolDisclaimer('vault_composition');
|
|
142
|
+
}
|
|
143
|
+
return result;
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=vault-composition.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vault-composition.js","sourceRoot":"","sources":["../../src/tools/vault-composition.ts"],"names":[],"mappings":"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"}
|
|
@@ -20,6 +20,8 @@ export interface RiskScoreBreakdown {
|
|
|
20
20
|
settlementRisk: number;
|
|
21
21
|
integrationComplexityRisk: number;
|
|
22
22
|
capacityUtilizationRisk: number;
|
|
23
|
+
protocolDiversificationRisk: number;
|
|
24
|
+
topProtocolConcentrationRisk: number;
|
|
23
25
|
overallRisk: number;
|
|
24
26
|
riskLevel: 'Low' | 'Medium' | 'High' | 'Critical';
|
|
25
27
|
}
|
|
@@ -156,6 +158,31 @@ export declare function calculateSettlementRisk(settlementData: {
|
|
|
156
158
|
* @returns Risk score 0-1 (0 = lowest risk, 1 = highest risk)
|
|
157
159
|
*/
|
|
158
160
|
export declare function calculateIntegrationComplexityRisk(integrationCount: number): number;
|
|
161
|
+
/**
|
|
162
|
+
* Calculate protocol diversification risk based on HHI (Herfindahl-Hirschman Index)
|
|
163
|
+
*
|
|
164
|
+
* HHI measures concentration: sum of squared market shares
|
|
165
|
+
* - HHI < 0.15: Well diversified across protocols
|
|
166
|
+
* - HHI 0.15-0.25: Moderate concentration
|
|
167
|
+
* - HHI 0.25-0.50: High concentration
|
|
168
|
+
* - HHI > 0.50: Very high concentration (single protocol dominance)
|
|
169
|
+
*
|
|
170
|
+
* @param compositions - Array of protocol compositions with repartition (0-100%)
|
|
171
|
+
* @returns Risk score 0-1 (lower = better diversification)
|
|
172
|
+
*/
|
|
173
|
+
export declare function calculateProtocolDiversificationRisk(compositions: Array<{
|
|
174
|
+
repartition: number;
|
|
175
|
+
}> | null | undefined): number;
|
|
176
|
+
/**
|
|
177
|
+
* Calculate top protocol concentration risk
|
|
178
|
+
*
|
|
179
|
+
* Evaluates the risk of having too much exposure to a single protocol.
|
|
180
|
+
* Complements HHI by specifically flagging dominant protocol exposure.
|
|
181
|
+
*
|
|
182
|
+
* @param topProtocolPercent - Percentage allocation to top protocol (0-100 or null)
|
|
183
|
+
* @returns Risk score 0-1 (lower = healthier distribution)
|
|
184
|
+
*/
|
|
185
|
+
export declare function calculateTopProtocolConcentrationRisk(topProtocolPercent: number | null | undefined): number;
|
|
159
186
|
/**
|
|
160
187
|
* Calculate capacity utilization risk score
|
|
161
188
|
* Assesses deposit headroom and demand signals
|
|
@@ -222,5 +249,11 @@ export declare function analyzeRisk(params: {
|
|
|
222
249
|
totalAssets: number;
|
|
223
250
|
maxCapacity: number | null;
|
|
224
251
|
};
|
|
252
|
+
compositionData?: {
|
|
253
|
+
compositions?: Array<{
|
|
254
|
+
repartition: number;
|
|
255
|
+
}>;
|
|
256
|
+
topProtocolPercent?: number | null;
|
|
257
|
+
};
|
|
225
258
|
}): RiskScoreBreakdown;
|
|
226
259
|
//# sourceMappingURL=risk-scoring.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"risk-scoring.d.ts","sourceRoot":"","sources":["../../src/utils/risk-scoring.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"risk-scoring.d.ts","sourceRoot":"","sources":["../../src/utils/risk-scoring.ts"],"names":[],"mappings":"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"}
|
|
@@ -385,6 +385,54 @@ export function calculateIntegrationComplexityRisk(integrationCount) {
|
|
|
385
385
|
return 1.0; // Very high complexity = large attack surface
|
|
386
386
|
}
|
|
387
387
|
}
|
|
388
|
+
/**
|
|
389
|
+
* Calculate protocol diversification risk based on HHI (Herfindahl-Hirschman Index)
|
|
390
|
+
*
|
|
391
|
+
* HHI measures concentration: sum of squared market shares
|
|
392
|
+
* - HHI < 0.15: Well diversified across protocols
|
|
393
|
+
* - HHI 0.15-0.25: Moderate concentration
|
|
394
|
+
* - HHI 0.25-0.50: High concentration
|
|
395
|
+
* - HHI > 0.50: Very high concentration (single protocol dominance)
|
|
396
|
+
*
|
|
397
|
+
* @param compositions - Array of protocol compositions with repartition (0-100%)
|
|
398
|
+
* @returns Risk score 0-1 (lower = better diversification)
|
|
399
|
+
*/
|
|
400
|
+
export function calculateProtocolDiversificationRisk(compositions) {
|
|
401
|
+
if (!compositions?.length) {
|
|
402
|
+
return 0.5; // Unknown composition = medium risk
|
|
403
|
+
}
|
|
404
|
+
// Calculate HHI: sum of squared shares (repartition is 0-100, convert to 0-1)
|
|
405
|
+
const hhi = compositions.reduce((sum, c) => sum + Math.pow(c.repartition / 100, 2), 0);
|
|
406
|
+
// Map HHI to risk score
|
|
407
|
+
if (hhi < 0.15)
|
|
408
|
+
return 0.1; // Well diversified
|
|
409
|
+
if (hhi < 0.25)
|
|
410
|
+
return 0.35; // Moderate concentration
|
|
411
|
+
if (hhi < 0.5)
|
|
412
|
+
return 0.65; // High concentration
|
|
413
|
+
return 0.9; // Very high concentration
|
|
414
|
+
}
|
|
415
|
+
/**
|
|
416
|
+
* Calculate top protocol concentration risk
|
|
417
|
+
*
|
|
418
|
+
* Evaluates the risk of having too much exposure to a single protocol.
|
|
419
|
+
* Complements HHI by specifically flagging dominant protocol exposure.
|
|
420
|
+
*
|
|
421
|
+
* @param topProtocolPercent - Percentage allocation to top protocol (0-100 or null)
|
|
422
|
+
* @returns Risk score 0-1 (lower = healthier distribution)
|
|
423
|
+
*/
|
|
424
|
+
export function calculateTopProtocolConcentrationRisk(topProtocolPercent) {
|
|
425
|
+
if (topProtocolPercent === null || topProtocolPercent === undefined) {
|
|
426
|
+
return 0.5; // Unknown = medium risk
|
|
427
|
+
}
|
|
428
|
+
if (topProtocolPercent < 30)
|
|
429
|
+
return 0.1; // Healthy distribution
|
|
430
|
+
if (topProtocolPercent < 50)
|
|
431
|
+
return 0.35; // Moderate top holding
|
|
432
|
+
if (topProtocolPercent < 70)
|
|
433
|
+
return 0.65; // High concentration
|
|
434
|
+
return 0.9; // Dangerous concentration
|
|
435
|
+
}
|
|
388
436
|
/**
|
|
389
437
|
* Calculate capacity utilization risk score
|
|
390
438
|
* Assesses deposit headroom and demand signals
|
|
@@ -418,20 +466,22 @@ export function calculateCapacityUtilizationRisk(utilizationData) {
|
|
|
418
466
|
* @returns Overall risk score 0-1 and risk level
|
|
419
467
|
*/
|
|
420
468
|
export function calculateOverallRisk(breakdown) {
|
|
421
|
-
// Weighted average of
|
|
469
|
+
// Weighted average of 14 risk factors (updated to include composition)
|
|
422
470
|
const weights = {
|
|
423
|
-
tvl: 0.1
|
|
424
|
-
concentration: 0.1
|
|
425
|
-
volatility: 0.15
|
|
426
|
-
age: 0.1
|
|
427
|
-
curator: 0.1
|
|
428
|
-
fee: 0.1
|
|
429
|
-
liquidity: 0.1
|
|
430
|
-
aprConsistency: 0.
|
|
431
|
-
yieldSustainability: 0.05,
|
|
432
|
-
settlement: 0.05,
|
|
433
|
-
integrationComplexity: 0.05,
|
|
434
|
-
capacityUtilization: 0.05,
|
|
471
|
+
tvl: 0.08, // Reduced from 0.1
|
|
472
|
+
concentration: 0.08, // Reduced from 0.1
|
|
473
|
+
volatility: 0.14, // Reduced from 0.15
|
|
474
|
+
age: 0.08, // Reduced from 0.1
|
|
475
|
+
curator: 0.08, // Reduced from 0.1
|
|
476
|
+
fee: 0.08, // Reduced from 0.1
|
|
477
|
+
liquidity: 0.08, // Reduced from 0.1
|
|
478
|
+
aprConsistency: 0.13, // Reduced from 0.15
|
|
479
|
+
yieldSustainability: 0.05,
|
|
480
|
+
settlement: 0.05,
|
|
481
|
+
integrationComplexity: 0.05,
|
|
482
|
+
capacityUtilization: 0.05,
|
|
483
|
+
protocolDiversification: 0.05, // NEW: Composition-based
|
|
484
|
+
topProtocolConcentration: 0.05, // NEW: Composition-based
|
|
435
485
|
};
|
|
436
486
|
const overallRisk = breakdown.tvlRisk * weights.tvl +
|
|
437
487
|
breakdown.concentrationRisk * weights.concentration +
|
|
@@ -444,7 +494,9 @@ export function calculateOverallRisk(breakdown) {
|
|
|
444
494
|
breakdown.yieldSustainabilityRisk * weights.yieldSustainability +
|
|
445
495
|
breakdown.settlementRisk * weights.settlement +
|
|
446
496
|
breakdown.integrationComplexityRisk * weights.integrationComplexity +
|
|
447
|
-
breakdown.capacityUtilizationRisk * weights.capacityUtilization
|
|
497
|
+
breakdown.capacityUtilizationRisk * weights.capacityUtilization +
|
|
498
|
+
breakdown.protocolDiversificationRisk * weights.protocolDiversification +
|
|
499
|
+
breakdown.topProtocolConcentrationRisk * weights.topProtocolConcentration;
|
|
448
500
|
// Determine risk level
|
|
449
501
|
let riskLevel;
|
|
450
502
|
if (overallRisk < RISK_THRESHOLDS.OVERALL_LOW) {
|
|
@@ -489,6 +541,9 @@ export function analyzeRisk(params) {
|
|
|
489
541
|
const capacityUtilizationRisk = params.capacityData
|
|
490
542
|
? calculateCapacityUtilizationRisk(params.capacityData)
|
|
491
543
|
: 0.2; // Default to low risk (no capacity limit)
|
|
544
|
+
// NEW: Calculate composition-based risk factors
|
|
545
|
+
const protocolDiversificationRisk = calculateProtocolDiversificationRisk(params.compositionData?.compositions);
|
|
546
|
+
const topProtocolConcentrationRisk = calculateTopProtocolConcentrationRisk(params.compositionData?.topProtocolPercent);
|
|
492
547
|
const { overallRisk, riskLevel } = calculateOverallRisk({
|
|
493
548
|
tvlRisk,
|
|
494
549
|
concentrationRisk,
|
|
@@ -502,6 +557,8 @@ export function analyzeRisk(params) {
|
|
|
502
557
|
settlementRisk,
|
|
503
558
|
integrationComplexityRisk,
|
|
504
559
|
capacityUtilizationRisk,
|
|
560
|
+
protocolDiversificationRisk,
|
|
561
|
+
topProtocolConcentrationRisk,
|
|
505
562
|
});
|
|
506
563
|
return {
|
|
507
564
|
tvlRisk,
|
|
@@ -516,6 +573,8 @@ export function analyzeRisk(params) {
|
|
|
516
573
|
settlementRisk,
|
|
517
574
|
integrationComplexityRisk,
|
|
518
575
|
capacityUtilizationRisk,
|
|
576
|
+
protocolDiversificationRisk,
|
|
577
|
+
topProtocolConcentrationRisk,
|
|
519
578
|
overallRisk,
|
|
520
579
|
riskLevel,
|
|
521
580
|
};
|