@defisaver/positions-sdk 2.1.11 → 2.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.mocharc.json +4 -4
- package/.nvmrc +1 -1
- package/README.md +64 -64
- package/cjs/aaveV3/index.js +1 -1
- package/cjs/contracts.d.ts +100947 -134653
- package/cjs/helpers/morphoBlueHelpers/index.js +66 -66
- package/cjs/markets/aave/marketAssets.js +1 -1
- package/cjs/services/viem.d.ts +2 -3254
- package/cjs/staking/staking.d.ts +1 -1
- package/cjs/staking/staking.js +17 -14
- package/esm/aaveV3/index.js +1 -1
- package/esm/contracts.d.ts +100947 -134653
- package/esm/helpers/morphoBlueHelpers/index.js +66 -66
- package/esm/markets/aave/marketAssets.js +1 -1
- package/esm/services/viem.d.ts +2 -3254
- package/esm/staking/staking.d.ts +1 -1
- package/esm/staking/staking.js +17 -14
- package/package.json +47 -47
- package/src/aaveV2/index.ts +240 -240
- package/src/aaveV3/index.ts +614 -614
- package/src/aaveV3/merit.ts +97 -97
- package/src/aaveV3/merkl.ts +74 -74
- package/src/claiming/aaveV3.ts +154 -154
- package/src/claiming/compV3.ts +22 -22
- package/src/claiming/index.ts +12 -12
- package/src/claiming/king.ts +66 -66
- package/src/claiming/morphoBlue.ts +118 -118
- package/src/claiming/spark.ts +225 -225
- package/src/compoundV2/index.ts +244 -244
- package/src/compoundV3/index.ts +274 -274
- package/src/config/contracts.ts +1251 -1251
- package/src/constants/index.ts +10 -10
- package/src/contracts.ts +120 -120
- package/src/curveUsd/index.ts +254 -254
- package/src/eulerV2/index.ts +324 -324
- package/src/exchange/index.ts +25 -25
- package/src/fluid/index.ts +1668 -1668
- package/src/helpers/aaveHelpers/index.ts +187 -187
- package/src/helpers/compoundHelpers/index.ts +283 -283
- package/src/helpers/curveUsdHelpers/index.ts +40 -40
- package/src/helpers/eulerHelpers/index.ts +222 -222
- package/src/helpers/fluidHelpers/index.ts +326 -326
- package/src/helpers/index.ts +10 -10
- package/src/helpers/liquityV2Helpers/index.ts +82 -82
- package/src/helpers/llamaLendHelpers/index.ts +53 -53
- package/src/helpers/makerHelpers/index.ts +52 -52
- package/src/helpers/morphoBlueHelpers/index.ts +396 -396
- package/src/helpers/sparkHelpers/index.ts +158 -158
- package/src/index.ts +47 -47
- package/src/liquity/index.ts +159 -159
- package/src/liquityV2/index.ts +657 -657
- package/src/llamaLend/index.ts +305 -305
- package/src/maker/index.ts +223 -223
- package/src/markets/aave/index.ts +116 -116
- package/src/markets/aave/marketAssets.ts +54 -54
- package/src/markets/compound/index.ts +238 -238
- package/src/markets/compound/marketsAssets.ts +97 -97
- package/src/markets/curveUsd/index.ts +69 -69
- package/src/markets/euler/index.ts +26 -26
- package/src/markets/fluid/index.ts +2460 -2460
- package/src/markets/index.ts +25 -25
- package/src/markets/liquityV2/index.ts +102 -102
- package/src/markets/llamaLend/contractAddresses.ts +141 -141
- package/src/markets/llamaLend/index.ts +235 -235
- package/src/markets/morphoBlue/index.ts +895 -895
- package/src/markets/spark/index.ts +29 -29
- package/src/markets/spark/marketAssets.ts +12 -12
- package/src/moneymarket/moneymarketCommonService.ts +80 -80
- package/src/morphoBlue/index.ts +274 -274
- package/src/portfolio/index.ts +570 -570
- package/src/services/priceService.ts +159 -159
- package/src/services/utils.ts +115 -115
- package/src/services/viem.ts +34 -34
- package/src/setup.ts +8 -8
- package/src/spark/index.ts +456 -456
- package/src/staking/eligibility.ts +53 -53
- package/src/staking/index.ts +1 -1
- package/src/staking/staking.ts +177 -172
- package/src/types/aave.ts +189 -189
- package/src/types/claiming.ts +109 -109
- package/src/types/common.ts +107 -107
- package/src/types/compound.ts +136 -136
- package/src/types/curveUsd.ts +123 -123
- package/src/types/euler.ts +175 -175
- package/src/types/fluid.ts +452 -452
- package/src/types/index.ts +13 -13
- package/src/types/liquity.ts +30 -30
- package/src/types/liquityV2.ts +126 -126
- package/src/types/llamaLend.ts +159 -159
- package/src/types/maker.ts +63 -63
- package/src/types/merit.ts +1 -1
- package/src/types/merkl.ts +70 -70
- package/src/types/morphoBlue.ts +194 -194
- package/src/types/portfolio.ts +60 -60
- package/src/types/spark.ts +133 -133
- package/src/umbrella/index.ts +69 -69
- package/src/umbrella/umbrellaUtils.ts +29 -29
|
@@ -1,327 +1,327 @@
|
|
|
1
|
-
import Dec from 'decimal.js';
|
|
2
|
-
import { assetAmountInEth } from '@defisaver/tokens';
|
|
3
|
-
import {
|
|
4
|
-
FluidAggregatedVaultData, FluidAssetData,
|
|
5
|
-
FluidAssetsData, FluidDexBorrowDataStructOutput, FluidDexSupplyDataStructOutput, FluidUsedAsset,
|
|
6
|
-
FluidUsedAssets,
|
|
7
|
-
FluidVaultType,
|
|
8
|
-
InnerFluidMarketData,
|
|
9
|
-
} from '../../types';
|
|
10
|
-
import { calcLeverageLiqPrice, getAssetsTotal, isLeveragedPos } from '../../moneymarket';
|
|
11
|
-
import { calculateNetApy } from '../../staking';
|
|
12
|
-
import { MMAssetsData } from '../../types/common';
|
|
13
|
-
import { getEthAmountForDecimals } from '../../services/utils';
|
|
14
|
-
|
|
15
|
-
const calculateNetApyDex = ({ marketData, suppliedUsd, borrowedUsd }: { marketData: InnerFluidMarketData, suppliedUsd: string, borrowedUsd: string }) => {
|
|
16
|
-
const {
|
|
17
|
-
borrowRate,
|
|
18
|
-
supplyRate,
|
|
19
|
-
incentiveBorrowRate,
|
|
20
|
-
incentiveSupplyRate,
|
|
21
|
-
tradingBorrowRate,
|
|
22
|
-
tradingSupplyRate,
|
|
23
|
-
} = marketData;
|
|
24
|
-
|
|
25
|
-
const totalBorrowRate = new Dec(borrowRate).minus(tradingBorrowRate || '0').toString();
|
|
26
|
-
const totalSupplyRate = new Dec(supplyRate).add(tradingSupplyRate || '0').toString();
|
|
27
|
-
|
|
28
|
-
const borrowIncentive = new Dec(incentiveBorrowRate || '0').mul(borrowedUsd).div(100).toString();
|
|
29
|
-
const supplyIncentive = new Dec(incentiveSupplyRate || '0').mul(suppliedUsd).div(100).toString();
|
|
30
|
-
const incentiveUsd = new Dec(supplyIncentive).minus(borrowIncentive).toString();
|
|
31
|
-
|
|
32
|
-
const borrowInterest = new Dec(totalBorrowRate).mul(borrowedUsd).div(100).toString();
|
|
33
|
-
const supplyInterest = new Dec(totalSupplyRate).mul(suppliedUsd).div(100).toString();
|
|
34
|
-
const totalInterestUsd = new Dec(supplyInterest).add(incentiveUsd).minus(borrowInterest).toString();
|
|
35
|
-
const balance = new Dec(suppliedUsd).sub(borrowedUsd).toString();
|
|
36
|
-
const netApy = new Dec(totalInterestUsd).div(balance).times(100).toString();
|
|
37
|
-
|
|
38
|
-
return {
|
|
39
|
-
netApy,
|
|
40
|
-
incentiveUsd,
|
|
41
|
-
totalInterestUsd,
|
|
42
|
-
};
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
export const getFluidAggregatedData = ({
|
|
46
|
-
usedAssets,
|
|
47
|
-
assetsData,
|
|
48
|
-
marketData,
|
|
49
|
-
}: {
|
|
50
|
-
usedAssets: FluidUsedAssets,
|
|
51
|
-
marketData: InnerFluidMarketData,
|
|
52
|
-
assetsData: FluidAssetsData
|
|
53
|
-
},
|
|
54
|
-
supplyShares?: string,
|
|
55
|
-
borrowShares?: string,
|
|
56
|
-
): FluidAggregatedVaultData => {
|
|
57
|
-
const payload = {} as FluidAggregatedVaultData;
|
|
58
|
-
|
|
59
|
-
payload.suppliedUsd = [FluidVaultType.T1, FluidVaultType.T3].includes(marketData.vaultType)
|
|
60
|
-
? getAssetsTotal(usedAssets, ({ isSupplied }: { isSupplied: boolean }) => isSupplied, ({ suppliedUsd }: { suppliedUsd: string }) => suppliedUsd)
|
|
61
|
-
: new Dec(marketData.collSharePrice!).mul(supplyShares!).toString();
|
|
62
|
-
payload.borrowedUsd = [FluidVaultType.T1, FluidVaultType.T2].includes(marketData.vaultType)
|
|
63
|
-
? getAssetsTotal(usedAssets, ({ isBorrowed }: { isBorrowed: boolean }) => isBorrowed, ({ borrowedUsd }: { borrowedUsd: string }) => borrowedUsd)
|
|
64
|
-
: new Dec(marketData.debtSharePrice!).mul(borrowShares!).toString();
|
|
65
|
-
|
|
66
|
-
const isDex = [FluidVaultType.T2, FluidVaultType.T3, FluidVaultType.T4].includes(marketData.vaultType);
|
|
67
|
-
const { netApy, incentiveUsd, totalInterestUsd } = isDex ? calculateNetApyDex({ marketData, suppliedUsd: payload.suppliedUsd, borrowedUsd: payload.borrowedUsd }) : calculateNetApy({ usedAssets, assetsData: assetsData as unknown as MMAssetsData });
|
|
68
|
-
payload.netApy = netApy;
|
|
69
|
-
payload.incentiveUsd = incentiveUsd;
|
|
70
|
-
payload.totalInterestUsd = totalInterestUsd;
|
|
71
|
-
const collFactor = marketData.collFactor;
|
|
72
|
-
const liqRatio = marketData.liquidationRatio;
|
|
73
|
-
|
|
74
|
-
payload.borrowLimitUsd = new Dec(payload.suppliedUsd).mul(collFactor).toString();
|
|
75
|
-
payload.liquidationLimitUsd = new Dec(payload.suppliedUsd).mul(liqRatio).div(100).toString();
|
|
76
|
-
const leftToBorrowUsd = new Dec(payload.borrowLimitUsd).sub(payload.borrowedUsd);
|
|
77
|
-
payload.leftToBorrowUsd = leftToBorrowUsd.lte('0') ? '0' : leftToBorrowUsd.toString();
|
|
78
|
-
payload.ratio = +payload.suppliedUsd ? new Dec(payload.borrowLimitUsd).div(payload.borrowedUsd).mul(100).toString() : '0';
|
|
79
|
-
payload.collRatio = +payload.suppliedUsd ? new Dec(payload.suppliedUsd).div(payload.borrowedUsd).mul(100).toString() : '0';
|
|
80
|
-
payload.minRatio = marketData.minRatio;
|
|
81
|
-
const { leveragedType, leveragedAsset } = isLeveragedPos(usedAssets);
|
|
82
|
-
|
|
83
|
-
payload.leveragedType = leveragedType;
|
|
84
|
-
if (leveragedType !== '') {
|
|
85
|
-
payload.leveragedAsset = leveragedAsset;
|
|
86
|
-
let assetPrice = assetsData[leveragedAsset].price;
|
|
87
|
-
if (leveragedType === 'lsd-leverage') {
|
|
88
|
-
// Treat ETH like a stablecoin in a long stETH position
|
|
89
|
-
payload.leveragedLsdAssetRatio = new Dec(assetsData[leveragedAsset].price).div(assetsData.ETH.price).toDP(18).toString();
|
|
90
|
-
assetPrice = new Dec(assetPrice).div(assetsData.ETH.price).toString();
|
|
91
|
-
}
|
|
92
|
-
payload.liquidationPrice = calcLeverageLiqPrice(leveragedType, assetPrice, payload.borrowedUsd, payload.liquidationLimitUsd);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
payload.minCollRatio = new Dec(payload.suppliedUsd).div(payload.borrowLimitUsd).mul(100).toString();
|
|
96
|
-
payload.collLiquidationRatio = new Dec(payload.suppliedUsd).div(payload.liquidationLimitUsd).mul(100).toString();
|
|
97
|
-
|
|
98
|
-
return payload;
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
interface DexSupplyData {
|
|
103
|
-
maxSupplyShares: string
|
|
104
|
-
supplyDexFee: string
|
|
105
|
-
token0PerSupplyShare: string
|
|
106
|
-
token1PerSupplyShare: string
|
|
107
|
-
withdrawable0: string
|
|
108
|
-
withdrawable1: string
|
|
109
|
-
withdrawableShares: string
|
|
110
|
-
utilizationSupply0: string
|
|
111
|
-
utilizationSupply1: string
|
|
112
|
-
supplyRate0: string
|
|
113
|
-
supplyRate1: string
|
|
114
|
-
totalSupplyShares: string
|
|
115
|
-
withdrawableToken0: string
|
|
116
|
-
withdrawableToken1: string
|
|
117
|
-
totalSupplyToken0: string
|
|
118
|
-
totalSupplyToken1: string
|
|
119
|
-
reservesSupplyToken0: string
|
|
120
|
-
reservesSupplyToken1: string
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
export const parseDexSupplyData = (dexSupplyData: FluidDexSupplyDataStructOutput, collAsset0: string, collAsset1: string): DexSupplyData => {
|
|
124
|
-
const {
|
|
125
|
-
dexPool, // address of the dex pool
|
|
126
|
-
dexId, // id of the dex pool
|
|
127
|
-
fee: _fee, // fee of the dex pool (Only used as swap fees)
|
|
128
|
-
lastStoredPrice, // last stored price of the dex pool
|
|
129
|
-
centerPrice, // center price of the dex pool
|
|
130
|
-
token0Utilization, // token0 utilization
|
|
131
|
-
token1Utilization, // token1 utilization
|
|
132
|
-
// ONLY FOR SUPPLY
|
|
133
|
-
totalSupplyShares: totalSupplySharesWei, // total supply shares, in 1e18
|
|
134
|
-
maxSupplyShares: maxSupplySharesWei, // max supply shares, in 1e18
|
|
135
|
-
token0Supplied, // token0 supplied, in token0 decimals
|
|
136
|
-
token1Supplied, // token1 supplied, in token1 decimals
|
|
137
|
-
sharesWithdrawable, // shares withdrawable, in 1e18
|
|
138
|
-
token0Withdrawable, // token0 withdrawable, in token0 decimals
|
|
139
|
-
token1Withdrawable, // token1 withdrawable, in token1 decimals
|
|
140
|
-
token0PerSupplyShare: token0PerSupplyShareWei, // token0 amount per 1e18 supply shares
|
|
141
|
-
token1PerSupplyShare: token1PerSupplyShareWei, // token1 amount per 1e18 supply shares
|
|
142
|
-
token0SupplyRate, // token0 supply rate. E.g 320 = 3.2% APR
|
|
143
|
-
token1SupplyRate, // token1 supply rate. E.g 320 = 3.2% APR
|
|
144
|
-
supplyToken0Reserves, // token0 reserves in the dex pool
|
|
145
|
-
supplyToken1Reserves, // token1 reserves in the dex pool
|
|
146
|
-
} = dexSupplyData;
|
|
147
|
-
|
|
148
|
-
const maxSupplyShares = getEthAmountForDecimals(maxSupplySharesWei.toString(), 18);
|
|
149
|
-
const fee = new Dec(_fee).div(100).toString();
|
|
150
|
-
|
|
151
|
-
const token0PerSupplyShare = assetAmountInEth(token0PerSupplyShareWei.toString(), collAsset0);
|
|
152
|
-
const token1PerSupplyShare = assetAmountInEth(token1PerSupplyShareWei.toString(), collAsset1);
|
|
153
|
-
|
|
154
|
-
const withdrawable0 = assetAmountInEth(token0Withdrawable.toString(), collAsset0);
|
|
155
|
-
const withdrawable1 = assetAmountInEth(token1Withdrawable.toString(), collAsset1);
|
|
156
|
-
const utilizationSupply0 = assetAmountInEth(token0Utilization.toString(), collAsset0);
|
|
157
|
-
const utilizationSupply1 = assetAmountInEth(token1Utilization.toString(), collAsset1);
|
|
158
|
-
|
|
159
|
-
const supplyRate0 = new Dec(token0SupplyRate).div(100).toString();
|
|
160
|
-
const supplyRate1 = new Dec(token1SupplyRate).div(100).toString();
|
|
161
|
-
|
|
162
|
-
const totalSupplyShares = getEthAmountForDecimals(totalSupplySharesWei.toString(), 18); // in shares
|
|
163
|
-
|
|
164
|
-
const withdrawableShares = getEthAmountForDecimals(sharesWithdrawable.toString(), 18);
|
|
165
|
-
const withdrawableToken0 = new Dec(withdrawableShares).mul(token0PerSupplyShare).div(1e18).toString();
|
|
166
|
-
const withdrawableToken1 = new Dec(withdrawableShares).mul(token1PerSupplyShare).div(1e18).toString();
|
|
167
|
-
|
|
168
|
-
const totalSupplyToken0 = assetAmountInEth(token0Supplied.toString(), collAsset0);
|
|
169
|
-
const totalSupplyToken1 = assetAmountInEth(token1Supplied.toString(), collAsset1);
|
|
170
|
-
|
|
171
|
-
const reservesSupplyToken0 = assetAmountInEth(supplyToken0Reserves.toString(), collAsset0);
|
|
172
|
-
const reservesSupplyToken1 = assetAmountInEth(supplyToken1Reserves.toString(), collAsset1);
|
|
173
|
-
|
|
174
|
-
return {
|
|
175
|
-
maxSupplyShares,
|
|
176
|
-
withdrawableShares,
|
|
177
|
-
supplyDexFee: fee,
|
|
178
|
-
token0PerSupplyShare,
|
|
179
|
-
token1PerSupplyShare,
|
|
180
|
-
withdrawable0,
|
|
181
|
-
withdrawable1,
|
|
182
|
-
utilizationSupply0,
|
|
183
|
-
utilizationSupply1,
|
|
184
|
-
supplyRate0,
|
|
185
|
-
supplyRate1,
|
|
186
|
-
totalSupplyShares,
|
|
187
|
-
withdrawableToken0,
|
|
188
|
-
withdrawableToken1,
|
|
189
|
-
totalSupplyToken0,
|
|
190
|
-
totalSupplyToken1,
|
|
191
|
-
reservesSupplyToken0,
|
|
192
|
-
reservesSupplyToken1,
|
|
193
|
-
};
|
|
194
|
-
};
|
|
195
|
-
|
|
196
|
-
interface DexBorrowData {
|
|
197
|
-
maxBorrowShares: string
|
|
198
|
-
borrowDexFee: string
|
|
199
|
-
token0PerBorrowShare: string
|
|
200
|
-
token1PerBorrowShare: string
|
|
201
|
-
borrowable0: string
|
|
202
|
-
borrowable1: string
|
|
203
|
-
utilizationBorrow0: string
|
|
204
|
-
utilizationBorrow1: string
|
|
205
|
-
borrowRate0: string
|
|
206
|
-
borrowRate1: string
|
|
207
|
-
totalBorrowShares: string
|
|
208
|
-
borrowableToken0: string
|
|
209
|
-
borrowableToken1: string
|
|
210
|
-
totalBorrowToken0: string
|
|
211
|
-
totalBorrowToken1: string
|
|
212
|
-
borrowableShares: string
|
|
213
|
-
quoteTokensPerShare: string
|
|
214
|
-
reservesBorrowToken0: string
|
|
215
|
-
reservesBorrowToken1: string
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
export const parseDexBorrowData = (dexBorrowData: FluidDexBorrowDataStructOutput, debtAsset0: string, debtAsset1: string): DexBorrowData => {
|
|
219
|
-
const {
|
|
220
|
-
dexPool,
|
|
221
|
-
dexId,
|
|
222
|
-
fee: _fee,
|
|
223
|
-
lastStoredPrice,
|
|
224
|
-
centerPrice,
|
|
225
|
-
token0Utilization,
|
|
226
|
-
token1Utilization,
|
|
227
|
-
totalBorrowShares: totalBorrowSharesWei,
|
|
228
|
-
maxBorrowShares: maxBorrowSharesWei,
|
|
229
|
-
token0Borrowed,
|
|
230
|
-
token1Borrowed,
|
|
231
|
-
sharesBorrowable,
|
|
232
|
-
token0Borrowable,
|
|
233
|
-
token1Borrowable,
|
|
234
|
-
token0PerBorrowShare: token0PerBorrowShareWei,
|
|
235
|
-
token1PerBorrowShare: token1PerBorrowShareWei,
|
|
236
|
-
token0BorrowRate,
|
|
237
|
-
token1BorrowRate,
|
|
238
|
-
quoteTokensPerShare,
|
|
239
|
-
borrowToken0Reserves,
|
|
240
|
-
borrowToken1Reserves,
|
|
241
|
-
} = dexBorrowData;
|
|
242
|
-
|
|
243
|
-
const maxBorrowShares = getEthAmountForDecimals(maxBorrowSharesWei.toString(), 18);
|
|
244
|
-
const fee = new Dec(_fee).div(100).toString();
|
|
245
|
-
|
|
246
|
-
const token0PerBorrowShare = assetAmountInEth(token0PerBorrowShareWei.toString(), debtAsset0);
|
|
247
|
-
const token1PerBorrowShare = assetAmountInEth(token1PerBorrowShareWei.toString(), debtAsset1);
|
|
248
|
-
|
|
249
|
-
const borrowable0 = assetAmountInEth(token0Borrowable.toString(), debtAsset0);
|
|
250
|
-
const borrowable1 = assetAmountInEth(token1Borrowable.toString(), debtAsset1);
|
|
251
|
-
const utilizationBorrow0 = assetAmountInEth(token0Utilization.toString(), debtAsset0);
|
|
252
|
-
const utilizationBorrow1 = assetAmountInEth(token1Utilization.toString(), debtAsset1);
|
|
253
|
-
|
|
254
|
-
const borrowRate0 = new Dec(token0BorrowRate).div(100).toString();
|
|
255
|
-
const borrowRate1 = new Dec(token1BorrowRate).div(100).toString();
|
|
256
|
-
|
|
257
|
-
const totalBorrowShares = getEthAmountForDecimals(totalBorrowSharesWei.toString(), 18); // in shares
|
|
258
|
-
|
|
259
|
-
const borrowableShares = getEthAmountForDecimals(sharesBorrowable.toString(), 18);
|
|
260
|
-
const borrowableToken0 = new Dec(borrowableShares).mul(token0PerBorrowShare).div(1e18).toString();
|
|
261
|
-
const borrowableToken1 = new Dec(borrowableShares).mul(token1PerBorrowShare).div(1e18).toString();
|
|
262
|
-
|
|
263
|
-
const totalBorrowToken0 = assetAmountInEth(token0Borrowed.toString(), debtAsset0);
|
|
264
|
-
const totalBorrowToken1 = assetAmountInEth(token1Borrowed.toString(), debtAsset1);
|
|
265
|
-
|
|
266
|
-
const reservesBorrowToken0 = assetAmountInEth(borrowToken0Reserves.toString(), debtAsset0);
|
|
267
|
-
const reservesBorrowToken1 = assetAmountInEth(borrowToken1Reserves.toString(), debtAsset1);
|
|
268
|
-
|
|
269
|
-
return {
|
|
270
|
-
borrowableShares,
|
|
271
|
-
maxBorrowShares,
|
|
272
|
-
borrowDexFee: fee,
|
|
273
|
-
token0PerBorrowShare,
|
|
274
|
-
token1PerBorrowShare,
|
|
275
|
-
borrowable0,
|
|
276
|
-
borrowable1,
|
|
277
|
-
utilizationBorrow0,
|
|
278
|
-
utilizationBorrow1,
|
|
279
|
-
borrowRate0,
|
|
280
|
-
borrowRate1,
|
|
281
|
-
totalBorrowShares,
|
|
282
|
-
borrowableToken0,
|
|
283
|
-
borrowableToken1,
|
|
284
|
-
totalBorrowToken0,
|
|
285
|
-
totalBorrowToken1,
|
|
286
|
-
quoteTokensPerShare: getEthAmountForDecimals(quoteTokensPerShare.toString(), 27),
|
|
287
|
-
reservesBorrowToken0,
|
|
288
|
-
reservesBorrowToken1,
|
|
289
|
-
};
|
|
290
|
-
};
|
|
291
|
-
|
|
292
|
-
const EMPTY_ASSET_DATA = {
|
|
293
|
-
symbol: '',
|
|
294
|
-
address: '',
|
|
295
|
-
price: '0',
|
|
296
|
-
totalSupply: '',
|
|
297
|
-
totalBorrow: '0',
|
|
298
|
-
canBeSupplied: false,
|
|
299
|
-
canBeBorrowed: false,
|
|
300
|
-
supplyRate: '0',
|
|
301
|
-
borrowRate: '0',
|
|
302
|
-
supplyIncentives: [],
|
|
303
|
-
borrowIncentives: [],
|
|
304
|
-
};
|
|
305
|
-
|
|
306
|
-
export const mergeAssetData = (existing: Partial<FluidAssetData> = {}, additional: Partial<FluidAssetData>): FluidAssetData => ({
|
|
307
|
-
...EMPTY_ASSET_DATA,
|
|
308
|
-
...existing,
|
|
309
|
-
...additional,
|
|
310
|
-
});
|
|
311
|
-
|
|
312
|
-
export const EMPTY_USED_ASSET = {
|
|
313
|
-
isSupplied: false,
|
|
314
|
-
isBorrowed: false,
|
|
315
|
-
supplied: '0',
|
|
316
|
-
suppliedUsd: '0',
|
|
317
|
-
borrowed: '0',
|
|
318
|
-
borrowedUsd: '0',
|
|
319
|
-
symbol: '',
|
|
320
|
-
collateral: false,
|
|
321
|
-
};
|
|
322
|
-
|
|
323
|
-
export const mergeUsedAssets = (existing: Partial<FluidUsedAsset> = {}, additional: Partial<FluidUsedAsset>): FluidUsedAsset => ({
|
|
324
|
-
...EMPTY_USED_ASSET,
|
|
325
|
-
...existing,
|
|
326
|
-
...additional,
|
|
1
|
+
import Dec from 'decimal.js';
|
|
2
|
+
import { assetAmountInEth } from '@defisaver/tokens';
|
|
3
|
+
import {
|
|
4
|
+
FluidAggregatedVaultData, FluidAssetData,
|
|
5
|
+
FluidAssetsData, FluidDexBorrowDataStructOutput, FluidDexSupplyDataStructOutput, FluidUsedAsset,
|
|
6
|
+
FluidUsedAssets,
|
|
7
|
+
FluidVaultType,
|
|
8
|
+
InnerFluidMarketData,
|
|
9
|
+
} from '../../types';
|
|
10
|
+
import { calcLeverageLiqPrice, getAssetsTotal, isLeveragedPos } from '../../moneymarket';
|
|
11
|
+
import { calculateNetApy } from '../../staking';
|
|
12
|
+
import { MMAssetsData } from '../../types/common';
|
|
13
|
+
import { getEthAmountForDecimals } from '../../services/utils';
|
|
14
|
+
|
|
15
|
+
const calculateNetApyDex = ({ marketData, suppliedUsd, borrowedUsd }: { marketData: InnerFluidMarketData, suppliedUsd: string, borrowedUsd: string }) => {
|
|
16
|
+
const {
|
|
17
|
+
borrowRate,
|
|
18
|
+
supplyRate,
|
|
19
|
+
incentiveBorrowRate,
|
|
20
|
+
incentiveSupplyRate,
|
|
21
|
+
tradingBorrowRate,
|
|
22
|
+
tradingSupplyRate,
|
|
23
|
+
} = marketData;
|
|
24
|
+
|
|
25
|
+
const totalBorrowRate = new Dec(borrowRate).minus(tradingBorrowRate || '0').toString();
|
|
26
|
+
const totalSupplyRate = new Dec(supplyRate).add(tradingSupplyRate || '0').toString();
|
|
27
|
+
|
|
28
|
+
const borrowIncentive = new Dec(incentiveBorrowRate || '0').mul(borrowedUsd).div(100).toString();
|
|
29
|
+
const supplyIncentive = new Dec(incentiveSupplyRate || '0').mul(suppliedUsd).div(100).toString();
|
|
30
|
+
const incentiveUsd = new Dec(supplyIncentive).minus(borrowIncentive).toString();
|
|
31
|
+
|
|
32
|
+
const borrowInterest = new Dec(totalBorrowRate).mul(borrowedUsd).div(100).toString();
|
|
33
|
+
const supplyInterest = new Dec(totalSupplyRate).mul(suppliedUsd).div(100).toString();
|
|
34
|
+
const totalInterestUsd = new Dec(supplyInterest).add(incentiveUsd).minus(borrowInterest).toString();
|
|
35
|
+
const balance = new Dec(suppliedUsd).sub(borrowedUsd).toString();
|
|
36
|
+
const netApy = new Dec(totalInterestUsd).div(balance).times(100).toString();
|
|
37
|
+
|
|
38
|
+
return {
|
|
39
|
+
netApy,
|
|
40
|
+
incentiveUsd,
|
|
41
|
+
totalInterestUsd,
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export const getFluidAggregatedData = ({
|
|
46
|
+
usedAssets,
|
|
47
|
+
assetsData,
|
|
48
|
+
marketData,
|
|
49
|
+
}: {
|
|
50
|
+
usedAssets: FluidUsedAssets,
|
|
51
|
+
marketData: InnerFluidMarketData,
|
|
52
|
+
assetsData: FluidAssetsData
|
|
53
|
+
},
|
|
54
|
+
supplyShares?: string,
|
|
55
|
+
borrowShares?: string,
|
|
56
|
+
): FluidAggregatedVaultData => {
|
|
57
|
+
const payload = {} as FluidAggregatedVaultData;
|
|
58
|
+
|
|
59
|
+
payload.suppliedUsd = [FluidVaultType.T1, FluidVaultType.T3].includes(marketData.vaultType)
|
|
60
|
+
? getAssetsTotal(usedAssets, ({ isSupplied }: { isSupplied: boolean }) => isSupplied, ({ suppliedUsd }: { suppliedUsd: string }) => suppliedUsd)
|
|
61
|
+
: new Dec(marketData.collSharePrice!).mul(supplyShares!).toString();
|
|
62
|
+
payload.borrowedUsd = [FluidVaultType.T1, FluidVaultType.T2].includes(marketData.vaultType)
|
|
63
|
+
? getAssetsTotal(usedAssets, ({ isBorrowed }: { isBorrowed: boolean }) => isBorrowed, ({ borrowedUsd }: { borrowedUsd: string }) => borrowedUsd)
|
|
64
|
+
: new Dec(marketData.debtSharePrice!).mul(borrowShares!).toString();
|
|
65
|
+
|
|
66
|
+
const isDex = [FluidVaultType.T2, FluidVaultType.T3, FluidVaultType.T4].includes(marketData.vaultType);
|
|
67
|
+
const { netApy, incentiveUsd, totalInterestUsd } = isDex ? calculateNetApyDex({ marketData, suppliedUsd: payload.suppliedUsd, borrowedUsd: payload.borrowedUsd }) : calculateNetApy({ usedAssets, assetsData: assetsData as unknown as MMAssetsData });
|
|
68
|
+
payload.netApy = netApy;
|
|
69
|
+
payload.incentiveUsd = incentiveUsd;
|
|
70
|
+
payload.totalInterestUsd = totalInterestUsd;
|
|
71
|
+
const collFactor = marketData.collFactor;
|
|
72
|
+
const liqRatio = marketData.liquidationRatio;
|
|
73
|
+
|
|
74
|
+
payload.borrowLimitUsd = new Dec(payload.suppliedUsd).mul(collFactor).toString();
|
|
75
|
+
payload.liquidationLimitUsd = new Dec(payload.suppliedUsd).mul(liqRatio).div(100).toString();
|
|
76
|
+
const leftToBorrowUsd = new Dec(payload.borrowLimitUsd).sub(payload.borrowedUsd);
|
|
77
|
+
payload.leftToBorrowUsd = leftToBorrowUsd.lte('0') ? '0' : leftToBorrowUsd.toString();
|
|
78
|
+
payload.ratio = +payload.suppliedUsd ? new Dec(payload.borrowLimitUsd).div(payload.borrowedUsd).mul(100).toString() : '0';
|
|
79
|
+
payload.collRatio = +payload.suppliedUsd ? new Dec(payload.suppliedUsd).div(payload.borrowedUsd).mul(100).toString() : '0';
|
|
80
|
+
payload.minRatio = marketData.minRatio;
|
|
81
|
+
const { leveragedType, leveragedAsset } = isLeveragedPos(usedAssets);
|
|
82
|
+
|
|
83
|
+
payload.leveragedType = leveragedType;
|
|
84
|
+
if (leveragedType !== '') {
|
|
85
|
+
payload.leveragedAsset = leveragedAsset;
|
|
86
|
+
let assetPrice = assetsData[leveragedAsset].price;
|
|
87
|
+
if (leveragedType === 'lsd-leverage') {
|
|
88
|
+
// Treat ETH like a stablecoin in a long stETH position
|
|
89
|
+
payload.leveragedLsdAssetRatio = new Dec(assetsData[leveragedAsset].price).div(assetsData.ETH.price).toDP(18).toString();
|
|
90
|
+
assetPrice = new Dec(assetPrice).div(assetsData.ETH.price).toString();
|
|
91
|
+
}
|
|
92
|
+
payload.liquidationPrice = calcLeverageLiqPrice(leveragedType, assetPrice, payload.borrowedUsd, payload.liquidationLimitUsd);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
payload.minCollRatio = new Dec(payload.suppliedUsd).div(payload.borrowLimitUsd).mul(100).toString();
|
|
96
|
+
payload.collLiquidationRatio = new Dec(payload.suppliedUsd).div(payload.liquidationLimitUsd).mul(100).toString();
|
|
97
|
+
|
|
98
|
+
return payload;
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
interface DexSupplyData {
|
|
103
|
+
maxSupplyShares: string
|
|
104
|
+
supplyDexFee: string
|
|
105
|
+
token0PerSupplyShare: string
|
|
106
|
+
token1PerSupplyShare: string
|
|
107
|
+
withdrawable0: string
|
|
108
|
+
withdrawable1: string
|
|
109
|
+
withdrawableShares: string
|
|
110
|
+
utilizationSupply0: string
|
|
111
|
+
utilizationSupply1: string
|
|
112
|
+
supplyRate0: string
|
|
113
|
+
supplyRate1: string
|
|
114
|
+
totalSupplyShares: string
|
|
115
|
+
withdrawableToken0: string
|
|
116
|
+
withdrawableToken1: string
|
|
117
|
+
totalSupplyToken0: string
|
|
118
|
+
totalSupplyToken1: string
|
|
119
|
+
reservesSupplyToken0: string
|
|
120
|
+
reservesSupplyToken1: string
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export const parseDexSupplyData = (dexSupplyData: FluidDexSupplyDataStructOutput, collAsset0: string, collAsset1: string): DexSupplyData => {
|
|
124
|
+
const {
|
|
125
|
+
dexPool, // address of the dex pool
|
|
126
|
+
dexId, // id of the dex pool
|
|
127
|
+
fee: _fee, // fee of the dex pool (Only used as swap fees)
|
|
128
|
+
lastStoredPrice, // last stored price of the dex pool
|
|
129
|
+
centerPrice, // center price of the dex pool
|
|
130
|
+
token0Utilization, // token0 utilization
|
|
131
|
+
token1Utilization, // token1 utilization
|
|
132
|
+
// ONLY FOR SUPPLY
|
|
133
|
+
totalSupplyShares: totalSupplySharesWei, // total supply shares, in 1e18
|
|
134
|
+
maxSupplyShares: maxSupplySharesWei, // max supply shares, in 1e18
|
|
135
|
+
token0Supplied, // token0 supplied, in token0 decimals
|
|
136
|
+
token1Supplied, // token1 supplied, in token1 decimals
|
|
137
|
+
sharesWithdrawable, // shares withdrawable, in 1e18
|
|
138
|
+
token0Withdrawable, // token0 withdrawable, in token0 decimals
|
|
139
|
+
token1Withdrawable, // token1 withdrawable, in token1 decimals
|
|
140
|
+
token0PerSupplyShare: token0PerSupplyShareWei, // token0 amount per 1e18 supply shares
|
|
141
|
+
token1PerSupplyShare: token1PerSupplyShareWei, // token1 amount per 1e18 supply shares
|
|
142
|
+
token0SupplyRate, // token0 supply rate. E.g 320 = 3.2% APR
|
|
143
|
+
token1SupplyRate, // token1 supply rate. E.g 320 = 3.2% APR
|
|
144
|
+
supplyToken0Reserves, // token0 reserves in the dex pool
|
|
145
|
+
supplyToken1Reserves, // token1 reserves in the dex pool
|
|
146
|
+
} = dexSupplyData;
|
|
147
|
+
|
|
148
|
+
const maxSupplyShares = getEthAmountForDecimals(maxSupplySharesWei.toString(), 18);
|
|
149
|
+
const fee = new Dec(_fee).div(100).toString();
|
|
150
|
+
|
|
151
|
+
const token0PerSupplyShare = assetAmountInEth(token0PerSupplyShareWei.toString(), collAsset0);
|
|
152
|
+
const token1PerSupplyShare = assetAmountInEth(token1PerSupplyShareWei.toString(), collAsset1);
|
|
153
|
+
|
|
154
|
+
const withdrawable0 = assetAmountInEth(token0Withdrawable.toString(), collAsset0);
|
|
155
|
+
const withdrawable1 = assetAmountInEth(token1Withdrawable.toString(), collAsset1);
|
|
156
|
+
const utilizationSupply0 = assetAmountInEth(token0Utilization.toString(), collAsset0);
|
|
157
|
+
const utilizationSupply1 = assetAmountInEth(token1Utilization.toString(), collAsset1);
|
|
158
|
+
|
|
159
|
+
const supplyRate0 = new Dec(token0SupplyRate).div(100).toString();
|
|
160
|
+
const supplyRate1 = new Dec(token1SupplyRate).div(100).toString();
|
|
161
|
+
|
|
162
|
+
const totalSupplyShares = getEthAmountForDecimals(totalSupplySharesWei.toString(), 18); // in shares
|
|
163
|
+
|
|
164
|
+
const withdrawableShares = getEthAmountForDecimals(sharesWithdrawable.toString(), 18);
|
|
165
|
+
const withdrawableToken0 = new Dec(withdrawableShares).mul(token0PerSupplyShare).div(1e18).toString();
|
|
166
|
+
const withdrawableToken1 = new Dec(withdrawableShares).mul(token1PerSupplyShare).div(1e18).toString();
|
|
167
|
+
|
|
168
|
+
const totalSupplyToken0 = assetAmountInEth(token0Supplied.toString(), collAsset0);
|
|
169
|
+
const totalSupplyToken1 = assetAmountInEth(token1Supplied.toString(), collAsset1);
|
|
170
|
+
|
|
171
|
+
const reservesSupplyToken0 = assetAmountInEth(supplyToken0Reserves.toString(), collAsset0);
|
|
172
|
+
const reservesSupplyToken1 = assetAmountInEth(supplyToken1Reserves.toString(), collAsset1);
|
|
173
|
+
|
|
174
|
+
return {
|
|
175
|
+
maxSupplyShares,
|
|
176
|
+
withdrawableShares,
|
|
177
|
+
supplyDexFee: fee,
|
|
178
|
+
token0PerSupplyShare,
|
|
179
|
+
token1PerSupplyShare,
|
|
180
|
+
withdrawable0,
|
|
181
|
+
withdrawable1,
|
|
182
|
+
utilizationSupply0,
|
|
183
|
+
utilizationSupply1,
|
|
184
|
+
supplyRate0,
|
|
185
|
+
supplyRate1,
|
|
186
|
+
totalSupplyShares,
|
|
187
|
+
withdrawableToken0,
|
|
188
|
+
withdrawableToken1,
|
|
189
|
+
totalSupplyToken0,
|
|
190
|
+
totalSupplyToken1,
|
|
191
|
+
reservesSupplyToken0,
|
|
192
|
+
reservesSupplyToken1,
|
|
193
|
+
};
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
interface DexBorrowData {
|
|
197
|
+
maxBorrowShares: string
|
|
198
|
+
borrowDexFee: string
|
|
199
|
+
token0PerBorrowShare: string
|
|
200
|
+
token1PerBorrowShare: string
|
|
201
|
+
borrowable0: string
|
|
202
|
+
borrowable1: string
|
|
203
|
+
utilizationBorrow0: string
|
|
204
|
+
utilizationBorrow1: string
|
|
205
|
+
borrowRate0: string
|
|
206
|
+
borrowRate1: string
|
|
207
|
+
totalBorrowShares: string
|
|
208
|
+
borrowableToken0: string
|
|
209
|
+
borrowableToken1: string
|
|
210
|
+
totalBorrowToken0: string
|
|
211
|
+
totalBorrowToken1: string
|
|
212
|
+
borrowableShares: string
|
|
213
|
+
quoteTokensPerShare: string
|
|
214
|
+
reservesBorrowToken0: string
|
|
215
|
+
reservesBorrowToken1: string
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
export const parseDexBorrowData = (dexBorrowData: FluidDexBorrowDataStructOutput, debtAsset0: string, debtAsset1: string): DexBorrowData => {
|
|
219
|
+
const {
|
|
220
|
+
dexPool,
|
|
221
|
+
dexId,
|
|
222
|
+
fee: _fee,
|
|
223
|
+
lastStoredPrice,
|
|
224
|
+
centerPrice,
|
|
225
|
+
token0Utilization,
|
|
226
|
+
token1Utilization,
|
|
227
|
+
totalBorrowShares: totalBorrowSharesWei,
|
|
228
|
+
maxBorrowShares: maxBorrowSharesWei,
|
|
229
|
+
token0Borrowed,
|
|
230
|
+
token1Borrowed,
|
|
231
|
+
sharesBorrowable,
|
|
232
|
+
token0Borrowable,
|
|
233
|
+
token1Borrowable,
|
|
234
|
+
token0PerBorrowShare: token0PerBorrowShareWei,
|
|
235
|
+
token1PerBorrowShare: token1PerBorrowShareWei,
|
|
236
|
+
token0BorrowRate,
|
|
237
|
+
token1BorrowRate,
|
|
238
|
+
quoteTokensPerShare,
|
|
239
|
+
borrowToken0Reserves,
|
|
240
|
+
borrowToken1Reserves,
|
|
241
|
+
} = dexBorrowData;
|
|
242
|
+
|
|
243
|
+
const maxBorrowShares = getEthAmountForDecimals(maxBorrowSharesWei.toString(), 18);
|
|
244
|
+
const fee = new Dec(_fee).div(100).toString();
|
|
245
|
+
|
|
246
|
+
const token0PerBorrowShare = assetAmountInEth(token0PerBorrowShareWei.toString(), debtAsset0);
|
|
247
|
+
const token1PerBorrowShare = assetAmountInEth(token1PerBorrowShareWei.toString(), debtAsset1);
|
|
248
|
+
|
|
249
|
+
const borrowable0 = assetAmountInEth(token0Borrowable.toString(), debtAsset0);
|
|
250
|
+
const borrowable1 = assetAmountInEth(token1Borrowable.toString(), debtAsset1);
|
|
251
|
+
const utilizationBorrow0 = assetAmountInEth(token0Utilization.toString(), debtAsset0);
|
|
252
|
+
const utilizationBorrow1 = assetAmountInEth(token1Utilization.toString(), debtAsset1);
|
|
253
|
+
|
|
254
|
+
const borrowRate0 = new Dec(token0BorrowRate).div(100).toString();
|
|
255
|
+
const borrowRate1 = new Dec(token1BorrowRate).div(100).toString();
|
|
256
|
+
|
|
257
|
+
const totalBorrowShares = getEthAmountForDecimals(totalBorrowSharesWei.toString(), 18); // in shares
|
|
258
|
+
|
|
259
|
+
const borrowableShares = getEthAmountForDecimals(sharesBorrowable.toString(), 18);
|
|
260
|
+
const borrowableToken0 = new Dec(borrowableShares).mul(token0PerBorrowShare).div(1e18).toString();
|
|
261
|
+
const borrowableToken1 = new Dec(borrowableShares).mul(token1PerBorrowShare).div(1e18).toString();
|
|
262
|
+
|
|
263
|
+
const totalBorrowToken0 = assetAmountInEth(token0Borrowed.toString(), debtAsset0);
|
|
264
|
+
const totalBorrowToken1 = assetAmountInEth(token1Borrowed.toString(), debtAsset1);
|
|
265
|
+
|
|
266
|
+
const reservesBorrowToken0 = assetAmountInEth(borrowToken0Reserves.toString(), debtAsset0);
|
|
267
|
+
const reservesBorrowToken1 = assetAmountInEth(borrowToken1Reserves.toString(), debtAsset1);
|
|
268
|
+
|
|
269
|
+
return {
|
|
270
|
+
borrowableShares,
|
|
271
|
+
maxBorrowShares,
|
|
272
|
+
borrowDexFee: fee,
|
|
273
|
+
token0PerBorrowShare,
|
|
274
|
+
token1PerBorrowShare,
|
|
275
|
+
borrowable0,
|
|
276
|
+
borrowable1,
|
|
277
|
+
utilizationBorrow0,
|
|
278
|
+
utilizationBorrow1,
|
|
279
|
+
borrowRate0,
|
|
280
|
+
borrowRate1,
|
|
281
|
+
totalBorrowShares,
|
|
282
|
+
borrowableToken0,
|
|
283
|
+
borrowableToken1,
|
|
284
|
+
totalBorrowToken0,
|
|
285
|
+
totalBorrowToken1,
|
|
286
|
+
quoteTokensPerShare: getEthAmountForDecimals(quoteTokensPerShare.toString(), 27),
|
|
287
|
+
reservesBorrowToken0,
|
|
288
|
+
reservesBorrowToken1,
|
|
289
|
+
};
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
const EMPTY_ASSET_DATA = {
|
|
293
|
+
symbol: '',
|
|
294
|
+
address: '',
|
|
295
|
+
price: '0',
|
|
296
|
+
totalSupply: '',
|
|
297
|
+
totalBorrow: '0',
|
|
298
|
+
canBeSupplied: false,
|
|
299
|
+
canBeBorrowed: false,
|
|
300
|
+
supplyRate: '0',
|
|
301
|
+
borrowRate: '0',
|
|
302
|
+
supplyIncentives: [],
|
|
303
|
+
borrowIncentives: [],
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
export const mergeAssetData = (existing: Partial<FluidAssetData> = {}, additional: Partial<FluidAssetData>): FluidAssetData => ({
|
|
307
|
+
...EMPTY_ASSET_DATA,
|
|
308
|
+
...existing,
|
|
309
|
+
...additional,
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
export const EMPTY_USED_ASSET = {
|
|
313
|
+
isSupplied: false,
|
|
314
|
+
isBorrowed: false,
|
|
315
|
+
supplied: '0',
|
|
316
|
+
suppliedUsd: '0',
|
|
317
|
+
borrowed: '0',
|
|
318
|
+
borrowedUsd: '0',
|
|
319
|
+
symbol: '',
|
|
320
|
+
collateral: false,
|
|
321
|
+
};
|
|
322
|
+
|
|
323
|
+
export const mergeUsedAssets = (existing: Partial<FluidUsedAsset> = {}, additional: Partial<FluidUsedAsset>): FluidUsedAsset => ({
|
|
324
|
+
...EMPTY_USED_ASSET,
|
|
325
|
+
...existing,
|
|
326
|
+
...additional,
|
|
327
327
|
});
|