Skip to content

Commit 0834a2c

Browse files
committed
feat: method to update prices
1 parent c1261c8 commit 0834a2c

File tree

5 files changed

+85
-109
lines changed

5 files changed

+85
-109
lines changed

src/sdk/accounts/CreditAccountsService.ts

Lines changed: 8 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
import type { Address, ContractFunctionArgs } from "viem";
2-
import { decodeFunctionData, encodeFunctionData } from "viem";
2+
import { encodeFunctionData } from "viem";
33

44
import {
55
iCreditAccountCompressorAbi,
66
iCreditFacadeV3MulticallAbi,
7-
iUpdatablePriceFeedAbi,
87
} from "../abi";
98
import { type CreditAccountData, SDKConstruct } from "../base";
109
import {
@@ -14,12 +13,13 @@ import {
1413
MIN_INT96,
1514
} from "../constants";
1615
import type { GearboxSDK } from "../GearboxSDK";
17-
import type {
18-
CreditFactory,
19-
IPriceFeedContract,
20-
OnDemandPriceUpdate,
21-
PriceOracleContract,
22-
UpdatePriceFeedsResult,
16+
import {
17+
type CreditFactory,
18+
type IPriceFeedContract,
19+
type OnDemandPriceUpdate,
20+
type PriceOracleContract,
21+
rawTxToMulticallPriceUpdate,
22+
type UpdatePriceFeedsResult,
2323
} from "../market";
2424
import type { MultiCall, RawTx } from "../types";
2525
import { simulateMulticall } from "../utils/viem";
@@ -434,23 +434,3 @@ export class CreditAccountsService extends SDKConstruct {
434434
return this.sdk.marketRegister.poolState.map(p => p.pool.address);
435435
}
436436
}
437-
438-
/**
439-
* Helper method to convert our RawTx into viem's multicall format
440-
* Involves decoding what was previously encoded, but it's better than adding another method to PriceFeedFactory
441-
* @param tx
442-
* @returns
443-
*/
444-
function rawTxToMulticallPriceUpdate(tx: RawTx) {
445-
const { to, callData } = tx;
446-
const { args, functionName } = decodeFunctionData({
447-
abi: iUpdatablePriceFeedAbi,
448-
data: callData,
449-
});
450-
return {
451-
abi: iUpdatablePriceFeedAbi,
452-
address: to,
453-
functionName,
454-
args,
455-
};
456-
}

src/sdk/constants/address-provider.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export const AP_PRICE_ORACLE = "PRICE_ORACLE";
1111
export const AP_ACCOUNT_FACTORY = "ACCOUNT_FACTORY";
1212
export const AP_DATA_COMPRESSOR = "DATA_COMPRESSOR";
1313
export const AP_MARKET_COMPRESSOR = "MARKET_COMPRESSOR";
14+
export const AP_PRICE_FEED_COMPRESSOR = "PRICE_FEED_COMPRESSOR";
1415
export const AP_CREDIT_ACCOUNT_COMPRESSOR = "CREDIT_ACCOUNT_COMPRESSOR";
1516
export const AP_TREASURY = "TREASURY";
1617
export const AP_GEAR_TOKEN = "GEAR_TOKEN";

src/sdk/market/PriceOracleContract.ts

Lines changed: 51 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,28 @@
11
import type { Address, Hex } from "viem";
22
import { decodeFunctionData } from "viem";
33

4-
import { iUpdatablePriceFeedAbi, priceOracleV3Abi } from "../abi";
5-
import type { PriceFeedTreeNode, PriceOracleData } from "../base";
4+
import {
5+
iPriceFeedCompressorAbi,
6+
iUpdatablePriceFeedAbi,
7+
priceOracleV3Abi,
8+
} from "../abi";
9+
import type {
10+
PriceFeedMapEntry,
11+
PriceFeedTreeNode,
12+
PriceOracleData,
13+
} from "../base";
614
import { BaseContract } from "../base";
15+
import { AP_PRICE_FEED_COMPRESSOR } from "../constants";
716
import type { GearboxSDK } from "../GearboxSDK";
817
import type { PriceOracleState } from "../state";
918
import { AddressMap } from "../utils";
19+
import { simulateMulticall } from "../utils/viem";
1020
import type {
1121
IPriceFeedContract,
1222
PriceFeedUsageType,
1323
UpdatePriceFeedsResult,
1424
} from "./pricefeeds";
15-
import { PriceFeedRef } from "./pricefeeds";
25+
import { PriceFeedRef, rawTxToMulticallPriceUpdate } from "./pricefeeds";
1626

1727
type abi = typeof priceOracleV3Abi;
1828

@@ -104,8 +114,8 @@ export class PriceOracleContract extends BaseContract<abi> {
104114
const reserve = opts?.reserve ?? true;
105115
return tokens
106116
.flatMap(t => [
107-
main ? this.mainPriceFeeds[t].priceFeed : undefined,
108-
reserve ? this.reservePriceFeeds[t].priceFeed : undefined,
117+
main ? this.mainPriceFeeds[t]?.priceFeed : undefined,
118+
reserve ? this.reservePriceFeeds[t]?.priceFeed : undefined,
109119
])
110120
.filter((f): f is IPriceFeedContract => !!f);
111121
}
@@ -205,83 +215,43 @@ export class PriceOracleContract extends BaseContract<abi> {
205215
return (amount * fromPrice * toScale) / (toPrice * fromScale);
206216
}
207217

208-
// async loadPrices(
209-
// priceUpdatesTxs: Array<RawTx>,
210-
// block: bigint,
211-
// ): Promise<{
212-
// mainPrices: Record<Address, bigint>;
213-
// reservePrices: Record<Address, bigint>;
214-
// }> {
215-
// const priceUpdateCalls: Array<MultiCallStruct> = priceUpdatesTxs.map(
216-
// tx => ({
217-
// target: tx.to,
218-
// callData: tx.callData,
219-
// allowFailure: false,
220-
// }),
221-
// );
222-
223-
// const getPricesRawCalls = (reserve: boolean): Array<MultiCallStruct> => {
224-
// return Object.keys(
225-
// reserve ? this.reservePriceFeeds : this.mainPriceFeeds,
226-
// ).map(token => ({
227-
// target: this.address,
228-
// callData: encodeFunctionData({
229-
// functionName: "getPriceRaw",
230-
// args: [token as Address, reserve],
231-
// abi: this.abi,
232-
// }),
233-
// allowFailure: true,
234-
// }));
235-
// };
236-
237-
// const { result } = await this.v3.publicClient.simulateContract({
238-
// address: MULTICALL_ADDRESS,
239-
// abi: multicall3Abi,
240-
// functionName: "aggregate3",
241-
// args: [
242-
// [
243-
// ...priceUpdateCalls,
244-
// ...getPricesRawCalls(false),
245-
// ...getPricesRawCalls(true),
246-
// ],
247-
// ],
248-
// chain: this.v3.publicClient.chain!,
249-
// account: this.v3.walletClient.account!,
250-
// gas: 550_000_000n,
251-
// // blockNumber: BigInt(block),
252-
// });
253-
254-
// const returnRawPrices = (
255-
// result as Array<{ success: boolean; returnData: Hex }>
256-
// ).slice(priceUpdateCalls.length);
257-
258-
// const prices = returnRawPrices.map(callReturn =>
259-
// callReturn.success
260-
// ? decodeFunctionResult({
261-
// functionName: "getPrice",
262-
// abi: this.abi,
263-
// data: callReturn.returnData! as Hex,
264-
// })
265-
// : 0n,
266-
// ) as Array<bigint>;
267-
268-
// const mainPrices: Record<Address, bigint> = {};
269-
// const reservePrices: Record<Address, bigint> = {};
270-
271-
// const mainPFlength = Object.keys(this.mainPriceFeeds).length;
272-
273-
// prices.forEach((price, i) => {
274-
// if (i < mainPFlength) {
275-
// mainPrices[Object.keys(this.mainPriceFeeds)[i] as Address] = price;
276-
// } else {
277-
// reservePrices[
278-
// Object.keys(this.reservePriceFeeds)[i - mainPFlength] as Address
279-
// ] = price;
280-
// }
281-
// });
218+
/**
219+
* Loads new prices for this oracle from PriceFeedCompressor
220+
* Does not update price feeds, only updates prices
221+
*/
222+
public async updatePrices(): Promise<void> {
223+
const { txs } = await this.updatePriceFeeds();
224+
const resp = await simulateMulticall(this.provider.publicClient, {
225+
contracts: [
226+
...txs.map(rawTxToMulticallPriceUpdate),
227+
{
228+
abi: iPriceFeedCompressorAbi,
229+
address: this.sdk.addressProvider.getLatestVersion(
230+
AP_PRICE_FEED_COMPRESSOR,
231+
),
232+
functionName: "getPriceFeeds",
233+
args: [this.address],
234+
},
235+
],
236+
allowFailure: false,
237+
gas: 550_000_000n,
238+
batchSize: 0, // we cannot have price updates and compressor request in different batches
239+
});
240+
const [entries, tree] = resp.pop() as [
241+
PriceFeedMapEntry[],
242+
PriceFeedTreeNode[],
243+
];
282244

283-
// return { mainPrices, reservePrices };
284-
// }
245+
entries.forEach(({ token, priceFeed, reserve }) => {
246+
const price = tree.find(n => n.baseParams.addr === priceFeed)?.answer
247+
?.price;
248+
if (reserve && price) {
249+
this.reservePrices.upsert(token, price);
250+
} else if (price) {
251+
this.mainPrices.upsert(token, price);
252+
}
253+
});
254+
}
285255

286256
#labelPriceFeed(
287257
address: Address,

src/sdk/market/pricefeeds/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export * from "./PriceFeedRef";
1313
export * from "./PriceFeedsRegister";
1414
export * from "./RedstonePriceFeed";
1515
export * from "./types";
16+
export * from "./utils";
1617
export * from "./WstETHPriceFeed";
1718
export * from "./YearnPriceFeed";
1819
export * from "./ZeroPriceFeed";

src/sdk/market/pricefeeds/utils.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { decodeFunctionData } from "viem";
2+
3+
import { iUpdatablePriceFeedAbi } from "../../abi";
4+
import type { RawTx } from "../../types";
5+
6+
/**
7+
* Helper method to convert our RawTx into viem's multicall format
8+
* Involves decoding what was previously encoded, but it's better than adding another method to PriceFeedFactory
9+
* @param tx
10+
* @returns
11+
*/
12+
export function rawTxToMulticallPriceUpdate(tx: RawTx) {
13+
const { to, callData } = tx;
14+
const { args, functionName } = decodeFunctionData({
15+
abi: iUpdatablePriceFeedAbi,
16+
data: callData,
17+
});
18+
return {
19+
abi: iUpdatablePriceFeedAbi,
20+
address: to,
21+
functionName,
22+
args,
23+
};
24+
}

0 commit comments

Comments
 (0)