@evaafi/sdk 0.5.6 → 0.6.0-a

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 (45) hide show
  1. package/dist/api/helpers.js +3 -2
  2. package/dist/api/math.d.ts +1 -10
  3. package/dist/api/math.js +32 -76
  4. package/dist/api/parser.d.ts +2 -1
  5. package/dist/api/parser.js +46 -57
  6. package/dist/api/prices.d.ts +2 -1
  7. package/dist/api/prices.js +29 -19
  8. package/dist/config.d.ts +1 -2
  9. package/dist/config.js +2 -3
  10. package/dist/constants/general.d.ts +7 -5
  11. package/dist/constants/general.js +29 -10
  12. package/dist/constants/pools.js +6 -3
  13. package/dist/constants.d.ts +35 -6
  14. package/dist/constants.js +47 -92
  15. package/dist/contracts/MasterContract.d.ts +9 -3
  16. package/dist/contracts/MasterContract.js +13 -8
  17. package/dist/contracts/UserContract.d.ts +2 -2
  18. package/dist/contracts/UserContract.js +5 -5
  19. package/dist/index.d.ts +3 -3
  20. package/dist/index.js +3 -1
  21. package/dist/types/Common.d.ts +9 -0
  22. package/dist/types/Master.d.ts +23 -4
  23. package/dist/types/User.d.ts +4 -1
  24. package/dist/utils/merkleProof.js +4 -3
  25. package/dist/utils/priceUtils.d.ts +2 -2
  26. package/dist/utils/priceUtils.js +16 -16
  27. package/dist/utils/sha256BigInt.js +2 -1
  28. package/dist/utils/tonConnectSender.js +3 -2
  29. package/dist/utils/userJettonWallet.js +2 -1
  30. package/dist/utils/utils.js +2 -1
  31. package/package.json +2 -2
  32. package/src/api/math.ts +22 -84
  33. package/src/api/parser.ts +37 -52
  34. package/src/api/prices.ts +33 -57
  35. package/src/config.ts +1 -0
  36. package/src/constants/general.ts +32 -9
  37. package/src/constants/pools.ts +7 -4
  38. package/src/contracts/MasterContract.ts +23 -17
  39. package/src/contracts/UserContract.ts +7 -3
  40. package/src/index.ts +4 -0
  41. package/src/types/Common.ts +10 -0
  42. package/src/types/Master.ts +23 -9
  43. package/src/types/User.ts +2 -3
  44. package/src/utils/merkleProof.ts +141 -0
  45. package/src/utils/priceUtils.ts +177 -0
@@ -1,3 +1,4 @@
1
+ /// <reference types="node" />
1
2
  import { Address, Cell, Dictionary } from '@ton/core';
2
3
  export type MasterConstants = {
3
4
  FACTOR_SCALE: bigint;
@@ -20,7 +21,8 @@ export type PoolConfig = {
20
21
  masterAddress: Address;
21
22
  masterVersion: number;
22
23
  masterConstants: MasterConstants;
23
- nftId: string;
24
+ oracles: OracleNFT[];
25
+ minimalOracles: number;
24
26
  poolAssetsConfig: PoolAssetsConfig;
25
27
  lendingCode: Cell;
26
28
  };
@@ -31,7 +33,6 @@ export type UpgradeConfig = {
31
33
  updateTime: number;
32
34
  freezeTime: number;
33
35
  userCode: Cell;
34
- blankCode: Cell;
35
36
  newMasterCode: Cell | null;
36
37
  newUserCode: Cell | null;
37
38
  };
@@ -52,13 +53,20 @@ export type AssetConfig = {
52
53
  maxTotalSupply: bigint;
53
54
  reserveFactor: bigint;
54
55
  liquidationReserveFactor: bigint;
56
+ minPrincipalForRewards: bigint;
57
+ baseTrackingSupplySpeed: bigint;
58
+ baseTrackingBorrowSpeed: bigint;
55
59
  };
56
60
  export type MasterConfig = {
57
61
  ifActive: number;
58
62
  admin: Address;
59
- adminPK: bigint;
63
+ oraclesInfo: OraclesInfo;
60
64
  tokenKeys: Cell | null;
61
- walletToMaster: Cell | null;
65
+ };
66
+ export type OraclesInfo = {
67
+ numOracles: number;
68
+ threshold: number;
69
+ oracles: Cell | null;
62
70
  };
63
71
  export type AssetData = {
64
72
  sRate: bigint;
@@ -67,6 +75,9 @@ export type AssetData = {
67
75
  totalBorrow: bigint;
68
76
  lastAccural: bigint;
69
77
  balance: bigint;
78
+ trackingSupplyIndex: bigint;
79
+ trackingBorrowIndex: bigint;
80
+ awaitedSupply?: bigint;
70
81
  };
71
82
  export type AssetInterest = {
72
83
  supplyInterest: bigint;
@@ -95,3 +106,11 @@ export type AgregatedBalances = {
95
106
  totalBorrow: bigint;
96
107
  totalSupply: bigint;
97
108
  };
109
+ export type OracleNFT = {
110
+ id: number;
111
+ address: string;
112
+ };
113
+ export type Oracle = {
114
+ id: number;
115
+ pubkey: Buffer;
116
+ };
@@ -37,6 +37,9 @@ export type UserLiteData = {
37
37
  trackingBorrowIndex: bigint;
38
38
  dutchAuctionStart: number;
39
39
  backupCell: Cell;
40
+ rewards: Dictionary<bigint, UserRewards>;
41
+ backupCell1: Cell | null;
42
+ backupCell2: Cell | null;
40
43
  };
41
44
  export type UserDataActive = UserLiteData & {
42
45
  withdrawalLimits: Dictionary<bigint, bigint>;
@@ -67,7 +70,7 @@ export declare enum BalanceChangeType {
67
70
  export type PredictHealthFactorArgs = {
68
71
  balanceChangeType: BalanceChangeType;
69
72
  amount: bigint;
70
- tokenSymbol: string;
73
+ asset: PoolAssetConfig;
71
74
  principals: Dictionary<bigint, bigint>;
72
75
  prices: Dictionary<bigint, bigint>;
73
76
  assetsData: ExtendedAssetsData;
@@ -1,8 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.convertToMerkleProof = convertToMerkleProof;
4
- exports.generateMerkleProofDirect = generateMerkleProofDirect;
5
- exports.generateMerkleProof = generateMerkleProof;
3
+ exports.generateMerkleProof = exports.generateMerkleProofDirect = exports.convertToMerkleProof = void 0;
6
4
  const core_1 = require("@ton/core");
7
5
  function readUnaryLength(slice) {
8
6
  let res = 0;
@@ -22,6 +20,7 @@ function convertToMerkleProof(c) {
22
20
  .storeUint(c.depth(0), 16)
23
21
  .storeRef(c));
24
22
  }
23
+ exports.convertToMerkleProof = convertToMerkleProof;
25
24
  function convertToPrunedBranch(c) {
26
25
  return endExoticCell((0, core_1.beginCell)()
27
26
  .storeUint(1, 8)
@@ -102,6 +101,8 @@ function generateMerkleProofDirect(dict, keys, keyObject) {
102
101
  const s = (0, core_1.beginCell)().storeDictDirect(dict).asSlice();
103
102
  return doGenerateMerkleProof('', s, keyObject.bits, keys.map((key) => keyObject.serialize(key).toString(2).padStart(keyObject.bits, '0')));
104
103
  }
104
+ exports.generateMerkleProofDirect = generateMerkleProofDirect;
105
105
  function generateMerkleProof(dict, keys, keyObject) {
106
106
  return convertToMerkleProof(generateMerkleProofDirect(dict, keys, keyObject));
107
107
  }
108
+ exports.generateMerkleProof = generateMerkleProof;
@@ -1,7 +1,7 @@
1
+ /// <reference types="node" />
1
2
  import { Cell, Dictionary, Slice } from "@ton/core";
2
3
  import { PriceData, RawPriceData } from "../types/Common";
3
4
  import { Oracle, PoolAssetsConfig } from "../types/Master";
4
- import 'promise.any';
5
5
  type OutputData = {
6
6
  metadata: {
7
7
  blockId: string;
@@ -36,7 +36,7 @@ export type OraclePricesData = {
36
36
  timestamp: number;
37
37
  prices: Dictionary<bigint, bigint>;
38
38
  };
39
- export declare function loadPrices(oracleNftId: String, endpoints: String[], timeout: number): Promise<OutputData>;
39
+ export declare function loadPrices(oracleNftId: String, endpoints: String[]): Promise<OutputData>;
40
40
  export declare function parsePrices(outputData: OutputData, oracleId: number): Promise<RawPriceData>;
41
41
  export declare function verifyPrices(assets: PoolAssetsConfig): (priceData: RawPriceData) => boolean;
42
42
  export declare function getMedianPrice(pricesData: PriceData[], asset: bigint): bigint;
@@ -1,30 +1,22 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.loadPrices = loadPrices;
4
- exports.parsePrices = parsePrices;
5
- exports.verifyPrices = verifyPrices;
6
- exports.getMedianPrice = getMedianPrice;
7
- exports.packAssetsData = packAssetsData;
8
- exports.packPrices = packPrices;
9
- exports.createOracleDataProof = createOracleDataProof;
10
- exports.packOraclesData = packOraclesData;
11
- exports.sumDicts = sumDicts;
3
+ exports.sumDicts = exports.packOraclesData = exports.createOracleDataProof = exports.packPrices = exports.packAssetsData = exports.getMedianPrice = exports.verifyPrices = exports.parsePrices = exports.loadPrices = void 0;
12
4
  const core_1 = require("@ton/core");
13
5
  const config_1 = require("../config");
14
6
  const merkleProof_1 = require("./merkleProof");
15
- require("promise.any");
16
- async function loadPrices(oracleNftId, endpoints, timeout) {
17
- return await Promise.any(endpoints.map(x => loadOracleData(oracleNftId, x, timeout)));
7
+ async function loadPrices(oracleNftId, endpoints) {
8
+ return await Promise.any(endpoints.map(x => loadOracleData(oracleNftId, x)));
18
9
  }
19
- async function loadOracleData(oracleNftId, endpoint, timeout) {
10
+ exports.loadPrices = loadPrices;
11
+ async function loadOracleData(oracleNftId, endpoint) {
20
12
  let result = await fetch(`https://${endpoint}/api/indexer/v1/outputs/nft/${oracleNftId}`, {
21
13
  headers: { accept: 'application/json' },
22
- signal: AbortSignal.timeout(timeout)
14
+ signal: AbortSignal.timeout(5000)
23
15
  });
24
16
  let outputId = (await result.json());
25
17
  result = await fetch(`https://${endpoint}/api/core/v2/outputs/${outputId.items[0]}`, {
26
18
  headers: { accept: 'application/json' },
27
- signal: AbortSignal.timeout(timeout)
19
+ signal: AbortSignal.timeout(5000)
28
20
  });
29
21
  return await result.json();
30
22
  }
@@ -49,11 +41,12 @@ async function parsePrices(outputData, oracleId) {
49
41
  throw Error();
50
42
  }
51
43
  }
44
+ exports.parsePrices = parsePrices;
52
45
  function verifyPrices(assets) {
53
46
  return function (priceData) {
54
47
  const timestamp = Date.now() / 1000;
55
48
  const pricesTime = priceData.timestamp;
56
- for (const [key, asset] of Object.entries(assets)) {
49
+ for (const asset of assets) {
57
50
  if (!priceData.dict.has(asset.assetId)) {
58
51
  return false;
59
52
  }
@@ -62,6 +55,7 @@ function verifyPrices(assets) {
62
55
  return timestamp - pricesTime < config_1.TTL_ORACLE_DATA_SEC;
63
56
  };
64
57
  }
58
+ exports.verifyPrices = verifyPrices;
65
59
  function getMedianPrice(pricesData, asset) {
66
60
  const sorted = pricesData.map(x => x.dict.get(asset)).sort((a, b) => Number(a) - Number(b));
67
61
  const mid = Math.floor(sorted.length / 2);
@@ -72,6 +66,7 @@ function getMedianPrice(pricesData, asset) {
72
66
  return sorted[mid];
73
67
  }
74
68
  }
69
+ exports.getMedianPrice = getMedianPrice;
75
70
  function packAssetsData(assetsData) {
76
71
  if (assetsData.length == 0) {
77
72
  throw new Error("No assets data to pack");
@@ -82,6 +77,7 @@ function packAssetsData(assetsData) {
82
77
  .storeMaybeRef(acc)
83
78
  .endCell(), null);
84
79
  }
80
+ exports.packAssetsData = packAssetsData;
85
81
  function packPrices(assetsDataCell, oraclesDataCell) {
86
82
  let pricesCell = (0, core_1.beginCell)()
87
83
  .storeRef(assetsDataCell)
@@ -89,6 +85,7 @@ function packPrices(assetsDataCell, oraclesDataCell) {
89
85
  .endCell();
90
86
  return pricesCell;
91
87
  }
88
+ exports.packPrices = packPrices;
92
89
  function createOracleDataProof(oracle, data, signature, assets) {
93
90
  let prunedDict = (0, merkleProof_1.generateMerkleProofDirect)(data.prices, assets, core_1.Dictionary.Keys.BigUint(256));
94
91
  let prunedData = (0, core_1.beginCell)().storeUint(data.timestamp, 32).storeMaybeRef(prunedDict).endCell();
@@ -96,6 +93,7 @@ function createOracleDataProof(oracle, data, signature, assets) {
96
93
  let oracleDataProof = (0, core_1.beginCell)().storeUint(oracle.id, 32).storeRef(merkleProof).storeBuffer(signature).asSlice();
97
94
  return oracleDataProof;
98
95
  }
96
+ exports.createOracleDataProof = createOracleDataProof;
99
97
  function packOraclesData(oraclesData, assets) {
100
98
  if (oraclesData.length == 0) {
101
99
  throw new Error("no oracles data to pack");
@@ -103,6 +101,7 @@ function packOraclesData(oraclesData, assets) {
103
101
  let proofs = oraclesData.sort((d1, d2) => d1.oracle.id - d2.oracle.id).map(({ oracle, data, signature }) => createOracleDataProof(oracle, data, signature, assets));
104
102
  return proofs.reduceRight((acc, val) => (0, core_1.beginCell)().storeSlice(val).storeMaybeRef(acc).endCell(), null);
105
103
  }
104
+ exports.packOraclesData = packOraclesData;
106
105
  // : String = "api.stardust-mainnet.iotaledger.net"
107
106
  function sumDicts(result, addendum) {
108
107
  for (const key of addendum.keys()) {
@@ -115,3 +114,4 @@ function sumDicts(result, addendum) {
115
114
  result.set(key, current + value);
116
115
  }
117
116
  }
117
+ exports.sumDicts = sumDicts;
@@ -3,10 +3,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.sha256Hash = sha256Hash;
6
+ exports.sha256Hash = void 0;
7
7
  const sha256_1 = __importDefault(require("crypto-js/sha256"));
8
8
  function sha256Hash(input) {
9
9
  const hash = (0, sha256_1.default)(input);
10
10
  const hashHex = hash.toString();
11
11
  return BigInt('0x' + hashHex);
12
12
  }
13
+ exports.sha256Hash = sha256Hash;
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getLastSentBoc = getLastSentBoc;
4
- exports.getTonConnectSender = getTonConnectSender;
3
+ exports.getTonConnectSender = exports.getLastSentBoc = void 0;
5
4
  const core_1 = require("@ton/core");
6
5
  /*
7
6
  This is not the best solution to get the BOC of the sent external message, however the Sender
@@ -12,6 +11,7 @@ let lastSentBoc;
12
11
  function getLastSentBoc() {
13
12
  return lastSentBoc;
14
13
  }
14
+ exports.getLastSentBoc = getLastSentBoc;
15
15
  function getTonConnectSender(connector) {
16
16
  return {
17
17
  get address() {
@@ -34,3 +34,4 @@ function getTonConnectSender(connector) {
34
34
  },
35
35
  };
36
36
  }
37
+ exports.getTonConnectSender = getTonConnectSender;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getUserJettonWallet = getUserJettonWallet;
3
+ exports.getUserJettonWallet = void 0;
4
4
  const core_1 = require("@ton/core");
5
5
  const assets_1 = require("../constants/assets");
6
6
  function getUserJettonWallet(ownerAddress, poolAssetConfig) {
@@ -59,3 +59,4 @@ function getUserJettonWallet(ownerAddress, poolAssetConfig) {
59
59
  .endCell();
60
60
  return new core_1.Address(0, stateInit.hash());
61
61
  }
62
+ exports.getUserJettonWallet = getUserJettonWallet;
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isTonAsset = isTonAsset;
3
+ exports.isTonAsset = void 0;
4
4
  function isTonAsset(asset) {
5
5
  return asset.name === 'TON';
6
6
  }
7
+ exports.isTonAsset = isTonAsset;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@evaafi/sdk",
3
- "version": "0.5.6",
4
- "description": "SDK for EVAA contracts",
3
+ "version": "0.6.0a",
4
+ "description": "The EVAA SDK is designed to easily integrate with the EVAA lending protocol on TON blockchain.",
5
5
  "main": "dist/index.js",
6
6
  "files": [
7
7
  "dist",
package/src/api/math.ts CHANGED
@@ -14,8 +14,9 @@ export function mulDiv(x: bigint, y: bigint, z: bigint): bigint {
14
14
  }
15
15
 
16
16
  export function mulDivC(x: bigint, y: bigint, z: bigint): bigint {
17
- const mul = x * y;
18
- return mul / z + (mul % z ? 1n : 0n);
17
+ //const mul = x * y;
18
+ //return mul / z + (mul % z ? 1n : 0n);
19
+ return BigInt(Math.ceil(Number(x * y) / Number(z)));
19
20
  }
20
21
 
21
22
  export function bigIntMax(...args: bigint[]): bigint {
@@ -147,85 +148,19 @@ export function getAgregatedBalances (
147
148
  const price = prices.get(assetId)!;
148
149
  const assetData = assetsData.get(assetId)!;
149
150
  const assetConfig = assetsConfig.get(assetId)!;
150
-
151
+ // console.log('price', price);
151
152
  if (principal < 0) {
152
153
  user_total_borrow += presentValue(assetData.sRate, assetData.bRate, principal, masterConstants).amount * price / 10n ** assetConfig.decimals;
153
154
  } else {
154
155
  user_total_supply += presentValue(assetData.sRate, assetData.bRate, principal, masterConstants).amount * price / 10n ** assetConfig.decimals;
155
156
  }
156
-
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)
157
158
  }
158
159
  }
159
160
  return {totalSupply: user_total_supply, totalBorrow: user_total_borrow};
160
161
  }
161
162
 
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?
163
+ export function calculateMaximumWithdrawAmount(
229
164
  assetsConfig: ExtendedAssetsConfig,
230
165
  assetsData: ExtendedAssetsData,
231
166
  principals: Dictionary<bigint, bigint>,
@@ -258,10 +193,12 @@ export function calculateMaximumWithdrawAmount( // todo v6 ifelse dust not deb
258
193
  }
259
194
  else if (price > 0) {
260
195
  maxAmountToReclaim =
261
- mulDiv(
262
- mulDivC(borrowable, masterConstants.ASSET_COEFFICIENT_SCALE, assetConfig.collateralFactor),
263
- 10n ** assetConfig.decimals, price
264
- );
196
+ bigIntMax(0n,
197
+ mulDiv(
198
+ mulDiv(borrowable, masterConstants.ASSET_COEFFICIENT_SCALE, assetConfig.collateralFactor),
199
+ 10n ** assetConfig.decimals, price)
200
+ - calculatePresentValue(assetData.sRate, assetConfig.dust, masterConstants) / 2n
201
+ );
265
202
  }
266
203
 
267
204
  withdrawAmountMax = bigIntMin(
@@ -299,13 +236,13 @@ export function getAvailableToBorrow(
299
236
  const principal = principals.get(assetID) as bigint;
300
237
 
301
238
  if (principal < 0) {
302
- borrowAmount += (calculatePresentValue(assetData.bRate, -principal, masterConstants) * price) / 10n ** assetConfig.decimals;
239
+ borrowAmount += mulDiv(calculatePresentValue(assetData.bRate, -principal, masterConstants), price, 10n ** assetConfig.decimals);
303
240
  } else if (principal > 0) {
304
241
  borrowLimit +=
305
- mulDivC(
306
- mulDivC(calculatePresentValue(assetData.sRate, principal, masterConstants), price, 10n ** assetConfig.decimals),
307
- assetConfig.collateralFactor,
308
- masterConstants.ASSET_COEFFICIENT_SCALE);
242
+ mulDiv(
243
+ mulDiv(calculatePresentValue(assetData.sRate, principal, masterConstants), price, 10n ** assetConfig.decimals),
244
+ assetConfig.collateralFactor,
245
+ masterConstants.ASSET_COEFFICIENT_SCALE);
309
246
  }
310
247
  }
311
248
 
@@ -405,7 +342,7 @@ export function calculateLiquidationData(
405
342
  loanScale -
406
343
  10n;
407
344
  minCollateralAmount = (minCollateralAmount * 97n) / 100n;
408
- if (minCollateralAmount / collateralDecimal >= 1n) {
345
+ if (minCollateralAmount / collateralDecimal >= 0n) { // todo back to 1
409
346
  return {
410
347
  greatestCollateralAsset: collateralAsset,
411
348
  greatestCollateralValue: collateralValue,
@@ -433,10 +370,11 @@ export function calculateLiquidationData(
433
370
 
434
371
  export function predictHealthFactor(args: PredictHealthFactorArgs): number {
435
372
  const liquidationData = calculateLiquidationData(args.assetsConfig, args.assetsData, args.principals, args.prices, args.poolConfig);
436
- const tokenHash = sha256Hash(args.tokenSymbol);
373
+ const assetId = args.asset.assetId;
437
374
 
438
- const assetConfig = args.assetsConfig.get(tokenHash)!;
439
- const assetPrice = Number(args.prices.get(tokenHash)!);
375
+ const assetConfig = args.assetsConfig.get(assetId)!;
376
+ const assetPrice = Number(args.prices.get(assetId)!);
377
+ const assetData = args.assetsData.get(assetId)!;
440
378
 
441
379
  let totalLimit = Number(liquidationData.totalLimit);
442
380
  let totalBorrow = Number(liquidationData.totalDebt);