@evaafi/sdk 0.6.2 → 0.6.3

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 (59) hide show
  1. package/README.md +2 -1
  2. package/dist/api/math.d.ts +12 -2
  3. package/dist/api/math.js +56 -4
  4. package/dist/api/parser.js +48 -20
  5. package/dist/constants/assets.d.ts +5 -1
  6. package/dist/constants/assets.js +24 -9
  7. package/dist/constants/general.d.ts +16 -0
  8. package/dist/constants/general.js +18 -2
  9. package/dist/constants/pools.d.ts +6 -1
  10. package/dist/constants/pools.js +46 -26
  11. package/dist/index.d.ts +10 -3
  12. package/dist/index.js +25 -2
  13. package/dist/prices/PricesCollector.d.ts +2 -2
  14. package/dist/prices/PricesCollector.js +8 -6
  15. package/dist/rewards/EvaaRewards.d.ts +10 -0
  16. package/dist/rewards/EvaaRewards.js +21 -0
  17. package/dist/rewards/JettonMinter.d.ts +30 -0
  18. package/dist/rewards/JettonMinter.js +83 -0
  19. package/dist/rewards/JettonWallet.d.ts +23 -0
  20. package/dist/rewards/JettonWallet.js +60 -0
  21. package/dist/rewards/RewardMaster.d.ts +26 -0
  22. package/dist/rewards/RewardMaster.js +83 -0
  23. package/dist/rewards/RewardUser.d.ts +23 -0
  24. package/dist/rewards/RewardUser.js +70 -0
  25. package/dist/types/MasterRewards.d.ts +13 -0
  26. package/dist/types/User.d.ts +11 -1
  27. package/dist/types/UserRewards.d.ts +10 -0
  28. package/dist/types/UserRewards.js +2 -0
  29. package/dist/utils/sha256BigInt.d.ts +2 -0
  30. package/dist/utils/sha256BigInt.js +9 -1
  31. package/dist/utils/userJettonWallet.js +7 -0
  32. package/package.json +42 -42
  33. package/src/api/math.ts +78 -3
  34. package/src/api/parser.ts +57 -22
  35. package/src/constants/assets.ts +91 -65
  36. package/src/constants/general.ts +30 -2
  37. package/src/constants/pools.ts +91 -28
  38. package/src/index.ts +23 -2
  39. package/src/prices/PricesCollector.ts +9 -5
  40. package/src/rewards/EvaaRewards.ts +23 -0
  41. package/src/rewards/JettonMinter.ts +113 -0
  42. package/src/rewards/JettonWallet.ts +77 -0
  43. package/src/rewards/RewardMaster.ts +110 -0
  44. package/src/rewards/RewardUser.ts +90 -0
  45. package/src/types/Master.ts +1 -1
  46. package/src/types/MasterRewards.ts +13 -0
  47. package/src/types/User.ts +13 -3
  48. package/src/types/UserRewards.ts +10 -0
  49. package/src/utils/sha256BigInt.ts +8 -0
  50. package/src/utils/userJettonWallet.ts +39 -33
  51. package/CHANGELOG.md +0 -240
  52. package/dist/config.d.ts +0 -1
  53. package/dist/config.js +0 -4
  54. package/dist/constants.d.ts +0 -69
  55. package/dist/constants.js +0 -83
  56. package/dist/types/Common.d.ts +0 -14
  57. package/dist/utils/priceUtils.d.ts +0 -55
  58. package/dist/utils/priceUtils.js +0 -117
  59. /package/dist/types/{Common.js → MasterRewards.js} +0 -0
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RewardUser = void 0;
4
+ const crypto_1 = require("@ton/crypto");
5
+ const ton_1 = require("@ton/ton");
6
+ const general_1 = require("../constants/general");
7
+ const sha256BigInt_1 = require("../utils/sha256BigInt");
8
+ class RewardUser {
9
+ constructor(address, init) {
10
+ this.address = address;
11
+ this.init = init;
12
+ }
13
+ static createFromAddress(address) {
14
+ return new RewardUser(address);
15
+ }
16
+ static rewardUserConfigToCell(config) {
17
+ return (0, ton_1.beginCell)()
18
+ .storeAddress(config.userAddress)
19
+ .storeCoins(0)
20
+ .storeRef((0, ton_1.beginCell)()
21
+ .storeAddress(config.rewardMasterAddress)
22
+ .storeBuffer((0, sha256BigInt_1.bigIntToBuffer)(config.asset.assetId), 256 / 8)
23
+ .storeBuffer(config.publicKey, 256 / 8)
24
+ .endCell())
25
+ .endCell();
26
+ }
27
+ static createFromConfig(config, workchain = 0) {
28
+ const data = this.rewardUserConfigToCell(config);
29
+ const init = { code: config.rewardUserCode, data };
30
+ return new RewardUser((0, ton_1.contractAddress)(workchain, init), init);
31
+ }
32
+ async sendDeploy(provider, via) {
33
+ await provider.internal(via, {
34
+ value: general_1.FEES.REWARD_MASTER_DEPLOY,
35
+ sendMode: ton_1.SendMode.PAY_GAS_SEPARATELY,
36
+ body: (0, ton_1.beginCell)().endCell(),
37
+ });
38
+ }
39
+ claimMessageToCell(claimAmount) {
40
+ return (0, ton_1.beginCell)().storeAddress(this.address).storeCoins(claimAmount).endCell();
41
+ }
42
+ signClaimMessage(claimBody, privateKey) {
43
+ return (0, ton_1.beginCell)()
44
+ .storeUint(general_1.OPCODES.REWARD_CLAIM, 32)
45
+ .storeUint(0, 64)
46
+ .storeBuffer((0, crypto_1.sign)(claimBody.hash(), privateKey))
47
+ .storeRef(claimBody)
48
+ .endCell();
49
+ }
50
+ async sendClaim(provider, via, signedClaimMessage) {
51
+ await provider.internal(via, {
52
+ value: general_1.FEES.REWARD_USER_CLAIM,
53
+ sendMode: ton_1.SendMode.PAY_GAS_SEPARATELY,
54
+ body: signedClaimMessage,
55
+ });
56
+ }
57
+ async getData(provider) {
58
+ const result = await provider.get('load_data', []);
59
+ // TODO: maybe it will be typed
60
+ const data = {
61
+ userAddress: result.stack.readAddress(),
62
+ baseTrackingAccrued: Number((0, ton_1.fromNano)(result.stack.readBigNumber())),
63
+ rewardMasterAddress: result.stack.readAddress(),
64
+ assetId: Buffer.from(result.stack.readBigNumber().toString(16), 'hex'),
65
+ publicKey: Buffer.from(result.stack.readBigNumber().toString(16), 'hex'),
66
+ };
67
+ return data;
68
+ }
69
+ }
70
+ exports.RewardUser = RewardUser;
@@ -0,0 +1,13 @@
1
+ /// <reference types="node" />
2
+ import { Address, Cell } from '@ton/ton';
3
+ import { PoolAssetConfig } from './Master';
4
+ export type EvaaRewardsConfig = {
5
+ workchain?: number;
6
+ adminAddress: Address;
7
+ evaaMasterAddress: Address;
8
+ availableReward: number;
9
+ asset: PoolAssetConfig;
10
+ rewardMasterCode: Cell;
11
+ rewardUserCode: Cell;
12
+ publicKey: Buffer;
13
+ };
@@ -1,5 +1,5 @@
1
1
  import { Address, Cell, Dictionary } from '@ton/core';
2
- import { ExtendedAssetsConfig, ExtendedAssetsData, PoolAssetConfig, PoolConfig } from './Master';
2
+ import { AssetConfig, AssetData, ExtendedAssetsConfig, ExtendedAssetsData, MasterConstants, PoolAssetConfig, PoolConfig } from './Master';
3
3
  export declare enum BalanceType {
4
4
  supply = "supply",
5
5
  borrow = "borrow"
@@ -31,6 +31,7 @@ export type UserLiteData = {
31
31
  masterAddress: Address;
32
32
  ownerAddress: Address;
33
33
  principals: Dictionary<bigint, bigint>;
34
+ realPrincipals: Dictionary<bigint, bigint>;
34
35
  state: number;
35
36
  balances: Dictionary<bigint, UserBalance>;
36
37
  trackingSupplyIndex: bigint;
@@ -40,6 +41,7 @@ export type UserLiteData = {
40
41
  rewards: Dictionary<bigint, UserRewards>;
41
42
  backupCell1: Cell | null;
42
43
  backupCell2: Cell | null;
44
+ fullyParsed: boolean;
43
45
  };
44
46
  export type UserDataActive = UserLiteData & {
45
47
  withdrawalLimits: Dictionary<bigint, bigint>;
@@ -52,6 +54,7 @@ export type UserDataActive = UserLiteData & {
52
54
  limitUsed: bigint;
53
55
  healthFactor: number;
54
56
  liquidationData: LiquidationData;
57
+ havePrincipalWithoutPrice: boolean;
55
58
  };
56
59
  export type UserDataInactive = {
57
60
  type: 'inactive';
@@ -84,3 +87,10 @@ export type PredictHealthFactorArgs = {
84
87
  assetsConfig: ExtendedAssetsConfig;
85
88
  poolConfig: PoolConfig;
86
89
  };
90
+ export type PredictAPYArgs = {
91
+ balanceChangeType: BalanceChangeType;
92
+ amount: bigint;
93
+ assetData: AssetData;
94
+ assetConfig: AssetConfig;
95
+ masterConstants: MasterConstants;
96
+ };
@@ -0,0 +1,10 @@
1
+ /// <reference types="node" />
2
+ import { Address, Cell } from '@ton/ton';
3
+ import { PoolAssetConfig } from './Master';
4
+ export type EvaaUserRewardsConfig = {
5
+ userAddress: Address;
6
+ rewardUserCode: Cell;
7
+ rewardMasterAddress: Address;
8
+ asset: PoolAssetConfig;
9
+ publicKey: Buffer;
10
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1 +1,3 @@
1
+ /// <reference types="node" />
1
2
  export declare function sha256Hash(input: string): bigint;
3
+ export declare function bigIntToBuffer(value: bigint): Buffer;
@@ -3,7 +3,7 @@ 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 = void 0;
6
+ exports.bigIntToBuffer = 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);
@@ -11,3 +11,11 @@ function sha256Hash(input) {
11
11
  return BigInt('0x' + hashHex);
12
12
  }
13
13
  exports.sha256Hash = sha256Hash;
14
+ function bigIntToBuffer(value) {
15
+ let hex = value.toString(16);
16
+ if (hex.length % 2) {
17
+ hex = '0' + hex;
18
+ }
19
+ return Buffer.from(hex, 'hex');
20
+ }
21
+ exports.bigIntToBuffer = bigIntToBuffer;
@@ -31,6 +31,13 @@ function getUserJettonData(ownerAddress, assetName, jettonWalletCode, jettonMast
31
31
  .storeCoins(0)
32
32
  .storeUint(0, 48)
33
33
  .endCell();
34
+ case 'tgBTC':
35
+ return (0, core_1.beginCell)()
36
+ .storeUint(0, 4)
37
+ .storeCoins(0)
38
+ .storeAddress(ownerAddress)
39
+ .storeAddress(jettonMasterAddress)
40
+ .endCell();
34
41
  default:
35
42
  return (0, core_1.beginCell)().storeCoins(0)
36
43
  .storeAddress(ownerAddress)
package/package.json CHANGED
@@ -1,44 +1,44 @@
1
1
  {
2
- "name": "@evaafi/sdk",
3
- "version": "0.6.2",
4
- "description": "The EVAA SDK is designed to easily integrate with the EVAA lending protocol on TON blockchain.",
5
- "main": "dist/index.js",
6
- "files": [
7
- "dist",
8
- "src"
9
- ],
10
- "scripts": {
11
- "build": "tsc --declaration",
12
- "test": "jest"
13
- },
14
- "repository": {
15
- "type": "git",
16
- "url": "git+https://github.com/evaafi/sdk.git"
17
- },
18
- "author": "EVAA Finance",
19
- "license": "MIT",
20
- "homepage": "https://github.com/evaafi/sdk#readme",
21
- "devDependencies": {
22
- "@orbs-network/ton-access": "^2.3.3",
23
- "@ton/core": "0.56.0",
24
- "@ton/crypto": "^3.3.0",
25
- "@tonconnect/sdk": "^3.0.5",
26
- "@types/jest": "^29.5.12",
27
- "@types/node": "^20.10.4",
28
- "crypto-js": "^4.2.0",
29
- "prettier": "^3.2.4",
30
- "ts-jest": "^29.2.4",
31
- "ts-node": "^10.9.1",
32
- "typedoc": "^0.27.4",
33
- "typescript": "^5.3.3"
34
- },
35
- "peerDependencies": {
36
- "@ton/core": ">=0.56.0",
37
- "@tonconnect/sdk": ">=3.0.0",
38
- "crypto-js": ">=4.2.0"
39
- },
40
- "dependencies": {
41
- "@ton/ton": "^14.0.0",
42
- "dotenv": "^16.4.5"
43
- }
2
+ "name": "@evaafi/sdk",
3
+ "version": "0.6.3",
4
+ "description": "The EVAA SDK is designed to easily integrate with the EVAA lending protocol on TON blockchain.",
5
+ "main": "dist/index.js",
6
+ "files": [
7
+ "dist",
8
+ "src"
9
+ ],
10
+ "scripts": {
11
+ "build": "tsc --declaration",
12
+ "test": "jest"
13
+ },
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "git+https://github.com/evaafi/sdk.git"
17
+ },
18
+ "author": "EVAA Finance",
19
+ "license": "MIT",
20
+ "homepage": "https://github.com/evaafi/sdk#readme",
21
+ "devDependencies": {
22
+ "@orbs-network/ton-access": "^2.3.3",
23
+ "@ton/core": "0.56.0",
24
+ "@ton/crypto": "^3.3.0",
25
+ "@tonconnect/sdk": "3.0.5",
26
+ "@types/jest": "^29.5.12",
27
+ "@types/node": "^20.10.4",
28
+ "crypto-js": "4.2.0",
29
+ "prettier": "3.2.4",
30
+ "ts-jest": "^29.2.4",
31
+ "ts-node": "^10.9.1",
32
+ "typedoc": "0.27.4",
33
+ "typescript": "5.3.3"
34
+ },
35
+ "peerDependencies": {
36
+ "@ton/core": ">=0.56.0",
37
+ "@tonconnect/sdk": ">=3.0.0",
38
+ "crypto-js": ">=4.2.0"
39
+ },
40
+ "dependencies": {
41
+ "@ton/ton": "14.0.0",
42
+ "dotenv": "16.4.5"
43
+ }
44
44
  }
package/src/api/math.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import {
2
2
  AgregatedBalances,
3
+ AssetApy,
3
4
  AssetConfig,
4
5
  AssetData,
5
6
  AssetInterest,
@@ -15,6 +16,7 @@ import {
15
16
  BalanceType,
16
17
  HealthParamsArgs,
17
18
  LiquidationData,
19
+ PredictAPYArgs,
18
20
  PredictHealthFactorArgs,
19
21
  UserBalance
20
22
  } from '../types/User';
@@ -53,6 +55,12 @@ export function calculatePresentValue(index: bigint, principalValue: bigint, mas
53
55
  return (principalValue * index) / masterConstants.FACTOR_SCALE;
54
56
  }
55
57
 
58
+ export function getAssetLiquidityMinusReserves(assetData: AssetData, masterConstants: MasterConstants) {
59
+ const total_supply = calculatePresentValue(assetData.sRate, assetData.totalSupply, masterConstants);
60
+ const total_borrow = calculatePresentValue(assetData.bRate, assetData.totalBorrow, masterConstants);
61
+ return bigIntMin(total_supply - total_borrow, assetData.balance);
62
+ }
63
+
56
64
  export function calculateCurrentRates(assetConfig: AssetConfig, assetData: AssetData, masterConstants: MasterConstants) {
57
65
  const now = BigInt(Math.floor(Date.now() / 1000));
58
66
  const timeElapsed = now - assetData.lastAccural;
@@ -109,9 +117,28 @@ export function calculateAssetData(
109
117
  };
110
118
  }
111
119
 
112
- export function calculateAssetInterest(assetConfig: AssetConfig, assetData: AssetData, masterConstants: MasterConstants): AssetInterest {
120
+ export function calculateAssetInterest(
121
+ assetConfig: AssetConfig,
122
+ assetData: AssetData,
123
+ masterConstants: MasterConstants
124
+ ): AssetInterest {
113
125
  const totalSupply = calculatePresentValue(assetData.sRate, assetData.totalSupply, masterConstants);
114
126
  const totalBorrow = calculatePresentValue(assetData.bRate, assetData.totalBorrow, masterConstants);
127
+
128
+ return calculateInterestWithSupplyBorrow(
129
+ totalSupply,
130
+ totalBorrow,
131
+ assetConfig,
132
+ masterConstants
133
+ );
134
+ }
135
+
136
+ export function calculateInterestWithSupplyBorrow(
137
+ totalSupply: bigint,
138
+ totalBorrow: bigint,
139
+ assetConfig: AssetConfig,
140
+ masterConstants: MasterConstants
141
+ ): AssetInterest {
115
142
  let utilization = 0n;
116
143
  let supplyInterest = 0n;
117
144
  let borrowInterest = 0n;
@@ -147,6 +174,7 @@ export function calculateAssetInterest(assetConfig: AssetConfig, assetData: Asse
147
174
  };
148
175
  }
149
176
 
177
+
150
178
  export function checkNotInDebtAtAll(principals: Dictionary<bigint, bigint>): boolean {
151
179
  return principals.values().every(x => x >= 0n);
152
180
  }
@@ -250,10 +278,19 @@ export function getAvailableToBorrow(
250
278
  let borrowAmount = 0n;
251
279
 
252
280
  for (const assetID of principals.keys()) {
281
+ const principal = principals.get(assetID) as bigint;
282
+
283
+ if (principal == 0n) {
284
+ continue;
285
+ }
286
+
287
+ if (!prices.has(assetID)) {
288
+ return 0n;
289
+ }
290
+
253
291
  const assetConfig = assetsConfig.get(assetID) as AssetConfig;
254
292
  const assetData = assetsData.get(assetID) as ExtendedAssetData;
255
293
  const price = prices.get(assetID) as bigint;
256
- const principal = principals.get(assetID) as bigint;
257
294
 
258
295
  if (principal < 0n) {
259
296
  borrowAmount += mulDiv(calculatePresentValue(assetData.bRate, -principal, masterConstants), price, 10n ** assetConfig.decimals);
@@ -464,7 +501,6 @@ export function predictHealthFactor(args: PredictHealthFactorArgs): number {
464
501
 
465
502
  const assetConfig = args.assetsConfig.get(assetId)!;
466
503
  const assetPrice = Number(args.prices.get(assetId)!);
467
- const assetData = args.assetsData.get(assetId)!;
468
504
 
469
505
  let totalLimit = Number(healthParams.totalLimit);
470
506
  let totalBorrow = Number(healthParams.totalDebt);
@@ -493,3 +529,42 @@ const assetData = args.assetsData.get(assetId)!;
493
529
 
494
530
  return Math.min(Math.max(1 - totalBorrow / totalLimit, 0), 1); // let's limit a result to zero below and one above
495
531
  }
532
+
533
+ /**
534
+ * Predicts how APY will change as a result of one of the actions Borrow, Supply, Withdraw or Repay.
535
+ *
536
+ * Used on the front-end.
537
+ *
538
+ * @returns Estimated APYs for Supply and Borrow
539
+ */
540
+ export function predictAPY(args: PredictAPYArgs): AssetInterest & AssetApy {
541
+ const assetConfig = args.assetConfig;
542
+ const assetData = args.assetData;
543
+ const masterConstants = args.masterConstants;
544
+
545
+ let totalSupply = calculatePresentValue(assetData.sRate, assetData.totalSupply, masterConstants);
546
+ let totalBorrow = calculatePresentValue(assetData.bRate, assetData.totalBorrow, masterConstants);
547
+
548
+ const currentAmount = args.amount;
549
+ const changeType = args.balanceChangeType;
550
+
551
+ if (currentAmount != null && currentAmount != 0n) {
552
+ if (changeType == BalanceChangeType.Borrow) {
553
+ totalBorrow += currentAmount;
554
+ } else if (changeType == BalanceChangeType.Repay) {
555
+ totalBorrow -= currentAmount;
556
+ } else if (changeType == BalanceChangeType.Withdraw) {
557
+ totalSupply -= currentAmount;
558
+ } else if (changeType == BalanceChangeType.Supply) {
559
+ totalSupply += currentAmount;
560
+ }
561
+ }
562
+
563
+ const interest = calculateInterestWithSupplyBorrow(totalSupply, totalBorrow, assetConfig, masterConstants);
564
+
565
+ return {
566
+ ...interest,
567
+ supplyApy: (1 + (Number(interest.supplyInterest) / 1e12) * 24 * 3600) ** 365 - 1,
568
+ borrowApy: (1 + (Number(interest.borrowInterest) / 1e12) * 24 * 3600) ** 365 - 1
569
+ }
570
+ }
package/src/api/parser.ts CHANGED
@@ -7,11 +7,13 @@ import {
7
7
  calculateLiquidationData,
8
8
  calculateMaximumWithdrawAmount,
9
9
  calculatePresentValue,
10
+ getAssetLiquidityMinusReserves,
10
11
  getAvailableToBorrow,
11
12
  presentValue,
12
13
  } from './math';
13
14
  import { loadMaybeMyRef, loadMyRef } from './helpers';
14
15
  import { BalanceType, UserBalance, UserData, UserLiteData, UserRewards } from '../types/User';
16
+ import { checkNotInDebtAtAll } from "../api/math";
15
17
 
16
18
  export function createUserRewards(): DictionaryValue<UserRewards> {
17
19
  return {
@@ -32,8 +34,8 @@ export function createAssetData(): DictionaryValue<AssetData> {
32
34
  serialize: (src: any, buidler: any) => {
33
35
  buidler.storeUint(src.sRate, 64);
34
36
  buidler.storeUint(src.bRate, 64);
35
- buidler.storeUint(src.totalSupply, 64);
36
- buidler.storeUint(src.totalBorrow, 64);
37
+ buidler.storeInt(src.totalSupply, 64);
38
+ buidler.storeInt(src.totalBorrow, 64);
37
39
  buidler.storeUint(src.lastAccural, 32);
38
40
  buidler.storeUint(src.balance, 64);
39
41
  buidler.storeUint(src.trackingSupplyIndex, 64);
@@ -41,15 +43,15 @@ export function createAssetData(): DictionaryValue<AssetData> {
41
43
  buidler.storeUint(src.awaitedSupply, 64);
42
44
  },
43
45
  parse: (src: Slice) => {
44
- const sRate = BigInt(src.loadInt(64));
45
- const bRate = BigInt(src.loadInt(64));
46
- const totalSupply = BigInt(src.loadInt(64));
47
- const totalBorrow = BigInt(src.loadInt(64));
48
- const lastAccural = BigInt(src.loadInt(32));
49
- const balance = BigInt(src.loadInt(64));
50
- const trackingSupplyIndex = BigInt(src.loadUint(64));
51
- const trackingBorrowIndex = BigInt(src.loadUint(64));
52
- const awaitedSupply = BigInt(src.loadUint(64));
46
+ const sRate = BigInt(src.loadUintBig(64));
47
+ const bRate = BigInt(src.loadUintBig(64));
48
+ const totalSupply = BigInt(src.loadIntBig(64));
49
+ const totalBorrow = BigInt(src.loadIntBig(64));
50
+ const lastAccural = BigInt(src.loadUintBig(32));
51
+ const balance = BigInt(src.loadUintBig(64));
52
+ const trackingSupplyIndex = BigInt(src.loadUintBig(64));
53
+ const trackingBorrowIndex = BigInt(src.loadUintBig(64));
54
+ const awaitedSupply = BigInt(src.loadUintBig(64));
53
55
 
54
56
  return { sRate, bRate, totalSupply, totalBorrow, lastAccural, balance, trackingSupplyIndex, trackingBorrowIndex, awaitedSupply};
55
57
  },
@@ -208,7 +210,8 @@ export function parseUserLiteData(
208
210
  const codeVersion = userSlice.loadCoins();
209
211
  const masterAddress = userSlice.loadAddress();
210
212
  const userAddress = userSlice.loadAddress();
211
- const principalsDict = userSlice.loadDict(Dictionary.Keys.BigUint(256), Dictionary.Values.BigInt(64));
213
+ const realPrincipals = userSlice.loadDict(Dictionary.Keys.BigUint(256), Dictionary.Values.BigInt(64));
214
+ const principalsDict = Dictionary.empty(Dictionary.Keys.BigUint(256), Dictionary.Values.BigInt(64));
212
215
  const userState = userSlice.loadInt(64);
213
216
 
214
217
  let trackingSupplyIndex = 0n;
@@ -237,7 +240,7 @@ export function parseUserLiteData(
237
240
  const assetData = assetsData.get(asset.assetId) as ExtendedAssetData;
238
241
  const assetConfig = assetsConfig.get(asset.assetId) as AssetConfig;
239
242
 
240
- let principal = principalsDict.get(asset.assetId) || 0n;
243
+ let principal = realPrincipals.get(asset.assetId) || 0n;
241
244
  let balance = presentValue(assetData.sRate, assetData.bRate, principal, masterConstants);
242
245
 
243
246
  if (applyDust && (principal > 0 && (principal < assetConfig.dust))) {
@@ -247,6 +250,8 @@ export function parseUserLiteData(
247
250
  type: BalanceType.supply,
248
251
  };
249
252
  principalsDict.set(asset.assetId, 0n);
253
+ } else {
254
+ principalsDict.set(asset.assetId, principal);
250
255
  }
251
256
  userBalances.set(asset.assetId, balance);
252
257
  }
@@ -257,12 +262,14 @@ export function parseUserLiteData(
257
262
  masterAddress: masterAddress,
258
263
  ownerAddress: userAddress,
259
264
  principals: principalsDict,
265
+ realPrincipals: realPrincipals,
260
266
  state: userState,
261
267
  balances: userBalances,
262
268
  trackingSupplyIndex: trackingSupplyIndex,
263
269
  trackingBorrowIndex: trackingBorrowIndex,
264
270
  dutchAuctionStart: dutchAuctionStart,
265
271
  backupCell: backupCell,
272
+ fullyParsed: false,
266
273
 
267
274
  rewards: rewards,
268
275
  backupCell1: backupCell1,
@@ -278,6 +285,9 @@ export function parseUserData(
278
285
  poolConfig: PoolConfig,
279
286
  applyDust: boolean = false
280
287
  ): UserData {
288
+ userLiteData.fullyParsed = true;
289
+ let havePrincipalWithoutPrice = false;
290
+
281
291
  const poolAssetsConfig = poolConfig.poolAssetsConfig;
282
292
  const masterConstants = poolConfig.masterConstants;
283
293
 
@@ -287,6 +297,16 @@ export function parseUserData(
287
297
  let supplyBalance = 0n;
288
298
  let borrowBalance = 0n;
289
299
 
300
+ for (const [assetId, principal] of userLiteData.realPrincipals) {
301
+ if (!prices.has(assetId)) {
302
+ userLiteData.fullyParsed = false;
303
+
304
+ if (principal != 0n) {
305
+ havePrincipalWithoutPrice = true;
306
+ }
307
+ }
308
+ }
309
+
290
310
  for (const [_, asset] of Object.entries(poolAssetsConfig)) {
291
311
  const assetData = assetsData.get(asset.assetId) as ExtendedAssetData;
292
312
  const assetConfig = assetsConfig.get(asset.assetId) as AssetConfig;
@@ -303,6 +323,10 @@ export function parseUserData(
303
323
  }
304
324
 
305
325
  for (const [_, asset] of Object.entries(poolAssetsConfig)) {
326
+ if (!prices.has(asset.assetId)) {
327
+ continue;
328
+ }
329
+
306
330
  const assetConfig = assetsConfig.get(asset.assetId) as AssetConfig;
307
331
  const balance = userLiteData.balances.get(asset.assetId) as UserBalance;
308
332
 
@@ -314,22 +338,30 @@ export function parseUserData(
314
338
  }
315
339
  }
316
340
 
317
- const availableToBorrow = getAvailableToBorrow(assetsConfig, assetsData, userLiteData.principals, prices, masterConstants);
341
+ const availableToBorrow = getAvailableToBorrow(assetsConfig, assetsData, userLiteData.realPrincipals, prices, masterConstants);
342
+
318
343
  for (const [_, asset] of Object.entries(poolAssetsConfig)) {
344
+ const balance = userLiteData.balances.get(asset.assetId) as UserBalance;
319
345
  const assetConfig = assetsConfig.get(asset.assetId) as AssetConfig;
320
346
  const assetData = assetsData.get(asset.assetId) as ExtendedAssetData;
321
- const balance = userLiteData.balances.get(asset.assetId) as UserBalance;
322
347
 
348
+ const assetLiquidityMinusReserves = getAssetLiquidityMinusReserves(assetData, masterConstants);
349
+
323
350
  if (balance.type === BalanceType.supply) {
324
351
  withdrawalLimits.set(
325
352
  asset.assetId,
326
- bigIntMin(calculateMaximumWithdrawAmount(assetsConfig, assetsData, userLiteData.principals, prices, masterConstants, asset.assetId), assetData.balance)
353
+ bigIntMin(calculateMaximumWithdrawAmount(assetsConfig, assetsData, userLiteData.realPrincipals, prices, masterConstants, asset.assetId), assetData.balance)
327
354
  );
328
355
  }
329
356
 
357
+ if (!prices.has(asset.assetId)) {
358
+ borrowLimits.set(asset.assetId, 0n);
359
+ continue;
360
+ }
361
+
330
362
  borrowLimits.set(
331
363
  asset.assetId,
332
- bigIntMax(0n, bigIntMin((availableToBorrow * 10n ** assetConfig.decimals) / prices.get(asset.assetId)!, assetData.balance, assetData.totalSupply - assetData.totalBorrow)),
364
+ bigIntMax(0n, bigIntMin((availableToBorrow * 10n ** assetConfig.decimals) / prices.get(asset.assetId)!, assetLiquidityMinusReserves)),
333
365
  );
334
366
  }
335
367
 
@@ -339,12 +371,14 @@ export function parseUserData(
339
371
  ? 0
340
372
  : Number(BigInt(1e9) - (availableToBorrow * BigInt(1e9)) / (borrowBalance + availableToBorrow)) / 1e7;
341
373
 
342
- const liquidationData = calculateLiquidationData(assetsConfig, assetsData, userLiteData.principals, prices, poolConfig);
343
374
  let healthFactor = 1;
344
- if (liquidationData.totalLimit != 0n) {
345
- healthFactor = 1 - Number(liquidationData.totalDebt) / Number(liquidationData.totalLimit);
346
- }
347
-
375
+ let liquidationData;
376
+ if (!havePrincipalWithoutPrice) {
377
+ liquidationData = calculateLiquidationData(assetsConfig, assetsData, userLiteData.realPrincipals, prices, poolConfig);
378
+ if (liquidationData.totalLimit != 0n) {
379
+ healthFactor = 1 - Number(liquidationData.totalDebt) / Number(liquidationData.totalLimit);
380
+ }
381
+ }
348
382
  return {
349
383
  ...userLiteData,
350
384
  withdrawalLimits: withdrawalLimits,
@@ -356,5 +390,6 @@ export function parseUserData(
356
390
  limitUsed: limitUsed,
357
391
  liquidationData: liquidationData,
358
392
  healthFactor: healthFactor,
393
+ havePrincipalWithoutPrice: havePrincipalWithoutPrice
359
394
  };
360
395
  }