@defisaver/positions-sdk 2.1.11 → 2.1.13-dev-plasma-fluid

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 (114) hide show
  1. package/.mocharc.json +4 -4
  2. package/.nvmrc +1 -1
  3. package/CLAUDE.md +32 -0
  4. package/README.md +64 -64
  5. package/cjs/aaveV3/index.js +1 -1
  6. package/cjs/config/contracts.d.ts +12 -0
  7. package/cjs/config/contracts.js +7 -3
  8. package/cjs/contracts.d.ts +100947 -134653
  9. package/cjs/fluid/index.js +44 -23
  10. package/cjs/helpers/morphoBlueHelpers/index.js +66 -66
  11. package/cjs/markets/aave/marketAssets.js +1 -1
  12. package/cjs/markets/fluid/index.d.ts +46 -0
  13. package/cjs/markets/fluid/index.js +436 -1
  14. package/cjs/services/priceService.js +1 -1
  15. package/cjs/services/viem.d.ts +2 -3254
  16. package/cjs/staking/staking.d.ts +1 -1
  17. package/cjs/staking/staking.js +17 -14
  18. package/cjs/types/fluid.d.ts +30 -1
  19. package/cjs/types/fluid.js +31 -1
  20. package/esm/aaveV3/index.js +1 -1
  21. package/esm/config/contracts.d.ts +12 -0
  22. package/esm/config/contracts.js +7 -3
  23. package/esm/contracts.d.ts +100947 -134653
  24. package/esm/fluid/index.js +45 -24
  25. package/esm/helpers/morphoBlueHelpers/index.js +66 -66
  26. package/esm/markets/aave/marketAssets.js +1 -1
  27. package/esm/markets/fluid/index.d.ts +46 -0
  28. package/esm/markets/fluid/index.js +415 -1
  29. package/esm/services/priceService.js +2 -2
  30. package/esm/services/viem.d.ts +2 -3254
  31. package/esm/staking/staking.d.ts +1 -1
  32. package/esm/staking/staking.js +17 -14
  33. package/esm/types/fluid.d.ts +30 -1
  34. package/esm/types/fluid.js +30 -0
  35. package/package.json +47 -47
  36. package/src/aaveV2/index.ts +240 -240
  37. package/src/aaveV3/index.ts +614 -614
  38. package/src/aaveV3/merit.ts +97 -97
  39. package/src/aaveV3/merkl.ts +74 -74
  40. package/src/claiming/aaveV3.ts +154 -154
  41. package/src/claiming/compV3.ts +22 -22
  42. package/src/claiming/index.ts +12 -12
  43. package/src/claiming/king.ts +66 -66
  44. package/src/claiming/morphoBlue.ts +118 -118
  45. package/src/claiming/spark.ts +225 -225
  46. package/src/compoundV2/index.ts +244 -244
  47. package/src/compoundV3/index.ts +274 -274
  48. package/src/config/contracts.ts +1255 -1251
  49. package/src/constants/index.ts +10 -10
  50. package/src/contracts.ts +120 -120
  51. package/src/curveUsd/index.ts +254 -254
  52. package/src/eulerV2/index.ts +324 -324
  53. package/src/exchange/index.ts +25 -25
  54. package/src/fluid/index.ts +1694 -1668
  55. package/src/helpers/aaveHelpers/index.ts +187 -187
  56. package/src/helpers/compoundHelpers/index.ts +283 -283
  57. package/src/helpers/curveUsdHelpers/index.ts +40 -40
  58. package/src/helpers/eulerHelpers/index.ts +222 -222
  59. package/src/helpers/fluidHelpers/index.ts +326 -326
  60. package/src/helpers/index.ts +10 -10
  61. package/src/helpers/liquityV2Helpers/index.ts +82 -82
  62. package/src/helpers/llamaLendHelpers/index.ts +53 -53
  63. package/src/helpers/makerHelpers/index.ts +52 -52
  64. package/src/helpers/morphoBlueHelpers/index.ts +396 -396
  65. package/src/helpers/sparkHelpers/index.ts +158 -158
  66. package/src/index.ts +47 -47
  67. package/src/liquity/index.ts +159 -159
  68. package/src/liquityV2/index.ts +657 -657
  69. package/src/llamaLend/index.ts +305 -305
  70. package/src/maker/index.ts +223 -223
  71. package/src/markets/aave/index.ts +116 -116
  72. package/src/markets/aave/marketAssets.ts +54 -54
  73. package/src/markets/compound/index.ts +238 -238
  74. package/src/markets/compound/marketsAssets.ts +97 -97
  75. package/src/markets/curveUsd/index.ts +69 -69
  76. package/src/markets/euler/index.ts +26 -26
  77. package/src/markets/fluid/index.ts +2900 -2460
  78. package/src/markets/index.ts +25 -25
  79. package/src/markets/liquityV2/index.ts +102 -102
  80. package/src/markets/llamaLend/contractAddresses.ts +141 -141
  81. package/src/markets/llamaLend/index.ts +235 -235
  82. package/src/markets/morphoBlue/index.ts +895 -895
  83. package/src/markets/spark/index.ts +29 -29
  84. package/src/markets/spark/marketAssets.ts +12 -12
  85. package/src/moneymarket/moneymarketCommonService.ts +80 -80
  86. package/src/morphoBlue/index.ts +274 -274
  87. package/src/portfolio/index.ts +570 -570
  88. package/src/services/priceService.ts +159 -159
  89. package/src/services/utils.ts +115 -115
  90. package/src/services/viem.ts +34 -34
  91. package/src/setup.ts +8 -8
  92. package/src/spark/index.ts +456 -456
  93. package/src/staking/eligibility.ts +53 -53
  94. package/src/staking/index.ts +1 -1
  95. package/src/staking/staking.ts +177 -172
  96. package/src/types/aave.ts +189 -189
  97. package/src/types/claiming.ts +109 -109
  98. package/src/types/common.ts +107 -107
  99. package/src/types/compound.ts +136 -136
  100. package/src/types/curveUsd.ts +123 -123
  101. package/src/types/euler.ts +175 -175
  102. package/src/types/fluid.ts +483 -452
  103. package/src/types/index.ts +13 -13
  104. package/src/types/liquity.ts +30 -30
  105. package/src/types/liquityV2.ts +126 -126
  106. package/src/types/llamaLend.ts +159 -159
  107. package/src/types/maker.ts +63 -63
  108. package/src/types/merit.ts +1 -1
  109. package/src/types/merkl.ts +70 -70
  110. package/src/types/morphoBlue.ts +194 -194
  111. package/src/types/portfolio.ts +60 -60
  112. package/src/types/spark.ts +133 -133
  113. package/src/umbrella/index.ts +69 -69
  114. package/src/umbrella/umbrellaUtils.ts +29 -29
@@ -1,254 +1,254 @@
1
- import Dec from 'decimal.js';
2
- import { assetAmountInEth, getAssetInfo } from '@defisaver/tokens';
3
- import { Client } from 'viem';
4
- import {
5
- CrvUSDGlobalMarketData, CrvUSDMarketData, CrvUSDStatus, CrvUSDUsedAssets, CrvUSDUserData,
6
- } from '../types';
7
- import {
8
- Blockish, EthAddress, EthereumProvider, NetworkNumber, PositionBalances,
9
- } from '../types/common';
10
- import {
11
- createViemContractFromConfigFunc, CrvUSDFactoryContractViem, CrvUSDViewContractViem,
12
- } from '../contracts';
13
- import { getCrvUsdAggregatedData } from '../helpers/curveUsdHelpers';
14
- import { CrvUsdMarkets } from '../markets';
15
- import { wethToEth } from '../services/utils';
16
- import { getViemProvider, setViemBlockNumber } from '../services/viem';
17
-
18
- const getAndFormatBands = async (provider: Client, network: NetworkNumber, selectedMarket: CrvUSDMarketData, _minBand: string, _maxBand: string) => {
19
- const contract = CrvUSDViewContractViem(provider, network);
20
- const minBand = parseInt(_minBand, 10);
21
- const maxBand = parseInt(_maxBand, 10);
22
- const pivots: number[] = [];
23
-
24
- // getBandsData uses a lot of gas to get all of the bands at once, so we use pagination and fetch 200 bands at a time
25
- let i = minBand;
26
- while (i < maxBand) {
27
- i += 200;
28
- if (i > maxBand) {
29
- pivots.push(maxBand);
30
- } else {
31
- pivots.push(i);
32
- }
33
- }
34
-
35
- const bandsData = (await Promise.all(pivots.map(async (pivot, index) => {
36
- let start = 0;
37
- if (index === 0) {
38
- start = minBand;
39
- } else {
40
- start = pivots[index - 1] + 1;
41
- }
42
- const pivotedBandsData = await contract.read.getBandsData([selectedMarket.controllerAddress, BigInt(start), BigInt(pivot)]);
43
- return pivotedBandsData;
44
- }))).flat();
45
-
46
- return bandsData.map((band) => ({
47
- id: band.id.toString(),
48
- collAmount: assetAmountInEth(band.collAmount.toString()),
49
- debtAmount: assetAmountInEth(band.debtAmount.toString()),
50
- lowPrice: assetAmountInEth(band.lowPrice.toString()),
51
- highPrice: assetAmountInEth(band.highPrice.toString()),
52
- }));
53
- };
54
-
55
- export const _getCurveUsdGlobalData = async (provider: Client, network: NetworkNumber, selectedMarket: CrvUSDMarketData): Promise<CrvUSDGlobalMarketData> => {
56
- const contract = CrvUSDViewContractViem(provider, network);
57
- const factoryContract = CrvUSDFactoryContractViem(provider, network);
58
- const cntrollerContract = createViemContractFromConfigFunc('crvUSDwstETHController', selectedMarket.controllerAddress)(provider, network);
59
- const debtAsset = selectedMarket.baseAsset;
60
-
61
- const [debtCeiling, _, data, loanDiscountWei] = await Promise.all([
62
- factoryContract.read.debt_ceiling([selectedMarket.controllerAddress]),
63
- factoryContract.read.total_debt(),
64
- contract.read.globalData([selectedMarket.controllerAddress]),
65
- cntrollerContract.read.loan_discount(),
66
- ]);
67
-
68
- // all prices are in 18 decimals
69
- const totalDebt = assetAmountInEth(data.totalDebt.toString(), debtAsset);
70
- const ammPrice = assetAmountInEth(data.ammPrice.toString(), debtAsset);
71
-
72
- const rate = assetAmountInEth(data.ammRate.toString());
73
- const futureRate = assetAmountInEth(data.monetaryPolicyRate.toString());
74
-
75
- const exponentRate = new Dec(rate).mul(365).mul(86400);
76
- const exponentFutureRate = new Dec(futureRate).mul(365).mul(86400);
77
- const borrowRate = new Dec(new Dec(2.718281828459).pow(exponentRate).minus(1)).mul(100)
78
- .toString();
79
- const futureBorrowRate = new Dec(new Dec(2.718281828459).pow(exponentFutureRate).minus(1)).mul(100)
80
- .toString();
81
-
82
- const bandsData = await getAndFormatBands(provider, network, selectedMarket, data.minBand.toString(), data.maxBand.toString());
83
-
84
- const leftToBorrow = new Dec(debtCeiling.toString()).minus(totalDebt).toString();
85
-
86
- const loanDiscount = assetAmountInEth(loanDiscountWei.toString(), debtAsset);
87
-
88
- return {
89
- ...data,
90
- decimals: data.decimals.toString(),
91
- activeBand: data.activeBand.toString(),
92
- monetaryPolicyRate: data.monetaryPolicyRate.toString(),
93
- ammRate: data.ammRate.toString(),
94
- minBand: data.minBand.toString(),
95
- maxBand: data.maxBand.toString(),
96
- debtCeiling: debtCeiling.toString(),
97
- totalDebt,
98
- ammPrice,
99
- oraclePrice: assetAmountInEth(data.oraclePrice.toString(), debtAsset),
100
- basePrice: assetAmountInEth(data.basePrice.toString(), debtAsset),
101
- minted: assetAmountInEth(data.minted.toString(), debtAsset),
102
- redeemed: assetAmountInEth(data.redeemed.toString(), debtAsset),
103
- borrowRate,
104
- futureBorrowRate,
105
- bands: bandsData,
106
- leftToBorrow,
107
- loanDiscount,
108
- };
109
- };
110
-
111
- export const getCurveUsdGlobalData = async (
112
- provider: EthereumProvider,
113
- network: NetworkNumber,
114
- selectedMarket: CrvUSDMarketData,
115
- ): Promise<CrvUSDGlobalMarketData> => _getCurveUsdGlobalData(getViemProvider(provider, network), network, selectedMarket);
116
-
117
- const getStatusForUser = (bandRange: string[], activeBand: string, crvUSDSupplied: string, collSupplied: string, healthPercent: string) => {
118
- // if bands are equal, that can only be [0,0] which means user doesn't have loan (min number of bands is 4)
119
- if (new Dec(bandRange[0]).eq(bandRange[1])) return CrvUSDStatus.Nonexistant;
120
- // if user doesn't have crvUSD as collateral, then his position is not in soft liquidation
121
- if (new Dec(crvUSDSupplied).lte(0)) {
122
- const isHealthRisky = new Dec(healthPercent).lt(10);
123
- if (new Dec(bandRange[0]).minus(activeBand).lte(3) || isHealthRisky) return CrvUSDStatus.Risk; // if user band is less than 3 bands away from active band, his position is at risk
124
- return CrvUSDStatus.Safe;
125
- }
126
- if (new Dec(bandRange[0]).lte(activeBand) && new Dec(bandRange[1]).gte(activeBand)) return CrvUSDStatus.SoftLiquidating; // user has crvUSD as coll so he is in soft liquidation
127
- if (new Dec(collSupplied).lte(0) || new Dec(bandRange[1]).lte(activeBand)) return CrvUSDStatus.SoftLiquidated; // or is fully soft liquidated
128
- return CrvUSDStatus.Nonexistant;
129
- };
130
-
131
- export const _getCrvUsdAccountBalances = async (provider: Client, network: NetworkNumber, block: Blockish, addressMapping: boolean, address: EthAddress, controllerAddress: EthAddress): Promise<PositionBalances> => {
132
- let balances: PositionBalances = {
133
- collateral: {},
134
- debt: {},
135
- };
136
-
137
- if (!address) {
138
- return balances;
139
- }
140
-
141
- const contract = CrvUSDViewContractViem(provider, network, block);
142
- const selectedMarket = Object.values(CrvUsdMarkets(network)).find(i => i.controllerAddress.toLowerCase() === controllerAddress.toLowerCase()) as CrvUSDMarketData;
143
-
144
- const data = await contract.read.userData([selectedMarket.controllerAddress, address], setViemBlockNumber(block));
145
-
146
- balances = {
147
- collateral: {
148
- [addressMapping ? getAssetInfo(wethToEth(selectedMarket.collAsset), network).address.toLowerCase() : wethToEth(selectedMarket.collAsset)]: data.marketCollateralAmount.toString(),
149
- },
150
- debt: {
151
- [addressMapping ? getAssetInfo(wethToEth(selectedMarket.baseAsset), network).address.toLowerCase() : wethToEth(selectedMarket.baseAsset)]: data.debtAmount.toString(),
152
- },
153
- };
154
-
155
- return balances;
156
- };
157
-
158
- export const getCrvUsdAccountBalances = async (
159
- provider: EthereumProvider,
160
- network: NetworkNumber,
161
- block: Blockish,
162
- addressMapping: boolean,
163
- address: EthAddress,
164
- controllerAddress: EthAddress,
165
- ): Promise<PositionBalances> => _getCrvUsdAccountBalances(getViemProvider(provider, network), network, block, addressMapping, address, controllerAddress);
166
-
167
- export const _getCurveUsdUserData = async (provider: Client, network: NetworkNumber, address: EthAddress, selectedMarket: CrvUSDMarketData, activeBand: string): Promise<CrvUSDUserData> => {
168
- const contract = CrvUSDViewContractViem(provider, network);
169
-
170
- const data = await contract.read.userData([selectedMarket.controllerAddress, address]);
171
- const collAsset = selectedMarket.collAsset;
172
- const debtAsset = selectedMarket.baseAsset;
173
-
174
- const health = assetAmountInEth(data.health.toString());
175
- const healthPercent = new Dec(health).mul(100).toString();
176
- const collPrice = assetAmountInEth(data.collateralPrice.toString(), debtAsset);
177
- const collSupplied = assetAmountInEth(data.marketCollateralAmount.toString(), collAsset);
178
- const collSuppliedUsd = new Dec(collSupplied).mul(collPrice).toString();
179
- const crvUSDSupplied = assetAmountInEth(data.curveUsdCollateralAmount.toString(), debtAsset);
180
- const debtBorrowed = assetAmountInEth(data.debtAmount.toString(), debtAsset);
181
-
182
- const collRatio = data.loanExists ? new Dec(collSuppliedUsd).div(debtBorrowed).toString() : '0';
183
- const usedAssets: CrvUSDUsedAssets = data.loanExists ? {
184
- [collAsset]: {
185
- isSupplied: true,
186
- supplied: collSupplied,
187
- suppliedUsd: collSuppliedUsd, // need oracle price, or amm price
188
- borrowed: '0',
189
- borrowedUsd: '0',
190
- isBorrowed: false,
191
- symbol: collAsset,
192
- collateral: true,
193
- price: collPrice, // price_amm
194
- },
195
- [debtAsset]: {
196
- isSupplied: new Dec(crvUSDSupplied).gt('0'),
197
- collateral: new Dec(crvUSDSupplied).gt('0'),
198
- supplied: crvUSDSupplied,
199
- suppliedUsd: crvUSDSupplied,
200
- borrowed: debtBorrowed,
201
- borrowedUsd: debtBorrowed,
202
- isBorrowed: new Dec(debtBorrowed).gt('0'),
203
- symbol: 'crvUSD',
204
- price: '1',
205
- interestRate: '0',
206
- },
207
- } : {};
208
-
209
- const priceHigh = assetAmountInEth(data.priceHigh.toString());
210
- const priceLow = assetAmountInEth(data.priceLow.toString());
211
-
212
- const _userBands = data.loanExists ? (await getAndFormatBands(provider, network, selectedMarket, data.bandRange[0].toString(), data.bandRange[1].toString())) : [];
213
-
214
- const status = data.loanExists ? getStatusForUser(data.bandRange.map(b => b.toString()), activeBand, crvUSDSupplied, collSupplied, healthPercent) : CrvUSDStatus.Nonexistant;
215
-
216
- const userBands = _userBands.map((band, index) => ({
217
- ...band,
218
- userDebtAmount: assetAmountInEth(data.usersBands[0][index].toString(), debtAsset),
219
- userCollAmount: assetAmountInEth(data.usersBands[1][index].toString(), collAsset),
220
- })).sort((a, b) => parseInt(b.id, 10) - parseInt(a.id, 10));
221
-
222
- return {
223
- ...data,
224
- collRatio,
225
- collateralPrice: collPrice,
226
- debtAmount: assetAmountInEth(data.debtAmount.toString(), debtAsset),
227
- health,
228
- healthPercent,
229
- priceHigh,
230
- priceLow,
231
- liquidationDiscount: assetAmountInEth(data.liquidationDiscount.toString()),
232
- numOfBands: data.N.toString(),
233
- usedAssets,
234
- status,
235
- ...getCrvUsdAggregatedData({
236
- loanExists: data.loanExists, usedAssets, network: NetworkNumber.Eth, selectedMarket, numOfBands: data.N.toString(),
237
- }),
238
- userBands,
239
- };
240
- };
241
-
242
- export const getCurveUsdUserData = async (
243
- provider: EthereumProvider,
244
- network: NetworkNumber,
245
- address: EthAddress,
246
- selectedMarket: CrvUSDMarketData,
247
- activeBand: string,
248
- ): Promise<CrvUSDUserData> => _getCurveUsdUserData(getViemProvider(provider, network), network, address, selectedMarket, activeBand);
249
-
250
- export const getCurveUsdFullPositionData = async (provider: EthereumProvider, network: NetworkNumber, address: EthAddress, selectedMarket: CrvUSDMarketData): Promise<CrvUSDUserData> => {
251
- const marketData = await getCurveUsdGlobalData(provider, network, selectedMarket);
252
- const positionData = await getCurveUsdUserData(provider, network, address, selectedMarket, marketData.activeBand);
253
- return positionData;
254
- };
1
+ import Dec from 'decimal.js';
2
+ import { assetAmountInEth, getAssetInfo } from '@defisaver/tokens';
3
+ import { Client } from 'viem';
4
+ import {
5
+ CrvUSDGlobalMarketData, CrvUSDMarketData, CrvUSDStatus, CrvUSDUsedAssets, CrvUSDUserData,
6
+ } from '../types';
7
+ import {
8
+ Blockish, EthAddress, EthereumProvider, NetworkNumber, PositionBalances,
9
+ } from '../types/common';
10
+ import {
11
+ createViemContractFromConfigFunc, CrvUSDFactoryContractViem, CrvUSDViewContractViem,
12
+ } from '../contracts';
13
+ import { getCrvUsdAggregatedData } from '../helpers/curveUsdHelpers';
14
+ import { CrvUsdMarkets } from '../markets';
15
+ import { wethToEth } from '../services/utils';
16
+ import { getViemProvider, setViemBlockNumber } from '../services/viem';
17
+
18
+ const getAndFormatBands = async (provider: Client, network: NetworkNumber, selectedMarket: CrvUSDMarketData, _minBand: string, _maxBand: string) => {
19
+ const contract = CrvUSDViewContractViem(provider, network);
20
+ const minBand = parseInt(_minBand, 10);
21
+ const maxBand = parseInt(_maxBand, 10);
22
+ const pivots: number[] = [];
23
+
24
+ // getBandsData uses a lot of gas to get all of the bands at once, so we use pagination and fetch 200 bands at a time
25
+ let i = minBand;
26
+ while (i < maxBand) {
27
+ i += 200;
28
+ if (i > maxBand) {
29
+ pivots.push(maxBand);
30
+ } else {
31
+ pivots.push(i);
32
+ }
33
+ }
34
+
35
+ const bandsData = (await Promise.all(pivots.map(async (pivot, index) => {
36
+ let start = 0;
37
+ if (index === 0) {
38
+ start = minBand;
39
+ } else {
40
+ start = pivots[index - 1] + 1;
41
+ }
42
+ const pivotedBandsData = await contract.read.getBandsData([selectedMarket.controllerAddress, BigInt(start), BigInt(pivot)]);
43
+ return pivotedBandsData;
44
+ }))).flat();
45
+
46
+ return bandsData.map((band) => ({
47
+ id: band.id.toString(),
48
+ collAmount: assetAmountInEth(band.collAmount.toString()),
49
+ debtAmount: assetAmountInEth(band.debtAmount.toString()),
50
+ lowPrice: assetAmountInEth(band.lowPrice.toString()),
51
+ highPrice: assetAmountInEth(band.highPrice.toString()),
52
+ }));
53
+ };
54
+
55
+ export const _getCurveUsdGlobalData = async (provider: Client, network: NetworkNumber, selectedMarket: CrvUSDMarketData): Promise<CrvUSDGlobalMarketData> => {
56
+ const contract = CrvUSDViewContractViem(provider, network);
57
+ const factoryContract = CrvUSDFactoryContractViem(provider, network);
58
+ const cntrollerContract = createViemContractFromConfigFunc('crvUSDwstETHController', selectedMarket.controllerAddress)(provider, network);
59
+ const debtAsset = selectedMarket.baseAsset;
60
+
61
+ const [debtCeiling, _, data, loanDiscountWei] = await Promise.all([
62
+ factoryContract.read.debt_ceiling([selectedMarket.controllerAddress]),
63
+ factoryContract.read.total_debt(),
64
+ contract.read.globalData([selectedMarket.controllerAddress]),
65
+ cntrollerContract.read.loan_discount(),
66
+ ]);
67
+
68
+ // all prices are in 18 decimals
69
+ const totalDebt = assetAmountInEth(data.totalDebt.toString(), debtAsset);
70
+ const ammPrice = assetAmountInEth(data.ammPrice.toString(), debtAsset);
71
+
72
+ const rate = assetAmountInEth(data.ammRate.toString());
73
+ const futureRate = assetAmountInEth(data.monetaryPolicyRate.toString());
74
+
75
+ const exponentRate = new Dec(rate).mul(365).mul(86400);
76
+ const exponentFutureRate = new Dec(futureRate).mul(365).mul(86400);
77
+ const borrowRate = new Dec(new Dec(2.718281828459).pow(exponentRate).minus(1)).mul(100)
78
+ .toString();
79
+ const futureBorrowRate = new Dec(new Dec(2.718281828459).pow(exponentFutureRate).minus(1)).mul(100)
80
+ .toString();
81
+
82
+ const bandsData = await getAndFormatBands(provider, network, selectedMarket, data.minBand.toString(), data.maxBand.toString());
83
+
84
+ const leftToBorrow = new Dec(debtCeiling.toString()).minus(totalDebt).toString();
85
+
86
+ const loanDiscount = assetAmountInEth(loanDiscountWei.toString(), debtAsset);
87
+
88
+ return {
89
+ ...data,
90
+ decimals: data.decimals.toString(),
91
+ activeBand: data.activeBand.toString(),
92
+ monetaryPolicyRate: data.monetaryPolicyRate.toString(),
93
+ ammRate: data.ammRate.toString(),
94
+ minBand: data.minBand.toString(),
95
+ maxBand: data.maxBand.toString(),
96
+ debtCeiling: debtCeiling.toString(),
97
+ totalDebt,
98
+ ammPrice,
99
+ oraclePrice: assetAmountInEth(data.oraclePrice.toString(), debtAsset),
100
+ basePrice: assetAmountInEth(data.basePrice.toString(), debtAsset),
101
+ minted: assetAmountInEth(data.minted.toString(), debtAsset),
102
+ redeemed: assetAmountInEth(data.redeemed.toString(), debtAsset),
103
+ borrowRate,
104
+ futureBorrowRate,
105
+ bands: bandsData,
106
+ leftToBorrow,
107
+ loanDiscount,
108
+ };
109
+ };
110
+
111
+ export const getCurveUsdGlobalData = async (
112
+ provider: EthereumProvider,
113
+ network: NetworkNumber,
114
+ selectedMarket: CrvUSDMarketData,
115
+ ): Promise<CrvUSDGlobalMarketData> => _getCurveUsdGlobalData(getViemProvider(provider, network), network, selectedMarket);
116
+
117
+ const getStatusForUser = (bandRange: string[], activeBand: string, crvUSDSupplied: string, collSupplied: string, healthPercent: string) => {
118
+ // if bands are equal, that can only be [0,0] which means user doesn't have loan (min number of bands is 4)
119
+ if (new Dec(bandRange[0]).eq(bandRange[1])) return CrvUSDStatus.Nonexistant;
120
+ // if user doesn't have crvUSD as collateral, then his position is not in soft liquidation
121
+ if (new Dec(crvUSDSupplied).lte(0)) {
122
+ const isHealthRisky = new Dec(healthPercent).lt(10);
123
+ if (new Dec(bandRange[0]).minus(activeBand).lte(3) || isHealthRisky) return CrvUSDStatus.Risk; // if user band is less than 3 bands away from active band, his position is at risk
124
+ return CrvUSDStatus.Safe;
125
+ }
126
+ if (new Dec(bandRange[0]).lte(activeBand) && new Dec(bandRange[1]).gte(activeBand)) return CrvUSDStatus.SoftLiquidating; // user has crvUSD as coll so he is in soft liquidation
127
+ if (new Dec(collSupplied).lte(0) || new Dec(bandRange[1]).lte(activeBand)) return CrvUSDStatus.SoftLiquidated; // or is fully soft liquidated
128
+ return CrvUSDStatus.Nonexistant;
129
+ };
130
+
131
+ export const _getCrvUsdAccountBalances = async (provider: Client, network: NetworkNumber, block: Blockish, addressMapping: boolean, address: EthAddress, controllerAddress: EthAddress): Promise<PositionBalances> => {
132
+ let balances: PositionBalances = {
133
+ collateral: {},
134
+ debt: {},
135
+ };
136
+
137
+ if (!address) {
138
+ return balances;
139
+ }
140
+
141
+ const contract = CrvUSDViewContractViem(provider, network, block);
142
+ const selectedMarket = Object.values(CrvUsdMarkets(network)).find(i => i.controllerAddress.toLowerCase() === controllerAddress.toLowerCase()) as CrvUSDMarketData;
143
+
144
+ const data = await contract.read.userData([selectedMarket.controllerAddress, address], setViemBlockNumber(block));
145
+
146
+ balances = {
147
+ collateral: {
148
+ [addressMapping ? getAssetInfo(wethToEth(selectedMarket.collAsset), network).address.toLowerCase() : wethToEth(selectedMarket.collAsset)]: data.marketCollateralAmount.toString(),
149
+ },
150
+ debt: {
151
+ [addressMapping ? getAssetInfo(wethToEth(selectedMarket.baseAsset), network).address.toLowerCase() : wethToEth(selectedMarket.baseAsset)]: data.debtAmount.toString(),
152
+ },
153
+ };
154
+
155
+ return balances;
156
+ };
157
+
158
+ export const getCrvUsdAccountBalances = async (
159
+ provider: EthereumProvider,
160
+ network: NetworkNumber,
161
+ block: Blockish,
162
+ addressMapping: boolean,
163
+ address: EthAddress,
164
+ controllerAddress: EthAddress,
165
+ ): Promise<PositionBalances> => _getCrvUsdAccountBalances(getViemProvider(provider, network), network, block, addressMapping, address, controllerAddress);
166
+
167
+ export const _getCurveUsdUserData = async (provider: Client, network: NetworkNumber, address: EthAddress, selectedMarket: CrvUSDMarketData, activeBand: string): Promise<CrvUSDUserData> => {
168
+ const contract = CrvUSDViewContractViem(provider, network);
169
+
170
+ const data = await contract.read.userData([selectedMarket.controllerAddress, address]);
171
+ const collAsset = selectedMarket.collAsset;
172
+ const debtAsset = selectedMarket.baseAsset;
173
+
174
+ const health = assetAmountInEth(data.health.toString());
175
+ const healthPercent = new Dec(health).mul(100).toString();
176
+ const collPrice = assetAmountInEth(data.collateralPrice.toString(), debtAsset);
177
+ const collSupplied = assetAmountInEth(data.marketCollateralAmount.toString(), collAsset);
178
+ const collSuppliedUsd = new Dec(collSupplied).mul(collPrice).toString();
179
+ const crvUSDSupplied = assetAmountInEth(data.curveUsdCollateralAmount.toString(), debtAsset);
180
+ const debtBorrowed = assetAmountInEth(data.debtAmount.toString(), debtAsset);
181
+
182
+ const collRatio = data.loanExists ? new Dec(collSuppliedUsd).div(debtBorrowed).toString() : '0';
183
+ const usedAssets: CrvUSDUsedAssets = data.loanExists ? {
184
+ [collAsset]: {
185
+ isSupplied: true,
186
+ supplied: collSupplied,
187
+ suppliedUsd: collSuppliedUsd, // need oracle price, or amm price
188
+ borrowed: '0',
189
+ borrowedUsd: '0',
190
+ isBorrowed: false,
191
+ symbol: collAsset,
192
+ collateral: true,
193
+ price: collPrice, // price_amm
194
+ },
195
+ [debtAsset]: {
196
+ isSupplied: new Dec(crvUSDSupplied).gt('0'),
197
+ collateral: new Dec(crvUSDSupplied).gt('0'),
198
+ supplied: crvUSDSupplied,
199
+ suppliedUsd: crvUSDSupplied,
200
+ borrowed: debtBorrowed,
201
+ borrowedUsd: debtBorrowed,
202
+ isBorrowed: new Dec(debtBorrowed).gt('0'),
203
+ symbol: 'crvUSD',
204
+ price: '1',
205
+ interestRate: '0',
206
+ },
207
+ } : {};
208
+
209
+ const priceHigh = assetAmountInEth(data.priceHigh.toString());
210
+ const priceLow = assetAmountInEth(data.priceLow.toString());
211
+
212
+ const _userBands = data.loanExists ? (await getAndFormatBands(provider, network, selectedMarket, data.bandRange[0].toString(), data.bandRange[1].toString())) : [];
213
+
214
+ const status = data.loanExists ? getStatusForUser(data.bandRange.map(b => b.toString()), activeBand, crvUSDSupplied, collSupplied, healthPercent) : CrvUSDStatus.Nonexistant;
215
+
216
+ const userBands = _userBands.map((band, index) => ({
217
+ ...band,
218
+ userDebtAmount: assetAmountInEth(data.usersBands[0][index].toString(), debtAsset),
219
+ userCollAmount: assetAmountInEth(data.usersBands[1][index].toString(), collAsset),
220
+ })).sort((a, b) => parseInt(b.id, 10) - parseInt(a.id, 10));
221
+
222
+ return {
223
+ ...data,
224
+ collRatio,
225
+ collateralPrice: collPrice,
226
+ debtAmount: assetAmountInEth(data.debtAmount.toString(), debtAsset),
227
+ health,
228
+ healthPercent,
229
+ priceHigh,
230
+ priceLow,
231
+ liquidationDiscount: assetAmountInEth(data.liquidationDiscount.toString()),
232
+ numOfBands: data.N.toString(),
233
+ usedAssets,
234
+ status,
235
+ ...getCrvUsdAggregatedData({
236
+ loanExists: data.loanExists, usedAssets, network: NetworkNumber.Eth, selectedMarket, numOfBands: data.N.toString(),
237
+ }),
238
+ userBands,
239
+ };
240
+ };
241
+
242
+ export const getCurveUsdUserData = async (
243
+ provider: EthereumProvider,
244
+ network: NetworkNumber,
245
+ address: EthAddress,
246
+ selectedMarket: CrvUSDMarketData,
247
+ activeBand: string,
248
+ ): Promise<CrvUSDUserData> => _getCurveUsdUserData(getViemProvider(provider, network), network, address, selectedMarket, activeBand);
249
+
250
+ export const getCurveUsdFullPositionData = async (provider: EthereumProvider, network: NetworkNumber, address: EthAddress, selectedMarket: CrvUSDMarketData): Promise<CrvUSDUserData> => {
251
+ const marketData = await getCurveUsdGlobalData(provider, network, selectedMarket);
252
+ const positionData = await getCurveUsdUserData(provider, network, address, selectedMarket, marketData.activeBand);
253
+ return positionData;
254
+ };