@defisaver/positions-sdk 2.1.52 → 2.1.53-aave-v4

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 (201) hide show
  1. package/.mocharc.json +4 -4
  2. package/.nvmrc +1 -1
  3. package/README.md +64 -64
  4. package/cjs/aaveV4/index.d.ts +7 -0
  5. package/cjs/aaveV4/index.js +174 -0
  6. package/cjs/config/contracts.d.ts +1277 -0
  7. package/cjs/config/contracts.js +9 -0
  8. package/cjs/contracts.d.ts +23120 -0
  9. package/cjs/contracts.js +2 -1
  10. package/cjs/fluid/index.d.ts +6 -6
  11. package/cjs/helpers/aaveHelpers/index.d.ts +2 -2
  12. package/cjs/helpers/aaveHelpers/index.js +16 -5
  13. package/cjs/helpers/aaveV4Helpers/index.d.ts +13 -0
  14. package/cjs/helpers/aaveV4Helpers/index.js +117 -0
  15. package/cjs/helpers/compoundHelpers/index.js +15 -18
  16. package/cjs/helpers/eulerHelpers/index.d.ts +2 -2
  17. package/cjs/helpers/eulerHelpers/index.js +21 -13
  18. package/cjs/helpers/fluidHelpers/index.js +16 -5
  19. package/cjs/helpers/index.d.ts +1 -0
  20. package/cjs/helpers/index.js +2 -1
  21. package/cjs/helpers/morphoBlueHelpers/index.js +81 -71
  22. package/cjs/helpers/sparkHelpers/index.d.ts +2 -2
  23. package/cjs/helpers/sparkHelpers/index.js +15 -5
  24. package/cjs/index.d.ts +2 -1
  25. package/cjs/index.js +3 -1
  26. package/cjs/markets/aaveV4/index.d.ts +13 -0
  27. package/cjs/markets/aaveV4/index.js +39 -0
  28. package/cjs/markets/index.d.ts +1 -0
  29. package/cjs/markets/index.js +3 -1
  30. package/cjs/moneymarket/moneymarketCommonService.d.ts +3 -3
  31. package/cjs/moneymarket/moneymarketCommonService.js +9 -9
  32. package/cjs/portfolio/index.js +20 -0
  33. package/cjs/savings/morphoVaults/index.js +17 -17
  34. package/cjs/types/aave.d.ts +3 -3
  35. package/cjs/types/aaveV4.d.ts +137 -0
  36. package/cjs/types/aaveV4.js +11 -0
  37. package/cjs/types/common.d.ts +7 -0
  38. package/cjs/types/common.js +9 -1
  39. package/cjs/types/compound.d.ts +3 -3
  40. package/cjs/types/curveUsd.d.ts +2 -2
  41. package/cjs/types/euler.d.ts +3 -3
  42. package/cjs/types/fluid.d.ts +3 -3
  43. package/cjs/types/index.d.ts +2 -0
  44. package/cjs/types/index.js +2 -0
  45. package/cjs/types/liquityV2.d.ts +3 -3
  46. package/cjs/types/llamaLend.d.ts +2 -2
  47. package/cjs/types/morphoBlue.d.ts +5 -5
  48. package/cjs/types/portfolio.d.ts +4 -0
  49. package/cjs/types/spark.d.ts +3 -3
  50. package/esm/aaveV4/index.d.ts +7 -0
  51. package/esm/aaveV4/index.js +165 -0
  52. package/esm/config/contracts.d.ts +1277 -0
  53. package/esm/config/contracts.js +8 -0
  54. package/esm/contracts.d.ts +23120 -0
  55. package/esm/contracts.js +1 -0
  56. package/esm/fluid/index.d.ts +6 -6
  57. package/esm/helpers/aaveHelpers/index.d.ts +2 -2
  58. package/esm/helpers/aaveHelpers/index.js +16 -5
  59. package/esm/helpers/aaveV4Helpers/index.d.ts +13 -0
  60. package/esm/helpers/aaveV4Helpers/index.js +108 -0
  61. package/esm/helpers/compoundHelpers/index.js +16 -19
  62. package/esm/helpers/eulerHelpers/index.d.ts +2 -2
  63. package/esm/helpers/eulerHelpers/index.js +21 -13
  64. package/esm/helpers/fluidHelpers/index.js +16 -5
  65. package/esm/helpers/index.d.ts +1 -0
  66. package/esm/helpers/index.js +1 -0
  67. package/esm/helpers/morphoBlueHelpers/index.js +82 -72
  68. package/esm/helpers/sparkHelpers/index.d.ts +2 -2
  69. package/esm/helpers/sparkHelpers/index.js +16 -6
  70. package/esm/index.d.ts +2 -1
  71. package/esm/index.js +2 -1
  72. package/esm/markets/aaveV4/index.d.ts +13 -0
  73. package/esm/markets/aaveV4/index.js +29 -0
  74. package/esm/markets/index.d.ts +1 -0
  75. package/esm/markets/index.js +1 -0
  76. package/esm/moneymarket/moneymarketCommonService.d.ts +3 -3
  77. package/esm/moneymarket/moneymarketCommonService.js +9 -9
  78. package/esm/portfolio/index.js +21 -1
  79. package/esm/savings/morphoVaults/index.js +17 -17
  80. package/esm/types/aave.d.ts +3 -3
  81. package/esm/types/aaveV4.d.ts +137 -0
  82. package/esm/types/aaveV4.js +8 -0
  83. package/esm/types/common.d.ts +7 -0
  84. package/esm/types/common.js +8 -0
  85. package/esm/types/compound.d.ts +3 -3
  86. package/esm/types/curveUsd.d.ts +2 -2
  87. package/esm/types/euler.d.ts +3 -3
  88. package/esm/types/fluid.d.ts +3 -3
  89. package/esm/types/fluid.js +1 -1
  90. package/esm/types/index.d.ts +2 -0
  91. package/esm/types/index.js +2 -0
  92. package/esm/types/liquityV2.d.ts +3 -3
  93. package/esm/types/llamaLend.d.ts +2 -2
  94. package/esm/types/morphoBlue.d.ts +5 -5
  95. package/esm/types/portfolio.d.ts +4 -0
  96. package/esm/types/spark.d.ts +3 -3
  97. package/package.json +48 -48
  98. package/src/aaveV2/index.ts +240 -240
  99. package/src/aaveV3/index.ts +635 -635
  100. package/src/aaveV3/merit.ts +97 -97
  101. package/src/aaveV3/merkl.ts +74 -74
  102. package/src/aaveV4/index.ts +176 -0
  103. package/src/claiming/aaveV3.ts +154 -154
  104. package/src/claiming/compV3.ts +22 -22
  105. package/src/claiming/ethena.ts +61 -61
  106. package/src/claiming/index.ts +12 -12
  107. package/src/claiming/king.ts +66 -66
  108. package/src/claiming/morphoBlue.ts +118 -118
  109. package/src/claiming/spark.ts +225 -225
  110. package/src/compoundV2/index.ts +244 -244
  111. package/src/compoundV3/index.ts +274 -274
  112. package/src/config/contracts.ts +1328 -1320
  113. package/src/constants/index.ts +10 -10
  114. package/src/contracts.ts +174 -172
  115. package/src/curveUsd/index.ts +254 -254
  116. package/src/eulerV2/index.ts +324 -324
  117. package/src/exchange/index.ts +25 -25
  118. package/src/fluid/index.ts +1800 -1800
  119. package/src/helpers/aaveHelpers/index.ts +202 -191
  120. package/src/helpers/aaveV4Helpers/index.ts +128 -0
  121. package/src/helpers/compoundHelpers/index.ts +276 -283
  122. package/src/helpers/curveUsdHelpers/index.ts +40 -40
  123. package/src/helpers/eulerHelpers/index.ts +229 -222
  124. package/src/helpers/fluidHelpers/index.ts +335 -326
  125. package/src/helpers/index.ts +11 -10
  126. package/src/helpers/liquityV2Helpers/index.ts +82 -82
  127. package/src/helpers/llamaLendHelpers/index.ts +53 -53
  128. package/src/helpers/makerHelpers/index.ts +52 -52
  129. package/src/helpers/morphoBlueHelpers/index.ts +405 -396
  130. package/src/helpers/sparkHelpers/index.ts +169 -158
  131. package/src/index.ts +51 -49
  132. package/src/liquity/index.ts +159 -159
  133. package/src/liquityV2/index.ts +703 -703
  134. package/src/llamaLend/index.ts +305 -305
  135. package/src/maker/index.ts +223 -223
  136. package/src/markets/aave/index.ts +118 -118
  137. package/src/markets/aave/marketAssets.ts +54 -54
  138. package/src/markets/aaveV4/index.ts +42 -0
  139. package/src/markets/compound/index.ts +243 -243
  140. package/src/markets/compound/marketsAssets.ts +97 -97
  141. package/src/markets/curveUsd/index.ts +69 -69
  142. package/src/markets/euler/index.ts +26 -26
  143. package/src/markets/fluid/index.ts +2900 -2900
  144. package/src/markets/index.ts +26 -25
  145. package/src/markets/liquityV2/index.ts +102 -102
  146. package/src/markets/llamaLend/contractAddresses.ts +141 -141
  147. package/src/markets/llamaLend/index.ts +235 -235
  148. package/src/markets/morphoBlue/index.ts +988 -988
  149. package/src/markets/spark/index.ts +29 -29
  150. package/src/markets/spark/marketAssets.ts +12 -12
  151. package/src/moneymarket/moneymarketCommonService.ts +84 -85
  152. package/src/morphoBlue/index.ts +274 -274
  153. package/src/portfolio/index.ts +606 -586
  154. package/src/savings/index.ts +95 -95
  155. package/src/savings/makerDsr/index.ts +53 -53
  156. package/src/savings/makerDsr/options.ts +9 -9
  157. package/src/savings/morphoVaults/index.ts +80 -80
  158. package/src/savings/morphoVaults/options.ts +193 -193
  159. package/src/savings/skyOptions/index.ts +95 -95
  160. package/src/savings/skyOptions/options.ts +10 -10
  161. package/src/savings/sparkSavingsVaults/index.ts +60 -60
  162. package/src/savings/sparkSavingsVaults/options.ts +35 -35
  163. package/src/savings/yearnV3Vaults/index.ts +61 -61
  164. package/src/savings/yearnV3Vaults/options.ts +55 -55
  165. package/src/savings/yearnVaults/index.ts +73 -73
  166. package/src/savings/yearnVaults/options.ts +32 -32
  167. package/src/services/priceService.ts +278 -278
  168. package/src/services/utils.ts +115 -115
  169. package/src/services/viem.ts +57 -57
  170. package/src/setup.ts +8 -8
  171. package/src/spark/index.ts +459 -459
  172. package/src/staking/eligibility.ts +53 -53
  173. package/src/staking/index.ts +1 -1
  174. package/src/staking/staking.ts +192 -192
  175. package/src/types/aave.ts +199 -198
  176. package/src/types/aaveV4.ts +153 -0
  177. package/src/types/claiming.ts +114 -114
  178. package/src/types/common.ts +115 -107
  179. package/src/types/compound.ts +145 -144
  180. package/src/types/curveUsd.ts +123 -123
  181. package/src/types/euler.ts +176 -175
  182. package/src/types/fluid.ts +485 -483
  183. package/src/types/index.ts +17 -15
  184. package/src/types/liquity.ts +30 -30
  185. package/src/types/liquityV2.ts +128 -126
  186. package/src/types/llamaLend.ts +161 -159
  187. package/src/types/maker.ts +63 -63
  188. package/src/types/merit.ts +1 -1
  189. package/src/types/merkl.ts +70 -70
  190. package/src/types/morphoBlue.ts +202 -202
  191. package/src/types/portfolio.ts +64 -60
  192. package/src/types/savings/index.ts +23 -23
  193. package/src/types/savings/makerDsr.ts +13 -13
  194. package/src/types/savings/morphoVaults.ts +32 -32
  195. package/src/types/savings/sky.ts +14 -14
  196. package/src/types/savings/sparkSavingsVaults.ts +15 -15
  197. package/src/types/savings/yearnV3Vaults.ts +17 -17
  198. package/src/types/savings/yearnVaults.ts +14 -14
  199. package/src/types/spark.ts +135 -134
  200. package/src/umbrella/index.ts +69 -69
  201. package/src/umbrella/umbrellaUtils.ts +29 -29
@@ -1,244 +1,244 @@
1
- import { assetAmountInEth, getAssetInfo, getAssetInfoByAddress } from '@defisaver/tokens';
2
- import Dec from 'decimal.js';
3
- import { Client } from 'viem';
4
- import { BLOCKS_IN_A_YEAR } from '../constants';
5
- import { aprToApy } from '../moneymarket';
6
- import { compareAddresses, handleWbtcLegacy, wethToEth } from '../services/utils';
7
- import {
8
- Blockish, EthAddress, EthereumProvider, IncentiveKind, NetworkNumber, PositionBalances,
9
- } from '../types/common';
10
- import { CompoundLoanInfoContractViem, ComptrollerContractViem } from '../contracts';
11
- import { compoundV2CollateralAssets } from '../markets';
12
- import {
13
- CompoundV2AssetsData, CompoundV2MarketsData, CompoundV2PositionData, CompoundV2UsedAsset, CompoundV2UsedAssets,
14
- } from '../types';
15
- import { getCompoundV2AggregatedData } from '../helpers/compoundHelpers';
16
- import { getViemProvider, setViemBlockNumber } from '../services/viem';
17
-
18
- const compAddress = '0xc00e94cb662c3520282e6f5717214004a7f26888';
19
-
20
- export const _getCompoundV2MarketsData = async (provider: Client, network: NetworkNumber): Promise<CompoundV2MarketsData> => {
21
- const cAddresses = compoundV2CollateralAssets.map(a => a.address);
22
-
23
- const loanInfoContract = CompoundLoanInfoContractViem(provider, network);
24
- const loanInfo = await loanInfoContract.read.getFullTokensInfo([cAddresses as EthAddress[]]);
25
-
26
- const compPrice = loanInfo.find(m => compareAddresses(m.underlyingTokenAddress, compAddress))!.price.toString();
27
-
28
- const assetsData = loanInfo
29
- .map((market, i) => {
30
- let symbol = getAssetInfoByAddress(cAddresses[i]).underlyingAsset;
31
- let isWbtcLegacy = false;
32
- const totalSupply = new Dec(market.totalSupply.toString()).div(1e18).times(market.exchangeRate.toString());
33
- const totalBorrow = market.totalBorrow.toString();
34
- const borrowCap = market.borrowCap.toString();
35
- const compSupplySpeeds = market.compSupplySpeeds.toString();
36
- const compBorrowSpeeds = market.compBorrowSpeeds.toString();
37
- const assetPrice = market.price.toString();
38
-
39
- const pricePrecisionDiff = 18 - getAssetInfo(getAssetInfoByAddress(cAddresses[i]).underlyingAsset).decimals;
40
-
41
- if (cAddresses[i].toLowerCase() === '0xc11b1268c1a384e55c48c2391d8d480264a3a7f4'.toLowerCase()) {
42
- symbol = 'WBTC Legacy';
43
- isWbtcLegacy = true;
44
- }
45
- return {
46
- symbol,
47
- underlyingTokenAddress: market.underlyingTokenAddress,
48
- supplyRate: aprToApy(new Dec(BLOCKS_IN_A_YEAR).times(market.supplyRate.toString()).div(1e16).toString()).toString(),
49
- borrowRate: aprToApy(new Dec(BLOCKS_IN_A_YEAR).times(market.borrowRate.toString()).div(1e16).toString()).toString(),
50
- supplyIncentives: [{
51
- token: 'COMP',
52
- apy: aprToApy((100 * BLOCKS_IN_A_YEAR * +compSupplySpeeds * +compPrice) / +assetPrice / +totalSupply).toString(),
53
- incentiveKind: IncentiveKind.Reward,
54
- description: 'Eligible for protocol-level COMP incentives.',
55
- }],
56
- borrowIncentives: [{
57
- token: 'COMP',
58
- apy: aprToApy((100 * BLOCKS_IN_A_YEAR * +compBorrowSpeeds * +compPrice) / +assetPrice / +totalBorrow).toString(),
59
- incentiveKind: IncentiveKind.Reward,
60
- description: 'Eligible for protocol-level COMP incentives.',
61
- }],
62
- collateralFactor: new Dec(market.collateralFactor.toString()).div(1e18).toString(),
63
- marketLiquidity: assetAmountInEth(market.marketLiquidity.toString(), handleWbtcLegacy(symbol)),
64
- utilization: new Dec(market.totalBorrow.toString()).div(totalSupply).times(100).toString(),
65
- totalSupply: assetAmountInEth(totalSupply, handleWbtcLegacy(symbol)),
66
- totalBorrow: assetAmountInEth(totalBorrow, handleWbtcLegacy(symbol)),
67
- exchangeRate: new Dec(market.exchangeRate.toString()).div(1e28).mul(10 ** pricePrecisionDiff).toString(),
68
- borrowCap: assetAmountInEth(borrowCap, handleWbtcLegacy(symbol)),
69
- canBeBorrowed: market.canBorrow,
70
- canBeSupplied: market.canMint,
71
- price: new Dec(market.price.toString()).div(10 ** (18 + pricePrecisionDiff)).toString(),
72
- };
73
- });
74
-
75
- const payload = {} as CompoundV2AssetsData;
76
- // Sort by market size
77
- assetsData
78
- .sort((a, b) => {
79
- const aMarket = new Dec(a.price).times(a.totalSupply).toString();
80
- const bMarket = new Dec(b.price).times(b.totalSupply).toString();
81
-
82
- return new Dec(bMarket).minus(aMarket).toNumber();
83
- })
84
- .forEach((market, i) => { payload[market.symbol] = { ...market, sortIndex: i }; });
85
-
86
- return { assetsData: payload };
87
- };
88
-
89
- export const getCompoundV2MarketsData = async (provider: EthereumProvider, network: NetworkNumber): Promise<CompoundV2MarketsData> => _getCompoundV2MarketsData(getViemProvider(provider, network), network);
90
-
91
- export const EMPTY_COMPOUND_DATA = {
92
- usedAssets: {},
93
- suppliedUsd: '0',
94
- borrowedUsd: '0',
95
- borrowLimitUsd: '0',
96
- leftToBorrowUsd: '0',
97
- ratio: '0',
98
- minRatio: '0',
99
- netApy: '0',
100
- incentiveUsd: '0',
101
- totalInterestUsd: '0',
102
- borrowStableSupplyUnstable: false,
103
- };
104
-
105
- const getCollateralAssetsAddresses = async (provider: Client, network: NetworkNumber, account: EthAddress) => {
106
- const contract = ComptrollerContractViem(provider, network);
107
-
108
- return contract.read.getAssetsIn([account]);
109
- };
110
-
111
- const getAllMarketAddresses = async (provider: Client, network: NetworkNumber, block: Blockish) => {
112
- const contract = ComptrollerContractViem(provider, network);
113
-
114
- return contract.read.getAllMarkets(setViemBlockNumber(block));
115
- };
116
-
117
-
118
- export const _getCompoundV2AccountBalances = async (provider: Client, network: NetworkNumber, block: Blockish, addressMapping: boolean, address: EthAddress): Promise<PositionBalances> => {
119
- let balances: PositionBalances = {
120
- collateral: {},
121
- debt: {},
122
- };
123
-
124
- if (!address) {
125
- return balances;
126
- }
127
-
128
- const assets = await getAllMarketAddresses(provider, network, block);
129
- const assetInfo = assets.map(a => getAssetInfoByAddress(a, network));
130
- const loanInfoContract = CompoundLoanInfoContractViem(provider, network, block);
131
- const loanInfo = await loanInfoContract.read.getTokenBalances([address, assets], setViemBlockNumber(block));
132
-
133
- loanInfo[0].forEach((weiAmount: any, i: number) => {
134
- const asset = wethToEth(
135
- assetInfo[i].symbol === 'cWBTC Legacy'
136
- ? `${assetInfo[i].underlyingAsset} Legacy`
137
- : assetInfo[i].underlyingAsset,
138
- );
139
-
140
- balances = {
141
- collateral: {
142
- ...balances.collateral,
143
- [addressMapping ? getAssetInfo(asset, network).address.toLowerCase() : asset]: weiAmount.toString(),
144
- },
145
- };
146
- });
147
- loanInfo[1].forEach((weiAmount: any, i: number) => {
148
- const asset = wethToEth(
149
- assetInfo[i].symbol === 'cWBTC Legacy'
150
- ? `${assetInfo[i].underlyingAsset} Legacy`
151
- : assetInfo[i].underlyingAsset,
152
- );
153
-
154
- balances = {
155
- ...balances,
156
- debt: {
157
- ...balances.debt,
158
- [addressMapping ? getAssetInfo(asset, network).address.toLowerCase() : asset]: weiAmount.toString(),
159
- },
160
- };
161
- });
162
-
163
- return balances;
164
- };
165
-
166
- export const getCompoundV2AccountBalances = async (
167
- provider: EthereumProvider,
168
- network: NetworkNumber,
169
- block: Blockish,
170
- addressMapping: boolean,
171
- address: EthAddress,
172
- ): Promise<PositionBalances> => _getCompoundV2AccountBalances(getViemProvider(provider, network), network, block, addressMapping, address);
173
-
174
- export const _getCompoundV2AccountData = async (provider: Client, network: NetworkNumber, address: EthAddress, assetsData: CompoundV2AssetsData): Promise<CompoundV2PositionData> => {
175
- if (!address) throw new Error('No address provided');
176
-
177
- let payload = { ...EMPTY_COMPOUND_DATA, lastUpdated: Date.now() };
178
-
179
- const loanInfoContract = CompoundLoanInfoContractViem(provider, network);
180
- const [loanInfo, collateralAssetsAddresses] = await Promise.all([
181
- loanInfoContract.read.getTokenBalances([address, compoundV2CollateralAssets.map(a => a.address) as EthAddress[]]),
182
- getCollateralAssetsAddresses(provider, network, address),
183
- ]);
184
-
185
- const usedAssets = {} as CompoundV2UsedAssets;
186
-
187
- loanInfo[0].forEach((weiAmount: BigInt, i: number) => {
188
- const asset = compoundV2CollateralAssets[i].symbol === 'cWBTC Legacy'
189
- ? `${compoundV2CollateralAssets[i].underlyingAsset} Legacy`
190
- : compoundV2CollateralAssets[i].underlyingAsset;
191
- const amount = assetAmountInEth(weiAmount.toString(), asset);
192
- const collateral = !!collateralAssetsAddresses.find(a => compareAddresses(a, compoundV2CollateralAssets[i].address));
193
- if (weiAmount.toString() === '0' && !collateral) return;
194
- if (!usedAssets[asset]) usedAssets[asset] = {} as CompoundV2UsedAsset;
195
- usedAssets[asset] = {
196
- ...usedAssets[asset],
197
- symbol: asset,
198
- supplied: amount,
199
- suppliedUsd: new Dec(amount).mul(assetsData[handleWbtcLegacy(asset)].price).toString(),
200
- isSupplied: +amount > 0,
201
- collateral,
202
- };
203
- });
204
-
205
- loanInfo[1].forEach((weiAmount, i) => {
206
- if (weiAmount.toString() === '0') return;
207
- const asset = compoundV2CollateralAssets[i].symbol === 'cWBTC Legacy'
208
- ? `${compoundV2CollateralAssets[i].underlyingAsset} Legacy`
209
- : compoundV2CollateralAssets[i].underlyingAsset;
210
- const amount = assetAmountInEth(weiAmount.toString(), asset);
211
- if (!usedAssets[asset]) usedAssets[asset] = {} as CompoundV2UsedAsset;
212
- usedAssets[asset] = {
213
- ...usedAssets[asset],
214
- symbol: asset,
215
- borrowed: amount,
216
- borrowedUsd: new Dec(amount).mul(assetsData[handleWbtcLegacy(asset)].price).toString(),
217
- isBorrowed: true,
218
- collateral: !!usedAssets[asset].collateral,
219
- };
220
- });
221
-
222
- payload = {
223
- ...payload,
224
- usedAssets,
225
- ...getCompoundV2AggregatedData({
226
- usedAssets, assetsData,
227
- }),
228
- };
229
-
230
- return payload;
231
- };
232
-
233
- export const getCompoundV2AccountData = async (
234
- provider: EthereumProvider,
235
- network: NetworkNumber,
236
- address: EthAddress,
237
- assetsData: CompoundV2AssetsData,
238
- ): Promise<CompoundV2PositionData> => _getCompoundV2AccountData(getViemProvider(provider, network), network, address, assetsData);
239
-
240
- export const getCompoundV2FullPositionData = async (provider: EthereumProvider, network: NetworkNumber, address: EthAddress): Promise<CompoundV2PositionData> => {
241
- const marketData = await getCompoundV2MarketsData(provider, network);
242
- const positionData = await getCompoundV2AccountData(provider, network, address, marketData.assetsData);
243
- return positionData;
244
- };
1
+ import { assetAmountInEth, getAssetInfo, getAssetInfoByAddress } from '@defisaver/tokens';
2
+ import Dec from 'decimal.js';
3
+ import { Client } from 'viem';
4
+ import { BLOCKS_IN_A_YEAR } from '../constants';
5
+ import { aprToApy } from '../moneymarket';
6
+ import { compareAddresses, handleWbtcLegacy, wethToEth } from '../services/utils';
7
+ import {
8
+ Blockish, EthAddress, EthereumProvider, IncentiveKind, NetworkNumber, PositionBalances,
9
+ } from '../types/common';
10
+ import { CompoundLoanInfoContractViem, ComptrollerContractViem } from '../contracts';
11
+ import { compoundV2CollateralAssets } from '../markets';
12
+ import {
13
+ CompoundV2AssetsData, CompoundV2MarketsData, CompoundV2PositionData, CompoundV2UsedAsset, CompoundV2UsedAssets,
14
+ } from '../types';
15
+ import { getCompoundV2AggregatedData } from '../helpers/compoundHelpers';
16
+ import { getViemProvider, setViemBlockNumber } from '../services/viem';
17
+
18
+ const compAddress = '0xc00e94cb662c3520282e6f5717214004a7f26888';
19
+
20
+ export const _getCompoundV2MarketsData = async (provider: Client, network: NetworkNumber): Promise<CompoundV2MarketsData> => {
21
+ const cAddresses = compoundV2CollateralAssets.map(a => a.address);
22
+
23
+ const loanInfoContract = CompoundLoanInfoContractViem(provider, network);
24
+ const loanInfo = await loanInfoContract.read.getFullTokensInfo([cAddresses as EthAddress[]]);
25
+
26
+ const compPrice = loanInfo.find(m => compareAddresses(m.underlyingTokenAddress, compAddress))!.price.toString();
27
+
28
+ const assetsData = loanInfo
29
+ .map((market, i) => {
30
+ let symbol = getAssetInfoByAddress(cAddresses[i]).underlyingAsset;
31
+ let isWbtcLegacy = false;
32
+ const totalSupply = new Dec(market.totalSupply.toString()).div(1e18).times(market.exchangeRate.toString());
33
+ const totalBorrow = market.totalBorrow.toString();
34
+ const borrowCap = market.borrowCap.toString();
35
+ const compSupplySpeeds = market.compSupplySpeeds.toString();
36
+ const compBorrowSpeeds = market.compBorrowSpeeds.toString();
37
+ const assetPrice = market.price.toString();
38
+
39
+ const pricePrecisionDiff = 18 - getAssetInfo(getAssetInfoByAddress(cAddresses[i]).underlyingAsset).decimals;
40
+
41
+ if (cAddresses[i].toLowerCase() === '0xc11b1268c1a384e55c48c2391d8d480264a3a7f4'.toLowerCase()) {
42
+ symbol = 'WBTC Legacy';
43
+ isWbtcLegacy = true;
44
+ }
45
+ return {
46
+ symbol,
47
+ underlyingTokenAddress: market.underlyingTokenAddress,
48
+ supplyRate: aprToApy(new Dec(BLOCKS_IN_A_YEAR).times(market.supplyRate.toString()).div(1e16).toString()).toString(),
49
+ borrowRate: aprToApy(new Dec(BLOCKS_IN_A_YEAR).times(market.borrowRate.toString()).div(1e16).toString()).toString(),
50
+ supplyIncentives: [{
51
+ token: 'COMP',
52
+ apy: aprToApy((100 * BLOCKS_IN_A_YEAR * +compSupplySpeeds * +compPrice) / +assetPrice / +totalSupply).toString(),
53
+ incentiveKind: IncentiveKind.Reward,
54
+ description: 'Eligible for protocol-level COMP incentives.',
55
+ }],
56
+ borrowIncentives: [{
57
+ token: 'COMP',
58
+ apy: aprToApy((100 * BLOCKS_IN_A_YEAR * +compBorrowSpeeds * +compPrice) / +assetPrice / +totalBorrow).toString(),
59
+ incentiveKind: IncentiveKind.Reward,
60
+ description: 'Eligible for protocol-level COMP incentives.',
61
+ }],
62
+ collateralFactor: new Dec(market.collateralFactor.toString()).div(1e18).toString(),
63
+ marketLiquidity: assetAmountInEth(market.marketLiquidity.toString(), handleWbtcLegacy(symbol)),
64
+ utilization: new Dec(market.totalBorrow.toString()).div(totalSupply).times(100).toString(),
65
+ totalSupply: assetAmountInEth(totalSupply, handleWbtcLegacy(symbol)),
66
+ totalBorrow: assetAmountInEth(totalBorrow, handleWbtcLegacy(symbol)),
67
+ exchangeRate: new Dec(market.exchangeRate.toString()).div(1e28).mul(10 ** pricePrecisionDiff).toString(),
68
+ borrowCap: assetAmountInEth(borrowCap, handleWbtcLegacy(symbol)),
69
+ canBeBorrowed: market.canBorrow,
70
+ canBeSupplied: market.canMint,
71
+ price: new Dec(market.price.toString()).div(10 ** (18 + pricePrecisionDiff)).toString(),
72
+ };
73
+ });
74
+
75
+ const payload = {} as CompoundV2AssetsData;
76
+ // Sort by market size
77
+ assetsData
78
+ .sort((a, b) => {
79
+ const aMarket = new Dec(a.price).times(a.totalSupply).toString();
80
+ const bMarket = new Dec(b.price).times(b.totalSupply).toString();
81
+
82
+ return new Dec(bMarket).minus(aMarket).toNumber();
83
+ })
84
+ .forEach((market, i) => { payload[market.symbol] = { ...market, sortIndex: i }; });
85
+
86
+ return { assetsData: payload };
87
+ };
88
+
89
+ export const getCompoundV2MarketsData = async (provider: EthereumProvider, network: NetworkNumber): Promise<CompoundV2MarketsData> => _getCompoundV2MarketsData(getViemProvider(provider, network), network);
90
+
91
+ export const EMPTY_COMPOUND_DATA = {
92
+ usedAssets: {},
93
+ suppliedUsd: '0',
94
+ borrowedUsd: '0',
95
+ borrowLimitUsd: '0',
96
+ leftToBorrowUsd: '0',
97
+ ratio: '0',
98
+ minRatio: '0',
99
+ netApy: '0',
100
+ incentiveUsd: '0',
101
+ totalInterestUsd: '0',
102
+ borrowStableSupplyUnstable: false,
103
+ };
104
+
105
+ const getCollateralAssetsAddresses = async (provider: Client, network: NetworkNumber, account: EthAddress) => {
106
+ const contract = ComptrollerContractViem(provider, network);
107
+
108
+ return contract.read.getAssetsIn([account]);
109
+ };
110
+
111
+ const getAllMarketAddresses = async (provider: Client, network: NetworkNumber, block: Blockish) => {
112
+ const contract = ComptrollerContractViem(provider, network);
113
+
114
+ return contract.read.getAllMarkets(setViemBlockNumber(block));
115
+ };
116
+
117
+
118
+ export const _getCompoundV2AccountBalances = async (provider: Client, network: NetworkNumber, block: Blockish, addressMapping: boolean, address: EthAddress): Promise<PositionBalances> => {
119
+ let balances: PositionBalances = {
120
+ collateral: {},
121
+ debt: {},
122
+ };
123
+
124
+ if (!address) {
125
+ return balances;
126
+ }
127
+
128
+ const assets = await getAllMarketAddresses(provider, network, block);
129
+ const assetInfo = assets.map(a => getAssetInfoByAddress(a, network));
130
+ const loanInfoContract = CompoundLoanInfoContractViem(provider, network, block);
131
+ const loanInfo = await loanInfoContract.read.getTokenBalances([address, assets], setViemBlockNumber(block));
132
+
133
+ loanInfo[0].forEach((weiAmount: any, i: number) => {
134
+ const asset = wethToEth(
135
+ assetInfo[i].symbol === 'cWBTC Legacy'
136
+ ? `${assetInfo[i].underlyingAsset} Legacy`
137
+ : assetInfo[i].underlyingAsset,
138
+ );
139
+
140
+ balances = {
141
+ collateral: {
142
+ ...balances.collateral,
143
+ [addressMapping ? getAssetInfo(asset, network).address.toLowerCase() : asset]: weiAmount.toString(),
144
+ },
145
+ };
146
+ });
147
+ loanInfo[1].forEach((weiAmount: any, i: number) => {
148
+ const asset = wethToEth(
149
+ assetInfo[i].symbol === 'cWBTC Legacy'
150
+ ? `${assetInfo[i].underlyingAsset} Legacy`
151
+ : assetInfo[i].underlyingAsset,
152
+ );
153
+
154
+ balances = {
155
+ ...balances,
156
+ debt: {
157
+ ...balances.debt,
158
+ [addressMapping ? getAssetInfo(asset, network).address.toLowerCase() : asset]: weiAmount.toString(),
159
+ },
160
+ };
161
+ });
162
+
163
+ return balances;
164
+ };
165
+
166
+ export const getCompoundV2AccountBalances = async (
167
+ provider: EthereumProvider,
168
+ network: NetworkNumber,
169
+ block: Blockish,
170
+ addressMapping: boolean,
171
+ address: EthAddress,
172
+ ): Promise<PositionBalances> => _getCompoundV2AccountBalances(getViemProvider(provider, network), network, block, addressMapping, address);
173
+
174
+ export const _getCompoundV2AccountData = async (provider: Client, network: NetworkNumber, address: EthAddress, assetsData: CompoundV2AssetsData): Promise<CompoundV2PositionData> => {
175
+ if (!address) throw new Error('No address provided');
176
+
177
+ let payload = { ...EMPTY_COMPOUND_DATA, lastUpdated: Date.now() };
178
+
179
+ const loanInfoContract = CompoundLoanInfoContractViem(provider, network);
180
+ const [loanInfo, collateralAssetsAddresses] = await Promise.all([
181
+ loanInfoContract.read.getTokenBalances([address, compoundV2CollateralAssets.map(a => a.address) as EthAddress[]]),
182
+ getCollateralAssetsAddresses(provider, network, address),
183
+ ]);
184
+
185
+ const usedAssets = {} as CompoundV2UsedAssets;
186
+
187
+ loanInfo[0].forEach((weiAmount: BigInt, i: number) => {
188
+ const asset = compoundV2CollateralAssets[i].symbol === 'cWBTC Legacy'
189
+ ? `${compoundV2CollateralAssets[i].underlyingAsset} Legacy`
190
+ : compoundV2CollateralAssets[i].underlyingAsset;
191
+ const amount = assetAmountInEth(weiAmount.toString(), asset);
192
+ const collateral = !!collateralAssetsAddresses.find(a => compareAddresses(a, compoundV2CollateralAssets[i].address));
193
+ if (weiAmount.toString() === '0' && !collateral) return;
194
+ if (!usedAssets[asset]) usedAssets[asset] = {} as CompoundV2UsedAsset;
195
+ usedAssets[asset] = {
196
+ ...usedAssets[asset],
197
+ symbol: asset,
198
+ supplied: amount,
199
+ suppliedUsd: new Dec(amount).mul(assetsData[handleWbtcLegacy(asset)].price).toString(),
200
+ isSupplied: +amount > 0,
201
+ collateral,
202
+ };
203
+ });
204
+
205
+ loanInfo[1].forEach((weiAmount, i) => {
206
+ if (weiAmount.toString() === '0') return;
207
+ const asset = compoundV2CollateralAssets[i].symbol === 'cWBTC Legacy'
208
+ ? `${compoundV2CollateralAssets[i].underlyingAsset} Legacy`
209
+ : compoundV2CollateralAssets[i].underlyingAsset;
210
+ const amount = assetAmountInEth(weiAmount.toString(), asset);
211
+ if (!usedAssets[asset]) usedAssets[asset] = {} as CompoundV2UsedAsset;
212
+ usedAssets[asset] = {
213
+ ...usedAssets[asset],
214
+ symbol: asset,
215
+ borrowed: amount,
216
+ borrowedUsd: new Dec(amount).mul(assetsData[handleWbtcLegacy(asset)].price).toString(),
217
+ isBorrowed: true,
218
+ collateral: !!usedAssets[asset].collateral,
219
+ };
220
+ });
221
+
222
+ payload = {
223
+ ...payload,
224
+ usedAssets,
225
+ ...getCompoundV2AggregatedData({
226
+ usedAssets, assetsData,
227
+ }),
228
+ };
229
+
230
+ return payload;
231
+ };
232
+
233
+ export const getCompoundV2AccountData = async (
234
+ provider: EthereumProvider,
235
+ network: NetworkNumber,
236
+ address: EthAddress,
237
+ assetsData: CompoundV2AssetsData,
238
+ ): Promise<CompoundV2PositionData> => _getCompoundV2AccountData(getViemProvider(provider, network), network, address, assetsData);
239
+
240
+ export const getCompoundV2FullPositionData = async (provider: EthereumProvider, network: NetworkNumber, address: EthAddress): Promise<CompoundV2PositionData> => {
241
+ const marketData = await getCompoundV2MarketsData(provider, network);
242
+ const positionData = await getCompoundV2AccountData(provider, network, address, marketData.assetsData);
243
+ return positionData;
244
+ };