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