@evaafi/sdk 0.5.3 → 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.
- package/dist/api/math.d.ts +8 -8
- package/dist/api/math.js +31 -33
- package/dist/api/parser.d.ts +4 -4
- package/dist/api/parser.js +42 -46
- package/dist/api/prices.d.ts +1 -1
- package/dist/api/prices.js +6 -7
- package/dist/constants/assets.d.ts +16 -0
- package/dist/constants/assets.js +77 -0
- package/dist/constants/general.d.ts +38 -0
- package/dist/constants/general.js +41 -0
- package/dist/constants/pools.d.ts +5 -0
- package/dist/constants/pools.js +60 -0
- package/dist/contracts/MasterContract.d.ts +13 -11
- package/dist/contracts/MasterContract.js +39 -35
- package/dist/contracts/UserContract.d.ts +6 -7
- package/dist/contracts/UserContract.js +13 -13
- package/dist/index.d.ts +6 -3
- package/dist/index.js +44 -12
- package/dist/types/Master.d.ts +32 -2
- package/dist/types/User.d.ts +4 -3
- package/dist/utils/userJettonWallet.d.ts +2 -1
- package/dist/utils/userJettonWallet.js +45 -61
- package/package.json +8 -1
- package/src/api/math.ts +39 -38
- package/src/api/parser.ts +51 -52
- package/src/api/prices.ts +4 -5
- package/src/constants/assets.ts +117 -0
- package/src/constants/general.ts +54 -0
- package/src/constants/pools.ts +63 -0
- package/src/contracts/MasterContract.ts +51 -43
- package/src/contracts/UserContract.ts +22 -19
- package/src/index.ts +32 -4
- package/src/types/Master.ts +37 -2
- package/src/types/User.ts +4 -3
- package/src/utils/userJettonWallet.ts +67 -63
- package/src/constants.ts +0 -127
package/dist/types/User.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Address, Cell, Dictionary } from '@ton/core';
|
|
2
|
-
import {
|
|
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:
|
|
74
|
-
assetsConfig:
|
|
73
|
+
assetsData: ExtendedAssetsData;
|
|
74
|
+
assetsConfig: ExtendedAssetsConfig;
|
|
75
|
+
masterConstants: MasterConstants;
|
|
75
76
|
};
|
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
import { Address } from '@ton/core';
|
|
2
|
-
|
|
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
|
-
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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
|
-
|
|
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:
|
|
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.
|
|
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) /
|
|
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(
|
|
32
|
+
assetData.sRate + mulFactor(masterConstants.FACTOR_SCALE, assetData.sRate, supplyInterest * timeElapsed);
|
|
34
33
|
const updatedBRate =
|
|
35
|
-
assetData.bRate + mulFactor(
|
|
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:
|
|
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 *
|
|
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(
|
|
95
|
+
mulFactor(masterConstants.FACTOR_SCALE, assetConfig.borrowRateSlopeLow, utilization);
|
|
96
96
|
} else {
|
|
97
97
|
borrowInterest =
|
|
98
98
|
assetConfig.baseBorrowRate +
|
|
99
|
-
mulFactor(
|
|
99
|
+
mulFactor(masterConstants.FACTOR_SCALE, assetConfig.borrowRateSlopeLow, assetConfig.targetUtilization) +
|
|
100
100
|
mulFactor(
|
|
101
|
-
|
|
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,
|
|
109
|
-
|
|
110
|
-
|
|
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:
|
|
121
|
-
assetsData:
|
|
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
|
-
|
|
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:
|
|
168
|
-
assetsData:
|
|
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) /
|
|
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
|
-
|
|
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)!;
|
|
@@ -267,16 +269,15 @@ export function predictHealthFactor(args: PredictHealthFactorArgs): number {
|
|
|
267
269
|
const currentBalance = assetPrice * Number(currentAmount) / Math.pow(10, decimals);
|
|
268
270
|
const changeType = args.balanceChangeType;
|
|
269
271
|
|
|
270
|
-
if (currentAmount != null &&
|
|
271
|
-
Number.isFinite(currentAmount) && currentAmount != 0n) {
|
|
272
|
+
if (currentAmount != null && currentAmount != 0n) {
|
|
272
273
|
if (changeType == BalanceChangeType.Borrow) {
|
|
273
|
-
totalBorrow += currentBalance * (1 + Number(assetConfig.originationFee) / Number(
|
|
274
|
+
totalBorrow += currentBalance * (1 + Number(assetConfig.originationFee) / Number(args.masterConstants.ASSET_ORIGINATION_FEE_SCALE));
|
|
274
275
|
} else if (changeType == BalanceChangeType.Repay) {
|
|
275
276
|
totalBorrow -= currentBalance;
|
|
276
277
|
} else if (changeType == BalanceChangeType.Withdraw) {
|
|
277
|
-
totalLimit -= currentBalance * Number(assetConfig.liquidationThreshold) / Number(
|
|
278
|
+
totalLimit -= currentBalance * Number(assetConfig.liquidationThreshold) / Number(args.masterConstants.ASSET_COEFFICIENT_SCALE);
|
|
278
279
|
} else if (changeType == BalanceChangeType.Supply) {
|
|
279
|
-
totalLimit += currentBalance * Number(assetConfig.liquidationThreshold) / Number(
|
|
280
|
+
totalLimit += currentBalance * Number(assetConfig.liquidationThreshold) / Number(args.masterConstants.ASSET_COEFFICIENT_SCALE);
|
|
280
281
|
}
|
|
281
282
|
}
|
|
282
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,
|
|
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,
|
|
168
|
-
const assetData = calculateAssetData(assetsConfigDict, assetsDataDict,
|
|
169
|
-
assetsExtendedData.set(
|
|
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 [_,
|
|
183
|
-
const assetData = assetsExtendedData.get(
|
|
184
|
-
const totalSupply = calculatePresentValue(assetData.sRate, assetData.totalSupply);
|
|
185
|
-
const totalBorrow = calculatePresentValue(assetData.bRate, assetData.totalBorrow);
|
|
186
|
-
assetsReserves.set(
|
|
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(
|
|
189
|
-
apy.borrow.set(
|
|
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:
|
|
206
|
-
assetsConfig:
|
|
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 [_,
|
|
247
|
-
const assetData = assetsData.get(
|
|
248
|
-
const assetConfig = assetsConfig.get(
|
|
249
|
-
let principals = principalsDict.get(
|
|
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(
|
|
252
|
+
principalsDict.set(asset.assetId, 0n);
|
|
254
253
|
}
|
|
255
|
-
const balance = presentValue(assetData.sRate, assetData.bRate, principals);
|
|
256
|
-
userBalances.set(
|
|
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:
|
|
281
|
-
assetsConfig:
|
|
279
|
+
assetsData: ExtendedAssetsData,
|
|
280
|
+
assetsConfig: ExtendedAssetsConfig,
|
|
282
281
|
prices: Dictionary<bigint, bigint>,
|
|
283
|
-
|
|
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 [_,
|
|
293
|
-
const assetData = assetsData.get(
|
|
294
|
-
const assetConfig = assetsConfig.get(
|
|
295
|
-
let principals = userLiteData.principals.get(
|
|
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(
|
|
298
|
+
userLiteData.principals.set(asset.assetId, 0n);
|
|
300
299
|
}
|
|
301
300
|
|
|
302
|
-
const balance = presentValue(assetData.sRate, assetData.bRate, principals);
|
|
303
|
-
userLiteData.balances.set(
|
|
301
|
+
const balance = presentValue(assetData.sRate, assetData.bRate, principals, masterConstants);
|
|
302
|
+
userLiteData.balances.set(asset.assetId, balance);
|
|
304
303
|
}
|
|
305
304
|
|
|
306
|
-
for (const [_,
|
|
307
|
-
const assetConfig = assetsConfig.get(
|
|
308
|
-
const balance = userLiteData.balances.get(
|
|
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(
|
|
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(
|
|
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 [_,
|
|
320
|
-
const assetConfig = assetsConfig.get(
|
|
321
|
-
const assetData = assetsData.get(
|
|
322
|
-
const balance = userLiteData.balances.get(
|
|
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
|
-
|
|
325
|
+
asset.assetId,
|
|
327
326
|
bigIntMax(
|
|
328
327
|
bigIntMin(
|
|
329
328
|
assetData.balance,
|
|
330
329
|
((supplyBalance -
|
|
331
|
-
(borrowBalance *
|
|
330
|
+
(borrowBalance * masterConstants.ASSET_COEFFICIENT_SCALE) / assetConfig.collateralFactor) *
|
|
332
331
|
10n ** assetConfig.decimals) /
|
|
333
|
-
prices.get(
|
|
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
|
-
|
|
343
|
-
bigIntMin((availableToBorrow * 10n ** assetConfig.decimals) / prices.get(
|
|
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 {
|
package/src/api/prices.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { beginCell, Cell, Dictionary } from '@ton/core';
|
|
2
|
-
import { NFT_ID } from '../constants';
|
|
3
2
|
import { PriceData } from '../types/Common';
|
|
4
3
|
|
|
5
4
|
type NftData = {
|
|
@@ -39,12 +38,12 @@ type OutputData = {
|
|
|
39
38
|
};
|
|
40
39
|
}
|
|
41
40
|
|
|
42
|
-
export async function
|
|
43
|
-
return await Promise.any(endpoints.map(x => loadPrices(x)));
|
|
41
|
+
export async function getPricesByNft(nftId: string, endpoints: string[] = ["api.stardust-mainnet.iotaledger.net"]) {
|
|
42
|
+
return await Promise.any(endpoints.map(x => loadPrices(nftId, x)));
|
|
44
43
|
}
|
|
45
44
|
|
|
46
|
-
async function loadPrices(endpoint:
|
|
47
|
-
let result = await fetch(`https://${endpoint}/api/indexer/v1/outputs/nft/${
|
|
45
|
+
async function loadPrices(nftId: string, endpoint: string = "api.stardust-mainnet.iotaledger.net"): Promise<PriceData> {
|
|
46
|
+
let result = await fetch(`https://${endpoint}/api/indexer/v1/outputs/nft/${nftId}`, {
|
|
48
47
|
headers: { accept: 'application/json' },
|
|
49
48
|
});
|
|
50
49
|
let outputId = (await result.json()) as NftData;
|