@defisaver/positions-sdk 2.1.160-dev → 2.1.160-morpho-vault-dev
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/cjs/savings/index.js +5 -2
- package/cjs/savings/morphoVaults/index.d.ts +1 -1
- package/cjs/savings/morphoVaults/index.js +56 -18
- package/cjs/savings/morphoVaults/options.d.ts +1 -0
- package/cjs/savings/morphoVaults/options.js +50 -1
- package/cjs/types/savings/morphoVaults.d.ts +9 -2
- package/cjs/types/savings/morphoVaults.js +8 -1
- package/esm/savings/index.js +5 -2
- package/esm/savings/morphoVaults/index.d.ts +1 -1
- package/esm/savings/morphoVaults/index.js +57 -19
- package/esm/savings/morphoVaults/options.d.ts +1 -0
- package/esm/savings/morphoVaults/options.js +50 -1
- package/esm/types/savings/morphoVaults.d.ts +9 -2
- package/esm/types/savings/morphoVaults.js +7 -0
- package/package.json +1 -1
- package/src/savings/index.ts +5 -2
- package/src/savings/morphoVaults/index.ts +73 -21
- package/src/savings/morphoVaults/options.ts +55 -1
- package/src/types/savings/morphoVaults.ts +10 -1
package/cjs/savings/index.js
CHANGED
|
@@ -60,7 +60,8 @@ exports.summerVaults = summerVaults;
|
|
|
60
60
|
const yearnV3Vaults = __importStar(require("./yearnV3Vaults"));
|
|
61
61
|
exports.yearnV3Vaults = yearnV3Vaults;
|
|
62
62
|
const getSavingsData = (provider, network, accounts) => __awaiter(void 0, void 0, void 0, function* () {
|
|
63
|
-
const morphoVaultsList = Object.keys(morphoVaults.morphoVaultsOptions.MORPHO_VAULTS)
|
|
63
|
+
const morphoVaultsList = Object.keys(morphoVaults.morphoVaultsOptions.MORPHO_VAULTS)
|
|
64
|
+
.filter((key) => morphoVaults.morphoVaultsOptions.getMorphoVault(key).network === network);
|
|
64
65
|
const yearnVaultsList = Object.keys(yearnVaults.yearnVaultsOptions.YEARN_VAULTS);
|
|
65
66
|
const sparkSavingsVaultsList = Object.keys(sparkSavingsVaults.sparkSavingsVaultsOptions.SPARK_SAVINGS_VAULTS);
|
|
66
67
|
const yearnV3VaultsList = Object.keys(yearnV3Vaults.yearnV3VaultsOptions.YEARN_V3_VAULTS);
|
|
@@ -68,7 +69,7 @@ const getSavingsData = (provider, network, accounts) => __awaiter(void 0, void 0
|
|
|
68
69
|
.filter((key) => summerVaults.summerVaultsOptions.getSummerVault(key).network === network);
|
|
69
70
|
const savingsData = {};
|
|
70
71
|
yield Promise.all([
|
|
71
|
-
...(
|
|
72
|
+
...(morphoVaultsList.length ? [
|
|
72
73
|
(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
73
74
|
try {
|
|
74
75
|
const vaults = morphoVaultsList.map((vaultKey) => morphoVaults.morphoVaultsOptions.getMorphoVault(vaultKey));
|
|
@@ -79,6 +80,8 @@ const getSavingsData = (provider, network, accounts) => __awaiter(void 0, void 0
|
|
|
79
80
|
console.error('[getSavingsData] Error fetching morpho vaults:', err);
|
|
80
81
|
}
|
|
81
82
|
}))(),
|
|
83
|
+
] : []),
|
|
84
|
+
...(network === common_1.NetworkNumber.Eth ? [
|
|
82
85
|
...yearnVaultsList.map((vaultKey) => __awaiter(void 0, void 0, void 0, function* () {
|
|
83
86
|
try {
|
|
84
87
|
const vault = yearnVaults.yearnVaultsOptions.getYearnVault(vaultKey);
|
|
@@ -3,7 +3,7 @@ import * as morphoVaultsOptions from './options';
|
|
|
3
3
|
import { EthAddress, EthereumProvider, NetworkNumber, MorphoVault, MorphoVaultType, SavingsVaultData } from '../../types';
|
|
4
4
|
export { morphoVaultsOptions, };
|
|
5
5
|
/**
|
|
6
|
-
* Fetches liquidity for all given vaults
|
|
6
|
+
* Fetches liquidity for all given vaults, one API request per vault version (chunked if over the page cap),
|
|
7
7
|
* returned as a map keyed by lowercased vault address. A vault missing from the API response is
|
|
8
8
|
* absent from the map.
|
|
9
9
|
*/
|
|
@@ -53,42 +53,50 @@ const graphql_request_1 = require("graphql-request");
|
|
|
53
53
|
const tokens_1 = require("@defisaver/tokens");
|
|
54
54
|
const morphoVaultsOptions = __importStar(require("./options"));
|
|
55
55
|
exports.morphoVaultsOptions = morphoVaultsOptions;
|
|
56
|
+
const types_1 = require("../../types");
|
|
56
57
|
const viem_1 = require("../../services/viem");
|
|
57
58
|
const contracts_1 = require("../../contracts");
|
|
58
59
|
const constants_1 = require("../../constants");
|
|
59
60
|
// Morpho API caps list page size at 100 items
|
|
60
61
|
const MORPHO_API_PAGE_SIZE = 100;
|
|
61
|
-
const
|
|
62
|
+
const buildLiquidityQuery = (listField) => `
|
|
62
63
|
query VaultsLiquidity($addresses: [String!], $chainIds: [Int!]) {
|
|
63
|
-
|
|
64
|
+
${listField}(first: ${MORPHO_API_PAGE_SIZE}, where: { address_in: $addresses, chainId_in: $chainIds }) {
|
|
64
65
|
items {
|
|
65
66
|
address
|
|
66
|
-
liquidity {
|
|
67
|
-
underlying
|
|
68
|
-
}
|
|
67
|
+
liquidity${listField === 'vaults' ? ' {\n underlying\n }' : ''}
|
|
69
68
|
}
|
|
70
69
|
}
|
|
71
70
|
}`;
|
|
71
|
+
const liquidityQueries = {
|
|
72
|
+
[types_1.MorphoVaultVersion.V1]: { field: 'vaults', query: buildLiquidityQuery('vaults') },
|
|
73
|
+
[types_1.MorphoVaultVersion.V2]: { field: 'vaultV2s', query: buildLiquidityQuery('vaultV2s') },
|
|
74
|
+
};
|
|
72
75
|
/**
|
|
73
|
-
* Fetches liquidity for all given vaults
|
|
76
|
+
* Fetches liquidity for all given vaults, one API request per vault version (chunked if over the page cap),
|
|
74
77
|
* returned as a map keyed by lowercased vault address. A vault missing from the API response is
|
|
75
78
|
* absent from the map.
|
|
76
79
|
*/
|
|
77
80
|
const fetchMorphoVaultsLiquidity = (network, vaults) => __awaiter(void 0, void 0, void 0, function* () {
|
|
78
|
-
const
|
|
79
|
-
|
|
80
|
-
|
|
81
|
+
const requests = [];
|
|
82
|
+
[types_1.MorphoVaultVersion.V1, types_1.MorphoVaultVersion.V2].forEach((version) => {
|
|
83
|
+
const versionVaults = vaults.filter((vault) => vault.version === version);
|
|
84
|
+
for (let i = 0; i < versionVaults.length; i += MORPHO_API_PAGE_SIZE)
|
|
85
|
+
requests.push({ version, chunk: versionVaults.slice(i, i + MORPHO_API_PAGE_SIZE) });
|
|
86
|
+
});
|
|
81
87
|
const liquidityByAddress = {};
|
|
82
|
-
yield Promise.all(
|
|
83
|
-
const
|
|
88
|
+
yield Promise.all(requests.map((_a) => __awaiter(void 0, [_a], void 0, function* ({ version, chunk }) {
|
|
89
|
+
const { field, query } = liquidityQueries[version];
|
|
90
|
+
const data = yield (0, graphql_request_1.request)(constants_1.MORPHO_API_URL, query, {
|
|
84
91
|
addresses: chunk.map((vault) => vault.address),
|
|
85
92
|
chainIds: [network],
|
|
86
93
|
// the BigInt scalar serializes as a JSON number when it fits in Number.MAX_SAFE_INTEGER, a string otherwise
|
|
87
94
|
});
|
|
88
|
-
(data.
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
95
|
+
(data[field].items || []).forEach((item) => {
|
|
96
|
+
// V1 exposes liquidity as { underlying }, V2 as a plain BigInt scalar
|
|
97
|
+
const underlying = (item === null || item === void 0 ? void 0 : item.liquidity) !== null && typeof (item === null || item === void 0 ? void 0 : item.liquidity) === 'object' ? item.liquidity.underlying : item === null || item === void 0 ? void 0 : item.liquidity;
|
|
98
|
+
if (underlying !== undefined && underlying !== null) {
|
|
99
|
+
liquidityByAddress[item.address.toLowerCase()] = String(underlying);
|
|
92
100
|
}
|
|
93
101
|
});
|
|
94
102
|
})));
|
|
@@ -102,7 +110,19 @@ const getBatchedViemProvider = (provider, network) => (0, viem_1.getViemProvider
|
|
|
102
110
|
},
|
|
103
111
|
},
|
|
104
112
|
});
|
|
105
|
-
|
|
113
|
+
// Vault V2 is ERC-4626 but has no decimals offset, so shares are converted with convertToAssets
|
|
114
|
+
const getMorphoVaultV2ChainData = (provider, morphoVault, accounts) => __awaiter(void 0, void 0, void 0, function* () {
|
|
115
|
+
const vaultContract = (0, contracts_1.getErc4626ContractViem)(provider, morphoVault.address);
|
|
116
|
+
const [totalAssets, suppliedAssets] = yield Promise.all([
|
|
117
|
+
vaultContract.read.totalAssets(),
|
|
118
|
+
Promise.all(accounts.map((account) => __awaiter(void 0, void 0, void 0, function* () {
|
|
119
|
+
const share = yield vaultContract.read.balanceOf([account]);
|
|
120
|
+
return share === BigInt(0) ? BigInt(0) : vaultContract.read.convertToAssets([share]);
|
|
121
|
+
}))),
|
|
122
|
+
]);
|
|
123
|
+
return { totalAssets, suppliedAssets };
|
|
124
|
+
});
|
|
125
|
+
const getMorphoVaultV1ChainData = (provider, morphoVault, accounts) => __awaiter(void 0, void 0, void 0, function* () {
|
|
106
126
|
const morphoVaultContract = (0, contracts_1.getMorphoVaultContractViem)(provider, morphoVault.address);
|
|
107
127
|
const shares = {};
|
|
108
128
|
const [totalAssets, totalSupply, decimals, decimalsOffset] = yield Promise.all([
|
|
@@ -119,11 +139,29 @@ const getMorphoVaultChainData = (provider, morphoVault, accounts) => __awaiter(v
|
|
|
119
139
|
totalAssets, totalSupply, decimals, decimalsOffset, shares,
|
|
120
140
|
};
|
|
121
141
|
});
|
|
142
|
+
const getMorphoVaultChainData = (provider, morphoVault, accounts) => __awaiter(void 0, void 0, void 0, function* () {
|
|
143
|
+
return (morphoVault.version === types_1.MorphoVaultVersion.V2
|
|
144
|
+
? { v2: yield getMorphoVaultV2ChainData(provider, morphoVault, accounts) }
|
|
145
|
+
: { v1: yield getMorphoVaultV1ChainData(provider, morphoVault, accounts) });
|
|
146
|
+
});
|
|
122
147
|
const formatMorphoVaultData = (morphoVault, chainData, liquidityUnderlying, accounts) => {
|
|
123
|
-
const { totalAssets, totalSupply, decimals, decimalsOffset, shares, } = chainData;
|
|
124
|
-
const poolSize = (0, tokens_1.assetAmountInEth)(totalAssets.toString(), morphoVault.asset);
|
|
125
148
|
const liquidity = (0, tokens_1.assetAmountInEth)(liquidityUnderlying, morphoVault.asset);
|
|
126
149
|
const supplied = {};
|
|
150
|
+
if (chainData.v2) {
|
|
151
|
+
const { totalAssets, suppliedAssets } = chainData.v2;
|
|
152
|
+
accounts.forEach((account, i) => {
|
|
153
|
+
supplied[account.toLowerCase()] = (0, tokens_1.assetAmountInEth)(suppliedAssets[i].toString(), morphoVault.asset);
|
|
154
|
+
});
|
|
155
|
+
return {
|
|
156
|
+
poolSize: (0, tokens_1.assetAmountInEth)(totalAssets.toString(), morphoVault.asset),
|
|
157
|
+
supplied,
|
|
158
|
+
liquidity,
|
|
159
|
+
asset: morphoVault.asset,
|
|
160
|
+
optionType: morphoVault.type,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
const { totalAssets, totalSupply, decimals, decimalsOffset, shares, } = chainData.v1;
|
|
164
|
+
const poolSize = (0, tokens_1.assetAmountInEth)(totalAssets.toString(), morphoVault.asset);
|
|
127
165
|
accounts.forEach((account) => {
|
|
128
166
|
const share = shares[account] || BigInt(0);
|
|
129
167
|
supplied[account.toLowerCase()] = new decimal_js_1.default(new decimal_js_1.default(share.toString()).mul(new decimal_js_1.default(totalAssets.toString()).add(1)).div(new decimal_js_1.default(totalSupply.toString()).add(Math.pow(10, decimalsOffset))).div(Math.pow(10, 18))
|
|
@@ -17,5 +17,6 @@ export declare const MORPHO_VAULT_STEAKHOUSE_PYUSD: MorphoVault;
|
|
|
17
17
|
export declare const MORPHO_VAULT_SMOKEHOUSE_USDT: MorphoVault;
|
|
18
18
|
export declare const MORPHO_VAULT_SMOKEHOUSE_USDC: MorphoVault;
|
|
19
19
|
export declare const MORPHO_VAULT_SMOKEHOUSE_DAI: MorphoVault;
|
|
20
|
+
export declare const MORPHO_VAULT_GAUNTLET_USDG_PREMIUM: MorphoVault;
|
|
20
21
|
export declare const MORPHO_VAULTS: Record<MorphoVaultType, MorphoVault>;
|
|
21
22
|
export declare const getMorphoVault: (type: MorphoVaultType) => MorphoVault;
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getMorphoVault = exports.MORPHO_VAULTS = exports.MORPHO_VAULT_SMOKEHOUSE_DAI = exports.MORPHO_VAULT_SMOKEHOUSE_USDC = exports.MORPHO_VAULT_SMOKEHOUSE_USDT = exports.MORPHO_VAULT_STEAKHOUSE_PYUSD = exports.MORPHO_VAULT_STEAKHOUSE_ETH = exports.MORPHO_VAULT_STEAKHOUSE_USDC = exports.MORPHO_VAULT_STEAKHOUSE_USDT = exports.MORPHO_VAULT_GAUNTLET_RESOLV_USDC = exports.MORPHO_VAULT_GAUNTLET_USDT_PRIME = exports.MORPHO_VAULT_GAUNTLET_USDA_CORE = exports.MORPHO_VAULT_FLAGSHIP_USDT = exports.MORPHO_VAULT_BOOSTED_USDC = exports.MORPHO_VAULT_GAUNTLET_WETH_PRIME = exports.MORPHO_VAULT_GAUNTLET_WETH_CORE = exports.MORPHO_VAULT_RE7_WETH = exports.MORPHO_VAULT_GAUNTLET_USDC_PRIME = exports.MORPHO_VAULT_GAUNTLET_USDC_CORE = exports.MORPHO_VAULT_FLAGSHIP_ETH = void 0;
|
|
3
|
+
exports.getMorphoVault = exports.MORPHO_VAULTS = exports.MORPHO_VAULT_GAUNTLET_USDG_PREMIUM = exports.MORPHO_VAULT_SMOKEHOUSE_DAI = exports.MORPHO_VAULT_SMOKEHOUSE_USDC = exports.MORPHO_VAULT_SMOKEHOUSE_USDT = exports.MORPHO_VAULT_STEAKHOUSE_PYUSD = exports.MORPHO_VAULT_STEAKHOUSE_ETH = exports.MORPHO_VAULT_STEAKHOUSE_USDC = exports.MORPHO_VAULT_STEAKHOUSE_USDT = exports.MORPHO_VAULT_GAUNTLET_RESOLV_USDC = exports.MORPHO_VAULT_GAUNTLET_USDT_PRIME = exports.MORPHO_VAULT_GAUNTLET_USDA_CORE = exports.MORPHO_VAULT_FLAGSHIP_USDT = exports.MORPHO_VAULT_BOOSTED_USDC = exports.MORPHO_VAULT_GAUNTLET_WETH_PRIME = exports.MORPHO_VAULT_GAUNTLET_WETH_CORE = exports.MORPHO_VAULT_RE7_WETH = exports.MORPHO_VAULT_GAUNTLET_USDC_PRIME = exports.MORPHO_VAULT_GAUNTLET_USDC_CORE = exports.MORPHO_VAULT_FLAGSHIP_ETH = void 0;
|
|
4
4
|
const types_1 = require("../../types");
|
|
5
5
|
exports.MORPHO_VAULT_FLAGSHIP_ETH = {
|
|
6
6
|
type: types_1.MorphoVaultType.MorphoVaultFlagshipEth,
|
|
7
7
|
name: 'Flagship ETH',
|
|
8
8
|
address: '0x38989BBA00BDF8181F4082995b3DEAe96163aC5D',
|
|
9
9
|
asset: 'WETH',
|
|
10
|
+
network: types_1.NetworkNumber.Eth,
|
|
11
|
+
version: types_1.MorphoVaultVersion.V1,
|
|
10
12
|
deploymentBlock: 18927491,
|
|
11
13
|
isLegacy: true,
|
|
12
14
|
};
|
|
@@ -15,6 +17,8 @@ exports.MORPHO_VAULT_GAUNTLET_USDC_CORE = {
|
|
|
15
17
|
name: 'Gauntlet USDC Core',
|
|
16
18
|
address: '0x8eB67A509616cd6A7c1B3c8C21D48FF57df3d458',
|
|
17
19
|
asset: 'USDC',
|
|
20
|
+
network: types_1.NetworkNumber.Eth,
|
|
21
|
+
version: types_1.MorphoVaultVersion.V1,
|
|
18
22
|
deploymentBlock: 19777569,
|
|
19
23
|
isLegacy: true,
|
|
20
24
|
};
|
|
@@ -23,6 +27,8 @@ exports.MORPHO_VAULT_GAUNTLET_USDC_PRIME = {
|
|
|
23
27
|
name: 'Gauntlet USDC Prime',
|
|
24
28
|
address: '0xdd0f28e19C1780eb6396170735D45153D261490d',
|
|
25
29
|
asset: 'USDC',
|
|
30
|
+
network: types_1.NetworkNumber.Eth,
|
|
31
|
+
version: types_1.MorphoVaultVersion.V1,
|
|
26
32
|
deploymentBlock: 19777569,
|
|
27
33
|
isLegacy: true,
|
|
28
34
|
};
|
|
@@ -31,6 +37,8 @@ exports.MORPHO_VAULT_RE7_WETH = {
|
|
|
31
37
|
name: 'RE7 WETH',
|
|
32
38
|
address: '0x78Fc2c2eD1A4cDb5402365934aE5648aDAd094d0',
|
|
33
39
|
asset: 'WETH',
|
|
40
|
+
network: types_1.NetworkNumber.Eth,
|
|
41
|
+
version: types_1.MorphoVaultVersion.V1,
|
|
34
42
|
deploymentBlock: 19121118,
|
|
35
43
|
isLegacy: true,
|
|
36
44
|
};
|
|
@@ -39,6 +47,8 @@ exports.MORPHO_VAULT_GAUNTLET_WETH_CORE = {
|
|
|
39
47
|
name: 'Gauntlet WETH Core',
|
|
40
48
|
address: '0x4881Ef0BF6d2365D3dd6499ccd7532bcdBCE0658',
|
|
41
49
|
asset: 'WETH',
|
|
50
|
+
network: types_1.NetworkNumber.Eth,
|
|
51
|
+
version: types_1.MorphoVaultVersion.V1,
|
|
42
52
|
deploymentBlock: 19541126,
|
|
43
53
|
isLegacy: true,
|
|
44
54
|
};
|
|
@@ -47,6 +57,8 @@ exports.MORPHO_VAULT_GAUNTLET_WETH_PRIME = {
|
|
|
47
57
|
name: 'Gauntlet WETH Prime',
|
|
48
58
|
address: '0x2371e134e3455e0593363cBF89d3b6cf53740618',
|
|
49
59
|
asset: 'WETH',
|
|
60
|
+
network: types_1.NetworkNumber.Eth,
|
|
61
|
+
version: types_1.MorphoVaultVersion.V1,
|
|
50
62
|
deploymentBlock: 19372149,
|
|
51
63
|
isLegacy: true,
|
|
52
64
|
};
|
|
@@ -55,6 +67,8 @@ exports.MORPHO_VAULT_BOOSTED_USDC = {
|
|
|
55
67
|
name: 'Boosted USDC',
|
|
56
68
|
address: '0xd63070114470f685b75B74D60EEc7c1113d33a3D',
|
|
57
69
|
asset: 'USDC',
|
|
70
|
+
network: types_1.NetworkNumber.Eth,
|
|
71
|
+
version: types_1.MorphoVaultVersion.V1,
|
|
58
72
|
deploymentBlock: 20377233,
|
|
59
73
|
isLegacy: true,
|
|
60
74
|
};
|
|
@@ -63,6 +77,8 @@ exports.MORPHO_VAULT_FLAGSHIP_USDT = {
|
|
|
63
77
|
name: 'Flagship USDT',
|
|
64
78
|
address: '0x2C25f6C25770fFEC5959D34B94Bf898865e5D6b1',
|
|
65
79
|
asset: 'USDT',
|
|
80
|
+
network: types_1.NetworkNumber.Eth,
|
|
81
|
+
version: types_1.MorphoVaultVersion.V1,
|
|
66
82
|
deploymentBlock: 19127039,
|
|
67
83
|
isLegacy: true,
|
|
68
84
|
};
|
|
@@ -71,6 +87,8 @@ exports.MORPHO_VAULT_GAUNTLET_USDA_CORE = {
|
|
|
71
87
|
name: 'Gauntlet USDA Core',
|
|
72
88
|
address: '0x125D41A6e5dbf455cD9Df8F80BCC6fd172D52Cc6',
|
|
73
89
|
asset: 'USDA',
|
|
90
|
+
network: types_1.NetworkNumber.Eth,
|
|
91
|
+
version: types_1.MorphoVaultVersion.V1,
|
|
74
92
|
deploymentBlock: 19633608,
|
|
75
93
|
isLegacy: true,
|
|
76
94
|
};
|
|
@@ -79,6 +97,8 @@ exports.MORPHO_VAULT_GAUNTLET_USDT_PRIME = {
|
|
|
79
97
|
name: 'Gauntlet USDT Prime',
|
|
80
98
|
address: '0x8CB3649114051cA5119141a34C200D65dc0Faa73',
|
|
81
99
|
asset: 'USDT',
|
|
100
|
+
network: types_1.NetworkNumber.Eth,
|
|
101
|
+
version: types_1.MorphoVaultVersion.V1,
|
|
82
102
|
deploymentBlock: 19486541,
|
|
83
103
|
isLegacy: true,
|
|
84
104
|
};
|
|
@@ -87,6 +107,8 @@ exports.MORPHO_VAULT_GAUNTLET_RESOLV_USDC = {
|
|
|
87
107
|
name: 'Gauntlet Resolv USDC',
|
|
88
108
|
address: '0x132E6C9C33A62D7727cd359b1f51e5B566E485Eb',
|
|
89
109
|
asset: 'USDC',
|
|
110
|
+
network: types_1.NetworkNumber.Eth,
|
|
111
|
+
version: types_1.MorphoVaultVersion.V1,
|
|
90
112
|
deploymentBlock: 21487882,
|
|
91
113
|
isLegacy: true,
|
|
92
114
|
};
|
|
@@ -96,6 +118,8 @@ exports.MORPHO_VAULT_STEAKHOUSE_USDT = {
|
|
|
96
118
|
name: 'Steakhouse USDT',
|
|
97
119
|
address: '0xbEef047a543E45807105E51A8BBEFCc5950fcfBa',
|
|
98
120
|
asset: 'USDT',
|
|
121
|
+
network: types_1.NetworkNumber.Eth,
|
|
122
|
+
version: types_1.MorphoVaultVersion.V1,
|
|
99
123
|
deploymentBlock: 19043398,
|
|
100
124
|
isLegacy: false,
|
|
101
125
|
};
|
|
@@ -104,6 +128,8 @@ exports.MORPHO_VAULT_STEAKHOUSE_USDC = {
|
|
|
104
128
|
name: 'Steakhouse USDC',
|
|
105
129
|
address: '0xBEEF01735c132Ada46AA9aA4c54623cAA92A64CB',
|
|
106
130
|
asset: 'USDC',
|
|
131
|
+
network: types_1.NetworkNumber.Eth,
|
|
132
|
+
version: types_1.MorphoVaultVersion.V1,
|
|
107
133
|
deploymentBlock: 18928285,
|
|
108
134
|
isLegacy: false,
|
|
109
135
|
};
|
|
@@ -112,6 +138,8 @@ exports.MORPHO_VAULT_STEAKHOUSE_ETH = {
|
|
|
112
138
|
name: 'Steakhouse WETH',
|
|
113
139
|
address: '0xBEEf050ecd6a16c4e7bfFbB52Ebba7846C4b8cD4',
|
|
114
140
|
asset: 'WETH',
|
|
141
|
+
network: types_1.NetworkNumber.Eth,
|
|
142
|
+
version: types_1.MorphoVaultVersion.V1,
|
|
115
143
|
deploymentBlock: 19380443,
|
|
116
144
|
isLegacy: false,
|
|
117
145
|
};
|
|
@@ -120,6 +148,8 @@ exports.MORPHO_VAULT_STEAKHOUSE_PYUSD = {
|
|
|
120
148
|
name: 'Steakhouse PYUSD',
|
|
121
149
|
address: '0xbEEF02e5E13584ab96848af90261f0C8Ee04722a',
|
|
122
150
|
asset: 'PYUSD',
|
|
151
|
+
network: types_1.NetworkNumber.Eth,
|
|
152
|
+
version: types_1.MorphoVaultVersion.V1,
|
|
123
153
|
deploymentBlock: 19043398,
|
|
124
154
|
isLegacy: false,
|
|
125
155
|
};
|
|
@@ -129,6 +159,8 @@ exports.MORPHO_VAULT_SMOKEHOUSE_USDT = {
|
|
|
129
159
|
name: 'Smokehouse USDT',
|
|
130
160
|
address: '0xA0804346780b4c2e3bE118ac957D1DB82F9d7484',
|
|
131
161
|
asset: 'USDT',
|
|
162
|
+
network: types_1.NetworkNumber.Eth,
|
|
163
|
+
version: types_1.MorphoVaultVersion.V1,
|
|
132
164
|
deploymentBlock: 21522238,
|
|
133
165
|
isLegacy: false,
|
|
134
166
|
};
|
|
@@ -137,6 +169,8 @@ exports.MORPHO_VAULT_SMOKEHOUSE_USDC = {
|
|
|
137
169
|
name: 'Smokehouse USDC',
|
|
138
170
|
address: '0xBEeFFF209270748ddd194831b3fa287a5386f5bC',
|
|
139
171
|
asset: 'USDC',
|
|
172
|
+
network: types_1.NetworkNumber.Eth,
|
|
173
|
+
version: types_1.MorphoVaultVersion.V1,
|
|
140
174
|
deploymentBlock: 21337719,
|
|
141
175
|
isLegacy: false,
|
|
142
176
|
};
|
|
@@ -145,9 +179,22 @@ exports.MORPHO_VAULT_SMOKEHOUSE_DAI = {
|
|
|
145
179
|
name: 'Smokehouse DAI',
|
|
146
180
|
address: '0xbeeFfF68CC520D68f82641EFF84330C631E2490E',
|
|
147
181
|
asset: 'DAI',
|
|
182
|
+
network: types_1.NetworkNumber.Eth,
|
|
183
|
+
version: types_1.MorphoVaultVersion.V1,
|
|
148
184
|
deploymentBlock: 21343808,
|
|
149
185
|
isLegacy: false,
|
|
150
186
|
};
|
|
187
|
+
// Vault V2
|
|
188
|
+
exports.MORPHO_VAULT_GAUNTLET_USDG_PREMIUM = {
|
|
189
|
+
type: types_1.MorphoVaultType.MorphoVaultGauntletUSDGPremium,
|
|
190
|
+
name: 'Gauntlet USDG Premium',
|
|
191
|
+
address: '0x390c1bb01F3F627144a40617e287d4cE3D5aBCfa',
|
|
192
|
+
asset: 'USDG',
|
|
193
|
+
network: types_1.NetworkNumber.Arb,
|
|
194
|
+
version: types_1.MorphoVaultVersion.V2,
|
|
195
|
+
deploymentBlock: 510799903,
|
|
196
|
+
isLegacy: false,
|
|
197
|
+
};
|
|
151
198
|
exports.MORPHO_VAULTS = {
|
|
152
199
|
[types_1.MorphoVaultType.MorphoVaultFlagshipEth]: exports.MORPHO_VAULT_FLAGSHIP_ETH,
|
|
153
200
|
[types_1.MorphoVaultType.MorphoVaultGauntletUSDCCore]: exports.MORPHO_VAULT_GAUNTLET_USDC_CORE,
|
|
@@ -169,6 +216,8 @@ exports.MORPHO_VAULTS = {
|
|
|
169
216
|
[types_1.MorphoVaultType.MorphoVaultSmokehouseUSDT]: exports.MORPHO_VAULT_SMOKEHOUSE_USDT,
|
|
170
217
|
[types_1.MorphoVaultType.MorphoVaultSmokehouseUSDC]: exports.MORPHO_VAULT_SMOKEHOUSE_USDC,
|
|
171
218
|
[types_1.MorphoVaultType.MorphoVaultSmokehouseDAI]: exports.MORPHO_VAULT_SMOKEHOUSE_DAI,
|
|
219
|
+
// Vault V2
|
|
220
|
+
[types_1.MorphoVaultType.MorphoVaultGauntletUSDGPremium]: exports.MORPHO_VAULT_GAUNTLET_USDG_PREMIUM,
|
|
172
221
|
};
|
|
173
222
|
const getMorphoVault = (type) => exports.MORPHO_VAULTS[type];
|
|
174
223
|
exports.getMorphoVault = getMorphoVault;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EthAddress } from '../common';
|
|
1
|
+
import { EthAddress, NetworkNumber } from '../common';
|
|
2
2
|
export declare enum MorphoVaultType {
|
|
3
3
|
MorphoVaultFlagshipEth = "morpho_vault_flagship_eth",
|
|
4
4
|
MorphoVaultGauntletUSDCCore = "morpho_vault_gauntlet_usdc_core",
|
|
@@ -17,13 +17,20 @@ export declare enum MorphoVaultType {
|
|
|
17
17
|
MorphoVaultSteakhousePYUSD = "morpho_vault_steakhouse_pyusd",
|
|
18
18
|
MorphoVaultSmokehouseUSDT = "morpho_vault_smokehouse_usdt",
|
|
19
19
|
MorphoVaultSmokehouseUSDC = "morpho_vault_smokehouse_usdc",
|
|
20
|
-
MorphoVaultSmokehouseDAI = "morpho_vault_smokehouse_dai"
|
|
20
|
+
MorphoVaultSmokehouseDAI = "morpho_vault_smokehouse_dai",
|
|
21
|
+
MorphoVaultGauntletUSDGPremium = "morpho_vault_gauntlet_usdg_premium"
|
|
22
|
+
}
|
|
23
|
+
export declare enum MorphoVaultVersion {
|
|
24
|
+
V1 = 1,
|
|
25
|
+
V2 = 2
|
|
21
26
|
}
|
|
22
27
|
export interface MorphoVault {
|
|
23
28
|
type: MorphoVaultType;
|
|
24
29
|
name: string;
|
|
25
30
|
address: EthAddress;
|
|
26
31
|
asset: string;
|
|
32
|
+
network: NetworkNumber;
|
|
33
|
+
version: MorphoVaultVersion;
|
|
27
34
|
deploymentBlock: number;
|
|
28
35
|
isLegacy: boolean;
|
|
29
36
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MorphoVaultType = void 0;
|
|
3
|
+
exports.MorphoVaultVersion = exports.MorphoVaultType = void 0;
|
|
4
4
|
var MorphoVaultType;
|
|
5
5
|
(function (MorphoVaultType) {
|
|
6
6
|
MorphoVaultType["MorphoVaultFlagshipEth"] = "morpho_vault_flagship_eth";
|
|
@@ -23,4 +23,11 @@ var MorphoVaultType;
|
|
|
23
23
|
MorphoVaultType["MorphoVaultSmokehouseUSDT"] = "morpho_vault_smokehouse_usdt";
|
|
24
24
|
MorphoVaultType["MorphoVaultSmokehouseUSDC"] = "morpho_vault_smokehouse_usdc";
|
|
25
25
|
MorphoVaultType["MorphoVaultSmokehouseDAI"] = "morpho_vault_smokehouse_dai";
|
|
26
|
+
// Vault V2
|
|
27
|
+
MorphoVaultType["MorphoVaultGauntletUSDGPremium"] = "morpho_vault_gauntlet_usdg_premium";
|
|
26
28
|
})(MorphoVaultType || (exports.MorphoVaultType = MorphoVaultType = {}));
|
|
29
|
+
var MorphoVaultVersion;
|
|
30
|
+
(function (MorphoVaultVersion) {
|
|
31
|
+
MorphoVaultVersion[MorphoVaultVersion["V1"] = 1] = "V1";
|
|
32
|
+
MorphoVaultVersion[MorphoVaultVersion["V2"] = 2] = "V2";
|
|
33
|
+
})(MorphoVaultVersion || (exports.MorphoVaultVersion = MorphoVaultVersion = {}));
|
package/esm/savings/index.js
CHANGED
|
@@ -18,7 +18,8 @@ import * as summerVaults from './summerVaults';
|
|
|
18
18
|
import * as yearnV3Vaults from './yearnV3Vaults';
|
|
19
19
|
export { morphoVaults, yearnVaults, makerDsr, skyOptions, sparkSavingsVaults, summerVaults, yearnV3Vaults, };
|
|
20
20
|
export const getSavingsData = (provider, network, accounts) => __awaiter(void 0, void 0, void 0, function* () {
|
|
21
|
-
const morphoVaultsList = Object.keys(morphoVaults.morphoVaultsOptions.MORPHO_VAULTS)
|
|
21
|
+
const morphoVaultsList = Object.keys(morphoVaults.morphoVaultsOptions.MORPHO_VAULTS)
|
|
22
|
+
.filter((key) => morphoVaults.morphoVaultsOptions.getMorphoVault(key).network === network);
|
|
22
23
|
const yearnVaultsList = Object.keys(yearnVaults.yearnVaultsOptions.YEARN_VAULTS);
|
|
23
24
|
const sparkSavingsVaultsList = Object.keys(sparkSavingsVaults.sparkSavingsVaultsOptions.SPARK_SAVINGS_VAULTS);
|
|
24
25
|
const yearnV3VaultsList = Object.keys(yearnV3Vaults.yearnV3VaultsOptions.YEARN_V3_VAULTS);
|
|
@@ -26,7 +27,7 @@ export const getSavingsData = (provider, network, accounts) => __awaiter(void 0,
|
|
|
26
27
|
.filter((key) => summerVaults.summerVaultsOptions.getSummerVault(key).network === network);
|
|
27
28
|
const savingsData = {};
|
|
28
29
|
yield Promise.all([
|
|
29
|
-
...(
|
|
30
|
+
...(morphoVaultsList.length ? [
|
|
30
31
|
(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
31
32
|
try {
|
|
32
33
|
const vaults = morphoVaultsList.map((vaultKey) => morphoVaults.morphoVaultsOptions.getMorphoVault(vaultKey));
|
|
@@ -37,6 +38,8 @@ export const getSavingsData = (provider, network, accounts) => __awaiter(void 0,
|
|
|
37
38
|
console.error('[getSavingsData] Error fetching morpho vaults:', err);
|
|
38
39
|
}
|
|
39
40
|
}))(),
|
|
41
|
+
] : []),
|
|
42
|
+
...(network === NetworkNumber.Eth ? [
|
|
40
43
|
...yearnVaultsList.map((vaultKey) => __awaiter(void 0, void 0, void 0, function* () {
|
|
41
44
|
try {
|
|
42
45
|
const vault = yearnVaults.yearnVaultsOptions.getYearnVault(vaultKey);
|
|
@@ -3,7 +3,7 @@ import * as morphoVaultsOptions from './options';
|
|
|
3
3
|
import { EthAddress, EthereumProvider, NetworkNumber, MorphoVault, MorphoVaultType, SavingsVaultData } from '../../types';
|
|
4
4
|
export { morphoVaultsOptions, };
|
|
5
5
|
/**
|
|
6
|
-
* Fetches liquidity for all given vaults
|
|
6
|
+
* Fetches liquidity for all given vaults, one API request per vault version (chunked if over the page cap),
|
|
7
7
|
* returned as a map keyed by lowercased vault address. A vault missing from the API response is
|
|
8
8
|
* absent from the map.
|
|
9
9
|
*/
|
|
@@ -11,43 +11,51 @@ import Dec from 'decimal.js';
|
|
|
11
11
|
import { request as graphqlRequest } from 'graphql-request';
|
|
12
12
|
import { assetAmountInEth } from '@defisaver/tokens';
|
|
13
13
|
import * as morphoVaultsOptions from './options';
|
|
14
|
+
import { MorphoVaultVersion, } from '../../types';
|
|
14
15
|
import { getViemProvider } from '../../services/viem';
|
|
15
|
-
import { getMorphoVaultContractViem } from '../../contracts';
|
|
16
|
+
import { getErc4626ContractViem, getMorphoVaultContractViem } from '../../contracts';
|
|
16
17
|
import { MORPHO_API_URL } from '../../constants';
|
|
17
18
|
export { morphoVaultsOptions, };
|
|
18
19
|
// Morpho API caps list page size at 100 items
|
|
19
20
|
const MORPHO_API_PAGE_SIZE = 100;
|
|
20
|
-
const
|
|
21
|
+
const buildLiquidityQuery = (listField) => `
|
|
21
22
|
query VaultsLiquidity($addresses: [String!], $chainIds: [Int!]) {
|
|
22
|
-
|
|
23
|
+
${listField}(first: ${MORPHO_API_PAGE_SIZE}, where: { address_in: $addresses, chainId_in: $chainIds }) {
|
|
23
24
|
items {
|
|
24
25
|
address
|
|
25
|
-
liquidity {
|
|
26
|
-
underlying
|
|
27
|
-
}
|
|
26
|
+
liquidity${listField === 'vaults' ? ' {\n underlying\n }' : ''}
|
|
28
27
|
}
|
|
29
28
|
}
|
|
30
29
|
}`;
|
|
30
|
+
const liquidityQueries = {
|
|
31
|
+
[MorphoVaultVersion.V1]: { field: 'vaults', query: buildLiquidityQuery('vaults') },
|
|
32
|
+
[MorphoVaultVersion.V2]: { field: 'vaultV2s', query: buildLiquidityQuery('vaultV2s') },
|
|
33
|
+
};
|
|
31
34
|
/**
|
|
32
|
-
* Fetches liquidity for all given vaults
|
|
35
|
+
* Fetches liquidity for all given vaults, one API request per vault version (chunked if over the page cap),
|
|
33
36
|
* returned as a map keyed by lowercased vault address. A vault missing from the API response is
|
|
34
37
|
* absent from the map.
|
|
35
38
|
*/
|
|
36
39
|
export const fetchMorphoVaultsLiquidity = (network, vaults) => __awaiter(void 0, void 0, void 0, function* () {
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
40
|
+
const requests = [];
|
|
41
|
+
[MorphoVaultVersion.V1, MorphoVaultVersion.V2].forEach((version) => {
|
|
42
|
+
const versionVaults = vaults.filter((vault) => vault.version === version);
|
|
43
|
+
for (let i = 0; i < versionVaults.length; i += MORPHO_API_PAGE_SIZE)
|
|
44
|
+
requests.push({ version, chunk: versionVaults.slice(i, i + MORPHO_API_PAGE_SIZE) });
|
|
45
|
+
});
|
|
40
46
|
const liquidityByAddress = {};
|
|
41
|
-
yield Promise.all(
|
|
42
|
-
const
|
|
47
|
+
yield Promise.all(requests.map((_a) => __awaiter(void 0, [_a], void 0, function* ({ version, chunk }) {
|
|
48
|
+
const { field, query } = liquidityQueries[version];
|
|
49
|
+
const data = yield graphqlRequest(MORPHO_API_URL, query, {
|
|
43
50
|
addresses: chunk.map((vault) => vault.address),
|
|
44
51
|
chainIds: [network],
|
|
45
52
|
// the BigInt scalar serializes as a JSON number when it fits in Number.MAX_SAFE_INTEGER, a string otherwise
|
|
46
53
|
});
|
|
47
|
-
(data.
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
54
|
+
(data[field].items || []).forEach((item) => {
|
|
55
|
+
// V1 exposes liquidity as { underlying }, V2 as a plain BigInt scalar
|
|
56
|
+
const underlying = (item === null || item === void 0 ? void 0 : item.liquidity) !== null && typeof (item === null || item === void 0 ? void 0 : item.liquidity) === 'object' ? item.liquidity.underlying : item === null || item === void 0 ? void 0 : item.liquidity;
|
|
57
|
+
if (underlying !== undefined && underlying !== null) {
|
|
58
|
+
liquidityByAddress[item.address.toLowerCase()] = String(underlying);
|
|
51
59
|
}
|
|
52
60
|
});
|
|
53
61
|
})));
|
|
@@ -60,7 +68,19 @@ const getBatchedViemProvider = (provider, network) => getViemProvider(provider,
|
|
|
60
68
|
},
|
|
61
69
|
},
|
|
62
70
|
});
|
|
63
|
-
|
|
71
|
+
// Vault V2 is ERC-4626 but has no decimals offset, so shares are converted with convertToAssets
|
|
72
|
+
const getMorphoVaultV2ChainData = (provider, morphoVault, accounts) => __awaiter(void 0, void 0, void 0, function* () {
|
|
73
|
+
const vaultContract = getErc4626ContractViem(provider, morphoVault.address);
|
|
74
|
+
const [totalAssets, suppliedAssets] = yield Promise.all([
|
|
75
|
+
vaultContract.read.totalAssets(),
|
|
76
|
+
Promise.all(accounts.map((account) => __awaiter(void 0, void 0, void 0, function* () {
|
|
77
|
+
const share = yield vaultContract.read.balanceOf([account]);
|
|
78
|
+
return share === BigInt(0) ? BigInt(0) : vaultContract.read.convertToAssets([share]);
|
|
79
|
+
}))),
|
|
80
|
+
]);
|
|
81
|
+
return { totalAssets, suppliedAssets };
|
|
82
|
+
});
|
|
83
|
+
const getMorphoVaultV1ChainData = (provider, morphoVault, accounts) => __awaiter(void 0, void 0, void 0, function* () {
|
|
64
84
|
const morphoVaultContract = getMorphoVaultContractViem(provider, morphoVault.address);
|
|
65
85
|
const shares = {};
|
|
66
86
|
const [totalAssets, totalSupply, decimals, decimalsOffset] = yield Promise.all([
|
|
@@ -77,11 +97,29 @@ const getMorphoVaultChainData = (provider, morphoVault, accounts) => __awaiter(v
|
|
|
77
97
|
totalAssets, totalSupply, decimals, decimalsOffset, shares,
|
|
78
98
|
};
|
|
79
99
|
});
|
|
100
|
+
const getMorphoVaultChainData = (provider, morphoVault, accounts) => __awaiter(void 0, void 0, void 0, function* () {
|
|
101
|
+
return (morphoVault.version === MorphoVaultVersion.V2
|
|
102
|
+
? { v2: yield getMorphoVaultV2ChainData(provider, morphoVault, accounts) }
|
|
103
|
+
: { v1: yield getMorphoVaultV1ChainData(provider, morphoVault, accounts) });
|
|
104
|
+
});
|
|
80
105
|
const formatMorphoVaultData = (morphoVault, chainData, liquidityUnderlying, accounts) => {
|
|
81
|
-
const { totalAssets, totalSupply, decimals, decimalsOffset, shares, } = chainData;
|
|
82
|
-
const poolSize = assetAmountInEth(totalAssets.toString(), morphoVault.asset);
|
|
83
106
|
const liquidity = assetAmountInEth(liquidityUnderlying, morphoVault.asset);
|
|
84
107
|
const supplied = {};
|
|
108
|
+
if (chainData.v2) {
|
|
109
|
+
const { totalAssets, suppliedAssets } = chainData.v2;
|
|
110
|
+
accounts.forEach((account, i) => {
|
|
111
|
+
supplied[account.toLowerCase()] = assetAmountInEth(suppliedAssets[i].toString(), morphoVault.asset);
|
|
112
|
+
});
|
|
113
|
+
return {
|
|
114
|
+
poolSize: assetAmountInEth(totalAssets.toString(), morphoVault.asset),
|
|
115
|
+
supplied,
|
|
116
|
+
liquidity,
|
|
117
|
+
asset: morphoVault.asset,
|
|
118
|
+
optionType: morphoVault.type,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
const { totalAssets, totalSupply, decimals, decimalsOffset, shares, } = chainData.v1;
|
|
122
|
+
const poolSize = assetAmountInEth(totalAssets.toString(), morphoVault.asset);
|
|
85
123
|
accounts.forEach((account) => {
|
|
86
124
|
const share = shares[account] || BigInt(0);
|
|
87
125
|
supplied[account.toLowerCase()] = new Dec(new Dec(share.toString()).mul(new Dec(totalAssets.toString()).add(1)).div(new Dec(totalSupply.toString()).add(Math.pow(10, decimalsOffset))).div(Math.pow(10, 18))
|
|
@@ -17,5 +17,6 @@ export declare const MORPHO_VAULT_STEAKHOUSE_PYUSD: MorphoVault;
|
|
|
17
17
|
export declare const MORPHO_VAULT_SMOKEHOUSE_USDT: MorphoVault;
|
|
18
18
|
export declare const MORPHO_VAULT_SMOKEHOUSE_USDC: MorphoVault;
|
|
19
19
|
export declare const MORPHO_VAULT_SMOKEHOUSE_DAI: MorphoVault;
|
|
20
|
+
export declare const MORPHO_VAULT_GAUNTLET_USDG_PREMIUM: MorphoVault;
|
|
20
21
|
export declare const MORPHO_VAULTS: Record<MorphoVaultType, MorphoVault>;
|
|
21
22
|
export declare const getMorphoVault: (type: MorphoVaultType) => MorphoVault;
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import { MorphoVaultType } from '../../types';
|
|
1
|
+
import { MorphoVaultType, MorphoVaultVersion, NetworkNumber, } from '../../types';
|
|
2
2
|
export const MORPHO_VAULT_FLAGSHIP_ETH = {
|
|
3
3
|
type: MorphoVaultType.MorphoVaultFlagshipEth,
|
|
4
4
|
name: 'Flagship ETH',
|
|
5
5
|
address: '0x38989BBA00BDF8181F4082995b3DEAe96163aC5D',
|
|
6
6
|
asset: 'WETH',
|
|
7
|
+
network: NetworkNumber.Eth,
|
|
8
|
+
version: MorphoVaultVersion.V1,
|
|
7
9
|
deploymentBlock: 18927491,
|
|
8
10
|
isLegacy: true,
|
|
9
11
|
};
|
|
@@ -12,6 +14,8 @@ export const MORPHO_VAULT_GAUNTLET_USDC_CORE = {
|
|
|
12
14
|
name: 'Gauntlet USDC Core',
|
|
13
15
|
address: '0x8eB67A509616cd6A7c1B3c8C21D48FF57df3d458',
|
|
14
16
|
asset: 'USDC',
|
|
17
|
+
network: NetworkNumber.Eth,
|
|
18
|
+
version: MorphoVaultVersion.V1,
|
|
15
19
|
deploymentBlock: 19777569,
|
|
16
20
|
isLegacy: true,
|
|
17
21
|
};
|
|
@@ -20,6 +24,8 @@ export const MORPHO_VAULT_GAUNTLET_USDC_PRIME = {
|
|
|
20
24
|
name: 'Gauntlet USDC Prime',
|
|
21
25
|
address: '0xdd0f28e19C1780eb6396170735D45153D261490d',
|
|
22
26
|
asset: 'USDC',
|
|
27
|
+
network: NetworkNumber.Eth,
|
|
28
|
+
version: MorphoVaultVersion.V1,
|
|
23
29
|
deploymentBlock: 19777569,
|
|
24
30
|
isLegacy: true,
|
|
25
31
|
};
|
|
@@ -28,6 +34,8 @@ export const MORPHO_VAULT_RE7_WETH = {
|
|
|
28
34
|
name: 'RE7 WETH',
|
|
29
35
|
address: '0x78Fc2c2eD1A4cDb5402365934aE5648aDAd094d0',
|
|
30
36
|
asset: 'WETH',
|
|
37
|
+
network: NetworkNumber.Eth,
|
|
38
|
+
version: MorphoVaultVersion.V1,
|
|
31
39
|
deploymentBlock: 19121118,
|
|
32
40
|
isLegacy: true,
|
|
33
41
|
};
|
|
@@ -36,6 +44,8 @@ export const MORPHO_VAULT_GAUNTLET_WETH_CORE = {
|
|
|
36
44
|
name: 'Gauntlet WETH Core',
|
|
37
45
|
address: '0x4881Ef0BF6d2365D3dd6499ccd7532bcdBCE0658',
|
|
38
46
|
asset: 'WETH',
|
|
47
|
+
network: NetworkNumber.Eth,
|
|
48
|
+
version: MorphoVaultVersion.V1,
|
|
39
49
|
deploymentBlock: 19541126,
|
|
40
50
|
isLegacy: true,
|
|
41
51
|
};
|
|
@@ -44,6 +54,8 @@ export const MORPHO_VAULT_GAUNTLET_WETH_PRIME = {
|
|
|
44
54
|
name: 'Gauntlet WETH Prime',
|
|
45
55
|
address: '0x2371e134e3455e0593363cBF89d3b6cf53740618',
|
|
46
56
|
asset: 'WETH',
|
|
57
|
+
network: NetworkNumber.Eth,
|
|
58
|
+
version: MorphoVaultVersion.V1,
|
|
47
59
|
deploymentBlock: 19372149,
|
|
48
60
|
isLegacy: true,
|
|
49
61
|
};
|
|
@@ -52,6 +64,8 @@ export const MORPHO_VAULT_BOOSTED_USDC = {
|
|
|
52
64
|
name: 'Boosted USDC',
|
|
53
65
|
address: '0xd63070114470f685b75B74D60EEc7c1113d33a3D',
|
|
54
66
|
asset: 'USDC',
|
|
67
|
+
network: NetworkNumber.Eth,
|
|
68
|
+
version: MorphoVaultVersion.V1,
|
|
55
69
|
deploymentBlock: 20377233,
|
|
56
70
|
isLegacy: true,
|
|
57
71
|
};
|
|
@@ -60,6 +74,8 @@ export const MORPHO_VAULT_FLAGSHIP_USDT = {
|
|
|
60
74
|
name: 'Flagship USDT',
|
|
61
75
|
address: '0x2C25f6C25770fFEC5959D34B94Bf898865e5D6b1',
|
|
62
76
|
asset: 'USDT',
|
|
77
|
+
network: NetworkNumber.Eth,
|
|
78
|
+
version: MorphoVaultVersion.V1,
|
|
63
79
|
deploymentBlock: 19127039,
|
|
64
80
|
isLegacy: true,
|
|
65
81
|
};
|
|
@@ -68,6 +84,8 @@ export const MORPHO_VAULT_GAUNTLET_USDA_CORE = {
|
|
|
68
84
|
name: 'Gauntlet USDA Core',
|
|
69
85
|
address: '0x125D41A6e5dbf455cD9Df8F80BCC6fd172D52Cc6',
|
|
70
86
|
asset: 'USDA',
|
|
87
|
+
network: NetworkNumber.Eth,
|
|
88
|
+
version: MorphoVaultVersion.V1,
|
|
71
89
|
deploymentBlock: 19633608,
|
|
72
90
|
isLegacy: true,
|
|
73
91
|
};
|
|
@@ -76,6 +94,8 @@ export const MORPHO_VAULT_GAUNTLET_USDT_PRIME = {
|
|
|
76
94
|
name: 'Gauntlet USDT Prime',
|
|
77
95
|
address: '0x8CB3649114051cA5119141a34C200D65dc0Faa73',
|
|
78
96
|
asset: 'USDT',
|
|
97
|
+
network: NetworkNumber.Eth,
|
|
98
|
+
version: MorphoVaultVersion.V1,
|
|
79
99
|
deploymentBlock: 19486541,
|
|
80
100
|
isLegacy: true,
|
|
81
101
|
};
|
|
@@ -84,6 +104,8 @@ export const MORPHO_VAULT_GAUNTLET_RESOLV_USDC = {
|
|
|
84
104
|
name: 'Gauntlet Resolv USDC',
|
|
85
105
|
address: '0x132E6C9C33A62D7727cd359b1f51e5B566E485Eb',
|
|
86
106
|
asset: 'USDC',
|
|
107
|
+
network: NetworkNumber.Eth,
|
|
108
|
+
version: MorphoVaultVersion.V1,
|
|
87
109
|
deploymentBlock: 21487882,
|
|
88
110
|
isLegacy: true,
|
|
89
111
|
};
|
|
@@ -93,6 +115,8 @@ export const MORPHO_VAULT_STEAKHOUSE_USDT = {
|
|
|
93
115
|
name: 'Steakhouse USDT',
|
|
94
116
|
address: '0xbEef047a543E45807105E51A8BBEFCc5950fcfBa',
|
|
95
117
|
asset: 'USDT',
|
|
118
|
+
network: NetworkNumber.Eth,
|
|
119
|
+
version: MorphoVaultVersion.V1,
|
|
96
120
|
deploymentBlock: 19043398,
|
|
97
121
|
isLegacy: false,
|
|
98
122
|
};
|
|
@@ -101,6 +125,8 @@ export const MORPHO_VAULT_STEAKHOUSE_USDC = {
|
|
|
101
125
|
name: 'Steakhouse USDC',
|
|
102
126
|
address: '0xBEEF01735c132Ada46AA9aA4c54623cAA92A64CB',
|
|
103
127
|
asset: 'USDC',
|
|
128
|
+
network: NetworkNumber.Eth,
|
|
129
|
+
version: MorphoVaultVersion.V1,
|
|
104
130
|
deploymentBlock: 18928285,
|
|
105
131
|
isLegacy: false,
|
|
106
132
|
};
|
|
@@ -109,6 +135,8 @@ export const MORPHO_VAULT_STEAKHOUSE_ETH = {
|
|
|
109
135
|
name: 'Steakhouse WETH',
|
|
110
136
|
address: '0xBEEf050ecd6a16c4e7bfFbB52Ebba7846C4b8cD4',
|
|
111
137
|
asset: 'WETH',
|
|
138
|
+
network: NetworkNumber.Eth,
|
|
139
|
+
version: MorphoVaultVersion.V1,
|
|
112
140
|
deploymentBlock: 19380443,
|
|
113
141
|
isLegacy: false,
|
|
114
142
|
};
|
|
@@ -117,6 +145,8 @@ export const MORPHO_VAULT_STEAKHOUSE_PYUSD = {
|
|
|
117
145
|
name: 'Steakhouse PYUSD',
|
|
118
146
|
address: '0xbEEF02e5E13584ab96848af90261f0C8Ee04722a',
|
|
119
147
|
asset: 'PYUSD',
|
|
148
|
+
network: NetworkNumber.Eth,
|
|
149
|
+
version: MorphoVaultVersion.V1,
|
|
120
150
|
deploymentBlock: 19043398,
|
|
121
151
|
isLegacy: false,
|
|
122
152
|
};
|
|
@@ -126,6 +156,8 @@ export const MORPHO_VAULT_SMOKEHOUSE_USDT = {
|
|
|
126
156
|
name: 'Smokehouse USDT',
|
|
127
157
|
address: '0xA0804346780b4c2e3bE118ac957D1DB82F9d7484',
|
|
128
158
|
asset: 'USDT',
|
|
159
|
+
network: NetworkNumber.Eth,
|
|
160
|
+
version: MorphoVaultVersion.V1,
|
|
129
161
|
deploymentBlock: 21522238,
|
|
130
162
|
isLegacy: false,
|
|
131
163
|
};
|
|
@@ -134,6 +166,8 @@ export const MORPHO_VAULT_SMOKEHOUSE_USDC = {
|
|
|
134
166
|
name: 'Smokehouse USDC',
|
|
135
167
|
address: '0xBEeFFF209270748ddd194831b3fa287a5386f5bC',
|
|
136
168
|
asset: 'USDC',
|
|
169
|
+
network: NetworkNumber.Eth,
|
|
170
|
+
version: MorphoVaultVersion.V1,
|
|
137
171
|
deploymentBlock: 21337719,
|
|
138
172
|
isLegacy: false,
|
|
139
173
|
};
|
|
@@ -142,9 +176,22 @@ export const MORPHO_VAULT_SMOKEHOUSE_DAI = {
|
|
|
142
176
|
name: 'Smokehouse DAI',
|
|
143
177
|
address: '0xbeeFfF68CC520D68f82641EFF84330C631E2490E',
|
|
144
178
|
asset: 'DAI',
|
|
179
|
+
network: NetworkNumber.Eth,
|
|
180
|
+
version: MorphoVaultVersion.V1,
|
|
145
181
|
deploymentBlock: 21343808,
|
|
146
182
|
isLegacy: false,
|
|
147
183
|
};
|
|
184
|
+
// Vault V2
|
|
185
|
+
export const MORPHO_VAULT_GAUNTLET_USDG_PREMIUM = {
|
|
186
|
+
type: MorphoVaultType.MorphoVaultGauntletUSDGPremium,
|
|
187
|
+
name: 'Gauntlet USDG Premium',
|
|
188
|
+
address: '0x390c1bb01F3F627144a40617e287d4cE3D5aBCfa',
|
|
189
|
+
asset: 'USDG',
|
|
190
|
+
network: NetworkNumber.Arb,
|
|
191
|
+
version: MorphoVaultVersion.V2,
|
|
192
|
+
deploymentBlock: 510799903,
|
|
193
|
+
isLegacy: false,
|
|
194
|
+
};
|
|
148
195
|
export const MORPHO_VAULTS = {
|
|
149
196
|
[MorphoVaultType.MorphoVaultFlagshipEth]: MORPHO_VAULT_FLAGSHIP_ETH,
|
|
150
197
|
[MorphoVaultType.MorphoVaultGauntletUSDCCore]: MORPHO_VAULT_GAUNTLET_USDC_CORE,
|
|
@@ -166,5 +213,7 @@ export const MORPHO_VAULTS = {
|
|
|
166
213
|
[MorphoVaultType.MorphoVaultSmokehouseUSDT]: MORPHO_VAULT_SMOKEHOUSE_USDT,
|
|
167
214
|
[MorphoVaultType.MorphoVaultSmokehouseUSDC]: MORPHO_VAULT_SMOKEHOUSE_USDC,
|
|
168
215
|
[MorphoVaultType.MorphoVaultSmokehouseDAI]: MORPHO_VAULT_SMOKEHOUSE_DAI,
|
|
216
|
+
// Vault V2
|
|
217
|
+
[MorphoVaultType.MorphoVaultGauntletUSDGPremium]: MORPHO_VAULT_GAUNTLET_USDG_PREMIUM,
|
|
169
218
|
};
|
|
170
219
|
export const getMorphoVault = (type) => MORPHO_VAULTS[type];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EthAddress } from '../common';
|
|
1
|
+
import { EthAddress, NetworkNumber } from '../common';
|
|
2
2
|
export declare enum MorphoVaultType {
|
|
3
3
|
MorphoVaultFlagshipEth = "morpho_vault_flagship_eth",
|
|
4
4
|
MorphoVaultGauntletUSDCCore = "morpho_vault_gauntlet_usdc_core",
|
|
@@ -17,13 +17,20 @@ export declare enum MorphoVaultType {
|
|
|
17
17
|
MorphoVaultSteakhousePYUSD = "morpho_vault_steakhouse_pyusd",
|
|
18
18
|
MorphoVaultSmokehouseUSDT = "morpho_vault_smokehouse_usdt",
|
|
19
19
|
MorphoVaultSmokehouseUSDC = "morpho_vault_smokehouse_usdc",
|
|
20
|
-
MorphoVaultSmokehouseDAI = "morpho_vault_smokehouse_dai"
|
|
20
|
+
MorphoVaultSmokehouseDAI = "morpho_vault_smokehouse_dai",
|
|
21
|
+
MorphoVaultGauntletUSDGPremium = "morpho_vault_gauntlet_usdg_premium"
|
|
22
|
+
}
|
|
23
|
+
export declare enum MorphoVaultVersion {
|
|
24
|
+
V1 = 1,
|
|
25
|
+
V2 = 2
|
|
21
26
|
}
|
|
22
27
|
export interface MorphoVault {
|
|
23
28
|
type: MorphoVaultType;
|
|
24
29
|
name: string;
|
|
25
30
|
address: EthAddress;
|
|
26
31
|
asset: string;
|
|
32
|
+
network: NetworkNumber;
|
|
33
|
+
version: MorphoVaultVersion;
|
|
27
34
|
deploymentBlock: number;
|
|
28
35
|
isLegacy: boolean;
|
|
29
36
|
}
|
|
@@ -20,4 +20,11 @@ export var MorphoVaultType;
|
|
|
20
20
|
MorphoVaultType["MorphoVaultSmokehouseUSDT"] = "morpho_vault_smokehouse_usdt";
|
|
21
21
|
MorphoVaultType["MorphoVaultSmokehouseUSDC"] = "morpho_vault_smokehouse_usdc";
|
|
22
22
|
MorphoVaultType["MorphoVaultSmokehouseDAI"] = "morpho_vault_smokehouse_dai";
|
|
23
|
+
// Vault V2
|
|
24
|
+
MorphoVaultType["MorphoVaultGauntletUSDGPremium"] = "morpho_vault_gauntlet_usdg_premium";
|
|
23
25
|
})(MorphoVaultType || (MorphoVaultType = {}));
|
|
26
|
+
export var MorphoVaultVersion;
|
|
27
|
+
(function (MorphoVaultVersion) {
|
|
28
|
+
MorphoVaultVersion[MorphoVaultVersion["V1"] = 1] = "V1";
|
|
29
|
+
MorphoVaultVersion[MorphoVaultVersion["V2"] = 2] = "V2";
|
|
30
|
+
})(MorphoVaultVersion || (MorphoVaultVersion = {}));
|
package/package.json
CHANGED
package/src/savings/index.ts
CHANGED
|
@@ -32,7 +32,8 @@ export const getSavingsData = async (
|
|
|
32
32
|
network: NetworkNumber,
|
|
33
33
|
accounts: EthAddress[],
|
|
34
34
|
) => {
|
|
35
|
-
const morphoVaultsList = Object.keys(morphoVaults.morphoVaultsOptions.MORPHO_VAULTS) as MorphoVaultType[]
|
|
35
|
+
const morphoVaultsList = (Object.keys(morphoVaults.morphoVaultsOptions.MORPHO_VAULTS) as MorphoVaultType[])
|
|
36
|
+
.filter((key) => morphoVaults.morphoVaultsOptions.getMorphoVault(key).network === network);
|
|
36
37
|
const yearnVaultsList = Object.keys(yearnVaults.yearnVaultsOptions.YEARN_VAULTS) as YearnVaultType[];
|
|
37
38
|
const sparkSavingsVaultsList = Object.keys(sparkSavingsVaults.sparkSavingsVaultsOptions.SPARK_SAVINGS_VAULTS) as SparkSavingsVaultType[];
|
|
38
39
|
const yearnV3VaultsList = Object.keys(yearnV3Vaults.yearnV3VaultsOptions.YEARN_V3_VAULTS) as YearnV3VaultType[];
|
|
@@ -42,7 +43,7 @@ export const getSavingsData = async (
|
|
|
42
43
|
const savingsData: SavingsData = {};
|
|
43
44
|
|
|
44
45
|
await Promise.all([
|
|
45
|
-
...(
|
|
46
|
+
...(morphoVaultsList.length ? [
|
|
46
47
|
(async () => {
|
|
47
48
|
try {
|
|
48
49
|
const vaults = morphoVaultsList.map((vaultKey) => morphoVaults.morphoVaultsOptions.getMorphoVault(vaultKey));
|
|
@@ -52,6 +53,8 @@ export const getSavingsData = async (
|
|
|
52
53
|
console.error('[getSavingsData] Error fetching morpho vaults:', err);
|
|
53
54
|
}
|
|
54
55
|
})(),
|
|
56
|
+
] : []),
|
|
57
|
+
...(network === NetworkNumber.Eth ? [
|
|
55
58
|
...yearnVaultsList.map(async (vaultKey) => {
|
|
56
59
|
try {
|
|
57
60
|
const vault = yearnVaults.yearnVaultsOptions.getYearnVault(vaultKey);
|
|
@@ -4,10 +4,10 @@ import { request as graphqlRequest } from 'graphql-request';
|
|
|
4
4
|
import { assetAmountInEth } from '@defisaver/tokens';
|
|
5
5
|
import * as morphoVaultsOptions from './options';
|
|
6
6
|
import {
|
|
7
|
-
EthAddress, EthereumProvider, NetworkNumber, MorphoVault, MorphoVaultType, SavingsVaultData,
|
|
7
|
+
EthAddress, EthereumProvider, NetworkNumber, MorphoVault, MorphoVaultType, MorphoVaultVersion, SavingsVaultData,
|
|
8
8
|
} from '../../types';
|
|
9
9
|
import { getViemProvider } from '../../services/viem';
|
|
10
|
-
import { getMorphoVaultContractViem } from '../../contracts';
|
|
10
|
+
import { getErc4626ContractViem, getMorphoVaultContractViem } from '../../contracts';
|
|
11
11
|
import { MORPHO_API_URL } from '../../constants';
|
|
12
12
|
|
|
13
13
|
export {
|
|
@@ -17,38 +17,49 @@ export {
|
|
|
17
17
|
// Morpho API caps list page size at 100 items
|
|
18
18
|
const MORPHO_API_PAGE_SIZE = 100;
|
|
19
19
|
|
|
20
|
-
const
|
|
20
|
+
const buildLiquidityQuery = (listField: 'vaults' | 'vaultV2s') => `
|
|
21
21
|
query VaultsLiquidity($addresses: [String!], $chainIds: [Int!]) {
|
|
22
|
-
|
|
22
|
+
${listField}(first: ${MORPHO_API_PAGE_SIZE}, where: { address_in: $addresses, chainId_in: $chainIds }) {
|
|
23
23
|
items {
|
|
24
24
|
address
|
|
25
|
-
liquidity {
|
|
26
|
-
underlying
|
|
27
|
-
}
|
|
25
|
+
liquidity${listField === 'vaults' ? ' {\n underlying\n }' : ''}
|
|
28
26
|
}
|
|
29
27
|
}
|
|
30
28
|
}`;
|
|
31
29
|
|
|
30
|
+
const liquidityQueries = {
|
|
31
|
+
[MorphoVaultVersion.V1]: { field: 'vaults', query: buildLiquidityQuery('vaults') },
|
|
32
|
+
[MorphoVaultVersion.V2]: { field: 'vaultV2s', query: buildLiquidityQuery('vaultV2s') },
|
|
33
|
+
} as const;
|
|
34
|
+
|
|
35
|
+
type LiquidityItem = { address: string, liquidity: { underlying: string | number | null } | string | number | null };
|
|
36
|
+
|
|
32
37
|
/**
|
|
33
|
-
* Fetches liquidity for all given vaults
|
|
38
|
+
* Fetches liquidity for all given vaults, one API request per vault version (chunked if over the page cap),
|
|
34
39
|
* returned as a map keyed by lowercased vault address. A vault missing from the API response is
|
|
35
40
|
* absent from the map.
|
|
36
41
|
*/
|
|
37
42
|
export const fetchMorphoVaultsLiquidity = async (network: NetworkNumber, vaults: MorphoVault[]): Promise<Record<string, string>> => {
|
|
38
|
-
const
|
|
39
|
-
|
|
43
|
+
const requests: { version: MorphoVaultVersion, chunk: MorphoVault[] }[] = [];
|
|
44
|
+
[MorphoVaultVersion.V1, MorphoVaultVersion.V2].forEach((version) => {
|
|
45
|
+
const versionVaults = vaults.filter((vault) => vault.version === version);
|
|
46
|
+
for (let i = 0; i < versionVaults.length; i += MORPHO_API_PAGE_SIZE) requests.push({ version, chunk: versionVaults.slice(i, i + MORPHO_API_PAGE_SIZE) });
|
|
47
|
+
});
|
|
40
48
|
|
|
41
49
|
const liquidityByAddress: Record<string, string> = {};
|
|
42
|
-
await Promise.all(
|
|
43
|
-
const
|
|
50
|
+
await Promise.all(requests.map(async ({ version, chunk }) => {
|
|
51
|
+
const { field, query } = liquidityQueries[version];
|
|
52
|
+
const data = await graphqlRequest(MORPHO_API_URL, query, {
|
|
44
53
|
addresses: chunk.map((vault) => vault.address),
|
|
45
54
|
chainIds: [network],
|
|
46
55
|
// the BigInt scalar serializes as a JSON number when it fits in Number.MAX_SAFE_INTEGER, a string otherwise
|
|
47
|
-
}) as
|
|
56
|
+
}) as Record<string, { items: LiquidityItem[] | null }>;
|
|
48
57
|
|
|
49
|
-
(data.
|
|
50
|
-
|
|
51
|
-
|
|
58
|
+
(data[field].items || []).forEach((item) => {
|
|
59
|
+
// V1 exposes liquidity as { underlying }, V2 as a plain BigInt scalar
|
|
60
|
+
const underlying = item?.liquidity !== null && typeof item?.liquidity === 'object' ? item.liquidity.underlying : item?.liquidity;
|
|
61
|
+
if (underlying !== undefined && underlying !== null) {
|
|
62
|
+
liquidityByAddress[item.address.toLowerCase()] = String(underlying);
|
|
52
63
|
}
|
|
53
64
|
});
|
|
54
65
|
}));
|
|
@@ -63,7 +74,22 @@ const getBatchedViemProvider = (provider: EthereumProvider, network: NetworkNumb
|
|
|
63
74
|
},
|
|
64
75
|
});
|
|
65
76
|
|
|
66
|
-
|
|
77
|
+
// Vault V2 is ERC-4626 but has no decimals offset, so shares are converted with convertToAssets
|
|
78
|
+
const getMorphoVaultV2ChainData = async (provider: Client, morphoVault: MorphoVault, accounts: EthAddress[]) => {
|
|
79
|
+
const vaultContract = getErc4626ContractViem(provider, morphoVault.address);
|
|
80
|
+
|
|
81
|
+
const [totalAssets, suppliedAssets] = await Promise.all([
|
|
82
|
+
vaultContract.read.totalAssets(),
|
|
83
|
+
Promise.all(accounts.map(async (account) => {
|
|
84
|
+
const share = await vaultContract.read.balanceOf([account]);
|
|
85
|
+
return share === BigInt(0) ? BigInt(0) : vaultContract.read.convertToAssets([share]);
|
|
86
|
+
})),
|
|
87
|
+
]);
|
|
88
|
+
|
|
89
|
+
return { totalAssets, suppliedAssets };
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
const getMorphoVaultV1ChainData = async (provider: Client, morphoVault: MorphoVault, accounts: EthAddress[]) => {
|
|
67
93
|
const morphoVaultContract = getMorphoVaultContractViem(provider, morphoVault.address);
|
|
68
94
|
|
|
69
95
|
const shares: Record<EthAddress, bigint> = {};
|
|
@@ -84,20 +110,46 @@ const getMorphoVaultChainData = async (provider: Client, morphoVault: MorphoVaul
|
|
|
84
110
|
};
|
|
85
111
|
};
|
|
86
112
|
|
|
113
|
+
type MorphoVaultChainData = {
|
|
114
|
+
v1?: Awaited<ReturnType<typeof getMorphoVaultV1ChainData>>,
|
|
115
|
+
v2?: Awaited<ReturnType<typeof getMorphoVaultV2ChainData>>,
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
const getMorphoVaultChainData = async (provider: Client, morphoVault: MorphoVault, accounts: EthAddress[]): Promise<MorphoVaultChainData> => (
|
|
119
|
+
morphoVault.version === MorphoVaultVersion.V2
|
|
120
|
+
? { v2: await getMorphoVaultV2ChainData(provider, morphoVault, accounts) }
|
|
121
|
+
: { v1: await getMorphoVaultV1ChainData(provider, morphoVault, accounts) }
|
|
122
|
+
);
|
|
123
|
+
|
|
87
124
|
const formatMorphoVaultData = (
|
|
88
125
|
morphoVault: MorphoVault,
|
|
89
|
-
chainData:
|
|
126
|
+
chainData: MorphoVaultChainData,
|
|
90
127
|
liquidityUnderlying: string,
|
|
91
128
|
accounts: EthAddress[],
|
|
92
129
|
): SavingsVaultData => {
|
|
130
|
+
const liquidity = assetAmountInEth(liquidityUnderlying, morphoVault.asset);
|
|
131
|
+
const supplied: Record<EthAddress, string> = {};
|
|
132
|
+
|
|
133
|
+
if (chainData.v2) {
|
|
134
|
+
const { totalAssets, suppliedAssets } = chainData.v2;
|
|
135
|
+
accounts.forEach((account, i) => {
|
|
136
|
+
supplied[account.toLowerCase() as EthAddress] = assetAmountInEth(suppliedAssets[i].toString(), morphoVault.asset);
|
|
137
|
+
});
|
|
138
|
+
return {
|
|
139
|
+
poolSize: assetAmountInEth(totalAssets.toString(), morphoVault.asset),
|
|
140
|
+
supplied,
|
|
141
|
+
liquidity,
|
|
142
|
+
asset: morphoVault.asset,
|
|
143
|
+
optionType: morphoVault.type,
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
|
|
93
147
|
const {
|
|
94
148
|
totalAssets, totalSupply, decimals, decimalsOffset, shares,
|
|
95
|
-
} = chainData
|
|
149
|
+
} = chainData.v1!;
|
|
96
150
|
|
|
97
151
|
const poolSize = assetAmountInEth(totalAssets.toString(), morphoVault.asset);
|
|
98
|
-
const liquidity = assetAmountInEth(liquidityUnderlying, morphoVault.asset);
|
|
99
152
|
|
|
100
|
-
const supplied: Record<EthAddress, string> = {};
|
|
101
153
|
accounts.forEach((account) => {
|
|
102
154
|
const share = shares[account] || BigInt(0);
|
|
103
155
|
supplied[account.toLowerCase() as EthAddress] = new Dec(new Dec(share.toString()).mul(new Dec(totalAssets.toString()).add(1)).div(new Dec(totalSupply.toString()).add(10 ** decimalsOffset)).div(10 ** 18)
|
|
@@ -1,10 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
MorphoVault, MorphoVaultType, MorphoVaultVersion, NetworkNumber,
|
|
3
|
+
} from '../../types';
|
|
2
4
|
|
|
3
5
|
export const MORPHO_VAULT_FLAGSHIP_ETH: MorphoVault = {
|
|
4
6
|
type: MorphoVaultType.MorphoVaultFlagshipEth,
|
|
5
7
|
name: 'Flagship ETH',
|
|
6
8
|
address: '0x38989BBA00BDF8181F4082995b3DEAe96163aC5D',
|
|
7
9
|
asset: 'WETH',
|
|
10
|
+
network: NetworkNumber.Eth,
|
|
11
|
+
version: MorphoVaultVersion.V1,
|
|
8
12
|
deploymentBlock: 18927491,
|
|
9
13
|
isLegacy: true,
|
|
10
14
|
};
|
|
@@ -14,6 +18,8 @@ export const MORPHO_VAULT_GAUNTLET_USDC_CORE: MorphoVault = {
|
|
|
14
18
|
name: 'Gauntlet USDC Core',
|
|
15
19
|
address: '0x8eB67A509616cd6A7c1B3c8C21D48FF57df3d458',
|
|
16
20
|
asset: 'USDC',
|
|
21
|
+
network: NetworkNumber.Eth,
|
|
22
|
+
version: MorphoVaultVersion.V1,
|
|
17
23
|
deploymentBlock: 19777569,
|
|
18
24
|
isLegacy: true,
|
|
19
25
|
};
|
|
@@ -23,6 +29,8 @@ export const MORPHO_VAULT_GAUNTLET_USDC_PRIME: MorphoVault = {
|
|
|
23
29
|
name: 'Gauntlet USDC Prime',
|
|
24
30
|
address: '0xdd0f28e19C1780eb6396170735D45153D261490d',
|
|
25
31
|
asset: 'USDC',
|
|
32
|
+
network: NetworkNumber.Eth,
|
|
33
|
+
version: MorphoVaultVersion.V1,
|
|
26
34
|
deploymentBlock: 19777569,
|
|
27
35
|
isLegacy: true,
|
|
28
36
|
};
|
|
@@ -32,6 +40,8 @@ export const MORPHO_VAULT_RE7_WETH: MorphoVault = {
|
|
|
32
40
|
name: 'RE7 WETH',
|
|
33
41
|
address: '0x78Fc2c2eD1A4cDb5402365934aE5648aDAd094d0',
|
|
34
42
|
asset: 'WETH',
|
|
43
|
+
network: NetworkNumber.Eth,
|
|
44
|
+
version: MorphoVaultVersion.V1,
|
|
35
45
|
deploymentBlock: 19121118,
|
|
36
46
|
isLegacy: true,
|
|
37
47
|
};
|
|
@@ -41,6 +51,8 @@ export const MORPHO_VAULT_GAUNTLET_WETH_CORE: MorphoVault = {
|
|
|
41
51
|
name: 'Gauntlet WETH Core',
|
|
42
52
|
address: '0x4881Ef0BF6d2365D3dd6499ccd7532bcdBCE0658',
|
|
43
53
|
asset: 'WETH',
|
|
54
|
+
network: NetworkNumber.Eth,
|
|
55
|
+
version: MorphoVaultVersion.V1,
|
|
44
56
|
deploymentBlock: 19541126,
|
|
45
57
|
isLegacy: true,
|
|
46
58
|
};
|
|
@@ -50,6 +62,8 @@ export const MORPHO_VAULT_GAUNTLET_WETH_PRIME: MorphoVault = {
|
|
|
50
62
|
name: 'Gauntlet WETH Prime',
|
|
51
63
|
address: '0x2371e134e3455e0593363cBF89d3b6cf53740618',
|
|
52
64
|
asset: 'WETH',
|
|
65
|
+
network: NetworkNumber.Eth,
|
|
66
|
+
version: MorphoVaultVersion.V1,
|
|
53
67
|
deploymentBlock: 19372149,
|
|
54
68
|
isLegacy: true,
|
|
55
69
|
};
|
|
@@ -59,6 +73,8 @@ export const MORPHO_VAULT_BOOSTED_USDC: MorphoVault = {
|
|
|
59
73
|
name: 'Boosted USDC',
|
|
60
74
|
address: '0xd63070114470f685b75B74D60EEc7c1113d33a3D',
|
|
61
75
|
asset: 'USDC',
|
|
76
|
+
network: NetworkNumber.Eth,
|
|
77
|
+
version: MorphoVaultVersion.V1,
|
|
62
78
|
deploymentBlock: 20377233,
|
|
63
79
|
isLegacy: true,
|
|
64
80
|
};
|
|
@@ -68,6 +84,8 @@ export const MORPHO_VAULT_FLAGSHIP_USDT: MorphoVault = {
|
|
|
68
84
|
name: 'Flagship USDT',
|
|
69
85
|
address: '0x2C25f6C25770fFEC5959D34B94Bf898865e5D6b1',
|
|
70
86
|
asset: 'USDT',
|
|
87
|
+
network: NetworkNumber.Eth,
|
|
88
|
+
version: MorphoVaultVersion.V1,
|
|
71
89
|
deploymentBlock: 19127039,
|
|
72
90
|
isLegacy: true,
|
|
73
91
|
};
|
|
@@ -77,6 +95,8 @@ export const MORPHO_VAULT_GAUNTLET_USDA_CORE: MorphoVault = {
|
|
|
77
95
|
name: 'Gauntlet USDA Core',
|
|
78
96
|
address: '0x125D41A6e5dbf455cD9Df8F80BCC6fd172D52Cc6',
|
|
79
97
|
asset: 'USDA',
|
|
98
|
+
network: NetworkNumber.Eth,
|
|
99
|
+
version: MorphoVaultVersion.V1,
|
|
80
100
|
deploymentBlock: 19633608,
|
|
81
101
|
isLegacy: true,
|
|
82
102
|
};
|
|
@@ -86,6 +106,8 @@ export const MORPHO_VAULT_GAUNTLET_USDT_PRIME: MorphoVault = {
|
|
|
86
106
|
name: 'Gauntlet USDT Prime',
|
|
87
107
|
address: '0x8CB3649114051cA5119141a34C200D65dc0Faa73',
|
|
88
108
|
asset: 'USDT',
|
|
109
|
+
network: NetworkNumber.Eth,
|
|
110
|
+
version: MorphoVaultVersion.V1,
|
|
89
111
|
deploymentBlock: 19486541,
|
|
90
112
|
isLegacy: true,
|
|
91
113
|
};
|
|
@@ -95,6 +117,8 @@ export const MORPHO_VAULT_GAUNTLET_RESOLV_USDC: MorphoVault = {
|
|
|
95
117
|
name: 'Gauntlet Resolv USDC',
|
|
96
118
|
address: '0x132E6C9C33A62D7727cd359b1f51e5B566E485Eb',
|
|
97
119
|
asset: 'USDC',
|
|
120
|
+
network: NetworkNumber.Eth,
|
|
121
|
+
version: MorphoVaultVersion.V1,
|
|
98
122
|
deploymentBlock: 21487882,
|
|
99
123
|
isLegacy: true,
|
|
100
124
|
};
|
|
@@ -106,6 +130,8 @@ export const MORPHO_VAULT_STEAKHOUSE_USDT: MorphoVault = {
|
|
|
106
130
|
name: 'Steakhouse USDT',
|
|
107
131
|
address: '0xbEef047a543E45807105E51A8BBEFCc5950fcfBa',
|
|
108
132
|
asset: 'USDT',
|
|
133
|
+
network: NetworkNumber.Eth,
|
|
134
|
+
version: MorphoVaultVersion.V1,
|
|
109
135
|
deploymentBlock: 19043398,
|
|
110
136
|
isLegacy: false,
|
|
111
137
|
};
|
|
@@ -115,6 +141,8 @@ export const MORPHO_VAULT_STEAKHOUSE_USDC: MorphoVault = {
|
|
|
115
141
|
name: 'Steakhouse USDC',
|
|
116
142
|
address: '0xBEEF01735c132Ada46AA9aA4c54623cAA92A64CB',
|
|
117
143
|
asset: 'USDC',
|
|
144
|
+
network: NetworkNumber.Eth,
|
|
145
|
+
version: MorphoVaultVersion.V1,
|
|
118
146
|
deploymentBlock: 18928285,
|
|
119
147
|
isLegacy: false,
|
|
120
148
|
};
|
|
@@ -124,6 +152,8 @@ export const MORPHO_VAULT_STEAKHOUSE_ETH: MorphoVault = {
|
|
|
124
152
|
name: 'Steakhouse WETH',
|
|
125
153
|
address: '0xBEEf050ecd6a16c4e7bfFbB52Ebba7846C4b8cD4',
|
|
126
154
|
asset: 'WETH',
|
|
155
|
+
network: NetworkNumber.Eth,
|
|
156
|
+
version: MorphoVaultVersion.V1,
|
|
127
157
|
deploymentBlock: 19380443,
|
|
128
158
|
isLegacy: false,
|
|
129
159
|
};
|
|
@@ -133,6 +163,8 @@ export const MORPHO_VAULT_STEAKHOUSE_PYUSD: MorphoVault = {
|
|
|
133
163
|
name: 'Steakhouse PYUSD',
|
|
134
164
|
address: '0xbEEF02e5E13584ab96848af90261f0C8Ee04722a',
|
|
135
165
|
asset: 'PYUSD',
|
|
166
|
+
network: NetworkNumber.Eth,
|
|
167
|
+
version: MorphoVaultVersion.V1,
|
|
136
168
|
deploymentBlock: 19043398,
|
|
137
169
|
isLegacy: false,
|
|
138
170
|
};
|
|
@@ -144,6 +176,8 @@ export const MORPHO_VAULT_SMOKEHOUSE_USDT: MorphoVault = {
|
|
|
144
176
|
name: 'Smokehouse USDT',
|
|
145
177
|
address: '0xA0804346780b4c2e3bE118ac957D1DB82F9d7484',
|
|
146
178
|
asset: 'USDT',
|
|
179
|
+
network: NetworkNumber.Eth,
|
|
180
|
+
version: MorphoVaultVersion.V1,
|
|
147
181
|
deploymentBlock: 21522238,
|
|
148
182
|
isLegacy: false,
|
|
149
183
|
};
|
|
@@ -153,6 +187,8 @@ export const MORPHO_VAULT_SMOKEHOUSE_USDC: MorphoVault = {
|
|
|
153
187
|
name: 'Smokehouse USDC',
|
|
154
188
|
address: '0xBEeFFF209270748ddd194831b3fa287a5386f5bC',
|
|
155
189
|
asset: 'USDC',
|
|
190
|
+
network: NetworkNumber.Eth,
|
|
191
|
+
version: MorphoVaultVersion.V1,
|
|
156
192
|
deploymentBlock: 21337719,
|
|
157
193
|
isLegacy: false,
|
|
158
194
|
};
|
|
@@ -162,10 +198,25 @@ export const MORPHO_VAULT_SMOKEHOUSE_DAI: MorphoVault = {
|
|
|
162
198
|
name: 'Smokehouse DAI',
|
|
163
199
|
address: '0xbeeFfF68CC520D68f82641EFF84330C631E2490E',
|
|
164
200
|
asset: 'DAI',
|
|
201
|
+
network: NetworkNumber.Eth,
|
|
202
|
+
version: MorphoVaultVersion.V1,
|
|
165
203
|
deploymentBlock: 21343808,
|
|
166
204
|
isLegacy: false,
|
|
167
205
|
};
|
|
168
206
|
|
|
207
|
+
// Vault V2
|
|
208
|
+
|
|
209
|
+
export const MORPHO_VAULT_GAUNTLET_USDG_PREMIUM: MorphoVault = {
|
|
210
|
+
type: MorphoVaultType.MorphoVaultGauntletUSDGPremium,
|
|
211
|
+
name: 'Gauntlet USDG Premium',
|
|
212
|
+
address: '0x390c1bb01F3F627144a40617e287d4cE3D5aBCfa',
|
|
213
|
+
asset: 'USDG',
|
|
214
|
+
network: NetworkNumber.Arb,
|
|
215
|
+
version: MorphoVaultVersion.V2,
|
|
216
|
+
deploymentBlock: 510799903,
|
|
217
|
+
isLegacy: false,
|
|
218
|
+
};
|
|
219
|
+
|
|
169
220
|
export const MORPHO_VAULTS: Record<MorphoVaultType, MorphoVault> = {
|
|
170
221
|
[MorphoVaultType.MorphoVaultFlagshipEth]: MORPHO_VAULT_FLAGSHIP_ETH,
|
|
171
222
|
[MorphoVaultType.MorphoVaultGauntletUSDCCore]: MORPHO_VAULT_GAUNTLET_USDC_CORE,
|
|
@@ -189,6 +240,9 @@ export const MORPHO_VAULTS: Record<MorphoVaultType, MorphoVault> = {
|
|
|
189
240
|
[MorphoVaultType.MorphoVaultSmokehouseUSDT]: MORPHO_VAULT_SMOKEHOUSE_USDT,
|
|
190
241
|
[MorphoVaultType.MorphoVaultSmokehouseUSDC]: MORPHO_VAULT_SMOKEHOUSE_USDC,
|
|
191
242
|
[MorphoVaultType.MorphoVaultSmokehouseDAI]: MORPHO_VAULT_SMOKEHOUSE_DAI,
|
|
243
|
+
|
|
244
|
+
// Vault V2
|
|
245
|
+
[MorphoVaultType.MorphoVaultGauntletUSDGPremium]: MORPHO_VAULT_GAUNTLET_USDG_PREMIUM,
|
|
192
246
|
};
|
|
193
247
|
|
|
194
248
|
export const getMorphoVault = (type: MorphoVaultType): MorphoVault => MORPHO_VAULTS[type];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EthAddress } from '../common';
|
|
1
|
+
import { EthAddress, NetworkNumber } from '../common';
|
|
2
2
|
|
|
3
3
|
export enum MorphoVaultType {
|
|
4
4
|
MorphoVaultFlagshipEth = 'morpho_vault_flagship_eth',
|
|
@@ -21,6 +21,13 @@ export enum MorphoVaultType {
|
|
|
21
21
|
MorphoVaultSmokehouseUSDT = 'morpho_vault_smokehouse_usdt',
|
|
22
22
|
MorphoVaultSmokehouseUSDC = 'morpho_vault_smokehouse_usdc',
|
|
23
23
|
MorphoVaultSmokehouseDAI = 'morpho_vault_smokehouse_dai',
|
|
24
|
+
// Vault V2
|
|
25
|
+
MorphoVaultGauntletUSDGPremium = 'morpho_vault_gauntlet_usdg_premium',
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export enum MorphoVaultVersion {
|
|
29
|
+
V1 = 1,
|
|
30
|
+
V2 = 2,
|
|
24
31
|
}
|
|
25
32
|
|
|
26
33
|
export interface MorphoVault {
|
|
@@ -28,6 +35,8 @@ export interface MorphoVault {
|
|
|
28
35
|
name: string;
|
|
29
36
|
address: EthAddress;
|
|
30
37
|
asset: string;
|
|
38
|
+
network: NetworkNumber;
|
|
39
|
+
version: MorphoVaultVersion;
|
|
31
40
|
deploymentBlock: number;
|
|
32
41
|
isLegacy: boolean;
|
|
33
42
|
}
|