@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.
- package/dist/api/helpers.js +2 -3
- package/dist/api/math.d.ts +24 -2
- package/dist/api/math.js +189 -62
- package/dist/api/parser.d.ts +3 -3
- package/dist/api/parser.js +37 -25
- package/dist/api/prices.d.ts +1 -1
- package/dist/api/prices.js +3 -3
- package/dist/config.d.ts +2 -0
- package/dist/config.js +5 -0
- package/dist/constants/assets.d.ts +2 -3
- package/dist/constants/assets.js +10 -2
- package/dist/constants/general.d.ts +3 -2
- package/dist/constants/general.js +6 -5
- package/dist/constants/pools.d.ts +0 -1
- package/dist/constants/pools.js +1 -14
- package/dist/constants.d.ts +5 -34
- package/dist/constants.js +90 -37
- package/dist/contracts/MasterContract.d.ts +13 -45
- package/dist/contracts/MasterContract.js +10 -12
- package/dist/contracts/UserContract.js +7 -7
- package/dist/index.d.ts +6 -5
- package/dist/index.js +5 -3
- package/dist/types/Master.d.ts +8 -7
- package/dist/types/User.d.ts +5 -5
- package/dist/utils/merkleProof.d.ts +4 -0
- package/dist/utils/merkleProof.js +107 -0
- package/dist/utils/priceUtils.d.ts +55 -0
- package/dist/utils/priceUtils.js +117 -0
- package/dist/utils/sha256BigInt.js +1 -2
- package/dist/utils/tonConnectSender.js +2 -3
- package/dist/utils/userJettonWallet.d.ts +2 -2
- package/dist/utils/userJettonWallet.js +5 -2
- package/dist/utils/utils.d.ts +2 -0
- package/dist/utils/utils.js +6 -0
- package/package.json +2 -2
- package/src/api/math.ts +229 -50
- package/src/api/parser.ts +52 -37
- package/src/api/prices.ts +2 -1
- package/src/constants/assets.ts +11 -3
- package/src/constants/general.ts +6 -4
- package/src/constants/pools.ts +1 -15
- package/src/contracts/MasterContract.ts +25 -67
- package/src/contracts/UserContract.ts +8 -10
- package/src/index.ts +4 -7
- package/src/types/Master.ts +9 -8
- package/src/types/User.ts +5 -5
- package/src/utils/userJettonWallet.ts +6 -2
- 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
|
-
|
|
140
|
-
10n ** assetConfig.decimals
|
|
141
|
-
|
|
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
|
-
|
|
348
|
+
poolConfig: PoolConfig,
|
|
173
349
|
): LiquidationData {
|
|
174
|
-
let
|
|
175
|
-
let
|
|
176
|
-
let
|
|
177
|
-
let
|
|
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
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
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(
|
|
189
|
-
totalLimit += (assetWorth * assetConfig.liquidationThreshold) / masterConstants.ASSET_COEFFICIENT_SCALE;
|
|
190
|
-
if (assetWorth >
|
|
191
|
-
|
|
192
|
-
|
|
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(
|
|
374
|
+
const assetWorth = (-balance * prices.get(asset.assetId)!) / 10n ** assetConfig.decimals;
|
|
196
375
|
totalDebt += assetWorth;
|
|
197
|
-
if (assetWorth >
|
|
198
|
-
|
|
199
|
-
|
|
376
|
+
if (assetWorth > loanValue) {
|
|
377
|
+
loanValue = assetWorth;
|
|
378
|
+
loanAsset = asset;
|
|
200
379
|
}
|
|
201
380
|
}
|
|
202
381
|
}
|
|
203
382
|
|
|
204
|
-
if (totalLimit < totalDebt) {
|
|
205
|
-
const
|
|
383
|
+
if (collateralAsset.assetId !== UNDEFINED_ASSET.assetId && totalLimit < totalDebt) {
|
|
384
|
+
const loanAssetPrice = prices.get(loanAsset.assetId)!;
|
|
206
385
|
const values: bigint[] = [];
|
|
207
|
-
const
|
|
208
|
-
const
|
|
209
|
-
const liquidationBonus =
|
|
210
|
-
const
|
|
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(
|
|
213
|
-
|
|
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
|
-
|
|
395
|
+
loanAssetPrice,
|
|
217
396
|
);
|
|
218
|
-
values.push((
|
|
397
|
+
values.push((loanValue * loanScale) / loanAssetPrice);
|
|
219
398
|
|
|
220
399
|
const liquidationAmount = (bigIntMin(...values) as bigint) - 5n;
|
|
221
|
-
const
|
|
222
|
-
const collateralDecimal = 10n **
|
|
400
|
+
const collateralAssetPrice: bigint = prices.get(collateralAsset.assetId)!;
|
|
401
|
+
const collateralDecimal = 10n ** collateralAssetConfig.decimals;
|
|
223
402
|
let minCollateralAmount =
|
|
224
|
-
(((liquidationAmount *
|
|
225
|
-
|
|
226
|
-
|
|
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:
|
|
232
|
-
greatestCollateralValue:
|
|
233
|
-
greatestLoanAsset:
|
|
234
|
-
greatestLoanValue:
|
|
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:
|
|
246
|
-
greatestCollateralValue:
|
|
247
|
-
greatestLoanAsset:
|
|
248
|
-
greatestLoanValue:
|
|
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.
|
|
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
|
-
|
|
206
|
-
|
|
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
|
-
|
|
251
|
-
|
|
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
|
-
|
|
283
|
-
|
|
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
|
-
|
|
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
|
-
|
|
297
|
-
|
|
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(
|
|
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(
|
|
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
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
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,
|
|
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
|
|
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
|
|
package/src/constants/assets.ts
CHANGED
|
@@ -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 = {
|
package/src/constants/general.ts
CHANGED
|
@@ -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
|
|
package/src/constants/pools.ts
CHANGED
|
@@ -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,
|
|
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,
|