@gearbox-protocol/sdk 16.0.0-next.51 → 16.0.0-next.52
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/cjs/model/index.js +1 -0
- package/dist/cjs/model/result.js +10 -0
- package/dist/cjs/onchain/accounts/intents/leverage-band.js +1 -1
- package/dist/cjs/onchain/accounts/intents/maxWithdrawCollateral.js +8 -19
- package/dist/cjs/onchain/accounts/intents/open-strategy.js +1 -1
- package/dist/cjs/onchain/accounts/intents/realize.js +1 -1
- package/dist/cjs/onchain/accounts/intents/testing/market.js +6 -5
- package/dist/cjs/onchain/accounts/intents/testing/sdk-mock.js +21 -74
- package/dist/cjs/onchain/accounts/intents/utils/pick-token.js +1 -1
- package/dist/cjs/onchain/accounts/intents/utils/price-impact.js +2 -2
- package/dist/cjs/onchain/accounts/intents/utils/router-path.js +1 -1
- package/dist/cjs/onchain/accounts/intents/view.js +1 -1
- package/dist/cjs/onchain/accounts/liquidations/LiquidationsService.js +3 -3
- package/dist/cjs/onchain/index.js +1 -1
- package/dist/cjs/onchain/market/MarketSuite.js +0 -28
- package/dist/cjs/onchain/market/credit/collateralUtils.js +2 -2
- package/dist/cjs/onchain/market/index.js +1 -1
- package/dist/cjs/onchain/market/oracle/PriceOracleBaseContract.js +66 -13
- package/dist/cjs/onchain/market/oracle/TestPriceOracle.mock.js +215 -0
- package/dist/cjs/onchain/market/oracle/index.js +1 -1
- package/dist/cjs/onchain/positions/PositionsService.js +5 -7
- package/dist/cjs/onchain/positions/calcHealthFactor.js +4 -3
- package/dist/cjs/onchain/router/AbstractRouterContract.js +2 -24
- package/dist/cjs/onchain/router/RouterV310Contract.js +1 -12
- package/dist/cjs/preview/preview/buildDelayedStrategyPositionOperationPreview.js +26 -38
- package/dist/cjs/preview/preview/previewAdjustStrategyPosition.js +2 -3
- package/dist/cjs/preview/preview/previewExitOrRepayStrategyPosition.js +4 -5
- package/dist/cjs/preview/preview/previewOpenStrategyPosition.js +3 -7
- package/dist/cjs/preview/preview/previewOperation.js +1 -2
- package/dist/esm/model/index.js +2 -2
- package/dist/esm/model/result.js +10 -1
- package/dist/esm/onchain/accounts/intents/leverage-band.js +1 -1
- package/dist/esm/onchain/accounts/intents/maxWithdrawCollateral.js +8 -19
- package/dist/esm/onchain/accounts/intents/open-strategy.js +1 -1
- package/dist/esm/onchain/accounts/intents/realize.js +1 -1
- package/dist/esm/onchain/accounts/intents/testing/market.js +6 -5
- package/dist/esm/onchain/accounts/intents/testing/sdk-mock.js +22 -75
- package/dist/esm/onchain/accounts/intents/utils/pick-token.js +1 -1
- package/dist/esm/onchain/accounts/intents/utils/price-impact.js +2 -2
- package/dist/esm/onchain/accounts/intents/utils/router-path.js +1 -1
- package/dist/esm/onchain/accounts/intents/view.js +1 -1
- package/dist/esm/onchain/accounts/liquidations/LiquidationsService.js +3 -3
- package/dist/esm/onchain/index.js +1 -1
- package/dist/esm/onchain/market/MarketSuite.js +0 -28
- package/dist/esm/onchain/market/credit/collateralUtils.js +2 -2
- package/dist/esm/onchain/market/index.js +1 -1
- package/dist/esm/onchain/market/oracle/PriceOracleBaseContract.js +66 -13
- package/dist/esm/onchain/market/oracle/TestPriceOracle.mock.js +213 -0
- package/dist/esm/onchain/market/oracle/index.js +1 -1
- package/dist/esm/onchain/positions/PositionsService.js +5 -7
- package/dist/esm/onchain/positions/calcHealthFactor.js +4 -3
- package/dist/esm/onchain/router/AbstractRouterContract.js +2 -24
- package/dist/esm/onchain/router/RouterV310Contract.js +1 -12
- package/dist/esm/preview/preview/buildDelayedStrategyPositionOperationPreview.js +26 -38
- package/dist/esm/preview/preview/previewAdjustStrategyPosition.js +2 -3
- package/dist/esm/preview/preview/previewExitOrRepayStrategyPosition.js +4 -5
- package/dist/esm/preview/preview/previewOpenStrategyPosition.js +3 -7
- package/dist/esm/preview/preview/previewOperation.js +1 -2
- package/dist/types/model/index.d.ts +2 -2
- package/dist/types/model/previews.d.ts +4 -3
- package/dist/types/model/result.d.ts +16 -1
- package/dist/types/onchain/accounts/intents/maxWithdrawCollateral.d.ts +5 -3
- package/dist/types/onchain/accounts/intents/testing/market.d.ts +5 -1
- package/dist/types/onchain/accounts/intents/testing/sdk-mock.d.ts +1 -2
- package/dist/types/onchain/index.d.ts +2 -2
- package/dist/types/onchain/market/MarketSuite.d.ts +2 -29
- package/dist/types/onchain/market/index.d.ts +2 -2
- package/dist/types/onchain/market/oracle/PriceOracleBaseContract.d.ts +15 -5
- package/dist/types/onchain/market/oracle/types.d.ts +40 -28
- package/dist/types/onchain/positions/calcHealthFactor.d.ts +7 -3
- package/dist/types/onchain/router/AbstractRouterContract.d.ts +0 -4
- package/dist/types/preview/preview/buildDelayedStrategyPositionOperationPreview.d.ts +4 -6
- package/package.json +2 -10
|
@@ -11,9 +11,11 @@ import { eq } from "./utils/common.js";
|
|
|
11
11
|
* check counts: a holding backed by a quota contributes the lesser of the
|
|
12
12
|
* quota and its threshold-weighted value, an unquoted one — the underlying —
|
|
13
13
|
* its weighted value alone, and dust or a disabled balance nothing at all.
|
|
14
|
-
* Collateral is valued at the
|
|
15
|
-
*
|
|
16
|
-
*
|
|
14
|
+
* Collateral is valued at the protocol safe price (`min` of the two feeds,
|
|
15
|
+
* 0 when there is no reserve), the way the facade values a call that hands
|
|
16
|
+
* funds over; the underlying is exempt and is valued at the main feed, as
|
|
17
|
+
* `CreditManagerV3._safeConvertToUSD` does. The debt is valued at the main
|
|
18
|
+
* feed, as the check does. Zero debt frees the whole balance.
|
|
17
19
|
*
|
|
18
20
|
* Rounding always favours the account, so the answer clears the check rather
|
|
19
21
|
* than landing a wei short of it.
|
|
@@ -36,7 +38,7 @@ function maxWithdrawCollateral(props) {
|
|
|
36
38
|
/** What a holding backs, in the check's units: USD × PERCENTAGE_FACTOR. */
|
|
37
39
|
const weigh = (t) => {
|
|
38
40
|
const lt = BigInt(creditManager.liquidationThresholds.get(t.token) ?? 0);
|
|
39
|
-
const weighted = (
|
|
41
|
+
const weighted = (eq(t.token, underlying) ? usd(priceOracle, t.token, t.balance) ?? 0n : priceOracle.safeConvertMinUSD(t.token, t.balance).value) * lt;
|
|
40
42
|
if (t.quota === 0n) return weighted;
|
|
41
43
|
return BigIntMath.min(quotaUsd(t) * PERCENTAGE_FACTOR, weighted);
|
|
42
44
|
};
|
|
@@ -54,8 +56,8 @@ function maxWithdrawCollateral(props) {
|
|
|
54
56
|
const shortfall = required - otherMoney;
|
|
55
57
|
if (target.quota > 0n && quotaUsd(target) * 10000n < shortfall) return 0n;
|
|
56
58
|
const targetLt = BigInt(creditManager.liquidationThresholds.get(target.token) ?? 0);
|
|
57
|
-
const targetUsd =
|
|
58
|
-
if (targetLt === 0n ||
|
|
59
|
+
const targetUsd = eq(target.token, underlying) ? usd(priceOracle, target.token, target.balance) ?? 0n : priceOracle.safeConvertMinUSD(target.token, target.balance).value;
|
|
60
|
+
if (targetLt === 0n || targetUsd === 0n) return 0n;
|
|
59
61
|
const keptUsd = BigIntMath.ceilDiv(shortfall, targetLt);
|
|
60
62
|
const kept = BigIntMath.ceilDiv(target.balance * keptUsd, targetUsd);
|
|
61
63
|
return kept >= target.balance ? 0n : target.balance - kept;
|
|
@@ -68,18 +70,5 @@ function usd(oracle, token, amount) {
|
|
|
68
70
|
return;
|
|
69
71
|
}
|
|
70
72
|
}
|
|
71
|
-
/**
|
|
72
|
-
* USD value at the lower of the token's two feeds — what a call handing funds
|
|
73
|
-
* over is judged at. Falls back to the main feed where there is no second one.
|
|
74
|
-
**/
|
|
75
|
-
function safeUsd(oracle, token, amount) {
|
|
76
|
-
const main = usd(oracle, token, amount);
|
|
77
|
-
if (main === void 0) return;
|
|
78
|
-
try {
|
|
79
|
-
return BigIntMath.min(main, oracle.convertToUSD(token, amount, true));
|
|
80
|
-
} catch {
|
|
81
|
-
return main;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
73
|
//#endregion
|
|
85
74
|
export { maxWithdrawCollateral };
|
|
@@ -27,7 +27,7 @@ async function buildOpenStrategyState(props) {
|
|
|
27
27
|
const market = sdk.marketRegister.findByCreditManager(creditManager);
|
|
28
28
|
assertMarketOperable(suite);
|
|
29
29
|
const underlying = market.pool.underlying.toLowerCase();
|
|
30
|
-
const convert = (from, to, amount) => market.priceOracle.safeConvert(from, to, amount)
|
|
30
|
+
const convert = (from, to, amount) => market.priceOracle.safeConvert(from, to, amount).value;
|
|
31
31
|
const margin = collateral.reduce((acc, a) => acc + convert(a.token, underlying, a.balance), 0n);
|
|
32
32
|
if (margin <= 0n) throw new IntentPreviewError("insufficientSourceBalance", void 0, "openStrategy: collateral is worth nothing in underlying");
|
|
33
33
|
const debt = debtForLeverage(margin, leverage);
|
|
@@ -29,7 +29,7 @@ async function realize(steps, props) {
|
|
|
29
29
|
slippage
|
|
30
30
|
});
|
|
31
31
|
const market = sdk.marketRegister.findByCreditManager(creditAccount.creditManager);
|
|
32
|
-
const price = (from, to, amount) => market.priceOracle.safeConvert(from, to, amount)
|
|
32
|
+
const price = (from, to, amount) => market.priceOracle.safeConvert(from, to, amount).value;
|
|
33
33
|
const suite = sdk.marketRegister.findCreditManager(creditAccount.creditManager);
|
|
34
34
|
const start = {
|
|
35
35
|
initialAssets: creditAccount.tokens,
|
|
@@ -78,12 +78,13 @@ const LIQUIDATION_THRESHOLDS = {
|
|
|
78
78
|
const MAX_DEBT = toBN("200000", 8);
|
|
79
79
|
/** Mock SDK on the shared fixture market. */
|
|
80
80
|
function buildMarketSdk(extras) {
|
|
81
|
+
const prices = {
|
|
82
|
+
...PRICES,
|
|
83
|
+
...extras?.extraPrices
|
|
84
|
+
};
|
|
81
85
|
return buildMockSdk({
|
|
82
|
-
prices
|
|
83
|
-
|
|
84
|
-
...extras?.extraPrices
|
|
85
|
-
},
|
|
86
|
-
reservePrices: extras?.reservePrices,
|
|
86
|
+
prices,
|
|
87
|
+
reservePrices: extras?.reservePrices ?? prices,
|
|
87
88
|
decimals: {
|
|
88
89
|
...DECIMALS,
|
|
89
90
|
...extras?.extraDecimals
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import "../../../constants/math.js";
|
|
2
2
|
import "../../../constants/index.js";
|
|
3
|
-
import { calcMaxLeverage
|
|
3
|
+
import { calcMaxLeverage } from "../../../market/math.js";
|
|
4
4
|
import { CreditSuite } from "../../../market/credit/CreditSuite.js";
|
|
5
|
-
import { MarketSuite } from "../../../market/MarketSuite.js";
|
|
6
5
|
import { PositionsService } from "../../../positions/PositionsService.js";
|
|
6
|
+
import { TestPriceOracle } from "../../../market/oracle/TestPriceOracle.mock.js";
|
|
7
7
|
import { vi } from "vitest";
|
|
8
8
|
//#region src/onchain/accounts/intents/testing/sdk-mock.ts
|
|
9
9
|
/**
|
|
@@ -94,27 +94,25 @@ function echoEncodableOpCalls(op) {
|
|
|
94
94
|
/**
|
|
95
95
|
* Mock `OnchainSDK` covering exactly what the intent-service touches:
|
|
96
96
|
* price conversion, quota params, CM/facade lookup and call assembly.
|
|
97
|
-
* Conversion
|
|
98
|
-
* `amount * price[from] * 10^dec(to) / (price[to] * 10^dec(from))`.
|
|
97
|
+
* Conversion is a real {@link TestPriceOracle} seeded from the fixture records.
|
|
99
98
|
*/
|
|
100
99
|
function buildMockSdk(args) {
|
|
101
100
|
const decimalsOf = (token) => args.decimals[token.toLowerCase()] ?? 18;
|
|
102
|
-
const
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
} catch {
|
|
115
|
-
return null;
|
|
116
|
-
}
|
|
101
|
+
const lookup = (record, token) => record?.[token.toLowerCase()] ?? record?.[token];
|
|
102
|
+
const tokenCfgs = {};
|
|
103
|
+
for (const token of /* @__PURE__ */ new Set([
|
|
104
|
+
...Object.keys(args.decimals),
|
|
105
|
+
...Object.keys(args.prices),
|
|
106
|
+
...Object.keys(args.reservePrices ?? {})
|
|
107
|
+
])) tokenCfgs[token] = {
|
|
108
|
+
decimals: lookup(args.decimals, token) ?? 18,
|
|
109
|
+
symbol: "TOKEN",
|
|
110
|
+
name: "TOKEN",
|
|
111
|
+
price: lookup(args.prices, token),
|
|
112
|
+
reservePrice: lookup(args.reservePrices, token)
|
|
117
113
|
};
|
|
114
|
+
const priceOracle = new TestPriceOracle(tokenCfgs);
|
|
115
|
+
const convert = (from, to, amount) => priceOracle.convert(from, to, amount);
|
|
118
116
|
const fullQuota = (q) => ({
|
|
119
117
|
cumulativeIndexLU: 0n,
|
|
120
118
|
totalQuoted: 0n,
|
|
@@ -133,18 +131,6 @@ function buildMockSdk(args) {
|
|
|
133
131
|
entries: () => Object.entries(args.liquidationThresholds),
|
|
134
132
|
get: (token) => args.liquidationThresholds[token.toLowerCase()] ?? args.liquidationThresholds[token]
|
|
135
133
|
};
|
|
136
|
-
const _convertToUSD = (token, amount, reserve = false) => {
|
|
137
|
-
const key = token.toLowerCase();
|
|
138
|
-
const price = reserve ? args.reservePrices?.[key] : args.prices[key];
|
|
139
|
-
if (price === void 0) throw new Error(`mock priceOracle: missing ${reserve ? "reserve" : "main"} price for ${token}`);
|
|
140
|
-
return amount * price / 10n ** BigInt(decimalsOf(token));
|
|
141
|
-
};
|
|
142
|
-
const safeUsd = (token, amount) => {
|
|
143
|
-
const from = token.toLowerCase();
|
|
144
|
-
const price = args.prices[from] ?? args.prices[token];
|
|
145
|
-
if (price === void 0) return null;
|
|
146
|
-
return amount * price / 10n ** BigInt(decimalsOf(from));
|
|
147
|
-
};
|
|
148
134
|
const tokenOf = (token) => ({
|
|
149
135
|
chainId: 1,
|
|
150
136
|
address: token,
|
|
@@ -152,57 +138,19 @@ function buildMockSdk(args) {
|
|
|
152
138
|
name: "TOKEN",
|
|
153
139
|
decimals: decimalsOf(token)
|
|
154
140
|
});
|
|
155
|
-
const mainPriceOf = (token) => {
|
|
156
|
-
const key = token.toLowerCase();
|
|
157
|
-
const price = args.prices[key] ?? args.prices[token];
|
|
158
|
-
if (price === void 0) throw new Error(`mock priceOracle: missing main price for ${token}`);
|
|
159
|
-
return price;
|
|
160
|
-
};
|
|
161
|
-
const reservePriceOf = (token) => {
|
|
162
|
-
const key = token.toLowerCase();
|
|
163
|
-
const price = args.reservePrices?.[key] ?? args.reservePrices?.[token];
|
|
164
|
-
if (price === void 0) throw new Error(`mock priceOracle: missing reserve price for ${token}`);
|
|
165
|
-
return price;
|
|
166
|
-
};
|
|
167
141
|
const poolPaused = args.poolPaused ?? false;
|
|
168
142
|
/** {@inheritDoc MarketSuite.toUnderlyingAmount} */
|
|
169
|
-
const toUnderlyingAmount = (value) => {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
value,
|
|
174
|
-
valueUsd: usd === null ? null : usdToNumber(usd)
|
|
175
|
-
};
|
|
176
|
-
};
|
|
143
|
+
const toUnderlyingAmount = (value) => ({
|
|
144
|
+
token: tokenOf(args.rwaAssets?.[args.underlying.toLowerCase()] ?? args.underlying),
|
|
145
|
+
...priceOracle.toAmount(args.underlying, value)
|
|
146
|
+
});
|
|
177
147
|
const market = {
|
|
178
148
|
toUnderlyingAmount,
|
|
179
149
|
/** {@inheritDoc MarketSuite.curator} */
|
|
180
150
|
curator: MOCK_CURATOR,
|
|
181
151
|
/** {@inheritDoc MarketSuite.underlying} */
|
|
182
152
|
underlying: args.underlying,
|
|
183
|
-
priceOracle
|
|
184
|
-
convert,
|
|
185
|
-
safeConvert,
|
|
186
|
-
mainPrice: mainPriceOf,
|
|
187
|
-
reservePrice: reservePriceOf,
|
|
188
|
-
convertToUSD: _convertToUSD,
|
|
189
|
-
toAmount: (token, value) => {
|
|
190
|
-
const usd = safeUsd(token, value);
|
|
191
|
-
return {
|
|
192
|
-
value,
|
|
193
|
-
valueUsd: usd === null ? null : usdToNumber(usd)
|
|
194
|
-
};
|
|
195
|
-
},
|
|
196
|
-
toTokenAmount: (token, value) => {
|
|
197
|
-
const usd = safeUsd(token, value);
|
|
198
|
-
return {
|
|
199
|
-
token: tokenOf(token),
|
|
200
|
-
value,
|
|
201
|
-
valueUsd: usd === null ? null : usdToNumber(usd)
|
|
202
|
-
};
|
|
203
|
-
},
|
|
204
|
-
safeConvertToUSD: safeUsd
|
|
205
|
-
},
|
|
153
|
+
priceOracle,
|
|
206
154
|
pool: {
|
|
207
155
|
pqk: {
|
|
208
156
|
quotas,
|
|
@@ -222,7 +170,6 @@ function buildMockSdk(args) {
|
|
|
222
170
|
underlying: args.underlying
|
|
223
171
|
}
|
|
224
172
|
};
|
|
225
|
-
Object.assign(market, { valueInUnderlying: MarketSuite.prototype.valueInUnderlying });
|
|
226
173
|
const collateralTokens = [args.underlying.toLowerCase(), ...Object.keys(args.liquidationThresholds).map((t) => t.toLowerCase()).filter((t) => t !== args.underlying.toLowerCase())];
|
|
227
174
|
const forbidden = new Set((args.forbiddenTokens ?? []).map((t) => t.toLowerCase()));
|
|
228
175
|
const forbiddenTokensMask = collateralTokens.reduce((mask, token, i) => forbidden.has(token) ? mask | 1n << BigInt(i) : mask, 0n);
|
|
@@ -36,7 +36,7 @@ function isRedemptionPhantomToken(sdk, token) {
|
|
|
36
36
|
function rankAccountTokens(args) {
|
|
37
37
|
const { creditAccount, sdk, exclude = [] } = args;
|
|
38
38
|
const oracle = sdk.marketRegister.findByCreditManager(creditAccount.creditManager).priceOracle;
|
|
39
|
-
const convert = (from, to, amount) => oracle.safeConvert(from, to, amount)
|
|
39
|
+
const convert = (from, to, amount) => oracle.safeConvert(from, to, amount).value;
|
|
40
40
|
const candidates = [];
|
|
41
41
|
for (const t of creditAccount.tokens) {
|
|
42
42
|
if (t.balance <= 0n) continue;
|
|
@@ -14,8 +14,8 @@ function probeBasket(balances, oracle) {
|
|
|
14
14
|
let basketWad = 0n;
|
|
15
15
|
for (const asset of balances) {
|
|
16
16
|
if (asset.balance <= 0n) continue;
|
|
17
|
-
const usd = oracle.safeConvertToUSD(asset.token, asset.balance);
|
|
18
|
-
if (usd
|
|
17
|
+
const usd = oracle.safeConvertToUSD(asset.token, asset.balance).value;
|
|
18
|
+
if (usd > 0n) basketWad += usd * WAD / PRICE_DECIMALS;
|
|
19
19
|
}
|
|
20
20
|
if (basketWad <= 0n) return;
|
|
21
21
|
const probeWad = PROBE_UNIT_USD_WAD;
|
|
@@ -151,7 +151,7 @@ function createRouterPaths(args) {
|
|
|
151
151
|
function createOraclePaths(args) {
|
|
152
152
|
const { sdk, creditAccount } = args;
|
|
153
153
|
const oracle = sdk.marketRegister.findByCreditManager(creditAccount.creditManager).priceOracle;
|
|
154
|
-
const price = (from, to, amount) => oracle.safeConvert(from, to, amount)
|
|
154
|
+
const price = (from, to, amount) => oracle.safeConvert(from, to, amount).value;
|
|
155
155
|
const estimate = (amount) => ({
|
|
156
156
|
amount,
|
|
157
157
|
minAmount: amount,
|
|
@@ -11,7 +11,7 @@ import { pickFattestNonPhantomToken } from "./utils/pick-token.js";
|
|
|
11
11
|
function accountView(creditAccount, sdk) {
|
|
12
12
|
const { underlying, creditManager } = creditAccount;
|
|
13
13
|
const oracle = sdk.marketRegister.findByCreditManager(creditManager).priceOracle;
|
|
14
|
-
const price = (from, to, amount) => oracle.safeConvert(from, to, amount)
|
|
14
|
+
const price = (from, to, amount) => oracle.safeConvert(from, to, amount).value;
|
|
15
15
|
const { creditFacade } = sdk.marketRegister.findCreditManager(creditManager);
|
|
16
16
|
let totalValue = 0n;
|
|
17
17
|
for (const t of creditAccount.tokens) totalValue += price(t.token, underlying, t.balance);
|
|
@@ -148,11 +148,11 @@ var LiquidationsService = class extends SDKConstruct {
|
|
|
148
148
|
#anyMarketTokenAmount(token, value) {
|
|
149
149
|
const meta = this.sdk.tokensMeta.mustGetToken(token);
|
|
150
150
|
for (const market of this.sdk.marketRegister.markets) {
|
|
151
|
-
const
|
|
152
|
-
if (
|
|
151
|
+
const priced = market.priceOracle.safeConvertToUSD(token, value);
|
|
152
|
+
if (!priced.error) return {
|
|
153
153
|
token: meta,
|
|
154
154
|
value,
|
|
155
|
-
valueUsd
|
|
155
|
+
valueUsd: usdToNumber(priced.value)
|
|
156
156
|
};
|
|
157
157
|
}
|
|
158
158
|
return {
|
|
@@ -169,9 +169,9 @@ import { WstETHPriceFeedContract } from "./market/pricefeeds/WstETHPriceFeed.js"
|
|
|
169
169
|
import { YearnPriceFeedContract } from "./market/pricefeeds/YearnPriceFeed.js";
|
|
170
170
|
import { ZeroPriceFeedContract } from "./market/pricefeeds/ZeroPriceFeed.js";
|
|
171
171
|
import { PriceFeedRegister } from "./market/pricefeeds/PriceFeedsRegister.js";
|
|
172
|
+
import { unpriceableTokenError } from "./market/oracle/errors.js";
|
|
172
173
|
import { PriceOracleV310Contract } from "./market/oracle/PriceOracleV310Contract.js";
|
|
173
174
|
import { createPriceOracle } from "./market/oracle/createPriceOracle.js";
|
|
174
|
-
import { unpriceableTokenError } from "./market/oracle/errors.js";
|
|
175
175
|
import { GaugeContract } from "./market/pool/GaugeContract.js";
|
|
176
176
|
import { LinearInterestRateModelContract } from "./market/pool/LinearInterestRateModelContract.js";
|
|
177
177
|
import { PoolV310Contract } from "./market/pool/PoolV310Contract.js";
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { AddressMap } from "../utils/AddressMap.js";
|
|
2
2
|
import { isRWAToken, isSunsetPool } from "../chain/chains.js";
|
|
3
|
-
import { DUST_THRESHOLD } from "../constants/math.js";
|
|
4
|
-
import "../constants/index.js";
|
|
5
3
|
import "../utils/index.js";
|
|
6
4
|
import { SDKConstruct } from "../base/SDKConstruct.js";
|
|
7
5
|
import "../base/index.js";
|
|
@@ -152,32 +150,6 @@ var MarketSuite = class extends SDKConstruct {
|
|
|
152
150
|
...this.priceOracle.toAmount(this.underlying, value)
|
|
153
151
|
});
|
|
154
152
|
/**
|
|
155
|
-
* Sums `assets` in this market's underlying at latest oracle prices.
|
|
156
|
-
*
|
|
157
|
-
* Balances at or below `minBalance` are ignored. A token the oracle cannot
|
|
158
|
-
* price contributes nothing; the first such token is {@link ValueInUnderlying.unpriceable}.
|
|
159
|
-
*
|
|
160
|
-
* The counterpart of {@link toUnderlyingAmount}: that method labels a figure
|
|
161
|
-
* already in underlying, this one produces the figure from mixed holdings.
|
|
162
|
-
**/
|
|
163
|
-
valueInUnderlying(assets, minBalance = DUST_THRESHOLD) {
|
|
164
|
-
let unpriceable;
|
|
165
|
-
let value = 0n;
|
|
166
|
-
for (const { token, balance } of assets) {
|
|
167
|
-
if (balance <= minBalance) continue;
|
|
168
|
-
const converted = this.priceOracle.safeConvert(token, this.underlying, balance);
|
|
169
|
-
if (converted === null) {
|
|
170
|
-
unpriceable ??= token;
|
|
171
|
-
continue;
|
|
172
|
-
}
|
|
173
|
-
value += converted;
|
|
174
|
-
}
|
|
175
|
-
return unpriceable === void 0 ? { value } : {
|
|
176
|
-
value,
|
|
177
|
-
unpriceable
|
|
178
|
-
};
|
|
179
|
-
}
|
|
180
|
-
/**
|
|
181
153
|
* Display name of this market's pool, e.g. `"USDC Pool"`.
|
|
182
154
|
*/
|
|
183
155
|
get poolName() {
|
|
@@ -66,11 +66,11 @@ function pickStrategyTargetCollateral(tokens) {
|
|
|
66
66
|
* nothing but its underlying, or nothing the oracle can price.
|
|
67
67
|
**/
|
|
68
68
|
function dominantCollateral(account, market) {
|
|
69
|
-
let bestValue =
|
|
69
|
+
let bestValue = 0n;
|
|
70
70
|
let dominant;
|
|
71
71
|
for (const t of account.tokens) {
|
|
72
72
|
if (isAddressEqual(t.token, account.underlying) || (t.mask & account.enabledTokensMask) === 0n || t.balance <= 10n) continue;
|
|
73
|
-
const value = market.priceOracle.
|
|
73
|
+
const value = market.priceOracle.safeConvertToUSD(t.token, t.balance).value;
|
|
74
74
|
if (value > bestValue) {
|
|
75
75
|
bestValue = value;
|
|
76
76
|
dominant = t.token;
|
|
@@ -119,9 +119,9 @@ import { YearnPriceFeedContract } from "./pricefeeds/YearnPriceFeed.js";
|
|
|
119
119
|
import { ZeroPriceFeedContract } from "./pricefeeds/ZeroPriceFeed.js";
|
|
120
120
|
import { PriceFeedRegister } from "./pricefeeds/PriceFeedsRegister.js";
|
|
121
121
|
import "./pricefeeds/index.js";
|
|
122
|
+
import { unpriceableTokenError } from "./oracle/errors.js";
|
|
122
123
|
import { PriceOracleV310Contract } from "./oracle/PriceOracleV310Contract.js";
|
|
123
124
|
import { createPriceOracle } from "./oracle/createPriceOracle.js";
|
|
124
|
-
import { unpriceableTokenError } from "./oracle/errors.js";
|
|
125
125
|
import "./oracle/index.js";
|
|
126
126
|
import { GaugeContract } from "./pool/GaugeContract.js";
|
|
127
127
|
import { LinearInterestRateModelContract } from "./pool/LinearInterestRateModelContract.js";
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { AddressMap } from "../../utils/AddressMap.js";
|
|
2
2
|
import { AddressSet } from "../../utils/AddressSet.js";
|
|
3
|
+
import { BigIntMath } from "../../utils/bigint-math.js";
|
|
3
4
|
import { AP_PRICE_FEED_COMPRESSOR, AP_WETH_TOKEN } from "../../constants/address-provider.js";
|
|
4
5
|
import { NATIVE_ADDRESS } from "../../constants/addresses.js";
|
|
5
6
|
import "../../constants/math.js";
|
|
@@ -10,10 +11,13 @@ import "../../utils/index.js";
|
|
|
10
11
|
import { BaseContract } from "../../base/BaseContract.js";
|
|
11
12
|
import "../../base/index.js";
|
|
12
13
|
import { usdToNumber } from "../math.js";
|
|
14
|
+
import { safeValue } from "../../../model/result.js";
|
|
15
|
+
import "../../../model/index.js";
|
|
13
16
|
import { priceFeedCompressorAbi } from "../../../abi/compressors/priceFeedCompressor.js";
|
|
14
17
|
import { PriceFeedRef } from "../pricefeeds/PriceFeedRef.js";
|
|
15
18
|
import { getRawPriceUpdates } from "../pricefeeds/getRawPriceUpdates.js";
|
|
16
19
|
import "../pricefeeds/index.js";
|
|
20
|
+
import { unpriceableTokenError } from "./errors.js";
|
|
17
21
|
import PriceFeedAnswerMap from "./PriceFeedAnswerMap.js";
|
|
18
22
|
import { isAddressEqual, stringToHex } from "viem";
|
|
19
23
|
import { format, formatDistanceToNow } from "date-fns";
|
|
@@ -141,10 +145,13 @@ var PriceOracleBaseContract = class extends BaseContract {
|
|
|
141
145
|
**/
|
|
142
146
|
safeConvert(from, to, amount) {
|
|
143
147
|
try {
|
|
144
|
-
return this.convert(from, to, amount);
|
|
145
|
-
} catch
|
|
146
|
-
|
|
147
|
-
|
|
148
|
+
return { value: this.convert(from, to, amount) };
|
|
149
|
+
} catch {
|
|
150
|
+
try {
|
|
151
|
+
return { value: this.convert(from, to, amount, true) };
|
|
152
|
+
} catch {
|
|
153
|
+
return safeValue(0n, unpriceableTokenError(from));
|
|
154
|
+
}
|
|
148
155
|
}
|
|
149
156
|
}
|
|
150
157
|
/**
|
|
@@ -152,26 +159,72 @@ var PriceOracleBaseContract = class extends BaseContract {
|
|
|
152
159
|
**/
|
|
153
160
|
safeConvertToUSD(token, amount) {
|
|
154
161
|
try {
|
|
155
|
-
return this.convertToUSD(token, amount);
|
|
156
|
-
} catch
|
|
157
|
-
|
|
158
|
-
|
|
162
|
+
return { value: this.convertToUSD(token, amount) };
|
|
163
|
+
} catch {
|
|
164
|
+
try {
|
|
165
|
+
return { value: this.convertToUSD(token, amount, true) };
|
|
166
|
+
} catch {
|
|
167
|
+
return safeValue(0n, unpriceableTokenError(token));
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* {@inheritDoc IPriceOracleContract.safeConvertMinUSD}
|
|
173
|
+
**/
|
|
174
|
+
safeConvertMinUSD(token, amount) {
|
|
175
|
+
let main;
|
|
176
|
+
try {
|
|
177
|
+
main = this.convertToUSD(token, amount);
|
|
178
|
+
} catch {
|
|
179
|
+
return safeValue(0n, unpriceableTokenError(token));
|
|
180
|
+
}
|
|
181
|
+
let feedToken = token;
|
|
182
|
+
if (isAddressEqual(token, "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE")) try {
|
|
183
|
+
feedToken = this.sdk.addressProvider.getAddress(AP_WETH_TOKEN, 0);
|
|
184
|
+
} catch {}
|
|
185
|
+
if (!this.reservePriceFeeds.has(feedToken)) return { value: 0n };
|
|
186
|
+
try {
|
|
187
|
+
return { value: BigIntMath.min(main, this.convertToUSD(token, amount, true)) };
|
|
188
|
+
} catch {
|
|
189
|
+
return safeValue(0n, unpriceableTokenError(token));
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* {@inheritDoc IPriceOracleContract.safeConvertFromUSD}
|
|
194
|
+
**/
|
|
195
|
+
safeConvertFromUSD(token, amount) {
|
|
196
|
+
try {
|
|
197
|
+
return { value: this.convertFromUSD(token, amount) };
|
|
198
|
+
} catch {
|
|
199
|
+
try {
|
|
200
|
+
return { value: this.convertFromUSD(token, amount, true) };
|
|
201
|
+
} catch {
|
|
202
|
+
return safeValue(0n, unpriceableTokenError(token));
|
|
203
|
+
}
|
|
159
204
|
}
|
|
160
205
|
}
|
|
161
206
|
/**
|
|
162
|
-
* {@inheritDoc IPriceOracleContract.
|
|
207
|
+
* {@inheritDoc IPriceOracleContract.safeConvertAssets}
|
|
163
208
|
**/
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
209
|
+
safeConvertAssets(assets, to) {
|
|
210
|
+
let value = 0n;
|
|
211
|
+
let error;
|
|
212
|
+
for (const { token, balance } of assets) {
|
|
213
|
+
if (balance <= 10n) continue;
|
|
214
|
+
const converted = this.safeConvert(token, to, balance);
|
|
215
|
+
value += converted.value;
|
|
216
|
+
error ??= converted.error;
|
|
217
|
+
}
|
|
218
|
+
return safeValue(value, error);
|
|
167
219
|
}
|
|
168
220
|
/**
|
|
169
221
|
* {@inheritDoc IPriceOracleContract.toAmount}
|
|
170
222
|
**/
|
|
171
223
|
toAmount = (token, value) => {
|
|
224
|
+
const priced = this.safeConvertToUSD(token, value);
|
|
172
225
|
return {
|
|
173
226
|
value,
|
|
174
|
-
valueUsd:
|
|
227
|
+
valueUsd: priced.error ? null : usdToNumber(priced.value)
|
|
175
228
|
};
|
|
176
229
|
};
|
|
177
230
|
/**
|