@evaafi/sdk 0.5.1 → 0.5.4

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.
@@ -1,4 +1,32 @@
1
1
  import { Address, Cell, Dictionary } from '@ton/core';
2
+ export type MasterConstants = {
3
+ FACTOR_SCALE: bigint;
4
+ ASSET_COEFFICIENT_SCALE: bigint;
5
+ ASSET_PRICE_SCALE: bigint;
6
+ ASSET_RESERVE_FACTOR_SCALE: bigint;
7
+ ASSET_LIQUIDATION_RESERVE_FACTOR_SCALE: bigint;
8
+ ASSET_ORIGINATION_FEE_SCALE: bigint;
9
+ };
10
+ export type PoolAssetConfig = (PoolTonAssetConfig | PoolJettonAssetConfig) & {
11
+ name: string;
12
+ };
13
+ export type PoolAssetsConfig = PoolAssetConfig[];
14
+ export type PoolTonAssetConfig = {
15
+ assetId: bigint;
16
+ };
17
+ export type PoolJettonAssetConfig = {
18
+ assetId: bigint;
19
+ jettonMasterAddress: Address;
20
+ jettonWalletCode: Cell;
21
+ };
22
+ export type PoolConfig = {
23
+ masterAddress: Address;
24
+ masterVersion: number;
25
+ masterConstants: MasterConstants;
26
+ nftId: string;
27
+ poolAssetsConfig: PoolAssetsConfig;
28
+ lendingCode: Cell;
29
+ };
2
30
  export type UpgradeConfig = {
3
31
  masterCodeVersion: number;
4
32
  userCodeVersion: number;
@@ -52,12 +80,14 @@ export type AssetApy = {
52
80
  borrowApy: number;
53
81
  };
54
82
  export type ExtendedAssetData = AssetData & AssetInterest & AssetApy;
83
+ export type ExtendedAssetsData = Dictionary<bigint, ExtendedAssetData>;
84
+ export type ExtendedAssetsConfig = Dictionary<bigint, AssetConfig>;
55
85
  export type MasterData = {
56
86
  meta: string;
57
87
  upgradeConfig: UpgradeConfig;
58
88
  masterConfig: MasterConfig;
59
- assetsConfig: Dictionary<bigint, AssetConfig>;
60
- assetsData: Dictionary<bigint, ExtendedAssetData>;
89
+ assetsConfig: ExtendedAssetsConfig;
90
+ assetsData: ExtendedAssetsData;
61
91
  assetsReserves: Dictionary<bigint, bigint>;
62
92
  apy: {
63
93
  supply: Dictionary<bigint, number>;
@@ -1,5 +1,5 @@
1
1
  import { Address, Cell, Dictionary } from '@ton/core';
2
- import { AssetConfig, ExtendedAssetData } from './Master';
2
+ import { ExtendedAssetsConfig, ExtendedAssetsData, MasterConstants } from './Master';
3
3
  export declare enum BalanceType {
4
4
  supply = "supply",
5
5
  borrow = "borrow"
@@ -70,6 +70,7 @@ export type PredictHealthFactorArgs = {
70
70
  tokenSymbol: string;
71
71
  balances: Dictionary<bigint, bigint>;
72
72
  prices: Dictionary<bigint, bigint>;
73
- assetsData: Dictionary<bigint, ExtendedAssetData>;
74
- assetsConfig: Dictionary<bigint, AssetConfig>;
73
+ assetsData: ExtendedAssetsData;
74
+ assetsConfig: ExtendedAssetsConfig;
75
+ masterConstants: MasterConstants;
75
76
  };
@@ -1,2 +1,3 @@
1
1
  import { Address } from '@ton/core';
2
- export declare function getUserJettonWallet(ownerAddress: Address, assetID: bigint, network: 'mainnet' | 'testnet'): Address;
2
+ import { PoolAssetConfig, PoolJettonAssetConfig } from '../types/Master';
3
+ export declare function getUserJettonWallet(ownerAddress: Address, poolAssetConfig: PoolAssetConfig & PoolJettonAssetConfig): Address;
@@ -2,71 +2,55 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getUserJettonWallet = void 0;
4
4
  const core_1 = require("@ton/core");
5
- const constants_1 = require("../constants");
6
- function getUserJettonWallet(ownerAddress, assetID, network) {
7
- const builder = (0, core_1.beginCell)().storeCoins(0).storeAddress(ownerAddress);
8
- let jettonWalletCode;
9
- switch (assetID) {
10
- case constants_1.MAINNET_ASSETS_ID.jUSDT:
11
- if (network === 'mainnet') {
12
- builder.storeAddress(constants_1.JETTON_MASTER_ADDRESSES.jUSDT_MAINNET);
13
- jettonWalletCode = constants_1.JETTON_WALLETS_CODE.jUSDT_MAINNET;
14
- }
15
- else {
16
- builder.storeAddress(constants_1.JETTON_MASTER_ADDRESSES.jUSDT_TESTNET);
17
- jettonWalletCode = constants_1.JETTON_WALLETS_CODE.jUSDT_TESTNET;
18
- }
19
- break;
20
- case constants_1.MAINNET_ASSETS_ID.jUSDC:
21
- if (network === 'mainnet') {
22
- builder.storeAddress(constants_1.JETTON_MASTER_ADDRESSES.jUSDC_MAINNET);
23
- jettonWalletCode = constants_1.JETTON_WALLETS_CODE.jUSDC_MAINNET;
24
- }
25
- else {
26
- builder.storeAddress(constants_1.JETTON_MASTER_ADDRESSES.jUSDC_TESTNET);
27
- jettonWalletCode = constants_1.JETTON_WALLETS_CODE.jUSDC_TESTNET;
28
- }
29
- break;
30
- case constants_1.MAINNET_ASSETS_ID.stTON:
31
- if (network === 'mainnet') {
32
- builder.storeAddress(constants_1.JETTON_MASTER_ADDRESSES.stTON_MAINNET);
33
- jettonWalletCode = constants_1.JETTON_WALLETS_CODE.stTON_MAINNET;
34
- }
35
- else {
36
- builder.storeAddress(constants_1.JETTON_MASTER_ADDRESSES.stTON_TESTNET);
37
- jettonWalletCode = constants_1.JETTON_WALLETS_CODE.stTON_TESTNET;
38
- }
39
- break;
40
- case constants_1.MAINNET_ASSETS_ID.tsTON:
41
- if (network === 'mainnet') {
42
- builder.storeAddress(constants_1.JETTON_MASTER_ADDRESSES.tsTON_MAINNET);
43
- jettonWalletCode = constants_1.JETTON_WALLETS_CODE.tsTON_MAINNET;
44
- }
45
- else {
46
- // builder.storeAddress(JETTON_MASTER_ADDRESSES.tsTON_TESTNET);
47
- // jettonWalletCode = JETTON_WALLETS_CODE.tsTON_TESTNET;
48
- throw new Error('tsTON is not supported on testnet');
49
- }
50
- break;
51
- case constants_1.MAINNET_ASSETS_ID.USDT:
52
- if (network === 'mainnet') {
53
- builder.storeAddress(constants_1.JETTON_MASTER_ADDRESSES.USDT_MAINNET);
54
- jettonWalletCode = constants_1.JETTON_WALLETS_CODE.USDT_MAINNET;
55
- }
56
- else {
57
- // builder.storeAddress(JETTON_MASTER_ADDRESSES.USDT_TESTNET);
58
- // jettonWalletCode = JETTON_WALLETS_CODE.USDT_TESTNET;
59
- throw new Error('USDT is not supported on testnet');
60
- }
61
- break;
62
- default:
63
- throw new Error('Unsupported asset');
5
+ function getUserJettonWallet(ownerAddress, poolAssetConfig) {
6
+ const jettonMasterAddress = poolAssetConfig.jettonMasterAddress;
7
+ const jettonWalletCode = poolAssetConfig.jettonWalletCode;
8
+ if (poolAssetConfig.name === 'USDT') {
9
+ const lib_prep = (0, core_1.beginCell)().storeUint(2, 8).storeBuffer(jettonWalletCode.hash()).endCell();
10
+ const jwallet_code = new core_1.Cell({ exotic: true, bits: lib_prep.bits, refs: lib_prep.refs });
11
+ const jettonData = (0, core_1.beginCell)()
12
+ .storeUint(0, 4)
13
+ .storeCoins(0)
14
+ .storeAddress(ownerAddress)
15
+ .storeAddress(jettonMasterAddress)
16
+ .endCell();
17
+ const stateInit = (0, core_1.beginCell)()
18
+ .store((0, core_1.storeStateInit)({
19
+ code: jwallet_code,
20
+ data: jettonData
21
+ }))
22
+ .endCell();
23
+ return new core_1.Address(0, stateInit.hash());
64
24
  }
65
- const data = builder.storeRef(jettonWalletCode).endCell();
25
+ if (poolAssetConfig.name === 'tsTON') {
26
+ const lib_prep = (0, core_1.beginCell)().storeUint(2, 8).storeBuffer(jettonWalletCode.hash()).endCell();
27
+ const jwallet_code = new core_1.Cell({ exotic: true, bits: lib_prep.bits, refs: lib_prep.refs });
28
+ const jettonData = (0, core_1.beginCell)()
29
+ .storeCoins(0)
30
+ .storeAddress(ownerAddress)
31
+ .storeAddress(jettonMasterAddress)
32
+ .storeRef(jwallet_code)
33
+ .storeCoins(0)
34
+ .storeUint(0, 48)
35
+ .endCell();
36
+ const stateInit = (0, core_1.beginCell)()
37
+ .store((0, core_1.storeStateInit)({
38
+ code: jwallet_code,
39
+ data: jettonData
40
+ }))
41
+ .endCell();
42
+ return new core_1.Address(0, stateInit.hash());
43
+ }
44
+ const jettonData = (0, core_1.beginCell)()
45
+ .storeCoins(0)
46
+ .storeAddress(ownerAddress)
47
+ .storeAddress(jettonMasterAddress)
48
+ .storeRef(jettonWalletCode)
49
+ .endCell();
66
50
  const stateInit = (0, core_1.beginCell)()
67
51
  .store((0, core_1.storeStateInit)({
68
52
  code: jettonWalletCode,
69
- data: data,
53
+ data: jettonData
70
54
  }))
71
55
  .endCell();
72
56
  return new core_1.Address(0, stateInit.hash());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@evaafi/sdk",
3
- "version": "0.5.1",
3
+ "version": "0.5.4",
4
4
  "description": "SDK for EVAA contracts",
5
5
  "main": "dist/index.js",
6
6
  "files": [
@@ -18,11 +18,14 @@
18
18
  "license": "MIT",
19
19
  "homepage": "https://github.com/evaafi/sdk#readme",
20
20
  "devDependencies": {
21
+ "@orbs-network/ton-access": "^2.3.3",
21
22
  "@ton/core": "0.56.0",
22
23
  "@tonconnect/sdk": "^3.0.0",
24
+ "@types/jest": "^29.5.12",
23
25
  "@types/node": "^20.10.4",
24
26
  "crypto-js": "^4.2.0",
25
27
  "prettier": "^3.2.4",
28
+ "ts-jest": "^29.2.4",
26
29
  "ts-node": "^10.9.1",
27
30
  "typescript": "^5.3.3"
28
31
  },
@@ -30,5 +33,9 @@
30
33
  "@ton/core": ">=0.56.0",
31
34
  "@tonconnect/sdk": ">=3.0.0",
32
35
  "crypto-js": ">=4.2.0"
36
+ },
37
+ "dependencies": {
38
+ "@ton/ton": "^14.0.0",
39
+ "dotenv": "^16.4.5"
33
40
  }
34
41
  }
package/src/api/math.ts CHANGED
@@ -1,5 +1,4 @@
1
- import { AssetConfig, AssetData, AssetInterest, ExtendedAssetData } from '../types/Master';
2
- import { MASTER_CONSTANTS } from '../constants';
1
+ import { AssetConfig, AssetData, AssetInterest, ExtendedAssetData, ExtendedAssetsConfig, ExtendedAssetsData, MasterConstants } from '../types/Master';
3
2
  import { Dictionary } from '@ton/core';
4
3
  import { BalanceChangeType, BalanceType, LiquidationData, PredictHealthFactorArgs, UserBalance } from '../types/User';
5
4
  import { sha256Hash } from '../utils/sha256BigInt';
@@ -19,20 +18,20 @@ export function bigIntMin(...args: bigint[]): bigint {
19
18
  return args.reduce((m, e) => (e < m ? e : m));
20
19
  }
21
20
 
22
- export function calculatePresentValue(index: bigint, principalValue: bigint): bigint {
23
- return (principalValue * index) / MASTER_CONSTANTS.FACTOR_SCALE;
21
+ export function calculatePresentValue(index: bigint, principalValue: bigint, masterConstants: MasterConstants): bigint {
22
+ return (principalValue * index) / masterConstants.FACTOR_SCALE;
24
23
  }
25
24
 
26
- export function calculateCurrentRates(assetConfig: AssetConfig, assetData: AssetData) {
25
+ export function calculateCurrentRates(assetConfig: AssetConfig, assetData: AssetData, masterConstants: MasterConstants) {
27
26
  const now = BigInt(Math.floor(Date.now() / 1000));
28
27
  const timeElapsed = now - assetData.lastAccural;
29
- const { supplyInterest, borrowInterest } = calculateAssetInterest(assetConfig, assetData);
28
+ const { supplyInterest, borrowInterest } = calculateAssetInterest(assetConfig, assetData, masterConstants);
30
29
 
31
30
  if (timeElapsed > 0) {
32
31
  const updatedSRate =
33
- assetData.sRate + mulFactor(MASTER_CONSTANTS.FACTOR_SCALE, assetData.sRate, supplyInterest * timeElapsed);
32
+ assetData.sRate + mulFactor(masterConstants.FACTOR_SCALE, assetData.sRate, supplyInterest * timeElapsed);
34
33
  const updatedBRate =
35
- assetData.bRate + mulFactor(MASTER_CONSTANTS.FACTOR_SCALE, assetData.bRate, borrowInterest * timeElapsed);
34
+ assetData.bRate + mulFactor(masterConstants.FACTOR_SCALE, assetData.bRate, borrowInterest * timeElapsed);
36
35
  return {
37
36
  sRate: updatedSRate,
38
37
  bRate: updatedBRate,
@@ -52,9 +51,10 @@ export function calculateCurrentRates(assetConfig: AssetConfig, assetData: Asset
52
51
  }
53
52
 
54
53
  export function calculateAssetData(
55
- assetsConfigDict: Dictionary<bigint, AssetConfig>,
54
+ assetsConfigDict: ExtendedAssetsConfig,
56
55
  assetsDataDict: Dictionary<bigint, AssetData>,
57
56
  assetId: bigint,
57
+ masterConstants: MasterConstants
58
58
  ): ExtendedAssetData {
59
59
  const config = assetsConfigDict.get(assetId);
60
60
  const data = assetsDataDict.get(assetId);
@@ -63,7 +63,7 @@ export function calculateAssetData(
63
63
  throw new Error('Asset Data or Config is not accessible');
64
64
  }
65
65
 
66
- const { sRate, bRate, supplyInterest, borrowInterest, now } = calculateCurrentRates(config, data);
66
+ const { sRate, bRate, supplyInterest, borrowInterest, now } = calculateCurrentRates(config, data, masterConstants);
67
67
  data.sRate = sRate || 0n;
68
68
  data.bRate = bRate || 0n;
69
69
  data.lastAccural = now;
@@ -78,36 +78,36 @@ export function calculateAssetData(
78
78
  };
79
79
  }
80
80
 
81
- export function calculateAssetInterest(assetConfig: AssetConfig, assetData: AssetData): AssetInterest {
82
- const totalSupply = calculatePresentValue(assetData.sRate, assetData.totalSupply);
83
- const totalBorrow = calculatePresentValue(assetData.bRate, assetData.totalBorrow);
81
+ export function calculateAssetInterest(assetConfig: AssetConfig, assetData: AssetData, masterConstants: MasterConstants): AssetInterest {
82
+ const totalSupply = calculatePresentValue(assetData.sRate, assetData.totalSupply, masterConstants);
83
+ const totalBorrow = calculatePresentValue(assetData.bRate, assetData.totalBorrow, masterConstants);
84
84
  let utilization = 0n;
85
85
  let supplyInterest = 0n;
86
86
  let borrowInterest = 0n;
87
87
 
88
88
  if (totalSupply !== 0n) {
89
- utilization = (totalBorrow * MASTER_CONSTANTS.FACTOR_SCALE) / totalSupply;
89
+ utilization = (totalBorrow * masterConstants.FACTOR_SCALE) / totalSupply;
90
90
  }
91
91
 
92
92
  if (utilization <= assetConfig.targetUtilization) {
93
93
  borrowInterest =
94
94
  assetConfig.baseBorrowRate +
95
- mulFactor(MASTER_CONSTANTS.FACTOR_SCALE, assetConfig.borrowRateSlopeLow, utilization);
95
+ mulFactor(masterConstants.FACTOR_SCALE, assetConfig.borrowRateSlopeLow, utilization);
96
96
  } else {
97
97
  borrowInterest =
98
98
  assetConfig.baseBorrowRate +
99
- mulFactor(MASTER_CONSTANTS.FACTOR_SCALE, assetConfig.borrowRateSlopeLow, assetConfig.targetUtilization) +
99
+ mulFactor(masterConstants.FACTOR_SCALE, assetConfig.borrowRateSlopeLow, assetConfig.targetUtilization) +
100
100
  mulFactor(
101
- MASTER_CONSTANTS.FACTOR_SCALE,
101
+ masterConstants.FACTOR_SCALE,
102
102
  assetConfig.borrowRateSlopeHigh,
103
103
  utilization - assetConfig.targetUtilization,
104
104
  );
105
105
  }
106
106
 
107
107
  supplyInterest = mulDiv(
108
- mulDiv(borrowInterest, utilization, MASTER_CONSTANTS.FACTOR_SCALE),
109
- MASTER_CONSTANTS.ASSET_RESERVE_FACTOR_SCALE - assetConfig.reserveFactor,
110
- MASTER_CONSTANTS.ASSET_RESERVE_FACTOR_SCALE,
108
+ mulDiv(borrowInterest, utilization, masterConstants.FACTOR_SCALE),
109
+ masterConstants.ASSET_RESERVE_FACTOR_SCALE - assetConfig.reserveFactor,
110
+ masterConstants.ASSET_RESERVE_FACTOR_SCALE,
111
111
  );
112
112
 
113
113
  return {
@@ -117,10 +117,11 @@ export function calculateAssetInterest(assetConfig: AssetConfig, assetData: Asse
117
117
  }
118
118
 
119
119
  export function getAvailableToBorrow(
120
- assetsConfig: Dictionary<bigint, AssetConfig>,
121
- assetsData: Dictionary<bigint, ExtendedAssetData>,
120
+ assetsConfig: ExtendedAssetsConfig,
121
+ assetsData: ExtendedAssetsData,
122
122
  principals: Dictionary<bigint, bigint>,
123
123
  prices: Dictionary<bigint, bigint>,
124
+ masterConstants: MasterConstants
124
125
  ): bigint {
125
126
  let borrowLimit = 0n;
126
127
  let borrowAmount = 0n;
@@ -132,27 +133,27 @@ export function getAvailableToBorrow(
132
133
  const principal = principals.get(assetID) as bigint;
133
134
 
134
135
  if (principal < 0) {
135
- borrowAmount += (calculatePresentValue(assetData.bRate, -principal) * price) / 10n ** assetConfig.decimals;
136
+ borrowAmount += (calculatePresentValue(assetData.bRate, -principal, masterConstants) * price) / 10n ** assetConfig.decimals;
136
137
  } else if (principal > 0) {
137
138
  borrowLimit +=
138
- (calculatePresentValue(assetData.sRate, principal) * price * assetConfig.collateralFactor) /
139
+ (calculatePresentValue(assetData.sRate, principal, masterConstants) * price * assetConfig.collateralFactor) /
139
140
  10n ** assetConfig.decimals /
140
- MASTER_CONSTANTS.ASSET_COEFFICIENT_SCALE;
141
+ masterConstants.ASSET_COEFFICIENT_SCALE;
141
142
  }
142
143
  }
143
144
 
144
145
  return borrowLimit - borrowAmount;
145
146
  }
146
147
 
147
- export function presentValue(sRate: bigint, bRate: bigint, principalValue: bigint): UserBalance {
148
+ export function presentValue(sRate: bigint, bRate: bigint, principalValue: bigint, masterConstants: MasterConstants): UserBalance {
148
149
  if (principalValue > 0) {
149
150
  return {
150
- amount: calculatePresentValue(sRate, principalValue),
151
+ amount: calculatePresentValue(sRate, principalValue, masterConstants),
151
152
  type: BalanceType.supply,
152
153
  };
153
154
  } else if (principalValue < 0) {
154
155
  return {
155
- amount: calculatePresentValue(bRate, -principalValue),
156
+ amount: calculatePresentValue(bRate, -principalValue, masterConstants),
156
157
  type: BalanceType.borrow,
157
158
  };
158
159
  } else {
@@ -164,10 +165,11 @@ export function presentValue(sRate: bigint, bRate: bigint, principalValue: bigin
164
165
  }
165
166
 
166
167
  export function calculateLiquidationData(
167
- assetsConfig: Dictionary<bigint, AssetConfig>,
168
- assetsData: Dictionary<bigint, ExtendedAssetData>,
168
+ assetsConfig: ExtendedAssetsConfig,
169
+ assetsData: ExtendedAssetsData,
169
170
  principals: Dictionary<bigint, bigint>,
170
171
  prices: Dictionary<bigint, bigint>,
172
+ masterConstants: MasterConstants,
171
173
  ): LiquidationData {
172
174
  let gCollateralValue = 0n;
173
175
  let gCollateralAsset = 0n;
@@ -184,7 +186,7 @@ export function calculateLiquidationData(
184
186
  principal > 0 ? (principal * assetData.sRate) / BigInt(1e12) : (principal * assetData.bRate) / BigInt(1e12);
185
187
  if (balance > 0) {
186
188
  const assetWorth = (balance * prices.get(key)!) / 10n ** assetConfig.decimals;
187
- totalLimit += (assetWorth * assetConfig.liquidationThreshold) / MASTER_CONSTANTS.ASSET_COEFFICIENT_SCALE;
189
+ totalLimit += (assetWorth * assetConfig.liquidationThreshold) / masterConstants.ASSET_COEFFICIENT_SCALE;
188
190
  if (assetWorth > gCollateralValue) {
189
191
  gCollateralValue = assetWorth;
190
192
  gCollateralAsset = key;
@@ -209,7 +211,7 @@ export function calculateLiquidationData(
209
211
  values.push(
210
212
  (bigIntMax(gCollateralValue / 2n, bigIntMin(gCollateralValue, 10_000_000_000n)) *
211
213
  loanDecimal *
212
- MASTER_CONSTANTS.ASSET_COEFFICIENT_SCALE) /
214
+ masterConstants.ASSET_COEFFICIENT_SCALE) /
213
215
  liquidationBonus /
214
216
  gLoanAssetPrice,
215
217
  );
@@ -251,7 +253,7 @@ export function calculateLiquidationData(
251
253
  }
252
254
 
253
255
  export function predictHealthFactor(args: PredictHealthFactorArgs): number {
254
- const liquidationData = calculateLiquidationData(args.assetsConfig, args.assetsData, args.balances, args.prices);
256
+ const liquidationData = calculateLiquidationData(args.assetsConfig, args.assetsData, args.balances, args.prices, args.masterConstants);
255
257
  const tokenHash = sha256Hash(args.tokenSymbol);
256
258
 
257
259
  const assetConfig = args.assetsConfig.get(tokenHash)!;
@@ -269,13 +271,13 @@ export function predictHealthFactor(args: PredictHealthFactorArgs): number {
269
271
 
270
272
  if (currentAmount != null && currentAmount != 0n) {
271
273
  if (changeType == BalanceChangeType.Borrow) {
272
- totalBorrow += currentBalance * (1 + Number(assetConfig.originationFee) / Number(MASTER_CONSTANTS.ASSET_ORIGINATION_FEE_SCALE));
274
+ totalBorrow += currentBalance * (1 + Number(assetConfig.originationFee) / Number(args.masterConstants.ASSET_ORIGINATION_FEE_SCALE));
273
275
  } else if (changeType == BalanceChangeType.Repay) {
274
276
  totalBorrow -= currentBalance;
275
277
  } else if (changeType == BalanceChangeType.Withdraw) {
276
- totalLimit -= currentBalance * Number(assetConfig.liquidationThreshold) / Number(MASTER_CONSTANTS.ASSET_COEFFICIENT_SCALE);
278
+ totalLimit -= currentBalance * Number(assetConfig.liquidationThreshold) / Number(args.masterConstants.ASSET_COEFFICIENT_SCALE);
277
279
  } else if (changeType == BalanceChangeType.Supply) {
278
- totalLimit += currentBalance * Number(assetConfig.liquidationThreshold) / Number(MASTER_CONSTANTS.ASSET_COEFFICIENT_SCALE);
280
+ totalLimit += currentBalance * Number(assetConfig.liquidationThreshold) / Number(args.masterConstants.ASSET_COEFFICIENT_SCALE);
279
281
  }
280
282
  }
281
283
  if (Number(totalLimit) == 0) {
package/src/api/parser.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  import { beginCell, Cell, Dictionary, DictionaryValue, Slice } from '@ton/core';
2
- import { AssetConfig, AssetData, ExtendedAssetData, MasterData } from '../types/Master';
3
- import { MAINNET_ASSETS_ID, MASTER_CONSTANTS, TESTNET_ASSETS_ID } from '../constants';
2
+ import { AssetConfig, AssetData, ExtendedAssetData, ExtendedAssetsConfig, ExtendedAssetsData, MasterConfig, MasterConstants, MasterData, PoolAssetsConfig } from '../types/Master';
4
3
  import {
5
4
  bigIntMax,
6
5
  bigIntMin,
@@ -134,8 +133,7 @@ export function createAssetConfig(): DictionaryValue<AssetConfig> {
134
133
  };
135
134
  }
136
135
 
137
- export function parseMasterData(masterDataBOC: string, testnet: boolean = false): MasterData {
138
- const ASSETS_ID = testnet ? TESTNET_ASSETS_ID : MAINNET_ASSETS_ID;
136
+ export function parseMasterData(masterDataBOC: string, poolAssetsConfig: PoolAssetsConfig, masterConstants: MasterConstants): MasterData {
139
137
  const masterSlice = Cell.fromBase64(masterDataBOC).beginParse();
140
138
  const meta = masterSlice.loadRef().beginParse().loadStringTail();
141
139
  const upgradeConfigParser = masterSlice.loadRef().beginParse();
@@ -163,10 +161,10 @@ export function parseMasterData(masterDataBOC: string, testnet: boolean = false)
163
161
  supply: Dictionary.empty<bigint, number>(),
164
162
  borrow: Dictionary.empty<bigint, number>(),
165
163
  };
166
-
167
- for (const [tokenSymbol, assetID] of Object.entries(ASSETS_ID)) {
168
- const assetData = calculateAssetData(assetsConfigDict, assetsDataDict, assetID);
169
- assetsExtendedData.set(assetID, assetData);
164
+
165
+ for (const [tokenSymbol, asset] of Object.entries(poolAssetsConfig)) {
166
+ const assetData = calculateAssetData(assetsConfigDict, assetsDataDict, asset.assetId, masterConstants);
167
+ assetsExtendedData.set(asset.assetId, assetData);
170
168
  }
171
169
 
172
170
  const masterConfig = {
@@ -179,14 +177,14 @@ export function parseMasterData(masterDataBOC: string, testnet: boolean = false)
179
177
 
180
178
  masterConfigSlice.endParse();
181
179
 
182
- for (const [_, assetID] of Object.entries(ASSETS_ID)) {
183
- const assetData = assetsExtendedData.get(assetID) as ExtendedAssetData;
184
- const totalSupply = calculatePresentValue(assetData.sRate, assetData.totalSupply);
185
- const totalBorrow = calculatePresentValue(assetData.bRate, assetData.totalBorrow);
186
- assetsReserves.set(assetID, assetData.balance - totalSupply + totalBorrow);
180
+ for (const [_, asset] of Object.entries(poolAssetsConfig)) {
181
+ const assetData = assetsExtendedData.get(asset.assetId) as ExtendedAssetData;
182
+ const totalSupply = calculatePresentValue(assetData.sRate, assetData.totalSupply, masterConstants);
183
+ const totalBorrow = calculatePresentValue(assetData.bRate, assetData.totalBorrow, masterConstants);
184
+ assetsReserves.set(asset.assetId, assetData.balance - totalSupply + totalBorrow);
187
185
 
188
- apy.supply.set(assetID, (1 + (Number(assetData.supplyInterest) / 1e12) * 24 * 3600) ** 365 - 1);
189
- apy.borrow.set(assetID, (1 + (Number(assetData.borrowInterest) / 1e12) * 24 * 3600) ** 365 - 1);
186
+ apy.supply.set(asset.assetId, (1 + (Number(assetData.supplyInterest) / 1e12) * 24 * 3600) ** 365 - 1);
187
+ apy.borrow.set(asset.assetId, (1 + (Number(assetData.borrowInterest) / 1e12) * 24 * 3600) ** 365 - 1);
190
188
  }
191
189
 
192
190
  return {
@@ -202,12 +200,13 @@ export function parseMasterData(masterDataBOC: string, testnet: boolean = false)
202
200
 
203
201
  export function parseUserLiteData(
204
202
  userDataBOC: string,
205
- assetsData: Dictionary<bigint, ExtendedAssetData>,
206
- assetsConfig: Dictionary<bigint, AssetConfig>,
203
+ assetsData: ExtendedAssetsData,
204
+ assetsConfig: ExtendedAssetsConfig,
205
+ poolAssetsConfig: PoolAssetsConfig,
206
+ masterConstants: MasterConstants,
207
207
  testnet: boolean = false,
208
208
  applyDust: boolean = false
209
209
  ): UserLiteData {
210
- const ASSETS_ID = testnet ? TESTNET_ASSETS_ID : MAINNET_ASSETS_ID;
211
210
  const userSlice = Cell.fromBase64(userDataBOC).beginParse();
212
211
 
213
212
  const codeVersion = userSlice.loadCoins();
@@ -243,17 +242,17 @@ export function parseUserLiteData(
243
242
 
244
243
  const userBalances = Dictionary.empty<bigint, UserBalance>();
245
244
 
246
- for (const [_, assetID] of Object.entries(ASSETS_ID)) {
247
- const assetData = assetsData.get(assetID) as ExtendedAssetData;
248
- const assetConfig = assetsConfig.get(assetID) as AssetConfig;
249
- let principals = principalsDict.get(assetID) || 0n;
245
+ for (const [_, asset] of Object.entries(poolAssetsConfig)) {
246
+ const assetData = assetsData.get(asset.assetId) as ExtendedAssetData;
247
+ const assetConfig = assetsConfig.get(asset.assetId) as AssetConfig;
248
+ let principals = principalsDict.get(asset.assetId) || 0n;
250
249
 
251
250
  if (applyDust && (principals > -assetConfig.dust && principals < assetConfig.dust)) { // abs(principals) < dust
252
251
  principals = 0n;
253
- principalsDict.set(assetID, 0n);
252
+ principalsDict.set(asset.assetId, 0n);
254
253
  }
255
- const balance = presentValue(assetData.sRate, assetData.bRate, principals);
256
- userBalances.set(assetID, balance);
254
+ const balance = presentValue(assetData.sRate, assetData.bRate, principals, masterConstants);
255
+ userBalances.set(asset.assetId, balance);
257
256
  }
258
257
 
259
258
  return {
@@ -277,60 +276,60 @@ export function parseUserLiteData(
277
276
 
278
277
  export function parseUserData(
279
278
  userLiteData: UserLiteData,
280
- assetsData: Dictionary<bigint, ExtendedAssetData>,
281
- assetsConfig: Dictionary<bigint, AssetConfig>,
279
+ assetsData: ExtendedAssetsData,
280
+ assetsConfig: ExtendedAssetsConfig,
282
281
  prices: Dictionary<bigint, bigint>,
283
- testnet: boolean = false,
282
+ poolAssetConfig: PoolAssetsConfig,
283
+ masterConstants: MasterConstants,
284
284
  applyDust: boolean = false
285
285
  ): UserData {
286
- const ASSETS_ID = testnet ? TESTNET_ASSETS_ID : MAINNET_ASSETS_ID;
287
286
  const withdrawalLimits = Dictionary.empty<bigint, bigint>();
288
287
  const borrowLimits = Dictionary.empty<bigint, bigint>();
289
288
 
290
289
  let supplyBalance = 0n;
291
290
  let borrowBalance = 0n;
292
- for (const [_, assetID] of Object.entries(ASSETS_ID)) {
293
- const assetData = assetsData.get(assetID) as ExtendedAssetData;
294
- const assetConfig = assetsConfig.get(assetID) as AssetConfig;
295
- let principals = userLiteData.principals.get(assetID) || 0n;
291
+ for (const [_, asset] of Object.entries(poolAssetConfig)) {
292
+ const assetData = assetsData.get(asset.assetId) as ExtendedAssetData;
293
+ const assetConfig = assetsConfig.get(asset.assetId) as AssetConfig;
294
+ let principals = userLiteData.principals.get(asset.assetId) || 0n;
296
295
 
297
296
  if (applyDust && (principals > -assetConfig.dust && principals < assetConfig.dust )) { // abs(principals) < dust
298
297
  principals = 0n;
299
- userLiteData.principals.set(assetID, 0n);
298
+ userLiteData.principals.set(asset.assetId, 0n);
300
299
  }
301
300
 
302
- const balance = presentValue(assetData.sRate, assetData.bRate, principals);
303
- userLiteData.balances.set(assetID, balance);
301
+ const balance = presentValue(assetData.sRate, assetData.bRate, principals, masterConstants);
302
+ userLiteData.balances.set(asset.assetId, balance);
304
303
  }
305
304
 
306
- for (const [_, assetID] of Object.entries(ASSETS_ID)) {
307
- const assetConfig = assetsConfig.get(assetID) as AssetConfig;
308
- const balance = userLiteData.balances.get(assetID) as UserBalance;
305
+ for (const [_, asset] of Object.entries(poolAssetConfig)) {
306
+ const assetConfig = assetsConfig.get(asset.assetId) as AssetConfig;
307
+ const balance = userLiteData.balances.get(asset.assetId) as UserBalance;
309
308
 
310
309
  if (balance.type === BalanceType.supply) {
311
- supplyBalance += (balance.amount * prices.get(assetID)!) / 10n ** assetConfig.decimals;
310
+ supplyBalance += (balance.amount * prices.get(asset.assetId)!) / 10n ** assetConfig.decimals;
312
311
  }
313
312
  if (balance.type === BalanceType.borrow) {
314
- borrowBalance += (balance.amount * prices.get(assetID)!) / 10n ** assetConfig.decimals;
313
+ borrowBalance += (balance.amount * prices.get(asset.assetId)!) / 10n ** assetConfig.decimals;
315
314
  }
316
315
  }
317
316
 
318
- const availableToBorrow = getAvailableToBorrow(assetsConfig, assetsData, userLiteData.principals, prices);
319
- for (const [_, assetID] of Object.entries(ASSETS_ID)) {
320
- const assetConfig = assetsConfig.get(assetID) as AssetConfig;
321
- const assetData = assetsData.get(assetID) as ExtendedAssetData;
322
- const balance = userLiteData.balances.get(assetID) as UserBalance;
317
+ const availableToBorrow = getAvailableToBorrow(assetsConfig, assetsData, userLiteData.principals, prices, masterConstants);
318
+ for (const [_, asset] of Object.entries(poolAssetConfig)) {
319
+ const assetConfig = assetsConfig.get(asset.assetId) as AssetConfig;
320
+ const assetData = assetsData.get(asset.assetId) as ExtendedAssetData;
321
+ const balance = userLiteData.balances.get(asset.assetId) as UserBalance;
323
322
 
324
323
  if (balance.type === BalanceType.supply) {
325
324
  withdrawalLimits.set(
326
- assetID,
325
+ asset.assetId,
327
326
  bigIntMax(
328
327
  bigIntMin(
329
328
  assetData.balance,
330
329
  ((supplyBalance -
331
- (borrowBalance * MASTER_CONSTANTS.ASSET_COEFFICIENT_SCALE) / assetConfig.collateralFactor) *
330
+ (borrowBalance * masterConstants.ASSET_COEFFICIENT_SCALE) / assetConfig.collateralFactor) *
332
331
  10n ** assetConfig.decimals) /
333
- prices.get(assetID)! -
332
+ prices.get(asset.assetId)! -
334
333
  5n,
335
334
  balance.amount,
336
335
  ),
@@ -339,8 +338,8 @@ export function parseUserData(
339
338
  );
340
339
  }
341
340
  borrowLimits.set(
342
- assetID,
343
- bigIntMin((availableToBorrow * 10n ** assetConfig.decimals) / prices.get(assetID)!, assetData.balance),
341
+ asset.assetId,
342
+ bigIntMin((availableToBorrow * 10n ** assetConfig.decimals) / prices.get(asset.assetId)!, assetData.balance),
344
343
  );
345
344
  }
346
345
 
@@ -350,7 +349,7 @@ export function parseUserData(
350
349
  ? 0
351
350
  : Number(BigInt(1e9) - (availableToBorrow * BigInt(1e9)) / (borrowBalance + availableToBorrow)) / 1e7;
352
351
 
353
- const liquidationData = calculateLiquidationData(assetsConfig, assetsData, userLiteData.principals, prices);
352
+ const liquidationData = calculateLiquidationData(assetsConfig, assetsData, userLiteData.principals, prices, masterConstants);
354
353
  const healthFactor = 1 - Number(liquidationData.totalDebt) / Number(liquidationData.totalLimit);
355
354
 
356
355
  return {