|
1 | 1 | import type { Address } from "viem"; |
2 | 2 |
|
3 | | -import { iMarketCompressorAbi } from "../abi"; |
4 | | -import type { MarketData } from "../base"; |
| 3 | +import { iMarketCompressorAbi, iPriceFeedCompressorAbi } from "../abi"; |
| 4 | +import type { MarketData, PriceFeedMapEntry, PriceFeedTreeNode } from "../base"; |
5 | 5 | import { SDKConstruct } from "../base"; |
6 | 6 | import { |
7 | 7 | ADDRESS_0X0, |
8 | 8 | AP_MARKET_COMPRESSOR, |
9 | 9 | AP_MARKET_CONFIGURATOR, |
| 10 | + AP_PRICE_FEED_COMPRESSOR, |
10 | 11 | } from "../constants"; |
11 | 12 | import type { GearboxSDK } from "../GearboxSDK"; |
12 | 13 | import type { ILogger, MarketStateHuman, TVL } from "../types"; |
13 | 14 | import { AddressMap, childLogger } from "../utils"; |
| 15 | +import { simulateMulticall } from "../utils/viem"; |
14 | 16 | import type { CreditFactory } from "./CreditFactory"; |
15 | 17 | import { MarketConfiguratorContract } from "./MarketConfiguratorContract"; |
16 | 18 | import { MarketFactory } from "./MarketFactory"; |
17 | 19 | import type { PoolFactory } from "./PoolFactory"; |
| 20 | +import { rawTxToMulticallPriceUpdate } from "./pricefeeds"; |
| 21 | +import type { PriceOracleContract } from "./PriceOracleContract"; |
18 | 22 |
|
19 | 23 | export class MarketRegister extends SDKConstruct { |
20 | 24 | #logger?: ILogger; |
@@ -91,6 +95,51 @@ export class MarketRegister extends SDKConstruct { |
91 | 95 | this.#logger?.info(`loaded ${markets.length} markets`); |
92 | 96 | } |
93 | 97 |
|
| 98 | + /** |
| 99 | + * Loads new prices for given oracles from PriceFeedCompressor, defaults to all oracles |
| 100 | + * Does not update price feeds, only updates prices |
| 101 | + */ |
| 102 | + public async updatePrices(oracles?: Address[]): Promise<void> { |
| 103 | + const oraclez = oracles ?? this.markets.map(m => m.priceOracle.address); |
| 104 | + if (!oraclez.length) { |
| 105 | + return; |
| 106 | + } |
| 107 | + const { txs } = await this.sdk.priceFeeds.generatePriceFeedsUpdateTxs(); |
| 108 | + const resp = await simulateMulticall(this.provider.publicClient, { |
| 109 | + contracts: [ |
| 110 | + ...txs.map(rawTxToMulticallPriceUpdate), |
| 111 | + ...oraclez.map(o => ({ |
| 112 | + abi: iPriceFeedCompressorAbi, |
| 113 | + address: this.sdk.addressProvider.getLatestVersion( |
| 114 | + AP_PRICE_FEED_COMPRESSOR, |
| 115 | + ), |
| 116 | + functionName: "getPriceFeeds", |
| 117 | + args: [o], |
| 118 | + })), |
| 119 | + ], |
| 120 | + allowFailure: false, |
| 121 | + gas: 550_000_000n, |
| 122 | + batchSize: 0, // we cannot have price updates and compressor request in different batches |
| 123 | + }); |
| 124 | + const oraclesStates = resp.slice(txs.length) as any as Array< |
| 125 | + [PriceFeedMapEntry[], PriceFeedTreeNode[]] |
| 126 | + >; |
| 127 | + for (let i = 0; i < oraclez.length; i++) { |
| 128 | + const oracleAddr = oraclez[i]; |
| 129 | + const oracle = this.findPriceOracle(oracleAddr); |
| 130 | + const [entries, tree] = oraclesStates[i]; |
| 131 | + for (const { token, priceFeed, reserve } of entries) { |
| 132 | + const price = tree.find(n => n.baseParams.addr === priceFeed)?.answer |
| 133 | + ?.price; |
| 134 | + if (reserve && price) { |
| 135 | + oracle.reservePrices.upsert(token, price); |
| 136 | + } else if (price) { |
| 137 | + oracle.mainPrices.upsert(token, price); |
| 138 | + } |
| 139 | + } |
| 140 | + } |
| 141 | + } |
| 142 | + |
94 | 143 | public get state(): MarketData[] { |
95 | 144 | return this.markets.map(market => market.state); |
96 | 145 | } |
@@ -118,6 +167,15 @@ export class MarketRegister extends SDKConstruct { |
118 | 167 | throw new Error(`cannot find credit manager ${creditManager}`); |
119 | 168 | } |
120 | 169 |
|
| 170 | + public findPriceOracle(address: Address): PriceOracleContract { |
| 171 | + for (const market of this.markets) { |
| 172 | + if (market.priceOracle.address.toLowerCase() === address.toLowerCase()) { |
| 173 | + return market.priceOracle; |
| 174 | + } |
| 175 | + } |
| 176 | + throw new Error(`cannot find price oracle ${address}`); |
| 177 | + } |
| 178 | + |
121 | 179 | public findByCreditManager(creditManager: Address): MarketFactory { |
122 | 180 | const market = this.markets.find(m => |
123 | 181 | m.creditManagers.some( |
|
0 commit comments