@evaafi/sdk 0.6.0 → 0.6.1-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.
- package/dist/api/liquidation.d.ts +136 -0
- package/dist/api/liquidation.js +252 -0
- package/dist/api/math.d.ts +34 -7
- package/dist/api/math.js +100 -32
- package/dist/api/parser.js +8 -10
- package/dist/constants/assets.d.ts +12 -0
- package/dist/constants/assets.js +25 -13
- package/dist/constants/general.d.ts +4 -1
- package/dist/constants/general.js +10 -9
- package/dist/constants/pools.js +2 -2
- package/dist/contracts/MasterContract.d.ts +6 -1
- package/dist/contracts/MasterContract.js +17 -11
- package/dist/contracts/UserContract.d.ts +3 -2
- package/dist/contracts/UserContract.js +6 -5
- package/dist/index.d.ts +5 -4
- package/dist/index.js +20 -2
- package/dist/types/Master.d.ts +4 -1
- package/dist/types/User.d.ts +7 -0
- package/dist/utils/utils.d.ts +1 -0
- package/dist/utils/utils.js +6 -1
- package/package.json +3 -2
- package/src/api/liquidation.ts +346 -0
- package/src/api/math.ts +169 -76
- package/src/api/parser.ts +8 -10
- package/src/constants/assets.ts +26 -12
- package/src/constants/general.ts +12 -9
- package/src/constants/pools.ts +2 -2
- package/src/contracts/MasterContract.ts +21 -13
- package/src/contracts/UserContract.ts +8 -3
- package/src/index.ts +30 -6
- package/src/types/Master.ts +5 -2
- package/src/types/User.ts +8 -0
- package/src/utils/utils.ts +4 -0
|
@@ -18,10 +18,16 @@ class Evaa {
|
|
|
18
18
|
*/
|
|
19
19
|
constructor(parameters) {
|
|
20
20
|
this.lastSync = 0;
|
|
21
|
-
this.
|
|
22
|
-
this.address = this.
|
|
21
|
+
this._poolConfig = parameters?.poolConfig ?? __1.MAINNET_POOL_CONFIG;
|
|
22
|
+
this.address = this._poolConfig.masterAddress;
|
|
23
23
|
this.debug = parameters?.debug;
|
|
24
24
|
}
|
|
25
|
+
/**
|
|
26
|
+
* Returns pool config
|
|
27
|
+
*/
|
|
28
|
+
get poolConfig() {
|
|
29
|
+
return this._poolConfig;
|
|
30
|
+
}
|
|
25
31
|
/**
|
|
26
32
|
* Create supply message
|
|
27
33
|
* @returns supply message as a cell
|
|
@@ -101,7 +107,7 @@ class Evaa {
|
|
|
101
107
|
// the exact amount of transferred jettons for liquidation is known
|
|
102
108
|
.storeUint(0, 64)
|
|
103
109
|
.storeRef((0, core_1.beginCell)()
|
|
104
|
-
.storeUint(parameters.
|
|
110
|
+
.storeUint(parameters.payloadForwardAmount ?? 0, 64)
|
|
105
111
|
.storeRef(parameters.payload)
|
|
106
112
|
.endCell())
|
|
107
113
|
.storeRef(parameters.priceData)
|
|
@@ -119,7 +125,7 @@ class Evaa {
|
|
|
119
125
|
.storeInt(parameters.includeUserCode ? -1 : 0, 2)
|
|
120
126
|
.storeUint(parameters.liquidationAmount, 64)
|
|
121
127
|
.storeRef((0, core_1.beginCell)()
|
|
122
|
-
.storeUint(parameters.
|
|
128
|
+
.storeUint(parameters.payloadForwardAmount ?? 0, 64)
|
|
123
129
|
.storeRef(parameters.payload)
|
|
124
130
|
.endCell())
|
|
125
131
|
.storeRef(parameters.priceData)
|
|
@@ -152,7 +158,7 @@ class Evaa {
|
|
|
152
158
|
* @returns user contract
|
|
153
159
|
*/
|
|
154
160
|
openUserContract(userAddress) {
|
|
155
|
-
return UserContract_1.EvaaUser.createFromAddress(this.calculateUserSCAddr(userAddress, this.
|
|
161
|
+
return UserContract_1.EvaaUser.createFromAddress(this.calculateUserSCAddr(userAddress, this._poolConfig.lendingCode), this._poolConfig);
|
|
156
162
|
}
|
|
157
163
|
getOpenedUserContract(provider, userAddress) {
|
|
158
164
|
return provider.open(this.openUserContract(userAddress));
|
|
@@ -190,7 +196,7 @@ class Evaa {
|
|
|
190
196
|
}
|
|
191
197
|
async sendLiquidation(provider, via, value, parameters) {
|
|
192
198
|
const message = this.createLiquidationMessage(parameters);
|
|
193
|
-
if (!(0, __1.
|
|
199
|
+
if (!(0, __1.isTonAssetId)(parameters.loanAsset)) {
|
|
194
200
|
if (!via.address) {
|
|
195
201
|
throw Error('Via address is required for jetton liquidation');
|
|
196
202
|
}
|
|
@@ -226,9 +232,9 @@ class Evaa {
|
|
|
226
232
|
async getSync(provider) {
|
|
227
233
|
const state = (await provider.getState()).state;
|
|
228
234
|
if (state.type === 'active') {
|
|
229
|
-
this._data = (0, parser_1.parseMasterData)(state.data.toString('base64'), this.
|
|
230
|
-
if (this._data.upgradeConfig.masterCodeVersion !== this.
|
|
231
|
-
throw Error(`Outdated SDK pool version. It supports only master code version ${this.
|
|
235
|
+
this._data = (0, parser_1.parseMasterData)(state.data.toString('base64'), this._poolConfig.poolAssetsConfig, this._poolConfig.masterConstants);
|
|
236
|
+
if (this._data.upgradeConfig.masterCodeVersion !== this._poolConfig.masterVersion) {
|
|
237
|
+
throw Error(`Outdated SDK pool version. It supports only master code version ${this._poolConfig.masterVersion}, but the current master code version is ${this._data.upgradeConfig.masterCodeVersion}`);
|
|
232
238
|
}
|
|
233
239
|
this.lastSync = Math.floor(Date.now() / 1000);
|
|
234
240
|
}
|
|
@@ -238,10 +244,10 @@ class Evaa {
|
|
|
238
244
|
}
|
|
239
245
|
async getPrices(provider, endpoints) {
|
|
240
246
|
if ((endpoints?.length ?? 0) > 0) {
|
|
241
|
-
return await (0, __1.getPrices)(endpoints, this.
|
|
247
|
+
return await (0, __1.getPrices)(endpoints, this._poolConfig);
|
|
242
248
|
}
|
|
243
249
|
else {
|
|
244
|
-
return await (0, __1.getPrices)(undefined, this.
|
|
250
|
+
return await (0, __1.getPrices)(undefined, this._poolConfig);
|
|
245
251
|
}
|
|
246
252
|
}
|
|
247
253
|
}
|
|
@@ -14,10 +14,11 @@ export declare class EvaaUser implements Contract {
|
|
|
14
14
|
/**
|
|
15
15
|
* Create user contract wrapper from address
|
|
16
16
|
* @param address user contract address
|
|
17
|
+
* @param poolConfig pool config
|
|
17
18
|
*/
|
|
18
19
|
static createFromAddress(address: Address, poolConfig?: PoolConfig): EvaaUser;
|
|
19
20
|
private constructor();
|
|
20
|
-
getSyncLite(provider: ContractProvider, assetsData: ExtendedAssetsData, assetsConfig: ExtendedAssetsConfig): Promise<void>;
|
|
21
|
+
getSyncLite(provider: ContractProvider, assetsData: ExtendedAssetsData, assetsConfig: ExtendedAssetsConfig, applyDust?: boolean): Promise<void>;
|
|
21
22
|
/**
|
|
22
23
|
* Calculate full user data from lite data and prices
|
|
23
24
|
* @param assetsData assets data
|
|
@@ -31,7 +32,7 @@ export declare class EvaaUser implements Contract {
|
|
|
31
32
|
* @param forwardPayload - payload that will be forwarded to the address which requested the data
|
|
32
33
|
*/
|
|
33
34
|
sendOnchainGetter(provider: ContractProvider, via: Sender, value: bigint, queryID: bigint, forwardPayload: Cell): Promise<void>;
|
|
34
|
-
getSync(provider: ContractProvider, assetsData: ExtendedAssetsData, assetsConfig: ExtendedAssetsConfig, prices: Dictionary<bigint, bigint
|
|
35
|
+
getSync(provider: ContractProvider, assetsData: ExtendedAssetsData, assetsConfig: ExtendedAssetsConfig, prices: Dictionary<bigint, bigint>, applyDust?: boolean): Promise<void>;
|
|
35
36
|
/**
|
|
36
37
|
* Get user contract lite data
|
|
37
38
|
* @returns user lite data if available, otherwise undefined
|
|
@@ -13,6 +13,7 @@ class EvaaUser {
|
|
|
13
13
|
/**
|
|
14
14
|
* Create user contract wrapper from address
|
|
15
15
|
* @param address user contract address
|
|
16
|
+
* @param poolConfig pool config
|
|
16
17
|
*/
|
|
17
18
|
static createFromAddress(address, poolConfig = pools_1.MAINNET_POOL_CONFIG) {
|
|
18
19
|
return new EvaaUser(address, poolConfig);
|
|
@@ -22,10 +23,10 @@ class EvaaUser {
|
|
|
22
23
|
this.address = address;
|
|
23
24
|
this.poolConfig = poolConfig;
|
|
24
25
|
}
|
|
25
|
-
async getSyncLite(provider, assetsData, assetsConfig) {
|
|
26
|
+
async getSyncLite(provider, assetsData, assetsConfig, applyDust = false) {
|
|
26
27
|
const state = (await provider.getState()).state;
|
|
27
28
|
if (state.type === 'active') {
|
|
28
|
-
this._liteData = (0, parser_1.parseUserLiteData)(state.data.toString('base64'), assetsData, assetsConfig, this.poolConfig);
|
|
29
|
+
this._liteData = (0, parser_1.parseUserLiteData)(state.data.toString('base64'), assetsData, assetsConfig, this.poolConfig, applyDust);
|
|
29
30
|
this.lastSync = Math.floor(Date.now() / 1000);
|
|
30
31
|
}
|
|
31
32
|
else {
|
|
@@ -62,11 +63,11 @@ class EvaaUser {
|
|
|
62
63
|
.endCell(),
|
|
63
64
|
});
|
|
64
65
|
}
|
|
65
|
-
async getSync(provider, assetsData, assetsConfig, prices) {
|
|
66
|
+
async getSync(provider, assetsData, assetsConfig, prices, applyDust = false) {
|
|
66
67
|
const state = (await provider.getState()).state;
|
|
67
68
|
if (state.type === 'active') {
|
|
68
|
-
this._liteData = (0, parser_1.parseUserLiteData)(state.data.toString('base64'), assetsData, assetsConfig, this.poolConfig);
|
|
69
|
-
this._data = (0, parser_1.parseUserData)(this._liteData, assetsData, assetsConfig, prices, this.poolConfig);
|
|
69
|
+
this._liteData = (0, parser_1.parseUserLiteData)(state.data.toString('base64'), assetsData, assetsConfig, this.poolConfig, applyDust);
|
|
70
|
+
this._data = (0, parser_1.parseUserData)(this._liteData, assetsData, assetsConfig, prices, this.poolConfig, applyDust);
|
|
70
71
|
this.lastSync = Math.floor(Date.now() / 1000);
|
|
71
72
|
}
|
|
72
73
|
else {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
export { mulFactor, mulDiv, bigIntMin, bigIntMax, calculatePresentValue, calculateCurrentRates, calculateAssetData, calculateAssetInterest, getAvailableToBorrow, calculateMaximumWithdrawAmount, presentValue, calculateLiquidationData, predictHealthFactor } from './api/math';
|
|
1
|
+
export { mulFactor, mulDiv, bigIntMin, bigIntMax, calculatePresentValue, calculateCurrentRates, calculateAssetData, calculateAssetInterest, getAvailableToBorrow, calculateMaximumWithdrawAmount, presentValue, calculateLiquidationData, predictHealthFactor, calculateHealthParams, BigMath, } from './api/math';
|
|
2
|
+
export { calculateLiquidationAmounts, calculateMinCollateralByTransferredAmount, isLiquidatable, isBadDebt, addReserve, deductReserve, addLiquidationBonus, deductLiquidationBonus, toAssetAmount, toAssetWorth, PreparedAssetInfo, PreparedAssetInfoResult, prepareAssetInfo, findAssetById, selectGreatestAssets, calculateAssetsValues, AssetsValues, SelectedAssets, } from './api/liquidation';
|
|
2
3
|
export { createAssetData, createAssetConfig, parseMasterData, parseUserData, parseUserLiteData } from './api/parser';
|
|
3
4
|
export { getPrices } from './api/prices';
|
|
4
5
|
export { JettonWallet } from './contracts/JettonWallet';
|
|
5
|
-
export { EvaaParameters, WithdrawParameters, LiquidationBaseData, LiquidationParameters, Evaa
|
|
6
|
+
export { EvaaParameters, WithdrawParameters, LiquidationBaseData, LiquidationParameters, Evaa } from './contracts/MasterContract';
|
|
6
7
|
export { EvaaUser } from './contracts/UserContract';
|
|
7
8
|
export { PriceData } from './types/Common';
|
|
8
9
|
export { UpgradeConfig, AssetConfig, MasterConfig, AssetData, AssetInterest, AssetApy, ExtendedAssetData, MasterData, PoolConfig, ExtendedAssetsData, ExtendedAssetsConfig, PoolAssetConfig, PoolAssetsConfig, MasterConstants } from './types/Master';
|
|
9
10
|
export { BalanceType, UserBalance, UserLiqudationData, LiquidableData, NonLiquidableData, LiquidationData, UserDataInactive, UserDataActive, UserData, BalanceChangeType } from './types/User';
|
|
10
11
|
export { EVAA_MASTER_MAINNET, MAINNET_VERSION, EVAA_MASTER_TESTNET, TESTNET_VERSION, LENDING_CODE, OPCODES, FEES, MASTER_CONSTANTS } from './constants/general';
|
|
11
|
-
export { MAINNET_POOL_CONFIG, TESTNET_POOL_CONFIG, MAINNET_LP_POOL_CONFIG
|
|
12
|
-
export { UNDEFINED_ASSET, TON_MAINNET, USDT_MAINNET, TONUSDT_DEDUST_MAINNET, TON_STORM_MAINNET, USDT_STORM_MAINNET, JUSDT_MAINNET, JUSDC_MAINNET, STTON_MAINNET, TSTON_MAINNET, JUSDT_TESTNET, JUSDC_TESTNET, STTON_TESTNET
|
|
12
|
+
export { MAINNET_POOL_CONFIG, TESTNET_POOL_CONFIG, MAINNET_LP_POOL_CONFIG } from './constants/pools';
|
|
13
|
+
export { ASSET_ID, UNDEFINED_ASSET, TON_MAINNET, USDT_MAINNET, TONUSDT_DEDUST_MAINNET, TON_STORM_MAINNET, USDT_STORM_MAINNET, JUSDT_MAINNET, JUSDC_MAINNET, STTON_MAINNET, TSTON_MAINNET, JUSDT_TESTNET, JUSDC_TESTNET, STTON_TESTNET } from './constants/assets';
|
|
13
14
|
export * from './constants/assets';
|
|
14
15
|
export * from './utils/utils';
|
|
15
16
|
export { getLastSentBoc, getTonConnectSender } from './utils/tonConnectSender';
|
package/dist/index.js
CHANGED
|
@@ -14,8 +14,8 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.
|
|
18
|
-
exports.getUserJettonWallet = void 0;
|
|
17
|
+
exports.TESTNET_POOL_CONFIG = exports.MAINNET_POOL_CONFIG = exports.MASTER_CONSTANTS = exports.FEES = exports.OPCODES = exports.LENDING_CODE = exports.TESTNET_VERSION = exports.EVAA_MASTER_TESTNET = exports.MAINNET_VERSION = exports.EVAA_MASTER_MAINNET = exports.BalanceChangeType = exports.BalanceType = exports.EvaaUser = exports.Evaa = exports.JettonWallet = exports.getPrices = exports.parseUserLiteData = exports.parseUserData = exports.parseMasterData = exports.createAssetConfig = exports.createAssetData = exports.calculateAssetsValues = exports.selectGreatestAssets = exports.findAssetById = exports.prepareAssetInfo = exports.toAssetWorth = exports.toAssetAmount = exports.deductLiquidationBonus = exports.addLiquidationBonus = exports.deductReserve = exports.addReserve = exports.isBadDebt = exports.isLiquidatable = exports.calculateMinCollateralByTransferredAmount = exports.calculateLiquidationAmounts = exports.BigMath = exports.calculateHealthParams = exports.predictHealthFactor = exports.calculateLiquidationData = exports.presentValue = exports.calculateMaximumWithdrawAmount = exports.getAvailableToBorrow = exports.calculateAssetInterest = exports.calculateAssetData = exports.calculateCurrentRates = exports.calculatePresentValue = exports.bigIntMax = exports.bigIntMin = exports.mulDiv = exports.mulFactor = void 0;
|
|
18
|
+
exports.getUserJettonWallet = exports.getTonConnectSender = exports.getLastSentBoc = exports.STTON_TESTNET = exports.JUSDC_TESTNET = exports.JUSDT_TESTNET = exports.TSTON_MAINNET = exports.STTON_MAINNET = exports.JUSDC_MAINNET = exports.JUSDT_MAINNET = exports.USDT_STORM_MAINNET = exports.TON_STORM_MAINNET = exports.TONUSDT_DEDUST_MAINNET = exports.USDT_MAINNET = exports.TON_MAINNET = exports.UNDEFINED_ASSET = exports.ASSET_ID = exports.MAINNET_LP_POOL_CONFIG = void 0;
|
|
19
19
|
// Math
|
|
20
20
|
var math_1 = require("./api/math");
|
|
21
21
|
Object.defineProperty(exports, "mulFactor", { enumerable: true, get: function () { return math_1.mulFactor; } });
|
|
@@ -31,6 +31,23 @@ Object.defineProperty(exports, "calculateMaximumWithdrawAmount", { enumerable: t
|
|
|
31
31
|
Object.defineProperty(exports, "presentValue", { enumerable: true, get: function () { return math_1.presentValue; } });
|
|
32
32
|
Object.defineProperty(exports, "calculateLiquidationData", { enumerable: true, get: function () { return math_1.calculateLiquidationData; } });
|
|
33
33
|
Object.defineProperty(exports, "predictHealthFactor", { enumerable: true, get: function () { return math_1.predictHealthFactor; } });
|
|
34
|
+
Object.defineProperty(exports, "calculateHealthParams", { enumerable: true, get: function () { return math_1.calculateHealthParams; } });
|
|
35
|
+
Object.defineProperty(exports, "BigMath", { enumerable: true, get: function () { return math_1.BigMath; } });
|
|
36
|
+
var liquidation_1 = require("./api/liquidation");
|
|
37
|
+
Object.defineProperty(exports, "calculateLiquidationAmounts", { enumerable: true, get: function () { return liquidation_1.calculateLiquidationAmounts; } });
|
|
38
|
+
Object.defineProperty(exports, "calculateMinCollateralByTransferredAmount", { enumerable: true, get: function () { return liquidation_1.calculateMinCollateralByTransferredAmount; } });
|
|
39
|
+
Object.defineProperty(exports, "isLiquidatable", { enumerable: true, get: function () { return liquidation_1.isLiquidatable; } });
|
|
40
|
+
Object.defineProperty(exports, "isBadDebt", { enumerable: true, get: function () { return liquidation_1.isBadDebt; } });
|
|
41
|
+
Object.defineProperty(exports, "addReserve", { enumerable: true, get: function () { return liquidation_1.addReserve; } });
|
|
42
|
+
Object.defineProperty(exports, "deductReserve", { enumerable: true, get: function () { return liquidation_1.deductReserve; } });
|
|
43
|
+
Object.defineProperty(exports, "addLiquidationBonus", { enumerable: true, get: function () { return liquidation_1.addLiquidationBonus; } });
|
|
44
|
+
Object.defineProperty(exports, "deductLiquidationBonus", { enumerable: true, get: function () { return liquidation_1.deductLiquidationBonus; } });
|
|
45
|
+
Object.defineProperty(exports, "toAssetAmount", { enumerable: true, get: function () { return liquidation_1.toAssetAmount; } });
|
|
46
|
+
Object.defineProperty(exports, "toAssetWorth", { enumerable: true, get: function () { return liquidation_1.toAssetWorth; } });
|
|
47
|
+
Object.defineProperty(exports, "prepareAssetInfo", { enumerable: true, get: function () { return liquidation_1.prepareAssetInfo; } });
|
|
48
|
+
Object.defineProperty(exports, "findAssetById", { enumerable: true, get: function () { return liquidation_1.findAssetById; } });
|
|
49
|
+
Object.defineProperty(exports, "selectGreatestAssets", { enumerable: true, get: function () { return liquidation_1.selectGreatestAssets; } });
|
|
50
|
+
Object.defineProperty(exports, "calculateAssetsValues", { enumerable: true, get: function () { return liquidation_1.calculateAssetsValues; } });
|
|
34
51
|
// Parser
|
|
35
52
|
var parser_1 = require("./api/parser");
|
|
36
53
|
Object.defineProperty(exports, "createAssetData", { enumerable: true, get: function () { return parser_1.createAssetData; } });
|
|
@@ -66,6 +83,7 @@ Object.defineProperty(exports, "MAINNET_POOL_CONFIG", { enumerable: true, get: f
|
|
|
66
83
|
Object.defineProperty(exports, "TESTNET_POOL_CONFIG", { enumerable: true, get: function () { return pools_1.TESTNET_POOL_CONFIG; } });
|
|
67
84
|
Object.defineProperty(exports, "MAINNET_LP_POOL_CONFIG", { enumerable: true, get: function () { return pools_1.MAINNET_LP_POOL_CONFIG; } });
|
|
68
85
|
var assets_1 = require("./constants/assets");
|
|
86
|
+
Object.defineProperty(exports, "ASSET_ID", { enumerable: true, get: function () { return assets_1.ASSET_ID; } });
|
|
69
87
|
Object.defineProperty(exports, "UNDEFINED_ASSET", { enumerable: true, get: function () { return assets_1.UNDEFINED_ASSET; } });
|
|
70
88
|
Object.defineProperty(exports, "TON_MAINNET", { enumerable: true, get: function () { return assets_1.TON_MAINNET; } });
|
|
71
89
|
Object.defineProperty(exports, "USDT_MAINNET", { enumerable: true, get: function () { return assets_1.USDT_MAINNET; } });
|
package/dist/types/Master.d.ts
CHANGED
|
@@ -9,6 +9,9 @@ export type MasterConstants = {
|
|
|
9
9
|
ASSET_LIQUIDATION_THRESHOLD_SCALE: bigint;
|
|
10
10
|
ASSET_LIQUIDATION_BONUS_SCALE: bigint;
|
|
11
11
|
ASSET_ORIGINATION_FEE_SCALE: bigint;
|
|
12
|
+
ASSET_SRATE_SCALE: bigint;
|
|
13
|
+
ASSET_BRATE_SCALE: bigint;
|
|
14
|
+
COLLATERAL_WORTH_THRESHOLD: bigint;
|
|
12
15
|
};
|
|
13
16
|
export type PoolAssetsConfig = PoolAssetConfig[];
|
|
14
17
|
export type PoolAssetConfig = {
|
|
@@ -77,7 +80,7 @@ export type AssetData = {
|
|
|
77
80
|
balance: bigint;
|
|
78
81
|
trackingSupplyIndex: bigint;
|
|
79
82
|
trackingBorrowIndex: bigint;
|
|
80
|
-
awaitedSupply
|
|
83
|
+
awaitedSupply: bigint;
|
|
81
84
|
};
|
|
82
85
|
export type AssetInterest = {
|
|
83
86
|
supplyInterest: bigint;
|
package/dist/types/User.d.ts
CHANGED
|
@@ -61,6 +61,13 @@ export type UserRewards = {
|
|
|
61
61
|
trackingIndex: bigint;
|
|
62
62
|
trackingAccured: bigint;
|
|
63
63
|
};
|
|
64
|
+
export type HealthParamsArgs = {
|
|
65
|
+
assetsData: ExtendedAssetsData;
|
|
66
|
+
assetsConfig: ExtendedAssetsConfig;
|
|
67
|
+
principals: Dictionary<bigint, bigint>;
|
|
68
|
+
prices: Dictionary<bigint, bigint>;
|
|
69
|
+
poolConfig: PoolConfig;
|
|
70
|
+
};
|
|
64
71
|
export declare enum BalanceChangeType {
|
|
65
72
|
Borrow = 0,
|
|
66
73
|
Repay = 1,
|
package/dist/utils/utils.d.ts
CHANGED
package/dist/utils/utils.js
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.isTonAsset = void 0;
|
|
3
|
+
exports.isTonAssetId = exports.isTonAsset = void 0;
|
|
4
|
+
const assets_1 = require("../constants/assets");
|
|
4
5
|
function isTonAsset(asset) {
|
|
5
6
|
return asset.name === 'TON';
|
|
6
7
|
}
|
|
7
8
|
exports.isTonAsset = isTonAsset;
|
|
9
|
+
function isTonAssetId(assetId) {
|
|
10
|
+
return assetId === assets_1.ASSET_ID.TON;
|
|
11
|
+
}
|
|
12
|
+
exports.isTonAssetId = isTonAssetId;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@evaafi/sdk",
|
|
3
|
-
"version": "0.6.
|
|
4
|
-
"description": "SDK
|
|
3
|
+
"version": "0.6.1-a",
|
|
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",
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
"devDependencies": {
|
|
21
21
|
"@orbs-network/ton-access": "^2.3.3",
|
|
22
22
|
"@ton/core": "0.56.0",
|
|
23
|
+
"@ton/crypto": "^3.3.0",
|
|
23
24
|
"@tonconnect/sdk": "^3.0.5",
|
|
24
25
|
"@types/jest": "^29.5.12",
|
|
25
26
|
"@types/node": "^20.10.4",
|
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
import { Dictionary } from '@ton/core';
|
|
2
|
+
import {
|
|
3
|
+
AssetConfig,
|
|
4
|
+
AssetData,
|
|
5
|
+
ExtendedAssetsConfig,
|
|
6
|
+
ExtendedAssetsData,
|
|
7
|
+
MasterConstants,
|
|
8
|
+
PoolAssetConfig,
|
|
9
|
+
PoolConfig
|
|
10
|
+
} from '../types/Master';
|
|
11
|
+
import { BigMath, calculateHealthParams, presentValue } from './math';
|
|
12
|
+
import { BalanceType, UserBalance } from '../types/User';
|
|
13
|
+
|
|
14
|
+
export function findAssetById(assetId: bigint, poolConfig: PoolConfig): PoolAssetConfig | undefined {
|
|
15
|
+
return poolConfig.poolAssetsConfig.find(asset => asset.assetId === assetId);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export type AssetsValues = {
|
|
19
|
+
loanAssets: Dictionary<bigint, bigint>,
|
|
20
|
+
collateralAssets: Dictionary<bigint, bigint>
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export type SelectedAssets = {
|
|
24
|
+
selectedLoanId: bigint,
|
|
25
|
+
selectedCollateralId: bigint,
|
|
26
|
+
selectedLoanValue?: bigint,
|
|
27
|
+
selectedCollateralValue?: bigint,
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function calculateAssetsValues(
|
|
31
|
+
principalsDict: Dictionary<bigint, bigint>,
|
|
32
|
+
pricesDict: Dictionary<bigint, bigint>,
|
|
33
|
+
assetsConfigDict: ExtendedAssetsConfig,
|
|
34
|
+
assetsDataDict: ExtendedAssetsData,
|
|
35
|
+
poolConfig: PoolConfig
|
|
36
|
+
): AssetsValues {
|
|
37
|
+
const loanAssets = Dictionary.empty<bigint, bigint>();
|
|
38
|
+
const collateralAssets = Dictionary.empty<bigint, bigint>();
|
|
39
|
+
|
|
40
|
+
for (const asset of poolConfig.poolAssetsConfig) {
|
|
41
|
+
const assetId = asset.assetId;
|
|
42
|
+
if (!principalsDict.has(assetId)) {
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
const assetPrincipal: bigint = principalsDict.get(assetId)!;
|
|
46
|
+
if (!pricesDict.has(assetId)) {
|
|
47
|
+
console.warn(`No price for asset ${asset.name}`);
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
const assetPrice = pricesDict.get(assetId)!;
|
|
51
|
+
if (!assetsDataDict.has(assetId)) {
|
|
52
|
+
console.warn(`Dynamics for assetId ${assetId} is not defined, skipping`);
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
const assetData = assetsDataDict.get(assetId)!;
|
|
56
|
+
|
|
57
|
+
if (!assetsConfigDict.has(assetId)) {
|
|
58
|
+
console.warn(`Config for assetId ${assetId} is not defined, skipping`);
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
const assetConfig = assetsConfigDict.get(assetId)!;
|
|
62
|
+
const assetScale = 10n ** assetConfig.decimals;
|
|
63
|
+
const { sRate, bRate } = assetData;
|
|
64
|
+
const assetPresent = presentValue(sRate, bRate, assetPrincipal, poolConfig.masterConstants);
|
|
65
|
+
const assetValue = assetPresent.amount * assetPrice / assetScale;
|
|
66
|
+
if (assetPresent.type === BalanceType.borrow) {
|
|
67
|
+
loanAssets.set(assetId, assetValue);
|
|
68
|
+
} else {
|
|
69
|
+
collateralAssets.set(assetId, assetValue);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return { loanAssets, collateralAssets };
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export function selectGreatestAssets(principalsDict: Dictionary<bigint, bigint>,
|
|
77
|
+
pricesDict: Dictionary<bigint, bigint>,
|
|
78
|
+
assetsConfigDict: ExtendedAssetsConfig,
|
|
79
|
+
assetsDataDict: ExtendedAssetsData,
|
|
80
|
+
poolConfig: PoolConfig): SelectedAssets {
|
|
81
|
+
let maxLoanId = 0n;
|
|
82
|
+
let maxLoanValue = 0n;
|
|
83
|
+
let maxCollateralId = 0n;
|
|
84
|
+
let maxCollateralValue = 0n;
|
|
85
|
+
|
|
86
|
+
const assetsValues = calculateAssetsValues(principalsDict, pricesDict, assetsConfigDict, assetsDataDict, poolConfig);
|
|
87
|
+
|
|
88
|
+
for (const [loanId, loanValue] of assetsValues.loanAssets) {
|
|
89
|
+
if (loanValue > maxLoanValue) {
|
|
90
|
+
maxLoanId = loanId;
|
|
91
|
+
maxLoanValue = loanValue;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
for (const [collateralId, collateralValue] of assetsValues.collateralAssets) {
|
|
96
|
+
if (collateralValue > maxCollateralValue) {
|
|
97
|
+
maxCollateralValue = collateralValue;
|
|
98
|
+
maxCollateralId = collateralId;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return {
|
|
103
|
+
selectedLoanId: maxLoanId,
|
|
104
|
+
selectedLoanValue: maxLoanValue,
|
|
105
|
+
selectedCollateralId: maxCollateralId,
|
|
106
|
+
selectedCollateralValue: maxCollateralValue
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* This function shows how to calculate min collateral amount value.
|
|
112
|
+
* when liquidator has not enough of loan asset to cover the full loan.
|
|
113
|
+
* @param transferredAmount amount of loan asset liquidator want to transfer.
|
|
114
|
+
* @param maxLiquidationAmount max liquidation amount value calculated.
|
|
115
|
+
* @param maxCollateralReward max collateral reward amount calculated.
|
|
116
|
+
* @returns minCollateralAmount value for safe liquidation.
|
|
117
|
+
*/
|
|
118
|
+
export function calculateMinCollateralByTransferredAmount(
|
|
119
|
+
transferredAmount: bigint, maxLiquidationAmount: bigint, maxCollateralReward: bigint
|
|
120
|
+
) {
|
|
121
|
+
if (maxLiquidationAmount === 0n) {
|
|
122
|
+
return 0n;
|
|
123
|
+
}
|
|
124
|
+
return maxCollateralReward * transferredAmount / maxLiquidationAmount;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Calculates liquidation amount and corresponding collateral amount
|
|
129
|
+
* @param supplyAmount user total supply worth amount
|
|
130
|
+
* @param borrowAmount user total borrow worth amount
|
|
131
|
+
* @param masterConstants evaa master contract constants
|
|
132
|
+
* @param loanAsset loan asset pool config
|
|
133
|
+
* @param collateralAsset collateral asset pool config
|
|
134
|
+
* @param principalsDict user principals
|
|
135
|
+
* @param assetsDataDict assets data collection
|
|
136
|
+
* @param assetsConfigDict assets config collection
|
|
137
|
+
* @param pricesDict assets prices
|
|
138
|
+
* @returns maxLiquidationAmount max loan asset amount to transfer
|
|
139
|
+
* @returns maxCollateralRewardAmount max collateral reward amount, which can be obtained
|
|
140
|
+
*/
|
|
141
|
+
export function calculateLiquidationAmounts(
|
|
142
|
+
loanAsset: PoolAssetConfig,
|
|
143
|
+
collateralAsset: PoolAssetConfig,
|
|
144
|
+
supplyAmount: bigint,
|
|
145
|
+
borrowAmount: bigint, // from calculate health params
|
|
146
|
+
principalsDict: Dictionary<bigint, bigint>,
|
|
147
|
+
pricesDict: Dictionary<bigint, bigint>,
|
|
148
|
+
assetsDataDict: ExtendedAssetsData,
|
|
149
|
+
assetsConfigDict: ExtendedAssetsConfig,
|
|
150
|
+
masterConstants: MasterConstants
|
|
151
|
+
): {
|
|
152
|
+
maxLiquidationAmount: bigint, maxCollateralRewardAmount: bigint
|
|
153
|
+
} {
|
|
154
|
+
const loanInfo = prepareAssetInfo(loanAsset.assetId,
|
|
155
|
+
assetsConfigDict, assetsDataDict, pricesDict, principalsDict, masterConstants
|
|
156
|
+
);
|
|
157
|
+
const collateralInfo = prepareAssetInfo(collateralAsset.assetId,
|
|
158
|
+
assetsConfigDict, assetsDataDict, pricesDict, principalsDict, masterConstants
|
|
159
|
+
);
|
|
160
|
+
|
|
161
|
+
if (!loanInfo.ok || !collateralInfo.ok ||
|
|
162
|
+
loanInfo.present.type !== BalanceType.borrow ||
|
|
163
|
+
collateralInfo.present.type !== BalanceType.supply) {
|
|
164
|
+
return { maxLiquidationAmount: 0n, maxCollateralRewardAmount: 0n };
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const liquidationBonusScale = masterConstants.ASSET_LIQUIDATION_BONUS_SCALE;
|
|
168
|
+
const collateralThreshold = masterConstants.COLLATERAL_WORTH_THRESHOLD; // basically 100$ worth (100*10^9)
|
|
169
|
+
const reserveFactorScale = masterConstants.ASSET_RESERVE_FACTOR_SCALE;
|
|
170
|
+
const reserveFactor = loanInfo.liquidationReserveFactor;
|
|
171
|
+
const liquidationBonus = collateralInfo.liquidationBonus;
|
|
172
|
+
|
|
173
|
+
let allowedCollateralValue = toAssetWorth(collateralInfo.balance, collateralInfo.scale, collateralInfo.price);
|
|
174
|
+
|
|
175
|
+
const _isBadDebt = isBadDebt(supplyAmount, borrowAmount, liquidationBonus, masterConstants);
|
|
176
|
+
if (!_isBadDebt) {
|
|
177
|
+
allowedCollateralValue = BigMath.min(allowedCollateralValue, BigMath.max(allowedCollateralValue / 2n, collateralThreshold));
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const loanValue = toAssetWorth(loanInfo.balance, loanInfo.scale, loanInfo.price);
|
|
181
|
+
const baseLiquidationValue = BigMath.min(
|
|
182
|
+
// deductReserve(loanValue, reserveFactor, reserveFactorScale),
|
|
183
|
+
loanValue,
|
|
184
|
+
deductLiquidationBonus(allowedCollateralValue, liquidationBonus, liquidationBonusScale)
|
|
185
|
+
);
|
|
186
|
+
|
|
187
|
+
// calculate collateral amount
|
|
188
|
+
let collateralAmount = addLiquidationBonus(baseLiquidationValue, liquidationBonus, liquidationBonusScale);
|
|
189
|
+
collateralAmount = toAssetAmount(collateralAmount, collateralInfo.scale, collateralInfo.price);
|
|
190
|
+
|
|
191
|
+
// calculate loan amount
|
|
192
|
+
let liquidationAmount = addReserve(baseLiquidationValue, reserveFactor, reserveFactorScale);
|
|
193
|
+
liquidationAmount = toAssetAmount(liquidationAmount, loanInfo.scale, loanInfo.price);
|
|
194
|
+
|
|
195
|
+
return {
|
|
196
|
+
maxLiquidationAmount: liquidationAmount,
|
|
197
|
+
maxCollateralRewardAmount: collateralAmount
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Check if the user is subject to liquidation
|
|
203
|
+
* @param args
|
|
204
|
+
*/
|
|
205
|
+
export function isLiquidatable(args: {
|
|
206
|
+
assetsData: ExtendedAssetsData, assetsConfig: ExtendedAssetsConfig,
|
|
207
|
+
principals: Dictionary<bigint, bigint>, prices: Dictionary<bigint, bigint>,
|
|
208
|
+
poolConfig: PoolConfig
|
|
209
|
+
}): boolean {
|
|
210
|
+
const { isLiquidatable: res } = calculateHealthParams(args);
|
|
211
|
+
return res;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Determines if the provided pair of assets forms a bad debt.
|
|
216
|
+
* @param totalSupply total supply worth amount
|
|
217
|
+
* @param totalBorrow total borrow worth amount
|
|
218
|
+
* @param liquidationBonus collateral liquidation bonus value
|
|
219
|
+
* @param masterConstants pool constants
|
|
220
|
+
*/
|
|
221
|
+
export function isBadDebt(totalSupply: bigint, totalBorrow: bigint,
|
|
222
|
+
liquidationBonus: bigint, masterConstants: MasterConstants
|
|
223
|
+
) {
|
|
224
|
+
return totalSupply * masterConstants.ASSET_LIQUIDATION_BONUS_SCALE < totalBorrow * liquidationBonus;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Adds reserve to liquidation amount
|
|
229
|
+
* @param amount raw liquidation amount
|
|
230
|
+
* @param reserveFactor asset reserve factor
|
|
231
|
+
* @param factorScale asset reserve factor scale
|
|
232
|
+
* @returns liquidation amount with reserve
|
|
233
|
+
*/
|
|
234
|
+
export function addReserve(amount: bigint, reserveFactor: bigint, factorScale: bigint): bigint {
|
|
235
|
+
return amount * factorScale / (factorScale - reserveFactor);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Deducts reserve from liquidation amount
|
|
240
|
+
* @param amount liquidation amount with reserve
|
|
241
|
+
* @param reserveFactor asset reserve factor
|
|
242
|
+
* @param reserveFactorScale asset reserve factor scale
|
|
243
|
+
* @returns liquidation amount without reserve
|
|
244
|
+
*/
|
|
245
|
+
export function deductReserve(amount: bigint, reserveFactor: bigint, reserveFactorScale: bigint): bigint {
|
|
246
|
+
return amount * (reserveFactorScale - reserveFactor) / reserveFactorScale;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Converts worth value to specified asset amount
|
|
251
|
+
* @param worth worth value (decimals = 9)
|
|
252
|
+
* @param scale asset scale (10^asset_decimals)
|
|
253
|
+
* @param price asset price
|
|
254
|
+
*/
|
|
255
|
+
export function toAssetAmount(worth: bigint, scale: bigint, price: bigint): bigint {
|
|
256
|
+
return worth * scale / price;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Converts calculates worth value of specified asset amount
|
|
261
|
+
* @param amount worth value (decimals = 9)
|
|
262
|
+
* @param scale asset scale (10^asset_decimals)
|
|
263
|
+
* @param price asset price
|
|
264
|
+
*/
|
|
265
|
+
export function toAssetWorth(amount: bigint, scale: bigint, price: bigint): bigint {
|
|
266
|
+
return amount * price / scale;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Adds liquidation bonus to reward value.
|
|
271
|
+
* @param value reward asset value
|
|
272
|
+
* @param bonus liquidation bonus factor
|
|
273
|
+
* @param scale liquidation bonus scale
|
|
274
|
+
*/
|
|
275
|
+
export function addLiquidationBonus(value: bigint, bonus: bigint, scale: bigint): bigint {
|
|
276
|
+
return value * bonus / scale;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Deducts liquidation bonus from reward value.
|
|
281
|
+
* @param value reward asset value
|
|
282
|
+
* @param bonus liquidation bonus factor
|
|
283
|
+
* @param scale liquidation bonus scale
|
|
284
|
+
*/
|
|
285
|
+
export function deductLiquidationBonus(value: bigint, bonus: bigint, scale: bigint): bigint {
|
|
286
|
+
return value * scale / bonus;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
export type SuccessType = { ok: true };
|
|
290
|
+
export type FailType = { ok: false };
|
|
291
|
+
|
|
292
|
+
export type PreparedAssetInfo = {
|
|
293
|
+
config: AssetConfig,
|
|
294
|
+
data: AssetData,
|
|
295
|
+
price: bigint,
|
|
296
|
+
principal: bigint,
|
|
297
|
+
scale: bigint,
|
|
298
|
+
liquidationReserveFactor: bigint,
|
|
299
|
+
liquidationBonus: bigint,
|
|
300
|
+
present: UserBalance,
|
|
301
|
+
balance: bigint,
|
|
302
|
+
dust: bigint,
|
|
303
|
+
};
|
|
304
|
+
|
|
305
|
+
export type PreparedAssetInfoResult = (PreparedAssetInfo & SuccessType) | FailType;
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* Prepares extended asset info
|
|
309
|
+
* @param assetId
|
|
310
|
+
* @param assetsConfigDict
|
|
311
|
+
* @param assetsDataDict
|
|
312
|
+
* @param pricesDict
|
|
313
|
+
* @param principalsDict
|
|
314
|
+
* @param masterConstants
|
|
315
|
+
*/
|
|
316
|
+
export function prepareAssetInfo(assetId: bigint,
|
|
317
|
+
assetsConfigDict: ExtendedAssetsConfig,
|
|
318
|
+
assetsDataDict: ExtendedAssetsData,
|
|
319
|
+
pricesDict: Dictionary<bigint, bigint>,
|
|
320
|
+
principalsDict: Dictionary<bigint, bigint>,
|
|
321
|
+
masterConstants: MasterConstants
|
|
322
|
+
): PreparedAssetInfoResult {
|
|
323
|
+
if (!assetsConfigDict.has(assetId) ||
|
|
324
|
+
!assetsDataDict.has(assetId) ||
|
|
325
|
+
!pricesDict.has(assetId) ||
|
|
326
|
+
!principalsDict.has(assetId)) {
|
|
327
|
+
return { ok: false };
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
const config = assetsConfigDict.get(assetId)!;
|
|
331
|
+
const data = assetsDataDict.get(assetId)!;
|
|
332
|
+
const base = {
|
|
333
|
+
ok: true,
|
|
334
|
+
config, data,
|
|
335
|
+
price: pricesDict.get(assetId)!,
|
|
336
|
+
principal: principalsDict.get(assetId)!,
|
|
337
|
+
scale: 10n ** config.decimals,
|
|
338
|
+
liquidationReserveFactor: config.liquidationReserveFactor,
|
|
339
|
+
liquidationBonus: config.liquidationBonus
|
|
340
|
+
};
|
|
341
|
+
|
|
342
|
+
const assetPresent = presentValue(data.sRate, data.bRate, base.principal, masterConstants);
|
|
343
|
+
const dustPresent = presentValue(data.sRate, data.bRate, config.dust, masterConstants);
|
|
344
|
+
|
|
345
|
+
return { ...base, present: assetPresent, balance: assetPresent.amount, dust: dustPresent.amount };
|
|
346
|
+
}
|