@affluent-org/sdk 0.0.4 → 0.0.6
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/affluent.d.ts +3 -3
- package/dist/affluent.js +3 -3
- package/dist/common/computation.d.ts +6 -0
- package/dist/common/computation.js +54 -0
- package/dist/common/helper.d.ts +5 -0
- package/dist/common/helper.js +29 -0
- package/dist/common/service.d.ts +10 -2
- package/dist/common/service.js +56 -3
- package/dist/common/trace-action.d.ts +92 -0
- package/dist/common/trace-action.js +187 -0
- package/dist/common/transform.d.ts +87 -0
- package/dist/common/transform.js +264 -0
- package/dist/common/types.d.ts +140 -0
- package/dist/common/types.js +11 -0
- package/dist/context.d.ts +3 -0
- package/dist/context.js +9 -0
- package/dist/contracts/oracle/redstone-onchain-oracle/index.js +2 -0
- package/dist/contracts/oracle/redstone-onchain-oracle/type.d.ts +1 -1
- package/dist/contracts/vault/strategy-vault/index.d.ts +2 -1
- package/dist/contracts/vault/strategy-vault/index.js +1 -0
- package/dist/factorial.d.ts +18 -8
- package/dist/factorial.js +26 -14
- package/dist/index.d.ts +4 -2
- package/dist/index.js +18 -2
- package/dist/lib/send-msg.d.ts +16 -2
- package/dist/lib/send-msg.js +23 -2
- package/dist/monitor.js +2 -0
- package/dist/monitorCacheV1.js +3 -2
- package/dist/oracle/oracle.d.ts +3 -2
- package/dist/oracle/oracle.js +25 -2
- package/dist/pool.d.ts +41 -0
- package/dist/pool.js +146 -178
- package/dist/poolCacheV1.js +1 -0
- package/dist/rfq-auction.d.ts +2 -2
- package/dist/rfq-auction.js +6 -6
- package/dist/rfq-batch.d.ts +21 -11
- package/dist/rfq-batch.js +81 -9
- package/dist/services/composite-oracle/codec.d.ts +76 -0
- package/dist/services/composite-oracle/codec.js +281 -0
- package/dist/services/composite-oracle/computation.d.ts +8 -19
- package/dist/services/composite-oracle/computation.js +119 -76
- package/dist/services/composite-oracle/index.d.ts +2 -2
- package/dist/services/composite-oracle/index.js +5 -6
- package/dist/services/composite-oracle/query.d.ts +6 -6
- package/dist/services/composite-oracle/query.js +6 -47
- package/dist/services/pool/computation.d.ts +3 -9
- package/dist/services/pool/computation.js +12 -78
- package/dist/services/pool/index.d.ts +10 -59
- package/dist/services/pool/index.js +55 -8
- package/dist/services/pool/oracle.d.ts +2 -2
- package/dist/services/pool/query.d.ts +1 -1
- package/dist/services/pool/query.js +1 -1
- package/dist/services/pool/user/trace.d.ts +90 -0
- package/dist/services/pool/user/trace.js +168 -0
- package/dist/services/rfq-auction/index.d.ts +7 -23
- package/dist/services/rfq-auction/index.js +45 -6
- package/dist/services/rfq-auction/oracle.d.ts +2 -2
- package/dist/services/rfq-auction/user/index.js +1 -1
- package/dist/services/rfq-auction/user/trace.d.ts +53 -0
- package/dist/services/rfq-auction/user/trace.js +68 -0
- package/dist/services/rfq-batch/index.d.ts +16 -13
- package/dist/services/rfq-batch/index.js +34 -10
- package/dist/services/rfq-batch/oracle.d.ts +2 -2
- package/dist/services/rfq-batch/user/trace.d.ts +49 -0
- package/dist/services/rfq-batch/user/trace.js +67 -0
- package/dist/services/share-vault/index.d.ts +14 -88
- package/dist/services/share-vault/index.js +37 -10
- package/dist/services/share-vault/query.d.ts +5 -32
- package/dist/services/share-vault/query.js +25 -12
- package/dist/services/share-vault/user/trace.d.ts +54 -0
- package/dist/services/share-vault/user/trace.js +84 -0
- package/dist/services/strategy-vault/index.d.ts +77 -2115
- package/dist/services/strategy-vault/index.js +119 -54
- package/dist/services/strategy-vault/oracle.d.ts +3 -3
- package/dist/services/strategy-vault/oracle.js +1 -0
- package/dist/services/strategy-vault/owner/index.d.ts +2 -2
- package/dist/services/strategy-vault/owner/index.js +1 -1
- package/dist/services/strategy-vault/owner/types.d.ts +4 -0
- package/dist/services/strategy-vault/query.d.ts +14 -143
- package/dist/services/strategy-vault/query.js +28 -40
- package/dist/services/strategy-vault/user/trace.d.ts +156 -0
- package/dist/services/strategy-vault/user/trace.js +264 -0
- package/dist/share-vault.d.ts +164 -8
- package/dist/share-vault.js +222 -67
- package/dist/strategy_vault/base.d.ts +521 -105
- package/dist/strategy_vault/base.js +493 -41
- package/dist/strategy_vault/steps.d.ts +120 -3
- package/dist/strategy_vault/steps.js +161 -0
- package/dist/types/sender.d.ts +1 -0
- package/dist/utils/_parse_temp/StrategyVault.d.ts +9 -9
- package/dist/utils/_parse_temp/StrategyVault.js +48 -40
- package/dist/utils/_parse_temp/parseMsgBody.d.ts +2 -2
- package/dist/utils/_parse_temp/parseMsgBody.js +84 -84
- package/dist/utils/external-message-hash.d.ts +7 -3
- package/dist/utils/external-message-hash.js +20 -7
- package/dist/utils/oracle/redstone/helper.js +2 -0
- package/dist/utils/oracle/redstone/redstoneHelper.d.ts +7 -0
- package/dist/utils/oracle/redstone/redstoneHelper.js +103 -1
- package/dist/utils/pending-tracker/trackable-sender.d.ts +37 -4
- package/dist/utils/pending-tracker/trackable-sender.js +47 -8
- package/dist/utils/pending-tracker/v3-client.d.ts +16 -0
- package/dist/utils/pending-tracker/v3-client.js +80 -2
- package/dist/utils/risk_calculator/risk_calculator.d.ts +3 -3
- package/dist/utils/toncenter/index.d.ts +1 -0
- package/dist/utils/toncenter/index.js +17 -0
- package/dist/utils/toncenter/transform.d.ts +11 -0
- package/dist/utils/toncenter/transform.js +40 -0
- package/dist/utils/toncenter/type.d.ts +227 -0
- package/dist/utils/toncenter/type.js +2 -0
- package/package.json +3 -3
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createOracleExposures = createOracleExposures;
|
|
4
|
-
exports.applyPrice = applyPrice;
|
|
5
4
|
exports.calculateSyntheticPrices = calculateSyntheticPrices;
|
|
6
|
-
exports.computePoolPositionsValue = computePoolPositionsValue;
|
|
7
5
|
exports.computeVaultValue = computeVaultValue;
|
|
8
6
|
exports.calculateVaultPrices = calculateVaultPrices;
|
|
7
|
+
exports.nativeDecomposeContext = nativeDecomposeContext;
|
|
9
8
|
exports.computeCompositePrices = computeCompositePrices;
|
|
10
9
|
exports.getExposures = getExposures;
|
|
11
10
|
exports.separateAssets = separateAssets;
|
|
@@ -13,11 +12,13 @@ exports.updateOnchainInternalData = updateOnchainInternalData;
|
|
|
13
12
|
exports.buildOracleParamsCellFromPayload = buildOracleParamsCellFromPayload;
|
|
14
13
|
exports.buildOracleParamsCell = buildOracleParamsCell;
|
|
15
14
|
const core_1 = require("@ton/core");
|
|
16
|
-
const types_1 = require("
|
|
17
|
-
const pool_1 = require("../../contracts/core/pool");
|
|
15
|
+
const types_1 = require("../../common/types");
|
|
18
16
|
const type_1 = require("../../contracts/oracle/redstone-onchain-oracle/type");
|
|
19
17
|
const redstone_onchain_oracle_1 = require("../../contracts/oracle/redstone-onchain-oracle");
|
|
20
18
|
const redstoneHelper_1 = require("../../utils/oracle/redstone/redstoneHelper");
|
|
19
|
+
const utils_1 = require("../../contracts/common/utils");
|
|
20
|
+
const transform_1 = require("../../common/transform");
|
|
21
|
+
const helper_1 = require("../../common/helper");
|
|
21
22
|
function createOracleExposures() {
|
|
22
23
|
return {
|
|
23
24
|
assets: new Set(),
|
|
@@ -28,9 +29,6 @@ function createOracleExposures() {
|
|
|
28
29
|
},
|
|
29
30
|
};
|
|
30
31
|
}
|
|
31
|
-
function applyPrice(amount, price) {
|
|
32
|
-
return (amount * price) / types_1.DECIMALS_OF_PRICE;
|
|
33
|
-
}
|
|
34
32
|
function calculateSyntheticPrices(rawPrices, syntheticCompositions) {
|
|
35
33
|
const prices = { ...rawPrices };
|
|
36
34
|
let pendingAssets = Object.entries(syntheticCompositions);
|
|
@@ -43,6 +41,11 @@ function calculateSyntheticPrices(rawPrices, syntheticCompositions) {
|
|
|
43
41
|
prices[assetAddress] = {
|
|
44
42
|
type: types_1.CompositeAssetType.SYNTHETIC1,
|
|
45
43
|
price: (underlyingPrice.price * data.underlyingReserve) / data.totalSupply,
|
|
44
|
+
additionalData: {
|
|
45
|
+
underlying: (0, utils_1.toAddress)(data.underlyingAddress).toString(),
|
|
46
|
+
reserve: data.underlyingReserve,
|
|
47
|
+
totalSupply: data.totalSupply,
|
|
48
|
+
},
|
|
46
49
|
};
|
|
47
50
|
}
|
|
48
51
|
else {
|
|
@@ -53,11 +56,21 @@ function calculateSyntheticPrices(rawPrices, syntheticCompositions) {
|
|
|
53
56
|
const price0 = prices[data.underlying0Address.toString()];
|
|
54
57
|
const price1 = prices[data.underlying1Address.toString()];
|
|
55
58
|
if (price0 && price1) {
|
|
56
|
-
const value0 =
|
|
57
|
-
const value1 =
|
|
59
|
+
const value0 = price0.price * data.underlying0Reserve;
|
|
60
|
+
const value1 = price1.price * data.underlying1Reserve;
|
|
58
61
|
prices[assetAddress] = {
|
|
59
62
|
type: types_1.CompositeAssetType.SYNTHETIC2,
|
|
60
|
-
price: value0 + value1,
|
|
63
|
+
price: (value0 + value1) / data.totalSupply,
|
|
64
|
+
additionalData0: {
|
|
65
|
+
underlying: (0, utils_1.toAddress)(data.underlying0Address).toString(),
|
|
66
|
+
reserve: data.underlying0Reserve,
|
|
67
|
+
totalSupply: data.totalSupply,
|
|
68
|
+
},
|
|
69
|
+
additionalData1: {
|
|
70
|
+
underlying: (0, utils_1.toAddress)(data.underlying1Address).toString(),
|
|
71
|
+
reserve: data.underlying1Reserve,
|
|
72
|
+
totalSupply: data.totalSupply,
|
|
73
|
+
},
|
|
61
74
|
};
|
|
62
75
|
}
|
|
63
76
|
else {
|
|
@@ -72,57 +85,12 @@ function calculateSyntheticPrices(rawPrices, syntheticCompositions) {
|
|
|
72
85
|
}
|
|
73
86
|
return prices;
|
|
74
87
|
}
|
|
75
|
-
function computePoolPositionsValue(poolPositions, poolInfos, prices) {
|
|
76
|
-
const decomposed = {};
|
|
77
|
-
const assetAmounts = {};
|
|
78
|
-
let totalValue = 0n;
|
|
79
|
-
for (const [poolAddress, assetPositions] of Object.entries(poolPositions)) {
|
|
80
|
-
const poolInfo = poolInfos[poolAddress];
|
|
81
|
-
if (!poolInfo)
|
|
82
|
-
continue;
|
|
83
|
-
for (const [assetAddress, position] of Object.entries(assetPositions)) {
|
|
84
|
-
const assetInfo = poolInfo[assetAddress];
|
|
85
|
-
if (!assetInfo)
|
|
86
|
-
continue;
|
|
87
|
-
const amounts = (0, pool_1.positionShareToAmount)(position, assetInfo);
|
|
88
|
-
if (!decomposed[assetAddress]) {
|
|
89
|
-
decomposed[assetAddress] = { supply: 0n, borrow: 0n };
|
|
90
|
-
}
|
|
91
|
-
decomposed[assetAddress].supply += amounts.supply;
|
|
92
|
-
decomposed[assetAddress].borrow += amounts.borrow;
|
|
93
|
-
const netAmount = amounts.supply - amounts.borrow;
|
|
94
|
-
assetAmounts[assetAddress] = (assetAmounts[assetAddress] ?? 0n) + netAmount;
|
|
95
|
-
const price = prices[assetAddress];
|
|
96
|
-
if (price) {
|
|
97
|
-
totalValue += applyPrice(netAmount, price.price);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
return { totalValue, decomposed, assetAmounts };
|
|
102
|
-
}
|
|
103
88
|
function computeVaultValue(vault, poolInfos, prices) {
|
|
104
|
-
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
cashValue += applyPrice(amount, price.price);
|
|
110
|
-
}
|
|
111
|
-
decomposed[assetAddress] = { supply: amount, borrow: 0n };
|
|
112
|
-
}
|
|
113
|
-
const poolResult = computePoolPositionsValue(vault.poolPositions, poolInfos, prices);
|
|
114
|
-
for (const [assetAddress, amounts] of Object.entries(poolResult.decomposed)) {
|
|
115
|
-
if (decomposed[assetAddress]) {
|
|
116
|
-
decomposed[assetAddress].supply += amounts.supply;
|
|
117
|
-
decomposed[assetAddress].borrow += amounts.borrow;
|
|
118
|
-
}
|
|
119
|
-
else {
|
|
120
|
-
decomposed[assetAddress] = amounts;
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
const totalValue = cashValue + poolResult.totalValue;
|
|
124
|
-
const price = vault.totalSupply === 0n ? 0n : (totalValue * types_1.DECIMALS_OF_PRICE) / vault.totalSupply;
|
|
125
|
-
return { totalValue, price, decomposed };
|
|
89
|
+
const amountContext = vault.toAmountContext(poolInfos);
|
|
90
|
+
const valueContext = amountContext.toValueContext(prices);
|
|
91
|
+
const totalValue = valueContext.totalValue;
|
|
92
|
+
const price = vault.totalSupply === 0n ? 0n : (totalValue / vault.totalSupply);
|
|
93
|
+
return { totalValue, price, amountContext };
|
|
126
94
|
}
|
|
127
95
|
function calculateVaultPrices(vaultPositions, poolInfos, assetPrices) {
|
|
128
96
|
const vaultPrices = {};
|
|
@@ -136,11 +104,11 @@ function calculateVaultPrices(vaultPositions, poolInfos, assetPrices) {
|
|
|
136
104
|
try {
|
|
137
105
|
const requiredAssets = new Set();
|
|
138
106
|
for (const assetAddress of Object.keys(vault.assets)) {
|
|
139
|
-
if (vault.assets[assetAddress] > 0n) {
|
|
107
|
+
if (vault.assets[assetAddress].supply > 0n) {
|
|
140
108
|
requiredAssets.add(assetAddress);
|
|
141
109
|
}
|
|
142
110
|
}
|
|
143
|
-
for (const poolPositions of Object.values(vault.
|
|
111
|
+
for (const poolPositions of Object.values(vault.pools)) {
|
|
144
112
|
for (const [assetAddress, position] of Object.entries(poolPositions)) {
|
|
145
113
|
if (position.supply > 0n || position.borrow > 0n) {
|
|
146
114
|
requiredAssets.add(assetAddress);
|
|
@@ -157,18 +125,15 @@ function calculateVaultPrices(vaultPositions, poolInfos, assetPrices) {
|
|
|
157
125
|
if (!allPricesAvailable)
|
|
158
126
|
continue;
|
|
159
127
|
const result = computeVaultValue(vault, poolInfos, combinedPrices);
|
|
160
|
-
|
|
128
|
+
const vaultPriceEntry = {
|
|
161
129
|
type: types_1.CompositeAssetType.VAULT,
|
|
162
130
|
price: result.price,
|
|
163
131
|
additionalData: {
|
|
164
|
-
|
|
165
|
-
totalSupply: vault.totalSupply,
|
|
132
|
+
amountContext: result.amountContext,
|
|
166
133
|
},
|
|
167
134
|
};
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
price: result.price,
|
|
171
|
-
};
|
|
135
|
+
vaultPrices[vaultAddress] = vaultPriceEntry;
|
|
136
|
+
combinedPrices[vaultAddress] = vaultPriceEntry;
|
|
172
137
|
delete pendingVaults[vaultAddress];
|
|
173
138
|
resolved = true;
|
|
174
139
|
}
|
|
@@ -182,8 +147,7 @@ function calculateVaultPrices(vaultPositions, poolInfos, assetPrices) {
|
|
|
182
147
|
type: types_1.CompositeAssetType.VAULT,
|
|
183
148
|
price: 0n,
|
|
184
149
|
additionalData: {
|
|
185
|
-
|
|
186
|
-
totalSupply: pendingVaults[vaultAddress].totalSupply,
|
|
150
|
+
amountContext: new transform_1.VaultAmountContext(vaultAddress, pendingVaults[vaultAddress].totalSupply, {}, {}),
|
|
187
151
|
},
|
|
188
152
|
};
|
|
189
153
|
delete pendingVaults[vaultAddress];
|
|
@@ -192,12 +156,58 @@ function calculateVaultPrices(vaultPositions, poolInfos, assetPrices) {
|
|
|
192
156
|
}
|
|
193
157
|
return vaultPrices;
|
|
194
158
|
}
|
|
159
|
+
function nativeDecomposeContext(amountContext, prices) {
|
|
160
|
+
const nativeDecomposed = {};
|
|
161
|
+
Object.entries(amountContext)
|
|
162
|
+
.forEach(([asset, position]) => {
|
|
163
|
+
const price = prices[asset];
|
|
164
|
+
if (price.type === types_1.CompositeAssetType.NATIVE) {
|
|
165
|
+
nativeDecomposed[asset] = position.addPosition(nativeDecomposed[asset]);
|
|
166
|
+
}
|
|
167
|
+
else if (price.type === types_1.CompositeAssetType.SYNTHETIC1) {
|
|
168
|
+
if (prices[price.additionalData.underlying].type !== types_1.CompositeAssetType.NATIVE)
|
|
169
|
+
throw new Error(`Invalid underlying asset type: ${price.additionalData.underlying}`);
|
|
170
|
+
const underlyingNativeDecomposed = nativeDecomposeContext({ [price.additionalData.underlying]: position.muldiv(price.additionalData.reserve, price.additionalData.totalSupply) }, prices);
|
|
171
|
+
(0, helper_1.applyPositions)(nativeDecomposed, underlyingNativeDecomposed);
|
|
172
|
+
}
|
|
173
|
+
else if (price.type === types_1.CompositeAssetType.SYNTHETIC2) {
|
|
174
|
+
if (prices[price.additionalData0.underlying].type !== types_1.CompositeAssetType.NATIVE)
|
|
175
|
+
throw new Error(`Invalid underlying asset type: ${price.additionalData0.underlying}`);
|
|
176
|
+
if (prices[price.additionalData1.underlying].type !== types_1.CompositeAssetType.NATIVE)
|
|
177
|
+
throw new Error(`Invalid underlying asset type: ${price.additionalData1.underlying}`);
|
|
178
|
+
const price0 = prices[price.additionalData0.underlying].price;
|
|
179
|
+
const price1 = prices[price.additionalData1.underlying].price;
|
|
180
|
+
const value0 = price.additionalData0.reserve * price0;
|
|
181
|
+
const value1 = price.additionalData1.reserve * price1;
|
|
182
|
+
const totalValue = value0 + value1;
|
|
183
|
+
const underlyingNativeDecomposed = nativeDecomposeContext({
|
|
184
|
+
[price.additionalData0.underlying]: position.muldiv(value0, totalValue),
|
|
185
|
+
[price.additionalData1.underlying]: position.muldiv(value1, totalValue)
|
|
186
|
+
}, prices);
|
|
187
|
+
(0, helper_1.applyPositions)(nativeDecomposed, underlyingNativeDecomposed);
|
|
188
|
+
}
|
|
189
|
+
else if (price.type === types_1.CompositeAssetType.VAULT) {
|
|
190
|
+
const depVaultValue = price.price * price.additionalData.amountContext.totalSupply;
|
|
191
|
+
const depDecomposed = {};
|
|
192
|
+
Object.entries(price.additionalData.amountContext.decompose())
|
|
193
|
+
.forEach(([depAsset, depPosition]) => {
|
|
194
|
+
depDecomposed[depAsset] = position.cross(depPosition.toValuePosition(prices[depAsset].price), depVaultValue);
|
|
195
|
+
});
|
|
196
|
+
const depNativeDecomposed = nativeDecomposeContext(depDecomposed, prices);
|
|
197
|
+
(0, helper_1.applyPositions)(nativeDecomposed, depNativeDecomposed);
|
|
198
|
+
}
|
|
199
|
+
else {
|
|
200
|
+
throw new Error(`Invalid asset type: ${price}`);
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
return nativeDecomposed;
|
|
204
|
+
}
|
|
195
205
|
function computeCompositePrices(input) {
|
|
196
206
|
const assetPrices = calculateSyntheticPrices(input.rawPrices, input.syntheticCompositions);
|
|
197
207
|
const vaultPrices = calculateVaultPrices(input.vaultPositions, input.poolInfos, assetPrices);
|
|
198
208
|
const allPrices = { ...assetPrices };
|
|
199
209
|
for (const [address, entry] of Object.entries(vaultPrices)) {
|
|
200
|
-
allPrices[address] =
|
|
210
|
+
allPrices[address] = entry;
|
|
201
211
|
}
|
|
202
212
|
return { assetPrices, vaultPrices, allPrices };
|
|
203
213
|
}
|
|
@@ -206,10 +216,10 @@ function getExposures(vaultPositions) {
|
|
|
206
216
|
const pools = new Set();
|
|
207
217
|
for (const vault of Object.values(vaultPositions)) {
|
|
208
218
|
for (const [asset, amount] of Object.entries(vault.assets)) {
|
|
209
|
-
if (amount > 0n)
|
|
219
|
+
if (amount.supply > 0n)
|
|
210
220
|
assets.add(asset);
|
|
211
221
|
}
|
|
212
|
-
for (const [poolAddress, poolPositions] of Object.entries(vault.
|
|
222
|
+
for (const [poolAddress, poolPositions] of Object.entries(vault.pools)) {
|
|
213
223
|
for (const [asset, position] of Object.entries(poolPositions)) {
|
|
214
224
|
if (position.supply > 0n || position.borrow > 0n) {
|
|
215
225
|
pools.add(poolAddress);
|
|
@@ -287,9 +297,42 @@ function buildOracleParamsCellFromPayload(assets, oracleConfig, payload, pools,
|
|
|
287
297
|
*/
|
|
288
298
|
async function buildOracleParamsCell(assets, oracleConfig, pools, vaults) {
|
|
289
299
|
const requestParams = redstone_onchain_oracle_1.RedstoneOnchainOracle.getOracleRequestParams(assets, oracleConfig);
|
|
290
|
-
|
|
291
|
-
|
|
300
|
+
const signers = new Set(oracleConfig.signers
|
|
301
|
+
.map((s) => s.toLowerCase()));
|
|
302
|
+
let helper;
|
|
303
|
+
if (setEqual(signers, restonSigners)) {
|
|
304
|
+
helper = (0, redstoneHelper_1.createRedstoneHelper)("prod");
|
|
305
|
+
}
|
|
306
|
+
else if (setEqual(signers, affluentSigners)) {
|
|
307
|
+
helper = (0, redstoneHelper_1.createRedstoneCustomHelper)("http://aggregatora3loa-ktesxzhb-780180176.ap-northeast-2.elb.amazonaws.com");
|
|
308
|
+
}
|
|
309
|
+
else {
|
|
310
|
+
throw new Error(`Invalid signers: ${[...signers]}`);
|
|
311
|
+
}
|
|
312
|
+
// Fetch payload
|
|
292
313
|
const payload = await helper.createPayload(requestParams.redstoneAssetNames);
|
|
293
314
|
// Pure computation
|
|
294
315
|
return buildOracleParamsCellFromPayload(assets, oracleConfig, payload, pools, vaults);
|
|
295
316
|
}
|
|
317
|
+
const restonSigners = new Set([
|
|
318
|
+
'51Ce04Be4b3E32572C4Ec9135221d0691Ba7d202',
|
|
319
|
+
'8BB8F32Df04c8b654987DAaeD53D6B6091e3B774',
|
|
320
|
+
'9c5AE89C4Af6aA32cE58588DBaF90d18a855B6de',
|
|
321
|
+
'DD682daEC5A90dD295d14DA4b0bec9281017b5bE',
|
|
322
|
+
'dEB22f54738d54976C4c0fe5ce6d408E40d88499'
|
|
323
|
+
].map((s) => s.toLowerCase()));
|
|
324
|
+
const affluentSigners = new Set([
|
|
325
|
+
"938b33477fdcebcb1ca4dd9502af775a0c4f2e2c",
|
|
326
|
+
"7d8d5e5be15338797183652d401f290c21d08e73",
|
|
327
|
+
"95abc793f212a11330ddafd337edb8b1903f62f5",
|
|
328
|
+
"4d0a8877125e889004facfdef35fc256548ce038",
|
|
329
|
+
"fb023d5b920b1c13be0c4cdde27e7b75ef67c627",
|
|
330
|
+
].map((s) => s.toLowerCase()));
|
|
331
|
+
function setEqual(a, b) {
|
|
332
|
+
if (a.size !== b.size)
|
|
333
|
+
return false;
|
|
334
|
+
for (const v of a)
|
|
335
|
+
if (!b.has(v))
|
|
336
|
+
return false;
|
|
337
|
+
return true;
|
|
338
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { AddressLike } from "../../contracts/common/type";
|
|
2
2
|
import { StrategyVaultState } from "../../contracts/vault/strategy-vault";
|
|
3
|
-
import { Prices, CompositeOracleResult, CompositeOracleInput } from "
|
|
3
|
+
import { Prices, CompositeOracleResult, CompositeOracleInput } from "../../common/types";
|
|
4
4
|
import { CompositeOracleFetcher } from "./query";
|
|
5
|
-
export * from "
|
|
5
|
+
export * from "../../common/types";
|
|
6
6
|
export * from "./computation";
|
|
7
7
|
export { CompositeOracleFetcher, OracleContext } from "./query";
|
|
8
8
|
export declare class CompositeOracleV1 extends CompositeOracleFetcher {
|
|
@@ -16,10 +16,9 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
exports.CompositeOracleV1 = exports.CompositeOracleFetcher = void 0;
|
|
18
18
|
const utils_1 = require("../../contracts/common/utils");
|
|
19
|
-
const types_1 = require("./types");
|
|
20
19
|
const computation_1 = require("./computation");
|
|
21
20
|
const query_1 = require("./query");
|
|
22
|
-
__exportStar(require("
|
|
21
|
+
__exportStar(require("../../common/types"), exports);
|
|
23
22
|
__exportStar(require("./computation"), exports);
|
|
24
23
|
var query_2 = require("./query");
|
|
25
24
|
Object.defineProperty(exports, "CompositeOracleFetcher", { enumerable: true, get: function () { return query_2.CompositeOracleFetcher; } });
|
|
@@ -83,10 +82,10 @@ class CompositeOracleV1 extends query_1.CompositeOracleFetcher {
|
|
|
83
82
|
const result = this.compute(input);
|
|
84
83
|
const targetVaultAddress = (0, utils_1.toAddress)(vaultAddress).toString();
|
|
85
84
|
const vaultPriceEntry = result.vaultPrices[targetVaultAddress];
|
|
86
|
-
if (!vaultPriceEntry || vaultPriceEntry.additionalData.totalSupply === 0n) {
|
|
85
|
+
if (!vaultPriceEntry || vaultPriceEntry.additionalData.amountContext.totalSupply === 0n) {
|
|
87
86
|
return 0n;
|
|
88
87
|
}
|
|
89
|
-
return
|
|
88
|
+
return vaultPriceEntry.price * vaultPriceEntry.additionalData.amountContext.totalSupply;
|
|
90
89
|
}
|
|
91
90
|
// ============================================================
|
|
92
91
|
// Static computation methods (no instance needed)
|
|
@@ -101,10 +100,10 @@ class CompositeOracleV1 extends query_1.CompositeOracleFetcher {
|
|
|
101
100
|
static getTotalValueFromInput(input, vaultAddress) {
|
|
102
101
|
const result = (0, computation_1.computeCompositePrices)(input);
|
|
103
102
|
const vaultPriceEntry = result.vaultPrices[vaultAddress];
|
|
104
|
-
if (!vaultPriceEntry || vaultPriceEntry.additionalData.totalSupply === 0n) {
|
|
103
|
+
if (!vaultPriceEntry || vaultPriceEntry.additionalData.amountContext.totalSupply === 0n) {
|
|
105
104
|
return 0n;
|
|
106
105
|
}
|
|
107
|
-
return
|
|
106
|
+
return vaultPriceEntry.price * vaultPriceEntry.additionalData.amountContext.totalSupply;
|
|
108
107
|
}
|
|
109
108
|
}
|
|
110
109
|
exports.CompositeOracleV1 = CompositeOracleV1;
|
|
@@ -3,13 +3,13 @@ import { AffluentContext } from "../../context";
|
|
|
3
3
|
import { AddressLike } from "../../contracts/common/type";
|
|
4
4
|
import { OnchainDataInfo } from "../../contracts/oracle/redstone-onchain-oracle/type";
|
|
5
5
|
import { StrategyVaultState } from "../../contracts/vault/strategy-vault";
|
|
6
|
-
import { Prices,
|
|
6
|
+
import { Prices, SyntheticCompositions, IVaultStateContext, IPoolContext } from "../../common/types";
|
|
7
7
|
export type OracleContext = {
|
|
8
8
|
vaultData: StrategyVaultState;
|
|
9
9
|
oracleConfig: any;
|
|
10
10
|
assets: string[];
|
|
11
11
|
vaultAssets: string[];
|
|
12
|
-
vaultPositions:
|
|
12
|
+
vaultPositions: Record<string, IVaultStateContext>;
|
|
13
13
|
exposures: {
|
|
14
14
|
assets: string[];
|
|
15
15
|
pools: string[];
|
|
@@ -28,9 +28,9 @@ export declare class CompositeOracleFetcher {
|
|
|
28
28
|
}): Promise<OracleContext>;
|
|
29
29
|
fetchRawPrices(assets: string[], oracleConfig: any): Promise<{
|
|
30
30
|
rawPrices: Prices;
|
|
31
|
-
onchainData:
|
|
31
|
+
onchainData: SyntheticCompositions;
|
|
32
32
|
}>;
|
|
33
|
-
fetchOnchainData(onchainDataInfo: OnchainDataInfo): Promise<
|
|
34
|
-
fetchVaultPositions(vaultAddresses: (Address | string)[]): Promise<
|
|
35
|
-
fetchPoolInfos(poolAddresses: string[]): Promise<
|
|
33
|
+
fetchOnchainData(onchainDataInfo: OnchainDataInfo): Promise<SyntheticCompositions>;
|
|
34
|
+
fetchVaultPositions(vaultAddresses: (Address | string)[]): Promise<Record<string, IVaultStateContext>>;
|
|
35
|
+
fetchPoolInfos(poolAddresses: string[]): Promise<Record<string, IPoolContext>>;
|
|
36
36
|
}
|
|
@@ -7,12 +7,12 @@ const utils_1 = require("../../contracts/common/utils");
|
|
|
7
7
|
const pool_1 = require("../../contracts/core/pool");
|
|
8
8
|
const redstone_onchain_oracle_1 = require("../../contracts/oracle/redstone-onchain-oracle");
|
|
9
9
|
const type_1 = require("../../contracts/oracle/redstone-onchain-oracle/type");
|
|
10
|
-
const share_vault_1 = require("../../contracts/vault/share-vault");
|
|
11
10
|
const strategy_vault_1 = require("../../contracts/vault/strategy-vault");
|
|
12
11
|
const readonlyCachedRedstone_1 = require("../../utils/oracle/redstone/readonlyCachedRedstone");
|
|
13
12
|
const unknown_contract_1 = require("../../contracts/unknown-contract");
|
|
14
|
-
const types_1 = require("
|
|
13
|
+
const types_1 = require("../../common/types");
|
|
15
14
|
const computation_1 = require("./computation");
|
|
15
|
+
const transform_1 = require("../../common/transform");
|
|
16
16
|
// ============================================================
|
|
17
17
|
// Query Class (I/O - fetching data)
|
|
18
18
|
// ============================================================
|
|
@@ -59,8 +59,8 @@ class CompositeOracleFetcher {
|
|
|
59
59
|
if (rainfo.assetType === 0) {
|
|
60
60
|
rawPrices[rainfo.address.toString()] = {
|
|
61
61
|
type: types_1.CompositeAssetType.NATIVE,
|
|
62
|
+
price: (item.price * types_1.VALUE_SCALE) / rainfo.precision,
|
|
62
63
|
timestamp: item.timestamp,
|
|
63
|
-
price: (item.price * types_1.DECIMALS_OF_PRICE) / rainfo.precision,
|
|
64
64
|
};
|
|
65
65
|
}
|
|
66
66
|
else if (rainfo.assetType === 1) {
|
|
@@ -180,14 +180,12 @@ class CompositeOracleFetcher {
|
|
|
180
180
|
if (state.state.type === "active" && state.state.data) {
|
|
181
181
|
const data = core_1.Cell.fromBoc(state.state.data)[0];
|
|
182
182
|
try {
|
|
183
|
-
|
|
184
|
-
positions[addressStr] = extractStrategyVaultPosition(vaultData);
|
|
183
|
+
positions[addressStr] = transform_1.VaultStateContext.fromStrategyVaultStateCell((0, utils_1.toAddress)(vaultAddress), data);
|
|
185
184
|
return;
|
|
186
185
|
}
|
|
187
186
|
catch (e) { }
|
|
188
187
|
try {
|
|
189
|
-
|
|
190
|
-
positions[addressStr] = extractShareVaultPosition(vaultData);
|
|
188
|
+
positions[addressStr] = transform_1.VaultStateContext.fromShareVaultStateCell((0, utils_1.toAddress)(vaultAddress), data);
|
|
191
189
|
}
|
|
192
190
|
catch (e) { }
|
|
193
191
|
}
|
|
@@ -202,15 +200,7 @@ class CompositeOracleFetcher {
|
|
|
202
200
|
try {
|
|
203
201
|
const pool = this.ctx.getByContract(pool_1.Pool, (0, utils_1.toAddress)(poolAddress));
|
|
204
202
|
const poolData = await pool.getPoolData();
|
|
205
|
-
poolInfos[poolAddress] =
|
|
206
|
-
for (const [asset, assetData] of Object.entries(poolData.assets)) {
|
|
207
|
-
poolInfos[poolAddress][asset] = {
|
|
208
|
-
totalSupplyAmount: assetData.totalSupplyAmount,
|
|
209
|
-
totalSupplyShare: assetData.totalSupplyShare,
|
|
210
|
-
totalBorrowAmount: assetData.totalBorrowAmount,
|
|
211
|
-
totalBorrowShare: assetData.totalBorrowShare,
|
|
212
|
-
};
|
|
213
|
-
}
|
|
203
|
+
poolInfos[poolAddress] = transform_1.PoolContext.fromPoolState(poolData);
|
|
214
204
|
}
|
|
215
205
|
catch (e) { }
|
|
216
206
|
}));
|
|
@@ -218,34 +208,3 @@ class CompositeOracleFetcher {
|
|
|
218
208
|
}
|
|
219
209
|
}
|
|
220
210
|
exports.CompositeOracleFetcher = CompositeOracleFetcher;
|
|
221
|
-
// ============================================================
|
|
222
|
-
// Helper Functions
|
|
223
|
-
// ============================================================
|
|
224
|
-
function extractStrategyVaultPosition(vaultData) {
|
|
225
|
-
const assets = {};
|
|
226
|
-
const poolPositions = {};
|
|
227
|
-
for (const [asset, assetData] of Object.entries(vaultData.assets)) {
|
|
228
|
-
assets[asset] = assetData.cash;
|
|
229
|
-
}
|
|
230
|
-
for (const [pool, poolAssets] of Object.entries(vaultData.factorialPools)) {
|
|
231
|
-
poolPositions[pool] = {};
|
|
232
|
-
for (const [asset, position] of Object.entries(poolAssets)) {
|
|
233
|
-
poolPositions[pool][asset] = { supply: position.supply, borrow: position.borrow };
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
return { assets, poolPositions, totalSupply: vaultData.totalSupply };
|
|
237
|
-
}
|
|
238
|
-
function extractShareVaultPosition(vaultData) {
|
|
239
|
-
const asset = vaultData.asset.toString();
|
|
240
|
-
const poolPositions = {};
|
|
241
|
-
for (const pool of Object.values(vaultData.whitelistedPools)) {
|
|
242
|
-
poolPositions[pool.address.toString()] = {
|
|
243
|
-
[asset]: { supply: pool.supply, borrow: 0n },
|
|
244
|
-
};
|
|
245
|
-
}
|
|
246
|
-
return {
|
|
247
|
-
assets: { [asset]: vaultData.cash },
|
|
248
|
-
poolPositions,
|
|
249
|
-
totalSupply: vaultData.totalSupply,
|
|
250
|
-
};
|
|
251
|
-
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { PoolState } from "../../contracts/core/pool/type";
|
|
2
2
|
import { AccountState, AccountAssetState } from "../../contracts/core/account/type";
|
|
3
|
-
import { Prices, VaultCompositions, SyntheticCompositions } from "
|
|
3
|
+
import { Prices, VaultCompositions, SyntheticCompositions, IAmountPosition } from "../../common/types";
|
|
4
4
|
export type HealthResult = {
|
|
5
5
|
result: boolean;
|
|
6
6
|
healthy: boolean;
|
|
@@ -25,11 +25,6 @@ export type MaxWithdrawableResult = {
|
|
|
25
25
|
beforeAccountHealth?: HealthResult;
|
|
26
26
|
afterAccountHealth?: HealthResult;
|
|
27
27
|
};
|
|
28
|
-
type Position = {
|
|
29
|
-
supply: bigint;
|
|
30
|
-
borrow: bigint;
|
|
31
|
-
};
|
|
32
|
-
type PositionMap = Record<string, Position>;
|
|
33
28
|
/**
|
|
34
29
|
* Simulate interest accrual on pool data
|
|
35
30
|
*/
|
|
@@ -57,9 +52,9 @@ export declare function applyDelta(accountData: AccountState, delta: Record<stri
|
|
|
57
52
|
* - SYNTHETIC2: LP-TON-USDT(100) → TON(50) + USDT(50)
|
|
58
53
|
* - VAULT: StrategyVault(100) → TON(30) + USDT(70)
|
|
59
54
|
*
|
|
60
|
-
*
|
|
55
|
+
* Same native asset from multiple paths will be accumulated
|
|
61
56
|
*/
|
|
62
|
-
export declare function decomposePositions(positions: Record<string, AccountAssetState>, syntheticCompositions: SyntheticCompositions, vaultCompositions?: VaultCompositions):
|
|
57
|
+
export declare function decomposePositions(positions: Record<string, AccountAssetState>, syntheticCompositions: SyntheticCompositions, vaultCompositions?: VaultCompositions): Record<string, IAmountPosition>;
|
|
63
58
|
/** @deprecated Use decomposePositions instead */
|
|
64
59
|
export declare const decomposeAccountStatus: typeof decomposePositions;
|
|
65
60
|
/**
|
|
@@ -72,4 +67,3 @@ export declare function calculateRisk(decomposedAccountStatus: Record<string, Om
|
|
|
72
67
|
* Takes pre-fetched pool data, account status, and prices
|
|
73
68
|
*/
|
|
74
69
|
export declare function isHealthyFromData(poolData: PoolState, accountStatus: Record<string, AccountAssetState>, prices: Prices, syntheticCompositions: SyntheticCompositions, vaultCompositions?: VaultCompositions): HealthResult;
|
|
75
|
-
export {};
|
|
@@ -9,68 +9,12 @@ exports.applyDelta = applyDelta;
|
|
|
9
9
|
exports.decomposePositions = decomposePositions;
|
|
10
10
|
exports.calculateRisk = calculateRisk;
|
|
11
11
|
exports.isHealthyFromData = isHealthyFromData;
|
|
12
|
-
const core_1 = require("@ton/core");
|
|
13
12
|
const pool_1 = require("../../contracts/core/pool");
|
|
14
13
|
const account_1 = require("../../contracts/core/account");
|
|
15
|
-
const types_1 = require("
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
// ============================================================
|
|
20
|
-
/**
|
|
21
|
-
* Try to decompose a synthetic/vault asset to its underlying assets
|
|
22
|
-
* Returns null if asset is native (no decomposition needed)
|
|
23
|
-
*/
|
|
24
|
-
function tryDecomposeAsset(asset, position, syntheticCompositions, vaultCompositions) {
|
|
25
|
-
const data = syntheticCompositions[asset];
|
|
26
|
-
// SYNTHETIC1: stTON, tsTON 같은 단일 underlying asset
|
|
27
|
-
if (data?.assetType === types_1.CompositeAssetType.SYNTHETIC1 &&
|
|
28
|
-
"underlyingReserve" in data &&
|
|
29
|
-
data.underlyingReserve &&
|
|
30
|
-
data.totalSupply) {
|
|
31
|
-
const ratio = data.underlyingReserve;
|
|
32
|
-
const total = data.totalSupply;
|
|
33
|
-
return [
|
|
34
|
-
{
|
|
35
|
-
address: (0, utils_1.toAddress)(data.underlyingAddress),
|
|
36
|
-
supply: (position.supply * ratio) / total,
|
|
37
|
-
borrow: (position.borrow * ratio) / total,
|
|
38
|
-
},
|
|
39
|
-
];
|
|
40
|
-
}
|
|
41
|
-
// SYNTHETIC2: LP 토큰 같은 2개 underlying assets
|
|
42
|
-
if (data?.assetType === types_1.CompositeAssetType.SYNTHETIC2 &&
|
|
43
|
-
"underlying0Reserve" in data &&
|
|
44
|
-
data.underlying0Reserve &&
|
|
45
|
-
data.underlying1Reserve &&
|
|
46
|
-
data.totalSupply) {
|
|
47
|
-
const total = data.totalSupply;
|
|
48
|
-
return [
|
|
49
|
-
{
|
|
50
|
-
address: (0, utils_1.toAddress)(data.underlying0Address),
|
|
51
|
-
supply: (position.supply * data.underlying0Reserve) / total,
|
|
52
|
-
borrow: (position.borrow * data.underlying0Reserve) / total,
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
address: (0, utils_1.toAddress)(data.underlying1Address),
|
|
56
|
-
supply: (position.supply * data.underlying1Reserve) / total,
|
|
57
|
-
borrow: (position.borrow * data.underlying1Reserve) / total,
|
|
58
|
-
},
|
|
59
|
-
];
|
|
60
|
-
}
|
|
61
|
-
// VAULT: Strategy Vault - decomposed positions 사용
|
|
62
|
-
const vault = vaultCompositions[asset];
|
|
63
|
-
if (vault) {
|
|
64
|
-
const { decomposed, totalSupply } = vault;
|
|
65
|
-
return Object.entries(decomposed).map(([addr, pos]) => ({
|
|
66
|
-
address: core_1.Address.parse(addr),
|
|
67
|
-
// Vault는 supply/borrow가 교차됨
|
|
68
|
-
supply: (position.supply * pos.supply + position.borrow * pos.borrow) / totalSupply,
|
|
69
|
-
borrow: (position.supply * pos.borrow + position.borrow * pos.supply) / totalSupply,
|
|
70
|
-
}));
|
|
71
|
-
}
|
|
72
|
-
return null; // Native asset
|
|
73
|
-
}
|
|
14
|
+
const types_1 = require("../../common/types");
|
|
15
|
+
const transform_1 = require("../../common/transform");
|
|
16
|
+
const computation_1 = require("../../common/computation");
|
|
17
|
+
const helper_1 = require("../../common/helper");
|
|
74
18
|
// ============================================================
|
|
75
19
|
// Pure Computation (no I/O)
|
|
76
20
|
// ============================================================
|
|
@@ -111,26 +55,16 @@ function applyDelta(accountData, delta) {
|
|
|
111
55
|
* - SYNTHETIC2: LP-TON-USDT(100) → TON(50) + USDT(50)
|
|
112
56
|
* - VAULT: StrategyVault(100) → TON(30) + USDT(70)
|
|
113
57
|
*
|
|
114
|
-
*
|
|
58
|
+
* Same native asset from multiple paths will be accumulated
|
|
115
59
|
*/
|
|
116
60
|
function decomposePositions(positions, syntheticCompositions, vaultCompositions = {}) {
|
|
117
61
|
const accumulatedPositions = {};
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
const
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
const asset = current.address.toString();
|
|
125
|
-
accumulatedPositions[asset] ??= { supply: 0n, borrow: 0n };
|
|
126
|
-
accumulatedPositions[asset].supply += current.supply;
|
|
127
|
-
accumulatedPositions[asset].borrow += current.borrow;
|
|
128
|
-
// decompose 가능하면 underlying도 queue에 추가
|
|
129
|
-
const decomposed = tryDecomposeAsset(asset, current, syntheticCompositions, vaultCompositions);
|
|
130
|
-
if (decomposed) {
|
|
131
|
-
queue.push(...decomposed);
|
|
132
|
-
}
|
|
133
|
-
}
|
|
62
|
+
Object.values(positions)
|
|
63
|
+
.forEach(position => {
|
|
64
|
+
const asset = position.address.toString();
|
|
65
|
+
const decomposed = (0, computation_1.tryNativeDecomposeAsset)(asset, new transform_1.AmountPosition(position.supply, position.borrow), syntheticCompositions, vaultCompositions);
|
|
66
|
+
(0, helper_1.applyPositions)(accumulatedPositions, decomposed);
|
|
67
|
+
});
|
|
134
68
|
return accumulatedPositions;
|
|
135
69
|
}
|
|
136
70
|
/** @deprecated Use decomposePositions instead */
|
|
@@ -213,7 +147,7 @@ function calculateRisk(decomposedAccountStatus, prices, poolData) {
|
|
|
213
147
|
* Takes pre-fetched pool data, account status, and prices
|
|
214
148
|
*/
|
|
215
149
|
function isHealthyFromData(poolData, accountStatus, prices, syntheticCompositions, vaultCompositions = {}) {
|
|
216
|
-
const simulatedPoolData = simulateAccrueInterest(poolData);
|
|
217
150
|
const decomposed = decomposePositions(accountStatus, syntheticCompositions, vaultCompositions);
|
|
151
|
+
const simulatedPoolData = simulateAccrueInterest(poolData);
|
|
218
152
|
return calculateRisk(decomposed, prices, simulatedPoolData);
|
|
219
153
|
}
|