@evaafi/sdk 0.6.0-a → 0.6.1

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/src/api/math.ts CHANGED
@@ -1,9 +1,25 @@
1
- import { AgregatedBalances, AssetConfig, AssetData, AssetInterest, ExtendedAssetData, ExtendedAssetsConfig, ExtendedAssetsData, MasterConstants, PoolConfig } from '../types/Master';
1
+ import {
2
+ AgregatedBalances,
3
+ AssetConfig,
4
+ AssetData,
5
+ AssetInterest,
6
+ ExtendedAssetData,
7
+ ExtendedAssetsConfig,
8
+ ExtendedAssetsData,
9
+ MasterConstants,
10
+ PoolConfig
11
+ } from '../types/Master';
2
12
  import { Dictionary } from '@ton/core';
3
- import { BalanceChangeType, BalanceType, LiquidationData, PredictHealthFactorArgs, UserBalance } from '../types/User';
4
- import { sha256Hash } from '../utils/sha256BigInt';
5
- import { TON_MAINNET, UNDEFINED_ASSET } from '../constants/assets';
6
- import { MAINNET_POOL_CONFIG, TESTNET_POOL_CONFIG } from '..';
13
+ import {
14
+ BalanceChangeType,
15
+ BalanceType,
16
+ HealthParamsArgs,
17
+ LiquidationData,
18
+ PredictHealthFactorArgs,
19
+ UserBalance
20
+ } from '../types/User';
21
+ import { UNDEFINED_ASSET } from '../constants/assets';
22
+ import { addReserve, isBadDebt } from './liquidation';
7
23
 
8
24
  export function mulFactor(decimal: bigint, a: bigint, b: bigint): bigint {
9
25
  return (a * b) / decimal;
@@ -19,13 +35,20 @@ export function mulDivC(x: bigint, y: bigint, z: bigint): bigint {
19
35
  return BigInt(Math.ceil(Number(x * y) / Number(z)));
20
36
  }
21
37
 
38
+ export function bigAbs(value: bigint) {
39
+ return value > 0n ? value : -value;
40
+ }
41
+
22
42
  export function bigIntMax(...args: bigint[]): bigint {
23
43
  return args.reduce((m, e) => (e > m ? e : m));
24
44
  }
45
+
25
46
  export function bigIntMin(...args: bigint[]): bigint {
26
47
  return args.reduce((m, e) => (e < m ? e : m));
27
48
  }
28
49
 
50
+ export const BigMath = { mulFactor, mulDiv, mulDivC, abs: bigAbs, min: bigIntMin, max: bigIntMax };
51
+
29
52
  export function calculatePresentValue(index: bigint, principalValue: bigint, masterConstants: MasterConstants): bigint {
30
53
  return (principalValue * index) / masterConstants.FACTOR_SCALE;
31
54
  }
@@ -45,7 +68,7 @@ export function calculateCurrentRates(assetConfig: AssetConfig, assetData: Asset
45
68
  bRate: updatedBRate,
46
69
  supplyInterest,
47
70
  borrowInterest,
48
- now,
71
+ now
49
72
  };
50
73
  }
51
74
 
@@ -54,7 +77,7 @@ export function calculateCurrentRates(assetConfig: AssetConfig, assetData: Asset
54
77
  bRate: assetData.bRate,
55
78
  supplyInterest,
56
79
  borrowInterest,
57
- now,
80
+ now
58
81
  };
59
82
  }
60
83
 
@@ -82,7 +105,7 @@ export function calculateAssetData(
82
105
  return {
83
106
  ...data,
84
107
  ...{ supplyInterest, borrowInterest },
85
- ...{ supplyApy, borrowApy },
108
+ ...{ supplyApy, borrowApy }
86
109
  };
87
110
  }
88
111
 
@@ -108,19 +131,19 @@ export function calculateAssetInterest(assetConfig: AssetConfig, assetData: Asse
108
131
  mulFactor(
109
132
  masterConstants.FACTOR_SCALE,
110
133
  assetConfig.borrowRateSlopeHigh,
111
- utilization - assetConfig.targetUtilization,
134
+ utilization - assetConfig.targetUtilization
112
135
  );
113
136
  }
114
137
 
115
138
  supplyInterest = mulDiv(
116
139
  mulDiv(borrowInterest, utilization, masterConstants.FACTOR_SCALE),
117
140
  masterConstants.ASSET_RESERVE_FACTOR_SCALE - assetConfig.reserveFactor,
118
- masterConstants.ASSET_RESERVE_FACTOR_SCALE,
141
+ masterConstants.ASSET_RESERVE_FACTOR_SCALE
119
142
  );
120
143
 
121
144
  return {
122
145
  supplyInterest,
123
- borrowInterest,
146
+ borrowInterest
124
147
  };
125
148
  }
126
149
 
@@ -128,37 +151,36 @@ export function checkNotInDebtAtAll(principals: Dictionary<bigint, bigint>): boo
128
151
  return principals.values().every(x => x >= 0n);
129
152
  }
130
153
 
131
- export function getAgregatedBalances (
154
+ export function getAgregatedBalances(
132
155
  assetsData: ExtendedAssetsData,
133
156
  assetsConfig: ExtendedAssetsConfig,
134
157
  principals: Dictionary<bigint, bigint>,
135
158
  prices: Dictionary<bigint, bigint>,
136
- masterConstants: MasterConstants,
137
- ): AgregatedBalances {
159
+ masterConstants: MasterConstants
160
+ ): AgregatedBalances {
138
161
  let user_total_supply = 0n;
139
162
  let user_total_borrow = 0n;
140
-
141
- for (const [assetId, principal] of principals) {
142
163
 
164
+ for (const [assetId, principal] of principals) {
143
165
  if (principal) {
144
-
145
- if (!prices.has(assetId)) {
146
- return {totalSupply: 0n, totalBorrow: 0n};
147
- }
148
- const price = prices.get(assetId)!;
149
- const assetData = assetsData.get(assetId)!;
150
- const assetConfig = assetsConfig.get(assetId)!;
151
- // console.log('price', price);
152
- if (principal < 0) {
153
- user_total_borrow += presentValue(assetData.sRate, assetData.bRate, principal, masterConstants).amount * price / 10n ** assetConfig.decimals;
154
- } else {
155
- user_total_supply += presentValue(assetData.sRate, assetData.bRate, principal, masterConstants).amount * price / 10n ** assetConfig.decimals;
166
+
167
+ if (!prices.has(assetId)) {
168
+ return { totalSupply: 0n, totalBorrow: 0n };
169
+ }
170
+ const price = prices.get(assetId)!;
171
+ const assetData = assetsData.get(assetId)!;
172
+ const assetConfig = assetsConfig.get(assetId)!;
173
+ // console.log('price', price);
174
+ if (principal < 0) {
175
+ user_total_borrow += presentValue(assetData.sRate, assetData.bRate, principal, masterConstants).amount * price / 10n ** assetConfig.decimals;
176
+ } else {
177
+ user_total_supply += presentValue(assetData.sRate, assetData.bRate, principal, masterConstants).amount * price / 10n ** assetConfig.decimals;
178
+ }
179
+ // console.log('aggregated', assetId, presentValue(assetData.sRate, assetData.bRate, principal, masterConstants).type, presentValue(assetData.sRate, assetData.bRate, principal, masterConstants).amount * price / 10n ** assetConfig.decimals)
156
180
  }
157
- // console.log('aggregated', assetId, presentValue(assetData.sRate, assetData.bRate, principal, masterConstants).type, presentValue(assetData.sRate, assetData.bRate, principal, masterConstants).amount * price / 10n ** assetConfig.decimals)
158
- }
159
181
  }
160
- return {totalSupply: user_total_supply, totalBorrow: user_total_borrow};
161
- }
182
+ return { totalSupply: user_total_supply, totalBorrow: user_total_borrow };
183
+ }
162
184
 
163
185
  export function calculateMaximumWithdrawAmount(
164
186
  assetsConfig: ExtendedAssetsConfig,
@@ -166,7 +188,7 @@ export function calculateMaximumWithdrawAmount(
166
188
  principals: Dictionary<bigint, bigint>,
167
189
  prices: Dictionary<bigint, bigint>,
168
190
  masterConstants: MasterConstants,
169
- assetId: bigint,
191
+ assetId: bigint
170
192
  ): bigint {
171
193
  let withdrawAmountMax = 0n;
172
194
 
@@ -176,8 +198,8 @@ export function calculateMaximumWithdrawAmount(
176
198
 
177
199
  if (oldPrincipal > assetConfig.dust) {
178
200
  const oldPresentValue = presentValue(assetData.sRate, assetData.bRate, oldPrincipal, masterConstants);
179
- if(checkNotInDebtAtAll(principals)) {
180
- withdrawAmountMax = oldPresentValue.amount;
201
+ if (checkNotInDebtAtAll(principals)) {
202
+ withdrawAmountMax = oldPresentValue.amount;
181
203
  } else {
182
204
  if (!prices.has(assetId)) {
183
205
  return 0n;
@@ -190,17 +212,16 @@ export function calculateMaximumWithdrawAmount(
190
212
 
191
213
  if (assetConfig.collateralFactor == 0n) {
192
214
  maxAmountToReclaim = oldPresentValue.amount;
193
- }
194
- else if (price > 0) {
215
+ } else if (price > 0) {
195
216
  maxAmountToReclaim =
196
- bigIntMax(0n,
217
+ bigIntMax(0n,
197
218
  mulDiv(
198
219
  mulDiv(borrowable, masterConstants.ASSET_COEFFICIENT_SCALE, assetConfig.collateralFactor),
199
220
  10n ** assetConfig.decimals, price)
200
221
  - calculatePresentValue(assetData.sRate, assetConfig.dust, masterConstants) / 2n
201
222
  );
202
223
  }
203
-
224
+
204
225
  withdrawAmountMax = bigIntMin(
205
226
  maxAmountToReclaim,
206
227
  oldPresentValue.amount
@@ -235,9 +256,9 @@ export function getAvailableToBorrow(
235
256
  const price = prices.get(assetID) as bigint;
236
257
  const principal = principals.get(assetID) as bigint;
237
258
 
238
- if (principal < 0) {
259
+ if (principal < 0n) {
239
260
  borrowAmount += mulDiv(calculatePresentValue(assetData.bRate, -principal, masterConstants), price, 10n ** assetConfig.decimals);
240
- } else if (principal > 0) {
261
+ } else if (principal > 0n) {
241
262
  borrowLimit +=
242
263
  mulDiv(
243
264
  mulDiv(calculatePresentValue(assetData.sRate, principal, masterConstants), price, 10n ** assetConfig.decimals),
@@ -249,32 +270,96 @@ export function getAvailableToBorrow(
249
270
  return borrowLimit - borrowAmount;
250
271
  }
251
272
 
273
+ /**
274
+ * Calculates balance value for asset principal.
275
+ * @param sRate asset supply rate
276
+ * @param bRate asset borrow rate
277
+ * @param principalValue asset principal value
278
+ * @param masterConstants pool constants
279
+ */
252
280
  export function presentValue(sRate: bigint, bRate: bigint, principalValue: bigint, masterConstants: MasterConstants): UserBalance {
253
281
  if (principalValue > 0) {
254
282
  return {
255
283
  amount: calculatePresentValue(sRate, principalValue, masterConstants),
256
- type: BalanceType.supply,
284
+ type: BalanceType.supply
257
285
  };
258
286
  } else if (principalValue < 0) {
259
287
  return {
260
288
  amount: calculatePresentValue(bRate, -principalValue, masterConstants),
261
- type: BalanceType.borrow,
289
+ type: BalanceType.borrow
262
290
  };
263
291
  } else {
264
292
  return {
265
293
  amount: 0n,
266
- type: undefined,
294
+ type: undefined
267
295
  };
268
296
  }
269
297
  }
270
298
 
271
299
  /**
272
- *
273
- * @param assetsConfig
274
- * @param assetsData
275
- * @param principals
276
- * @param prices
277
- * @param poolConfig
300
+ * Calculates health parameters of the specified user account based on its parameters
301
+ * @param parameters
302
+ */
303
+ export function calculateHealthParams(parameters: HealthParamsArgs) {
304
+ const {
305
+ principals, prices,
306
+ assetsData, assetsConfig,
307
+ poolConfig
308
+ } = parameters;
309
+
310
+ const { ASSET_LIQUIDATION_THRESHOLD_SCALE } = poolConfig.masterConstants;
311
+
312
+ let totalSupply = 0n;
313
+ let totalDebt = 0n;
314
+ let totalLimit = 0n;
315
+
316
+ for (const asset of poolConfig.poolAssetsConfig) {
317
+ if (!principals.has(asset.assetId)) continue;
318
+ const assetPrincipal = principals.get(asset.assetId)!;
319
+
320
+ if (!assetsConfig.has(asset.assetId)) throw (`No config for ${asset.name}:${asset.assetId}`);
321
+ const assetConfig = assetsConfig.get(asset.assetId)!;
322
+
323
+ if (!assetsData.has(asset.assetId)) throw (`No data for asset ${asset.name}:${asset.assetId}`);
324
+ const assetData = assetsData.get(asset.assetId)!;
325
+
326
+ if (!prices.has(asset.assetId)) throw (`No price for asset ${asset.name}:${asset.assetId}`);
327
+ const assetPrice = prices.get(asset.assetId)! as bigint;
328
+ const assetScale = 10n ** assetConfig.decimals;
329
+
330
+ const { sRate, bRate } = assetData;
331
+ const assetBalance = presentValue(sRate, bRate, assetPrincipal, poolConfig.masterConstants);
332
+ const assetWorth = assetBalance.amount * assetPrice / assetScale;
333
+ if (assetBalance.type === BalanceType.supply) {
334
+ totalSupply += assetWorth;
335
+ totalLimit += assetWorth * assetConfig.liquidationThreshold / ASSET_LIQUIDATION_THRESHOLD_SCALE;
336
+ } else if (assetBalance.type === BalanceType.borrow) {
337
+ totalDebt += assetWorth;
338
+ }
339
+ }
340
+
341
+ const _isLiquidable = totalLimit < totalDebt;
342
+
343
+ // the `bad debt` condition depends on certain asset's liquidation bonus parameter
344
+ // , so it is not a user constant, but depends on certain asset
345
+ const _isBadDebt = (liquidationBonus: bigint): boolean => {
346
+ return isBadDebt(totalSupply, totalDebt, liquidationBonus, poolConfig.masterConstants) as boolean;
347
+ };
348
+
349
+ return {
350
+ totalDebt, totalLimit, totalSupply,
351
+ isLiquidatable: _isLiquidable,
352
+ isBadDebt: _isBadDebt
353
+ };
354
+ }
355
+
356
+ /**
357
+ * Calculates liquidation data for greatest loan and collateral assets
358
+ * @param assetsConfig assets config dictionary
359
+ * @param assetsData assets data dictionary
360
+ * @param principals principals dictionary
361
+ * @param prices prices dictionary
362
+ * @param poolConfig pool config
278
363
  * @returns can return UNDEFINED_ASSET if there are no assets
279
364
  */
280
365
  export function calculateLiquidationData(
@@ -282,7 +367,7 @@ export function calculateLiquidationData(
282
367
  assetsData: ExtendedAssetsData,
283
368
  principals: Dictionary<bigint, bigint>,
284
369
  prices: Dictionary<bigint, bigint>,
285
- poolConfig: PoolConfig,
370
+ poolConfig: PoolConfig
286
371
  ): LiquidationData {
287
372
  let collateralValue = 0n;
288
373
  let collateralAsset = UNDEFINED_ASSET;
@@ -291,25 +376,31 @@ export function calculateLiquidationData(
291
376
  let totalDebt = 0n;
292
377
  let totalLimit = 0n;
293
378
 
379
+ const {
380
+ ASSET_SRATE_SCALE, ASSET_BRATE_SCALE,
381
+ COLLATERAL_WORTH_THRESHOLD
382
+ } = poolConfig.masterConstants;
383
+
294
384
  for (const asset of poolConfig.poolAssetsConfig) {
295
- if (!principals.has(asset.assetId)) {
296
- continue;
297
- }
298
385
  const principal = principals.get(asset.assetId)!;
386
+ if (!principal) continue;
299
387
  const assetConfig = assetsConfig.get(asset.assetId)!;
300
388
  const assetData = assetsData.get(asset.assetId)!;
301
- const balance =
302
- principal > 0 ? (principal * assetData.sRate) / BigInt(1e12) : (principal * assetData.bRate) / BigInt(1e12);
389
+ const balance = principal > 0 ?
390
+ (principal * assetData.sRate) / ASSET_SRATE_SCALE :
391
+ (principal * assetData.bRate) / ASSET_BRATE_SCALE;
392
+
393
+ const assetWorth = (bigAbs(balance) * prices.get(asset.assetId)!) / 10n ** assetConfig.decimals;
303
394
  if (balance > 0) {
304
- const assetWorth = (balance * prices.get(asset.assetId)!) / 10n ** assetConfig.decimals;
305
395
  totalLimit += (assetWorth * assetConfig.liquidationThreshold) / poolConfig.masterConstants.ASSET_COEFFICIENT_SCALE;
396
+ // get the greatest collateral
306
397
  if (assetWorth > collateralValue) {
307
398
  collateralValue = assetWorth;
308
399
  collateralAsset = asset;
309
400
  }
310
401
  } else if (balance < 0) {
311
- const assetWorth = (-balance * prices.get(asset.assetId)!) / 10n ** assetConfig.decimals;
312
402
  totalDebt += assetWorth;
403
+ // get the greatest loan
313
404
  if (assetWorth > loanValue) {
314
405
  loanValue = assetWorth;
315
406
  loanAsset = asset;
@@ -325,11 +416,11 @@ export function calculateLiquidationData(
325
416
  const liquidationBonus = collateralAssetConfig.liquidationBonus;
326
417
  const loanScale = 10n ** loanAssetConfig.decimals;
327
418
  values.push(
328
- (bigIntMax(collateralValue / 2n, bigIntMin(collateralValue, 100_000_000_000n)) *
419
+ (bigIntMax(collateralValue / 2n, bigIntMin(collateralValue, COLLATERAL_WORTH_THRESHOLD)) *
329
420
  loanScale *
330
421
  poolConfig.masterConstants.ASSET_COEFFICIENT_SCALE) /
331
- liquidationBonus /
332
- loanAssetPrice,
422
+ liquidationBonus /
423
+ loanAssetPrice
333
424
  );
334
425
  values.push((loanValue * loanScale) / loanAssetPrice);
335
426
 
@@ -338,11 +429,11 @@ export function calculateLiquidationData(
338
429
  const collateralDecimal = 10n ** collateralAssetConfig.decimals;
339
430
  let minCollateralAmount =
340
431
  (((liquidationAmount * loanAssetPrice * liquidationBonus) / poolConfig.masterConstants.ASSET_LIQUIDATION_BONUS_SCALE) * collateralDecimal) /
341
- collateralAssetPrice /
342
- loanScale -
432
+ collateralAssetPrice /
433
+ loanScale -
343
434
  10n;
344
435
  minCollateralAmount = (minCollateralAmount * 97n) / 100n;
345
- if (minCollateralAmount / collateralDecimal >= 0n) { // todo back to 1
436
+ if (minCollateralAmount > 0n) {
346
437
  return {
347
438
  greatestCollateralAsset: collateralAsset,
348
439
  greatestCollateralValue: collateralValue,
@@ -351,8 +442,8 @@ export function calculateLiquidationData(
351
442
  totalDebt,
352
443
  totalLimit,
353
444
  liquidable: true,
354
- liquidationAmount,
355
- minCollateralAmount,
445
+ liquidationAmount: addReserve(liquidationAmount, loanAssetConfig.liquidationReserveFactor, poolConfig.masterConstants.ASSET_RESERVE_FACTOR_SCALE),
446
+ minCollateralAmount
356
447
  };
357
448
  }
358
449
  }
@@ -364,29 +455,29 @@ export function calculateLiquidationData(
364
455
  greatestLoanValue: loanValue,
365
456
  totalDebt,
366
457
  totalLimit,
367
- liquidable: false,
458
+ liquidable: false
368
459
  };
369
460
  }
370
461
 
371
462
  export function predictHealthFactor(args: PredictHealthFactorArgs): number {
372
- const liquidationData = calculateLiquidationData(args.assetsConfig, args.assetsData, args.principals, args.prices, args.poolConfig);
463
+ const healthParams = calculateHealthParams(args);
373
464
  const assetId = args.asset.assetId;
374
-
465
+
375
466
  const assetConfig = args.assetsConfig.get(assetId)!;
376
467
  const assetPrice = Number(args.prices.get(assetId)!);
377
- const assetData = args.assetsData.get(assetId)!;
378
-
379
- let totalLimit = Number(liquidationData.totalLimit);
380
- let totalBorrow = Number(liquidationData.totalDebt);
468
+ const assetData = args.assetsData.get(assetId)!;
469
+
470
+ let totalLimit = Number(healthParams.totalLimit);
471
+ let totalBorrow = Number(healthParams.totalDebt);
381
472
 
382
473
  const currentAmount = args.amount;
383
474
 
384
- const decimals = Number(assetConfig.decimals)
475
+ const decimals = Number(assetConfig.decimals);
385
476
 
386
477
  const currentBalance = assetPrice * Number(currentAmount) / Math.pow(10, decimals);
387
478
  const changeType = args.balanceChangeType;
388
479
 
389
- if (currentAmount != null && currentAmount != 0n) {
480
+ if (currentAmount != null && currentAmount != 0n) {
390
481
  if (changeType == BalanceChangeType.Borrow) {
391
482
  totalBorrow += currentBalance * (1 + Number(assetConfig.originationFee) / Number(args.poolConfig.masterConstants.ASSET_ORIGINATION_FEE_SCALE));
392
483
  } else if (changeType == BalanceChangeType.Repay) {
@@ -3,6 +3,19 @@ import { PoolAssetConfig } from "../types/Master";
3
3
  import { sha256Hash } from "../utils/sha256BigInt";
4
4
  import { JETTON_WALLET_STANDART_CODE, JETTON_WALLET_STANDART_CODE_TESTNET, NULL_ADDRESS } from "./general";
5
5
 
6
+ export const ASSET_ID = {
7
+ TON: sha256Hash('TON'),
8
+ USDT: sha256Hash('USDT'),
9
+ jUSDT: sha256Hash('jUSDT'),
10
+ jUSDC: sha256Hash('jUSDC'),
11
+ stTON: sha256Hash('stTON'),
12
+ tsTON: sha256Hash('tsTON'),
13
+ TONUSDT_DEDUST: sha256Hash('TONUSDT_DEDUST'),
14
+ TONUSDT_STONFI: sha256Hash('TONUSDT_STONFI'),
15
+ TON_STORM: sha256Hash('TON_STORM'),
16
+ USDT_STORM: sha256Hash('USDT_STORM'),
17
+ };
18
+
6
19
  export const UNDEFINED_ASSET: PoolAssetConfig = {
7
20
  name: 'undefined_asset',
8
21
  assetId: -1n,
@@ -12,7 +25,7 @@ export const UNDEFINED_ASSET: PoolAssetConfig = {
12
25
 
13
26
  export const TON_MAINNET: PoolAssetConfig = {
14
27
  name: 'TON',
15
- assetId: sha256Hash('TON'),
28
+ assetId: ASSET_ID.TON,
16
29
  jettonMasterAddress: NULL_ADDRESS, // fake
17
30
  jettonWalletCode: Cell.EMPTY
18
31
  }
@@ -20,21 +33,21 @@ export const TON_TESTNET = TON_MAINNET;
20
33
 
21
34
  export const JUSDT_MAINNET: PoolAssetConfig = {
22
35
  name: 'jUSDT',
23
- assetId: sha256Hash('jUSDT'),
36
+ assetId: ASSET_ID.jUSDT,
24
37
  jettonMasterAddress: Address.parse('EQBynBO23ywHy_CgarY9NK9FTz0yDsG82PtcbSTQgGoXwiuA'),
25
38
  jettonWalletCode: JETTON_WALLET_STANDART_CODE
26
39
  }
27
40
 
28
41
  export const JUSDC_MAINNET: PoolAssetConfig = {
29
42
  name: 'jUSDC',
30
- assetId: sha256Hash('jUSDC'),
43
+ assetId: ASSET_ID.jUSDC,
31
44
  jettonMasterAddress: Address.parse('EQB-MPwrd1G6WKNkLz_VnV6WqBDd142KMQv-g1O-8QUA3728'),
32
45
  jettonWalletCode: JETTON_WALLET_STANDART_CODE
33
46
  }
34
47
 
35
48
  export const STTON_MAINNET: PoolAssetConfig = {
36
49
  name: 'stTON',
37
- assetId: sha256Hash('stTON'),
50
+ assetId: ASSET_ID.stTON,
38
51
  jettonMasterAddress: Address.parse('EQDNhy-nxYFgUqzfUzImBEP67JqsyMIcyk2S5_RwNNEYku0k'),
39
52
  jettonWalletCode: Cell.fromBase64(
40
53
  'te6cckECEgEAA2IAART/APSkE/S88sgLAQIBYgIDAgLMBAUAG6D2BdqJofQB9IH0gahhAgHUBgcCASAJCgHPCDHAJJfBOAB0NMDAXGwlRNfA/AN4PpA+kAx+gAxcdch+gAx+gAwc6m0AALTHyGCEA+KfqW6lTE0WfAK4CGCEBeNRRm6ljFERAPwC+AhghBZXwe8upUxNFnwDOAUXwTABOMCMIQP8vCAIABE+kQwwADy4U2AAfO1E0PoA+kD6QNQwECNfAwGCCJiWgKFtgBByIm6zIJFxkXDiA8jLBVAGzxZQBPoCy2oDk1jMAZEw4gHJAfsAAgFYCwwCAUgQEQHxAPTP/oA+kAh8AHtRND6APpA+kDUMFE2oVIqxwXy4sEowv/y4sJUNEJwVCATVBQDyFAE+gJYzxYBzxbMySLIywES9AD0AMsAySD5AHB0yMsCygfL/8nQBPpA9AQx+gAg10nCAPLixHeAGMjLBVAIzxZw+gIXy2sTzIA0C9ztRND6APpA+kDUMAjTP/oAUVGgBfpA+kBTW8cFVHNtcFQgE1QUA8hQBPoCWM8WAc8WzMkiyMsBEvQA9ADLAMn5AHB0yMsCygfL/8nQUA3HBRyx8uLDCvoAUaihggiYloBmtgihggjk4cCgGKEnlxBJEDg3XwTjDSXXCwGAODwCeghAXjUUZyMsfGcs/UAf6AiLPFlAGzxYl+gJQA88WyVAFzCORcpFx4lAIqBOgggpiWgCgFLzy4sUEyYBA+wAQI8hQBPoCWM8WAc8WzMntVABwUnmgGKGCEHNi0JzIyx9SMMs/WPoCUAfPFlAHzxbJcYAQyMsFJM8WUAb6AhXLahTMyXH7ABAkECMAfMMAI8IAsI4hghDVMnbbcIAQyMsFUAjPFlAE+gIWy2oSyx8Syz/JcvsAkzVsIeIDyFAE+gJYzxYBzxbMye1UAMkMO1E0PoA+kD6QNQwBtM/+gAwUUShUjfHBfLiwSXC//LiwgSCC5OHAL7y4sWCEHvdl97Iyx8Uyz9Y+gIhzxbJcYAYyMsFJM8WcPoCy2rMyYBA+wBAE8hQBPoCWM8WAc8WzMntVIACBIAg1yHtRND6APpA+kDUMATTHyGCEBeNRRm6AoIQe92X3roSsfLgyNM/MfoAMBOgUCPIUAT6AljPFgHPFszJ7VSBpMmqD'
@@ -43,7 +56,7 @@ export const STTON_MAINNET: PoolAssetConfig = {
43
56
 
44
57
  export const TSTON_MAINNET: PoolAssetConfig = {
45
58
  name: 'tsTON',
46
- assetId: sha256Hash('tsTON'),
59
+ assetId: ASSET_ID.tsTON,
47
60
  jettonMasterAddress: Address.parse('EQC98_qAmNEptUtPc7W6xdHh_ZHrBUFpw5Ft_IzNU20QAJav'),
48
61
  jettonWalletCode: Cell.fromBase64(
49
62
  'te6cckECIQEAB38AART/APSkE/S88sgLAQIBYgIDAgLLBAUCASAWFwSz0IMcAkl8E4AHQ0wMBcbCOhRNfA9s84PpA+kAx+gAx9AQx+gAx+gAwc6m0AALTHwEgghAPin6luo6FMDRZ2zzgIIIQF41FGbqOhjBERAPbPOA1JIIQWV8HvLqBgcICQATov0iGGAAeXCmwADCgCDXIe1E0PoA+kD6QNT6ANMvMCD4I7mXMBSgcFQUAN4G0x8BggD/8CGCEBeNRRm6AoIQe92X3roSsfL00z8BMPoAMBWgBRA0QTDIUAb6AlAEzxZYzxbMAfoCAQHLL8ntVAL2A9M/AQH6APpAIfAV7UTQ+gD6QPpA1PoA0y8wIPgjuZcwFKBwVBQA3lFYoVJMxwXy4sEqwv/y4sJUNiFwVHAAJBA1EEcQNlnIUAb6AlAEzxZYzxbMAfoCAQHLL8kiyMsBEvQA9ADLAMkg2zwG+kD0BDH6ACDXScIA8uLEGwoC9u1E0PoA+kD6QNT6ANMvMCD4I7mXMBSgcFQUAN4lnSLXZZjII9DPFsn7BN/fCtM/AQH6AFFxoAf6QPpAU33HBVRzh3BUcAAkEDUQRxA2WchQBvoCUATPFljPFswB+gIBAcsvySLIywES9AD0AMsAyds8UA/HBR6x8uLDDBsLA/6OhDRZ2zzgbCLtRND6APpA+kDU+gDTLzAg+CO5lzAUoHBUFADeKIIQbY5ePLqOPRBFXwUzUiLHBfLiwYIImJaAcPsCyIAQAcsFWM8WcPoCcAHLaoIQ1TJ22wHLHwHTPwESAcs/AdHJgQCC+wDgKIIQdopQsrrjAiiCEGn7MGy6DQ4PANzIghAXjUUZAcsfUAwByz9QCvoCJc8WAc8WKPoCUAnPFsnIgBgBywVQBs8WcPoCQIV3UAPLa8zMJZFykXHiUAqoFaCCCfeKQKAWvPLixQbJgED7AFAEBQPIUAb6AlAEzxZYzxbMAfoCAQHLL8ntVAH4+gBRyqEhjjlSHKAaociCEHNi0JwByx8kAcs/UAP6AgHPFlAKzxbJyIAQAcsFJs8WUAj6AlAHcVjLaszJcfsAEFeVEEw7XwTiBoIImJaAtgly+wIn1wsBwwAFwgAVsJI1NeMNUCXIUAb6AlAEzxZYzxbMAfoCAQHLL8ntVAwATsiAEAHLBVAHzxZw+gJwActqghDVMnbbAcsfUAUByz/JgQCC+wAQNAH27UTQ+gD6QPpA1PoA0y8wIPgjuZcwFKBwVBQA3gnTPwEB+gD6QPQEMFGCoVJ8xwXy4sEqwv/y4sIIggle88CgghAstBeAoBm88uLHyIIQe92X3gHLHwEByz9QB/oCI88WUAXPFhP0AMnIgBgBywUjzxZw+gIBcVjLaszJEACkEEVfBTNSIscF8uLB0z8BAfpA+gD0BNHIgBgBywVQA88WcPoCyIIQD4p+pQHLH1AEAcs/AfoCI88WUAPPFhL0AHD6AnABygDJcVjLaszJgED7AAT+4wJfAzIkghAxjv8Xuo5YNFrHBfLixgHTPwEB0z8BMNMvAQHUgQ8Q+COCCCeNAKAkvPL0+CMjufLg+dHIgBgBywVQBM8WcPoCcAHLaoIQHH+aGgHLH1gByz8BAcsvzHAByz/JgED7AOAkgguaN0664wIEghDDnwvmuuMCXwSEDxESExQAPIBA+wAEUDXIUAb6AlAEzxZYzxbMAfoCAQHLL8ntVAP+OFI3xwXy4sYE0z8BAfpA0y8BgQ8Q+COCCCeNAKAivPL0+CMhufLg+QHSAAEB0gABAdH4KIhBUAJwAshYzxYBzxZw+gJw+gLJIcjLARP0ABL0AMsAySDbPFCooCJwDLYJyIAYAcsFUAnPFiv6AlAKdljLa8yCECvWNwQByx9QBBobFQBcNFjHBfLixtM/AQHRyIAQAcsFWM8WcPoCcAHLaoIQX+m4ygHLHwEByz/JgED7AABmWMcF8uLG0z8BAfpA0ciAEAHLBVADzxZw+gJwActqghAsy6AGAcsfAQHLPwHPFsmAQPsAAATy8ABmAcs/Jc8WAQHLLyf6AlgBygABAcoAyYBA+wBDQ8hQBvoCUATPFljPFswB+gIBAcsvye1UAgFYGBkAPb9rz2omh9AH0gfSBqfQBpl5gQfBHcy5gKUDgqCgBvQCTbQCXwURAkBOAFkLGeLAOeLOH0BOH0BZJDkZYCJ+gAJegBlgGTtnkBobAD+3YF2omh9AH0gfSBqfQBpl5gQfBHcy5gKUDgqCgBvLcAEU/wD0pBP0vPLICxwAHPkAdMjLAnABygfL/8nQAgFiHR4BQtAzMdDTAwFxsJFb4PpAMAHTHwGCECvWNwS64wJbhA/y8B8AHaFxl9qJofSB9IH0AfQAYQH+7UTQ+kD6QPoA+gAwUjbHBfLh9APTPwEB+kDTLwEB+gDSAAEB0gABMVEooSmhIZNRiKCVUZmgCQjiKML/8uH1ggiYloBw+wImEDhAGshQBM8WWM8WAfoCAfoCye1UyIAQAcsFUATPFnD6AnABy2qCEG7bGIkByx9YAcs/Ac8WASAAJgHLL1j6AlgBygABAcoAyYMG+wDZ+GMW'
@@ -52,7 +65,7 @@ export const TSTON_MAINNET: PoolAssetConfig = {
52
65
 
53
66
  export const USDT_MAINNET: PoolAssetConfig = {
54
67
  name: 'USDT',
55
- assetId: sha256Hash('USDT'),
68
+ assetId: ASSET_ID.USDT,
56
69
  jettonMasterAddress: Address.parse('EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs'),
57
70
  jettonWalletCode: Cell.fromBoc(
58
71
  Buffer.from(
@@ -64,21 +77,21 @@ export const USDT_MAINNET: PoolAssetConfig = {
64
77
 
65
78
  export const JUSDT_TESTNET: PoolAssetConfig = {
66
79
  name: 'jUSDT',
67
- assetId: sha256Hash('jUSDT'),
80
+ assetId: ASSET_ID.jUSDT,
68
81
  jettonMasterAddress: Address.parse('kQBe4gtSQMxM5RpMYLr4ydNY72F8JkY-icZXG1NJcsju8XM7'),
69
82
  jettonWalletCode: JETTON_WALLET_STANDART_CODE_TESTNET
70
83
  }
71
84
 
72
85
  export const JUSDC_TESTNET: PoolAssetConfig = {
73
86
  name: 'jUSDC',
74
- assetId: sha256Hash('jUSDC'),
87
+ assetId: ASSET_ID.jUSDC,
75
88
  jettonMasterAddress: Address.parse('kQDaY5yUatYnHei73HBqRX_Ox9LK2XnR7XuCY9MFC2INbfYI'),
76
89
  jettonWalletCode: JETTON_WALLET_STANDART_CODE_TESTNET
77
90
  }
78
91
 
79
92
  export const STTON_TESTNET: PoolAssetConfig = {
80
93
  name: 'stTON',
81
- assetId: sha256Hash('stTON'),
94
+ assetId: ASSET_ID.stTON,
82
95
  jettonMasterAddress: Address.parse('kQC3Duw3dg8k98xf5S7Bm7YOWVJ5QW8hm3iLqFfJfa_g9h07'),
83
96
  jettonWalletCode: Cell.fromBoc(
84
97
  Buffer.from(
@@ -90,7 +103,7 @@ export const STTON_TESTNET: PoolAssetConfig = {
90
103
 
91
104
  export const TONUSDT_DEDUST_MAINNET: PoolAssetConfig = {
92
105
  name: 'TONUSDT_DEDUST',
93
- assetId: sha256Hash('TONUSDT_DEDUST'),
106
+ assetId: ASSET_ID.TONUSDT_DEDUST,
94
107
  jettonMasterAddress: Address.parse('EQA-X_yo3fzzbDbJ_0bzFWKqtRuZFIRa1sJsveZJ1YpViO3r'),
95
108
  jettonWalletCode: Cell.fromBoc(
96
109
  Buffer.from(
@@ -102,7 +115,7 @@ export const TONUSDT_DEDUST_MAINNET: PoolAssetConfig = {
102
115
 
103
116
  export const TON_STORM_MAINNET: PoolAssetConfig = {
104
117
  name: 'TON_STORM',
105
- assetId: sha256Hash('TON_STORM'),
118
+ assetId: ASSET_ID.TON_STORM,
106
119
  jettonMasterAddress: Address.parse('EQCNY2AQ3ZDYwJAqx_nzl9i9Xhd_Ex7izKJM6JTxXRnO6n1F'),
107
120
  jettonWalletCode: Cell.fromBoc(
108
121
  Buffer.from(
@@ -110,11 +123,12 @@ export const TON_STORM_MAINNET: PoolAssetConfig = {
110
123
  'hex',
111
124
  ),
112
125
  )[0],
126
+
113
127
  }
114
128
 
115
129
  export const USDT_STORM_MAINNET: PoolAssetConfig = {
116
130
  name: 'USDT_STORM',
117
- assetId: sha256Hash('USDT_STORM'),
131
+ assetId: ASSET_ID.USDT_STORM,
118
132
  jettonMasterAddress: Address.parse('EQCup4xxCulCcNwmOocM9HtDYPU8xe0449tQLp6a-5BLEegW'),
119
133
  jettonWalletCode: Cell.fromBoc(
120
134
  Buffer.from(
@@ -2,15 +2,21 @@ import { Address, Cell, toNano } from '@ton/core';
2
2
  import { sha256Hash } from '../utils/sha256BigInt';
3
3
  import { OracleNFT } from '../types/Master';
4
4
 
5
+
6
+ const ASSET_PRICE_SCALE = BigInt(1e9);
7
+
5
8
  export const MASTER_CONSTANTS = {
6
9
  FACTOR_SCALE: BigInt(1e12),
7
10
  ASSET_COEFFICIENT_SCALE: 10000n,
8
- ASSET_PRICE_SCALE: BigInt(1e9),
11
+ ASSET_PRICE_SCALE,
9
12
  ASSET_RESERVE_FACTOR_SCALE: 10000n,
10
13
  ASSET_LIQUIDATION_RESERVE_FACTOR_SCALE: 10000n,
11
14
  ASSET_ORIGINATION_FEE_SCALE: BigInt(1e9),
12
15
  ASSET_LIQUIDATION_THRESHOLD_SCALE: 10_000n,
13
16
  ASSET_LIQUIDATION_BONUS_SCALE: 10_000n,
17
+ ASSET_SRATE_SCALE: BigInt(1e12),
18
+ ASSET_BRATE_SCALE: BigInt(1e12),
19
+ COLLATERAL_WORTH_THRESHOLD: 100n * ASSET_PRICE_SCALE, // literally 100$
14
20
  };
15
21
 
16
22
  export const NULL_ADDRESS = Address.parse('UQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJKZ');
@@ -46,7 +46,7 @@ export const MAINNET_LP_POOL_CONFIG: PoolConfig = {
46
46
  USDT_MAINNET,
47
47
  TONUSDT_DEDUST_MAINNET,
48
48
  TON_STORM_MAINNET,
49
- USDT_STORM_MAINNET,
49
+ USDT_STORM_MAINNET
50
50
  ],
51
51
  lendingCode: LENDING_CODE
52
52
  };