@defisaver/positions-sdk 2.1.21 → 2.1.22-dev-savings-2

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 (149) hide show
  1. package/.mocharc.json +4 -4
  2. package/.nvmrc +1 -1
  3. package/README.md +64 -64
  4. package/cjs/config/contracts.d.ts +153 -0
  5. package/cjs/config/contracts.js +19 -1
  6. package/cjs/contracts.d.ts +1344 -0
  7. package/cjs/contracts.js +20 -1
  8. package/cjs/helpers/morphoBlueHelpers/index.js +66 -66
  9. package/cjs/index.d.ts +2 -1
  10. package/cjs/index.js +3 -1
  11. package/cjs/markets/morphoBlue/index.d.ts +12 -0
  12. package/cjs/markets/morphoBlue/index.js +106 -2
  13. package/cjs/savings/index.d.ts +6 -0
  14. package/cjs/savings/index.js +71 -0
  15. package/cjs/savings/morphoVaults/index.d.ts +7 -0
  16. package/cjs/savings/morphoVaults/index.js +116 -0
  17. package/cjs/savings/morphoVaults/options.d.ts +16 -0
  18. package/cjs/savings/morphoVaults/options.js +99 -0
  19. package/cjs/savings/yearnVaults/index.d.ts +7 -0
  20. package/cjs/savings/yearnVaults/index.js +95 -0
  21. package/cjs/savings/yearnVaults/options.d.ts +6 -0
  22. package/cjs/savings/yearnVaults/options.js +26 -0
  23. package/cjs/types/index.d.ts +1 -0
  24. package/cjs/types/index.js +1 -0
  25. package/cjs/types/morphoBlue.d.ts +7 -1
  26. package/cjs/types/morphoBlue.js +7 -0
  27. package/cjs/types/savings/index.d.ts +18 -0
  28. package/cjs/types/savings/index.js +18 -0
  29. package/cjs/types/savings/morphoVaults.d.ts +22 -0
  30. package/cjs/types/savings/morphoVaults.js +19 -0
  31. package/cjs/types/savings/yearnVaults.d.ts +11 -0
  32. package/cjs/types/savings/yearnVaults.js +9 -0
  33. package/esm/config/contracts.d.ts +153 -0
  34. package/esm/config/contracts.js +18 -0
  35. package/esm/contracts.d.ts +1344 -0
  36. package/esm/contracts.js +17 -0
  37. package/esm/helpers/morphoBlueHelpers/index.js +66 -66
  38. package/esm/index.d.ts +2 -1
  39. package/esm/index.js +2 -1
  40. package/esm/markets/morphoBlue/index.d.ts +12 -0
  41. package/esm/markets/morphoBlue/index.js +98 -0
  42. package/esm/savings/index.d.ts +6 -0
  43. package/esm/savings/index.js +33 -0
  44. package/esm/savings/morphoVaults/index.d.ts +7 -0
  45. package/esm/savings/morphoVaults/index.js +75 -0
  46. package/esm/savings/morphoVaults/options.d.ts +16 -0
  47. package/esm/savings/morphoVaults/options.js +95 -0
  48. package/esm/savings/yearnVaults/index.d.ts +7 -0
  49. package/esm/savings/yearnVaults/index.js +54 -0
  50. package/esm/savings/yearnVaults/options.d.ts +6 -0
  51. package/esm/savings/yearnVaults/options.js +22 -0
  52. package/esm/types/index.d.ts +1 -0
  53. package/esm/types/index.js +1 -0
  54. package/esm/types/morphoBlue.d.ts +7 -1
  55. package/esm/types/morphoBlue.js +7 -0
  56. package/esm/types/savings/index.d.ts +18 -0
  57. package/esm/types/savings/index.js +2 -0
  58. package/esm/types/savings/morphoVaults.d.ts +22 -0
  59. package/esm/types/savings/morphoVaults.js +16 -0
  60. package/esm/types/savings/yearnVaults.d.ts +11 -0
  61. package/esm/types/savings/yearnVaults.js +6 -0
  62. package/package.json +48 -47
  63. package/src/aaveV2/index.ts +240 -240
  64. package/src/aaveV3/index.ts +614 -614
  65. package/src/aaveV3/merit.ts +97 -97
  66. package/src/aaveV3/merkl.ts +74 -74
  67. package/src/claiming/aaveV3.ts +154 -154
  68. package/src/claiming/compV3.ts +22 -22
  69. package/src/claiming/index.ts +12 -12
  70. package/src/claiming/king.ts +66 -66
  71. package/src/claiming/morphoBlue.ts +118 -118
  72. package/src/claiming/spark.ts +225 -225
  73. package/src/compoundV2/index.ts +244 -244
  74. package/src/compoundV3/index.ts +274 -274
  75. package/src/config/contracts.ts +1273 -1255
  76. package/src/constants/index.ts +10 -10
  77. package/src/contracts.ts +141 -121
  78. package/src/curveUsd/index.ts +254 -254
  79. package/src/eulerV2/index.ts +324 -324
  80. package/src/exchange/index.ts +25 -25
  81. package/src/fluid/index.ts +1774 -1774
  82. package/src/helpers/aaveHelpers/index.ts +187 -187
  83. package/src/helpers/compoundHelpers/index.ts +283 -283
  84. package/src/helpers/curveUsdHelpers/index.ts +40 -40
  85. package/src/helpers/eulerHelpers/index.ts +222 -222
  86. package/src/helpers/fluidHelpers/index.ts +326 -326
  87. package/src/helpers/index.ts +10 -10
  88. package/src/helpers/liquityV2Helpers/index.ts +82 -82
  89. package/src/helpers/llamaLendHelpers/index.ts +53 -53
  90. package/src/helpers/makerHelpers/index.ts +52 -52
  91. package/src/helpers/morphoBlueHelpers/index.ts +396 -396
  92. package/src/helpers/sparkHelpers/index.ts +158 -158
  93. package/src/index.ts +49 -47
  94. package/src/liquity/index.ts +159 -159
  95. package/src/liquityV2/index.ts +703 -703
  96. package/src/llamaLend/index.ts +305 -305
  97. package/src/maker/index.ts +223 -223
  98. package/src/markets/aave/index.ts +116 -116
  99. package/src/markets/aave/marketAssets.ts +54 -54
  100. package/src/markets/compound/index.ts +238 -238
  101. package/src/markets/compound/marketsAssets.ts +97 -97
  102. package/src/markets/curveUsd/index.ts +69 -69
  103. package/src/markets/euler/index.ts +26 -26
  104. package/src/markets/fluid/index.ts +2900 -2900
  105. package/src/markets/index.ts +25 -25
  106. package/src/markets/liquityV2/index.ts +102 -102
  107. package/src/markets/llamaLend/contractAddresses.ts +141 -141
  108. package/src/markets/llamaLend/index.ts +235 -235
  109. package/src/markets/morphoBlue/index.ts +971 -866
  110. package/src/markets/spark/index.ts +29 -29
  111. package/src/markets/spark/marketAssets.ts +12 -12
  112. package/src/moneymarket/moneymarketCommonService.ts +84 -84
  113. package/src/morphoBlue/index.ts +274 -274
  114. package/src/portfolio/index.ts +572 -572
  115. package/src/savings/index.ts +38 -0
  116. package/src/savings/morphoVaults/index.ts +79 -0
  117. package/src/savings/morphoVaults/options.ts +110 -0
  118. package/src/savings/yearnVaults/index.ts +56 -0
  119. package/src/savings/yearnVaults/options.ts +27 -0
  120. package/src/services/priceService.ts +278 -278
  121. package/src/services/utils.ts +115 -115
  122. package/src/services/viem.ts +34 -34
  123. package/src/setup.ts +8 -8
  124. package/src/spark/index.ts +456 -456
  125. package/src/staking/eligibility.ts +53 -53
  126. package/src/staking/index.ts +1 -1
  127. package/src/staking/staking.ts +183 -183
  128. package/src/types/aave.ts +189 -189
  129. package/src/types/claiming.ts +109 -109
  130. package/src/types/common.ts +107 -107
  131. package/src/types/compound.ts +136 -136
  132. package/src/types/curveUsd.ts +123 -123
  133. package/src/types/euler.ts +175 -175
  134. package/src/types/fluid.ts +483 -483
  135. package/src/types/index.ts +15 -14
  136. package/src/types/liquity.ts +30 -30
  137. package/src/types/liquityV2.ts +126 -126
  138. package/src/types/llamaLend.ts +159 -159
  139. package/src/types/maker.ts +63 -63
  140. package/src/types/merit.ts +1 -1
  141. package/src/types/merkl.ts +70 -70
  142. package/src/types/morphoBlue.ts +200 -192
  143. package/src/types/portfolio.ts +60 -60
  144. package/src/types/savings/index.ts +21 -0
  145. package/src/types/savings/morphoVaults.ts +24 -0
  146. package/src/types/savings/yearnVaults.ts +13 -0
  147. package/src/types/spark.ts +133 -133
  148. package/src/umbrella/index.ts +69 -69
  149. 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).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).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
+ };