@evaafi/sdk 0.5.4 → 0.5.6

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 (48) hide show
  1. package/dist/api/helpers.js +2 -3
  2. package/dist/api/math.d.ts +24 -2
  3. package/dist/api/math.js +189 -62
  4. package/dist/api/parser.d.ts +3 -3
  5. package/dist/api/parser.js +37 -25
  6. package/dist/api/prices.d.ts +1 -1
  7. package/dist/api/prices.js +3 -3
  8. package/dist/config.d.ts +2 -0
  9. package/dist/config.js +5 -0
  10. package/dist/constants/assets.d.ts +2 -3
  11. package/dist/constants/assets.js +10 -2
  12. package/dist/constants/general.d.ts +3 -2
  13. package/dist/constants/general.js +6 -5
  14. package/dist/constants/pools.d.ts +0 -1
  15. package/dist/constants/pools.js +1 -14
  16. package/dist/constants.d.ts +5 -34
  17. package/dist/constants.js +90 -37
  18. package/dist/contracts/MasterContract.d.ts +13 -45
  19. package/dist/contracts/MasterContract.js +10 -12
  20. package/dist/contracts/UserContract.js +7 -7
  21. package/dist/index.d.ts +6 -5
  22. package/dist/index.js +5 -3
  23. package/dist/types/Master.d.ts +8 -7
  24. package/dist/types/User.d.ts +5 -5
  25. package/dist/utils/merkleProof.d.ts +4 -0
  26. package/dist/utils/merkleProof.js +107 -0
  27. package/dist/utils/priceUtils.d.ts +55 -0
  28. package/dist/utils/priceUtils.js +117 -0
  29. package/dist/utils/sha256BigInt.js +1 -2
  30. package/dist/utils/tonConnectSender.js +2 -3
  31. package/dist/utils/userJettonWallet.d.ts +2 -2
  32. package/dist/utils/userJettonWallet.js +5 -2
  33. package/dist/utils/utils.d.ts +2 -0
  34. package/dist/utils/utils.js +6 -0
  35. package/package.json +2 -2
  36. package/src/api/math.ts +229 -50
  37. package/src/api/parser.ts +52 -37
  38. package/src/api/prices.ts +2 -1
  39. package/src/constants/assets.ts +11 -3
  40. package/src/constants/general.ts +6 -4
  41. package/src/constants/pools.ts +1 -15
  42. package/src/contracts/MasterContract.ts +25 -67
  43. package/src/contracts/UserContract.ts +8 -10
  44. package/src/index.ts +4 -7
  45. package/src/types/Master.ts +9 -8
  46. package/src/types/User.ts +5 -5
  47. package/src/utils/userJettonWallet.ts +6 -2
  48. package/src/utils/utils.ts +6 -0
package/src/api/math.ts CHANGED
@@ -1,7 +1,9 @@
1
- import { AssetConfig, AssetData, AssetInterest, ExtendedAssetData, ExtendedAssetsConfig, ExtendedAssetsData, MasterConstants } from '../types/Master';
1
+ import { AgregatedBalances, AssetConfig, AssetData, AssetInterest, ExtendedAssetData, ExtendedAssetsConfig, ExtendedAssetsData, MasterConstants, PoolConfig } from '../types/Master';
2
2
  import { Dictionary } from '@ton/core';
3
3
  import { BalanceChangeType, BalanceType, LiquidationData, PredictHealthFactorArgs, UserBalance } from '../types/User';
4
4
  import { sha256Hash } from '../utils/sha256BigInt';
5
+ import { TON_MAINNET, UNDEFINED_ASSET } from '../constants/assets';
6
+ import { MAINNET_POOL_CONFIG, TESTNET_POOL_CONFIG } from '..';
5
7
 
6
8
  export function mulFactor(decimal: bigint, a: bigint, b: bigint): bigint {
7
9
  return (a * b) / decimal;
@@ -11,6 +13,11 @@ export function mulDiv(x: bigint, y: bigint, z: bigint): bigint {
11
13
  return (x * y) / z;
12
14
  }
13
15
 
16
+ export function mulDivC(x: bigint, y: bigint, z: bigint): bigint {
17
+ const mul = x * y;
18
+ return mul / z + (mul % z ? 1n : 0n);
19
+ }
20
+
14
21
  export function bigIntMax(...args: bigint[]): bigint {
15
22
  return args.reduce((m, e) => (e > m ? e : m));
16
23
  }
@@ -116,6 +123,165 @@ export function calculateAssetInterest(assetConfig: AssetConfig, assetData: Asse
116
123
  };
117
124
  }
118
125
 
126
+ export function checkNotInDebtAtAll(principals: Dictionary<bigint, bigint>): boolean {
127
+ return principals.values().every(x => x >= 0n);
128
+ }
129
+
130
+ export function getAgregatedBalances (
131
+ assetsData: ExtendedAssetsData,
132
+ assetsConfig: ExtendedAssetsConfig,
133
+ principals: Dictionary<bigint, bigint>,
134
+ prices: Dictionary<bigint, bigint>,
135
+ masterConstants: MasterConstants,
136
+ ): AgregatedBalances {
137
+ let user_total_supply = 0n;
138
+ let user_total_borrow = 0n;
139
+
140
+ for (const [assetId, principal] of principals) {
141
+
142
+ if (principal) {
143
+
144
+ if (!prices.has(assetId)) {
145
+ return {totalSupply: 0n, totalBorrow: 0n};
146
+ }
147
+ const price = prices.get(assetId)!;
148
+ const assetData = assetsData.get(assetId)!;
149
+ const assetConfig = assetsConfig.get(assetId)!;
150
+
151
+ if (principal < 0) {
152
+ user_total_borrow += presentValue(assetData.sRate, assetData.bRate, principal, masterConstants).amount * price / 10n ** assetConfig.decimals;
153
+ } else {
154
+ user_total_supply += presentValue(assetData.sRate, assetData.bRate, principal, masterConstants).amount * price / 10n ** assetConfig.decimals;
155
+ }
156
+
157
+ }
158
+ }
159
+ return {totalSupply: user_total_supply, totalBorrow: user_total_borrow};
160
+ }
161
+
162
+ /**
163
+ * @deprecated The method should be used only for main contract v5
164
+ */
165
+ export function isV5MainPoolContract(poolConfig: PoolConfig): boolean {
166
+ if ((poolConfig.masterAddress == MAINNET_POOL_CONFIG.masterAddress && poolConfig.masterVersion == 5) ||
167
+ (poolConfig.masterAddress == TESTNET_POOL_CONFIG.masterAddress && poolConfig.masterVersion == 5)) {
168
+ return true;
169
+ } else {
170
+ return false;
171
+ }
172
+ }
173
+
174
+ /**
175
+ * @deprecated The method should be used only for main contract v5
176
+ */
177
+ export function calculateMaximumWithdrawAmountOld(
178
+ assetsConfig: ExtendedAssetsConfig,
179
+ assetsData: ExtendedAssetsData,
180
+ principals: Dictionary<bigint, bigint>,
181
+ prices: Dictionary<bigint, bigint>,
182
+ masterConstants: MasterConstants,
183
+ assetId: bigint,
184
+ ): bigint {
185
+ let withdrawAmountMax = 0n;
186
+
187
+ const assetConfig = assetsConfig.get(assetId) as AssetConfig;
188
+ const assetData = assetsData.get(assetId) as ExtendedAssetData;
189
+ const oldPrincipal = principals.get(assetId) as bigint;
190
+ const oldPresentValue = presentValue(assetData.sRate, assetData.bRate, oldPrincipal, masterConstants);
191
+
192
+ if (oldPresentValue.amount > assetConfig.dust) {
193
+ if(checkNotInDebtAtAll(principals)) {
194
+ withdrawAmountMax = oldPresentValue.amount;
195
+ } else {
196
+ if (!prices.has(assetId)) {
197
+ return 0n;
198
+ }
199
+
200
+ //const borrowable = getAvailableToBorrow(assetsConfig, assetsData, principals, prices, masterConstants);
201
+ const price = prices.get(assetId) as bigint;
202
+ const agregatedBalances = getAgregatedBalances(assetsData, assetsConfig, principals, principals, masterConstants);
203
+ let maxAmountToReclaim =
204
+ mulDiv(
205
+ agregatedBalances.totalSupply - mulDivC(agregatedBalances.totalBorrow, masterConstants.ASSET_COEFFICIENT_SCALE, assetConfig.collateralFactor),
206
+ 10n**assetConfig.decimals,
207
+ price
208
+ );
209
+
210
+ withdrawAmountMax = bigIntMin(
211
+ maxAmountToReclaim,
212
+ oldPresentValue.amount
213
+ );
214
+ }
215
+ } else {
216
+ if (!prices.has(assetId)) {
217
+ return 0n;
218
+ }
219
+
220
+ const price = prices.get(assetId) as bigint;
221
+
222
+ return getAvailableToBorrow(assetsConfig, assetsData, principals, prices, masterConstants) * (10n ** assetConfig.decimals) / price;
223
+ }
224
+
225
+ return withdrawAmountMax;
226
+ }
227
+
228
+ export function calculateMaximumWithdrawAmount( // todo v6 ifelse dust not debt at all is fixed?
229
+ assetsConfig: ExtendedAssetsConfig,
230
+ assetsData: ExtendedAssetsData,
231
+ principals: Dictionary<bigint, bigint>,
232
+ prices: Dictionary<bigint, bigint>,
233
+ masterConstants: MasterConstants,
234
+ assetId: bigint,
235
+ ): bigint {
236
+ let withdrawAmountMax = 0n;
237
+
238
+ const assetConfig = assetsConfig.get(assetId) as AssetConfig;
239
+ const assetData = assetsData.get(assetId) as ExtendedAssetData;
240
+ const oldPrincipal = principals.get(assetId) as bigint;
241
+
242
+ if (oldPrincipal > assetConfig.dust) {
243
+ const oldPresentValue = presentValue(assetData.sRate, assetData.bRate, oldPrincipal, masterConstants);
244
+ if(checkNotInDebtAtAll(principals)) {
245
+ withdrawAmountMax = oldPresentValue.amount;
246
+ } else {
247
+ if (!prices.has(assetId)) {
248
+ return 0n;
249
+ }
250
+
251
+ const borrowable = getAvailableToBorrow(assetsConfig, assetsData, principals, prices, masterConstants);
252
+ const price = prices.get(assetId) as bigint;
253
+
254
+ let maxAmountToReclaim = 0n;
255
+
256
+ if (assetConfig.collateralFactor == 0n) {
257
+ maxAmountToReclaim = oldPresentValue.amount;
258
+ }
259
+ else if (price > 0) {
260
+ maxAmountToReclaim =
261
+ mulDiv(
262
+ mulDivC(borrowable, masterConstants.ASSET_COEFFICIENT_SCALE, assetConfig.collateralFactor),
263
+ 10n ** assetConfig.decimals, price
264
+ );
265
+ }
266
+
267
+ withdrawAmountMax = bigIntMin(
268
+ maxAmountToReclaim,
269
+ oldPresentValue.amount
270
+ );
271
+ }
272
+ } else {
273
+ if (!prices.has(assetId)) {
274
+ return 0n;
275
+ }
276
+
277
+ const price = prices.get(assetId) as bigint;
278
+
279
+ return getAvailableToBorrow(assetsConfig, assetsData, principals, prices, masterConstants) * (10n ** assetConfig.decimals) / price;
280
+ }
281
+
282
+ return withdrawAmountMax;
283
+ }
284
+
119
285
  export function getAvailableToBorrow(
120
286
  assetsConfig: ExtendedAssetsConfig,
121
287
  assetsData: ExtendedAssetsData,
@@ -136,9 +302,10 @@ export function getAvailableToBorrow(
136
302
  borrowAmount += (calculatePresentValue(assetData.bRate, -principal, masterConstants) * price) / 10n ** assetConfig.decimals;
137
303
  } else if (principal > 0) {
138
304
  borrowLimit +=
139
- (calculatePresentValue(assetData.sRate, principal, masterConstants) * price * assetConfig.collateralFactor) /
140
- 10n ** assetConfig.decimals /
141
- masterConstants.ASSET_COEFFICIENT_SCALE;
305
+ mulDivC(
306
+ mulDivC(calculatePresentValue(assetData.sRate, principal, masterConstants), price, 10n ** assetConfig.decimals),
307
+ assetConfig.collateralFactor,
308
+ masterConstants.ASSET_COEFFICIENT_SCALE);
142
309
  }
143
310
  }
144
311
 
@@ -164,74 +331,86 @@ export function presentValue(sRate: bigint, bRate: bigint, principalValue: bigin
164
331
  }
165
332
  }
166
333
 
334
+ /**
335
+ *
336
+ * @param assetsConfig
337
+ * @param assetsData
338
+ * @param principals
339
+ * @param prices
340
+ * @param poolConfig
341
+ * @returns can return UNDEFINED_ASSET if there are no assets
342
+ */
167
343
  export function calculateLiquidationData(
168
344
  assetsConfig: ExtendedAssetsConfig,
169
345
  assetsData: ExtendedAssetsData,
170
346
  principals: Dictionary<bigint, bigint>,
171
347
  prices: Dictionary<bigint, bigint>,
172
- masterConstants: MasterConstants,
348
+ poolConfig: PoolConfig,
173
349
  ): LiquidationData {
174
- let gCollateralValue = 0n;
175
- let gCollateralAsset = 0n;
176
- let gLoanValue = 0n;
177
- let gLoanAsset = 0n;
350
+ let collateralValue = 0n;
351
+ let collateralAsset = UNDEFINED_ASSET;
352
+ let loanValue = 0n;
353
+ let loanAsset = UNDEFINED_ASSET;
178
354
  let totalDebt = 0n;
179
355
  let totalLimit = 0n;
180
356
 
181
- for (const key of principals.keys()) {
182
- const principal = principals.get(key)!;
183
- const assetConfig = assetsConfig.get(key)!;
184
- const assetData = assetsData.get(key)!;
357
+ for (const asset of poolConfig.poolAssetsConfig) {
358
+ if (!principals.has(asset.assetId)) {
359
+ continue;
360
+ }
361
+ const principal = principals.get(asset.assetId)!;
362
+ const assetConfig = assetsConfig.get(asset.assetId)!;
363
+ const assetData = assetsData.get(asset.assetId)!;
185
364
  const balance =
186
365
  principal > 0 ? (principal * assetData.sRate) / BigInt(1e12) : (principal * assetData.bRate) / BigInt(1e12);
187
366
  if (balance > 0) {
188
- const assetWorth = (balance * prices.get(key)!) / 10n ** assetConfig.decimals;
189
- totalLimit += (assetWorth * assetConfig.liquidationThreshold) / masterConstants.ASSET_COEFFICIENT_SCALE;
190
- if (assetWorth > gCollateralValue) {
191
- gCollateralValue = assetWorth;
192
- gCollateralAsset = key;
367
+ const assetWorth = (balance * prices.get(asset.assetId)!) / 10n ** assetConfig.decimals;
368
+ totalLimit += (assetWorth * assetConfig.liquidationThreshold) / poolConfig.masterConstants.ASSET_COEFFICIENT_SCALE;
369
+ if (assetWorth > collateralValue) {
370
+ collateralValue = assetWorth;
371
+ collateralAsset = asset;
193
372
  }
194
373
  } else if (balance < 0) {
195
- const assetWorth = (-balance * prices.get(key)!) / 10n ** assetConfig.decimals;
374
+ const assetWorth = (-balance * prices.get(asset.assetId)!) / 10n ** assetConfig.decimals;
196
375
  totalDebt += assetWorth;
197
- if (assetWorth > gLoanValue) {
198
- gLoanValue = assetWorth;
199
- gLoanAsset = key;
376
+ if (assetWorth > loanValue) {
377
+ loanValue = assetWorth;
378
+ loanAsset = asset;
200
379
  }
201
380
  }
202
381
  }
203
382
 
204
- if (totalLimit < totalDebt) {
205
- const gLoanAssetPrice = prices.get(gLoanAsset)!;
383
+ if (collateralAsset.assetId !== UNDEFINED_ASSET.assetId && totalLimit < totalDebt) {
384
+ const loanAssetPrice = prices.get(loanAsset.assetId)!;
206
385
  const values: bigint[] = [];
207
- const gCollateralAssetConfig = assetsConfig.get(gCollateralAsset)!;
208
- const gLoanAssetConfig = assetsConfig.get(gLoanAsset)!;
209
- const liquidationBonus = gCollateralAssetConfig.liquidationBonus;
210
- const loanDecimal = 10n ** gLoanAssetConfig.decimals;
386
+ const collateralAssetConfig = assetsConfig.get(collateralAsset.assetId)!;
387
+ const loanAssetConfig = assetsConfig.get(loanAsset.assetId)!;
388
+ const liquidationBonus = collateralAssetConfig.liquidationBonus;
389
+ const loanScale = 10n ** loanAssetConfig.decimals;
211
390
  values.push(
212
- (bigIntMax(gCollateralValue / 2n, bigIntMin(gCollateralValue, 10_000_000_000n)) *
213
- loanDecimal *
214
- masterConstants.ASSET_COEFFICIENT_SCALE) /
391
+ (bigIntMax(collateralValue / 2n, bigIntMin(collateralValue, 100_000_000_000n)) *
392
+ loanScale *
393
+ poolConfig.masterConstants.ASSET_COEFFICIENT_SCALE) /
215
394
  liquidationBonus /
216
- gLoanAssetPrice,
395
+ loanAssetPrice,
217
396
  );
218
- values.push((gLoanValue * loanDecimal) / gLoanAssetPrice);
397
+ values.push((loanValue * loanScale) / loanAssetPrice);
219
398
 
220
399
  const liquidationAmount = (bigIntMin(...values) as bigint) - 5n;
221
- const gCollateralAssetPrice: bigint = prices.get(gCollateralAsset)!;
222
- const collateralDecimal = 10n ** gCollateralAssetConfig.decimals;
400
+ const collateralAssetPrice: bigint = prices.get(collateralAsset.assetId)!;
401
+ const collateralDecimal = 10n ** collateralAssetConfig.decimals;
223
402
  let minCollateralAmount =
224
- (((liquidationAmount * gLoanAssetPrice * liquidationBonus) / 10000n) * collateralDecimal) /
225
- gCollateralAssetPrice /
226
- loanDecimal -
403
+ (((liquidationAmount * loanAssetPrice * liquidationBonus) / poolConfig.masterConstants.ASSET_LIQUIDATION_BONUS_SCALE) * collateralDecimal) /
404
+ collateralAssetPrice /
405
+ loanScale -
227
406
  10n;
228
407
  minCollateralAmount = (minCollateralAmount * 97n) / 100n;
229
408
  if (minCollateralAmount / collateralDecimal >= 1n) {
230
409
  return {
231
- greatestCollateralAsset: gCollateralAsset,
232
- greatestCollateralValue: gCollateralValue,
233
- greatestLoanAsset: gLoanAsset,
234
- greatestLoanValue: gLoanValue,
410
+ greatestCollateralAsset: collateralAsset,
411
+ greatestCollateralValue: collateralValue,
412
+ greatestLoanAsset: loanAsset,
413
+ greatestLoanValue: loanValue,
235
414
  totalDebt,
236
415
  totalLimit,
237
416
  liquidable: true,
@@ -242,10 +421,10 @@ export function calculateLiquidationData(
242
421
  }
243
422
 
244
423
  return {
245
- greatestCollateralAsset: gCollateralAsset,
246
- greatestCollateralValue: gCollateralValue,
247
- greatestLoanAsset: gLoanAsset,
248
- greatestLoanValue: gLoanValue,
424
+ greatestCollateralAsset: collateralAsset,
425
+ greatestCollateralValue: collateralValue,
426
+ greatestLoanAsset: loanAsset,
427
+ greatestLoanValue: loanValue,
249
428
  totalDebt,
250
429
  totalLimit,
251
430
  liquidable: false,
@@ -253,7 +432,7 @@ export function calculateLiquidationData(
253
432
  }
254
433
 
255
434
  export function predictHealthFactor(args: PredictHealthFactorArgs): number {
256
- const liquidationData = calculateLiquidationData(args.assetsConfig, args.assetsData, args.balances, args.prices, args.masterConstants);
435
+ const liquidationData = calculateLiquidationData(args.assetsConfig, args.assetsData, args.principals, args.prices, args.poolConfig);
257
436
  const tokenHash = sha256Hash(args.tokenSymbol);
258
437
 
259
438
  const assetConfig = args.assetsConfig.get(tokenHash)!;
@@ -271,13 +450,13 @@ export function predictHealthFactor(args: PredictHealthFactorArgs): number {
271
450
 
272
451
  if (currentAmount != null && currentAmount != 0n) {
273
452
  if (changeType == BalanceChangeType.Borrow) {
274
- totalBorrow += currentBalance * (1 + Number(assetConfig.originationFee) / Number(args.masterConstants.ASSET_ORIGINATION_FEE_SCALE));
453
+ totalBorrow += currentBalance * (1 + Number(assetConfig.originationFee) / Number(args.poolConfig.masterConstants.ASSET_ORIGINATION_FEE_SCALE));
275
454
  } else if (changeType == BalanceChangeType.Repay) {
276
455
  totalBorrow -= currentBalance;
277
456
  } else if (changeType == BalanceChangeType.Withdraw) {
278
- totalLimit -= currentBalance * Number(assetConfig.liquidationThreshold) / Number(args.masterConstants.ASSET_COEFFICIENT_SCALE);
457
+ totalLimit -= currentBalance * Number(assetConfig.liquidationThreshold) / Number(args.poolConfig.masterConstants.ASSET_COEFFICIENT_SCALE);
279
458
  } else if (changeType == BalanceChangeType.Supply) {
280
- totalLimit += currentBalance * Number(assetConfig.liquidationThreshold) / Number(args.masterConstants.ASSET_COEFFICIENT_SCALE);
459
+ totalLimit += currentBalance * Number(assetConfig.liquidationThreshold) / Number(args.poolConfig.masterConstants.ASSET_COEFFICIENT_SCALE);
281
460
  }
282
461
  }
283
462
  if (Number(totalLimit) == 0) {
package/src/api/parser.ts CHANGED
@@ -1,16 +1,21 @@
1
1
  import { beginCell, Cell, Dictionary, DictionaryValue, Slice } from '@ton/core';
2
- import { AssetConfig, AssetData, ExtendedAssetData, ExtendedAssetsConfig, ExtendedAssetsData, MasterConfig, MasterConstants, MasterData, PoolAssetsConfig } from '../types/Master';
2
+ import { AssetConfig, AssetData, ExtendedAssetData, ExtendedAssetsConfig, ExtendedAssetsData, MasterConfig, MasterConstants, MasterData, PoolAssetsConfig, PoolConfig } from '../types/Master';
3
3
  import {
4
4
  bigIntMax,
5
5
  bigIntMin,
6
6
  calculateAssetData,
7
7
  calculateLiquidationData,
8
+ calculateMaximumWithdrawAmount,
9
+ calculateMaximumWithdrawAmountOld,
8
10
  calculatePresentValue,
9
11
  getAvailableToBorrow,
12
+ isV5MainPoolContract,
10
13
  presentValue,
11
14
  } from './math';
12
15
  import { loadMaybeMyRef, loadMyRef } from './helpers';
13
16
  import { BalanceType, UserBalance, UserData, UserLiteData, UserRewards } from '../types/User';
17
+ import { MAINNET_POOL_CONFIG, TESTNET_POOL_CONFIG } from '../constants/pools';
18
+ import { basename } from 'path';
14
19
 
15
20
  // Will be in v6
16
21
  /* export function createUserRewards(): DictionaryValue<UserRewards> {
@@ -202,11 +207,12 @@ export function parseUserLiteData(
202
207
  userDataBOC: string,
203
208
  assetsData: ExtendedAssetsData,
204
209
  assetsConfig: ExtendedAssetsConfig,
205
- poolAssetsConfig: PoolAssetsConfig,
206
- masterConstants: MasterConstants,
207
- testnet: boolean = false,
208
- applyDust: boolean = false
210
+ poolConfig: PoolConfig,
211
+ applyDust: boolean = true
209
212
  ): UserLiteData {
213
+ const poolAssetsConfig = poolConfig.poolAssetsConfig;
214
+ const masterConstants = poolConfig.masterConstants;
215
+
210
216
  const userSlice = Cell.fromBase64(userDataBOC).beginParse();
211
217
 
212
218
  const codeVersion = userSlice.loadCoins();
@@ -239,19 +245,25 @@ export function parseUserLiteData(
239
245
  }
240
246
  */
241
247
  userSlice.endParse();
242
-
248
+ const isV5Main = isV5MainPoolContract(poolConfig);
243
249
  const userBalances = Dictionary.empty<bigint, UserBalance>();
244
250
 
245
251
  for (const [_, asset] of Object.entries(poolAssetsConfig)) {
246
252
  const assetData = assetsData.get(asset.assetId) as ExtendedAssetData;
247
253
  const assetConfig = assetsConfig.get(asset.assetId) as AssetConfig;
248
- let principals = principalsDict.get(asset.assetId) || 0n;
249
254
 
250
- if (applyDust && (principals > -assetConfig.dust && principals < assetConfig.dust)) { // abs(principals) < dust
251
- principals = 0n;
255
+ let principal = principalsDict.get(asset.assetId) || 0n;
256
+ let balance = presentValue(assetData.sRate, assetData.bRate, principal, masterConstants);
257
+ let leftBorder = isV5Main ? balance.amount : principal;
258
+
259
+ if (applyDust && (principal > 0 && (leftBorder < assetConfig.dust))) { // v6 will be abs(principals) < dust
260
+ principal = 0n;
261
+ balance = {
262
+ amount: 0n,
263
+ type: BalanceType.supply,
264
+ };
252
265
  principalsDict.set(asset.assetId, 0n);
253
266
  }
254
- const balance = presentValue(assetData.sRate, assetData.bRate, principals, masterConstants);
255
267
  userBalances.set(asset.assetId, balance);
256
268
  }
257
269
 
@@ -279,30 +291,36 @@ export function parseUserData(
279
291
  assetsData: ExtendedAssetsData,
280
292
  assetsConfig: ExtendedAssetsConfig,
281
293
  prices: Dictionary<bigint, bigint>,
282
- poolAssetConfig: PoolAssetsConfig,
283
- masterConstants: MasterConstants,
284
- applyDust: boolean = false
294
+ poolConfig: PoolConfig,
295
+ applyDust: boolean = true
285
296
  ): UserData {
297
+ const poolAssetsConfig = poolConfig.poolAssetsConfig;
298
+ const masterConstants = poolConfig.masterConstants;
299
+
286
300
  const withdrawalLimits = Dictionary.empty<bigint, bigint>();
287
301
  const borrowLimits = Dictionary.empty<bigint, bigint>();
288
302
 
289
303
  let supplyBalance = 0n;
290
304
  let borrowBalance = 0n;
291
- for (const [_, asset] of Object.entries(poolAssetConfig)) {
305
+ const isV5Main = isV5MainPoolContract(poolConfig);
306
+
307
+ for (const [_, asset] of Object.entries(poolAssetsConfig)) {
292
308
  const assetData = assetsData.get(asset.assetId) as ExtendedAssetData;
293
309
  const assetConfig = assetsConfig.get(asset.assetId) as AssetConfig;
294
- let principals = userLiteData.principals.get(asset.assetId) || 0n;
295
310
 
296
- if (applyDust && (principals > -assetConfig.dust && principals < assetConfig.dust )) { // abs(principals) < dust
297
- principals = 0n;
311
+ let principal = userLiteData.principals.get(asset.assetId) || 0n;
312
+ const balance = presentValue(assetData.sRate, assetData.bRate, principal, masterConstants);
313
+ let leftBorder = isV5Main ? balance.amount : principal;
314
+
315
+ if (applyDust && (principal > 0 && (leftBorder < assetConfig.dust))) { // v6 will be abs(principals) < dust
316
+ principal = 0n;
298
317
  userLiteData.principals.set(asset.assetId, 0n);
299
318
  }
300
319
 
301
- const balance = presentValue(assetData.sRate, assetData.bRate, principals, masterConstants);
302
320
  userLiteData.balances.set(asset.assetId, balance);
303
321
  }
304
322
 
305
- for (const [_, asset] of Object.entries(poolAssetConfig)) {
323
+ for (const [_, asset] of Object.entries(poolAssetsConfig)) {
306
324
  const assetConfig = assetsConfig.get(asset.assetId) as AssetConfig;
307
325
  const balance = userLiteData.balances.get(asset.assetId) as UserBalance;
308
326
 
@@ -315,27 +333,24 @@ export function parseUserData(
315
333
  }
316
334
 
317
335
  const availableToBorrow = getAvailableToBorrow(assetsConfig, assetsData, userLiteData.principals, prices, masterConstants);
318
- for (const [_, asset] of Object.entries(poolAssetConfig)) {
336
+ for (const [_, asset] of Object.entries(poolAssetsConfig)) {
319
337
  const assetConfig = assetsConfig.get(asset.assetId) as AssetConfig;
320
338
  const assetData = assetsData.get(asset.assetId) as ExtendedAssetData;
321
339
  const balance = userLiteData.balances.get(asset.assetId) as UserBalance;
322
-
340
+
323
341
  if (balance.type === BalanceType.supply) {
324
- withdrawalLimits.set(
325
- asset.assetId,
326
- bigIntMax(
327
- bigIntMin(
328
- assetData.balance,
329
- ((supplyBalance -
330
- (borrowBalance * masterConstants.ASSET_COEFFICIENT_SCALE) / assetConfig.collateralFactor) *
331
- 10n ** assetConfig.decimals) /
332
- prices.get(asset.assetId)! -
333
- 5n,
334
- balance.amount,
335
- ),
336
- 0n,
337
- ),
338
- );
342
+ if (isV5MainPoolContract(poolConfig)) {
343
+ withdrawalLimits.set(
344
+ asset.assetId,
345
+ calculateMaximumWithdrawAmountOld(assetsConfig, assetsData, userLiteData.principals, prices, masterConstants, asset.assetId)
346
+ );
347
+ }
348
+ else {
349
+ withdrawalLimits.set(
350
+ asset.assetId,
351
+ calculateMaximumWithdrawAmount(assetsConfig, assetsData, userLiteData.principals, prices, masterConstants, asset.assetId)
352
+ );
353
+ }
339
354
  }
340
355
  borrowLimits.set(
341
356
  asset.assetId,
@@ -349,7 +364,7 @@ export function parseUserData(
349
364
  ? 0
350
365
  : Number(BigInt(1e9) - (availableToBorrow * BigInt(1e9)) / (borrowBalance + availableToBorrow)) / 1e7;
351
366
 
352
- const liquidationData = calculateLiquidationData(assetsConfig, assetsData, userLiteData.principals, prices, masterConstants);
367
+ const liquidationData = calculateLiquidationData(assetsConfig, assetsData, userLiteData.principals, prices, poolConfig);
353
368
  const healthFactor = 1 - Number(liquidationData.totalDebt) / Number(liquidationData.totalLimit);
354
369
 
355
370
  return {
package/src/api/prices.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { beginCell, Cell, Dictionary } from '@ton/core';
2
2
  import { PriceData } from '../types/Common';
3
+ import { MAIN_POOL_NFT_ID } from '../constants/general';
3
4
 
4
5
  type NftData = {
5
6
  ledgerIndex: number;
@@ -38,7 +39,7 @@ type OutputData = {
38
39
  };
39
40
  }
40
41
 
41
- export async function getPricesByNft(nftId: string, endpoints: string[] = ["api.stardust-mainnet.iotaledger.net"]) {
42
+ export async function getPrices(endpoints: string[] = ["api.stardust-mainnet.iotaledger.net"], nftId: string = MAIN_POOL_NFT_ID) {
42
43
  return await Promise.any(endpoints.map(x => loadPrices(nftId, x)));
43
44
  }
44
45
 
@@ -1,13 +1,21 @@
1
1
  import { Address, Cell } from "@ton/core";
2
2
  import { PoolAssetConfig } from "../types/Master";
3
3
  import { sha256Hash } from "../utils/sha256BigInt";
4
- import { JETTON_WALLET_STANDART_CODE, JETTON_WALLET_STANDART_CODE_TESTNET } from "./general";
4
+ import { JETTON_WALLET_STANDART_CODE, JETTON_WALLET_STANDART_CODE_TESTNET, NULL_ADDRESS } from "./general";
5
+
6
+ export const UNDEFINED_ASSET: PoolAssetConfig = {
7
+ name: 'undefined_asset',
8
+ assetId: -1n,
9
+ jettonMasterAddress: NULL_ADDRESS, // fake
10
+ jettonWalletCode: Cell.EMPTY
11
+ }
5
12
 
6
13
  export const TON_MAINNET: PoolAssetConfig = {
7
14
  name: 'TON',
8
- assetId: sha256Hash('TON')
15
+ assetId: sha256Hash('TON'),
16
+ jettonMasterAddress: NULL_ADDRESS, // fake
17
+ jettonWalletCode: Cell.EMPTY
9
18
  }
10
-
11
19
  export const TON_TESTNET = TON_MAINNET;
12
20
 
13
21
  export const JUSDT_MAINNET: PoolAssetConfig = {
@@ -7,15 +7,17 @@ export const MASTER_CONSTANTS = {
7
7
  ASSET_PRICE_SCALE: BigInt(1e9),
8
8
  ASSET_RESERVE_FACTOR_SCALE: 10000n,
9
9
  ASSET_LIQUIDATION_RESERVE_FACTOR_SCALE: 10000n,
10
- ASSET_ORIGINATION_FEE_SCALE: BigInt(1e9)
10
+ ASSET_ORIGINATION_FEE_SCALE: BigInt(1e9),
11
+ ASSET_LIQUIDATION_THRESHOLD_SCALE: 10_000n,
12
+ ASSET_LIQUIDATION_BONUS_SCALE: 10_000n,
11
13
  };
12
14
 
15
+ export const NULL_ADDRESS = Address.parse('UQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJKZ');
16
+
13
17
  export const EVAA_MASTER_MAINNET = Address.parse('EQC8rUZqR_pWV1BylWUlPNBzyiTYVoBEmQkMIQDZXICfnuRr');
14
18
  export const MAINNET_VERSION = 5;
15
- export const EVAA_MASTER_TESTNET = Address.parse('EQCoIxsE8m0Q_Ui9uM-2RPtVWXqHK0ttuW2Mccuaj4FfdkLl');
19
+ export const EVAA_MASTER_TESTNET = Address.parse('EQCoIxsE8m0Q_Ui9uM-2RPtVWXqHK0ttuW2Mccuaj4FfdkLl'); // EQBghPVKxgauOyrcyNYNwE2MRRnebaNpDGpVDQLbml_LIXnK
16
20
  export const TESTNET_VERSION = 5;
17
- export const EVAA_LP_TESTNET = Address.parse('EQBghPVKxgauOyrcyNYNwE2MRRnebaNpDGpVDQLbml_LIXnK');
18
- export const EVAA_LP_TESTNET_VERSION = 5;
19
21
  export const EVAA_LP_MAINNET = Address.parse('EQBIlZX2URWkXCSg3QF2MJZU-wC5XkBoLww-hdWk2G37Jc6N');
20
22
  export const EVAA_LP_MAINNET_VERSION = 0;
21
23
 
@@ -1,7 +1,7 @@
1
1
  import { Address } from "@ton/core";
2
2
  import { JUSDC_MAINNET, JUSDC_TESTNET, JUSDT_MAINNET, JUSDT_TESTNET, STTON_MAINNET, STTON_TESTNET, TON_MAINNET, TON_STORM_MAINNET, TONUSDT_DEDUST_MAINNET, TSTON_MAINNET, USDT_MAINNET, USDT_STORM_MAINNET } from "./assets";
3
3
  import { PoolConfig } from "../types/Master";
4
- import { EVAA_MASTER_MAINNET, EVAA_MASTER_TESTNET, LENDING_CODE, MAINNET_VERSION, MASTER_CONSTANTS, MAIN_POOL_NFT_ID, TESTNET_VERSION, LP_POOL_NFT_ID, EVAA_LP_TESTNET, EVAA_LP_TESTNET_VERSION, EVAA_LP_MAINNET, EVAA_LP_MAINNET_VERSION } from "./general";
4
+ import { EVAA_MASTER_MAINNET, EVAA_MASTER_TESTNET, LENDING_CODE, MAINNET_VERSION, MASTER_CONSTANTS, MAIN_POOL_NFT_ID, TESTNET_VERSION, LP_POOL_NFT_ID, EVAA_LP_MAINNET, EVAA_LP_MAINNET_VERSION } from "./general";
5
5
 
6
6
  export const MAINNET_POOL_CONFIG: PoolConfig = {
7
7
  masterAddress: EVAA_MASTER_MAINNET,
@@ -33,20 +33,6 @@ export const TESTNET_POOL_CONFIG: PoolConfig = {
33
33
  lendingCode: LENDING_CODE
34
34
  };
35
35
 
36
- export const TESTNET_LP_POOL_CONFIG: PoolConfig = {
37
- masterAddress: EVAA_LP_TESTNET,
38
- masterVersion: EVAA_LP_TESTNET_VERSION,
39
- masterConstants: MASTER_CONSTANTS,
40
- nftId: LP_POOL_NFT_ID,
41
- poolAssetsConfig: [
42
- TON_MAINNET,
43
- JUSDT_TESTNET,
44
- JUSDC_TESTNET,
45
- STTON_TESTNET
46
- ],
47
- lendingCode: LENDING_CODE
48
- };
49
-
50
36
  export const MAINNET_LP_POOL_CONFIG: PoolConfig = {
51
37
  masterAddress: EVAA_LP_MAINNET,
52
38
  masterVersion: EVAA_LP_MAINNET_VERSION,