@moonwell-fi/moonwell-sdk 0.9.21 → 0.9.23
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/CHANGELOG.md +14 -0
- package/_cjs/actions/governance/common.js +33 -4
- package/_cjs/actions/governance/common.js.map +1 -1
- package/_cjs/actions/morpho/vaults/common.js +61 -2
- package/_cjs/actions/morpho/vaults/common.js.map +1 -1
- package/_cjs/environments/definitions/base/morpho-markets.js +0 -5
- package/_cjs/environments/definitions/base/morpho-markets.js.map +1 -1
- package/_cjs/environments/definitions/base/morpho-vaults.js +3 -3
- package/_cjs/environments/definitions/base/morpho-vaults.js.map +1 -1
- package/_cjs/environments/definitions/base/tokens.js +5 -5
- package/_cjs/errors/version.js +1 -1
- package/_esm/actions/governance/common.js +35 -4
- package/_esm/actions/governance/common.js.map +1 -1
- package/_esm/actions/morpho/vaults/common.js +85 -6
- package/_esm/actions/morpho/vaults/common.js.map +1 -1
- package/_esm/environments/definitions/base/morpho-markets.js +0 -5
- package/_esm/environments/definitions/base/morpho-markets.js.map +1 -1
- package/_esm/environments/definitions/base/morpho-vaults.js +3 -3
- package/_esm/environments/definitions/base/morpho-vaults.js.map +1 -1
- package/_esm/environments/definitions/base/tokens.js +5 -5
- package/_esm/errors/version.js +1 -1
- package/_types/actions/governance/common.d.ts.map +1 -1
- package/_types/actions/morpho/vaults/common.d.ts.map +1 -1
- package/_types/client/createMoonwellClient.d.ts +32 -32
- package/_types/environments/definitions/base/morpho-markets.d.ts +0 -5
- package/_types/environments/definitions/base/morpho-markets.d.ts.map +1 -1
- package/_types/environments/definitions/base/morpho-vaults.d.ts +3 -3
- package/_types/environments/definitions/base/tokens.d.ts +5 -5
- package/_types/environments/index.d.ts +8 -8
- package/_types/errors/version.d.ts +1 -1
- package/actions/governance/common.ts +51 -4
- package/actions/morpho/vaults/common.ts +208 -7
- package/environments/definitions/base/morpho-markets.ts +0 -5
- package/environments/definitions/base/morpho-vaults.ts +3 -3
- package/environments/definitions/base/tokens.ts +5 -5
- package/errors/version.ts +1 -1
- package/package.json +1 -1
|
@@ -28,6 +28,108 @@ import {
|
|
|
28
28
|
wMulDown,
|
|
29
29
|
} from "../utils/math.js";
|
|
30
30
|
|
|
31
|
+
/**
|
|
32
|
+
* Morpho Vault Data Aggregation
|
|
33
|
+
*
|
|
34
|
+
* This module handles data retrieval for both V1 (MetaMorpho) and V2 (Morpho Vault) vaults.
|
|
35
|
+
*
|
|
36
|
+
* IMPORTANT: Vault Key Naming Convention
|
|
37
|
+
* ------------------------------------------
|
|
38
|
+
* V2 vaults wrap V1 vaults, creating a nested structure. The naming convention reflects this:
|
|
39
|
+
*
|
|
40
|
+
* - `meUSDC` = V2 vault (version 2) - wraps the V1 vault below
|
|
41
|
+
* - `meUSDCv1` = V1 vault (version 1) - the underlying vault wrapped by V2
|
|
42
|
+
*
|
|
43
|
+
* The V2 vault allocates its assets to one or more V1 vaults via adapters.
|
|
44
|
+
* Market allocations for V2 vaults are calculated by scaling the V1 vault's
|
|
45
|
+
* market positions based on V2's ownership percentage in the V1 vault.
|
|
46
|
+
*
|
|
47
|
+
* Example:
|
|
48
|
+
* - meUSDC (V2) owns 60% of meUSDCv1 (V1)
|
|
49
|
+
* - meUSDCv1 (V1) has 100 USDC supplied to Market A
|
|
50
|
+
* - meUSDC's (V2) effective supply to Market A = 60 USDC
|
|
51
|
+
*
|
|
52
|
+
* @module morpho/vaults/common
|
|
53
|
+
*/
|
|
54
|
+
|
|
55
|
+
// Type definitions for V2 vault data structures
|
|
56
|
+
type MorphoViewsV2GetVaultsInfoReturn = readonly {
|
|
57
|
+
readonly vault: Address;
|
|
58
|
+
readonly totalSupply: bigint;
|
|
59
|
+
readonly totalAssets: bigint;
|
|
60
|
+
readonly underlyingPrice: bigint;
|
|
61
|
+
readonly adapters: readonly {
|
|
62
|
+
readonly adapter: Address;
|
|
63
|
+
readonly realAssets: bigint;
|
|
64
|
+
readonly underlyingVault: Address;
|
|
65
|
+
readonly underlyingVaultName: string;
|
|
66
|
+
readonly underlyingVaultTotalAssets: bigint;
|
|
67
|
+
readonly underlyingVaultFee: bigint;
|
|
68
|
+
readonly underlyingVaultTimelock: bigint;
|
|
69
|
+
readonly allocationPercentage: bigint;
|
|
70
|
+
readonly underlyingMarkets: readonly {
|
|
71
|
+
readonly marketId: `0x${string}`;
|
|
72
|
+
readonly collateralToken: Address;
|
|
73
|
+
readonly collateralName: string;
|
|
74
|
+
readonly collateralSymbol: string;
|
|
75
|
+
readonly marketLiquidity: bigint;
|
|
76
|
+
readonly marketLltv: bigint;
|
|
77
|
+
readonly marketSupplyApy: bigint;
|
|
78
|
+
readonly marketBorrowApy: bigint;
|
|
79
|
+
}[];
|
|
80
|
+
}[];
|
|
81
|
+
}[];
|
|
82
|
+
|
|
83
|
+
type V2VaultInfo = MorphoViewsV2GetVaultsInfoReturn[number];
|
|
84
|
+
type AdapterInfo = V2VaultInfo["adapters"][number];
|
|
85
|
+
type UnderlyingMarket = AdapterInfo["underlyingMarkets"][number];
|
|
86
|
+
|
|
87
|
+
// Type definitions for V1 vault data structures
|
|
88
|
+
type MorphoViewsGetVaultsInfoReturn = readonly {
|
|
89
|
+
readonly vault: Address;
|
|
90
|
+
readonly totalSupply: bigint;
|
|
91
|
+
readonly totalAssets: bigint;
|
|
92
|
+
readonly underlyingPrice: bigint;
|
|
93
|
+
readonly fee: bigint;
|
|
94
|
+
readonly timelock: bigint;
|
|
95
|
+
readonly markets: readonly {
|
|
96
|
+
readonly marketId: `0x${string}`;
|
|
97
|
+
readonly marketCollateral: Address;
|
|
98
|
+
readonly marketCollateralName: string;
|
|
99
|
+
readonly marketCollateralSymbol: string;
|
|
100
|
+
readonly marketLltv: bigint;
|
|
101
|
+
readonly marketApy: bigint;
|
|
102
|
+
readonly marketLiquidity: bigint;
|
|
103
|
+
readonly vaultSupplied: bigint;
|
|
104
|
+
}[];
|
|
105
|
+
}[];
|
|
106
|
+
|
|
107
|
+
type V1VaultInfo = MorphoViewsGetVaultsInfoReturn[number];
|
|
108
|
+
type V1MarketInfo = V1VaultInfo["markets"][number];
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Scales a V1 vault's market position by V2's ownership percentage.
|
|
112
|
+
*
|
|
113
|
+
* V2 vaults wrap V1 vaults - this calculates the V2 vault's effective
|
|
114
|
+
* position in a V1 vault's market by scaling based on ownership:
|
|
115
|
+
* V2 ownership = realAssets / underlyingVaultTotalAssets
|
|
116
|
+
*
|
|
117
|
+
* @param v1VaultSupplied - The V1 vault's supplied amount in the market
|
|
118
|
+
* @param v2RealAssets - The V2 vault's real assets in the V1 vault
|
|
119
|
+
* @param v1VaultTotalAssets - Total assets in the underlying V1 vault
|
|
120
|
+
* @returns Scaled vault supplied amount, or 0n if V1 vault has no assets
|
|
121
|
+
*/
|
|
122
|
+
function scaleV1MarketPositionByV2Ownership(
|
|
123
|
+
v1VaultSupplied: bigint,
|
|
124
|
+
v2RealAssets: bigint,
|
|
125
|
+
v1VaultTotalAssets: bigint,
|
|
126
|
+
): bigint {
|
|
127
|
+
if (v1VaultTotalAssets === 0n) {
|
|
128
|
+
return 0n;
|
|
129
|
+
}
|
|
130
|
+
return mulDivDown(v1VaultSupplied, v2RealAssets, v1VaultTotalAssets);
|
|
131
|
+
}
|
|
132
|
+
|
|
31
133
|
export async function getMorphoVaultsData(params: {
|
|
32
134
|
environments: Environment[];
|
|
33
135
|
vaults?: string[];
|
|
@@ -111,6 +213,8 @@ export async function getMorphoVaultsData(params: {
|
|
|
111
213
|
}
|
|
112
214
|
|
|
113
215
|
// Query v2 vaults with morphoViewsV2
|
|
216
|
+
// Note: V2 vaults (e.g., meUSDC) wrap V1 vaults (e.g., meUSDCv1).
|
|
217
|
+
// The V2 vault allocates its assets to underlying V1 vaults via adapters.
|
|
114
218
|
if (v2VaultsAddresses.length > 0 && environment.contracts.morphoViewsV2) {
|
|
115
219
|
queryPromises.push(
|
|
116
220
|
(async () => {
|
|
@@ -120,8 +224,45 @@ export async function getMorphoVaultsData(params: {
|
|
|
120
224
|
v2VaultsAddresses,
|
|
121
225
|
]);
|
|
122
226
|
|
|
227
|
+
// Extract unique underlying vault addresses from V2 adapters
|
|
228
|
+
const underlyingVaultAddresses =
|
|
229
|
+
(vaultInfoV2 as MorphoViewsV2GetVaultsInfoReturn | undefined)
|
|
230
|
+
?.flatMap((v2Vault) =>
|
|
231
|
+
v2Vault.adapters?.map((adapter) => adapter.underlyingVault),
|
|
232
|
+
)
|
|
233
|
+
.filter((addr) => addr && addr !== zeroAddress) || [];
|
|
234
|
+
|
|
235
|
+
const uniqueUnderlyingAddresses = [
|
|
236
|
+
...new Set(underlyingVaultAddresses),
|
|
237
|
+
] as `0x${string}`[];
|
|
238
|
+
|
|
239
|
+
// Query underlying V1 vaults to get their market positions
|
|
240
|
+
const underlyingVaultsData: Map<string, V1VaultInfo> = new Map();
|
|
241
|
+
if (
|
|
242
|
+
uniqueUnderlyingAddresses.length > 0 &&
|
|
243
|
+
environment.contracts.morphoViews
|
|
244
|
+
) {
|
|
245
|
+
const underlyingInfo =
|
|
246
|
+
await environment.contracts.morphoViews.read.getVaultsInfo([
|
|
247
|
+
uniqueUnderlyingAddresses,
|
|
248
|
+
]);
|
|
249
|
+
|
|
250
|
+
// Map by vault address for quick lookup
|
|
251
|
+
underlyingInfo?.forEach(
|
|
252
|
+
(vaultData: V1VaultInfo, index: number) => {
|
|
253
|
+
underlyingVaultsData.set(
|
|
254
|
+
uniqueUnderlyingAddresses[index].toLowerCase(),
|
|
255
|
+
vaultData,
|
|
256
|
+
);
|
|
257
|
+
},
|
|
258
|
+
);
|
|
259
|
+
}
|
|
260
|
+
|
|
123
261
|
// Transform v2 structure to v1 structure
|
|
124
|
-
|
|
262
|
+
// V2 vaults wrap V1 vaults - we fetch the V1 data and scale allocations
|
|
263
|
+
const transformedVaults = (
|
|
264
|
+
vaultInfoV2 as MorphoViewsV2GetVaultsInfoReturn | undefined
|
|
265
|
+
)?.map((v2Vault) => {
|
|
125
266
|
// Get the first adapter (assuming single adapter for now)
|
|
126
267
|
const adapter = v2Vault.adapters?.[0];
|
|
127
268
|
|
|
@@ -137,11 +278,55 @@ export async function getMorphoVaultsData(params: {
|
|
|
137
278
|
};
|
|
138
279
|
}
|
|
139
280
|
|
|
140
|
-
//
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
281
|
+
// Get underlying vault data for accurate market allocations
|
|
282
|
+
const underlyingVaultData = underlyingVaultsData.get(
|
|
283
|
+
adapter.underlyingVault.toLowerCase(),
|
|
284
|
+
);
|
|
285
|
+
|
|
286
|
+
let markets: V1MarketInfo[] = [];
|
|
287
|
+
|
|
288
|
+
if (underlyingVaultData?.markets) {
|
|
289
|
+
// Map V1 vault's markets with scaled allocations
|
|
290
|
+
markets = underlyingVaultData.markets.map(
|
|
291
|
+
(v1Market: V1MarketInfo) => {
|
|
292
|
+
// Scale the V1 vault's position by V2's ownership
|
|
293
|
+
// V2 ownership = realAssets / underlyingVaultTotalAssets
|
|
294
|
+
const scaledVaultSupplied =
|
|
295
|
+
scaleV1MarketPositionByV2Ownership(
|
|
296
|
+
v1Market.vaultSupplied,
|
|
297
|
+
adapter.realAssets,
|
|
298
|
+
adapter.underlyingVaultTotalAssets,
|
|
299
|
+
);
|
|
300
|
+
|
|
301
|
+
return {
|
|
302
|
+
marketId: v1Market.marketId,
|
|
303
|
+
marketCollateral: v1Market.marketCollateral,
|
|
304
|
+
marketCollateralName: v1Market.marketCollateralName,
|
|
305
|
+
marketCollateralSymbol: v1Market.marketCollateralSymbol,
|
|
306
|
+
marketLltv: v1Market.marketLltv,
|
|
307
|
+
marketApy: v1Market.marketApy,
|
|
308
|
+
marketLiquidity: v1Market.marketLiquidity,
|
|
309
|
+
vaultSupplied: scaledVaultSupplied,
|
|
310
|
+
};
|
|
311
|
+
},
|
|
312
|
+
);
|
|
313
|
+
} else {
|
|
314
|
+
// Fallback: if we can't get V1 data, use underlyingMarkets with 0 allocations
|
|
315
|
+
markets =
|
|
316
|
+
(adapter.underlyingMarkets || []).map(
|
|
317
|
+
(underlyingMarket: UnderlyingMarket) => ({
|
|
318
|
+
marketId: underlyingMarket.marketId,
|
|
319
|
+
marketCollateral: underlyingMarket.collateralToken,
|
|
320
|
+
marketCollateralName: underlyingMarket.collateralName,
|
|
321
|
+
marketCollateralSymbol:
|
|
322
|
+
underlyingMarket.collateralSymbol,
|
|
323
|
+
marketLltv: underlyingMarket.marketLltv,
|
|
324
|
+
marketApy: underlyingMarket.marketSupplyApy,
|
|
325
|
+
marketLiquidity: underlyingMarket.marketLiquidity,
|
|
326
|
+
vaultSupplied: 0n,
|
|
327
|
+
}),
|
|
328
|
+
) || [];
|
|
329
|
+
}
|
|
145
330
|
|
|
146
331
|
return {
|
|
147
332
|
vault: v2Vault.vault,
|
|
@@ -167,7 +352,23 @@ export async function getMorphoVaultsData(params: {
|
|
|
167
352
|
.filter((r): r is NonNullable<typeof r> => r !== undefined)
|
|
168
353
|
.flat();
|
|
169
354
|
|
|
170
|
-
|
|
355
|
+
// Sort results to match the order in environment.config.vaults
|
|
356
|
+
const vaultKeys = Object.keys(environment.config.vaults);
|
|
357
|
+
const sortedResults = results.sort((a, b) => {
|
|
358
|
+
const aIndex = vaultKeys.findIndex(
|
|
359
|
+
(key) =>
|
|
360
|
+
environment.vaults[key]?.address.toLowerCase() ===
|
|
361
|
+
a.vault.toLowerCase(),
|
|
362
|
+
);
|
|
363
|
+
const bIndex = vaultKeys.findIndex(
|
|
364
|
+
(key) =>
|
|
365
|
+
environment.vaults[key]?.address.toLowerCase() ===
|
|
366
|
+
b.vault.toLowerCase(),
|
|
367
|
+
);
|
|
368
|
+
return aIndex - bIndex;
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
return sortedResults;
|
|
171
372
|
}),
|
|
172
373
|
);
|
|
173
374
|
|
|
@@ -45,11 +45,6 @@ export const morphoMarkets = createMorphoMarketConfig({
|
|
|
45
45
|
id: "0xa066f3893b780833699043f824e5bb88b8df039886f524f62b9a1ac83cb7f1f0",
|
|
46
46
|
deprecated: true,
|
|
47
47
|
},
|
|
48
|
-
"rETH-USDC": {
|
|
49
|
-
collateralToken: "rETH",
|
|
50
|
-
loanToken: "USDC",
|
|
51
|
-
id: "0xdb0bc9f10a174f29a345c5f30a719933f71ccea7a2a75a632a281929bba1b535",
|
|
52
|
-
},
|
|
53
48
|
"cbBTC-USDC": {
|
|
54
49
|
collateralToken: "cbBTC",
|
|
55
50
|
loanToken: "USDC",
|
|
@@ -33,13 +33,13 @@ export const vaults = createVaultConfig({
|
|
|
33
33
|
vaultToken: "meUSDC",
|
|
34
34
|
campaignId:
|
|
35
35
|
"0x6738320fdf80785ff7a1d45ed93a6ffa07068ce9ec4170c1887d09f32fba7b57",
|
|
36
|
+
version: 2,
|
|
36
37
|
},
|
|
37
|
-
|
|
38
|
+
meUSDCv1: {
|
|
38
39
|
underlyingToken: "USDC",
|
|
39
|
-
vaultToken: "
|
|
40
|
+
vaultToken: "meUSDCv1",
|
|
40
41
|
campaignId:
|
|
41
42
|
"0x6738320fdf80785ff7a1d45ed93a6ffa07068ce9ec4170c1887d09f32fba7b57",
|
|
42
|
-
version: 2,
|
|
43
43
|
},
|
|
44
44
|
},
|
|
45
45
|
});
|
|
@@ -279,16 +279,16 @@ export const tokens = createTokenConfig({
|
|
|
279
279
|
symbol: "mcbXRP",
|
|
280
280
|
},
|
|
281
281
|
meUSDC: {
|
|
282
|
-
address: "
|
|
282
|
+
address: "0xbB2F06CeAE42CBcF5559Ed0713538c8892D977c9",
|
|
283
283
|
decimals: 18,
|
|
284
284
|
name: "Moonwell Ecosystem USDC Vault",
|
|
285
285
|
symbol: "meUSDC",
|
|
286
286
|
},
|
|
287
|
-
|
|
288
|
-
address: "
|
|
287
|
+
meUSDCv1: {
|
|
288
|
+
address: "0xe1ba476304255353aef290e6474a417d06e7b773",
|
|
289
289
|
decimals: 18,
|
|
290
|
-
name: "Moonwell Ecosystem USDC Vault
|
|
291
|
-
symbol: "
|
|
290
|
+
name: "Moonwell Ecosystem USDC Vault V1",
|
|
291
|
+
symbol: "meUSDCv1",
|
|
292
292
|
},
|
|
293
293
|
MAMO: {
|
|
294
294
|
address: "0x7300B37DfdfAb110d83290A29DfB31B1740219fE",
|
package/errors/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '0.9.
|
|
1
|
+
export const version = '0.9.23'
|