@evaafi/sdk 0.6.4 → 0.9.0-a
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/feeds.d.ts +31 -0
- package/dist/api/feeds.js +73 -0
- package/dist/api/liquidation.js +1 -1
- package/dist/api/math.js +1 -1
- package/dist/api/parser.d.ts +4 -2
- package/dist/api/parser.js +39 -18
- package/dist/api/parsers/AbstractOracleParser.d.ts +11 -0
- package/dist/api/parsers/AbstractOracleParser.js +9 -0
- package/dist/api/parsers/ClassicOracleParser.d.ts +10 -0
- package/dist/api/parsers/ClassicOracleParser.js +16 -0
- package/dist/api/parsers/PythOracleParser.d.ts +18 -0
- package/dist/api/parsers/PythOracleParser.js +22 -0
- package/dist/api/parsers/index.d.ts +3 -0
- package/dist/api/parsers/index.js +19 -0
- package/dist/api/prices.d.ts +7 -6
- package/dist/api/prices.js +37 -46
- package/dist/constants/assets/assetId.d.ts +22 -0
- package/dist/constants/assets/assetId.js +29 -0
- package/dist/constants/assets/index.d.ts +3 -0
- package/dist/constants/assets/index.js +19 -0
- package/dist/constants/{assets.d.ts → assets/mainnet.d.ts} +3 -29
- package/dist/constants/{assets.js → assets/mainnet.js} +30 -79
- package/dist/constants/assets/testnet.d.ts +14 -0
- package/dist/constants/assets/testnet.js +54 -0
- package/dist/constants/general/index.d.ts +65 -0
- package/dist/constants/general/index.js +93 -0
- package/dist/constants/general/mainnet.d.ts +24 -0
- package/dist/constants/{general.js → general/mainnet.js} +38 -60
- package/dist/constants/general/testnet.d.ts +12 -0
- package/dist/constants/general/testnet.js +15 -0
- package/dist/constants/index.d.ts +3 -0
- package/dist/constants/index.js +19 -0
- package/dist/constants/pools/index.d.ts +2 -0
- package/dist/constants/pools/index.js +18 -0
- package/dist/constants/pools/mainnet.d.ts +14 -0
- package/dist/constants/pools/mainnet.js +145 -0
- package/dist/constants/pools/testnet.d.ts +9 -0
- package/dist/constants/pools/testnet.js +57 -0
- package/dist/contracts/AbstractMaster.d.ts +185 -0
- package/dist/contracts/AbstractMaster.js +179 -0
- package/dist/contracts/ClassicMaster.d.ts +34 -0
- package/dist/contracts/ClassicMaster.js +87 -0
- package/dist/contracts/PythMaster.d.ts +62 -0
- package/dist/contracts/PythMaster.js +179 -0
- package/dist/contracts/UserContract.d.ts +1 -7
- package/dist/contracts/UserContract.js +1 -19
- package/dist/contracts/index.d.ts +5 -0
- package/dist/contracts/index.js +21 -0
- package/dist/index.d.ts +14 -14
- package/dist/index.js +20 -60
- package/dist/prices/Oracle.interface.d.ts +9 -0
- package/dist/prices/Oracle.interface.js +2 -0
- package/dist/prices/Prices.d.ts +5 -3
- package/dist/prices/Prices.js +13 -3
- package/dist/prices/PricesCollector.d.ts +17 -7
- package/dist/prices/PricesCollector.js +67 -51
- package/dist/prices/PythCollector.d.ts +22 -0
- package/dist/prices/PythCollector.js +217 -0
- package/dist/prices/Types.d.ts +17 -1
- package/dist/prices/Types.js +8 -1
- package/dist/prices/index.d.ts +4 -3
- package/dist/prices/index.js +4 -3
- package/dist/prices/sources/Backend.d.ts +5 -4
- package/dist/prices/sources/Backend.js +16 -13
- package/dist/prices/sources/Icp.d.ts +2 -1
- package/dist/prices/sources/Icp.js +12 -9
- package/dist/prices/sources/PriceSource.d.ts +7 -6
- package/dist/prices/utils.d.ts +10 -8
- package/dist/prices/utils.js +32 -46
- package/dist/types/Master.d.ts +10 -30
- package/dist/types/Master.js +3 -0
- package/dist/utils/userJettonWallet.js +0 -8
- package/dist/utils/utils.d.ts +8 -1
- package/dist/utils/utils.js +31 -2
- package/package.json +4 -3
- package/src/api/feeds.ts +90 -0
- package/src/api/liquidation.ts +1 -1
- package/src/api/math.ts +1 -1
- package/src/api/parser.ts +100 -38
- package/src/api/parsers/AbstractOracleParser.ts +16 -0
- package/src/api/parsers/ClassicOracleParser.ts +20 -0
- package/src/api/parsers/PythOracleParser.ts +34 -0
- package/src/api/parsers/index.ts +3 -0
- package/src/api/prices.ts +32 -41
- package/src/constants/assets/assetId.ts +30 -0
- package/src/constants/assets/index.ts +3 -0
- package/src/constants/{assets.ts → assets/mainnet.ts} +27 -94
- package/src/constants/assets/testnet.ts +74 -0
- package/src/constants/general/index.ts +91 -0
- package/src/constants/{general.ts → general/mainnet.ts} +48 -72
- package/src/constants/general/testnet.ts +25 -0
- package/src/constants/index.ts +3 -0
- package/src/constants/pools/index.ts +2 -0
- package/src/constants/pools/mainnet.ts +218 -0
- package/src/constants/pools/testnet.ts +75 -0
- package/src/contracts/AbstractMaster.ts +450 -0
- package/src/contracts/ClassicMaster.ts +149 -0
- package/src/contracts/PythMaster.ts +313 -0
- package/src/contracts/UserContract.ts +7 -28
- package/src/contracts/index.ts +7 -0
- package/src/index.ts +18 -85
- package/src/prices/Oracle.interface.ts +18 -0
- package/src/prices/Prices.ts +17 -4
- package/src/prices/PricesCollector.ts +91 -68
- package/src/prices/PythCollector.ts +294 -0
- package/src/prices/Types.ts +28 -6
- package/src/prices/index.ts +4 -3
- package/src/prices/sources/Backend.ts +21 -19
- package/src/prices/sources/Icp.ts +13 -10
- package/src/prices/sources/PriceSource.ts +6 -5
- package/src/prices/utils.ts +65 -68
- package/src/types/Master.ts +29 -52
- package/src/types/User.ts +15 -7
- package/src/utils/userJettonWallet.ts +0 -8
- package/src/utils/utils.ts +41 -2
- package/dist/constants/general.d.ts +0 -67
- package/dist/constants/pools.d.ts +0 -13
- package/dist/constants/pools.js +0 -120
- package/dist/contracts/MasterContract.d.ts +0 -156
- package/dist/contracts/MasterContract.js +0 -260
- package/src/constants/pools.ts +0 -175
- package/src/contracts/MasterContract.ts +0 -410
package/dist/types/Master.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
/// <reference types="node" />
|
|
3
3
|
import { Address, Cell, Dictionary } from '@ton/core';
|
|
4
|
+
import { Oracle } from '../prices/Oracle.interface';
|
|
5
|
+
export { FeedMapItem, parseFeedsMapDict } from '../api/feeds';
|
|
4
6
|
export type MasterConstants = {
|
|
5
7
|
FACTOR_SCALE: bigint;
|
|
6
8
|
ASSET_COEFFICIENT_SCALE: bigint;
|
|
@@ -25,10 +27,9 @@ export type PoolConfig = {
|
|
|
25
27
|
masterAddress: Address;
|
|
26
28
|
masterVersion: number;
|
|
27
29
|
masterConstants: MasterConstants;
|
|
28
|
-
oracles: OracleNFT[];
|
|
29
|
-
minimalOracles: number;
|
|
30
30
|
poolAssetsConfig: PoolAssetsConfig;
|
|
31
31
|
lendingCode: Cell;
|
|
32
|
+
oracles: Oracle;
|
|
32
33
|
};
|
|
33
34
|
export type UpgradeConfig = {
|
|
34
35
|
masterCodeVersion: number;
|
|
@@ -41,7 +42,7 @@ export type UpgradeConfig = {
|
|
|
41
42
|
newUserCode: Cell | null;
|
|
42
43
|
};
|
|
43
44
|
export type AssetConfig = {
|
|
44
|
-
|
|
45
|
+
jwAddress: bigint;
|
|
45
46
|
decimals: bigint;
|
|
46
47
|
collateralFactor: bigint;
|
|
47
48
|
liquidationThreshold: bigint;
|
|
@@ -60,17 +61,10 @@ export type AssetConfig = {
|
|
|
60
61
|
minPrincipalForRewards: bigint;
|
|
61
62
|
baseTrackingSupplySpeed: bigint;
|
|
62
63
|
baseTrackingBorrowSpeed: bigint;
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
oraclesInfo: OraclesInfo;
|
|
68
|
-
tokenKeys: Cell | null;
|
|
69
|
-
};
|
|
70
|
-
export type OraclesInfo = {
|
|
71
|
-
numOracles: number;
|
|
72
|
-
threshold: number;
|
|
73
|
-
oracles: Cell | null;
|
|
64
|
+
borrowCap: number | bigint;
|
|
65
|
+
heCategory: number;
|
|
66
|
+
heCollateralFactor: number;
|
|
67
|
+
heLiquidationThreshold: number;
|
|
74
68
|
};
|
|
75
69
|
export type AssetData = {
|
|
76
70
|
sRate: bigint;
|
|
@@ -94,28 +88,14 @@ export type AssetApy = {
|
|
|
94
88
|
export type ExtendedAssetData = AssetData & AssetInterest & AssetApy;
|
|
95
89
|
export type ExtendedAssetsData = Dictionary<bigint, ExtendedAssetData>;
|
|
96
90
|
export type ExtendedAssetsConfig = Dictionary<bigint, AssetConfig>;
|
|
97
|
-
export type MasterData = {
|
|
98
|
-
meta: string;
|
|
99
|
-
upgradeConfig: UpgradeConfig;
|
|
100
|
-
masterConfig: MasterConfig;
|
|
101
|
-
assetsConfig: ExtendedAssetsConfig;
|
|
102
|
-
assetsData: ExtendedAssetsData;
|
|
103
|
-
assetsReserves: Dictionary<bigint, bigint>;
|
|
104
|
-
apy: {
|
|
105
|
-
supply: Dictionary<bigint, number>;
|
|
106
|
-
borrow: Dictionary<bigint, number>;
|
|
107
|
-
};
|
|
108
|
-
};
|
|
109
91
|
export type AgregatedBalances = {
|
|
110
92
|
totalBorrow: bigint;
|
|
111
93
|
totalSupply: bigint;
|
|
112
94
|
};
|
|
113
|
-
export type
|
|
114
|
-
id: number;
|
|
95
|
+
export type ExtendedEvaaOracle = EvaaOracle & {
|
|
115
96
|
address: string;
|
|
116
|
-
pubkey: Buffer;
|
|
117
97
|
};
|
|
118
|
-
export type
|
|
98
|
+
export type EvaaOracle = {
|
|
119
99
|
id: number;
|
|
120
100
|
pubkey: Buffer;
|
|
121
101
|
};
|
package/dist/types/Master.js
CHANGED
|
@@ -1,2 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseFeedsMapDict = void 0;
|
|
4
|
+
var feeds_1 = require("../api/feeds");
|
|
5
|
+
Object.defineProperty(exports, "parseFeedsMapDict", { enumerable: true, get: function () { return feeds_1.parseFeedsMapDict; } });
|
|
@@ -5,14 +5,6 @@ const core_1 = require("@ton/core");
|
|
|
5
5
|
const assets_1 = require("../constants/assets");
|
|
6
6
|
function getUserJettonData(ownerAddress, assetName, jettonWalletCode, jettonMasterAddress) {
|
|
7
7
|
switch (assetName) {
|
|
8
|
-
case 'uTON':
|
|
9
|
-
return (0, core_1.beginCell)()
|
|
10
|
-
.storeCoins(0)
|
|
11
|
-
.storeUint(0, 64)
|
|
12
|
-
.storeAddress(ownerAddress)
|
|
13
|
-
.storeAddress(jettonMasterAddress)
|
|
14
|
-
.storeRef(jettonWalletCode)
|
|
15
|
-
.endCell();
|
|
16
8
|
case 'DOGS':
|
|
17
9
|
case 'NOT':
|
|
18
10
|
case 'USDT':
|
package/dist/utils/utils.d.ts
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
import { PoolAssetConfig } from
|
|
1
|
+
import { PoolAssetConfig } from '../types/Master';
|
|
2
2
|
export declare function isTonAsset(asset: PoolAssetConfig): boolean;
|
|
3
3
|
export declare function isTonAssetId(assetId: bigint): boolean;
|
|
4
4
|
export declare function delay(ms: number): Promise<unknown>;
|
|
5
|
+
export interface FetchConfig {
|
|
6
|
+
retries: number;
|
|
7
|
+
timeout: number;
|
|
8
|
+
}
|
|
9
|
+
export declare const DefaultFetchConfig: FetchConfig;
|
|
10
|
+
export declare function proxyFetchRetries<T>(fetch: Promise<T>, config?: FetchConfig): Promise<T>;
|
|
11
|
+
export declare function isValidSubaccountId(subaccountId: number): boolean;
|
package/dist/utils/utils.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.delay = exports.isTonAssetId = exports.isTonAsset = void 0;
|
|
3
|
+
exports.isValidSubaccountId = exports.proxyFetchRetries = exports.DefaultFetchConfig = exports.delay = exports.isTonAssetId = exports.isTonAsset = void 0;
|
|
4
4
|
const assets_1 = require("../constants/assets");
|
|
5
5
|
function isTonAsset(asset) {
|
|
6
6
|
return asset.name === 'TON';
|
|
@@ -11,6 +11,35 @@ function isTonAssetId(assetId) {
|
|
|
11
11
|
}
|
|
12
12
|
exports.isTonAssetId = isTonAssetId;
|
|
13
13
|
function delay(ms) {
|
|
14
|
-
return new Promise(resolve => setTimeout(resolve, ms));
|
|
14
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
15
15
|
}
|
|
16
16
|
exports.delay = delay;
|
|
17
|
+
exports.DefaultFetchConfig = {
|
|
18
|
+
retries: 3,
|
|
19
|
+
timeout: 1000,
|
|
20
|
+
};
|
|
21
|
+
async function proxyFetchRetries(fetch, config = exports.DefaultFetchConfig) {
|
|
22
|
+
let lastError = null;
|
|
23
|
+
for (let attempt = 0; attempt <= config.retries; attempt++) {
|
|
24
|
+
try {
|
|
25
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
26
|
+
setTimeout(() => reject(new Error('Request timeout')), config.timeout);
|
|
27
|
+
});
|
|
28
|
+
return await Promise.race([fetch, timeoutPromise]);
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
32
|
+
if (attempt < config.retries) {
|
|
33
|
+
// Exponential backoff: wait 1s, 2s, 4s, etc.
|
|
34
|
+
const delay = Math.pow(2, attempt) * 1000;
|
|
35
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
throw new Error(`Failed to fetch after ${config.retries + 1} attempts. Last error: ${lastError instanceof Error ? lastError.message : JSON.stringify(lastError, null, 2)}`);
|
|
40
|
+
}
|
|
41
|
+
exports.proxyFetchRetries = proxyFetchRetries;
|
|
42
|
+
function isValidSubaccountId(subaccountId) {
|
|
43
|
+
return (subaccountId << 16) >> 16 === subaccountId && subaccountId !== -0x8000;
|
|
44
|
+
}
|
|
45
|
+
exports.isValidSubaccountId = isValidSubaccountId;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@evaafi/sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0a",
|
|
4
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": [
|
|
@@ -19,7 +19,6 @@
|
|
|
19
19
|
"license": "MIT",
|
|
20
20
|
"homepage": "https://github.com/evaafi/sdk#readme",
|
|
21
21
|
"devDependencies": {
|
|
22
|
-
"@orbs-network/ton-access": "^2.3.3",
|
|
23
22
|
"@ton/core": "0.56.0",
|
|
24
23
|
"@ton/crypto": "^3.3.0",
|
|
25
24
|
"@tonconnect/sdk": "3.0.5",
|
|
@@ -38,8 +37,10 @@
|
|
|
38
37
|
"crypto-js": ">=4.2.0"
|
|
39
38
|
},
|
|
40
39
|
"dependencies": {
|
|
40
|
+
"@pythnetwork/hermes-client": "^2.0.0",
|
|
41
|
+
"@pythnetwork/pyth-ton-js": "^0.1.2",
|
|
41
42
|
"@ton/ton": "14.0.0",
|
|
42
43
|
"dotenv": "16.4.5"
|
|
43
44
|
},
|
|
44
|
-
"packageManager": "yarn@4.9.
|
|
45
|
+
"packageManager": "yarn@4.9.2+sha512.1fc009bc09d13cfd0e19efa44cbfc2b9cf6ca61482725eb35bbc5e257e093ebf4130db6dfe15d604ff4b79efd8e1e8e99b25fa7d0a6197c9f9826358d4d65c3c"
|
|
45
46
|
}
|
package/src/api/feeds.ts
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { Dictionary } from '@ton/ton';
|
|
2
|
+
import { Buffer } from 'buffer';
|
|
3
|
+
import { ASSET_ID } from '../constants/assets';
|
|
4
|
+
|
|
5
|
+
export const PYTH_TON_PRICE_FEED_ID = '0x8963217838ab4cf5cadc172203c1f0b763fbaa45f346d8ee50ba994bbcac3026';
|
|
6
|
+
export const PYTH_USDT_PRICE_FEED_ID = '0x2b89b9dc8fdf9f34709a5b106b472f0f39bb6ca9ce04b0fd7f2e971688e2e53b';
|
|
7
|
+
export const PYTH_STTON_PRICE_FEED_ID = '0x9145e059026a4d5a46f3b96408f7e572e33b3257b9c2dbe8dba551c772762002';
|
|
8
|
+
export const PYTH_TSTON_PRICE_FEED_ID = '0x3d1784128eeab5961ec60648fe497d3901eebd211b7f51e4bb0db9f024977d25';
|
|
9
|
+
export const PYTH_USDC_PRICE_FEED_ID = '0xeaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a';
|
|
10
|
+
export const PYTH_USDE_PRICE_FEED_ID = '0x6ec879b1e9963de5ee97e9c8710b742d6228252a5e2ca12d4ae81d7fe5ee8c5d';
|
|
11
|
+
export const PYTH_TSUSDE_PRICE_FEED_ID = '0xcbe184846426619a60f51056d26efecb0537ad3a73b1e965fe695d06a257cb19';
|
|
12
|
+
|
|
13
|
+
export function bigintToBuffer(value: bigint, size: number): Buffer {
|
|
14
|
+
if (value < 0n) {
|
|
15
|
+
throw new Error('Only non-negative bigint is supported');
|
|
16
|
+
}
|
|
17
|
+
// it's questionable whether it stores in LE or BE
|
|
18
|
+
// and what option will TVM use, now by default it's BE
|
|
19
|
+
const hex = value.toString(16);
|
|
20
|
+
const padded = hex.padStart(size * 2, '0');
|
|
21
|
+
return Buffer.from(padded, 'hex');
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const packConnectedFeeds = (evaa_id: bigint, reffered_id: bigint) => {
|
|
25
|
+
return Buffer.concat([bigintToBuffer(evaa_id, 32), bigintToBuffer(reffered_id, 32)]);
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export const EVAA_TON_PRICE_FEED_ID = ASSET_ID.TON;
|
|
29
|
+
export const EVAA_NOT_PRICE_FEED_ID = ASSET_ID.NOT;
|
|
30
|
+
export const EVAA_DOGS_PRICE_FEED_ID = ASSET_ID.DOGS;
|
|
31
|
+
export const EVAA_USDT_PRICE_FEED_ID = ASSET_ID.USDT;
|
|
32
|
+
export const EVAA_STTON_PRICE_FEED_ID = ASSET_ID.stTON;
|
|
33
|
+
export const EVAA_TSTON_PRICE_FEED_ID = ASSET_ID.tsTON;
|
|
34
|
+
export const EVAA_JUSDC_PRICE_FEED_ID = ASSET_ID.jUSDC;
|
|
35
|
+
export const EVAA_JUSDT_PRICE_FEED_ID = ASSET_ID.jUSDT;
|
|
36
|
+
export const EVAA_USDE_PRICE_FEED_ID = ASSET_ID.USDe;
|
|
37
|
+
export const EVAA_TSUSDE_PRICE_FEED_ID = ASSET_ID.tsUSDe;
|
|
38
|
+
|
|
39
|
+
export const MAIN_POOL_FEEDS_MAP: Dictionary<bigint, Buffer> = (() => {
|
|
40
|
+
const map = Dictionary.empty<bigint, Buffer>();
|
|
41
|
+
map.set(BigInt(PYTH_TON_PRICE_FEED_ID), packConnectedFeeds(EVAA_TON_PRICE_FEED_ID, 0n));
|
|
42
|
+
map.set(BigInt(PYTH_USDT_PRICE_FEED_ID), packConnectedFeeds(EVAA_USDT_PRICE_FEED_ID, 0n));
|
|
43
|
+
map.set(
|
|
44
|
+
BigInt(PYTH_STTON_PRICE_FEED_ID),
|
|
45
|
+
packConnectedFeeds(EVAA_STTON_PRICE_FEED_ID, BigInt(PYTH_TON_PRICE_FEED_ID)),
|
|
46
|
+
);
|
|
47
|
+
map.set(
|
|
48
|
+
BigInt(PYTH_TSTON_PRICE_FEED_ID),
|
|
49
|
+
packConnectedFeeds(EVAA_TSTON_PRICE_FEED_ID, BigInt(PYTH_TON_PRICE_FEED_ID)),
|
|
50
|
+
);
|
|
51
|
+
map.set(BigInt(PYTH_USDC_PRICE_FEED_ID), packConnectedFeeds(EVAA_JUSDC_PRICE_FEED_ID, 0n));
|
|
52
|
+
map.set(BigInt(PYTH_USDT_PRICE_FEED_ID), packConnectedFeeds(EVAA_JUSDT_PRICE_FEED_ID, 0n));
|
|
53
|
+
map.set(BigInt(PYTH_USDE_PRICE_FEED_ID), packConnectedFeeds(EVAA_USDE_PRICE_FEED_ID, 0n));
|
|
54
|
+
map.set(BigInt(PYTH_TSUSDE_PRICE_FEED_ID), packConnectedFeeds(EVAA_TSUSDE_PRICE_FEED_ID, 0n));
|
|
55
|
+
return map;
|
|
56
|
+
})();
|
|
57
|
+
|
|
58
|
+
export type FeedMapItem = {
|
|
59
|
+
evaaId: bigint;
|
|
60
|
+
referredPythFeed: bigint;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export function parseFeedsMapDict(dict: Dictionary<bigint, Buffer>) {
|
|
64
|
+
const parsedData = new Map<bigint, FeedMapItem>();
|
|
65
|
+
for (const key of dict.keys()) {
|
|
66
|
+
const buffer = dict.get(key)!;
|
|
67
|
+
|
|
68
|
+
const hex1 = '0x' + buffer.toString('hex', 0, 32);
|
|
69
|
+
const hex2 = '0x' + buffer.toString('hex', 32);
|
|
70
|
+
|
|
71
|
+
const evaaId = BigInt(hex1);
|
|
72
|
+
const referredPythFeed = BigInt(hex2);
|
|
73
|
+
|
|
74
|
+
parsedData.set(key, { evaaId, referredPythFeed });
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return parsedData;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export const TESTNET_ALLOWED_REF_TOKENS: Dictionary<bigint, bigint> = (() => {
|
|
81
|
+
const map = Dictionary.empty<bigint, bigint>();
|
|
82
|
+
map.set(BigInt(EVAA_JUSDT_PRICE_FEED_ID), BigInt(EVAA_USDT_PRICE_FEED_ID));
|
|
83
|
+
return map;
|
|
84
|
+
})();
|
|
85
|
+
|
|
86
|
+
export const TESTNET_FEEDS_MAP: Dictionary<bigint, Buffer> = (() => {
|
|
87
|
+
const map = Dictionary.empty<bigint, Buffer>();
|
|
88
|
+
map.set(BigInt(PYTH_TON_PRICE_FEED_ID), packConnectedFeeds(EVAA_TON_PRICE_FEED_ID, 0n));
|
|
89
|
+
return map;
|
|
90
|
+
})();
|
package/src/api/liquidation.ts
CHANGED
|
@@ -174,7 +174,7 @@ export function calculateLiquidationAmounts(
|
|
|
174
174
|
|
|
175
175
|
const _isBadDebt = isBadDebt(supplyAmount, borrowAmount, liquidationBonus, masterConstants);
|
|
176
176
|
if (!_isBadDebt) {
|
|
177
|
-
allowedCollateralValue = BigMath.min(allowedCollateralValue, BigMath.max(allowedCollateralValue /
|
|
177
|
+
allowedCollateralValue = BigMath.min(allowedCollateralValue, BigMath.max(allowedCollateralValue / 3n, collateralThreshold));
|
|
178
178
|
}
|
|
179
179
|
|
|
180
180
|
const loanValue = toAssetWorth(loanInfo.balance, loanInfo.scale, loanInfo.price);
|
package/src/api/math.ts
CHANGED
|
@@ -452,7 +452,7 @@ export function calculateLiquidationData(
|
|
|
452
452
|
const liquidationBonus = collateralAssetConfig.liquidationBonus;
|
|
453
453
|
const loanScale = 10n ** loanAssetConfig.decimals;
|
|
454
454
|
values.push(
|
|
455
|
-
(bigIntMax(collateralValue /
|
|
455
|
+
(bigIntMax(collateralValue / 3n, bigIntMin(collateralValue, COLLATERAL_WORTH_THRESHOLD)) *
|
|
456
456
|
loanScale *
|
|
457
457
|
poolConfig.masterConstants.ASSET_COEFFICIENT_SCALE) /
|
|
458
458
|
liquidationBonus /
|
package/src/api/parser.ts
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
import { beginCell, Cell, Dictionary, DictionaryValue, Slice } from '@ton/core';
|
|
2
|
-
import {
|
|
2
|
+
import { MasterConfig, MasterData, OracleInfo } from '../contracts/AbstractMaster';
|
|
3
|
+
import {
|
|
4
|
+
AssetConfig,
|
|
5
|
+
AssetData,
|
|
6
|
+
ExtendedAssetData,
|
|
7
|
+
ExtendedAssetsConfig,
|
|
8
|
+
ExtendedAssetsData,
|
|
9
|
+
MasterConstants,
|
|
10
|
+
PoolAssetsConfig,
|
|
11
|
+
PoolConfig,
|
|
12
|
+
} from '../types/Master';
|
|
13
|
+
import { BalanceType, UserBalance, UserData, UserLiteData, UserRewards } from '../types/User';
|
|
14
|
+
import { loadMaybeMyRef, loadMyRef } from './helpers';
|
|
3
15
|
import {
|
|
4
16
|
bigIntMax,
|
|
5
17
|
bigIntMin,
|
|
@@ -11,16 +23,14 @@ import {
|
|
|
11
23
|
getAvailableToBorrow,
|
|
12
24
|
presentValue,
|
|
13
25
|
} from './math';
|
|
14
|
-
import {
|
|
15
|
-
import { BalanceType, UserBalance, UserData, UserLiteData, UserRewards } from '../types/User';
|
|
16
|
-
import { checkNotInDebtAtAll } from "../api/math";
|
|
26
|
+
import { OracleParser } from './parsers/AbstractOracleParser';
|
|
17
27
|
|
|
18
28
|
export function createUserRewards(): DictionaryValue<UserRewards> {
|
|
19
29
|
return {
|
|
20
30
|
serialize: (src: any, buidler: any) => {
|
|
21
31
|
buidler.storeUint(src.trackingIndex, 64);
|
|
22
32
|
buidler.storeUint(src.trackingAccured, 64);
|
|
23
|
-
|
|
33
|
+
},
|
|
24
34
|
parse: (src: Slice) => {
|
|
25
35
|
const trackingIndex = BigInt(src.loadUint(64));
|
|
26
36
|
const trackingAccured = BigInt(src.loadUint(64));
|
|
@@ -51,9 +61,19 @@ export function createAssetData(): DictionaryValue<AssetData> {
|
|
|
51
61
|
const balance = BigInt(src.loadUintBig(64));
|
|
52
62
|
const trackingSupplyIndex = BigInt(src.loadUintBig(64));
|
|
53
63
|
const trackingBorrowIndex = BigInt(src.loadUintBig(64));
|
|
54
|
-
const awaitedSupply = BigInt(src.loadUintBig(64));
|
|
64
|
+
const awaitedSupply = BigInt(src.loadUintBig(64));
|
|
55
65
|
|
|
56
|
-
return {
|
|
66
|
+
return {
|
|
67
|
+
sRate,
|
|
68
|
+
bRate,
|
|
69
|
+
totalSupply,
|
|
70
|
+
totalBorrow,
|
|
71
|
+
lastAccural,
|
|
72
|
+
balance,
|
|
73
|
+
trackingSupplyIndex,
|
|
74
|
+
trackingBorrowIndex,
|
|
75
|
+
awaitedSupply,
|
|
76
|
+
};
|
|
57
77
|
},
|
|
58
78
|
};
|
|
59
79
|
}
|
|
@@ -61,7 +81,7 @@ export function createAssetData(): DictionaryValue<AssetData> {
|
|
|
61
81
|
export function createAssetConfig(): DictionaryValue<AssetConfig> {
|
|
62
82
|
return {
|
|
63
83
|
serialize: (src: any, builder: any) => {
|
|
64
|
-
builder.storeUint(src.
|
|
84
|
+
builder.storeUint(src.jwAddress, 256);
|
|
65
85
|
builder.storeUint(src.decimals, 8);
|
|
66
86
|
const refBuild = beginCell();
|
|
67
87
|
refBuild.storeUint(src.collateralFactor, 16);
|
|
@@ -81,10 +101,14 @@ export function createAssetConfig(): DictionaryValue<AssetConfig> {
|
|
|
81
101
|
refBuild.storeUint(src.minPrincipalForRewards, 64);
|
|
82
102
|
refBuild.storeUint(src.baseTrackingSupplySpeed, 64);
|
|
83
103
|
refBuild.storeUint(src.baseTrackingBorrowSpeed, 64);
|
|
104
|
+
refBuild.storeInt(src.borrowCap, 64);
|
|
105
|
+
refBuild.storeUint(src.heCategory, 8);
|
|
106
|
+
refBuild.storeUint(src.heCollateralFactor, 16);
|
|
107
|
+
refBuild.storeUint(src.heLiquidationThreshold, 16);
|
|
84
108
|
builder.storeRef(refBuild.endCell());
|
|
85
109
|
},
|
|
86
110
|
parse: (src: Slice) => {
|
|
87
|
-
const
|
|
111
|
+
const jwAddress = src.loadUintBig(256);
|
|
88
112
|
const decimals = BigInt(src.loadUint(8));
|
|
89
113
|
const ref = src.loadRef().beginParse();
|
|
90
114
|
const collateralFactor = ref.loadUintBig(16);
|
|
@@ -104,9 +128,13 @@ export function createAssetConfig(): DictionaryValue<AssetConfig> {
|
|
|
104
128
|
const minPrincipalForRewards = ref.loadUintBig(64);
|
|
105
129
|
const baseTrackingSupplySpeed = ref.loadUintBig(64);
|
|
106
130
|
const baseTrackingBorrowSpeed = ref.loadUintBig(64);
|
|
131
|
+
const borrowCap = ref.loadInt(64);
|
|
132
|
+
const heCategory = ref.loadUint(8);
|
|
133
|
+
const heCollateralFactor = ref.loadUint(16);
|
|
134
|
+
const heLiquidationThreshold = ref.loadUint(16);
|
|
107
135
|
|
|
108
136
|
return {
|
|
109
|
-
|
|
137
|
+
jwAddress,
|
|
110
138
|
decimals,
|
|
111
139
|
collateralFactor,
|
|
112
140
|
liquidationThreshold,
|
|
@@ -124,17 +152,25 @@ export function createAssetConfig(): DictionaryValue<AssetConfig> {
|
|
|
124
152
|
liquidationReserveFactor,
|
|
125
153
|
minPrincipalForRewards,
|
|
126
154
|
baseTrackingSupplySpeed,
|
|
127
|
-
baseTrackingBorrowSpeed
|
|
155
|
+
baseTrackingBorrowSpeed,
|
|
156
|
+
borrowCap,
|
|
157
|
+
heCategory,
|
|
158
|
+
heCollateralFactor,
|
|
159
|
+
heLiquidationThreshold,
|
|
128
160
|
};
|
|
129
161
|
},
|
|
130
162
|
};
|
|
131
163
|
}
|
|
132
164
|
|
|
133
|
-
export function parseMasterData(
|
|
165
|
+
export function parseMasterData(
|
|
166
|
+
masterDataBOC: string,
|
|
167
|
+
poolAssetsConfig: PoolAssetsConfig,
|
|
168
|
+
masterConstants: MasterConstants,
|
|
169
|
+
oracleParser: OracleParser,
|
|
170
|
+
): MasterData<MasterConfig<OracleInfo>> {
|
|
134
171
|
const masterSlice = Cell.fromBase64(masterDataBOC).beginParse();
|
|
135
172
|
const meta = masterSlice.loadRef().beginParse().loadStringTail();
|
|
136
173
|
const upgradeConfigParser = masterSlice.loadRef().beginParse();
|
|
137
|
-
|
|
138
174
|
const upgradeConfig = {
|
|
139
175
|
masterCodeVersion: Number(upgradeConfigParser.loadCoins()),
|
|
140
176
|
userCodeVersion: Number(upgradeConfigParser.loadCoins()),
|
|
@@ -146,31 +182,31 @@ export function parseMasterData(masterDataBOC: string, poolAssetsConfig: PoolAss
|
|
|
146
182
|
newUserCode: loadMaybeMyRef(upgradeConfigParser),
|
|
147
183
|
};
|
|
148
184
|
// upgradeConfigParser.endParse(); todo fix with new testnet contract
|
|
149
|
-
|
|
150
185
|
const masterConfigSlice = masterSlice.loadRef().beginParse();
|
|
186
|
+
|
|
151
187
|
const assetsConfigDict = masterConfigSlice.loadDict(Dictionary.Keys.BigUint(256), createAssetConfig());
|
|
152
188
|
const assetsDataDict = masterSlice.loadDict(Dictionary.Keys.BigUint(256), createAssetData());
|
|
153
|
-
|
|
154
189
|
const assetsExtendedData = Dictionary.empty<bigint, ExtendedAssetData>();
|
|
155
190
|
const assetsReserves = Dictionary.empty<bigint, bigint>();
|
|
156
191
|
const apy = {
|
|
157
192
|
supply: Dictionary.empty<bigint, number>(),
|
|
158
193
|
borrow: Dictionary.empty<bigint, number>(),
|
|
159
194
|
};
|
|
160
|
-
|
|
161
|
-
for (const [
|
|
195
|
+
|
|
196
|
+
for (const [, asset] of Object.entries(poolAssetsConfig)) {
|
|
162
197
|
const assetData = calculateAssetData(assetsConfigDict, assetsDataDict, asset.assetId, masterConstants);
|
|
163
198
|
assetsExtendedData.set(asset.assetId, assetData);
|
|
164
199
|
}
|
|
200
|
+
|
|
201
|
+
const ifActive = oracleParser.getIfActive(masterConfigSlice);
|
|
202
|
+
const oraclesInfo = oracleParser.parseOracleConfig(masterConfigSlice);
|
|
203
|
+
|
|
165
204
|
const masterConfig = {
|
|
166
|
-
ifActive
|
|
205
|
+
ifActive,
|
|
167
206
|
admin: masterConfigSlice.loadAddress(),
|
|
168
|
-
oraclesInfo
|
|
169
|
-
numOracles: masterConfigSlice.loadUint(16),
|
|
170
|
-
threshold: masterConfigSlice.loadUint(16),
|
|
171
|
-
oracles: loadMaybeMyRef(masterConfigSlice)
|
|
172
|
-
},
|
|
207
|
+
oraclesInfo,
|
|
173
208
|
tokenKeys: loadMaybeMyRef(masterConfigSlice),
|
|
209
|
+
supervisor: masterConfigSlice.loadMaybeAddress(),
|
|
174
210
|
};
|
|
175
211
|
masterConfigSlice.endParse();
|
|
176
212
|
|
|
@@ -179,11 +215,9 @@ export function parseMasterData(masterDataBOC: string, poolAssetsConfig: PoolAss
|
|
|
179
215
|
const totalSupply = calculatePresentValue(assetData.sRate, assetData.totalSupply, masterConstants);
|
|
180
216
|
const totalBorrow = calculatePresentValue(assetData.bRate, assetData.totalBorrow, masterConstants);
|
|
181
217
|
assetsReserves.set(asset.assetId, assetData.balance - totalSupply + totalBorrow);
|
|
182
|
-
|
|
183
218
|
apy.supply.set(asset.assetId, (1 + (Number(assetData.supplyInterest) / 1e12) * 24 * 3600) ** 365 - 1);
|
|
184
219
|
apy.borrow.set(asset.assetId, (1 + (Number(assetData.borrowInterest) / 1e12) * 24 * 3600) ** 365 - 1);
|
|
185
220
|
}
|
|
186
|
-
|
|
187
221
|
return {
|
|
188
222
|
meta: meta,
|
|
189
223
|
upgradeConfig: upgradeConfig,
|
|
@@ -200,7 +234,7 @@ export function parseUserLiteData(
|
|
|
200
234
|
assetsData: ExtendedAssetsData,
|
|
201
235
|
assetsConfig: ExtendedAssetsConfig,
|
|
202
236
|
poolConfig: PoolConfig,
|
|
203
|
-
applyDust: boolean = false
|
|
237
|
+
applyDust: boolean = false,
|
|
204
238
|
): UserLiteData {
|
|
205
239
|
const poolAssetsConfig = poolConfig.poolAssetsConfig;
|
|
206
240
|
const masterConstants = poolConfig.masterConstants;
|
|
@@ -232,7 +266,7 @@ export function parseUserLiteData(
|
|
|
232
266
|
backupCell1 = userSlice.loadMaybeRef();
|
|
233
267
|
backupCell2 = userSlice.loadMaybeRef();
|
|
234
268
|
}
|
|
235
|
-
|
|
269
|
+
|
|
236
270
|
userSlice.endParse();
|
|
237
271
|
const userBalances = Dictionary.empty<bigint, UserBalance>();
|
|
238
272
|
|
|
@@ -243,7 +277,7 @@ export function parseUserLiteData(
|
|
|
243
277
|
let principal = realPrincipals.get(asset.assetId) || 0n;
|
|
244
278
|
let balance = presentValue(assetData.sRate, assetData.bRate, principal, masterConstants);
|
|
245
279
|
|
|
246
|
-
if (applyDust &&
|
|
280
|
+
if (applyDust && principal > 0 && principal < assetConfig.dust) {
|
|
247
281
|
principal = 0n;
|
|
248
282
|
balance = {
|
|
249
283
|
amount: 0n,
|
|
@@ -270,7 +304,7 @@ export function parseUserLiteData(
|
|
|
270
304
|
dutchAuctionStart: dutchAuctionStart,
|
|
271
305
|
backupCell: backupCell,
|
|
272
306
|
fullyParsed: false,
|
|
273
|
-
|
|
307
|
+
|
|
274
308
|
rewards: rewards,
|
|
275
309
|
backupCell1: backupCell1,
|
|
276
310
|
backupCell2: backupCell2,
|
|
@@ -283,7 +317,7 @@ export function parseUserData(
|
|
|
283
317
|
assetsConfig: ExtendedAssetsConfig,
|
|
284
318
|
prices: Dictionary<bigint, bigint>,
|
|
285
319
|
poolConfig: PoolConfig,
|
|
286
|
-
applyDust: boolean = false
|
|
320
|
+
applyDust: boolean = false,
|
|
287
321
|
): UserData {
|
|
288
322
|
userLiteData.fullyParsed = true;
|
|
289
323
|
let havePrincipalWithoutPrice = false;
|
|
@@ -314,7 +348,7 @@ export function parseUserData(
|
|
|
314
348
|
let principal = userLiteData.principals.get(asset.assetId) || 0n;
|
|
315
349
|
const balance = presentValue(assetData.sRate, assetData.bRate, principal, masterConstants);
|
|
316
350
|
|
|
317
|
-
if (applyDust &&
|
|
351
|
+
if (applyDust && principal > 0 && principal < assetConfig.dust) {
|
|
318
352
|
principal = 0n;
|
|
319
353
|
userLiteData.principals.set(asset.assetId, 0n);
|
|
320
354
|
}
|
|
@@ -338,19 +372,35 @@ export function parseUserData(
|
|
|
338
372
|
}
|
|
339
373
|
}
|
|
340
374
|
|
|
341
|
-
const availableToBorrow = getAvailableToBorrow(
|
|
375
|
+
const availableToBorrow = getAvailableToBorrow(
|
|
376
|
+
assetsConfig,
|
|
377
|
+
assetsData,
|
|
378
|
+
userLiteData.realPrincipals,
|
|
379
|
+
prices,
|
|
380
|
+
masterConstants,
|
|
381
|
+
);
|
|
342
382
|
|
|
343
383
|
for (const [_, asset] of Object.entries(poolAssetsConfig)) {
|
|
344
384
|
const balance = userLiteData.balances.get(asset.assetId) as UserBalance;
|
|
345
385
|
const assetConfig = assetsConfig.get(asset.assetId) as AssetConfig;
|
|
346
386
|
const assetData = assetsData.get(asset.assetId) as ExtendedAssetData;
|
|
347
|
-
|
|
387
|
+
|
|
348
388
|
const assetLiquidityMinusReserves = getAssetLiquidityMinusReserves(assetData, masterConstants);
|
|
349
389
|
|
|
350
390
|
if (balance.type === BalanceType.supply) {
|
|
351
391
|
withdrawalLimits.set(
|
|
352
392
|
asset.assetId,
|
|
353
|
-
bigIntMin(
|
|
393
|
+
bigIntMin(
|
|
394
|
+
calculateMaximumWithdrawAmount(
|
|
395
|
+
assetsConfig,
|
|
396
|
+
assetsData,
|
|
397
|
+
userLiteData.realPrincipals,
|
|
398
|
+
prices,
|
|
399
|
+
masterConstants,
|
|
400
|
+
asset.assetId,
|
|
401
|
+
),
|
|
402
|
+
assetData.balance,
|
|
403
|
+
),
|
|
354
404
|
);
|
|
355
405
|
}
|
|
356
406
|
|
|
@@ -361,7 +411,13 @@ export function parseUserData(
|
|
|
361
411
|
|
|
362
412
|
borrowLimits.set(
|
|
363
413
|
asset.assetId,
|
|
364
|
-
bigIntMax(
|
|
414
|
+
bigIntMax(
|
|
415
|
+
0n,
|
|
416
|
+
bigIntMin(
|
|
417
|
+
(availableToBorrow * 10n ** assetConfig.decimals) / prices.get(asset.assetId)!,
|
|
418
|
+
assetLiquidityMinusReserves,
|
|
419
|
+
),
|
|
420
|
+
),
|
|
365
421
|
);
|
|
366
422
|
}
|
|
367
423
|
|
|
@@ -374,10 +430,16 @@ export function parseUserData(
|
|
|
374
430
|
let healthFactor = 1;
|
|
375
431
|
let liquidationData;
|
|
376
432
|
if (!havePrincipalWithoutPrice) {
|
|
377
|
-
liquidationData = calculateLiquidationData(
|
|
433
|
+
liquidationData = calculateLiquidationData(
|
|
434
|
+
assetsConfig,
|
|
435
|
+
assetsData,
|
|
436
|
+
userLiteData.realPrincipals,
|
|
437
|
+
prices,
|
|
438
|
+
poolConfig,
|
|
439
|
+
);
|
|
378
440
|
if (liquidationData.totalLimit != 0n) {
|
|
379
441
|
healthFactor = 1 - Number(liquidationData.totalDebt) / Number(liquidationData.totalLimit);
|
|
380
|
-
}
|
|
442
|
+
}
|
|
381
443
|
}
|
|
382
444
|
return {
|
|
383
445
|
...userLiteData,
|
|
@@ -390,6 +452,6 @@ export function parseUserData(
|
|
|
390
452
|
limitUsed: limitUsed,
|
|
391
453
|
liquidationData: liquidationData,
|
|
392
454
|
healthFactor: healthFactor,
|
|
393
|
-
havePrincipalWithoutPrice: havePrincipalWithoutPrice
|
|
455
|
+
havePrincipalWithoutPrice: havePrincipalWithoutPrice,
|
|
394
456
|
};
|
|
395
457
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Slice } from '@ton/core';
|
|
2
|
+
import { ClassicOracleInfo } from './ClassicOracleParser';
|
|
3
|
+
import { PythOracleInfo } from './PythOracleParser';
|
|
4
|
+
|
|
5
|
+
export interface OracleParser {
|
|
6
|
+
parseOracleConfig(masterConfigSlice: Slice): ClassicOracleInfo | PythOracleInfo;
|
|
7
|
+
getIfActive(masterConfigSlice: Slice): number;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export abstract class AbstractOracleParser implements OracleParser {
|
|
11
|
+
abstract parseOracleConfig(masterConfigSlice: Slice): ClassicOracleInfo | PythOracleInfo;
|
|
12
|
+
|
|
13
|
+
getIfActive(masterConfigSlice: Slice): number {
|
|
14
|
+
return masterConfigSlice.loadInt(8);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Cell, Slice } from '@ton/core';
|
|
2
|
+
import { loadMaybeMyRef } from '../helpers';
|
|
3
|
+
import { AbstractOracleParser } from './AbstractOracleParser';
|
|
4
|
+
|
|
5
|
+
export type ClassicOracleInfo = {
|
|
6
|
+
numOracles: number;
|
|
7
|
+
threshold: number;
|
|
8
|
+
oracles: Cell | null;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export class ClassicOracleParser extends AbstractOracleParser {
|
|
12
|
+
parseOracleConfig(masterConfigSlice: Slice): ClassicOracleInfo {
|
|
13
|
+
const oraclesSlice = masterConfigSlice.loadRef().beginParse();
|
|
14
|
+
return {
|
|
15
|
+
numOracles: oraclesSlice.loadUint(16),
|
|
16
|
+
threshold: oraclesSlice.loadUint(16),
|
|
17
|
+
oracles: loadMaybeMyRef(oraclesSlice),
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
}
|