@evaafi/sdk 0.9.0 → 0.9.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.
Files changed (117) hide show
  1. package/dist/api/feeds.d.ts +16 -24
  2. package/dist/api/feeds.js +22 -49
  3. package/dist/api/math.d.ts +1 -1
  4. package/dist/api/math.js +55 -38
  5. package/dist/api/parser.d.ts +2 -2
  6. package/dist/api/parser.js +3 -3
  7. package/dist/api/parsers/PythOracleParser.d.ts +3 -2
  8. package/dist/api/parsers/PythOracleParser.js +2 -1
  9. package/dist/api/prices.d.ts +1 -0
  10. package/dist/api/prices.js +2 -1
  11. package/dist/constants/general/index.d.ts +25 -11
  12. package/dist/constants/general/index.js +15 -1
  13. package/dist/constants/pools/mainnet.js +20 -18
  14. package/dist/constants/pools/testnet.js +14 -6
  15. package/dist/contracts/AbstractMaster.d.ts +239 -127
  16. package/dist/contracts/AbstractMaster.js +101 -16
  17. package/dist/contracts/ClassicMaster.d.ts +12 -12
  18. package/dist/contracts/PythMaster.d.ts +41 -24
  19. package/dist/contracts/PythMaster.js +61 -76
  20. package/dist/contracts/PythOracle.d.ts +16 -0
  21. package/dist/contracts/PythOracle.js +19 -0
  22. package/dist/contracts/index.d.ts +1 -0
  23. package/dist/contracts/index.js +1 -0
  24. package/dist/index.d.ts +1 -1
  25. package/dist/index.js +1 -1
  26. package/dist/{prices → oracles}/Types.d.ts +1 -4
  27. package/dist/oracles/collectors/AbstractCollector.d.ts +10 -0
  28. package/dist/oracles/collectors/AbstractCollector.js +6 -0
  29. package/dist/oracles/collectors/ClassicCollector.d.ts +22 -0
  30. package/dist/oracles/collectors/ClassicCollector.js +192 -0
  31. package/dist/oracles/collectors/PythCollector.d.ts +27 -0
  32. package/dist/oracles/collectors/PythCollector.js +252 -0
  33. package/dist/oracles/collectors/index.d.ts +3 -0
  34. package/dist/oracles/collectors/index.js +19 -0
  35. package/dist/{prices → oracles}/index.d.ts +2 -3
  36. package/dist/{prices → oracles}/index.js +2 -3
  37. package/dist/oracles/prices/AbstractPrices.d.ts +33 -0
  38. package/dist/oracles/prices/AbstractPrices.js +40 -0
  39. package/dist/oracles/prices/ClassicPrices.d.ts +19 -0
  40. package/dist/oracles/prices/ClassicPrices.js +48 -0
  41. package/dist/oracles/prices/PythPrices.d.ts +18 -0
  42. package/dist/oracles/prices/PythPrices.js +32 -0
  43. package/dist/oracles/prices/index.d.ts +3 -0
  44. package/dist/oracles/prices/index.js +19 -0
  45. package/dist/{prices → oracles}/utils.d.ts +7 -1
  46. package/dist/{prices → oracles}/utils.js +10 -1
  47. package/dist/rewards/RewardMaster.d.ts +1 -0
  48. package/dist/rewards/RewardUser.d.ts +1 -0
  49. package/dist/types/Master.d.ts +5 -5
  50. package/dist/types/MasterRewards.d.ts +1 -0
  51. package/dist/types/UserRewards.d.ts +1 -0
  52. package/dist/utils/sha256BigInt.d.ts +1 -0
  53. package/package.json +2 -3
  54. package/src/api/feeds.ts +24 -60
  55. package/src/api/math.ts +118 -90
  56. package/src/api/parser.ts +5 -5
  57. package/src/api/parsers/PythOracleParser.ts +6 -2
  58. package/src/api/prices.ts +2 -1
  59. package/src/constants/general/index.ts +16 -1
  60. package/src/constants/pools/mainnet.ts +20 -35
  61. package/src/constants/pools/testnet.ts +17 -8
  62. package/src/contracts/AbstractMaster.ts +272 -144
  63. package/src/contracts/ClassicMaster.ts +12 -12
  64. package/src/contracts/PythMaster.ts +130 -123
  65. package/src/contracts/PythOracle.ts +20 -0
  66. package/src/contracts/index.ts +2 -0
  67. package/src/index.ts +1 -1
  68. package/src/{prices → oracles}/Types.ts +0 -5
  69. package/src/oracles/collectors/AbstractCollector.ts +22 -0
  70. package/src/oracles/collectors/ClassicCollector.ts +263 -0
  71. package/src/oracles/collectors/PythCollector.ts +358 -0
  72. package/src/oracles/collectors/index.ts +3 -0
  73. package/src/{prices → oracles}/index.ts +2 -3
  74. package/src/oracles/prices/AbstractPrices.ts +59 -0
  75. package/src/oracles/prices/ClassicPrices.ts +52 -0
  76. package/src/oracles/prices/PythPrices.ts +40 -0
  77. package/src/oracles/prices/index.ts +3 -0
  78. package/src/{prices → oracles}/utils.ts +12 -1
  79. package/src/types/Master.ts +4 -6
  80. package/dist/api/pyth.d.ts +0 -16
  81. package/dist/api/pyth.js +0 -35
  82. package/dist/constants/assets.d.ts +0 -48
  83. package/dist/constants/assets.js +0 -176
  84. package/dist/constants/general.d.ts +0 -67
  85. package/dist/constants/general.js +0 -75
  86. package/dist/constants/pools.d.ts +0 -13
  87. package/dist/constants/pools.js +0 -120
  88. package/dist/contracts/MasterContract.d.ts +0 -156
  89. package/dist/contracts/MasterContract.js +0 -260
  90. package/dist/prices/Oracle.interface.d.ts +0 -9
  91. package/dist/prices/Oracle.interface.js +0 -2
  92. package/dist/prices/Prices.d.ts +0 -11
  93. package/dist/prices/Prices.js +0 -53
  94. package/dist/prices/PricesCollector.d.ts +0 -22
  95. package/dist/prices/PricesCollector.js +0 -146
  96. package/dist/prices/PythCollector.d.ts +0 -22
  97. package/dist/prices/PythCollector.js +0 -217
  98. package/src/prices/Oracle.interface.ts +0 -18
  99. package/src/prices/Prices.ts +0 -45
  100. package/src/prices/PricesCollector.ts +0 -169
  101. package/src/prices/PythCollector.ts +0 -294
  102. /package/dist/{prices → oracles}/Types.js +0 -0
  103. /package/dist/{prices → oracles}/constants.d.ts +0 -0
  104. /package/dist/{prices → oracles}/constants.js +0 -0
  105. /package/dist/{prices → oracles}/sources/Backend.d.ts +0 -0
  106. /package/dist/{prices → oracles}/sources/Backend.js +0 -0
  107. /package/dist/{prices → oracles}/sources/Icp.d.ts +0 -0
  108. /package/dist/{prices → oracles}/sources/Icp.js +0 -0
  109. /package/dist/{prices → oracles}/sources/PriceSource.d.ts +0 -0
  110. /package/dist/{prices → oracles}/sources/PriceSource.js +0 -0
  111. /package/dist/{prices → oracles}/sources/index.d.ts +0 -0
  112. /package/dist/{prices → oracles}/sources/index.js +0 -0
  113. /package/src/{prices → oracles}/constants.ts +0 -0
  114. /package/src/{prices → oracles}/sources/Backend.ts +0 -0
  115. /package/src/{prices → oracles}/sources/Icp.ts +0 -0
  116. /package/src/{prices → oracles}/sources/PriceSource.ts +0 -0
  117. /package/src/{prices → oracles}/sources/index.ts +0 -0
package/src/api/math.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import { Dictionary } from '@ton/core';
2
+ import { UNDEFINED_ASSET } from '../constants/assets';
1
3
  import {
2
4
  AgregatedBalances,
3
5
  AssetApy,
@@ -8,9 +10,8 @@ import {
8
10
  ExtendedAssetsConfig,
9
11
  ExtendedAssetsData,
10
12
  MasterConstants,
11
- PoolConfig
13
+ PoolConfig,
12
14
  } from '../types/Master';
13
- import { Dictionary } from '@ton/core';
14
15
  import {
15
16
  BalanceChangeType,
16
17
  BalanceType,
@@ -18,9 +19,8 @@ import {
18
19
  LiquidationData,
19
20
  PredictAPYArgs,
20
21
  PredictHealthFactorArgs,
21
- UserBalance
22
+ UserBalance,
22
23
  } from '../types/User';
23
- import { UNDEFINED_ASSET } from '../constants/assets';
24
24
  import { addReserve, isBadDebt } from './liquidation';
25
25
 
26
26
  export function mulFactor(decimal: bigint, a: bigint, b: bigint): bigint {
@@ -61,9 +61,13 @@ export function getAssetLiquidityMinusReserves(assetData: AssetData, masterConst
61
61
  return bigIntMin(total_supply - total_borrow, assetData.balance);
62
62
  }
63
63
 
64
- export function calculateCurrentRates(assetConfig: AssetConfig, assetData: AssetData, masterConstants: MasterConstants) {
64
+ export function calculateCurrentRates(
65
+ assetConfig: AssetConfig,
66
+ assetData: AssetData,
67
+ masterConstants: MasterConstants,
68
+ ) {
65
69
  const now = BigInt(Math.floor(Date.now() / 1000));
66
- const timeElapsed = now - assetData.lastAccural;
70
+ const timeElapsed = now - assetData.lastAccrual;
67
71
  const { supplyInterest, borrowInterest } = calculateAssetInterest(assetConfig, assetData, masterConstants);
68
72
 
69
73
  if (timeElapsed > 0) {
@@ -76,7 +80,7 @@ export function calculateCurrentRates(assetConfig: AssetConfig, assetData: Asset
76
80
  bRate: updatedBRate,
77
81
  supplyInterest,
78
82
  borrowInterest,
79
- now
83
+ now,
80
84
  };
81
85
  }
82
86
 
@@ -85,7 +89,7 @@ export function calculateCurrentRates(assetConfig: AssetConfig, assetData: Asset
85
89
  bRate: assetData.bRate,
86
90
  supplyInterest,
87
91
  borrowInterest,
88
- now
92
+ now,
89
93
  };
90
94
  }
91
95
 
@@ -93,7 +97,7 @@ export function calculateAssetData(
93
97
  assetsConfigDict: ExtendedAssetsConfig,
94
98
  assetsDataDict: Dictionary<bigint, AssetData>,
95
99
  assetId: bigint,
96
- masterConstants: MasterConstants
100
+ masterConstants: MasterConstants,
97
101
  ): ExtendedAssetData {
98
102
  const config = assetsConfigDict.get(assetId);
99
103
  const data = assetsDataDict.get(assetId);
@@ -105,7 +109,7 @@ export function calculateAssetData(
105
109
  const { sRate, bRate, supplyInterest, borrowInterest, now } = calculateCurrentRates(config, data, masterConstants);
106
110
  data.sRate = sRate || 0n;
107
111
  data.bRate = bRate || 0n;
108
- data.lastAccural = now;
112
+ data.lastAccrual = now;
109
113
 
110
114
  const supplyApy = (1 + (Number(supplyInterest) / 1e12) * 24 * 3600) ** 365 - 1;
111
115
  const borrowApy = (1 + (Number(borrowInterest) / 1e12) * 24 * 3600) ** 365 - 1;
@@ -113,31 +117,26 @@ export function calculateAssetData(
113
117
  return {
114
118
  ...data,
115
119
  ...{ supplyInterest, borrowInterest },
116
- ...{ supplyApy, borrowApy }
120
+ ...{ supplyApy, borrowApy },
117
121
  };
118
122
  }
119
123
 
120
124
  export function calculateAssetInterest(
121
125
  assetConfig: AssetConfig,
122
126
  assetData: AssetData,
123
- masterConstants: MasterConstants
127
+ masterConstants: MasterConstants,
124
128
  ): AssetInterest {
125
129
  const totalSupply = calculatePresentValue(assetData.sRate, assetData.totalSupply, masterConstants);
126
130
  const totalBorrow = calculatePresentValue(assetData.bRate, assetData.totalBorrow, masterConstants);
127
131
 
128
- return calculateInterestWithSupplyBorrow(
129
- totalSupply,
130
- totalBorrow,
131
- assetConfig,
132
- masterConstants
133
- );
132
+ return calculateInterestWithSupplyBorrow(totalSupply, totalBorrow, assetConfig, masterConstants);
134
133
  }
135
134
 
136
135
  export function calculateInterestWithSupplyBorrow(
137
136
  totalSupply: bigint,
138
137
  totalBorrow: bigint,
139
138
  assetConfig: AssetConfig,
140
- masterConstants: MasterConstants
139
+ masterConstants: MasterConstants,
141
140
  ): AssetInterest {
142
141
  let utilization = 0n;
143
142
  let supplyInterest = 0n;
@@ -158,25 +157,24 @@ export function calculateInterestWithSupplyBorrow(
158
157
  mulFactor(
159
158
  masterConstants.FACTOR_SCALE,
160
159
  assetConfig.borrowRateSlopeHigh,
161
- utilization - assetConfig.targetUtilization
160
+ utilization - assetConfig.targetUtilization,
162
161
  );
163
162
  }
164
163
 
165
164
  supplyInterest = mulDiv(
166
165
  mulDiv(borrowInterest, utilization, masterConstants.FACTOR_SCALE),
167
166
  masterConstants.ASSET_RESERVE_FACTOR_SCALE - assetConfig.reserveFactor,
168
- masterConstants.ASSET_RESERVE_FACTOR_SCALE
167
+ masterConstants.ASSET_RESERVE_FACTOR_SCALE,
169
168
  );
170
169
 
171
170
  return {
172
171
  supplyInterest,
173
- borrowInterest
172
+ borrowInterest,
174
173
  };
175
174
  }
176
175
 
177
-
178
176
  export function checkNotInDebtAtAll(principals: Dictionary<bigint, bigint>): boolean {
179
- return principals.values().every(x => x >= 0n);
177
+ return principals.values().every((x) => x >= 0n);
180
178
  }
181
179
 
182
180
  export function getAgregatedBalances(
@@ -184,14 +182,13 @@ export function getAgregatedBalances(
184
182
  assetsConfig: ExtendedAssetsConfig,
185
183
  principals: Dictionary<bigint, bigint>,
186
184
  prices: Dictionary<bigint, bigint>,
187
- masterConstants: MasterConstants
185
+ masterConstants: MasterConstants,
188
186
  ): AgregatedBalances {
189
187
  let user_total_supply = 0n;
190
188
  let user_total_borrow = 0n;
191
189
 
192
190
  for (const [assetId, principal] of principals) {
193
191
  if (principal) {
194
-
195
192
  if (!prices.has(assetId)) {
196
193
  return { totalSupply: 0n, totalBorrow: 0n };
197
194
  }
@@ -200,9 +197,13 @@ export function getAgregatedBalances(
200
197
  const assetConfig = assetsConfig.get(assetId)!;
201
198
 
202
199
  if (principal < 0) {
203
- user_total_borrow += presentValue(assetData.sRate, assetData.bRate, principal, masterConstants).amount * price / 10n ** assetConfig.decimals;
200
+ user_total_borrow +=
201
+ (presentValue(assetData.sRate, assetData.bRate, principal, masterConstants).amount * price) /
202
+ 10n ** assetConfig.decimals;
204
203
  } else {
205
- user_total_supply += presentValue(assetData.sRate, assetData.bRate, principal, masterConstants).amount * price / 10n ** assetConfig.decimals;
204
+ user_total_supply +=
205
+ (presentValue(assetData.sRate, assetData.bRate, principal, masterConstants).amount * price) /
206
+ 10n ** assetConfig.decimals;
206
207
  }
207
208
  }
208
209
  }
@@ -215,7 +216,7 @@ export function calculateMaximumWithdrawAmount(
215
216
  principals: Dictionary<bigint, bigint>,
216
217
  prices: Dictionary<bigint, bigint>,
217
218
  masterConstants: MasterConstants,
218
- assetId: bigint
219
+ assetId: bigint,
219
220
  ): bigint {
220
221
  let withdrawAmountMax = 0n;
221
222
 
@@ -240,19 +241,18 @@ export function calculateMaximumWithdrawAmount(
240
241
  if (assetConfig.collateralFactor == 0n) {
241
242
  maxAmountToReclaim = oldPresentValue.amount;
242
243
  } else if (price > 0) {
243
- maxAmountToReclaim =
244
- bigIntMax(0n,
245
- mulDiv(
246
- mulDiv(borrowable, masterConstants.ASSET_COEFFICIENT_SCALE, assetConfig.collateralFactor),
247
- 10n ** assetConfig.decimals, price)
248
- - calculatePresentValue(assetData.sRate, assetConfig.dust, masterConstants) / 2n
249
- );
244
+ maxAmountToReclaim = bigIntMax(
245
+ 0n,
246
+ mulDiv(
247
+ mulDiv(borrowable, masterConstants.ASSET_COEFFICIENT_SCALE, assetConfig.collateralFactor),
248
+ 10n ** assetConfig.decimals,
249
+ price,
250
+ ) -
251
+ calculatePresentValue(assetData.sRate, assetConfig.dust, masterConstants) / 2n,
252
+ );
250
253
  }
251
254
 
252
- withdrawAmountMax = bigIntMin(
253
- maxAmountToReclaim,
254
- oldPresentValue.amount
255
- );
255
+ withdrawAmountMax = bigIntMin(maxAmountToReclaim, oldPresentValue.amount);
256
256
  }
257
257
  } else {
258
258
  if (!prices.has(assetId)) {
@@ -261,7 +261,11 @@ export function calculateMaximumWithdrawAmount(
261
261
 
262
262
  const price = prices.get(assetId) as bigint;
263
263
 
264
- return getAvailableToBorrow(assetsConfig, assetsData, principals, prices, masterConstants) * (10n ** assetConfig.decimals) / price;
264
+ return (
265
+ (getAvailableToBorrow(assetsConfig, assetsData, principals, prices, masterConstants) *
266
+ 10n ** assetConfig.decimals) /
267
+ price
268
+ );
265
269
  }
266
270
 
267
271
  return withdrawAmountMax;
@@ -272,14 +276,14 @@ export function getAvailableToBorrow(
272
276
  assetsData: ExtendedAssetsData,
273
277
  principals: Dictionary<bigint, bigint>,
274
278
  prices: Dictionary<bigint, bigint>,
275
- masterConstants: MasterConstants
279
+ masterConstants: MasterConstants,
276
280
  ): bigint {
277
281
  let borrowLimit = 0n;
278
282
  let borrowAmount = 0n;
279
283
 
280
284
  for (const assetID of principals.keys()) {
281
285
  const principal = principals.get(assetID) as bigint;
282
-
286
+
283
287
  if (principal == 0n) {
284
288
  continue;
285
289
  }
@@ -293,13 +297,21 @@ export function getAvailableToBorrow(
293
297
  const price = prices.get(assetID) as bigint;
294
298
 
295
299
  if (principal < 0n) {
296
- borrowAmount += mulDiv(calculatePresentValue(assetData.bRate, -principal, masterConstants), price, 10n ** assetConfig.decimals);
300
+ borrowAmount += mulDiv(
301
+ calculatePresentValue(assetData.bRate, -principal, masterConstants),
302
+ price,
303
+ 10n ** assetConfig.decimals,
304
+ );
297
305
  } else if (principal > 0n) {
298
- borrowLimit +=
306
+ borrowLimit += mulDiv(
299
307
  mulDiv(
300
- mulDiv(calculatePresentValue(assetData.sRate, principal, masterConstants), price, 10n ** assetConfig.decimals),
301
- assetConfig.collateralFactor,
302
- masterConstants.ASSET_COEFFICIENT_SCALE);
308
+ calculatePresentValue(assetData.sRate, principal, masterConstants),
309
+ price,
310
+ 10n ** assetConfig.decimals,
311
+ ),
312
+ assetConfig.collateralFactor,
313
+ masterConstants.ASSET_COEFFICIENT_SCALE,
314
+ );
303
315
  }
304
316
  }
305
317
 
@@ -313,21 +325,26 @@ export function getAvailableToBorrow(
313
325
  * @param principalValue asset principal value
314
326
  * @param masterConstants pool constants
315
327
  */
316
- export function presentValue(sRate: bigint, bRate: bigint, principalValue: bigint, masterConstants: MasterConstants): UserBalance {
328
+ export function presentValue(
329
+ sRate: bigint,
330
+ bRate: bigint,
331
+ principalValue: bigint,
332
+ masterConstants: MasterConstants,
333
+ ): UserBalance {
317
334
  if (principalValue > 0) {
318
335
  return {
319
336
  amount: calculatePresentValue(sRate, principalValue, masterConstants),
320
- type: BalanceType.supply
337
+ type: BalanceType.supply,
321
338
  };
322
339
  } else if (principalValue < 0) {
323
340
  return {
324
341
  amount: calculatePresentValue(bRate, -principalValue, masterConstants),
325
- type: BalanceType.borrow
342
+ type: BalanceType.borrow,
326
343
  };
327
344
  } else {
328
345
  return {
329
346
  amount: 0n,
330
- type: undefined
347
+ type: undefined,
331
348
  };
332
349
  }
333
350
  }
@@ -337,11 +354,7 @@ export function presentValue(sRate: bigint, bRate: bigint, principalValue: bigin
337
354
  * @param parameters
338
355
  */
339
356
  export function calculateHealthParams(parameters: HealthParamsArgs) {
340
- const {
341
- principals, prices,
342
- assetsData, assetsConfig,
343
- poolConfig
344
- } = parameters;
357
+ const { principals, prices, assetsData, assetsConfig, poolConfig } = parameters;
345
358
 
346
359
  const { ASSET_LIQUIDATION_THRESHOLD_SCALE } = poolConfig.masterConstants;
347
360
 
@@ -353,22 +366,22 @@ export function calculateHealthParams(parameters: HealthParamsArgs) {
353
366
  if (!principals.has(asset.assetId)) continue;
354
367
  const assetPrincipal = principals.get(asset.assetId)!;
355
368
 
356
- if (!assetsConfig.has(asset.assetId)) throw (`No config for ${asset.name}:${asset.assetId}`);
369
+ if (!assetsConfig.has(asset.assetId)) throw `No config for ${asset.name}:${asset.assetId}`;
357
370
  const assetConfig = assetsConfig.get(asset.assetId)!;
358
371
 
359
- if (!assetsData.has(asset.assetId)) throw (`No data for asset ${asset.name}:${asset.assetId}`);
372
+ if (!assetsData.has(asset.assetId)) throw `No data for asset ${asset.name}:${asset.assetId}`;
360
373
  const assetData = assetsData.get(asset.assetId)!;
361
374
 
362
- if (!prices.has(asset.assetId)) throw (`No price for asset ${asset.name}:${asset.assetId}`);
375
+ if (!prices.has(asset.assetId)) throw `No price for asset ${asset.name}:${asset.assetId}`;
363
376
  const assetPrice = prices.get(asset.assetId)! as bigint;
364
377
  const assetScale = 10n ** assetConfig.decimals;
365
378
 
366
379
  const { sRate, bRate } = assetData;
367
380
  const assetBalance = presentValue(sRate, bRate, assetPrincipal, poolConfig.masterConstants);
368
- const assetWorth = assetBalance.amount * assetPrice / assetScale;
381
+ const assetWorth = (assetBalance.amount * assetPrice) / assetScale;
369
382
  if (assetBalance.type === BalanceType.supply) {
370
383
  totalSupply += assetWorth;
371
- totalLimit += assetWorth * assetConfig.liquidationThreshold / ASSET_LIQUIDATION_THRESHOLD_SCALE;
384
+ totalLimit += (assetWorth * assetConfig.liquidationThreshold) / ASSET_LIQUIDATION_THRESHOLD_SCALE;
372
385
  } else if (assetBalance.type === BalanceType.borrow && assetConfig.dust < assetBalance.amount) {
373
386
  totalDebt += assetWorth;
374
387
  }
@@ -383,9 +396,11 @@ export function calculateHealthParams(parameters: HealthParamsArgs) {
383
396
  };
384
397
 
385
398
  return {
386
- totalDebt, totalLimit, totalSupply,
399
+ totalDebt,
400
+ totalLimit,
401
+ totalSupply,
387
402
  isLiquidatable: _isLiquidable,
388
- isBadDebt: _isBadDebt
403
+ isBadDebt: _isBadDebt,
389
404
  };
390
405
  }
391
406
 
@@ -403,7 +418,7 @@ export function calculateLiquidationData(
403
418
  assetsData: ExtendedAssetsData,
404
419
  principals: Dictionary<bigint, bigint>,
405
420
  prices: Dictionary<bigint, bigint>,
406
- poolConfig: PoolConfig
421
+ poolConfig: PoolConfig,
407
422
  ): LiquidationData {
408
423
  let collateralValue = 0n;
409
424
  let collateralAsset = UNDEFINED_ASSET;
@@ -412,23 +427,22 @@ export function calculateLiquidationData(
412
427
  let totalDebt = 0n;
413
428
  let totalLimit = 0n;
414
429
 
415
- const {
416
- ASSET_SRATE_SCALE, ASSET_BRATE_SCALE,
417
- COLLATERAL_WORTH_THRESHOLD
418
- } = poolConfig.masterConstants;
430
+ const { ASSET_SRATE_SCALE, ASSET_BRATE_SCALE, COLLATERAL_WORTH_THRESHOLD } = poolConfig.masterConstants;
419
431
 
420
432
  for (const asset of poolConfig.poolAssetsConfig) {
421
433
  const principal = principals.get(asset.assetId)!;
422
434
  if (!principal) continue;
423
435
  const assetConfig = assetsConfig.get(asset.assetId)!;
424
436
  const assetData = assetsData.get(asset.assetId)!;
425
- const balance = principal > 0 ?
426
- (principal * assetData.sRate) / ASSET_SRATE_SCALE :
427
- (principal * assetData.bRate) / ASSET_BRATE_SCALE;
437
+ const balance =
438
+ principal > 0
439
+ ? (principal * assetData.sRate) / ASSET_SRATE_SCALE
440
+ : (principal * assetData.bRate) / ASSET_BRATE_SCALE;
428
441
 
429
442
  const assetWorth = (bigAbs(balance) * prices.get(asset.assetId)!) / 10n ** assetConfig.decimals;
430
443
  if (balance > 0) {
431
- totalLimit += (assetWorth * assetConfig.liquidationThreshold) / poolConfig.masterConstants.ASSET_COEFFICIENT_SCALE;
444
+ totalLimit +=
445
+ (assetWorth * assetConfig.liquidationThreshold) / poolConfig.masterConstants.ASSET_COEFFICIENT_SCALE;
432
446
  // get the greatest collateral
433
447
  if (assetWorth > collateralValue) {
434
448
  collateralValue = assetWorth;
@@ -455,8 +469,8 @@ export function calculateLiquidationData(
455
469
  (bigIntMax(collateralValue / 3n, bigIntMin(collateralValue, COLLATERAL_WORTH_THRESHOLD)) *
456
470
  loanScale *
457
471
  poolConfig.masterConstants.ASSET_COEFFICIENT_SCALE) /
458
- liquidationBonus /
459
- loanAssetPrice
472
+ liquidationBonus /
473
+ loanAssetPrice,
460
474
  );
461
475
  values.push((loanValue * loanScale) / loanAssetPrice);
462
476
 
@@ -464,9 +478,11 @@ export function calculateLiquidationData(
464
478
  const collateralAssetPrice: bigint = prices.get(collateralAsset.assetId)!;
465
479
  const collateralDecimal = 10n ** collateralAssetConfig.decimals;
466
480
  let minCollateralAmount =
467
- (((liquidationAmount * loanAssetPrice * liquidationBonus) / poolConfig.masterConstants.ASSET_LIQUIDATION_BONUS_SCALE) * collateralDecimal) /
468
- collateralAssetPrice /
469
- loanScale -
481
+ (((liquidationAmount * loanAssetPrice * liquidationBonus) /
482
+ poolConfig.masterConstants.ASSET_LIQUIDATION_BONUS_SCALE) *
483
+ collateralDecimal) /
484
+ collateralAssetPrice /
485
+ loanScale -
470
486
  10n;
471
487
  minCollateralAmount = (minCollateralAmount * 97n) / 100n;
472
488
  if (minCollateralAmount > 0n) {
@@ -478,8 +494,12 @@ export function calculateLiquidationData(
478
494
  totalDebt,
479
495
  totalLimit,
480
496
  liquidable: true,
481
- liquidationAmount: addReserve(liquidationAmount, loanAssetConfig.liquidationReserveFactor, poolConfig.masterConstants.ASSET_RESERVE_FACTOR_SCALE),
482
- minCollateralAmount
497
+ liquidationAmount: addReserve(
498
+ liquidationAmount,
499
+ loanAssetConfig.liquidationReserveFactor,
500
+ poolConfig.masterConstants.ASSET_RESERVE_FACTOR_SCALE,
501
+ ),
502
+ minCollateralAmount,
483
503
  };
484
504
  }
485
505
  }
@@ -491,7 +511,7 @@ export function calculateLiquidationData(
491
511
  greatestLoanValue: loanValue,
492
512
  totalDebt,
493
513
  totalLimit,
494
- liquidable: false
514
+ liquidable: false,
495
515
  };
496
516
  }
497
517
 
@@ -509,31 +529,39 @@ export function predictHealthFactor(args: PredictHealthFactorArgs): number {
509
529
 
510
530
  const decimals = Number(assetConfig.decimals);
511
531
 
512
- const currentBalance = assetPrice * Number(currentAmount) / Math.pow(10, decimals);
532
+ const currentBalance = (assetPrice * Number(currentAmount)) / Math.pow(10, decimals);
513
533
  const changeType = args.balanceChangeType;
514
534
 
515
535
  if (currentAmount != null && currentAmount != 0n) {
516
536
  if (changeType == BalanceChangeType.Borrow) {
517
- totalBorrow += currentBalance * (1 + Number(assetConfig.originationFee) / Number(args.poolConfig.masterConstants.ASSET_ORIGINATION_FEE_SCALE));
537
+ totalBorrow +=
538
+ currentBalance *
539
+ (1 +
540
+ Number(assetConfig.originationFee) /
541
+ Number(args.poolConfig.masterConstants.ASSET_ORIGINATION_FEE_SCALE));
518
542
  } else if (changeType == BalanceChangeType.Repay) {
519
543
  totalBorrow -= currentBalance;
520
544
  } else if (changeType == BalanceChangeType.Withdraw) {
521
- totalLimit -= currentBalance * Number(assetConfig.liquidationThreshold) / Number(args.poolConfig.masterConstants.ASSET_COEFFICIENT_SCALE);
545
+ totalLimit -=
546
+ (currentBalance * Number(assetConfig.liquidationThreshold)) /
547
+ Number(args.poolConfig.masterConstants.ASSET_COEFFICIENT_SCALE);
522
548
  } else if (changeType == BalanceChangeType.Supply) {
523
- totalLimit += currentBalance * Number(assetConfig.liquidationThreshold) / Number(args.poolConfig.masterConstants.ASSET_COEFFICIENT_SCALE);
549
+ totalLimit +=
550
+ (currentBalance * Number(assetConfig.liquidationThreshold)) /
551
+ Number(args.poolConfig.masterConstants.ASSET_COEFFICIENT_SCALE);
524
552
  }
525
553
  }
526
554
  if (Number(totalLimit) == 0) {
527
555
  return 1;
528
556
  }
529
557
 
530
- return Math.min(Math.max(1 - totalBorrow / totalLimit, 0), 1); // let's limit a result to zero below and one above
558
+ return Math.min(Math.max(1 - totalBorrow / totalLimit, 0), 1); // let's limit a result to zero below and one above
531
559
  }
532
560
 
533
561
  /**
534
- * Predicts how APY will change as a result of one of the actions Borrow, Supply, Withdraw or Repay.
562
+ * Predicts how APY will change as a result of one of the actions Borrow, Supply, Withdraw or Repay.
535
563
  *
536
- * Used on the front-end.
564
+ * Used on the front-end.
537
565
  *
538
566
  * @returns Estimated APYs for Supply and Borrow
539
567
  */
@@ -565,6 +593,6 @@ export function predictAPY(args: PredictAPYArgs): AssetInterest & AssetApy {
565
593
  return {
566
594
  ...interest,
567
595
  supplyApy: (1 + (Number(interest.supplyInterest) / 1e12) * 24 * 3600) ** 365 - 1,
568
- borrowApy: (1 + (Number(interest.borrowInterest) / 1e12) * 24 * 3600) ** 365 - 1
569
- }
596
+ borrowApy: (1 + (Number(interest.borrowInterest) / 1e12) * 24 * 3600) ** 365 - 1,
597
+ };
570
598
  }
package/src/api/parser.ts CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  ExtendedAssetsConfig,
8
8
  ExtendedAssetsData,
9
9
  MasterConstants,
10
- PoolAssetsConfig,
10
+ PoolAssetConfig,
11
11
  PoolConfig,
12
12
  } from '../types/Master';
13
13
  import { BalanceType, UserBalance, UserData, UserLiteData, UserRewards } from '../types/User';
@@ -46,7 +46,7 @@ export function createAssetData(): DictionaryValue<AssetData> {
46
46
  buidler.storeUint(src.bRate, 64);
47
47
  buidler.storeInt(src.totalSupply, 64);
48
48
  buidler.storeInt(src.totalBorrow, 64);
49
- buidler.storeUint(src.lastAccural, 32);
49
+ buidler.storeUint(src.lastAccrual, 32);
50
50
  buidler.storeUint(src.balance, 64);
51
51
  buidler.storeUint(src.trackingSupplyIndex, 64);
52
52
  buidler.storeUint(src.trackingBorrowIndex, 64);
@@ -57,7 +57,7 @@ export function createAssetData(): DictionaryValue<AssetData> {
57
57
  const bRate = BigInt(src.loadUintBig(64));
58
58
  const totalSupply = BigInt(src.loadIntBig(64));
59
59
  const totalBorrow = BigInt(src.loadIntBig(64));
60
- const lastAccural = BigInt(src.loadUintBig(32));
60
+ const lastAccrual = BigInt(src.loadUintBig(32));
61
61
  const balance = BigInt(src.loadUintBig(64));
62
62
  const trackingSupplyIndex = BigInt(src.loadUintBig(64));
63
63
  const trackingBorrowIndex = BigInt(src.loadUintBig(64));
@@ -68,7 +68,7 @@ export function createAssetData(): DictionaryValue<AssetData> {
68
68
  bRate,
69
69
  totalSupply,
70
70
  totalBorrow,
71
- lastAccural,
71
+ lastAccrual,
72
72
  balance,
73
73
  trackingSupplyIndex,
74
74
  trackingBorrowIndex,
@@ -164,7 +164,7 @@ export function createAssetConfig(): DictionaryValue<AssetConfig> {
164
164
 
165
165
  export function parseMasterData(
166
166
  masterDataBOC: string,
167
- poolAssetsConfig: PoolAssetsConfig,
167
+ poolAssetsConfig: PoolAssetConfig[],
168
168
  masterConstants: MasterConstants,
169
169
  oracleParser: OracleParser,
170
170
  ): MasterData<MasterConfig<OracleInfo>> {
@@ -1,10 +1,12 @@
1
+ import { HexString } from '@pythnetwork/hermes-client';
1
2
  import { Address, Dictionary, Slice } from '@ton/core';
3
+ import { FeedMapItem, parseFeedsMapDict } from '../feeds';
2
4
  import { AbstractOracleParser } from './AbstractOracleParser';
3
5
 
4
6
  export type OracleConfig = {
5
7
  pythAddress: Address;
6
8
  // FYI: The Pyth max feeds count is 7, but it can add more in the future
7
- feedsMap: Dictionary<bigint, Buffer>;
9
+ feedsMap: Map<HexString, FeedMapItem>;
8
10
  allowedRefTokens: Dictionary<bigint, bigint>;
9
11
  };
10
12
 
@@ -23,7 +25,9 @@ export class PythOracleParser extends AbstractOracleParser {
23
25
 
24
26
  return {
25
27
  pythAddress: oraclesSlice.loadAddress(),
26
- feedsMap: feedDataSlice.loadDict(Dictionary.Keys.BigUint(256), Dictionary.Values.Buffer(64)),
28
+ feedsMap: parseFeedsMapDict(
29
+ feedDataSlice.loadDict(Dictionary.Keys.BigUint(256), Dictionary.Values.Buffer(64)),
30
+ ),
27
31
  allowedRefTokens: feedDataSlice.loadDict(Dictionary.Keys.BigUint(256), Dictionary.Values.BigUint(256)),
28
32
  pricesTtl: oraclesSlice.loadUint(32),
29
33
  pythComputeBaseGas: oraclesSlice.loadUintBig(64),
package/src/api/prices.ts CHANGED
@@ -4,6 +4,7 @@ import { Cell } from '@ton/core';
4
4
  import { beginCell } from '@ton/ton';
5
5
  import { Buffer } from 'buffer';
6
6
 
7
+ // TODO: move to PythCollector
7
8
  export function composeFeedsCell(feeds: HexString[]): Cell {
8
9
  if (feeds.length === 0) {
9
10
  return beginCell().storeUint(0, 8).endCell();
@@ -40,7 +41,7 @@ export async function getPrices(endpoints: string[] = ["api.stardust-mainnet.iot
40
41
  backendEndpoints: DefaultPriceSourcesConfig.backendEndpoints,
41
42
  }
42
43
 
43
- const priceCollector = new PricesCollector(poolConfig, sources);
44
+ const priceCollector = new ClassicCollector(poolConfig, sources);
44
45
  const prices = await priceCollector.getPrices();
45
46
 
46
47
  return { dict: prices.dict, dataCell: prices.dataCell };
@@ -88,4 +88,19 @@ export const FEES = {
88
88
  REWARD_MASTER_WITHDRAW: toNano('0.1'),
89
89
  REWARD_USER_DEPLOY: toNano('0.05'),
90
90
  REWARD_USER_CLAIM: toNano('0.1'),
91
- };
91
+ } as const;
92
+
93
+ /**
94
+ * Common validation constants and error messages
95
+ */
96
+ export const VALIDATION = {
97
+ ERRORS: {
98
+ INVALID_AMOUNT: 'Amount must be positive',
99
+ INVALID_SUBACCOUNT_ID: 'Subaccount ID must be between 0 and 255',
100
+ MISSING_JETTON_AMOUNT: 'Either amount, liquidationAmount, or supplyAmount must be provided',
101
+ MISSING_RESPONSE_ADDRESS: 'responseAddress, userAddress, or liquidatorAddress must be provided',
102
+ INVALID_ASSET_CONFIG: 'Invalid asset configuration provided',
103
+ MASTER_CONTRACT_INACTIVE: 'Master contract is not active',
104
+ OUTDATED_SDK_VERSION: 'Outdated SDK pool version',
105
+ } as const,
106
+ } as const;