@gearbox-protocol/sdk 5.2.0 → 6.0.0-next.2
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/dev/calcLiquidatableLTs.js +5 -1
- package/dist/cjs/sdk/base/BaseContract.js +0 -1
- package/dist/cjs/sdk/market/MarketSuite.js +1 -5
- package/dist/cjs/sdk/market/oracle/PriceOracleBaseContract.js +52 -47
- package/dist/cjs/sdk/market/oracle/PriceOracleV300Contract.js +2 -3
- package/dist/cjs/sdk/market/oracle/PriceOracleV310Contract.js +2 -3
- package/dist/cjs/sdk/market/oracle/createPriceOracle.js +28 -9
- package/dist/cjs/sdk/market/pricefeeds/AbstractLPPriceFeed.js +2 -1
- package/dist/cjs/sdk/market/pricefeeds/RedstonePriceFeed.js +1 -1
- package/dist/cjs/sdk/plugins/V300StalenessPeriodPlugin.js +5 -5
- package/dist/esm/dev/calcLiquidatableLTs.js +5 -1
- package/dist/esm/sdk/base/BaseContract.js +0 -1
- package/dist/esm/sdk/market/MarketSuite.js +2 -6
- package/dist/esm/sdk/market/oracle/PriceOracleBaseContract.js +53 -47
- package/dist/esm/sdk/market/oracle/PriceOracleV300Contract.js +2 -3
- package/dist/esm/sdk/market/oracle/PriceOracleV310Contract.js +2 -3
- package/dist/esm/sdk/market/oracle/createPriceOracle.js +27 -8
- package/dist/esm/sdk/market/pricefeeds/AbstractLPPriceFeed.js +2 -1
- package/dist/esm/sdk/market/pricefeeds/RedstonePriceFeed.js +2 -2
- package/dist/esm/sdk/plugins/V300StalenessPeriodPlugin.js +6 -6
- package/dist/types/sdk/market/MarketSuite.d.ts +2 -2
- package/dist/types/sdk/market/oracle/PriceOracleBaseContract.d.ts +28 -684
- package/dist/types/sdk/market/oracle/PriceOracleV300Contract.d.ts +1 -1
- package/dist/types/sdk/market/oracle/PriceOracleV310Contract.d.ts +2 -2
- package/dist/types/sdk/market/oracle/createPriceOracle.d.ts +14 -3
- package/dist/types/sdk/market/oracle/types.d.ts +97 -6
- package/dist/types/sdk/plugins/V300StalenessPeriodPlugin.d.ts +3 -2
- package/package.json +1 -1
|
@@ -30,7 +30,11 @@ async function calcLiquidatableLTs(sdk, ca, factor = 9990n, logger) {
|
|
|
30
30
|
return balance > minBalance;
|
|
31
31
|
}).map((t) => {
|
|
32
32
|
const { token, balance } = t;
|
|
33
|
-
const balanceU = market.priceOracle.
|
|
33
|
+
const balanceU = market.priceOracle.convert(
|
|
34
|
+
token,
|
|
35
|
+
ca.underlying,
|
|
36
|
+
balance
|
|
37
|
+
);
|
|
34
38
|
const lt = BigInt(cm.creditManager.liquidationThresholds.mustGet(token));
|
|
35
39
|
return {
|
|
36
40
|
token,
|
|
@@ -58,11 +58,7 @@ class MarketSuite extends import_base.SDKConstruct {
|
|
|
58
58
|
for (let i = 0; i < marketData.creditManagers.length; i++) {
|
|
59
59
|
this.creditManagers.push(new import_credit.CreditSuite(sdk, marketData, i));
|
|
60
60
|
}
|
|
61
|
-
this.priceOracle = (0, import_oracle.
|
|
62
|
-
sdk,
|
|
63
|
-
marketData.priceOracle,
|
|
64
|
-
marketData.pool.underlying
|
|
65
|
-
);
|
|
61
|
+
this.priceOracle = (0, import_oracle.getOrCreatePriceOracle)(sdk, marketData.priceOracle);
|
|
66
62
|
}
|
|
67
63
|
get dirty() {
|
|
68
64
|
return this.configurator.dirty || this.pool.dirty || this.priceOracle.dirty || this.creditManagers.some((cm) => cm.dirty);
|
|
@@ -42,10 +42,6 @@ var import_pricefeeds = require("../pricefeeds/index.js");
|
|
|
42
42
|
var import_PriceFeedAnswerMap = __toESM(require("./PriceFeedAnswerMap.js"));
|
|
43
43
|
const ZERO_PRICE_FEED = (0, import_viem.stringToHex)("PRICE_FEED::ZERO", { size: 32 });
|
|
44
44
|
class PriceOracleBaseContract extends import_base.BaseContract {
|
|
45
|
-
/**
|
|
46
|
-
* Underlying token of market to which this price oracle belongs
|
|
47
|
-
*/
|
|
48
|
-
underlying;
|
|
49
45
|
/**
|
|
50
46
|
* Mapping Token => [PriceFeed Address, stalenessPeriod]
|
|
51
47
|
*/
|
|
@@ -71,12 +67,14 @@ class PriceOracleBaseContract extends import_base.BaseContract {
|
|
|
71
67
|
void 0,
|
|
72
68
|
"reservePrices"
|
|
73
69
|
);
|
|
74
|
-
#priceFeedTree =
|
|
75
|
-
|
|
70
|
+
#priceFeedTree = new import_utils.AddressMap(
|
|
71
|
+
void 0,
|
|
72
|
+
"priceFeedTree"
|
|
73
|
+
);
|
|
74
|
+
constructor(sdk, args, data) {
|
|
76
75
|
super(sdk, args);
|
|
77
|
-
this.underlying = underlying;
|
|
78
76
|
const { priceFeedMap, priceFeedTree } = data;
|
|
79
|
-
this.#loadState(priceFeedMap, priceFeedTree);
|
|
77
|
+
this.#loadState(priceFeedMap, priceFeedTree, true);
|
|
80
78
|
}
|
|
81
79
|
/**
|
|
82
80
|
* Returns main and reserve price feeds for given tokens
|
|
@@ -98,7 +96,7 @@ class PriceOracleBaseContract extends import_base.BaseContract {
|
|
|
98
96
|
*/
|
|
99
97
|
async updatePriceFeeds() {
|
|
100
98
|
const updatables = [];
|
|
101
|
-
for (const node of this.#priceFeedTree) {
|
|
99
|
+
for (const node of this.#priceFeedTree.values()) {
|
|
102
100
|
if (node.updatable) {
|
|
103
101
|
updatables.push(this.sdk.priceFeeds.mustGet(node.baseParams.addr));
|
|
104
102
|
}
|
|
@@ -164,30 +162,19 @@ class PriceOracleBaseContract extends import_base.BaseContract {
|
|
|
164
162
|
}
|
|
165
163
|
/**
|
|
166
164
|
* Returns true if oracle's price feed tree contains given price feed
|
|
165
|
+
* This feed is not necessary connected to token, but can be a component of composite feed for some token
|
|
167
166
|
* @param priceFeed
|
|
168
167
|
* @returns
|
|
169
168
|
*/
|
|
170
169
|
usesPriceFeed(priceFeed) {
|
|
171
|
-
return this.#priceFeedTree.
|
|
172
|
-
(node) => node.baseParams.addr.toLowerCase() === priceFeed.toLowerCase()
|
|
173
|
-
);
|
|
174
|
-
}
|
|
175
|
-
/**
|
|
176
|
-
* Tries to convert amount of token into underlying of current market
|
|
177
|
-
* @param token
|
|
178
|
-
* @param amount
|
|
179
|
-
* @param reserve
|
|
180
|
-
* @returns
|
|
181
|
-
*/
|
|
182
|
-
convertToUnderlying(token, amount, reserve = false) {
|
|
183
|
-
return this.convert(token, this.underlying, amount, reserve);
|
|
170
|
+
return this.#priceFeedTree.has(priceFeed);
|
|
184
171
|
}
|
|
185
172
|
/**
|
|
186
173
|
* Tries to convert amount of from one token to another, using latest known prices
|
|
187
174
|
* @param from
|
|
188
175
|
* @param to
|
|
189
176
|
* @param amount
|
|
190
|
-
* @param reserve
|
|
177
|
+
* @param reserve use reserve price feed instead of main
|
|
191
178
|
*/
|
|
192
179
|
convert(from, to, amount, reserve = false) {
|
|
193
180
|
if (from === to) {
|
|
@@ -202,9 +189,8 @@ class PriceOracleBaseContract extends import_base.BaseContract {
|
|
|
202
189
|
/**
|
|
203
190
|
* Tries to convert amount of token to USD, using latest known prices
|
|
204
191
|
* @param from
|
|
205
|
-
* @param to
|
|
206
192
|
* @param amount
|
|
207
|
-
* @param reserve
|
|
193
|
+
* @param reserve use reserve price feed instead of main
|
|
208
194
|
*/
|
|
209
195
|
convertToUSD(from, amount, reserve = false) {
|
|
210
196
|
const price = reserve ? this.reservePrice(from) : this.mainPrice(from);
|
|
@@ -215,7 +201,7 @@ class PriceOracleBaseContract extends import_base.BaseContract {
|
|
|
215
201
|
* Tries to convert amount of USD to token, using latest known prices
|
|
216
202
|
* @param to
|
|
217
203
|
* @param amount
|
|
218
|
-
* @param reserve
|
|
204
|
+
* @param reserve use reserve price feed instead of main
|
|
219
205
|
*/
|
|
220
206
|
convertFromUSD(to, amount, reserve = false) {
|
|
221
207
|
const price = reserve ? this.reservePrice(to) : this.mainPrice(to);
|
|
@@ -224,23 +210,26 @@ class PriceOracleBaseContract extends import_base.BaseContract {
|
|
|
224
210
|
}
|
|
225
211
|
/**
|
|
226
212
|
* Loads new prices for this oracle from PriceFeedCompressor
|
|
227
|
-
*
|
|
213
|
+
* Will (re)create price feeds if needed
|
|
228
214
|
*/
|
|
229
215
|
async updatePrices() {
|
|
230
216
|
await this.sdk.marketRegister.updatePrices([this.address]);
|
|
231
217
|
}
|
|
218
|
+
/**
|
|
219
|
+
* Paired method to updatePrices, helps to update prices on all oracles in one multicall
|
|
220
|
+
*/
|
|
232
221
|
syncStateMulticall() {
|
|
233
|
-
|
|
234
|
-
if (this.version
|
|
235
|
-
args
|
|
222
|
+
let args = [this.address];
|
|
223
|
+
if ((0, import_constants.isV300)(this.version)) {
|
|
224
|
+
args = [
|
|
225
|
+
args[0],
|
|
236
226
|
Array.from(
|
|
237
227
|
/* @__PURE__ */ new Set([
|
|
238
|
-
this.underlying,
|
|
239
228
|
...this.mainPriceFeeds.keys(),
|
|
240
229
|
...this.reservePriceFeeds.keys()
|
|
241
230
|
])
|
|
242
231
|
)
|
|
243
|
-
|
|
232
|
+
];
|
|
244
233
|
}
|
|
245
234
|
const [address] = this.sdk.addressProvider.mustGetLatest(
|
|
246
235
|
import_constants.AP_PRICE_FEED_COMPRESSOR,
|
|
@@ -255,25 +244,39 @@ class PriceOracleBaseContract extends import_base.BaseContract {
|
|
|
255
244
|
},
|
|
256
245
|
onResult: (resp) => {
|
|
257
246
|
const { priceFeedMap, priceFeedTree } = resp;
|
|
258
|
-
this.#loadState(priceFeedMap, priceFeedTree);
|
|
247
|
+
this.#loadState(priceFeedMap, priceFeedTree, true);
|
|
259
248
|
}
|
|
260
249
|
};
|
|
261
250
|
}
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
251
|
+
/**
|
|
252
|
+
* Helper function to handle situation when we have multiple different compressor data entries for same oracle
|
|
253
|
+
* This happens in v300
|
|
254
|
+
*
|
|
255
|
+
* @deprecated should be unnecessary after full v310 migration (oracles will be unique)
|
|
256
|
+
* @param data
|
|
257
|
+
* @returns
|
|
258
|
+
*/
|
|
259
|
+
merge(data) {
|
|
260
|
+
const { priceFeedMap, priceFeedTree } = data;
|
|
261
|
+
this.#loadState(priceFeedMap, priceFeedTree, false);
|
|
262
|
+
return this;
|
|
263
|
+
}
|
|
264
|
+
#loadState(entries, tree, reset) {
|
|
265
|
+
if (reset) {
|
|
266
|
+
this.#priceFeedTree.clear();
|
|
267
|
+
this.mainPriceFeeds.clear();
|
|
268
|
+
this.reservePriceFeeds.clear();
|
|
269
|
+
this.mainPrices.clear();
|
|
270
|
+
this.reservePrices.clear();
|
|
271
|
+
}
|
|
268
272
|
for (const node of tree) {
|
|
273
|
+
this.#priceFeedTree.upsert(node.baseParams.addr, node);
|
|
269
274
|
this.sdk.priceFeeds.getOrCreate(node);
|
|
270
275
|
}
|
|
271
|
-
|
|
276
|
+
for (const entry of entries) {
|
|
272
277
|
const { token, priceFeed, reserve, stalenessPeriod } = entry;
|
|
273
278
|
const ref = new import_pricefeeds.PriceFeedRef(this.sdk, priceFeed, stalenessPeriod);
|
|
274
|
-
const node = this.#priceFeedTree.
|
|
275
|
-
(n) => n.baseParams.addr === priceFeed
|
|
276
|
-
);
|
|
279
|
+
const node = this.#priceFeedTree.get(priceFeed);
|
|
277
280
|
const price = node?.answer?.price;
|
|
278
281
|
const priceFeedType = node?.baseParams.contractType;
|
|
279
282
|
if (reserve) {
|
|
@@ -290,7 +293,7 @@ class PriceOracleBaseContract extends import_base.BaseContract {
|
|
|
290
293
|
}
|
|
291
294
|
}
|
|
292
295
|
this.#labelPriceFeed(priceFeed, reserve ? "Reserve" : "Main", token);
|
|
293
|
-
}
|
|
296
|
+
}
|
|
294
297
|
this.logger?.debug(
|
|
295
298
|
`Got ${this.mainPriceFeeds.size} main and ${this.reservePriceFeeds.size} reserve price feeds`
|
|
296
299
|
);
|
|
@@ -311,6 +314,8 @@ class PriceOracleBaseContract extends import_base.BaseContract {
|
|
|
311
314
|
* Helper method to find "attachment point" of price feed (makes sense for updatable price feeds only) -
|
|
312
315
|
* returns token (in v3.0 can be ticker) and main/reserve flag
|
|
313
316
|
*
|
|
317
|
+
* @deprecated Should be gone after v310 migration
|
|
318
|
+
*
|
|
314
319
|
* @param priceFeed
|
|
315
320
|
* @returns
|
|
316
321
|
*/
|
|
@@ -327,6 +332,9 @@ class PriceOracleBaseContract extends import_base.BaseContract {
|
|
|
327
332
|
}
|
|
328
333
|
return [void 0, false];
|
|
329
334
|
}
|
|
335
|
+
/**
|
|
336
|
+
* Returns list of addresses that should be watched for events to sync state
|
|
337
|
+
*/
|
|
330
338
|
get watchAddresses() {
|
|
331
339
|
return /* @__PURE__ */ new Set([this.address]);
|
|
332
340
|
}
|
|
@@ -353,9 +361,6 @@ class PriceOracleBaseContract extends import_base.BaseContract {
|
|
|
353
361
|
)
|
|
354
362
|
};
|
|
355
363
|
}
|
|
356
|
-
get priceFeedTree() {
|
|
357
|
-
return this.#priceFeedTree;
|
|
358
|
-
}
|
|
359
364
|
#noAnswerWarn(priceFeed, node) {
|
|
360
365
|
let label = this.labelAddress(priceFeed);
|
|
361
366
|
if (!node) {
|
|
@@ -27,7 +27,7 @@ var import_sdk_gov_legacy = require("../../sdk-gov-legacy/index.js");
|
|
|
27
27
|
var import_PriceOracleBaseContract = require("./PriceOracleBaseContract.js");
|
|
28
28
|
const abi = [...import_v300.iPriceOracleV300Abi, ...import_iPausable.iPausableAbi];
|
|
29
29
|
class PriceOracleV300Contract extends import_PriceOracleBaseContract.PriceOracleBaseContract {
|
|
30
|
-
constructor(sdk, data
|
|
30
|
+
constructor(sdk, data) {
|
|
31
31
|
super(
|
|
32
32
|
sdk,
|
|
33
33
|
{
|
|
@@ -35,8 +35,7 @@ class PriceOracleV300Contract extends import_PriceOracleBaseContract.PriceOracle
|
|
|
35
35
|
name: "PriceOracleV3",
|
|
36
36
|
abi
|
|
37
37
|
},
|
|
38
|
-
data
|
|
39
|
-
underlying
|
|
38
|
+
data
|
|
40
39
|
);
|
|
41
40
|
}
|
|
42
41
|
processLog(log) {
|
|
@@ -25,7 +25,7 @@ var import_v310 = require("../../../abi/v310.js");
|
|
|
25
25
|
var import_PriceOracleBaseContract = require("./PriceOracleBaseContract.js");
|
|
26
26
|
const abi = import_v310.iPriceOracleV310Abi;
|
|
27
27
|
class PriceOracleV310Contract extends import_PriceOracleBaseContract.PriceOracleBaseContract {
|
|
28
|
-
constructor(sdk, data
|
|
28
|
+
constructor(sdk, data) {
|
|
29
29
|
super(
|
|
30
30
|
sdk,
|
|
31
31
|
{
|
|
@@ -33,8 +33,7 @@ class PriceOracleV310Contract extends import_PriceOracleBaseContract.PriceOracle
|
|
|
33
33
|
name: "PriceOracleV3",
|
|
34
34
|
abi
|
|
35
35
|
},
|
|
36
|
-
data
|
|
37
|
-
underlying
|
|
36
|
+
data
|
|
38
37
|
);
|
|
39
38
|
}
|
|
40
39
|
processLog(log) {
|
|
@@ -18,23 +18,42 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
19
|
var createPriceOracle_exports = {};
|
|
20
20
|
__export(createPriceOracle_exports, {
|
|
21
|
-
|
|
21
|
+
getOrCreatePriceOracle: () => getOrCreatePriceOracle
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(createPriceOracle_exports);
|
|
24
24
|
var import_constants = require("../../constants/index.js");
|
|
25
|
+
var import_PriceOracleBaseContract = require("./PriceOracleBaseContract.js");
|
|
25
26
|
var import_PriceOracleV300Contract = require("./PriceOracleV300Contract.js");
|
|
26
27
|
var import_PriceOracleV310Contract = require("./PriceOracleV310Contract.js");
|
|
27
|
-
function
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
function getOrCreatePriceOracle(sdk, data) {
|
|
29
|
+
const { version, addr } = data.baseParams;
|
|
30
|
+
const existing = sdk.contracts.get(addr);
|
|
31
|
+
if (existing) {
|
|
32
|
+
return tryExtendExistingOracle(existing, data);
|
|
31
33
|
}
|
|
32
|
-
if ((0, import_constants.
|
|
33
|
-
return new
|
|
34
|
+
if ((0, import_constants.isV300)(version)) {
|
|
35
|
+
return new import_PriceOracleV300Contract.PriceOracleV300Contract(sdk, data);
|
|
34
36
|
}
|
|
35
|
-
|
|
37
|
+
if ((0, import_constants.isV310)(version)) {
|
|
38
|
+
return new import_PriceOracleV310Contract.PriceOracleV310Contract(sdk, data);
|
|
39
|
+
}
|
|
40
|
+
throw new Error(`Unsupported oracle version ${version}`);
|
|
41
|
+
}
|
|
42
|
+
function tryExtendExistingOracle(existing, data) {
|
|
43
|
+
const { version, addr } = data.baseParams;
|
|
44
|
+
if (!(existing instanceof import_PriceOracleBaseContract.PriceOracleBaseContract)) {
|
|
45
|
+
throw new Error(
|
|
46
|
+
`expected oracle contract at ${addr}, found existing ${existing.contractType}`
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
if (Number(existing.version) !== Number(version)) {
|
|
50
|
+
throw new Error(
|
|
51
|
+
`expected oracle contract at ${addr} to have version ${version}, found ${existing.version}`
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
return existing.merge(data);
|
|
36
55
|
}
|
|
37
56
|
// Annotate the CommonJS export names for ESM import in node:
|
|
38
57
|
0 && (module.exports = {
|
|
39
|
-
|
|
58
|
+
getOrCreatePriceOracle
|
|
40
59
|
});
|
|
@@ -22,6 +22,7 @@ __export(AbstractLPPriceFeed_exports, {
|
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(AbstractLPPriceFeed_exports);
|
|
24
24
|
var import_viem = require("viem");
|
|
25
|
+
var import_versions = require("../../constants/versions.js");
|
|
25
26
|
var import_AbstractPriceFeed = require("./AbstractPriceFeed.js");
|
|
26
27
|
const LOWER_BOUND_FACTOR = 99n;
|
|
27
28
|
class AbstractLPPriceFeedContract extends import_AbstractPriceFeed.AbstractPriceFeedContract {
|
|
@@ -36,7 +37,7 @@ class AbstractLPPriceFeedContract extends import_AbstractPriceFeed.AbstractPrice
|
|
|
36
37
|
constructor(sdk, args) {
|
|
37
38
|
super(sdk, { ...args, decimals: 8 });
|
|
38
39
|
this.hasLowerBoundCap = true;
|
|
39
|
-
if (args.baseParams.version
|
|
40
|
+
if ((0, import_versions.isV310)(args.baseParams.version)) {
|
|
40
41
|
const decoder = (0, import_viem.decodeAbiParameters)(
|
|
41
42
|
[
|
|
42
43
|
{ type: "address", name: "lpToken" },
|
|
@@ -40,7 +40,7 @@ class RedstonePriceFeedContract extends import_AbstractPriceFeed.AbstractPriceFe
|
|
|
40
40
|
name: `RedstonePriceFeed`,
|
|
41
41
|
abi: import_abi.redstonePriceFeedAbi
|
|
42
42
|
});
|
|
43
|
-
if (args.baseParams.version
|
|
43
|
+
if ((0, import_constants.isV310)(args.baseParams.version)) {
|
|
44
44
|
const decoder = (0, import_viem.decodeAbiParameters)(
|
|
45
45
|
[
|
|
46
46
|
{ type: "address", name: "token" },
|
|
@@ -39,12 +39,12 @@ class V300StalenessPeriodPlugin extends import_base.SDKConstruct {
|
|
|
39
39
|
this.#logger = sdk.logger?.child?.({ name: "V300StalenessPeriodPlugin" }) ?? sdk.logger;
|
|
40
40
|
}
|
|
41
41
|
async attach() {
|
|
42
|
-
await this.#
|
|
42
|
+
await this.#syncPriceFeeds();
|
|
43
43
|
}
|
|
44
44
|
async syncState() {
|
|
45
|
-
await this.#
|
|
45
|
+
await this.#syncPriceFeeds();
|
|
46
46
|
}
|
|
47
|
-
async #
|
|
47
|
+
async #syncPriceFeeds() {
|
|
48
48
|
const oracles = this.#getOraclesMap();
|
|
49
49
|
const [fromBlock, toBlock] = [this.#syncedTo + 1n, this.sdk.currentBlock];
|
|
50
50
|
if (oracles.size === 0 || fromBlock > toBlock) {
|
|
@@ -67,7 +67,7 @@ class V300StalenessPeriodPlugin extends import_base.SDKConstruct {
|
|
|
67
67
|
strict: true
|
|
68
68
|
});
|
|
69
69
|
this.#logger?.info(
|
|
70
|
-
`loaded ${events.length}
|
|
70
|
+
`loaded ${events.length} price feed events in range [${fromBlock}; ${toBlock}]`
|
|
71
71
|
);
|
|
72
72
|
for (const e of events) {
|
|
73
73
|
const oracle = oracles.mustGet(e.address);
|
|
@@ -120,7 +120,7 @@ class V300StalenessPeriodPlugin extends import_base.SDKConstruct {
|
|
|
120
120
|
}
|
|
121
121
|
#getOraclesMap() {
|
|
122
122
|
return new import_utils.AddressMap(
|
|
123
|
-
this.sdk.marketRegister.markets.filter((m) => m.priceOracle.version
|
|
123
|
+
this.sdk.marketRegister.markets.filter((m) => (0, import_constants.isV300)(m.priceOracle.version)).map((m) => [m.priceOracle.address, m.priceOracle])
|
|
124
124
|
);
|
|
125
125
|
}
|
|
126
126
|
}
|
|
@@ -7,7 +7,11 @@ async function calcLiquidatableLTs(sdk, ca, factor = 9990n, logger) {
|
|
|
7
7
|
return balance > minBalance;
|
|
8
8
|
}).map((t) => {
|
|
9
9
|
const { token, balance } = t;
|
|
10
|
-
const balanceU = market.priceOracle.
|
|
10
|
+
const balanceU = market.priceOracle.convert(
|
|
11
|
+
token,
|
|
12
|
+
ca.underlying,
|
|
13
|
+
balance
|
|
14
|
+
);
|
|
11
15
|
const lt = BigInt(cm.creditManager.liquidationThresholds.mustGet(token));
|
|
12
16
|
return {
|
|
13
17
|
token,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { SDKConstruct } from "../base/index.js";
|
|
2
2
|
import { CreditSuite } from "./credit/index.js";
|
|
3
3
|
import { MarketConfiguratorContract } from "./MarketConfiguratorContract.js";
|
|
4
|
-
import {
|
|
4
|
+
import { getOrCreatePriceOracle } from "./oracle/index.js";
|
|
5
5
|
import { PoolSuite } from "./pool/index.js";
|
|
6
6
|
class MarketSuite extends SDKConstruct {
|
|
7
7
|
acl;
|
|
@@ -35,11 +35,7 @@ class MarketSuite extends SDKConstruct {
|
|
|
35
35
|
for (let i = 0; i < marketData.creditManagers.length; i++) {
|
|
36
36
|
this.creditManagers.push(new CreditSuite(sdk, marketData, i));
|
|
37
37
|
}
|
|
38
|
-
this.priceOracle =
|
|
39
|
-
sdk,
|
|
40
|
-
marketData.priceOracle,
|
|
41
|
-
marketData.pool.underlying
|
|
42
|
-
);
|
|
38
|
+
this.priceOracle = getOrCreatePriceOracle(sdk, marketData.priceOracle);
|
|
43
39
|
}
|
|
44
40
|
get dirty() {
|
|
45
41
|
return this.configurator.dirty || this.pool.dirty || this.priceOracle.dirty || this.creditManagers.some((cm) => cm.dirty);
|
|
@@ -5,6 +5,7 @@ import { iUpdatablePriceFeedAbi } from "../../../abi/iUpdatablePriceFeed.js";
|
|
|
5
5
|
import { BaseContract } from "../../base/index.js";
|
|
6
6
|
import {
|
|
7
7
|
AP_PRICE_FEED_COMPRESSOR,
|
|
8
|
+
isV300,
|
|
8
9
|
VERSION_RANGE_310
|
|
9
10
|
} from "../../constants/index.js";
|
|
10
11
|
import { AddressMap, formatBN } from "../../utils/index.js";
|
|
@@ -12,10 +13,6 @@ import { PriceFeedRef } from "../pricefeeds/index.js";
|
|
|
12
13
|
import PriceFeedAnswerMap from "./PriceFeedAnswerMap.js";
|
|
13
14
|
const ZERO_PRICE_FEED = stringToHex("PRICE_FEED::ZERO", { size: 32 });
|
|
14
15
|
class PriceOracleBaseContract extends BaseContract {
|
|
15
|
-
/**
|
|
16
|
-
* Underlying token of market to which this price oracle belongs
|
|
17
|
-
*/
|
|
18
|
-
underlying;
|
|
19
16
|
/**
|
|
20
17
|
* Mapping Token => [PriceFeed Address, stalenessPeriod]
|
|
21
18
|
*/
|
|
@@ -41,12 +38,14 @@ class PriceOracleBaseContract extends BaseContract {
|
|
|
41
38
|
void 0,
|
|
42
39
|
"reservePrices"
|
|
43
40
|
);
|
|
44
|
-
#priceFeedTree =
|
|
45
|
-
|
|
41
|
+
#priceFeedTree = new AddressMap(
|
|
42
|
+
void 0,
|
|
43
|
+
"priceFeedTree"
|
|
44
|
+
);
|
|
45
|
+
constructor(sdk, args, data) {
|
|
46
46
|
super(sdk, args);
|
|
47
|
-
this.underlying = underlying;
|
|
48
47
|
const { priceFeedMap, priceFeedTree } = data;
|
|
49
|
-
this.#loadState(priceFeedMap, priceFeedTree);
|
|
48
|
+
this.#loadState(priceFeedMap, priceFeedTree, true);
|
|
50
49
|
}
|
|
51
50
|
/**
|
|
52
51
|
* Returns main and reserve price feeds for given tokens
|
|
@@ -68,7 +67,7 @@ class PriceOracleBaseContract extends BaseContract {
|
|
|
68
67
|
*/
|
|
69
68
|
async updatePriceFeeds() {
|
|
70
69
|
const updatables = [];
|
|
71
|
-
for (const node of this.#priceFeedTree) {
|
|
70
|
+
for (const node of this.#priceFeedTree.values()) {
|
|
72
71
|
if (node.updatable) {
|
|
73
72
|
updatables.push(this.sdk.priceFeeds.mustGet(node.baseParams.addr));
|
|
74
73
|
}
|
|
@@ -134,30 +133,19 @@ class PriceOracleBaseContract extends BaseContract {
|
|
|
134
133
|
}
|
|
135
134
|
/**
|
|
136
135
|
* Returns true if oracle's price feed tree contains given price feed
|
|
136
|
+
* This feed is not necessary connected to token, but can be a component of composite feed for some token
|
|
137
137
|
* @param priceFeed
|
|
138
138
|
* @returns
|
|
139
139
|
*/
|
|
140
140
|
usesPriceFeed(priceFeed) {
|
|
141
|
-
return this.#priceFeedTree.
|
|
142
|
-
(node) => node.baseParams.addr.toLowerCase() === priceFeed.toLowerCase()
|
|
143
|
-
);
|
|
144
|
-
}
|
|
145
|
-
/**
|
|
146
|
-
* Tries to convert amount of token into underlying of current market
|
|
147
|
-
* @param token
|
|
148
|
-
* @param amount
|
|
149
|
-
* @param reserve
|
|
150
|
-
* @returns
|
|
151
|
-
*/
|
|
152
|
-
convertToUnderlying(token, amount, reserve = false) {
|
|
153
|
-
return this.convert(token, this.underlying, amount, reserve);
|
|
141
|
+
return this.#priceFeedTree.has(priceFeed);
|
|
154
142
|
}
|
|
155
143
|
/**
|
|
156
144
|
* Tries to convert amount of from one token to another, using latest known prices
|
|
157
145
|
* @param from
|
|
158
146
|
* @param to
|
|
159
147
|
* @param amount
|
|
160
|
-
* @param reserve
|
|
148
|
+
* @param reserve use reserve price feed instead of main
|
|
161
149
|
*/
|
|
162
150
|
convert(from, to, amount, reserve = false) {
|
|
163
151
|
if (from === to) {
|
|
@@ -172,9 +160,8 @@ class PriceOracleBaseContract extends BaseContract {
|
|
|
172
160
|
/**
|
|
173
161
|
* Tries to convert amount of token to USD, using latest known prices
|
|
174
162
|
* @param from
|
|
175
|
-
* @param to
|
|
176
163
|
* @param amount
|
|
177
|
-
* @param reserve
|
|
164
|
+
* @param reserve use reserve price feed instead of main
|
|
178
165
|
*/
|
|
179
166
|
convertToUSD(from, amount, reserve = false) {
|
|
180
167
|
const price = reserve ? this.reservePrice(from) : this.mainPrice(from);
|
|
@@ -185,7 +172,7 @@ class PriceOracleBaseContract extends BaseContract {
|
|
|
185
172
|
* Tries to convert amount of USD to token, using latest known prices
|
|
186
173
|
* @param to
|
|
187
174
|
* @param amount
|
|
188
|
-
* @param reserve
|
|
175
|
+
* @param reserve use reserve price feed instead of main
|
|
189
176
|
*/
|
|
190
177
|
convertFromUSD(to, amount, reserve = false) {
|
|
191
178
|
const price = reserve ? this.reservePrice(to) : this.mainPrice(to);
|
|
@@ -194,23 +181,26 @@ class PriceOracleBaseContract extends BaseContract {
|
|
|
194
181
|
}
|
|
195
182
|
/**
|
|
196
183
|
* Loads new prices for this oracle from PriceFeedCompressor
|
|
197
|
-
*
|
|
184
|
+
* Will (re)create price feeds if needed
|
|
198
185
|
*/
|
|
199
186
|
async updatePrices() {
|
|
200
187
|
await this.sdk.marketRegister.updatePrices([this.address]);
|
|
201
188
|
}
|
|
189
|
+
/**
|
|
190
|
+
* Paired method to updatePrices, helps to update prices on all oracles in one multicall
|
|
191
|
+
*/
|
|
202
192
|
syncStateMulticall() {
|
|
203
|
-
|
|
204
|
-
if (this.version
|
|
205
|
-
args
|
|
193
|
+
let args = [this.address];
|
|
194
|
+
if (isV300(this.version)) {
|
|
195
|
+
args = [
|
|
196
|
+
args[0],
|
|
206
197
|
Array.from(
|
|
207
198
|
/* @__PURE__ */ new Set([
|
|
208
|
-
this.underlying,
|
|
209
199
|
...this.mainPriceFeeds.keys(),
|
|
210
200
|
...this.reservePriceFeeds.keys()
|
|
211
201
|
])
|
|
212
202
|
)
|
|
213
|
-
|
|
203
|
+
];
|
|
214
204
|
}
|
|
215
205
|
const [address] = this.sdk.addressProvider.mustGetLatest(
|
|
216
206
|
AP_PRICE_FEED_COMPRESSOR,
|
|
@@ -225,25 +215,39 @@ class PriceOracleBaseContract extends BaseContract {
|
|
|
225
215
|
},
|
|
226
216
|
onResult: (resp) => {
|
|
227
217
|
const { priceFeedMap, priceFeedTree } = resp;
|
|
228
|
-
this.#loadState(priceFeedMap, priceFeedTree);
|
|
218
|
+
this.#loadState(priceFeedMap, priceFeedTree, true);
|
|
229
219
|
}
|
|
230
220
|
};
|
|
231
221
|
}
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
222
|
+
/**
|
|
223
|
+
* Helper function to handle situation when we have multiple different compressor data entries for same oracle
|
|
224
|
+
* This happens in v300
|
|
225
|
+
*
|
|
226
|
+
* @deprecated should be unnecessary after full v310 migration (oracles will be unique)
|
|
227
|
+
* @param data
|
|
228
|
+
* @returns
|
|
229
|
+
*/
|
|
230
|
+
merge(data) {
|
|
231
|
+
const { priceFeedMap, priceFeedTree } = data;
|
|
232
|
+
this.#loadState(priceFeedMap, priceFeedTree, false);
|
|
233
|
+
return this;
|
|
234
|
+
}
|
|
235
|
+
#loadState(entries, tree, reset) {
|
|
236
|
+
if (reset) {
|
|
237
|
+
this.#priceFeedTree.clear();
|
|
238
|
+
this.mainPriceFeeds.clear();
|
|
239
|
+
this.reservePriceFeeds.clear();
|
|
240
|
+
this.mainPrices.clear();
|
|
241
|
+
this.reservePrices.clear();
|
|
242
|
+
}
|
|
238
243
|
for (const node of tree) {
|
|
244
|
+
this.#priceFeedTree.upsert(node.baseParams.addr, node);
|
|
239
245
|
this.sdk.priceFeeds.getOrCreate(node);
|
|
240
246
|
}
|
|
241
|
-
|
|
247
|
+
for (const entry of entries) {
|
|
242
248
|
const { token, priceFeed, reserve, stalenessPeriod } = entry;
|
|
243
249
|
const ref = new PriceFeedRef(this.sdk, priceFeed, stalenessPeriod);
|
|
244
|
-
const node = this.#priceFeedTree.
|
|
245
|
-
(n) => n.baseParams.addr === priceFeed
|
|
246
|
-
);
|
|
250
|
+
const node = this.#priceFeedTree.get(priceFeed);
|
|
247
251
|
const price = node?.answer?.price;
|
|
248
252
|
const priceFeedType = node?.baseParams.contractType;
|
|
249
253
|
if (reserve) {
|
|
@@ -260,7 +264,7 @@ class PriceOracleBaseContract extends BaseContract {
|
|
|
260
264
|
}
|
|
261
265
|
}
|
|
262
266
|
this.#labelPriceFeed(priceFeed, reserve ? "Reserve" : "Main", token);
|
|
263
|
-
}
|
|
267
|
+
}
|
|
264
268
|
this.logger?.debug(
|
|
265
269
|
`Got ${this.mainPriceFeeds.size} main and ${this.reservePriceFeeds.size} reserve price feeds`
|
|
266
270
|
);
|
|
@@ -281,6 +285,8 @@ class PriceOracleBaseContract extends BaseContract {
|
|
|
281
285
|
* Helper method to find "attachment point" of price feed (makes sense for updatable price feeds only) -
|
|
282
286
|
* returns token (in v3.0 can be ticker) and main/reserve flag
|
|
283
287
|
*
|
|
288
|
+
* @deprecated Should be gone after v310 migration
|
|
289
|
+
*
|
|
284
290
|
* @param priceFeed
|
|
285
291
|
* @returns
|
|
286
292
|
*/
|
|
@@ -297,6 +303,9 @@ class PriceOracleBaseContract extends BaseContract {
|
|
|
297
303
|
}
|
|
298
304
|
return [void 0, false];
|
|
299
305
|
}
|
|
306
|
+
/**
|
|
307
|
+
* Returns list of addresses that should be watched for events to sync state
|
|
308
|
+
*/
|
|
300
309
|
get watchAddresses() {
|
|
301
310
|
return /* @__PURE__ */ new Set([this.address]);
|
|
302
311
|
}
|
|
@@ -323,9 +332,6 @@ class PriceOracleBaseContract extends BaseContract {
|
|
|
323
332
|
)
|
|
324
333
|
};
|
|
325
334
|
}
|
|
326
|
-
get priceFeedTree() {
|
|
327
|
-
return this.#priceFeedTree;
|
|
328
|
-
}
|
|
329
335
|
#noAnswerWarn(priceFeed, node) {
|
|
330
336
|
let label = this.labelAddress(priceFeed);
|
|
331
337
|
if (!node) {
|