@defisaver/positions-sdk 2.1.7 → 2.1.8

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.
Files changed (132) hide show
  1. package/.mocharc.json +4 -4
  2. package/.nvmrc +1 -1
  3. package/README.md +64 -64
  4. package/cjs/aaveV3/index.js +3 -3
  5. package/cjs/aaveV3/merit.js +3 -0
  6. package/cjs/aaveV3/merkl.d.ts +1 -1
  7. package/cjs/config/contracts.d.ts +20 -0
  8. package/cjs/config/contracts.js +20 -0
  9. package/cjs/helpers/aaveHelpers/index.d.ts +1 -1
  10. package/cjs/helpers/aaveHelpers/index.js +6 -4
  11. package/cjs/helpers/morphoBlueHelpers/index.d.ts +1 -1
  12. package/cjs/helpers/morphoBlueHelpers/index.js +66 -66
  13. package/cjs/markets/aave/index.js +1 -1
  14. package/cjs/markets/aave/marketAssets.d.ts +4 -0
  15. package/cjs/markets/aave/marketAssets.js +5 -1
  16. package/cjs/markets/compound/index.js +11 -0
  17. package/cjs/markets/compound/marketsAssets.d.ts +7 -0
  18. package/cjs/markets/compound/marketsAssets.js +7 -0
  19. package/cjs/markets/spark/marketAssets.d.ts +1 -0
  20. package/cjs/markets/spark/marketAssets.js +1 -0
  21. package/cjs/services/utils.d.ts +8 -4
  22. package/cjs/services/utils.js +30 -10
  23. package/cjs/services/viem.d.ts +54 -15
  24. package/cjs/services/viem.js +2 -0
  25. package/cjs/staking/eligibility.js +1 -6
  26. package/cjs/types/common.d.ts +4 -2
  27. package/cjs/types/common.js +2 -0
  28. package/esm/aaveV3/index.js +4 -4
  29. package/esm/aaveV3/merit.js +3 -0
  30. package/esm/aaveV3/merkl.d.ts +1 -1
  31. package/esm/config/contracts.d.ts +20 -0
  32. package/esm/config/contracts.js +20 -0
  33. package/esm/helpers/aaveHelpers/index.d.ts +1 -1
  34. package/esm/helpers/aaveHelpers/index.js +7 -5
  35. package/esm/helpers/morphoBlueHelpers/index.d.ts +1 -1
  36. package/esm/helpers/morphoBlueHelpers/index.js +66 -66
  37. package/esm/markets/aave/index.js +1 -1
  38. package/esm/markets/aave/marketAssets.d.ts +4 -0
  39. package/esm/markets/aave/marketAssets.js +4 -0
  40. package/esm/markets/compound/index.js +11 -0
  41. package/esm/markets/compound/marketsAssets.d.ts +7 -0
  42. package/esm/markets/compound/marketsAssets.js +7 -0
  43. package/esm/markets/spark/marketAssets.d.ts +1 -0
  44. package/esm/markets/spark/marketAssets.js +1 -0
  45. package/esm/services/utils.d.ts +8 -4
  46. package/esm/services/utils.js +21 -5
  47. package/esm/services/viem.d.ts +54 -15
  48. package/esm/services/viem.js +3 -1
  49. package/esm/staking/eligibility.js +1 -6
  50. package/esm/types/common.d.ts +4 -2
  51. package/esm/types/common.js +2 -0
  52. package/package.json +47 -47
  53. package/src/aaveV2/index.ts +240 -240
  54. package/src/aaveV3/index.ts +614 -614
  55. package/src/aaveV3/merit.ts +97 -94
  56. package/src/aaveV3/merkl.ts +74 -74
  57. package/src/claiming/aaveV3.ts +154 -154
  58. package/src/claiming/compV3.ts +22 -22
  59. package/src/claiming/index.ts +12 -12
  60. package/src/claiming/king.ts +66 -66
  61. package/src/claiming/morphoBlue.ts +118 -118
  62. package/src/claiming/spark.ts +225 -225
  63. package/src/compoundV2/index.ts +244 -244
  64. package/src/compoundV3/index.ts +274 -274
  65. package/src/config/contracts.ts +1251 -1231
  66. package/src/constants/index.ts +10 -10
  67. package/src/contracts.ts +120 -120
  68. package/src/curveUsd/index.ts +254 -254
  69. package/src/eulerV2/index.ts +324 -324
  70. package/src/exchange/index.ts +25 -25
  71. package/src/fluid/index.ts +1638 -1638
  72. package/src/helpers/aaveHelpers/index.ts +187 -185
  73. package/src/helpers/compoundHelpers/index.ts +283 -283
  74. package/src/helpers/curveUsdHelpers/index.ts +40 -40
  75. package/src/helpers/eulerHelpers/index.ts +222 -222
  76. package/src/helpers/fluidHelpers/index.ts +326 -326
  77. package/src/helpers/index.ts +10 -10
  78. package/src/helpers/liquityV2Helpers/index.ts +82 -82
  79. package/src/helpers/llamaLendHelpers/index.ts +53 -53
  80. package/src/helpers/makerHelpers/index.ts +52 -52
  81. package/src/helpers/morphoBlueHelpers/index.ts +396 -396
  82. package/src/helpers/sparkHelpers/index.ts +155 -155
  83. package/src/index.ts +47 -47
  84. package/src/liquity/index.ts +159 -159
  85. package/src/liquityV2/index.ts +657 -657
  86. package/src/llamaLend/index.ts +305 -305
  87. package/src/maker/index.ts +223 -223
  88. package/src/markets/aave/index.ts +116 -116
  89. package/src/markets/aave/marketAssets.ts +54 -49
  90. package/src/markets/compound/index.ts +238 -227
  91. package/src/markets/compound/marketsAssets.ts +97 -90
  92. package/src/markets/curveUsd/index.ts +69 -69
  93. package/src/markets/euler/index.ts +26 -26
  94. package/src/markets/fluid/index.ts +2456 -2456
  95. package/src/markets/index.ts +25 -25
  96. package/src/markets/liquityV2/index.ts +102 -102
  97. package/src/markets/llamaLend/contractAddresses.ts +141 -141
  98. package/src/markets/llamaLend/index.ts +235 -235
  99. package/src/markets/morphoBlue/index.ts +895 -895
  100. package/src/markets/spark/index.ts +29 -29
  101. package/src/markets/spark/marketAssets.ts +12 -11
  102. package/src/moneymarket/moneymarketCommonService.ts +80 -80
  103. package/src/morphoBlue/index.ts +274 -274
  104. package/src/portfolio/index.ts +570 -570
  105. package/src/services/priceService.ts +159 -159
  106. package/src/services/utils.ts +115 -99
  107. package/src/services/viem.ts +34 -32
  108. package/src/setup.ts +8 -8
  109. package/src/spark/index.ts +445 -445
  110. package/src/staking/eligibility.ts +53 -59
  111. package/src/staking/index.ts +1 -1
  112. package/src/staking/staking.ts +170 -170
  113. package/src/types/aave.ts +189 -189
  114. package/src/types/claiming.ts +109 -109
  115. package/src/types/common.ts +107 -105
  116. package/src/types/compound.ts +136 -136
  117. package/src/types/curveUsd.ts +123 -123
  118. package/src/types/euler.ts +175 -175
  119. package/src/types/fluid.ts +448 -448
  120. package/src/types/index.ts +13 -13
  121. package/src/types/liquity.ts +30 -30
  122. package/src/types/liquityV2.ts +126 -126
  123. package/src/types/llamaLend.ts +159 -159
  124. package/src/types/maker.ts +63 -63
  125. package/src/types/merit.ts +1 -1
  126. package/src/types/merkl.ts +70 -70
  127. package/src/types/morphoBlue.ts +194 -194
  128. package/src/types/portfolio.ts +60 -60
  129. package/src/types/spark.ts +135 -135
  130. package/src/umbrella/index.ts +69 -69
  131. package/src/umbrella/umbrellaUtils.ts +29 -29
  132. package/CLAUDE.md +0 -32
@@ -1,275 +1,275 @@
1
- import Dec from 'decimal.js';
2
- import { assetAmountInEth, getAssetInfoByAddress } from '@defisaver/tokens';
3
- import { Client } from 'viem';
4
- import {
5
- Blockish, EthAddress, EthereumProvider, IncentiveKind, MMUsedAssets, NetworkNumber, PositionBalances, MMAssetsData,
6
- } from '../types/common';
7
- import {
8
- DFSFeedRegistryContractViem, FeedRegistryContractViem, MorphoBlueViewContractViem,
9
- } from '../contracts';
10
- import {
11
- MorphoBlueAssetsData, MorphoBlueMarketData, MorphoBlueMarketInfo, MorphoBluePositionData,
12
- } from '../types';
13
- import { USD_QUOTE, WAD } from '../constants';
14
- import { calculateNetApy, getStakingApy, STAKING_ASSETS } from '../staking';
15
- import { isMainnetNetwork, wethToEth } from '../services/utils';
16
- import {
17
- getBorrowRate, getMorphoBlueAggregatedPositionData, getRewardsForMarket, getSupplyRate,
18
- } from '../helpers/morphoBlueHelpers';
19
- import { getChainlinkAssetAddress } from '../services/priceService';
20
- import { getViemProvider, setViemBlockNumber } from '../services/viem';
21
-
22
- export async function _getMorphoBlueMarketData(provider: Client, network: NetworkNumber, selectedMarket: MorphoBlueMarketData): Promise<MorphoBlueMarketInfo> {
23
- const {
24
- loanToken, collateralToken, oracle, irm, lltv, oracleType,
25
- } = selectedMarket;
26
-
27
- const lltvInWei = new Dec(lltv).mul(WAD).toString();
28
- const loanTokenInfo = getAssetInfoByAddress(loanToken, network);
29
- const collateralTokenInfo = getAssetInfoByAddress(collateralToken, network);
30
-
31
- const loanTokenFeedAddress = getChainlinkAssetAddress(loanTokenInfo.symbol, network);
32
-
33
- const morphoBlueViewContract = MorphoBlueViewContractViem(provider, network);
34
-
35
- let marketInfo;
36
- let loanTokenPrice;
37
- const isTokenUSDA = loanTokenInfo.symbol === 'USDA';
38
- const isMainnet = isMainnetNetwork(network);
39
- if (isMainnet) {
40
- const feedRegistryContract = FeedRegistryContractViem(provider, NetworkNumber.Eth);
41
- const [_loanTokenPrice, _marketInfo] = await Promise.all([
42
- isTokenUSDA ? Promise.resolve('100000000') : feedRegistryContract.read.latestAnswer([loanTokenFeedAddress, USD_QUOTE]),
43
- morphoBlueViewContract.read.getMarketInfoNotTuple([loanToken, collateralToken, oracle, irm, BigInt(lltvInWei)]),
44
- ]);
45
- marketInfo = _marketInfo;
46
- loanTokenPrice = _loanTokenPrice;
47
- } else {
48
- // Currently only base network is supported
49
- const feedRegistryContract = DFSFeedRegistryContractViem(provider, network);
50
-
51
- const [loanTokenPriceRound, _marketInfo] = await Promise.all([
52
- isTokenUSDA ? Promise.resolve([0, '100000000']) // Normalize to match the expected object structure
53
- : feedRegistryContract.read.latestRoundData([loanTokenFeedAddress, USD_QUOTE]),
54
- morphoBlueViewContract.read.getMarketInfoNotTuple([loanToken, collateralToken, oracle, irm, BigInt(lltvInWei)]),
55
- ]);
56
- marketInfo = _marketInfo;
57
- loanTokenPrice = loanTokenPriceRound[1].toString();
58
- }
59
-
60
- let morphoSupplyApy = '0';
61
- let morphoBorrowApy = '0';
62
- try {
63
- const { supplyApy: _morphoSupplyApy, borrowApy: _morphoBorrowApy } = await getRewardsForMarket(selectedMarket.marketId, network);
64
- morphoSupplyApy = _morphoSupplyApy;
65
- morphoBorrowApy = _morphoBorrowApy;
66
- } catch (e) {
67
- console.error(e);
68
- }
69
-
70
- const supplyRate = getSupplyRate(marketInfo.totalSupplyAssets.toString(), marketInfo.totalBorrowAssets.toString(), marketInfo.borrowRate.toString(), marketInfo.fee.toString());
71
- const compoundedBorrowRate = getBorrowRate(marketInfo.borrowRate.toString(), marketInfo.totalBorrowShares.toString());
72
- const utillization = new Dec(marketInfo.totalBorrowAssets.toString()).div(marketInfo.totalSupplyAssets.toString()).mul(100).toString();
73
-
74
- const oracleScaleFactor = new Dec(36).add(loanTokenInfo.decimals).sub(collateralTokenInfo.decimals).toString();
75
- const oracleScale = new Dec(10).pow(oracleScaleFactor).toString();
76
-
77
- const scale = new Dec(10).pow(loanTokenInfo.decimals).toString();
78
-
79
- const oracleRate = new Dec(marketInfo.oracle.toString()).div(oracleScale).toString();
80
- const assetsData: MorphoBlueAssetsData = {};
81
- assetsData[wethToEth(loanTokenInfo.symbol)] = {
82
- symbol: wethToEth(loanTokenInfo.symbol),
83
- address: loanToken,
84
- price: new Dec(loanTokenPrice).div(1e8).toString(),
85
- supplyRate,
86
- borrowRate: compoundedBorrowRate,
87
- totalSupply: new Dec(marketInfo.totalSupplyAssets.toString()).div(scale).toString(),
88
- totalBorrow: new Dec(marketInfo.totalBorrowAssets.toString()).div(scale).toString(),
89
- canBeSupplied: true,
90
- canBeBorrowed: true,
91
- supplyIncentives: [{
92
- token: 'MORPHO',
93
- apy: morphoSupplyApy,
94
- incentiveKind: IncentiveKind.Reward,
95
- description: 'Eligible for protocol-level MORPHO incentives.',
96
- }],
97
- borrowIncentives: [{
98
- token: 'MORPHO',
99
- apy: morphoBorrowApy,
100
- incentiveKind: IncentiveKind.Reward,
101
- description: 'Eligible for protocol-level MORPHO incentives.',
102
- }],
103
- };
104
-
105
- assetsData[wethToEth(collateralTokenInfo.symbol)] = {
106
- symbol: wethToEth(collateralTokenInfo.symbol),
107
- address: collateralToken,
108
- price: new Dec(assetsData[wethToEth(loanTokenInfo.symbol)].price).mul(oracleRate).toString(),
109
- supplyRate: '0',
110
- borrowRate: '0',
111
- canBeSupplied: true,
112
- canBeBorrowed: false,
113
- supplyIncentives: [],
114
- borrowIncentives: [],
115
- };
116
- if (STAKING_ASSETS.includes(collateralTokenInfo.symbol)) {
117
- assetsData[collateralTokenInfo.symbol].supplyIncentives = [{
118
- apy: await getStakingApy(collateralTokenInfo.symbol),
119
- token: collateralTokenInfo.symbol,
120
- incentiveKind: IncentiveKind.Staking,
121
- description: `Native ${collateralTokenInfo.symbol} yield.`,
122
- }];
123
- }
124
-
125
- return {
126
- id: marketInfo.id,
127
- fee: new Dec(marketInfo.fee.toString()).div(WAD).toString(),
128
- loanToken: wethToEth(loanTokenInfo.symbol),
129
- collateralToken: wethToEth(collateralTokenInfo.symbol),
130
- utillization,
131
- oracle: oracleRate,
132
- oracleType,
133
- lltv: new Dec(lltv).toString(),
134
- minRatio: new Dec(1).div(lltv).mul(100).toString(),
135
- assetsData,
136
- };
137
- }
138
-
139
- export async function getMorphoBlueMarketData(provider: EthereumProvider, network: NetworkNumber, selectedMarket: MorphoBlueMarketData): Promise<MorphoBlueMarketInfo> {
140
- return _getMorphoBlueMarketData(getViemProvider(provider, network), network, selectedMarket);
141
- }
142
-
143
- export const _getMorphoBlueAccountBalances = async (provider: Client, network: NetworkNumber, block: Blockish, addressMapping: boolean, address: EthAddress, selectedMarket: MorphoBlueMarketData): Promise<PositionBalances> => {
144
- let balances: PositionBalances = {
145
- collateral: {},
146
- debt: {},
147
- };
148
-
149
- if (!address) {
150
- return balances;
151
- }
152
-
153
- const viewContract = MorphoBlueViewContractViem(provider, network, block);
154
- const {
155
- loanToken, collateralToken, oracle, irm, lltv,
156
- } = selectedMarket;
157
- const lltvInWei = BigInt(new Dec(lltv).mul(WAD).toString());
158
- const marketObject = {
159
- loanToken, collateralToken, oracle, irm, lltv: lltvInWei,
160
- };
161
-
162
- const loanInfo = await viewContract.read.getUserInfo([marketObject, address], setViemBlockNumber(block));
163
- const loanTokenInfo = getAssetInfoByAddress(selectedMarket.loanToken, network);
164
- const collateralTokenInfo = getAssetInfoByAddress(selectedMarket.collateralToken, network);
165
-
166
- balances = {
167
- collateral: {
168
- [addressMapping ? collateralTokenInfo.address.toLowerCase() : wethToEth(collateralTokenInfo.symbol)]: assetAmountInEth(loanInfo.collateral.toString(), collateralTokenInfo.symbol),
169
- },
170
- debt: {
171
- [addressMapping ? loanTokenInfo.address.toLowerCase() : wethToEth(loanTokenInfo.symbol)]: assetAmountInEth(loanInfo.borrowedInAssets.toString(), loanTokenInfo.symbol),
172
- },
173
- };
174
-
175
- return balances;
176
- };
177
-
178
- export const getMorphoBlueAccountBalances = async (
179
- provider: EthereumProvider,
180
- network: NetworkNumber,
181
- block: Blockish,
182
- addressMapping: boolean,
183
- address: EthAddress,
184
- selectedMarket: MorphoBlueMarketData,
185
- ): Promise<PositionBalances> => _getMorphoBlueAccountBalances(getViemProvider(provider, network), network, block, addressMapping, address, selectedMarket);
186
-
187
- export async function _getMorphoBlueAccountData(provider: Client, network: NetworkNumber, account: EthAddress, selectedMarket: MorphoBlueMarketData, marketInfo: MorphoBlueMarketInfo): Promise<MorphoBluePositionData> {
188
- const {
189
- loanToken, collateralToken, oracle, irm, lltv,
190
- } = selectedMarket;
191
- const lltvInWei = new Dec(lltv).mul(WAD).toString();
192
- const viewContract = MorphoBlueViewContractViem(provider, network);
193
- const loanInfo = (await viewContract.read.getUserInfo([
194
- {
195
- loanToken, collateralToken, oracle, irm, lltv: BigInt(lltvInWei),
196
- },
197
- account]));
198
- const usedAssets: MMUsedAssets = {};
199
-
200
- const loanTokenInfo = marketInfo.assetsData[marketInfo.loanToken];
201
- const loanTokenSupplied = assetAmountInEth(loanInfo.suppliedInAssets.toString(), marketInfo.loanToken);
202
- const loanTokenBorrowed = assetAmountInEth(loanInfo.borrowedInAssets.toString(), marketInfo.loanToken);
203
- usedAssets[marketInfo.loanToken] = {
204
- symbol: loanTokenInfo.symbol,
205
- supplied: loanTokenSupplied,
206
- borrowed: loanTokenBorrowed,
207
- isSupplied: new Dec(loanInfo.suppliedInAssets.toString()).gt(0),
208
- isBorrowed: new Dec(loanInfo.borrowedInAssets.toString()).gt(0),
209
- collateral: false,
210
- suppliedUsd: new Dec(loanTokenSupplied).mul(loanTokenInfo.price).toString(),
211
- borrowedUsd: new Dec(loanTokenBorrowed).mul(loanTokenInfo.price).toString(),
212
- };
213
-
214
- const collateralTokenInfo = marketInfo.assetsData[marketInfo.collateralToken];
215
- const collateralTokenSupplied = assetAmountInEth(loanInfo.collateral.toString(), marketInfo.collateralToken);
216
- usedAssets[marketInfo.collateralToken] = {
217
- symbol: collateralTokenInfo.symbol,
218
- supplied: collateralTokenSupplied,
219
- borrowed: '0',
220
- isSupplied: new Dec(loanInfo.collateral.toString()).gt(0),
221
- isBorrowed: false,
222
- collateral: true,
223
- suppliedUsd: new Dec(collateralTokenSupplied).mul(collateralTokenInfo.price).toString(),
224
- borrowedUsd: '0',
225
- };
226
-
227
- return {
228
- supplyShares: loanInfo.supplyShares.toString(),
229
- borrowShares: loanInfo.borrowShares.toString(),
230
- usedAssets,
231
- ...getMorphoBlueAggregatedPositionData({ usedAssets, assetsData: marketInfo.assetsData, marketInfo }),
232
- };
233
- }
234
-
235
- export async function getMorphoBlueAccountData(provider: EthereumProvider, network: NetworkNumber, account: EthAddress, selectedMarket: MorphoBlueMarketData, marketInfo: MorphoBlueMarketInfo): Promise<MorphoBluePositionData> {
236
- return _getMorphoBlueAccountData(getViemProvider(provider, network), network, account, selectedMarket, marketInfo);
237
- }
238
-
239
- export async function getMorphoEarn(provider: Client, network: NetworkNumber, account: EthAddress, selectedMarket: MorphoBlueMarketData, marketInfo: MorphoBlueMarketInfo): Promise<{ apy: string, amount: string, amountUsd: string }> {
240
- const {
241
- loanToken, collateralToken, oracle, irm, lltv,
242
- } = selectedMarket;
243
- const lltvInWei = new Dec(lltv).mul(WAD).toString();
244
-
245
- const viewContract = MorphoBlueViewContractViem(provider, network);
246
- const loanInfo = (await viewContract.read.getUserInfo([
247
- {
248
- loanToken, collateralToken, oracle, irm, lltv: BigInt(lltvInWei),
249
- },
250
- account]));
251
-
252
- const loanTokenInfo = marketInfo.assetsData[marketInfo.loanToken];
253
- const loanTokenSupplied = assetAmountInEth(loanInfo.suppliedInAssets.toString(), marketInfo.loanToken);
254
- const loanTokenSuppliedUsd = new Dec(loanTokenSupplied).mul(loanTokenInfo.price).toString();
255
- const usedAssets: MMUsedAssets = {
256
- [marketInfo.loanToken]: {
257
- symbol: loanTokenInfo.symbol,
258
- supplied: loanTokenSupplied,
259
- borrowed: '0',
260
- isSupplied: new Dec(loanInfo.suppliedInAssets.toString()).gt(0),
261
- isBorrowed: false,
262
- collateral: false,
263
- suppliedUsd: loanTokenSuppliedUsd,
264
- borrowedUsd: '0',
265
- },
266
- };
267
-
268
- const { netApy } = calculateNetApy({ usedAssets, assetsData: marketInfo.assetsData as unknown as MMAssetsData });
269
-
270
- return {
271
- apy: netApy,
272
- amount: loanTokenSupplied,
273
- amountUsd: loanTokenSuppliedUsd,
274
- };
1
+ import Dec from 'decimal.js';
2
+ import { assetAmountInEth, getAssetInfoByAddress } from '@defisaver/tokens';
3
+ import { Client } from 'viem';
4
+ import {
5
+ Blockish, EthAddress, EthereumProvider, IncentiveKind, MMUsedAssets, NetworkNumber, PositionBalances, MMAssetsData,
6
+ } from '../types/common';
7
+ import {
8
+ DFSFeedRegistryContractViem, FeedRegistryContractViem, MorphoBlueViewContractViem,
9
+ } from '../contracts';
10
+ import {
11
+ MorphoBlueAssetsData, MorphoBlueMarketData, MorphoBlueMarketInfo, MorphoBluePositionData,
12
+ } from '../types';
13
+ import { USD_QUOTE, WAD } from '../constants';
14
+ import { calculateNetApy, getStakingApy, STAKING_ASSETS } from '../staking';
15
+ import { isMainnetNetwork, wethToEth } from '../services/utils';
16
+ import {
17
+ getBorrowRate, getMorphoBlueAggregatedPositionData, getRewardsForMarket, getSupplyRate,
18
+ } from '../helpers/morphoBlueHelpers';
19
+ import { getChainlinkAssetAddress } from '../services/priceService';
20
+ import { getViemProvider, setViemBlockNumber } from '../services/viem';
21
+
22
+ export async function _getMorphoBlueMarketData(provider: Client, network: NetworkNumber, selectedMarket: MorphoBlueMarketData): Promise<MorphoBlueMarketInfo> {
23
+ const {
24
+ loanToken, collateralToken, oracle, irm, lltv, oracleType,
25
+ } = selectedMarket;
26
+
27
+ const lltvInWei = new Dec(lltv).mul(WAD).toString();
28
+ const loanTokenInfo = getAssetInfoByAddress(loanToken, network);
29
+ const collateralTokenInfo = getAssetInfoByAddress(collateralToken, network);
30
+
31
+ const loanTokenFeedAddress = getChainlinkAssetAddress(loanTokenInfo.symbol, network);
32
+
33
+ const morphoBlueViewContract = MorphoBlueViewContractViem(provider, network);
34
+
35
+ let marketInfo;
36
+ let loanTokenPrice;
37
+ const isTokenUSDA = loanTokenInfo.symbol === 'USDA';
38
+ const isMainnet = isMainnetNetwork(network);
39
+ if (isMainnet) {
40
+ const feedRegistryContract = FeedRegistryContractViem(provider, NetworkNumber.Eth);
41
+ const [_loanTokenPrice, _marketInfo] = await Promise.all([
42
+ isTokenUSDA ? Promise.resolve('100000000') : feedRegistryContract.read.latestAnswer([loanTokenFeedAddress, USD_QUOTE]),
43
+ morphoBlueViewContract.read.getMarketInfoNotTuple([loanToken, collateralToken, oracle, irm, BigInt(lltvInWei)]),
44
+ ]);
45
+ marketInfo = _marketInfo;
46
+ loanTokenPrice = _loanTokenPrice;
47
+ } else {
48
+ // Currently only base network is supported
49
+ const feedRegistryContract = DFSFeedRegistryContractViem(provider, network);
50
+
51
+ const [loanTokenPriceRound, _marketInfo] = await Promise.all([
52
+ isTokenUSDA ? Promise.resolve([0, '100000000']) // Normalize to match the expected object structure
53
+ : feedRegistryContract.read.latestRoundData([loanTokenFeedAddress, USD_QUOTE]),
54
+ morphoBlueViewContract.read.getMarketInfoNotTuple([loanToken, collateralToken, oracle, irm, BigInt(lltvInWei)]),
55
+ ]);
56
+ marketInfo = _marketInfo;
57
+ loanTokenPrice = loanTokenPriceRound[1].toString();
58
+ }
59
+
60
+ let morphoSupplyApy = '0';
61
+ let morphoBorrowApy = '0';
62
+ try {
63
+ const { supplyApy: _morphoSupplyApy, borrowApy: _morphoBorrowApy } = await getRewardsForMarket(selectedMarket.marketId, network);
64
+ morphoSupplyApy = _morphoSupplyApy;
65
+ morphoBorrowApy = _morphoBorrowApy;
66
+ } catch (e) {
67
+ console.error(e);
68
+ }
69
+
70
+ const supplyRate = getSupplyRate(marketInfo.totalSupplyAssets.toString(), marketInfo.totalBorrowAssets.toString(), marketInfo.borrowRate.toString(), marketInfo.fee.toString());
71
+ const compoundedBorrowRate = getBorrowRate(marketInfo.borrowRate.toString(), marketInfo.totalBorrowShares.toString());
72
+ const utillization = new Dec(marketInfo.totalBorrowAssets.toString()).div(marketInfo.totalSupplyAssets.toString()).mul(100).toString();
73
+
74
+ const oracleScaleFactor = new Dec(36).add(loanTokenInfo.decimals).sub(collateralTokenInfo.decimals).toString();
75
+ const oracleScale = new Dec(10).pow(oracleScaleFactor).toString();
76
+
77
+ const scale = new Dec(10).pow(loanTokenInfo.decimals).toString();
78
+
79
+ const oracleRate = new Dec(marketInfo.oracle.toString()).div(oracleScale).toString();
80
+ const assetsData: MorphoBlueAssetsData = {};
81
+ assetsData[wethToEth(loanTokenInfo.symbol)] = {
82
+ symbol: wethToEth(loanTokenInfo.symbol),
83
+ address: loanToken,
84
+ price: new Dec(loanTokenPrice).div(1e8).toString(),
85
+ supplyRate,
86
+ borrowRate: compoundedBorrowRate,
87
+ totalSupply: new Dec(marketInfo.totalSupplyAssets.toString()).div(scale).toString(),
88
+ totalBorrow: new Dec(marketInfo.totalBorrowAssets.toString()).div(scale).toString(),
89
+ canBeSupplied: true,
90
+ canBeBorrowed: true,
91
+ supplyIncentives: [{
92
+ token: 'MORPHO',
93
+ apy: morphoSupplyApy,
94
+ incentiveKind: IncentiveKind.Reward,
95
+ description: 'Eligible for protocol-level MORPHO incentives.',
96
+ }],
97
+ borrowIncentives: [{
98
+ token: 'MORPHO',
99
+ apy: morphoBorrowApy,
100
+ incentiveKind: IncentiveKind.Reward,
101
+ description: 'Eligible for protocol-level MORPHO incentives.',
102
+ }],
103
+ };
104
+
105
+ assetsData[wethToEth(collateralTokenInfo.symbol)] = {
106
+ symbol: wethToEth(collateralTokenInfo.symbol),
107
+ address: collateralToken,
108
+ price: new Dec(assetsData[wethToEth(loanTokenInfo.symbol)].price).mul(oracleRate).toString(),
109
+ supplyRate: '0',
110
+ borrowRate: '0',
111
+ canBeSupplied: true,
112
+ canBeBorrowed: false,
113
+ supplyIncentives: [],
114
+ borrowIncentives: [],
115
+ };
116
+ if (STAKING_ASSETS.includes(collateralTokenInfo.symbol)) {
117
+ assetsData[collateralTokenInfo.symbol].supplyIncentives = [{
118
+ apy: await getStakingApy(collateralTokenInfo.symbol),
119
+ token: collateralTokenInfo.symbol,
120
+ incentiveKind: IncentiveKind.Staking,
121
+ description: `Native ${collateralTokenInfo.symbol} yield.`,
122
+ }];
123
+ }
124
+
125
+ return {
126
+ id: marketInfo.id,
127
+ fee: new Dec(marketInfo.fee.toString()).div(WAD).toString(),
128
+ loanToken: wethToEth(loanTokenInfo.symbol),
129
+ collateralToken: wethToEth(collateralTokenInfo.symbol),
130
+ utillization,
131
+ oracle: oracleRate,
132
+ oracleType,
133
+ lltv: new Dec(lltv).toString(),
134
+ minRatio: new Dec(1).div(lltv).mul(100).toString(),
135
+ assetsData,
136
+ };
137
+ }
138
+
139
+ export async function getMorphoBlueMarketData(provider: EthereumProvider, network: NetworkNumber, selectedMarket: MorphoBlueMarketData): Promise<MorphoBlueMarketInfo> {
140
+ return _getMorphoBlueMarketData(getViemProvider(provider, network), network, selectedMarket);
141
+ }
142
+
143
+ export const _getMorphoBlueAccountBalances = async (provider: Client, network: NetworkNumber, block: Blockish, addressMapping: boolean, address: EthAddress, selectedMarket: MorphoBlueMarketData): Promise<PositionBalances> => {
144
+ let balances: PositionBalances = {
145
+ collateral: {},
146
+ debt: {},
147
+ };
148
+
149
+ if (!address) {
150
+ return balances;
151
+ }
152
+
153
+ const viewContract = MorphoBlueViewContractViem(provider, network, block);
154
+ const {
155
+ loanToken, collateralToken, oracle, irm, lltv,
156
+ } = selectedMarket;
157
+ const lltvInWei = BigInt(new Dec(lltv).mul(WAD).toString());
158
+ const marketObject = {
159
+ loanToken, collateralToken, oracle, irm, lltv: lltvInWei,
160
+ };
161
+
162
+ const loanInfo = await viewContract.read.getUserInfo([marketObject, address], setViemBlockNumber(block));
163
+ const loanTokenInfo = getAssetInfoByAddress(selectedMarket.loanToken, network);
164
+ const collateralTokenInfo = getAssetInfoByAddress(selectedMarket.collateralToken, network);
165
+
166
+ balances = {
167
+ collateral: {
168
+ [addressMapping ? collateralTokenInfo.address.toLowerCase() : wethToEth(collateralTokenInfo.symbol)]: assetAmountInEth(loanInfo.collateral.toString(), collateralTokenInfo.symbol),
169
+ },
170
+ debt: {
171
+ [addressMapping ? loanTokenInfo.address.toLowerCase() : wethToEth(loanTokenInfo.symbol)]: assetAmountInEth(loanInfo.borrowedInAssets.toString(), loanTokenInfo.symbol),
172
+ },
173
+ };
174
+
175
+ return balances;
176
+ };
177
+
178
+ export const getMorphoBlueAccountBalances = async (
179
+ provider: EthereumProvider,
180
+ network: NetworkNumber,
181
+ block: Blockish,
182
+ addressMapping: boolean,
183
+ address: EthAddress,
184
+ selectedMarket: MorphoBlueMarketData,
185
+ ): Promise<PositionBalances> => _getMorphoBlueAccountBalances(getViemProvider(provider, network), network, block, addressMapping, address, selectedMarket);
186
+
187
+ export async function _getMorphoBlueAccountData(provider: Client, network: NetworkNumber, account: EthAddress, selectedMarket: MorphoBlueMarketData, marketInfo: MorphoBlueMarketInfo): Promise<MorphoBluePositionData> {
188
+ const {
189
+ loanToken, collateralToken, oracle, irm, lltv,
190
+ } = selectedMarket;
191
+ const lltvInWei = new Dec(lltv).mul(WAD).toString();
192
+ const viewContract = MorphoBlueViewContractViem(provider, network);
193
+ const loanInfo = (await viewContract.read.getUserInfo([
194
+ {
195
+ loanToken, collateralToken, oracle, irm, lltv: BigInt(lltvInWei),
196
+ },
197
+ account]));
198
+ const usedAssets: MMUsedAssets = {};
199
+
200
+ const loanTokenInfo = marketInfo.assetsData[marketInfo.loanToken];
201
+ const loanTokenSupplied = assetAmountInEth(loanInfo.suppliedInAssets.toString(), marketInfo.loanToken);
202
+ const loanTokenBorrowed = assetAmountInEth(loanInfo.borrowedInAssets.toString(), marketInfo.loanToken);
203
+ usedAssets[marketInfo.loanToken] = {
204
+ symbol: loanTokenInfo.symbol,
205
+ supplied: loanTokenSupplied,
206
+ borrowed: loanTokenBorrowed,
207
+ isSupplied: new Dec(loanInfo.suppliedInAssets.toString()).gt(0),
208
+ isBorrowed: new Dec(loanInfo.borrowedInAssets.toString()).gt(0),
209
+ collateral: false,
210
+ suppliedUsd: new Dec(loanTokenSupplied).mul(loanTokenInfo.price).toString(),
211
+ borrowedUsd: new Dec(loanTokenBorrowed).mul(loanTokenInfo.price).toString(),
212
+ };
213
+
214
+ const collateralTokenInfo = marketInfo.assetsData[marketInfo.collateralToken];
215
+ const collateralTokenSupplied = assetAmountInEth(loanInfo.collateral.toString(), marketInfo.collateralToken);
216
+ usedAssets[marketInfo.collateralToken] = {
217
+ symbol: collateralTokenInfo.symbol,
218
+ supplied: collateralTokenSupplied,
219
+ borrowed: '0',
220
+ isSupplied: new Dec(loanInfo.collateral.toString()).gt(0),
221
+ isBorrowed: false,
222
+ collateral: true,
223
+ suppliedUsd: new Dec(collateralTokenSupplied).mul(collateralTokenInfo.price).toString(),
224
+ borrowedUsd: '0',
225
+ };
226
+
227
+ return {
228
+ supplyShares: loanInfo.supplyShares.toString(),
229
+ borrowShares: loanInfo.borrowShares.toString(),
230
+ usedAssets,
231
+ ...getMorphoBlueAggregatedPositionData({ usedAssets, assetsData: marketInfo.assetsData, marketInfo }),
232
+ };
233
+ }
234
+
235
+ export async function getMorphoBlueAccountData(provider: EthereumProvider, network: NetworkNumber, account: EthAddress, selectedMarket: MorphoBlueMarketData, marketInfo: MorphoBlueMarketInfo): Promise<MorphoBluePositionData> {
236
+ return _getMorphoBlueAccountData(getViemProvider(provider, network), network, account, selectedMarket, marketInfo);
237
+ }
238
+
239
+ export async function getMorphoEarn(provider: Client, network: NetworkNumber, account: EthAddress, selectedMarket: MorphoBlueMarketData, marketInfo: MorphoBlueMarketInfo): Promise<{ apy: string, amount: string, amountUsd: string }> {
240
+ const {
241
+ loanToken, collateralToken, oracle, irm, lltv,
242
+ } = selectedMarket;
243
+ const lltvInWei = new Dec(lltv).mul(WAD).toString();
244
+
245
+ const viewContract = MorphoBlueViewContractViem(provider, network);
246
+ const loanInfo = (await viewContract.read.getUserInfo([
247
+ {
248
+ loanToken, collateralToken, oracle, irm, lltv: BigInt(lltvInWei),
249
+ },
250
+ account]));
251
+
252
+ const loanTokenInfo = marketInfo.assetsData[marketInfo.loanToken];
253
+ const loanTokenSupplied = assetAmountInEth(loanInfo.suppliedInAssets.toString(), marketInfo.loanToken);
254
+ const loanTokenSuppliedUsd = new Dec(loanTokenSupplied).mul(loanTokenInfo.price).toString();
255
+ const usedAssets: MMUsedAssets = {
256
+ [marketInfo.loanToken]: {
257
+ symbol: loanTokenInfo.symbol,
258
+ supplied: loanTokenSupplied,
259
+ borrowed: '0',
260
+ isSupplied: new Dec(loanInfo.suppliedInAssets.toString()).gt(0),
261
+ isBorrowed: false,
262
+ collateral: false,
263
+ suppliedUsd: loanTokenSuppliedUsd,
264
+ borrowedUsd: '0',
265
+ },
266
+ };
267
+
268
+ const { netApy } = calculateNetApy({ usedAssets, assetsData: marketInfo.assetsData as unknown as MMAssetsData });
269
+
270
+ return {
271
+ apy: netApy,
272
+ amount: loanTokenSupplied,
273
+ amountUsd: loanTokenSuppliedUsd,
274
+ };
275
275
  }