@gearbox-protocol/deploy-tools 5.3.17 → 5.3.19

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.
Files changed (2) hide show
  1. package/dist/index.mjs +2349 -2339
  2. package/package.json +2 -2
package/dist/index.mjs CHANGED
@@ -134776,7 +134776,7 @@ var require_sonic_boom = __commonJS({
134776
134776
  if (!(this instanceof SonicBoom)) {
134777
134777
  return new SonicBoom(opts);
134778
134778
  }
134779
- let { fd, dest, minLength, maxLength, maxWrite, periodicFlush, sync, append = true, mkdir, retryEAGAIN, fsync, contentMode, mode } = opts || {};
134779
+ let { fd, dest, minLength, maxLength, maxWrite, periodicFlush, sync, append = true, mkdir: mkdir3, retryEAGAIN, fsync, contentMode, mode } = opts || {};
134780
134780
  fd = fd || dest;
134781
134781
  this._len = 0;
134782
134782
  this.fd = -1;
@@ -134801,7 +134801,7 @@ var require_sonic_boom = __commonJS({
134801
134801
  this.append = append || false;
134802
134802
  this.mode = mode;
134803
134803
  this.retryEAGAIN = retryEAGAIN || (() => true);
134804
- this.mkdir = mkdir || false;
134804
+ this.mkdir = mkdir3 || false;
134805
134805
  let fsWriteSync;
134806
134806
  let fsWrite;
134807
134807
  if (contentMode === kContentModeBuffer) {
@@ -375523,1733 +375523,6 @@ var PoolFactory = class extends SDKConstruct {
375523
375523
  };
375524
375524
  }
375525
375525
  };
375526
- var PriceFeedRef = class extends SDKConstruct {
375527
- address;
375528
- stalenessPeriod;
375529
- #priceFeed;
375530
- constructor(sdk, address, stalenessPeriod) {
375531
- super(sdk);
375532
- this.address = address;
375533
- this.stalenessPeriod = stalenessPeriod;
375534
- }
375535
- get priceFeed() {
375536
- if (!this.#priceFeed) {
375537
- this.#priceFeed = this.sdk.priceFeeds.mustGet(this.address);
375538
- }
375539
- return this.#priceFeed;
375540
- }
375541
- stateHuman(raw = true) {
375542
- return {
375543
- ...this.priceFeed.stateHuman(raw),
375544
- stalenessPeriod: formatDuration2(this.stalenessPeriod)
375545
- };
375546
- }
375547
- };
375548
- var AbstractPriceFeedContract = class extends BaseContract {
375549
- /**
375550
- * True if the contract deployed at this address implements IUpdatablePriceFeed interface
375551
- */
375552
- #updatable;
375553
- #decimals;
375554
- #underlyingPriceFeeds;
375555
- #skipCheck;
375556
- hasLowerBoundCap = false;
375557
- constructor(sdk, args) {
375558
- super(sdk, {
375559
- abi: args.abi,
375560
- addr: args.baseParams.addr,
375561
- name: args.name,
375562
- contractType: args.baseParams.contractType,
375563
- version: args.baseParams.version
375564
- });
375565
- this.#decimals = args.decimals;
375566
- this.#updatable = args.updatable;
375567
- this.#skipCheck = args.skipCheck;
375568
- if (args.underlyingFeeds && args.underlyingStalenessPeriods) {
375569
- this.#underlyingPriceFeeds = args.underlyingFeeds.map(
375570
- (address, i) => new PriceFeedRef(
375571
- this.sdk,
375572
- address,
375573
- args.underlyingStalenessPeriods[i]
375574
- )
375575
- );
375576
- }
375577
- }
375578
- get loaded() {
375579
- return this.#decimals !== void 0;
375580
- }
375581
- get decimals() {
375582
- if (this.#decimals === void 0) {
375583
- throw new Error("price feed has been initialized with BaseParams only");
375584
- }
375585
- return this.#decimals;
375586
- }
375587
- get updatable() {
375588
- if (this.#updatable === void 0) {
375589
- throw new Error("price feed has been initialized with BaseParams only");
375590
- }
375591
- return this.#updatable;
375592
- }
375593
- get skipCheck() {
375594
- if (this.#skipCheck === void 0) {
375595
- throw new Error("price feed has been initialized with BaseParams only");
375596
- }
375597
- return this.#skipCheck;
375598
- }
375599
- get underlyingPriceFeeds() {
375600
- if (!this.#underlyingPriceFeeds) {
375601
- throw new Error("price feed has been initialized with BaseParams only");
375602
- }
375603
- return this.#underlyingPriceFeeds;
375604
- }
375605
- get priceFeedType() {
375606
- return this.contractType;
375607
- }
375608
- stateHuman(raw = true) {
375609
- return {
375610
- ...super.stateHuman(raw),
375611
- contractType: this.priceFeedType,
375612
- skipCheck: this.skipCheck,
375613
- pricefeeds: this.underlyingPriceFeeds.map((f) => f.stateHuman(raw))
375614
- };
375615
- }
375616
- async currentLowerBound() {
375617
- return await this.sdk.provider.publicClient.readContract({
375618
- abi: ilpPriceFeedAbi,
375619
- address: this.address,
375620
- functionName: "lowerBound"
375621
- });
375622
- }
375623
- async answer(overrides) {
375624
- const lastRoundData = await this.sdk.provider.publicClient.readContract({
375625
- abi: ilpPriceFeedAbi,
375626
- address: this.address,
375627
- functionName: "latestRoundData",
375628
- ...overrides
375629
- });
375630
- return lastRoundData[1];
375631
- }
375632
- updatableDependencies() {
375633
- const underlying = this.underlyingPriceFeeds.flatMap(
375634
- (f) => f.priceFeed.updatableDependencies()
375635
- );
375636
- return this.updatable ? [this, ...underlying] : underlying;
375637
- }
375638
- };
375639
- var LOWER_BOUND_FACTOR = 99n;
375640
- var AbstractLPPriceFeedContract = class _AbstractLPPriceFeedContract extends AbstractPriceFeedContract {
375641
- lpContract;
375642
- lpToken;
375643
- lowerBound;
375644
- upperBound;
375645
- constructor(sdk, args) {
375646
- super(sdk, { ...args, decimals: 8 });
375647
- this.hasLowerBoundCap = true;
375648
- const decoder = decodeAbiParameters(
375649
- [
375650
- { type: "address", name: "lpToken" },
375651
- { type: "address", name: "lpContract" },
375652
- { type: "uint256", name: "lowerBound" },
375653
- { type: "uint256", name: "upperBound" },
375654
- // { type: "bool", name: "updateBoundsAllowed" },
375655
- // { type: "uint40", name: "lastBoundsUpdate" },
375656
- { type: "int256", name: "aggregatePrice" },
375657
- { type: "uint256", name: "lPExchangeRate" },
375658
- { type: "uint256", name: "scale" }
375659
- ],
375660
- hexToBytes(args.baseParams.serializedParams)
375661
- );
375662
- this.lpToken = decoder[0];
375663
- this.lpContract = decoder[1];
375664
- this.lowerBound = decoder[2];
375665
- this.upperBound = decoder[3];
375666
- }
375667
- async getLowerBound() {
375668
- const value = await this.getValue();
375669
- const lowerBound = _AbstractLPPriceFeedContract.toLowerBound(value);
375670
- this.logger?.debug(
375671
- `Lowerbound for ${this.labelAddress(this.address)}: ${lowerBound}`
375672
- );
375673
- return lowerBound;
375674
- }
375675
- static toLowerBound(value) {
375676
- return value * LOWER_BOUND_FACTOR / 100n;
375677
- }
375678
- stateHuman(raw) {
375679
- return {
375680
- ...super.stateHuman(raw),
375681
- lpContract: this.lpContract,
375682
- lpToken: this.lpToken,
375683
- lowerBound: this.lowerBound,
375684
- upperBound: this.upperBound
375685
- };
375686
- }
375687
- };
375688
- var BalancerStablePriceFeedContract = class extends AbstractLPPriceFeedContract {
375689
- constructor(sdk, args) {
375690
- super(sdk, {
375691
- ...args,
375692
- name: "BalancerStablePriceFeed",
375693
- abi: bptStablePriceFeedAbi
375694
- });
375695
- }
375696
- async getValue() {
375697
- return await this.sdk.provider.publicClient.readContract({
375698
- abi: iBalancerStablePoolAbi,
375699
- address: this.lpContract,
375700
- functionName: "getRate"
375701
- });
375702
- }
375703
- };
375704
- var BalancerWeightedPriceFeedContract = class extends AbstractLPPriceFeedContract {
375705
- vault;
375706
- poolId;
375707
- weights;
375708
- constructor(sdk, args) {
375709
- const decoded = decodeAbiParameters(
375710
- [
375711
- { type: "bytes", name: "superParams" },
375712
- { type: "address", name: "vault" },
375713
- { type: "bytes32", name: "poolId" },
375714
- { type: "uint256[8]", name: "weights" }
375715
- ],
375716
- hexToBytes(args.baseParams.serializedParams)
375717
- );
375718
- super(sdk, {
375719
- ...args,
375720
- baseParams: {
375721
- ...args.baseParams,
375722
- serializedParams: decoded[0]
375723
- },
375724
- name: "BalancerWeighedPriceFeed",
375725
- abi: bptWeightedPriceFeedAbi
375726
- });
375727
- this.vault = decoded[1];
375728
- this.poolId = decoded[2];
375729
- this.weights = decoded[3];
375730
- }
375731
- async getValue() {
375732
- return await this.sdk.provider.publicClient.readContract({
375733
- abi: iBalancerWeightedPoolAbi,
375734
- address: this.lpContract,
375735
- functionName: "getRate"
375736
- });
375737
- }
375738
- stateHuman(raw) {
375739
- return {
375740
- ...super.stateHuman(raw),
375741
- contractType: "PF_BALANCER_WEIGHTED_LP_ORACLE",
375742
- vault: this.vault,
375743
- poolId: this.poolId,
375744
- weights: [...this.weights]
375745
- };
375746
- }
375747
- };
375748
- var BoundedPriceFeedContract = class extends AbstractPriceFeedContract {
375749
- upperBound;
375750
- constructor(sdk, args) {
375751
- super(sdk, { ...args, name: "BoundedPriceFeed", abi: boundedPriceFeedAbi });
375752
- const decoder = decodeAbiParameters(
375753
- [
375754
- { type: "int256" }
375755
- // upperBound
375756
- ],
375757
- args.baseParams.serializedParams
375758
- );
375759
- this.upperBound = decoder[0];
375760
- }
375761
- stateHuman(raw = true) {
375762
- return {
375763
- ...super.stateHuman(raw),
375764
- contractType: "PF_BOUNDED_ORACLE",
375765
- upperBound: this.upperBound
375766
- };
375767
- }
375768
- };
375769
- var ChainlinkPriceFeedContract = class extends AbstractPriceFeedContract {
375770
- constructor(sdk, args) {
375771
- super(sdk, {
375772
- ...args,
375773
- name: "ChainlinkPriceFeed",
375774
- abi: chainlinkReadableAggregatorAbi
375775
- });
375776
- }
375777
- };
375778
- var CompositePriceFeedContract = class extends AbstractPriceFeedContract {
375779
- constructor(sdk, args) {
375780
- super(sdk, {
375781
- ...args,
375782
- name: "CompositePriceFeed",
375783
- abi: compositePriceFeedAbi
375784
- });
375785
- }
375786
- get targetToBasePriceFeed() {
375787
- return this.underlyingPriceFeeds[0];
375788
- }
375789
- get baseToUsdPriceFeed() {
375790
- return this.underlyingPriceFeeds[1];
375791
- }
375792
- };
375793
- var CurveCryptoPriceFeedContract = class extends AbstractLPPriceFeedContract {
375794
- constructor(sdk, args) {
375795
- super(sdk, {
375796
- ...args,
375797
- name: "CurveCryptoPriceFeed",
375798
- abi: curveCryptoLpPriceFeedAbi
375799
- });
375800
- }
375801
- async getValue() {
375802
- return await this.sdk.provider.publicClient.readContract({
375803
- abi: iCurvePoolAbi,
375804
- address: this.lpContract,
375805
- functionName: "get_virtual_price"
375806
- });
375807
- }
375808
- };
375809
- var CurveStablePriceFeedContract = class extends AbstractLPPriceFeedContract {
375810
- constructor(sdk, args) {
375811
- super(sdk, {
375812
- ...args,
375813
- name: "CurveStablePriceFeed",
375814
- abi: curveStableLpPriceFeedAbi
375815
- });
375816
- }
375817
- async getValue() {
375818
- return await this.sdk.provider.publicClient.readContract({
375819
- abi: iCurvePoolAbi,
375820
- address: this.lpContract,
375821
- functionName: "get_virtual_price"
375822
- });
375823
- }
375824
- };
375825
- var CurveUSDPriceFeedContract = class extends AbstractLPPriceFeedContract {
375826
- constructor(sdk, args) {
375827
- super(sdk, {
375828
- ...args,
375829
- name: "CurveUSDPriceFeed",
375830
- abi: curveUsdPriceFeedAbi
375831
- });
375832
- }
375833
- async getValue() {
375834
- return await this.sdk.provider.publicClient.readContract({
375835
- abi: iCurvePoolAbi,
375836
- address: this.lpContract,
375837
- functionName: "get_virtual_price"
375838
- });
375839
- }
375840
- };
375841
- var Erc4626PriceFeedContract = class extends AbstractLPPriceFeedContract {
375842
- constructor(sdk, args) {
375843
- super(sdk, {
375844
- ...args,
375845
- name: "ERC4626PriceFeed",
375846
- abi: erc4626PriceFeedAbi
375847
- });
375848
- }
375849
- async getValue() {
375850
- const decimals2 = await this.sdk.provider.publicClient.readContract({
375851
- abi: erc20Abi2,
375852
- address: this.lpContract,
375853
- functionName: "decimals"
375854
- });
375855
- const price = await this.sdk.provider.publicClient.readContract({
375856
- abi: erc4626Abi,
375857
- address: this.lpContract,
375858
- functionName: "convertToAssets",
375859
- args: [10n ** BigInt(decimals2)]
375860
- });
375861
- return price;
375862
- }
375863
- };
375864
- var MellowLRTPriceFeedContract = class extends AbstractLPPriceFeedContract {
375865
- constructor(sdk, args) {
375866
- super(sdk, {
375867
- ...args,
375868
- name: "MellowLRTPriceFeed",
375869
- abi: mellowLrtPriceFeedAbi
375870
- });
375871
- }
375872
- async getValue() {
375873
- const stack = await this.sdk.provider.publicClient.readContract({
375874
- abi: iMellowVaultAbi,
375875
- address: this.lpContract,
375876
- functionName: "calculateStack"
375877
- });
375878
- return stack.totalValue * BigInt(1e18) / stack.totalSupply;
375879
- }
375880
- };
375881
- var abi29 = pendleTWAPPTPriceFeedAbi;
375882
- var PendleTWAPPTPriceFeed = class extends AbstractPriceFeedContract {
375883
- market;
375884
- sy;
375885
- yt;
375886
- expiry;
375887
- twapWindow;
375888
- priceToSy;
375889
- constructor(sdk, args) {
375890
- super(sdk, {
375891
- ...args,
375892
- name: "PendleTWAPPTPriceFeed",
375893
- abi: abi29
375894
- });
375895
- const decoded = decodeAbiParameters(
375896
- [
375897
- { type: "address", name: "market" },
375898
- { type: "address", name: "sy" },
375899
- { type: "address", name: "yt" },
375900
- { type: "uint256", name: "expiry" },
375901
- { type: "uint32", name: "twapWindow" },
375902
- { type: "bool", name: "priceToSy" }
375903
- ],
375904
- args.baseParams.serializedParams
375905
- );
375906
- this.market = decoded[0];
375907
- this.sy = decoded[1];
375908
- this.yt = decoded[2];
375909
- this.expiry = decoded[3];
375910
- this.twapWindow = decoded[4];
375911
- this.priceToSy = decoded[5];
375912
- }
375913
- };
375914
- var Hooks = class {
375915
- #reg = {};
375916
- addHook(hookName, fn) {
375917
- if (!this.#reg[hookName]) {
375918
- this.#reg[hookName] = [];
375919
- }
375920
- this.#reg[hookName].push(fn);
375921
- }
375922
- removeHook(hookName, fn) {
375923
- if (!this.#reg[hookName]) {
375924
- return;
375925
- }
375926
- this.#reg[hookName] = this.#reg[hookName]?.filter((hookFn) => hookFn !== fn) ?? [];
375927
- }
375928
- async triggerHooks(hookName, ...args) {
375929
- if (!this.#reg[hookName]) {
375930
- return;
375931
- }
375932
- for (const fn of this.#reg[hookName]) {
375933
- await fn(...args);
375934
- }
375935
- }
375936
- };
375937
- var RedstonePriceFeedContract = class extends AbstractPriceFeedContract {
375938
- dataServiceId;
375939
- dataId;
375940
- signers;
375941
- signersThreshold;
375942
- constructor(sdk, args) {
375943
- super(sdk, {
375944
- ...args,
375945
- name: `RedstonePriceFeed`,
375946
- abi: redstonePriceFeedAbi
375947
- });
375948
- const decoder = decodeAbiParameters(
375949
- [
375950
- { type: "address" },
375951
- // [0]: pf.token(),
375952
- { type: "bytes32" },
375953
- // [1]: pf.dataFeedId(),
375954
- { type: "address" },
375955
- // [2]: pf.signerAddress0(),
375956
- { type: "address" },
375957
- // [3]: pf.signerAddress1(),
375958
- { type: "address" },
375959
- // [4]: pf.signerAddress2(),
375960
- { type: "address" },
375961
- // [5]: pf.signerAddress3(),
375962
- { type: "address" },
375963
- // [6]: pf.signerAddress4(),
375964
- { type: "address" },
375965
- // [7]: pf.signerAddress5()
375966
- { type: "address" },
375967
- // [8]: pf.signerAddress6(),
375968
- { type: "address" },
375969
- // [9]: pf.signerAddress7(),
375970
- { type: "address" },
375971
- // [10]: pf.signerAddress8(),
375972
- { type: "address" },
375973
- // [11]: pf.signerAddress9(),
375974
- { type: "uint8" },
375975
- // [12]: pf.getUniqueSignersThreshold()
375976
- { type: "uint128" },
375977
- // [13]: pf.lastPrice(),
375978
- { type: "uint40" }
375979
- // [14]: pf.lastPayloadTimestamp()
375980
- ],
375981
- args.baseParams.serializedParams
375982
- );
375983
- this.dataId = bytesToString(toBytes(decoder[1])).replaceAll("\0", "");
375984
- this.signers = decoder.slice(2, 11);
375985
- this.signersThreshold = Number(decoder[12]);
375986
- this.dataServiceId = ["GMX", "BAL"].includes(this.dataId) ? "redstone-arbitrum-prod" : "redstone-primary-prod";
375987
- }
375988
- stateHuman(raw = true) {
375989
- return {
375990
- ...super.stateHuman(raw),
375991
- contractType: "PF_REDSTONE_ORACLE",
375992
- dataId: this.dataId,
375993
- signers: this.signers,
375994
- signersThreshold: this.signersThreshold,
375995
- skipCheck: true
375996
- };
375997
- }
375998
- };
375999
- var RedstoneUpdater = class extends SDKConstruct {
376000
- #logger;
376001
- #cache = /* @__PURE__ */ new Map();
376002
- #historicalTimestampMs;
376003
- constructor(sdk) {
376004
- super(sdk);
376005
- this.#logger = childLogger("RedstoneUpdater", sdk.logger);
376006
- }
376007
- setHistoricalTimestamp(timestampMs) {
376008
- this.#historicalTimestampMs = 6e4 * Math.floor(timestampMs / 6e4);
376009
- }
376010
- async getUpdateTxs(feeds, logContext = {}) {
376011
- this.#logger?.debug(
376012
- logContext,
376013
- `generating update transactions for ${feeds.length} redstone price feeds`
376014
- );
376015
- const groupedFeeds = {};
376016
- const priceFeeds = /* @__PURE__ */ new Map();
376017
- for (const feed of feeds) {
376018
- const key = `${feed.dataServiceId}:${feed.signersThreshold}`;
376019
- if (!groupedFeeds[key]) {
376020
- groupedFeeds[key] = /* @__PURE__ */ new Set();
376021
- }
376022
- groupedFeeds[key].add(feed.dataId);
376023
- priceFeeds.set(feed.dataId, feed);
376024
- }
376025
- const results = [];
376026
- for (const [key, group] of Object.entries(groupedFeeds)) {
376027
- const [dataServiceId, signersStr] = key.split(":");
376028
- const uniqueSignersCount = parseInt(signersStr, 10);
376029
- const payloads = await this.#getPayloads(
376030
- dataServiceId,
376031
- group,
376032
- uniqueSignersCount
376033
- );
376034
- for (const { dataFeedId, data, timestamp } of payloads) {
376035
- const priceFeed = priceFeeds.get(dataFeedId);
376036
- if (!priceFeed) {
376037
- throw new Error(`cannot get price feed address for ${dataFeedId}`);
376038
- }
376039
- results.push({
376040
- priceFeed: priceFeed.address.toLowerCase(),
376041
- tx: priceFeed.createRawTx({
376042
- functionName: "updatePrice",
376043
- args: [data],
376044
- description: `updating price for ${dataFeedId} [${priceFeed.address}]`
376045
- }),
376046
- timestamp
376047
- });
376048
- }
376049
- }
376050
- this.#logger?.debug(
376051
- logContext,
376052
- `generated ${results.length} update transactions for redstone price feeds`
376053
- );
376054
- return results;
376055
- }
376056
- /**
376057
- * Gets redstone payloads in one request for multiple feeds with the same dataServiceId and uniqueSignersCount
376058
- * If historicalTimestamp is set, responses will be cached
376059
- * @param dataServiceId
376060
- * @param dataFeedsIds
376061
- * @param uniqueSignersCount
376062
- * @returns
376063
- */
376064
- async #getPayloads(dataServiceId, dataFeedsIds, uniqueSignersCount) {
376065
- this.#logger?.debug(
376066
- `getting redstone payloads for ${dataFeedsIds.size} data feeds in ${dataServiceId} with ${uniqueSignersCount} signers: ${Array.from(dataFeedsIds).join(", ")}`
376067
- );
376068
- const fromCache = [];
376069
- const uncached = [];
376070
- for (const dataFeedId of dataFeedsIds) {
376071
- const key = cacheKey2(
376072
- dataServiceId,
376073
- dataFeedId,
376074
- uniqueSignersCount,
376075
- this.#historicalTimestampMs
376076
- );
376077
- const cached = this.#cache.get(key);
376078
- if (this.#historicalTimestampMs && !!cached) {
376079
- fromCache.push(cached);
376080
- } else {
376081
- uncached.push(dataFeedId);
376082
- }
376083
- }
376084
- const fromRedstone = await this.#fetchPayloads(
376085
- dataServiceId,
376086
- new Set(uncached),
376087
- uniqueSignersCount
376088
- );
376089
- if (this.#historicalTimestampMs) {
376090
- for (const resp of fromRedstone) {
376091
- const key = cacheKey2(
376092
- dataServiceId,
376093
- resp.dataFeedId,
376094
- uniqueSignersCount,
376095
- this.#historicalTimestampMs
376096
- );
376097
- this.#cache.set(key, resp);
376098
- }
376099
- }
376100
- this.#logger?.debug(
376101
- `got ${fromRedstone.length} new redstone updates and ${fromCache.length} from cache`
376102
- );
376103
- return [...fromCache, ...fromRedstone];
376104
- }
376105
- /**
376106
- * Fetches redstone payloads in one request for multiple feeds with the same dataServiceId and uniqueSignersCount
376107
- * Payloads are loaded in one request to avoid redstone rate limit
376108
- * @param dataServiceId
376109
- * @param dataFeedsIds
376110
- * @param uniqueSignersCount
376111
- * @returns
376112
- */
376113
- async #fetchPayloads(dataServiceId, dataFeedsIds, uniqueSignersCount) {
376114
- if (dataFeedsIds.size === 0) {
376115
- return [];
376116
- }
376117
- const dataPackagesIds = Array.from(dataFeedsIds);
376118
- const tsStr = this.#historicalTimestampMs ? ` with historical timestamp ${this.#historicalTimestampMs}` : "";
376119
- this.#logger?.debug(
376120
- `fetching redstone payloads for ${dataFeedsIds.size} data feeds in ${dataServiceId} with ${uniqueSignersCount} signers: ${dataPackagesIds.join(", ")}${tsStr}`
376121
- );
376122
- const wrapper = new import_evm_connector.DataServiceWrapper({
376123
- dataServiceId,
376124
- dataPackagesIds,
376125
- uniqueSignersCount,
376126
- historicalTimestamp: this.#historicalTimestampMs
376127
- });
376128
- const dataPayload = await wrapper.prepareRedstonePayload(true);
376129
- const parsed = import_redstone_protocol.RedstonePayload.parse(toBytes(`0x${dataPayload}`));
376130
- const packagesByDataFeedId = groupDataPackages(parsed.signedDataPackages);
376131
- return dataPackagesIds.map((dataFeedId) => {
376132
- const signedDataPackages = packagesByDataFeedId[dataFeedId];
376133
- if (!signedDataPackages) {
376134
- throw new Error(`cannot find data packages for ${dataFeedId}`);
376135
- }
376136
- if (signedDataPackages.length !== uniqueSignersCount) {
376137
- throw new Error(
376138
- `got ${signedDataPackages.length} data packages for ${dataFeedId}, but expected ${uniqueSignersCount}`
376139
- );
376140
- }
376141
- return getCalldataWithTimestamp(
376142
- dataFeedId,
376143
- signedDataPackages,
376144
- wrapper.getUnsignedMetadata()
376145
- );
376146
- });
376147
- }
376148
- };
376149
- function cacheKey2(dataServiceId, dataFeedId, uniqueSignersCount, historicalTimestamp = 0) {
376150
- return `${dataServiceId}:${dataFeedId}:${uniqueSignersCount}:${historicalTimestamp}`;
376151
- }
376152
- function groupDataPackages(signedDataPackages) {
376153
- const packagesByDataFeedId = {};
376154
- for (const p of signedDataPackages) {
376155
- const { dataPoints } = p.dataPackage;
376156
- const dataFeedId0 = dataPoints[0].dataFeedId;
376157
- for (const dp of dataPoints) {
376158
- if (dp.dataFeedId !== dataFeedId0) {
376159
- throw new Error(
376160
- `data package contains data points with different dataFeedIds: ${dp.dataFeedId} and ${dataFeedId0}`
376161
- );
376162
- }
376163
- }
376164
- if (!packagesByDataFeedId[dataFeedId0]) {
376165
- packagesByDataFeedId[dataFeedId0] = [];
376166
- }
376167
- packagesByDataFeedId[dataFeedId0].push(p);
376168
- }
376169
- return packagesByDataFeedId;
376170
- }
376171
- function getCalldataWithTimestamp(dataFeedId, packages, unsignedMetadata) {
376172
- const originalPayload = import_redstone_protocol.RedstonePayload.prepare(packages, unsignedMetadata);
376173
- const originalPayloadLength = originalPayload.length / 2;
376174
- const bytesToAdd = 32 - originalPayloadLength % 32;
376175
- const newUnsignedMetadata = unsignedMetadata + "_".repeat(bytesToAdd);
376176
- const payload = import_redstone_protocol.RedstonePayload.prepare(packages, newUnsignedMetadata);
376177
- let timestamp = 0;
376178
- for (const p of packages) {
376179
- const newTimestamp = p.dataPackage.timestampMilliseconds / 1e3;
376180
- if (timestamp === 0) {
376181
- timestamp = newTimestamp;
376182
- } else if (timestamp !== newTimestamp) {
376183
- throw new Error("Timestamps are not equal");
376184
- }
376185
- }
376186
- return {
376187
- dataFeedId,
376188
- data: encodeAbiParameters(
376189
- [{ type: "uint256" }, { type: "bytes" }],
376190
- [BigInt(timestamp), `0x${payload}`]
376191
- ),
376192
- timestamp
376193
- };
376194
- }
376195
- var WstETHPriceFeedContract = class extends AbstractLPPriceFeedContract {
376196
- constructor(sdk, args) {
376197
- super(sdk, {
376198
- ...args,
376199
- name: "WstETHPriceFeed",
376200
- abi: wstEthPriceFeedAbi
376201
- });
376202
- }
376203
- async getValue() {
376204
- return await this.sdk.provider.publicClient.readContract({
376205
- abi: iwstEthAbi,
376206
- address: this.lpContract,
376207
- functionName: "stEthPerToken"
376208
- });
376209
- }
376210
- };
376211
- var YearnPriceFeedContract = class extends AbstractLPPriceFeedContract {
376212
- constructor(sdk, args) {
376213
- super(sdk, {
376214
- ...args,
376215
- name: "YearnPriceFeed",
376216
- abi: yearnPriceFeedAbi
376217
- });
376218
- }
376219
- async getValue() {
376220
- return await this.sdk.provider.publicClient.readContract({
376221
- abi: iyVaultAbi,
376222
- address: this.lpContract,
376223
- functionName: "pricePerShare"
376224
- });
376225
- }
376226
- };
376227
- var ZeroPriceFeedContract = class extends AbstractPriceFeedContract {
376228
- constructor(sdk, args) {
376229
- super(sdk, {
376230
- ...args,
376231
- name: "ZeroPriceFeed",
376232
- abi: zeroPriceFeedAbi,
376233
- decimals: 8
376234
- });
376235
- }
376236
- };
376237
- var PriceFeedRegister = class extends SDKConstruct {
376238
- logger;
376239
- #hooks = new Hooks();
376240
- #feeds = new AddressMap();
376241
- #redstoneUpdater;
376242
- constructor(sdk) {
376243
- super(sdk);
376244
- this.logger = childLogger("PriceFeedRegister", sdk.logger);
376245
- this.#redstoneUpdater = new RedstoneUpdater(sdk);
376246
- }
376247
- addHook = this.#hooks.addHook.bind(this.#hooks);
376248
- removeHook = this.#hooks.removeHook.bind(this.#hooks);
376249
- /**
376250
- * Returns RawTxs to update price feeds
376251
- * @param priceFeeds top-level price feeds, actual updatable price feeds will be derived. If not provided will use all price feeds that are attached
376252
- * @param logContext extra information for logging
376253
- * @returns
376254
- */
376255
- async generatePriceFeedsUpdateTxs(priceFeeds, logContext = {}) {
376256
- const updateables = priceFeeds ? priceFeeds.flatMap((pf) => pf.updatableDependencies()) : this.#feeds.values();
376257
- return this.#generatePriceFeedsUpdateTxs(updateables, logContext);
376258
- }
376259
- has(address) {
376260
- return this.#feeds.has(address);
376261
- }
376262
- mustGet(address) {
376263
- return this.#feeds.mustGet(address);
376264
- }
376265
- getOrCreate(data) {
376266
- const existing = this.#feeds.get(data.baseParams.addr);
376267
- if (existing?.loaded) {
376268
- return existing;
376269
- }
376270
- const feed = this.#create(data);
376271
- this.#feeds.upsert(data.baseParams.addr, feed);
376272
- return feed;
376273
- }
376274
- /**
376275
- * Set redstone historical timestamp
376276
- * @param timestampMs in milliseconds, or true to use timestamp from attach block
376277
- */
376278
- setRedstoneHistoricalTimestamp(timestampMs) {
376279
- const ts = timestampMs === true ? Number(this.sdk.timestamp) * 1e3 : timestampMs;
376280
- this.#redstoneUpdater.setHistoricalTimestamp(ts);
376281
- }
376282
- /**
376283
- * Loads PARTIAL information about all updatable price feeds from MarketCompressor
376284
- * This can later be used to load price feed updates
376285
- */
376286
- async preloadUpdatablePriceFeeds(marketConfigurators, pools) {
376287
- const feedsData = await this.#loadUpdatablePriceFeeds(
376288
- marketConfigurators,
376289
- pools
376290
- );
376291
- for (const data of feedsData) {
376292
- const feed = this.#create({ baseParams: data });
376293
- this.#feeds.upsert(feed.address, feed);
376294
- }
376295
- }
376296
- /**
376297
- * Generates price update transaction via multicall3 without any market data knowledge
376298
- * @param marketConfigurators
376299
- * @param pools
376300
- * @returns
376301
- */
376302
- async getUpdatePriceFeedsTx(marketConfigurators, pools) {
376303
- const feedsData = await this.#loadUpdatablePriceFeeds(
376304
- marketConfigurators,
376305
- pools
376306
- );
376307
- const feeds = feedsData.map((data) => this.#create({ baseParams: data }));
376308
- const updates = await this.#generatePriceFeedsUpdateTxs(feeds);
376309
- return createRawTx(
376310
- getChainContractAddress({
376311
- chain: this.sdk.provider.chain,
376312
- contract: "multicall3"
376313
- }),
376314
- {
376315
- abi: multicall3Abi,
376316
- functionName: "aggregate3",
376317
- args: [
376318
- updates.txs.map((tx) => ({
376319
- target: tx.to,
376320
- allowFailure: false,
376321
- callData: tx.callData
376322
- }))
376323
- ]
376324
- }
376325
- );
376326
- }
376327
- async #generatePriceFeedsUpdateTxs(updateables, logContext = {}) {
376328
- const txs = [];
376329
- const redstonePFs = [];
376330
- for (const pf of updateables) {
376331
- if (pf instanceof RedstonePriceFeedContract) {
376332
- redstonePFs.push(pf);
376333
- }
376334
- }
376335
- let maxTimestamp = 0;
376336
- if (redstonePFs.length > 0) {
376337
- const redstoneUpdates = await this.#redstoneUpdater.getUpdateTxs(
376338
- redstonePFs,
376339
- logContext
376340
- );
376341
- for (const { tx, timestamp } of redstoneUpdates) {
376342
- if (timestamp > maxTimestamp) {
376343
- maxTimestamp = timestamp;
376344
- }
376345
- txs.push(tx);
376346
- }
376347
- }
376348
- const result = { txs, timestamp: maxTimestamp };
376349
- this.logger?.debug(
376350
- logContext,
376351
- `generated ${txs.length} price feed update transactions, timestamp: ${maxTimestamp}`
376352
- );
376353
- if (txs.length) {
376354
- await this.#hooks.triggerHooks("updatesGenerated", result);
376355
- }
376356
- return result;
376357
- }
376358
- async #loadUpdatablePriceFeeds(marketConfigurators, pools) {
376359
- const marketCompressorAddress = this.sdk.addressProvider.getAddress(
376360
- AP_MARKET_COMPRESSOR,
376361
- 310
376362
- );
376363
- const configurators = marketConfigurators ?? this.sdk.marketRegister.marketConfigurators.map((mc) => mc.address);
376364
- this.logger?.debug(
376365
- { configurators, pools },
376366
- "calling getUpdatablePriceFeeds"
376367
- );
376368
- const result = await this.provider.publicClient.readContract({
376369
- address: marketCompressorAddress,
376370
- abi: iMarketCompressorAbi,
376371
- functionName: "getUpdatablePriceFeeds",
376372
- args: [
376373
- {
376374
- configurators,
376375
- pools: pools ?? [],
376376
- underlying: ADDRESS_0X0
376377
- }
376378
- ],
376379
- // It's passed as ...rest in viem readContract action, but this might change
376380
- // @ts-ignore
376381
- gas: 500000000n
376382
- });
376383
- this.logger?.debug(`loaded ${result.length} updatable price feeds`);
376384
- return result;
376385
- }
376386
- #create(data) {
376387
- const contractType = bytes32ToString(
376388
- data.baseParams.contractType
376389
- );
376390
- switch (contractType) {
376391
- case "PF_CHAINLINK_ORACLE":
376392
- return new ChainlinkPriceFeedContract(this.sdk, data);
376393
- case "PF_YEARN_ORACLE":
376394
- return new YearnPriceFeedContract(this.sdk, data);
376395
- case "PF_CURVE_STABLE_LP_ORACLE":
376396
- return new CurveStablePriceFeedContract(this.sdk, data);
376397
- case "PF_WSTETH_ORACLE":
376398
- return new WstETHPriceFeedContract(this.sdk, data);
376399
- case "PF_BOUNDED_ORACLE":
376400
- return new BoundedPriceFeedContract(this.sdk, data);
376401
- case "PF_COMPOSITE_ORACLE":
376402
- return new CompositePriceFeedContract(this.sdk, data);
376403
- case "PF_BALANCER_STABLE_LP_ORACLE":
376404
- return new BalancerStablePriceFeedContract(this.sdk, data);
376405
- case "PF_BALANCER_WEIGHTED_LP_ORACLE":
376406
- return new BalancerWeightedPriceFeedContract(this.sdk, data);
376407
- case "PF_CURVE_CRYPTO_LP_ORACLE":
376408
- return new CurveCryptoPriceFeedContract(this.sdk, data);
376409
- case "PF_REDSTONE_ORACLE":
376410
- return new RedstonePriceFeedContract(this.sdk, data);
376411
- case "PF_ERC4626_ORACLE":
376412
- return new Erc4626PriceFeedContract(this.sdk, data);
376413
- case "PF_CURVE_USD_ORACLE":
376414
- return new CurveUSDPriceFeedContract(this.sdk, data);
376415
- case "PF_ZERO_ORACLE":
376416
- return new ZeroPriceFeedContract(this.sdk, data);
376417
- case "PF_MELLOW_LRT_ORACLE":
376418
- return new MellowLRTPriceFeedContract(this.sdk, data);
376419
- case "PF_PENDLE_PT_TWAP_ORACLE":
376420
- return new PendleTWAPPTPriceFeed(this.sdk, data);
376421
- default:
376422
- throw new Error(`Price feed type ${contractType} not supported, `);
376423
- }
376424
- }
376425
- };
376426
- function rawTxToMulticallPriceUpdate(tx) {
376427
- const { to, callData } = tx;
376428
- const { args, functionName } = decodeFunctionData({
376429
- abi: iUpdatablePriceFeedAbi,
376430
- data: callData
376431
- });
376432
- return {
376433
- abi: iUpdatablePriceFeedAbi,
376434
- address: to,
376435
- functionName,
376436
- args
376437
- };
376438
- }
376439
- var PriceOracleBaseContract = class extends BaseContract {
376440
- /**
376441
- * Underlying token of market to which this price oracle belongs
376442
- */
376443
- underlying;
376444
- /**
376445
- * Mapping Token => [PriceFeed Address, stalenessPeriod]
376446
- */
376447
- mainPriceFeeds = new AddressMap();
376448
- /**
376449
- * Mapping Token => [PriceFeed Address, stalenessPeriod]
376450
- */
376451
- reservePriceFeeds = new AddressMap();
376452
- /**
376453
- * Mapping Token => Price in underlying
376454
- */
376455
- mainPrices = new AddressMap();
376456
- /**
376457
- * Mapping Token => Price in underlying
376458
- */
376459
- reservePrices = new AddressMap();
376460
- #priceFeedTree = [];
376461
- constructor(sdk, args, data, underlying) {
376462
- super(sdk, args);
376463
- this.underlying = underlying;
376464
- const { priceFeedMapping, priceFeedStructure } = data;
376465
- this.#loadState(priceFeedMapping, priceFeedStructure);
376466
- }
376467
- /**
376468
- * Returns main and reserve price feeds for given tokens
376469
- * @param tokens
376470
- * @param opts Option to include main/reserve feeds only, defaults to both
376471
- * @returns
376472
- */
376473
- priceFeedsForTokens(tokens, opts) {
376474
- const main = opts?.main ?? true;
376475
- const reserve = opts?.reserve ?? true;
376476
- return tokens.flatMap((t) => [
376477
- main ? this.mainPriceFeeds.get(t)?.priceFeed : void 0,
376478
- reserve ? this.reservePriceFeeds.get(t)?.priceFeed : void 0
376479
- ]).filter((f) => !!f);
376480
- }
376481
- /**
376482
- * Generates updates for all updateable price feeds in this oracle (including dependencies)
376483
- * @returns
376484
- */
376485
- async updatePriceFeeds() {
376486
- const updatables = [];
376487
- for (const node of this.#priceFeedTree) {
376488
- if (node.updatable) {
376489
- updatables.push(this.sdk.priceFeeds.mustGet(node.baseParams.addr));
376490
- }
376491
- }
376492
- return this.sdk.priceFeeds.generatePriceFeedsUpdateTxs(updatables);
376493
- }
376494
- /**
376495
- * Converts previously obtained price updates into CreditFacade multicall entries
376496
- * @param creditFacade
376497
- * @param updates
376498
- * @returns
376499
- */
376500
- onDemandPriceUpdates(updates) {
376501
- const result = [];
376502
- if (!updates) {
376503
- return result;
376504
- }
376505
- const { txs } = updates;
376506
- for (const tx of txs) {
376507
- const { to: priceFeed, callData } = tx;
376508
- const [token, reserve] = this.findTokenForPriceFeed(priceFeed);
376509
- if (!token) {
376510
- continue;
376511
- }
376512
- const { args } = decodeFunctionData({
376513
- abi: iUpdatablePriceFeedAbi,
376514
- data: callData
376515
- });
376516
- const data = args[0];
376517
- result.push({
376518
- priceFeed,
376519
- token,
376520
- reserve,
376521
- data
376522
- });
376523
- }
376524
- return result;
376525
- }
376526
- /**
376527
- * Tries to convert amount of token into underlying of current market
376528
- * @param token
376529
- * @param amount
376530
- * @param reserve
376531
- * @returns
376532
- */
376533
- convertToUnderlying(token, amount, reserve = false) {
376534
- return this.convert(token, this.underlying, amount, reserve);
376535
- }
376536
- /**
376537
- * Tries to convert amount of from one token to another, using latest known prices
376538
- * @param from
376539
- * @param to
376540
- * @param amount
376541
- * @param reserve
376542
- */
376543
- convert(from, to, amount, reserve = false) {
376544
- if (from === to) {
376545
- return amount;
376546
- }
376547
- const fromPrice = reserve ? this.reservePrices.mustGet(from) : this.mainPrices.mustGet(from);
376548
- const fromScale = 10n ** BigInt(this.sdk.tokensMeta.decimals(from));
376549
- const toPrice = reserve ? this.reservePrices.mustGet(to) : this.mainPrices.mustGet(to);
376550
- const toScale = 10n ** BigInt(this.sdk.tokensMeta.decimals(to));
376551
- return amount * fromPrice * toScale / (toPrice * fromScale);
376552
- }
376553
- /**
376554
- * Tries to convert amount of token to USD, using latest known prices
376555
- * @param from
376556
- * @param to
376557
- * @param amount
376558
- * @param reserve
376559
- */
376560
- convertToUSD(from, amount, reserve = false) {
376561
- const price = reserve ? this.reservePrices.mustGet(from) : this.mainPrices.mustGet(from);
376562
- const scale = 10n ** BigInt(this.sdk.tokensMeta.decimals(from));
376563
- return amount * price / scale;
376564
- }
376565
- /**
376566
- * Loads new prices for this oracle from PriceFeedCompressor
376567
- * Does not update price feeds, only updates prices
376568
- */
376569
- async updatePrices() {
376570
- await this.sdk.marketRegister.updatePrices([this.address]);
376571
- }
376572
- syncStateMulticall() {
376573
- const args = [this.address];
376574
- if (this.version === 300) {
376575
- args.push(
376576
- Array.from(
376577
- /* @__PURE__ */ new Set([
376578
- this.underlying,
376579
- ...this.mainPriceFeeds.keys(),
376580
- ...this.reservePriceFeeds.keys()
376581
- ])
376582
- )
376583
- );
376584
- }
376585
- return {
376586
- call: {
376587
- abi: iPriceFeedCompressorAbi,
376588
- address: this.sdk.addressProvider.getLatestVersion(
376589
- AP_PRICE_FEED_COMPRESSOR
376590
- ),
376591
- functionName: "getPriceFeeds",
376592
- args
376593
- },
376594
- onResult: ([entries, tree]) => {
376595
- this.#loadState(entries, tree);
376596
- }
376597
- };
376598
- }
376599
- #loadState(entries, tree) {
376600
- this.#priceFeedTree = tree;
376601
- this.mainPriceFeeds.clear();
376602
- this.reservePriceFeeds.clear();
376603
- this.mainPrices.clear();
376604
- this.reservePrices.clear();
376605
- for (const node of tree) {
376606
- this.sdk.priceFeeds.getOrCreate(node);
376607
- }
376608
- entries.forEach((node) => {
376609
- const { token, priceFeed, reserve, stalenessPeriod } = node;
376610
- const ref = new PriceFeedRef(this.sdk, priceFeed, stalenessPeriod);
376611
- const price = this.#priceFeedTree.find(
376612
- (n) => n.baseParams.addr === priceFeed
376613
- )?.answer?.price;
376614
- if (reserve) {
376615
- this.reservePriceFeeds.upsert(token, ref);
376616
- if (price) {
376617
- this.reservePrices.upsert(token, price);
376618
- }
376619
- } else {
376620
- this.mainPriceFeeds.upsert(token, ref);
376621
- if (price) {
376622
- this.mainPrices.upsert(token, price);
376623
- }
376624
- }
376625
- this.#labelPriceFeed(priceFeed, reserve ? "Reserve" : "Main", token);
376626
- });
376627
- this.logger?.debug(
376628
- `Got ${this.mainPriceFeeds.size} main and ${this.reservePriceFeeds.size} reserve price feeds`
376629
- );
376630
- }
376631
- #labelPriceFeed(address, usage, token) {
376632
- this.sdk.provider.addressLabels.set(address, (label) => {
376633
- const symbol = this.sdk.tokensMeta.symbol(token);
376634
- let pricefeedTag = `${symbol}.${usage}`;
376635
- if (label) {
376636
- pricefeedTag = `${label}, ${pricefeedTag}`;
376637
- }
376638
- return pricefeedTag;
376639
- });
376640
- }
376641
- /**
376642
- * Helper method to find "attachment point" of price feed (makes sense for updatable price feeds only) -
376643
- * returns token (in v3.0 can be ticker) and main/reserve flag
376644
- *
376645
- * @param priceFeed
376646
- * @returns
376647
- */
376648
- findTokenForPriceFeed(priceFeed) {
376649
- for (const [token, pf] of this.mainPriceFeeds.entries()) {
376650
- if (pf.address === priceFeed) {
376651
- return [token, false];
376652
- }
376653
- }
376654
- for (const [token, pf] of this.reservePriceFeeds.entries()) {
376655
- if (pf.address === priceFeed) {
376656
- return [token, true];
376657
- }
376658
- }
376659
- return [void 0, false];
376660
- }
376661
- stateHuman(raw = true) {
376662
- return {
376663
- ...super.stateHuman(raw),
376664
- mainPriceFeeds: Object.fromEntries(
376665
- this.mainPriceFeeds.entries().map(([token, v]) => [
376666
- this.labelAddress(token),
376667
- v.stateHuman(raw)
376668
- ])
376669
- ),
376670
- reservePriceFeeds: Object.fromEntries(
376671
- this.reservePriceFeeds.entries().map(([token, v]) => [
376672
- this.labelAddress(token),
376673
- v.stateHuman(raw)
376674
- ])
376675
- )
376676
- };
376677
- }
376678
- get priceFeedTree() {
376679
- return this.#priceFeedTree;
376680
- }
376681
- };
376682
- var PriceOracleV300Contract = class extends PriceOracleBaseContract {
376683
- constructor(sdk, data, underlying) {
376684
- super(
376685
- sdk,
376686
- {
376687
- ...data.baseParams,
376688
- name: "PriceOracleV3",
376689
- abi: priceOracleV3Abi
376690
- },
376691
- data,
376692
- underlying
376693
- );
376694
- }
376695
- processLog(log2) {
376696
- switch (log2.eventName) {
376697
- case "Paused":
376698
- case "Unpaused":
376699
- break;
376700
- case "NewController":
376701
- case "SetPriceFeed":
376702
- case "SetReservePriceFeed":
376703
- case "SetReservePriceFeedStatus":
376704
- this.dirty = true;
376705
- break;
376706
- }
376707
- }
376708
- findTokenForPriceFeed(priceFeed) {
376709
- const [token, reserve] = super.findTokenForPriceFeed(priceFeed);
376710
- if (token) {
376711
- return [token, reserve];
376712
- }
376713
- const ticker = priceFeedToTicker[this.sdk.provider.networkType][priceFeed];
376714
- if (ticker) {
376715
- return [ticker, false];
376716
- }
376717
- return [void 0, false];
376718
- }
376719
- };
376720
- var priceFeedToTicker = {
376721
- Mainnet: {
376722
- "0x6F13996411743d22566176482B6b677Ec4eb6cE6": "0x8C23b9E4CB9884e807294c4b4C33820333cC613c",
376723
- "0xa7cB34Cd731486F61cfDb7ff5F6fC7B40537eD76": "0xFb56Fb16B4F33A875b01881Da7458E09D286208e",
376724
- "0xcf1FDc8DC6e83B38729d58C117BE704bb2AC362a": "0xf08D818be34C82cB5e3f33AC78F8268828764F17",
376725
- "0xE683362b8ebcbfd9332CBB79BfAF9fC42073C49b": "0xBdb778F566b6cEd70D3d329DD1D14E221fFe1ba5",
376726
- "0xB72A69e2182bE87bda706B7Ff9A539AC78338C61": "0x7fF63E75F48aad6F4bE97E75C6421f348f19fE7F",
376727
- "0xd7396fA3aFB9833293Ce2149EEb3Dbf5380B1e0D": "0xB0EA0EC3Fd4947348816f76768b3a56249d47EEc"
376728
- },
376729
- Arbitrum: {
376730
- "0xcB44ADd611f75F03191f8f1A2e2AF7a0113eadd1": "0x07299E4E806e4253727084c0493fFDf6fB2dBa3D",
376731
- "0x354A63F07A5c1605920794aFFF09963b6DF897a9": "0x15094B05e679c9B7fDde6FB8e6BDa930ff1D6a62"
376732
- },
376733
- Optimism: {
376734
- "0xF23C91b1E3B7FD9174c82F7Fb2BD270C3CfcC3CE": "0x658f8e60c57ad62a9299ef6c7b1da9a0d1d1e681"
376735
- },
376736
- Base: {}
376737
- };
376738
- var PriceOracleV310Contract = class extends PriceOracleBaseContract {
376739
- constructor(sdk, data, underlying) {
376740
- super(
376741
- sdk,
376742
- {
376743
- ...data.baseParams,
376744
- name: "PriceOracleV3",
376745
- abi: iPriceOracleV310Abi
376746
- },
376747
- data,
376748
- underlying
376749
- );
376750
- }
376751
- processLog(log2) {
376752
- switch (log2.eventName) {
376753
- case "AddUpdatablePriceFeed":
376754
- case "NewController":
376755
- case "SetPriceFeed":
376756
- case "SetReservePriceFeed":
376757
- this.dirty = true;
376758
- break;
376759
- }
376760
- }
376761
- };
376762
- var MarketFactory = class extends SDKConstruct {
376763
- acl;
376764
- configurator;
376765
- poolFactory;
376766
- priceOracle;
376767
- creditManagers = [];
376768
- /**
376769
- * Original data received from compressor
376770
- */
376771
- state;
376772
- zappers;
376773
- constructor(sdk, marketData) {
376774
- super(sdk);
376775
- this.state = marketData;
376776
- let configurator = sdk.contracts.get(
376777
- marketData.configurator
376778
- );
376779
- if (!configurator) {
376780
- configurator = new MarketConfiguratorContract(
376781
- sdk,
376782
- marketData.configurator
376783
- );
376784
- }
376785
- this.configurator = configurator;
376786
- this.acl = marketData.acl;
376787
- const allTokens = [
376788
- ...marketData.tokens,
376789
- ...marketData.zappers.flatMap((z2) => [z2.tokenIn, z2.tokenOut])
376790
- ];
376791
- for (const t of allTokens) {
376792
- sdk.tokensMeta.upsert(t.addr, t);
376793
- sdk.provider.addressLabels.set(t.addr, t.symbol);
376794
- }
376795
- this.poolFactory = new PoolFactory(sdk, marketData);
376796
- this.zappers = marketData.zappers;
376797
- for (let i = 0; i < marketData.creditManagers.length; i++) {
376798
- this.creditManagers.push(new CreditFactory(sdk, marketData, i));
376799
- }
376800
- if (marketData.priceOracleData.baseParams.version < 310) {
376801
- this.priceOracle = new PriceOracleV300Contract(
376802
- sdk,
376803
- marketData.priceOracleData,
376804
- marketData.pool.underlying
376805
- );
376806
- } else {
376807
- this.priceOracle = new PriceOracleV310Contract(
376808
- sdk,
376809
- marketData.priceOracleData,
376810
- marketData.pool.underlying
376811
- );
376812
- }
376813
- }
376814
- get dirty() {
376815
- return this.configurator.dirty || this.poolFactory.dirty || this.priceOracle.dirty || this.creditManagers.some((cm) => cm.dirty);
376816
- }
376817
- stateHuman(raw = true) {
376818
- return {
376819
- pool: this.poolFactory.stateHuman(raw),
376820
- creditManagers: this.creditManagers.map((cm) => cm.stateHuman(raw)),
376821
- priceOracle: this.priceOracle.stateHuman(raw),
376822
- pausableAdmins: this.state.pausableAdmins.map((a) => this.labelAddress(a)),
376823
- unpausableAdmins: this.state.unpausableAdmins.map(
376824
- (a) => this.labelAddress(a)
376825
- ),
376826
- emergencyLiquidators: this.state.emergencyLiquidators.map(
376827
- (a) => this.labelAddress(a)
376828
- ),
376829
- zappers: this.zappers.map((z2) => ({
376830
- address: z2.baseParams.addr,
376831
- contractType: z2.baseParams.contractType,
376832
- version: Number(z2.baseParams.version),
376833
- tokenIn: this.labelAddress(z2.tokenIn.addr),
376834
- tokenOut: this.labelAddress(z2.tokenOut.addr)
376835
- }))
376836
- };
376837
- }
376838
- };
376839
- var SUPPORTED_CHAINS = [
376840
- "Mainnet",
376841
- "Arbitrum",
376842
- "Optimism",
376843
- "Base"
376844
- ];
376845
- var chains = {
376846
- Mainnet: mainnet,
376847
- Arbitrum: arbitrum,
376848
- Optimism: optimism,
376849
- Base: base
376850
- };
376851
- var CHAINS_BY_ID = {
376852
- [mainnet.id]: "Mainnet",
376853
- [arbitrum.id]: "Arbitrum",
376854
- [optimism.id]: "Optimism"
376855
- // [base.id]: "Base",
376856
- };
376857
- async function detectChain(transportOrRPC) {
376858
- const transport = typeof transportOrRPC === "string" ? http(transportOrRPC) : transportOrRPC;
376859
- const tempClient = createPublicClient({ transport });
376860
- const [networkType, chainId] = await Promise.all([
376861
- detectNetwork(tempClient),
376862
- tempClient.getChainId()
376863
- ]);
376864
- return defineChain({
376865
- ...chains[networkType],
376866
- id: chainId
376867
- });
376868
- }
376869
- function createTransport2(opts) {
376870
- const { timeout = 12e4, retryCount } = opts;
376871
- if ("transport" in opts) {
376872
- return opts.transport;
376873
- }
376874
- const rpcs = opts.rpcURLs.map((url) => http(url, { timeout, retryCount }));
376875
- return rpcs.length ? fallback(rpcs) : rpcs[0];
376876
- }
376877
- var Provider = class {
376878
- chainId;
376879
- chain;
376880
- networkType;
376881
- addressLabels;
376882
- #transport;
376883
- #publicClient;
376884
- constructor(opts) {
376885
- const { chainId, networkType } = opts;
376886
- this.chainId = chainId;
376887
- this.networkType = networkType;
376888
- this.chain = defineChain({
376889
- ...chains[networkType],
376890
- id: chainId
376891
- });
376892
- this.#transport = createTransport2(opts);
376893
- this.#publicClient = createPublicClient({
376894
- chain: this.chain,
376895
- transport: this.#transport
376896
- });
376897
- this.addressLabels = new AddressLabeller();
376898
- }
376899
- get transport() {
376900
- return this.#transport;
376901
- }
376902
- set transport(transport) {
376903
- this.#transport = transport;
376904
- this.#publicClient = createPublicClient({
376905
- chain: this.chain,
376906
- transport: this.#transport
376907
- });
376908
- }
376909
- get publicClient() {
376910
- return this.#publicClient;
376911
- }
376912
- };
376913
- async function detectNetwork(client) {
376914
- for (const chain of SUPPORTED_CHAINS) {
376915
- try {
376916
- await client.readContract({
376917
- abi: ierc20MetadataAbi,
376918
- address: USDC[chain],
376919
- functionName: "symbol"
376920
- });
376921
- return chain;
376922
- } catch {
376923
- }
376924
- }
376925
- throw new Error("Unsupported network");
376926
- }
376927
- async function sendRawTx(client, params) {
376928
- const { account, tx } = params;
376929
- return getAction(
376930
- client,
376931
- sendTransaction,
376932
- "sendTransaction"
376933
- )({
376934
- // @ts-expect-error
376935
- account,
376936
- data: tx.callData,
376937
- to: tx.to,
376938
- value: BigInt(tx.value)
376939
- });
376940
- }
376941
- async function simulateMulticall(client, parameters) {
376942
- const {
376943
- account,
376944
- allowFailure = true,
376945
- batchSize: batchSize_,
376946
- blockNumber,
376947
- blockTag,
376948
- gas,
376949
- multicallAddress: multicallAddress_,
376950
- stateOverride
376951
- } = parameters;
376952
- const contracts2 = parameters.contracts;
376953
- const batchSize = batchSize_ ?? (typeof client.batch?.multicall === "object" && client.batch.multicall.batchSize || 1024);
376954
- let multicallAddress = multicallAddress_;
376955
- if (!multicallAddress) {
376956
- if (!client.chain)
376957
- throw new Error(
376958
- "client chain not configured. multicallAddress is required."
376959
- );
376960
- multicallAddress = getChainContractAddress({
376961
- blockNumber,
376962
- chain: client.chain,
376963
- contract: "multicall3"
376964
- });
376965
- }
376966
- const chunkedCalls = [[]];
376967
- let currentChunk = 0;
376968
- let currentChunkSize = 0;
376969
- for (const contract of contracts2) {
376970
- const { abi: abi32, address, args, functionName } = contract;
376971
- try {
376972
- const callData = encodeFunctionData({ abi: abi32, args, functionName });
376973
- currentChunkSize += (callData.length - 2) / 2;
376974
- if (
376975
- // Check if batching is enabled.
376976
- batchSize > 0 && // Check if the current size of the batch exceeds the size limit.
376977
- currentChunkSize > batchSize && // Check if the current chunk is not already empty.
376978
- chunkedCalls[currentChunk].length > 0
376979
- ) {
376980
- currentChunk++;
376981
- currentChunkSize = (callData.length - 2) / 2;
376982
- chunkedCalls[currentChunk] = [];
376983
- }
376984
- chunkedCalls[currentChunk] = [
376985
- ...chunkedCalls[currentChunk],
376986
- {
376987
- allowFailure: true,
376988
- callData,
376989
- target: address
376990
- }
376991
- ];
376992
- } catch (err) {
376993
- const error = getContractError(err, {
376994
- abi: abi32,
376995
- address,
376996
- args,
376997
- docsPath: "/docs/contract/multicall",
376998
- functionName
376999
- });
377000
- if (!allowFailure) throw error;
377001
- chunkedCalls[currentChunk] = [
377002
- ...chunkedCalls[currentChunk],
377003
- {
377004
- allowFailure: true,
377005
- callData: "0x",
377006
- target: address
377007
- }
377008
- ];
377009
- }
377010
- }
377011
- const aggregate3Results = await Promise.allSettled(
377012
- chunkedCalls.map(
377013
- (calls) => getAction(
377014
- client,
377015
- simulateContract,
377016
- "simulateContract"
377017
- )({
377018
- account,
377019
- abi: multicall3Abi,
377020
- address: multicallAddress,
377021
- args: [calls],
377022
- blockNumber,
377023
- blockTag,
377024
- // does not infer well that either blockNumber or blockTag must be present
377025
- functionName: "aggregate3",
377026
- stateOverride,
377027
- gas
377028
- })
377029
- )
377030
- );
377031
- const results = [];
377032
- for (let i = 0; i < aggregate3Results.length; i++) {
377033
- const result = aggregate3Results[i];
377034
- if (result.status === "rejected") {
377035
- if (!allowFailure) {
377036
- throw result.reason;
377037
- }
377038
- for (const _i of chunkedCalls[i]) {
377039
- results.push({
377040
- status: "failure",
377041
- error: result.reason,
377042
- result: void 0
377043
- });
377044
- }
377045
- continue;
377046
- }
377047
- const aggregate3Result = result.value.result;
377048
- for (let j = 0; j < aggregate3Result.length; j++) {
377049
- const { returnData, success } = aggregate3Result[j];
377050
- const { callData } = chunkedCalls[i][j];
377051
- const { abi: abi32, address, functionName, args } = contracts2[results.length];
377052
- try {
377053
- if (callData === "0x") throw new AbiDecodingZeroDataError();
377054
- if (!success) throw new RawContractError({ data: returnData });
377055
- const result2 = decodeFunctionResult({
377056
- abi: abi32,
377057
- args,
377058
- data: returnData,
377059
- functionName
377060
- });
377061
- results.push(allowFailure ? { result: result2, status: "success" } : result2);
377062
- } catch (err) {
377063
- const error = getContractError(err, {
377064
- abi: abi32,
377065
- address,
377066
- args,
377067
- docsPath: "/docs/contract/multicall",
377068
- functionName
377069
- });
377070
- if (!allowFailure) throw error;
377071
- results.push({ error, result: void 0, status: "failure" });
377072
- }
377073
- }
377074
- }
377075
- if (results.length !== contracts2.length)
377076
- throw new BaseError2("multicall results mismatch");
377077
- return results;
377078
- }
377079
- var MarketRegister = class extends SDKConstruct {
377080
- #logger;
377081
- /**
377082
- * Mapping pool.address -> MarketFactory
377083
- */
377084
- #markets = new AddressMap();
377085
- constructor(sdk, markets) {
377086
- super(sdk);
377087
- this.#logger = childLogger("MarketRegister", sdk.logger);
377088
- for (const data of markets ?? []) {
377089
- this.#markets.upsert(
377090
- data.pool.baseParams.addr,
377091
- new MarketFactory(this.sdk, data)
377092
- );
377093
- }
377094
- }
377095
- async loadMarkets(marketConfigurators, ignoreUpdateablePrices) {
377096
- if (!marketConfigurators.length) {
377097
- this.#logger?.warn(
377098
- "no market configurators provided, skipping loadMarkets"
377099
- );
377100
- return;
377101
- }
377102
- await this.#loadMarkets(marketConfigurators, [], ignoreUpdateablePrices);
377103
- }
377104
- async syncState() {
377105
- const pools = this.markets.filter((m) => m.dirty).map((m) => m.poolFactory.pool.address);
377106
- if (pools.length) {
377107
- this.#logger?.debug(`need to reload ${pools.length} markets`);
377108
- await this.#loadMarkets([], pools);
377109
- }
377110
- }
377111
- async #loadMarkets(configurators, pools, ignoreUpdateablePrices) {
377112
- const marketCompressorAddress = this.sdk.addressProvider.getAddress(
377113
- AP_MARKET_COMPRESSOR,
377114
- 310
377115
- );
377116
- let txs = [];
377117
- if (!ignoreUpdateablePrices) {
377118
- await this.sdk.priceFeeds.preloadUpdatablePriceFeeds(
377119
- configurators,
377120
- pools
377121
- );
377122
- const updates = await this.sdk.priceFeeds.generatePriceFeedsUpdateTxs();
377123
- txs = updates.txs;
377124
- }
377125
- this.#logger?.debug({ configurators, pools }, "calling getMarkets");
377126
- const resp = await simulateMulticall(this.provider.publicClient, {
377127
- contracts: [
377128
- ...txs.map(rawTxToMulticallPriceUpdate),
377129
- {
377130
- abi: iMarketCompressorAbi,
377131
- address: marketCompressorAddress,
377132
- functionName: "getMarkets",
377133
- args: [
377134
- {
377135
- configurators,
377136
- pools,
377137
- underlying: ADDRESS_0X0
377138
- }
377139
- ]
377140
- }
377141
- ],
377142
- allowFailure: false,
377143
- gas: 550000000n,
377144
- batchSize: 0
377145
- // we cannot have price updates and compressor request in different batches
377146
- });
377147
- const markets = resp.pop();
377148
- for (const data of markets) {
377149
- this.#markets.upsert(
377150
- data.pool.baseParams.addr,
377151
- new MarketFactory(this.sdk, data)
377152
- );
377153
- }
377154
- this.#logger?.info(`loaded ${markets.length} markets`);
377155
- }
377156
- /**
377157
- * Loads new prices and price feeds for given oracles from PriceFeedCompressor, defaults to all oracles
377158
- * Supports v300 and v310 oracles
377159
- */
377160
- async updatePrices(oracles) {
377161
- const multicalls = this.markets.map((m) => m.priceOracle).filter((o) => !oracles || oracles.includes(o.address)).map((o) => o.syncStateMulticall());
377162
- if (!multicalls.length) {
377163
- return;
377164
- }
377165
- const { txs } = await this.sdk.priceFeeds.generatePriceFeedsUpdateTxs();
377166
- const resp = await simulateMulticall(this.provider.publicClient, {
377167
- contracts: [
377168
- ...txs.map(rawTxToMulticallPriceUpdate),
377169
- ...multicalls.map((mc) => mc.call)
377170
- ],
377171
- allowFailure: false,
377172
- gas: 550000000n,
377173
- batchSize: 0
377174
- // we cannot have price updates and compressor request in different batches
377175
- });
377176
- const oraclesStates = resp.slice(txs.length);
377177
- for (let i = 0; i < multicalls.length; i++) {
377178
- const handler = multicalls[i].onResult;
377179
- const result = oraclesStates[i];
377180
- handler(result);
377181
- }
377182
- }
377183
- get state() {
377184
- return this.markets.map((market) => market.state);
377185
- }
377186
- stateHuman(raw = true) {
377187
- return this.markets.map((market) => market.stateHuman(raw));
377188
- }
377189
- get pools() {
377190
- return this.markets.map((market) => market.poolFactory);
377191
- }
377192
- get creditManagers() {
377193
- return this.markets.flatMap((market) => market.creditManagers);
377194
- }
377195
- get marketConfigurators() {
377196
- const result = /* @__PURE__ */ new Set();
377197
- for (const m of this.markets) {
377198
- result.add(m.configurator);
377199
- }
377200
- return Array.from(result);
377201
- }
377202
- findCreditManager(creditManager) {
377203
- const addr = creditManager.toLowerCase();
377204
- for (const market of this.markets) {
377205
- for (const cm of market.creditManagers) {
377206
- if (cm.creditManager.address.toLowerCase() === addr) {
377207
- return cm;
377208
- }
377209
- }
377210
- }
377211
- throw new Error(`cannot find credit manager ${creditManager}`);
377212
- }
377213
- findByCreditManager(creditManager) {
377214
- const addr = creditManager.toLowerCase();
377215
- const market = this.markets.find(
377216
- (m) => m.creditManagers.some(
377217
- (cm) => cm.creditManager.address.toLowerCase() === addr
377218
- )
377219
- );
377220
- if (!market) {
377221
- throw new Error(`cannot find market for credit manager ${creditManager}`);
377222
- }
377223
- return market;
377224
- }
377225
- findByPriceOracle(address) {
377226
- const addr = address.toLowerCase();
377227
- for (const market of this.markets) {
377228
- if (market.priceOracle.address.toLowerCase() === addr) {
377229
- return market;
377230
- }
377231
- }
377232
- throw new Error(`cannot find price oracle ${address}`);
377233
- }
377234
- get marketsMap() {
377235
- return this.#markets;
377236
- }
377237
- get markets() {
377238
- return this.#markets.values();
377239
- }
377240
- async tvl() {
377241
- const creditManagers = this.creditManagers;
377242
- const tvls = await Promise.all(creditManagers.map((cm) => cm.tvl()));
377243
- return tvls.reduce(
377244
- (acc, curr) => {
377245
- acc.tvl += curr.tvl;
377246
- acc.tvlUSD += curr.tvlUSD;
377247
- return acc;
377248
- },
377249
- { tvl: 0n, tvlUSD: 0n }
377250
- );
377251
- }
377252
- };
377253
375526
  var AdapterInterface = /* @__PURE__ */ ((AdapterInterface2) => {
377254
375527
  AdapterInterface2[AdapterInterface2["ABSTRACT"] = 0] = "ABSTRACT";
377255
375528
  AdapterInterface2[AdapterInterface2["UNISWAP_V2_ROUTER"] = 1] = "UNISWAP_V2_ROUTER";
@@ -382819,648 +381092,2372 @@ var contractParams = {
382819
381092
  Base: NOT_DEPLOYED
382820
381093
  }
382821
381094
  }
382822
- ]
382823
- },
382824
- CONVEX_STECRV_POOL: {
382825
- name: "Convex STECRV",
382826
- protocol: 4,
382827
- type: 10,
382828
- stakedToken: "stkcvxsteCRV",
382829
- extraRewards: [
382830
- {
382831
- rewardToken: "LDO",
382832
- poolAddress: {
382833
- Mainnet: "0x008aEa5036b819B4FEAEd10b2190FBb3954981E8",
382834
- Arbitrum: NOT_DEPLOYED,
382835
- // CONVEX_STECRV_POOL_EXTRA_LDO
382836
- Optimism: NOT_DEPLOYED,
382837
- Base: NOT_DEPLOYED
381095
+ ]
381096
+ },
381097
+ CONVEX_STECRV_POOL: {
381098
+ name: "Convex STECRV",
381099
+ protocol: 4,
381100
+ type: 10,
381101
+ stakedToken: "stkcvxsteCRV",
381102
+ extraRewards: [
381103
+ {
381104
+ rewardToken: "LDO",
381105
+ poolAddress: {
381106
+ Mainnet: "0x008aEa5036b819B4FEAEd10b2190FBb3954981E8",
381107
+ Arbitrum: NOT_DEPLOYED,
381108
+ // CONVEX_STECRV_POOL_EXTRA_LDO
381109
+ Optimism: NOT_DEPLOYED,
381110
+ Base: NOT_DEPLOYED
381111
+ }
381112
+ }
381113
+ ]
381114
+ },
381115
+ CONVEX_FRAX3CRV_POOL: {
381116
+ name: "Convex FRAX3CRV",
381117
+ protocol: 4,
381118
+ type: 10,
381119
+ stakedToken: "stkcvxFRAX3CRV",
381120
+ extraRewards: [
381121
+ {
381122
+ rewardToken: "FXS",
381123
+ poolAddress: {
381124
+ Mainnet: "0xcDEC6714eB482f28f4889A0c122868450CDBF0b0",
381125
+ Arbitrum: NOT_DEPLOYED,
381126
+ // CONVEX_FRAX3CRV_POOL_EXTRA_FXS
381127
+ Optimism: NOT_DEPLOYED,
381128
+ Base: NOT_DEPLOYED
381129
+ }
381130
+ }
381131
+ ]
381132
+ },
381133
+ CONVEX_LUSD3CRV_POOL: {
381134
+ name: "Convex LUSD3CRV",
381135
+ protocol: 4,
381136
+ type: 10,
381137
+ stakedToken: "stkcvxLUSD3CRV",
381138
+ extraRewards: [
381139
+ {
381140
+ rewardToken: "LQTY",
381141
+ poolAddress: {
381142
+ Mainnet: "0x55d59b791f06dc519B176791c4E037E8Cf2f6361",
381143
+ Arbitrum: NOT_DEPLOYED,
381144
+ // CONVEX_LUSD3CRV_POOL_EXTRA_LQTY
381145
+ Optimism: NOT_DEPLOYED,
381146
+ Base: NOT_DEPLOYED
381147
+ }
381148
+ }
381149
+ ]
381150
+ },
381151
+ CONVEX_CRVETH_POOL: {
381152
+ name: "Convex crvCRVETH",
381153
+ protocol: 4,
381154
+ type: 10,
381155
+ stakedToken: "stkcvxcrvCRVETH",
381156
+ extraRewards: [
381157
+ {
381158
+ rewardToken: "CVX",
381159
+ poolAddress: {
381160
+ Mainnet: "0xE1eCBB4181378E2346EAC90Eb5606c01Aa08f052",
381161
+ Arbitrum: NOT_DEPLOYED,
381162
+ Optimism: NOT_DEPLOYED,
381163
+ Base: NOT_DEPLOYED
381164
+ }
381165
+ }
381166
+ ]
381167
+ },
381168
+ CONVEX_CVXETH_POOL: {
381169
+ name: "Convex crvCVXETH",
381170
+ protocol: 4,
381171
+ type: 10,
381172
+ stakedToken: "stkcvxcrvCVXETH",
381173
+ extraRewards: [
381174
+ {
381175
+ rewardToken: "CVX",
381176
+ poolAddress: {
381177
+ Mainnet: "0x834B9147Fd23bF131644aBC6e557Daf99C5cDa15",
381178
+ Arbitrum: NOT_DEPLOYED,
381179
+ Optimism: NOT_DEPLOYED,
381180
+ Base: NOT_DEPLOYED
381181
+ }
381182
+ }
381183
+ ]
381184
+ },
381185
+ CONVEX_3CRYPTO_POOL: {
381186
+ name: "Convex 3Crypto",
381187
+ protocol: 4,
381188
+ type: 10,
381189
+ stakedToken: "stkcvxcrvUSDTWBTCWETH",
381190
+ extraRewards: []
381191
+ },
381192
+ CONVEX_LDOETH_POOL: {
381193
+ name: "Convex LDOETH",
381194
+ protocol: 4,
381195
+ type: 10,
381196
+ stakedToken: "stkcvxLDOETH",
381197
+ extraRewards: [
381198
+ {
381199
+ rewardToken: "LDO",
381200
+ poolAddress: {
381201
+ Mainnet: "0x95e6092449a0f3946A5a0f308Ead4adcff244E2B",
381202
+ Arbitrum: NOT_DEPLOYED,
381203
+ Optimism: NOT_DEPLOYED,
381204
+ Base: NOT_DEPLOYED
381205
+ }
381206
+ }
381207
+ ]
381208
+ },
381209
+ CONVEX_CRVUSD_USDC_POOL: {
381210
+ name: "Convex crvUSDUSDC",
381211
+ protocol: 4,
381212
+ type: 10,
381213
+ stakedToken: "stkcvxcrvUSDUSDC",
381214
+ extraRewards: [
381215
+ {
381216
+ rewardToken: "CVX",
381217
+ poolAddress: {
381218
+ Mainnet: "0xac183F7cd62d5b04Fa40362EB67249A80339541A",
381219
+ Arbitrum: NOT_DEPLOYED,
381220
+ Optimism: NOT_DEPLOYED,
381221
+ Base: NOT_DEPLOYED
381222
+ }
381223
+ }
381224
+ ]
381225
+ },
381226
+ CONVEX_CRVUSD_USDT_POOL: {
381227
+ name: "Convex crvUSDUSDT",
381228
+ protocol: 4,
381229
+ type: 10,
381230
+ stakedToken: "stkcvxcrvUSDUSDT",
381231
+ extraRewards: [
381232
+ {
381233
+ rewardToken: "CVX",
381234
+ poolAddress: {
381235
+ Mainnet: "0xD490178B568b07c6DDbDfBBfaF9043772209Ec01",
381236
+ Arbitrum: NOT_DEPLOYED,
381237
+ Optimism: NOT_DEPLOYED,
381238
+ Base: NOT_DEPLOYED
381239
+ }
381240
+ }
381241
+ ]
381242
+ },
381243
+ CONVEX_CRVUSD_FRAX_POOL: {
381244
+ name: "Convex crvUSDFRAX",
381245
+ protocol: 4,
381246
+ type: 10,
381247
+ stakedToken: "stkcvxcrvUSDFRAX",
381248
+ extraRewards: [
381249
+ {
381250
+ rewardToken: "CVX",
381251
+ poolAddress: {
381252
+ Mainnet: "0x749cFfCb53e008841d7387ba37f9284BDeCEe0A9",
381253
+ Arbitrum: NOT_DEPLOYED,
381254
+ Optimism: NOT_DEPLOYED,
381255
+ Base: NOT_DEPLOYED
381256
+ }
381257
+ }
381258
+ ]
381259
+ },
381260
+ CONVEX_TRI_CRV_POOL: {
381261
+ name: "Convex TRICRV",
381262
+ protocol: 4,
381263
+ type: 10,
381264
+ stakedToken: "stkcvxcrvUSDETHCRV",
381265
+ extraRewards: [
381266
+ {
381267
+ rewardToken: "CVX",
381268
+ poolAddress: {
381269
+ Mainnet: "0x01eC96F1eEBF470E3fEAEEfB843fbC63424e668d",
381270
+ Arbitrum: NOT_DEPLOYED,
381271
+ Optimism: NOT_DEPLOYED,
381272
+ Base: NOT_DEPLOYED
381273
+ }
381274
+ }
381275
+ ]
381276
+ },
381277
+ CONVEX_GHO_CRVUSD_POOL: {
381278
+ name: "Convex GHOcrvUSD",
381279
+ protocol: 4,
381280
+ type: 10,
381281
+ stakedToken: "stkcvxGHOcrvUSD",
381282
+ extraRewards: [
381283
+ {
381284
+ rewardToken: "CVX",
381285
+ poolAddress: {
381286
+ Mainnet: "0xE7cC925739E41E2A03A53770F5E9Ed43afe13993",
381287
+ Arbitrum: NOT_DEPLOYED,
381288
+ Optimism: NOT_DEPLOYED,
381289
+ Base: NOT_DEPLOYED
381290
+ }
381291
+ }
381292
+ ]
381293
+ },
381294
+ CONVEX_LLAMA_THENA_POOL: {
381295
+ name: "Convex todo",
381296
+ protocol: 4,
381297
+ type: 10,
381298
+ stakedToken: "stkcvxllamathena",
381299
+ extraRewards: [
381300
+ {
381301
+ rewardToken: "CVX",
381302
+ poolAddress: {
381303
+ Mainnet: "0xc66844E5788b7d7D6DFFa5EC1Db62d898c59D6e7",
381304
+ Arbitrum: NOT_DEPLOYED,
381305
+ Optimism: NOT_DEPLOYED,
381306
+ Base: NOT_DEPLOYED
381307
+ }
381308
+ }
381309
+ ]
381310
+ },
381311
+ CONVEX_BOOSTER_ARB: {
381312
+ name: "Convex Booster (Arbitrum)",
381313
+ protocol: 4,
381314
+ type: 25
381315
+ /* CONVEX_L2_BOOSTER */
381316
+ },
381317
+ CONVEX_CRVUSD_USDT_POOL_ARB: {
381318
+ name: "Convex crvUSDT Pool",
381319
+ protocol: 4,
381320
+ type: 26,
381321
+ rewards: ["CRV", "CVX", "crvUSD", "ARB"],
381322
+ extraRewards: []
381323
+ },
381324
+ AURA_BOOSTER: {
381325
+ name: "Aura BOOSTER",
381326
+ protocol: 11,
381327
+ type: 11
381328
+ /* CONVEX_V1_BOOSTER */
381329
+ },
381330
+ AURA_B_RETH_STABLE_POOL: {
381331
+ name: "Balancer rETH Stable Pool Aura Deposit",
381332
+ protocol: 11,
381333
+ type: 10,
381334
+ stakedToken: "auraB_rETH_STABLE_vault",
381335
+ extraRewards: [
381336
+ {
381337
+ rewardToken: "AURA",
381338
+ poolAddress: {
381339
+ Mainnet: "0xf66a72886749c96b18526E8E124cC2e18b7c72D2",
381340
+ Arbitrum: NOT_DEPLOYED,
381341
+ Optimism: NOT_DEPLOYED,
381342
+ Base: NOT_DEPLOYED
381343
+ }
381344
+ }
381345
+ ]
381346
+ },
381347
+ AURA_WEETH_RETH_POOL: {
381348
+ name: "Balancer weETH-rETH Stable Pool Aura Deposit",
381349
+ protocol: 11,
381350
+ type: 10,
381351
+ stakedToken: "auraweETH_rETH_vault",
381352
+ extraRewards: [
381353
+ {
381354
+ rewardToken: "AURA",
381355
+ poolAddress: {
381356
+ Mainnet: "0x25d22C5191C67D63AAB70a37FAe06e1c1E1a830F",
381357
+ Arbitrum: NOT_DEPLOYED,
381358
+ Optimism: NOT_DEPLOYED,
381359
+ Base: NOT_DEPLOYED
381360
+ }
381361
+ }
381362
+ ]
381363
+ },
381364
+ AURA_OSETH_WETH_POOL: {
381365
+ name: "Balancer osETH-WETH Stable Pool Aura Deposit",
381366
+ protocol: 11,
381367
+ type: 10,
381368
+ stakedToken: "auraosETH_wETH_BPT_vault",
381369
+ extraRewards: [
381370
+ {
381371
+ rewardToken: "AURA",
381372
+ poolAddress: {
381373
+ Mainnet: "0x62e6D8dAe7089C8F2f2a5C328c710aa1788742fb",
381374
+ Arbitrum: NOT_DEPLOYED,
381375
+ Optimism: NOT_DEPLOYED,
381376
+ Base: NOT_DEPLOYED
381377
+ }
381378
+ },
381379
+ {
381380
+ rewardToken: "SWISE",
381381
+ poolAddress: {
381382
+ Mainnet: "0xC5E75ccd4d40e2Fb280f008f8AFB5EF3415EFA72",
381383
+ Arbitrum: NOT_DEPLOYED,
381384
+ Optimism: NOT_DEPLOYED,
381385
+ Base: NOT_DEPLOYED
381386
+ }
381387
+ }
381388
+ ]
381389
+ },
381390
+ AURA_BPT_RETH_ETH_POOL: {
381391
+ name: "BeethovenX rETH-ETH Pool Aura Deposit",
381392
+ protocol: 11,
381393
+ type: 10,
381394
+ stakedToken: "auraBPT_rETH_ETH_vault",
381395
+ extraRewards: [
381396
+ {
381397
+ rewardToken: "OP",
381398
+ poolAddress: {
381399
+ Mainnet: NOT_DEPLOYED,
381400
+ Arbitrum: NOT_DEPLOYED,
381401
+ Optimism: "0x0A22Ae9D9D149C14f6c15A235e715bB6C1Cfa739",
381402
+ Base: NOT_DEPLOYED
381403
+ }
381404
+ },
381405
+ {
381406
+ rewardToken: "AURA",
381407
+ poolAddress: {
381408
+ Mainnet: NOT_DEPLOYED,
381409
+ Arbitrum: NOT_DEPLOYED,
381410
+ Optimism: "0x81673Cdd00c2839440f31575cCFa5B6ca4a87B2B",
381411
+ Base: NOT_DEPLOYED
381412
+ }
381413
+ }
381414
+ ]
381415
+ },
381416
+ AURA_BPT_WSTETH_ETH_POOL: {
381417
+ name: "BeethovenX wstETH-ETH Pool Aura Deposit",
381418
+ protocol: 11,
381419
+ type: 10,
381420
+ stakedToken: "auraBPT_WSTETH_ETH_vault",
381421
+ extraRewards: [
381422
+ {
381423
+ rewardToken: "OP",
381424
+ poolAddress: {
381425
+ Mainnet: NOT_DEPLOYED,
381426
+ Arbitrum: NOT_DEPLOYED,
381427
+ Optimism: "0x903d716fe68e7e091eCC43AA93c0F8cfD7e7BC0a",
381428
+ Base: NOT_DEPLOYED
381429
+ }
381430
+ },
381431
+ {
381432
+ rewardToken: "AURA",
381433
+ poolAddress: {
381434
+ Mainnet: NOT_DEPLOYED,
381435
+ Arbitrum: NOT_DEPLOYED,
381436
+ Optimism: "0xb0709c230C06BE6e2A84b2Ba877094EB9a4fA014",
381437
+ Base: NOT_DEPLOYED
381438
+ }
381439
+ }
381440
+ ]
381441
+ },
381442
+ AURA_WSTETH_WETH_POOL_ARB: {
381443
+ name: "Balancer (Arbitrum) wstETH-WETH Aura Vault",
381444
+ protocol: 11,
381445
+ type: 10,
381446
+ stakedToken: "aurawstETH_WETH_BPT_vault",
381447
+ extraRewards: [
381448
+ {
381449
+ rewardToken: "AURA",
381450
+ poolAddress: {
381451
+ Mainnet: NOT_DEPLOYED,
381452
+ Arbitrum: "0xC0353d05D3F2b6e14E36c5d3B4bF8d179890A001",
381453
+ Optimism: NOT_DEPLOYED,
381454
+ Base: NOT_DEPLOYED
381455
+ }
381456
+ },
381457
+ {
381458
+ rewardToken: "ARB",
381459
+ poolAddress: {
381460
+ Mainnet: NOT_DEPLOYED,
381461
+ Arbitrum: "0x3a0beff39E243453960aD1198Fc3aAabdBDDe56C",
381462
+ Optimism: NOT_DEPLOYED,
381463
+ Base: NOT_DEPLOYED
381464
+ }
381465
+ }
381466
+ ]
381467
+ },
381468
+ AURA_WSTETH_RETH_SFRXETH_POOL_ARB: {
381469
+ name: "Balancer (Arbitrum) wstETH-rETH-sfrxETH Aura Vault",
381470
+ protocol: 11,
381471
+ type: 10,
381472
+ stakedToken: "aurawstETH_rETH_sfrxETH_vault",
381473
+ extraRewards: [
381474
+ {
381475
+ rewardToken: "AURA",
381476
+ poolAddress: {
381477
+ Mainnet: NOT_DEPLOYED,
381478
+ Arbitrum: "0x5901ce1c3Bf6C97fC49ED0fF08A88a57ea6E4Ca4",
381479
+ Optimism: NOT_DEPLOYED,
381480
+ Base: NOT_DEPLOYED
381481
+ }
381482
+ },
381483
+ {
381484
+ rewardToken: "ARB",
381485
+ poolAddress: {
381486
+ Mainnet: NOT_DEPLOYED,
381487
+ Arbitrum: "0x4601Ec46A285714e6F2A9466DA7f2BcB33646391",
381488
+ Optimism: NOT_DEPLOYED,
381489
+ Base: NOT_DEPLOYED
381490
+ }
381491
+ }
381492
+ ]
381493
+ },
381494
+ AURA_CBETH_RETH_WSTETH_POOL_ARB: {
381495
+ name: "Balancer (Arbitrum) wstETH-rETH-cbETH Aura Vault",
381496
+ protocol: 11,
381497
+ type: 10,
381498
+ stakedToken: "auracbETH_rETH_wstETH_vault",
381499
+ extraRewards: [
381500
+ {
381501
+ rewardToken: "ARB",
381502
+ poolAddress: {
381503
+ Mainnet: NOT_DEPLOYED,
381504
+ Arbitrum: "0xf0dcb30811228bED2b87b2753fabAfe80A9D0fb9",
381505
+ Optimism: NOT_DEPLOYED,
381506
+ Base: NOT_DEPLOYED
381507
+ }
381508
+ },
381509
+ {
381510
+ rewardToken: "AURA",
381511
+ poolAddress: {
381512
+ Mainnet: NOT_DEPLOYED,
381513
+ Arbitrum: "0xE42D389058D820177b83E2863FEb13733d6Dd5f2",
381514
+ Optimism: NOT_DEPLOYED,
381515
+ Base: NOT_DEPLOYED
381516
+ }
381517
+ }
381518
+ ]
381519
+ },
381520
+ AURA_RETH_WETH_POOL_ARB: {
381521
+ name: "Balancer (Arbitrum) rETH-WETH Aura Vault",
381522
+ protocol: 11,
381523
+ type: 10,
381524
+ stakedToken: "aurarETH_wETH_BPT_vault",
381525
+ extraRewards: [
381526
+ {
381527
+ rewardToken: "AURA",
381528
+ poolAddress: {
381529
+ Mainnet: NOT_DEPLOYED,
381530
+ Arbitrum: "0xeA270927C226454452DDF80e24a02087D0D7089F",
381531
+ Optimism: NOT_DEPLOYED,
381532
+ Base: NOT_DEPLOYED
381533
+ }
381534
+ },
381535
+ {
381536
+ rewardToken: "ARB",
381537
+ poolAddress: {
381538
+ Mainnet: NOT_DEPLOYED,
381539
+ Arbitrum: "0xB05Dc0b460Ca3ed5174b33A7dA2104388764F62D",
381540
+ Optimism: NOT_DEPLOYED,
381541
+ Base: NOT_DEPLOYED
381542
+ }
381543
+ }
381544
+ ]
381545
+ },
381546
+ LIDO_STETH_GATEWAY: {
381547
+ name: "Lido STETH",
381548
+ protocol: 5,
381549
+ type: 13,
381550
+ oracle: {
381551
+ Mainnet: "0x442af784A788A5bd6F42A01Ebe9F287a871243fb",
381552
+ Arbitrum: NOT_DEPLOYED,
381553
+ // LIDO_ORACLE
381554
+ Optimism: NOT_DEPLOYED,
381555
+ Base: NOT_DEPLOYED
381556
+ },
381557
+ lpToken: "steCRV"
381558
+ },
381559
+ LIDO_WSTETH: {
381560
+ name: "Lido wstETH",
381561
+ protocol: 5,
381562
+ type: 15
381563
+ /* LIDO_WSTETH_V1 */
381564
+ },
381565
+ UNIVERSAL_ADAPTER: {
381566
+ name: "Gearbox universal adapter",
381567
+ protocol: 6,
381568
+ type: 14
381569
+ /* UNIVERSAL */
381570
+ },
381571
+ BALANCER_VAULT: {
381572
+ name: "Balancer Vault",
381573
+ protocol: 7,
381574
+ type: 16,
381575
+ queries: {
381576
+ Mainnet: "0xE39B5e3B6D74016b2F6A9673D7d7493B6DF549d5",
381577
+ Arbitrum: "0xE39B5e3B6D74016b2F6A9673D7d7493B6DF549d5",
381578
+ Optimism: "0xE39B5e3B6D74016b2F6A9673D7d7493B6DF549d5",
381579
+ Base: NOT_DEPLOYED
381580
+ }
381581
+ },
381582
+ AAVE_V2_LENDING_POOL: {
381583
+ name: "Aave V2 Lending Pool",
381584
+ protocol: 8,
381585
+ type: 17
381586
+ /* AAVE_V2_LENDING_POOL */
381587
+ },
381588
+ AAVE_V2_DAI_TOKEN_WRAPPER: {
381589
+ name: "Aave V2 DAI Token Wrapper",
381590
+ protocol: 8,
381591
+ type: 18,
381592
+ underlying: "aDAI"
381593
+ },
381594
+ AAVE_V2_USDC_TOKEN_WRAPPER: {
381595
+ name: "Aave V2 USDC Token Wrapper",
381596
+ protocol: 8,
381597
+ type: 18,
381598
+ underlying: "aUSDC"
381599
+ },
381600
+ AAVE_V2_USDT_TOKEN_WRAPPER: {
381601
+ name: "Aave V2 USDT Token Wrapper",
381602
+ protocol: 8,
381603
+ type: 18,
381604
+ underlying: "aUSDT"
381605
+ },
381606
+ AAVE_V2_WETH_TOKEN_WRAPPER: {
381607
+ name: "Aave V2 WETH Token Wrapper",
381608
+ protocol: 8,
381609
+ type: 18,
381610
+ underlying: "aWETH"
381611
+ },
381612
+ AAVE_V3_LENDING_POOL: {
381613
+ name: "Aave V3 Lending Pool",
381614
+ protocol: 18,
381615
+ type: 27
381616
+ /* AAVE_V3_LENDING_POOL */
381617
+ },
381618
+ COMPOUND_V2_DAI_POOL: {
381619
+ name: "Compound V2 DAI",
381620
+ protocol: 9,
381621
+ type: 19,
381622
+ underlying: "DAI"
381623
+ },
381624
+ COMPOUND_V2_USDC_POOL: {
381625
+ name: "Compound V2 DAI",
381626
+ protocol: 9,
381627
+ type: 19,
381628
+ underlying: "USDT"
381629
+ },
381630
+ COMPOUND_V2_USDT_POOL: {
381631
+ name: "Compound V2 DAI",
381632
+ protocol: 9,
381633
+ type: 19,
381634
+ underlying: "USDT"
381635
+ },
381636
+ COMPOUND_V2_LINK_POOL: {
381637
+ name: "Compound V2 LINK",
381638
+ protocol: 9,
381639
+ type: 19,
381640
+ underlying: "LINK"
381641
+ },
381642
+ COMPOUND_V2_ETH_GATEWAY: {
381643
+ name: "Compound V2 ETH",
381644
+ protocol: 9,
381645
+ type: 20,
381646
+ underlying: "WETH"
381647
+ },
381648
+ FLUX_USDC_POOL: {
381649
+ name: "Flux USDC",
381650
+ protocol: 10,
381651
+ type: 19,
381652
+ underlying: "USDC"
381653
+ },
381654
+ ZIRCUIT_POOL: {
381655
+ name: "Zircuit staking pool",
381656
+ protocol: 20,
381657
+ type: 28
381658
+ /* ZIRCUIT_POOL */
381659
+ },
381660
+ MELLOW_STEAKHOUSE_VAULT: {
381661
+ name: "Mellow Steakhouse steakLRT vault",
381662
+ protocol: 21,
381663
+ type: 30
381664
+ /* MELLOW_LRT_VAULT */
381665
+ },
381666
+ MELLOW_RE7_LABS_VAULT: {
381667
+ name: "Mellow Re7 Labs Re7LRT vault",
381668
+ protocol: 21,
381669
+ type: 30
381670
+ /* MELLOW_LRT_VAULT */
381671
+ },
381672
+ MELLOW_AMPHOR_VAULT: {
381673
+ name: "Mellow Amphor amphrETH vault",
381674
+ protocol: 21,
381675
+ type: 30
381676
+ /* MELLOW_LRT_VAULT */
381677
+ },
381678
+ MELLOW_RESTAKING_VAULT: {
381679
+ name: "Mellow Restaking rstETH vault",
381680
+ protocol: 21,
381681
+ type: 30
381682
+ /* MELLOW_LRT_VAULT */
381683
+ },
381684
+ MELLOW_RENZO_VAULT: {
381685
+ name: "Mellow Renzo pzETH vault",
381686
+ protocol: 21,
381687
+ type: 30
381688
+ /* MELLOW_LRT_VAULT */
381689
+ },
381690
+ SKY_STAKING_REWARDS: {
381691
+ name: "Sky StakingRewards contract",
381692
+ protocol: 23,
381693
+ type: 34,
381694
+ stakedToken: "stkUSDS"
381695
+ },
381696
+ DAI_USDS: {
381697
+ name: "DAI/USDS Exchange",
381698
+ protocol: 23,
381699
+ type: 33
381700
+ /* DAI_USDS_EXCHANGE */
381701
+ }
381702
+ };
381703
+ var contractsByAddress = Object.entries(contractsByNetwork).reduce(
381704
+ (acc, [, contracts2]) => ({
381705
+ ...acc,
381706
+ ...Object.fromEntries(
381707
+ Object.entries(contracts2).map(([k, v]) => [v.toLowerCase(), k]).filter((k) => !!k)
381708
+ )
381709
+ }),
381710
+ {}
381711
+ );
381712
+ var PriceFeedType = /* @__PURE__ */ ((PriceFeedType2) => {
381713
+ PriceFeedType2[PriceFeedType2["CHAINLINK_ORACLE"] = 0] = "CHAINLINK_ORACLE";
381714
+ PriceFeedType2[PriceFeedType2["YEARN_ORACLE"] = 1] = "YEARN_ORACLE";
381715
+ PriceFeedType2[PriceFeedType2["CURVE_2LP_ORACLE"] = 2] = "CURVE_2LP_ORACLE";
381716
+ PriceFeedType2[PriceFeedType2["CURVE_3LP_ORACLE"] = 3] = "CURVE_3LP_ORACLE";
381717
+ PriceFeedType2[PriceFeedType2["CURVE_4LP_ORACLE"] = 4] = "CURVE_4LP_ORACLE";
381718
+ PriceFeedType2[PriceFeedType2["ZERO_ORACLE"] = 5] = "ZERO_ORACLE";
381719
+ PriceFeedType2[PriceFeedType2["WSTETH_ORACLE"] = 6] = "WSTETH_ORACLE";
381720
+ PriceFeedType2[PriceFeedType2["BOUNDED_ORACLE"] = 7] = "BOUNDED_ORACLE";
381721
+ PriceFeedType2[PriceFeedType2["COMPOSITE_ORACLE"] = 8] = "COMPOSITE_ORACLE";
381722
+ PriceFeedType2[PriceFeedType2["WRAPPED_AAVE_V2_ORACLE"] = 9] = "WRAPPED_AAVE_V2_ORACLE";
381723
+ PriceFeedType2[PriceFeedType2["COMPOUND_V2_ORACLE"] = 10] = "COMPOUND_V2_ORACLE";
381724
+ PriceFeedType2[PriceFeedType2["BALANCER_STABLE_LP_ORACLE"] = 11] = "BALANCER_STABLE_LP_ORACLE";
381725
+ PriceFeedType2[PriceFeedType2["BALANCER_WEIGHTED_LP_ORACLE"] = 12] = "BALANCER_WEIGHTED_LP_ORACLE";
381726
+ PriceFeedType2[PriceFeedType2["CURVE_CRYPTO_ORACLE"] = 13] = "CURVE_CRYPTO_ORACLE";
381727
+ PriceFeedType2[PriceFeedType2["THE_SAME_AS"] = 14] = "THE_SAME_AS";
381728
+ PriceFeedType2[PriceFeedType2["REDSTONE_ORACLE"] = 15] = "REDSTONE_ORACLE";
381729
+ PriceFeedType2[PriceFeedType2["ERC4626_VAULT_ORACLE"] = 16] = "ERC4626_VAULT_ORACLE";
381730
+ PriceFeedType2[PriceFeedType2["NETWORK_DEPENDENT"] = 17] = "NETWORK_DEPENDENT";
381731
+ PriceFeedType2[PriceFeedType2["CURVE_USD_ORACLE"] = 18] = "CURVE_USD_ORACLE";
381732
+ PriceFeedType2[PriceFeedType2["PYTH_ORACLE"] = 19] = "PYTH_ORACLE";
381733
+ PriceFeedType2[PriceFeedType2["MELLOW_LRT_ORACLE"] = 20] = "MELLOW_LRT_ORACLE";
381734
+ PriceFeedType2[PriceFeedType2["PENDLE_PT_TWAP_ORACLE"] = 21] = "PENDLE_PT_TWAP_ORACLE";
381735
+ return PriceFeedType2;
381736
+ })(PriceFeedType || {});
381737
+ var PriceFeedRef = class extends SDKConstruct {
381738
+ address;
381739
+ stalenessPeriod;
381740
+ #priceFeed;
381741
+ constructor(sdk, address, stalenessPeriod) {
381742
+ super(sdk);
381743
+ this.address = address;
381744
+ this.stalenessPeriod = stalenessPeriod;
381745
+ }
381746
+ get priceFeed() {
381747
+ if (!this.#priceFeed) {
381748
+ this.#priceFeed = this.sdk.priceFeeds.mustGet(this.address);
381749
+ }
381750
+ return this.#priceFeed;
381751
+ }
381752
+ stateHuman(raw = true) {
381753
+ return {
381754
+ ...this.priceFeed.stateHuman(raw),
381755
+ stalenessPeriod: formatDuration2(this.stalenessPeriod)
381756
+ };
381757
+ }
381758
+ };
381759
+ var AbstractPriceFeedContract = class extends BaseContract {
381760
+ /**
381761
+ * True if the contract deployed at this address implements IUpdatablePriceFeed interface
381762
+ */
381763
+ #updatable;
381764
+ #decimals;
381765
+ #underlyingPriceFeeds;
381766
+ #skipCheck;
381767
+ hasLowerBoundCap = false;
381768
+ constructor(sdk, args) {
381769
+ super(sdk, {
381770
+ abi: args.abi,
381771
+ addr: args.baseParams.addr,
381772
+ name: args.name,
381773
+ contractType: args.baseParams.contractType,
381774
+ version: args.baseParams.version
381775
+ });
381776
+ this.#decimals = args.decimals;
381777
+ this.#updatable = args.updatable;
381778
+ this.#skipCheck = args.skipCheck;
381779
+ if (args.underlyingFeeds && args.underlyingStalenessPeriods) {
381780
+ this.#underlyingPriceFeeds = args.underlyingFeeds.map(
381781
+ (address, i) => new PriceFeedRef(
381782
+ this.sdk,
381783
+ address,
381784
+ args.underlyingStalenessPeriods[i]
381785
+ )
381786
+ );
381787
+ }
381788
+ }
381789
+ get loaded() {
381790
+ return this.#decimals !== void 0;
381791
+ }
381792
+ get decimals() {
381793
+ if (this.#decimals === void 0) {
381794
+ throw new Error("price feed has been initialized with BaseParams only");
381795
+ }
381796
+ return this.#decimals;
381797
+ }
381798
+ get updatable() {
381799
+ if (this.#updatable === void 0) {
381800
+ throw new Error("price feed has been initialized with BaseParams only");
381801
+ }
381802
+ return this.#updatable;
381803
+ }
381804
+ get skipCheck() {
381805
+ if (this.#skipCheck === void 0) {
381806
+ throw new Error("price feed has been initialized with BaseParams only");
381807
+ }
381808
+ return this.#skipCheck;
381809
+ }
381810
+ get underlyingPriceFeeds() {
381811
+ if (!this.#underlyingPriceFeeds) {
381812
+ throw new Error("price feed has been initialized with BaseParams only");
381813
+ }
381814
+ return this.#underlyingPriceFeeds;
381815
+ }
381816
+ get priceFeedType() {
381817
+ return this.contractType;
381818
+ }
381819
+ stateHuman(raw = true) {
381820
+ return {
381821
+ ...super.stateHuman(raw),
381822
+ contractType: this.priceFeedType,
381823
+ skipCheck: this.skipCheck,
381824
+ pricefeeds: this.underlyingPriceFeeds.map((f) => f.stateHuman(raw))
381825
+ };
381826
+ }
381827
+ async currentLowerBound() {
381828
+ return await this.sdk.provider.publicClient.readContract({
381829
+ abi: ilpPriceFeedAbi,
381830
+ address: this.address,
381831
+ functionName: "lowerBound"
381832
+ });
381833
+ }
381834
+ async answer(overrides) {
381835
+ const lastRoundData = await this.sdk.provider.publicClient.readContract({
381836
+ abi: ilpPriceFeedAbi,
381837
+ address: this.address,
381838
+ functionName: "latestRoundData",
381839
+ ...overrides
381840
+ });
381841
+ return lastRoundData[1];
381842
+ }
381843
+ updatableDependencies() {
381844
+ const underlying = this.underlyingPriceFeeds.flatMap(
381845
+ (f) => f.priceFeed.updatableDependencies()
381846
+ );
381847
+ return this.updatable ? [this, ...underlying] : underlying;
381848
+ }
381849
+ };
381850
+ var LOWER_BOUND_FACTOR = 99n;
381851
+ var AbstractLPPriceFeedContract = class _AbstractLPPriceFeedContract extends AbstractPriceFeedContract {
381852
+ lpContract;
381853
+ lpToken;
381854
+ lowerBound;
381855
+ upperBound;
381856
+ constructor(sdk, args) {
381857
+ super(sdk, { ...args, decimals: 8 });
381858
+ this.hasLowerBoundCap = true;
381859
+ const decoder = decodeAbiParameters(
381860
+ [
381861
+ { type: "address", name: "lpToken" },
381862
+ { type: "address", name: "lpContract" },
381863
+ { type: "uint256", name: "lowerBound" },
381864
+ { type: "uint256", name: "upperBound" },
381865
+ // { type: "bool", name: "updateBoundsAllowed" },
381866
+ // { type: "uint40", name: "lastBoundsUpdate" },
381867
+ { type: "int256", name: "aggregatePrice" },
381868
+ { type: "uint256", name: "lPExchangeRate" },
381869
+ { type: "uint256", name: "scale" }
381870
+ ],
381871
+ hexToBytes(args.baseParams.serializedParams)
381872
+ );
381873
+ this.lpToken = decoder[0];
381874
+ this.lpContract = decoder[1];
381875
+ this.lowerBound = decoder[2];
381876
+ this.upperBound = decoder[3];
381877
+ }
381878
+ async getLowerBound() {
381879
+ const value = await this.getValue();
381880
+ const lowerBound = _AbstractLPPriceFeedContract.toLowerBound(value);
381881
+ this.logger?.debug(
381882
+ `Lowerbound for ${this.labelAddress(this.address)}: ${lowerBound}`
381883
+ );
381884
+ return lowerBound;
381885
+ }
381886
+ static toLowerBound(value) {
381887
+ return value * LOWER_BOUND_FACTOR / 100n;
381888
+ }
381889
+ stateHuman(raw) {
381890
+ return {
381891
+ ...super.stateHuman(raw),
381892
+ lpContract: this.lpContract,
381893
+ lpToken: this.lpToken,
381894
+ lowerBound: this.lowerBound,
381895
+ upperBound: this.upperBound
381896
+ };
381897
+ }
381898
+ };
381899
+ var BalancerStablePriceFeedContract = class extends AbstractLPPriceFeedContract {
381900
+ constructor(sdk, args) {
381901
+ super(sdk, {
381902
+ ...args,
381903
+ name: "BalancerStablePriceFeed",
381904
+ abi: bptStablePriceFeedAbi
381905
+ });
381906
+ }
381907
+ async getValue() {
381908
+ return await this.sdk.provider.publicClient.readContract({
381909
+ abi: iBalancerStablePoolAbi,
381910
+ address: this.lpContract,
381911
+ functionName: "getRate"
381912
+ });
381913
+ }
381914
+ };
381915
+ var BalancerWeightedPriceFeedContract = class extends AbstractLPPriceFeedContract {
381916
+ vault;
381917
+ poolId;
381918
+ weights;
381919
+ constructor(sdk, args) {
381920
+ const decoded = decodeAbiParameters(
381921
+ [
381922
+ { type: "bytes", name: "superParams" },
381923
+ { type: "address", name: "vault" },
381924
+ { type: "bytes32", name: "poolId" },
381925
+ { type: "uint256[8]", name: "weights" }
381926
+ ],
381927
+ hexToBytes(args.baseParams.serializedParams)
381928
+ );
381929
+ super(sdk, {
381930
+ ...args,
381931
+ baseParams: {
381932
+ ...args.baseParams,
381933
+ serializedParams: decoded[0]
381934
+ },
381935
+ name: "BalancerWeighedPriceFeed",
381936
+ abi: bptWeightedPriceFeedAbi
381937
+ });
381938
+ this.vault = decoded[1];
381939
+ this.poolId = decoded[2];
381940
+ this.weights = decoded[3];
381941
+ }
381942
+ async getValue() {
381943
+ return await this.sdk.provider.publicClient.readContract({
381944
+ abi: iBalancerWeightedPoolAbi,
381945
+ address: this.lpContract,
381946
+ functionName: "getRate"
381947
+ });
381948
+ }
381949
+ stateHuman(raw) {
381950
+ return {
381951
+ ...super.stateHuman(raw),
381952
+ contractType: "PF_BALANCER_WEIGHTED_LP_ORACLE",
381953
+ vault: this.vault,
381954
+ poolId: this.poolId,
381955
+ weights: [...this.weights]
381956
+ };
381957
+ }
381958
+ };
381959
+ var BoundedPriceFeedContract = class extends AbstractPriceFeedContract {
381960
+ upperBound;
381961
+ constructor(sdk, args) {
381962
+ super(sdk, { ...args, name: "BoundedPriceFeed", abi: boundedPriceFeedAbi });
381963
+ const decoder = decodeAbiParameters(
381964
+ [
381965
+ { type: "int256" }
381966
+ // upperBound
381967
+ ],
381968
+ args.baseParams.serializedParams
381969
+ );
381970
+ this.upperBound = decoder[0];
381971
+ }
381972
+ stateHuman(raw = true) {
381973
+ return {
381974
+ ...super.stateHuman(raw),
381975
+ contractType: "PF_BOUNDED_ORACLE",
381976
+ upperBound: this.upperBound
381977
+ };
381978
+ }
381979
+ };
381980
+ var ChainlinkPriceFeedContract = class extends AbstractPriceFeedContract {
381981
+ constructor(sdk, args) {
381982
+ super(sdk, {
381983
+ ...args,
381984
+ name: "ChainlinkPriceFeed",
381985
+ abi: chainlinkReadableAggregatorAbi
381986
+ });
381987
+ }
381988
+ };
381989
+ var CompositePriceFeedContract = class extends AbstractPriceFeedContract {
381990
+ constructor(sdk, args) {
381991
+ super(sdk, {
381992
+ ...args,
381993
+ name: "CompositePriceFeed",
381994
+ abi: compositePriceFeedAbi
381995
+ });
381996
+ }
381997
+ get targetToBasePriceFeed() {
381998
+ return this.underlyingPriceFeeds[0];
381999
+ }
382000
+ get baseToUsdPriceFeed() {
382001
+ return this.underlyingPriceFeeds[1];
382002
+ }
382003
+ };
382004
+ var CurveCryptoPriceFeedContract = class extends AbstractLPPriceFeedContract {
382005
+ constructor(sdk, args) {
382006
+ super(sdk, {
382007
+ ...args,
382008
+ name: "CurveCryptoPriceFeed",
382009
+ abi: curveCryptoLpPriceFeedAbi
382010
+ });
382011
+ }
382012
+ async getValue() {
382013
+ return await this.sdk.provider.publicClient.readContract({
382014
+ abi: iCurvePoolAbi,
382015
+ address: this.lpContract,
382016
+ functionName: "get_virtual_price"
382017
+ });
382018
+ }
382019
+ };
382020
+ var CurveStablePriceFeedContract = class extends AbstractLPPriceFeedContract {
382021
+ constructor(sdk, args) {
382022
+ super(sdk, {
382023
+ ...args,
382024
+ name: "CurveStablePriceFeed",
382025
+ abi: curveStableLpPriceFeedAbi
382026
+ });
382027
+ }
382028
+ async getValue() {
382029
+ return await this.sdk.provider.publicClient.readContract({
382030
+ abi: iCurvePoolAbi,
382031
+ address: this.lpContract,
382032
+ functionName: "get_virtual_price"
382033
+ });
382034
+ }
382035
+ };
382036
+ var CurveUSDPriceFeedContract = class extends AbstractLPPriceFeedContract {
382037
+ constructor(sdk, args) {
382038
+ super(sdk, {
382039
+ ...args,
382040
+ name: "CurveUSDPriceFeed",
382041
+ abi: curveUsdPriceFeedAbi
382042
+ });
382043
+ }
382044
+ async getValue() {
382045
+ return await this.sdk.provider.publicClient.readContract({
382046
+ abi: iCurvePoolAbi,
382047
+ address: this.lpContract,
382048
+ functionName: "get_virtual_price"
382049
+ });
382050
+ }
382051
+ };
382052
+ var Erc4626PriceFeedContract = class extends AbstractLPPriceFeedContract {
382053
+ constructor(sdk, args) {
382054
+ super(sdk, {
382055
+ ...args,
382056
+ name: "ERC4626PriceFeed",
382057
+ abi: erc4626PriceFeedAbi
382058
+ });
382059
+ }
382060
+ async getValue() {
382061
+ const decimals2 = await this.sdk.provider.publicClient.readContract({
382062
+ abi: erc20Abi2,
382063
+ address: this.lpContract,
382064
+ functionName: "decimals"
382065
+ });
382066
+ const price = await this.sdk.provider.publicClient.readContract({
382067
+ abi: erc4626Abi,
382068
+ address: this.lpContract,
382069
+ functionName: "convertToAssets",
382070
+ args: [10n ** BigInt(decimals2)]
382071
+ });
382072
+ return price;
382073
+ }
382074
+ };
382075
+ var MellowLRTPriceFeedContract = class extends AbstractLPPriceFeedContract {
382076
+ constructor(sdk, args) {
382077
+ super(sdk, {
382078
+ ...args,
382079
+ name: "MellowLRTPriceFeed",
382080
+ abi: mellowLrtPriceFeedAbi
382081
+ });
382082
+ }
382083
+ async getValue() {
382084
+ const stack = await this.sdk.provider.publicClient.readContract({
382085
+ abi: iMellowVaultAbi,
382086
+ address: this.lpContract,
382087
+ functionName: "calculateStack"
382088
+ });
382089
+ return stack.totalValue * BigInt(1e18) / stack.totalSupply;
382090
+ }
382091
+ };
382092
+ var abi29 = pendleTWAPPTPriceFeedAbi;
382093
+ var PendleTWAPPTPriceFeed = class extends AbstractPriceFeedContract {
382094
+ market;
382095
+ sy;
382096
+ yt;
382097
+ expiry;
382098
+ twapWindow;
382099
+ priceToSy;
382100
+ constructor(sdk, args) {
382101
+ super(sdk, {
382102
+ ...args,
382103
+ name: "PendleTWAPPTPriceFeed",
382104
+ abi: abi29
382105
+ });
382106
+ const decoded = decodeAbiParameters(
382107
+ [
382108
+ { type: "address", name: "market" },
382109
+ { type: "address", name: "sy" },
382110
+ { type: "address", name: "yt" },
382111
+ { type: "uint256", name: "expiry" },
382112
+ { type: "uint32", name: "twapWindow" },
382113
+ { type: "bool", name: "priceToSy" }
382114
+ ],
382115
+ args.baseParams.serializedParams
382116
+ );
382117
+ this.market = decoded[0];
382118
+ this.sy = decoded[1];
382119
+ this.yt = decoded[2];
382120
+ this.expiry = decoded[3];
382121
+ this.twapWindow = decoded[4];
382122
+ this.priceToSy = decoded[5];
382123
+ }
382124
+ };
382125
+ var Hooks = class {
382126
+ #reg = {};
382127
+ addHook(hookName, fn) {
382128
+ if (!this.#reg[hookName]) {
382129
+ this.#reg[hookName] = [];
382130
+ }
382131
+ this.#reg[hookName].push(fn);
382132
+ }
382133
+ removeHook(hookName, fn) {
382134
+ if (!this.#reg[hookName]) {
382135
+ return;
382136
+ }
382137
+ this.#reg[hookName] = this.#reg[hookName]?.filter((hookFn) => hookFn !== fn) ?? [];
382138
+ }
382139
+ async triggerHooks(hookName, ...args) {
382140
+ if (!this.#reg[hookName]) {
382141
+ return;
382142
+ }
382143
+ for (const fn of this.#reg[hookName]) {
382144
+ await fn(...args);
382145
+ }
382146
+ }
382147
+ };
382148
+ var RedstonePriceFeedContract = class extends AbstractPriceFeedContract {
382149
+ dataServiceId;
382150
+ dataId;
382151
+ signers;
382152
+ signersThreshold;
382153
+ constructor(sdk, args) {
382154
+ super(sdk, {
382155
+ ...args,
382156
+ name: `RedstonePriceFeed`,
382157
+ abi: redstonePriceFeedAbi
382158
+ });
382159
+ const decoder = decodeAbiParameters(
382160
+ [
382161
+ { type: "address" },
382162
+ // [0]: pf.token(),
382163
+ { type: "bytes32" },
382164
+ // [1]: pf.dataFeedId(),
382165
+ { type: "address" },
382166
+ // [2]: pf.signerAddress0(),
382167
+ { type: "address" },
382168
+ // [3]: pf.signerAddress1(),
382169
+ { type: "address" },
382170
+ // [4]: pf.signerAddress2(),
382171
+ { type: "address" },
382172
+ // [5]: pf.signerAddress3(),
382173
+ { type: "address" },
382174
+ // [6]: pf.signerAddress4(),
382175
+ { type: "address" },
382176
+ // [7]: pf.signerAddress5()
382177
+ { type: "address" },
382178
+ // [8]: pf.signerAddress6(),
382179
+ { type: "address" },
382180
+ // [9]: pf.signerAddress7(),
382181
+ { type: "address" },
382182
+ // [10]: pf.signerAddress8(),
382183
+ { type: "address" },
382184
+ // [11]: pf.signerAddress9(),
382185
+ { type: "uint8" },
382186
+ // [12]: pf.getUniqueSignersThreshold()
382187
+ { type: "uint128" },
382188
+ // [13]: pf.lastPrice(),
382189
+ { type: "uint40" }
382190
+ // [14]: pf.lastPayloadTimestamp()
382191
+ ],
382192
+ args.baseParams.serializedParams
382193
+ );
382194
+ this.dataId = bytesToString(toBytes(decoder[1])).replaceAll("\0", "");
382195
+ this.signers = decoder.slice(2, 11);
382196
+ this.signersThreshold = Number(decoder[12]);
382197
+ this.dataServiceId = ["GMX", "BAL"].includes(this.dataId) ? "redstone-arbitrum-prod" : "redstone-primary-prod";
382198
+ }
382199
+ stateHuman(raw = true) {
382200
+ return {
382201
+ ...super.stateHuman(raw),
382202
+ contractType: "PF_REDSTONE_ORACLE",
382203
+ dataId: this.dataId,
382204
+ signers: this.signers,
382205
+ signersThreshold: this.signersThreshold,
382206
+ skipCheck: true
382207
+ };
382208
+ }
382209
+ };
382210
+ var RedstoneUpdater = class extends SDKConstruct {
382211
+ #logger;
382212
+ #cache = /* @__PURE__ */ new Map();
382213
+ #historicalTimestampMs;
382214
+ constructor(sdk) {
382215
+ super(sdk);
382216
+ this.#logger = childLogger("RedstoneUpdater", sdk.logger);
382217
+ }
382218
+ setHistoricalTimestamp(timestampMs) {
382219
+ this.#historicalTimestampMs = 6e4 * Math.floor(timestampMs / 6e4);
382220
+ }
382221
+ async getUpdateTxs(feeds, logContext = {}) {
382222
+ this.#logger?.debug(
382223
+ logContext,
382224
+ `generating update transactions for ${feeds.length} redstone price feeds`
382225
+ );
382226
+ const groupedFeeds = {};
382227
+ const priceFeeds = /* @__PURE__ */ new Map();
382228
+ for (const feed of feeds) {
382229
+ const key = `${feed.dataServiceId}:${feed.signersThreshold}`;
382230
+ if (!groupedFeeds[key]) {
382231
+ groupedFeeds[key] = /* @__PURE__ */ new Set();
382232
+ }
382233
+ groupedFeeds[key].add(feed.dataId);
382234
+ priceFeeds.set(feed.dataId, feed);
382235
+ }
382236
+ const results = [];
382237
+ for (const [key, group] of Object.entries(groupedFeeds)) {
382238
+ const [dataServiceId, signersStr] = key.split(":");
382239
+ const uniqueSignersCount = parseInt(signersStr, 10);
382240
+ const payloads = await this.#getPayloads(
382241
+ dataServiceId,
382242
+ group,
382243
+ uniqueSignersCount
382244
+ );
382245
+ for (const { dataFeedId, data, timestamp } of payloads) {
382246
+ const priceFeed = priceFeeds.get(dataFeedId);
382247
+ if (!priceFeed) {
382248
+ throw new Error(`cannot get price feed address for ${dataFeedId}`);
382838
382249
  }
382250
+ results.push({
382251
+ priceFeed: priceFeed.address.toLowerCase(),
382252
+ tx: priceFeed.createRawTx({
382253
+ functionName: "updatePrice",
382254
+ args: [data],
382255
+ description: `updating price for ${dataFeedId} [${this.sdk.provider.addressLabels.get(priceFeed.address)}]`
382256
+ }),
382257
+ timestamp
382258
+ });
382839
382259
  }
382840
- ]
382841
- },
382842
- CONVEX_FRAX3CRV_POOL: {
382843
- name: "Convex FRAX3CRV",
382844
- protocol: 4,
382845
- type: 10,
382846
- stakedToken: "stkcvxFRAX3CRV",
382847
- extraRewards: [
382848
- {
382849
- rewardToken: "FXS",
382850
- poolAddress: {
382851
- Mainnet: "0xcDEC6714eB482f28f4889A0c122868450CDBF0b0",
382852
- Arbitrum: NOT_DEPLOYED,
382853
- // CONVEX_FRAX3CRV_POOL_EXTRA_FXS
382854
- Optimism: NOT_DEPLOYED,
382855
- Base: NOT_DEPLOYED
382856
- }
382260
+ }
382261
+ this.#logger?.debug(
382262
+ logContext,
382263
+ `generated ${results.length} update transactions for redstone price feeds`
382264
+ );
382265
+ return results;
382266
+ }
382267
+ /**
382268
+ * Gets redstone payloads in one request for multiple feeds with the same dataServiceId and uniqueSignersCount
382269
+ * If historicalTimestamp is set, responses will be cached
382270
+ * @param dataServiceId
382271
+ * @param dataFeedsIds
382272
+ * @param uniqueSignersCount
382273
+ * @returns
382274
+ */
382275
+ async #getPayloads(dataServiceId, dataFeedsIds, uniqueSignersCount) {
382276
+ this.#logger?.debug(
382277
+ `getting redstone payloads for ${dataFeedsIds.size} data feeds in ${dataServiceId} with ${uniqueSignersCount} signers: ${Array.from(dataFeedsIds).join(", ")}`
382278
+ );
382279
+ const fromCache = [];
382280
+ const uncached = [];
382281
+ for (const dataFeedId of dataFeedsIds) {
382282
+ const key = cacheKey2(
382283
+ dataServiceId,
382284
+ dataFeedId,
382285
+ uniqueSignersCount,
382286
+ this.#historicalTimestampMs
382287
+ );
382288
+ const cached = this.#cache.get(key);
382289
+ if (this.#historicalTimestampMs && !!cached) {
382290
+ fromCache.push(cached);
382291
+ } else {
382292
+ uncached.push(dataFeedId);
382857
382293
  }
382858
- ]
382859
- },
382860
- CONVEX_LUSD3CRV_POOL: {
382861
- name: "Convex LUSD3CRV",
382862
- protocol: 4,
382863
- type: 10,
382864
- stakedToken: "stkcvxLUSD3CRV",
382865
- extraRewards: [
382866
- {
382867
- rewardToken: "LQTY",
382868
- poolAddress: {
382869
- Mainnet: "0x55d59b791f06dc519B176791c4E037E8Cf2f6361",
382870
- Arbitrum: NOT_DEPLOYED,
382871
- // CONVEX_LUSD3CRV_POOL_EXTRA_LQTY
382872
- Optimism: NOT_DEPLOYED,
382873
- Base: NOT_DEPLOYED
382874
- }
382294
+ }
382295
+ const fromRedstone = await this.#fetchPayloads(
382296
+ dataServiceId,
382297
+ new Set(uncached),
382298
+ uniqueSignersCount
382299
+ );
382300
+ if (this.#historicalTimestampMs) {
382301
+ for (const resp of fromRedstone) {
382302
+ const key = cacheKey2(
382303
+ dataServiceId,
382304
+ resp.dataFeedId,
382305
+ uniqueSignersCount,
382306
+ this.#historicalTimestampMs
382307
+ );
382308
+ this.#cache.set(key, resp);
382875
382309
  }
382876
- ]
382877
- },
382878
- CONVEX_CRVETH_POOL: {
382879
- name: "Convex crvCRVETH",
382880
- protocol: 4,
382881
- type: 10,
382882
- stakedToken: "stkcvxcrvCRVETH",
382883
- extraRewards: [
382884
- {
382885
- rewardToken: "CVX",
382886
- poolAddress: {
382887
- Mainnet: "0xE1eCBB4181378E2346EAC90Eb5606c01Aa08f052",
382888
- Arbitrum: NOT_DEPLOYED,
382889
- Optimism: NOT_DEPLOYED,
382890
- Base: NOT_DEPLOYED
382891
- }
382310
+ }
382311
+ this.#logger?.debug(
382312
+ `got ${fromRedstone.length} new redstone updates and ${fromCache.length} from cache`
382313
+ );
382314
+ return [...fromCache, ...fromRedstone];
382315
+ }
382316
+ /**
382317
+ * Fetches redstone payloads in one request for multiple feeds with the same dataServiceId and uniqueSignersCount
382318
+ * Payloads are loaded in one request to avoid redstone rate limit
382319
+ * @param dataServiceId
382320
+ * @param dataFeedsIds
382321
+ * @param uniqueSignersCount
382322
+ * @returns
382323
+ */
382324
+ async #fetchPayloads(dataServiceId, dataFeedsIds, uniqueSignersCount) {
382325
+ if (dataFeedsIds.size === 0) {
382326
+ return [];
382327
+ }
382328
+ const dataPackagesIds = Array.from(dataFeedsIds);
382329
+ const tsStr = this.#historicalTimestampMs ? ` with historical timestamp ${this.#historicalTimestampMs}` : "";
382330
+ this.#logger?.debug(
382331
+ `fetching redstone payloads for ${dataFeedsIds.size} data feeds in ${dataServiceId} with ${uniqueSignersCount} signers: ${dataPackagesIds.join(", ")}${tsStr}`
382332
+ );
382333
+ const wrapper = new import_evm_connector.DataServiceWrapper({
382334
+ dataServiceId,
382335
+ dataPackagesIds,
382336
+ uniqueSignersCount,
382337
+ historicalTimestamp: this.#historicalTimestampMs
382338
+ });
382339
+ const dataPayload = await wrapper.prepareRedstonePayload(true);
382340
+ const parsed = import_redstone_protocol.RedstonePayload.parse(toBytes(`0x${dataPayload}`));
382341
+ const packagesByDataFeedId = groupDataPackages(parsed.signedDataPackages);
382342
+ return dataPackagesIds.map((dataFeedId) => {
382343
+ const signedDataPackages = packagesByDataFeedId[dataFeedId];
382344
+ if (!signedDataPackages) {
382345
+ throw new Error(`cannot find data packages for ${dataFeedId}`);
382892
382346
  }
382893
- ]
382894
- },
382895
- CONVEX_CVXETH_POOL: {
382896
- name: "Convex crvCVXETH",
382897
- protocol: 4,
382898
- type: 10,
382899
- stakedToken: "stkcvxcrvCVXETH",
382900
- extraRewards: [
382901
- {
382902
- rewardToken: "CVX",
382903
- poolAddress: {
382904
- Mainnet: "0x834B9147Fd23bF131644aBC6e557Daf99C5cDa15",
382905
- Arbitrum: NOT_DEPLOYED,
382906
- Optimism: NOT_DEPLOYED,
382907
- Base: NOT_DEPLOYED
382908
- }
382347
+ if (signedDataPackages.length !== uniqueSignersCount) {
382348
+ throw new Error(
382349
+ `got ${signedDataPackages.length} data packages for ${dataFeedId}, but expected ${uniqueSignersCount}`
382350
+ );
382909
382351
  }
382910
- ]
382911
- },
382912
- CONVEX_3CRYPTO_POOL: {
382913
- name: "Convex 3Crypto",
382914
- protocol: 4,
382915
- type: 10,
382916
- stakedToken: "stkcvxcrvUSDTWBTCWETH",
382917
- extraRewards: []
382918
- },
382919
- CONVEX_LDOETH_POOL: {
382920
- name: "Convex LDOETH",
382921
- protocol: 4,
382922
- type: 10,
382923
- stakedToken: "stkcvxLDOETH",
382924
- extraRewards: [
382925
- {
382926
- rewardToken: "LDO",
382927
- poolAddress: {
382928
- Mainnet: "0x95e6092449a0f3946A5a0f308Ead4adcff244E2B",
382929
- Arbitrum: NOT_DEPLOYED,
382930
- Optimism: NOT_DEPLOYED,
382931
- Base: NOT_DEPLOYED
382932
- }
382352
+ return getCalldataWithTimestamp(
382353
+ dataFeedId,
382354
+ signedDataPackages,
382355
+ wrapper.getUnsignedMetadata()
382356
+ );
382357
+ });
382358
+ }
382359
+ };
382360
+ function cacheKey2(dataServiceId, dataFeedId, uniqueSignersCount, historicalTimestamp = 0) {
382361
+ return `${dataServiceId}:${dataFeedId}:${uniqueSignersCount}:${historicalTimestamp}`;
382362
+ }
382363
+ function groupDataPackages(signedDataPackages) {
382364
+ const packagesByDataFeedId = {};
382365
+ for (const p of signedDataPackages) {
382366
+ const { dataPoints } = p.dataPackage;
382367
+ const dataFeedId0 = dataPoints[0].dataFeedId;
382368
+ for (const dp of dataPoints) {
382369
+ if (dp.dataFeedId !== dataFeedId0) {
382370
+ throw new Error(
382371
+ `data package contains data points with different dataFeedIds: ${dp.dataFeedId} and ${dataFeedId0}`
382372
+ );
382933
382373
  }
382934
- ]
382935
- },
382936
- CONVEX_CRVUSD_USDC_POOL: {
382937
- name: "Convex crvUSDUSDC",
382938
- protocol: 4,
382939
- type: 10,
382940
- stakedToken: "stkcvxcrvUSDUSDC",
382941
- extraRewards: [
382374
+ }
382375
+ if (!packagesByDataFeedId[dataFeedId0]) {
382376
+ packagesByDataFeedId[dataFeedId0] = [];
382377
+ }
382378
+ packagesByDataFeedId[dataFeedId0].push(p);
382379
+ }
382380
+ return packagesByDataFeedId;
382381
+ }
382382
+ function getCalldataWithTimestamp(dataFeedId, packages, unsignedMetadata) {
382383
+ const originalPayload = import_redstone_protocol.RedstonePayload.prepare(packages, unsignedMetadata);
382384
+ const originalPayloadLength = originalPayload.length / 2;
382385
+ const bytesToAdd = 32 - originalPayloadLength % 32;
382386
+ const newUnsignedMetadata = unsignedMetadata + "_".repeat(bytesToAdd);
382387
+ const payload = import_redstone_protocol.RedstonePayload.prepare(packages, newUnsignedMetadata);
382388
+ let timestamp = 0;
382389
+ for (const p of packages) {
382390
+ const newTimestamp = p.dataPackage.timestampMilliseconds / 1e3;
382391
+ if (timestamp === 0) {
382392
+ timestamp = newTimestamp;
382393
+ } else if (timestamp !== newTimestamp) {
382394
+ throw new Error("Timestamps are not equal");
382395
+ }
382396
+ }
382397
+ return {
382398
+ dataFeedId,
382399
+ data: encodeAbiParameters(
382400
+ [{ type: "uint256" }, { type: "bytes" }],
382401
+ [BigInt(timestamp), `0x${payload}`]
382402
+ ),
382403
+ timestamp
382404
+ };
382405
+ }
382406
+ var WstETHPriceFeedContract = class extends AbstractLPPriceFeedContract {
382407
+ constructor(sdk, args) {
382408
+ super(sdk, {
382409
+ ...args,
382410
+ name: "WstETHPriceFeed",
382411
+ abi: wstEthPriceFeedAbi
382412
+ });
382413
+ }
382414
+ async getValue() {
382415
+ return await this.sdk.provider.publicClient.readContract({
382416
+ abi: iwstEthAbi,
382417
+ address: this.lpContract,
382418
+ functionName: "stEthPerToken"
382419
+ });
382420
+ }
382421
+ };
382422
+ var YearnPriceFeedContract = class extends AbstractLPPriceFeedContract {
382423
+ constructor(sdk, args) {
382424
+ super(sdk, {
382425
+ ...args,
382426
+ name: "YearnPriceFeed",
382427
+ abi: yearnPriceFeedAbi
382428
+ });
382429
+ }
382430
+ async getValue() {
382431
+ return await this.sdk.provider.publicClient.readContract({
382432
+ abi: iyVaultAbi,
382433
+ address: this.lpContract,
382434
+ functionName: "pricePerShare"
382435
+ });
382436
+ }
382437
+ };
382438
+ var ZeroPriceFeedContract = class extends AbstractPriceFeedContract {
382439
+ constructor(sdk, args) {
382440
+ super(sdk, {
382441
+ ...args,
382442
+ name: "ZeroPriceFeed",
382443
+ abi: zeroPriceFeedAbi,
382444
+ decimals: 8
382445
+ });
382446
+ }
382447
+ };
382448
+ var PriceFeedRegister = class extends SDKConstruct {
382449
+ logger;
382450
+ #hooks = new Hooks();
382451
+ #feeds = new AddressMap();
382452
+ #redstoneUpdater;
382453
+ constructor(sdk) {
382454
+ super(sdk);
382455
+ this.logger = childLogger("PriceFeedRegister", sdk.logger);
382456
+ this.#redstoneUpdater = new RedstoneUpdater(sdk);
382457
+ }
382458
+ addHook = this.#hooks.addHook.bind(this.#hooks);
382459
+ removeHook = this.#hooks.removeHook.bind(this.#hooks);
382460
+ /**
382461
+ * Returns RawTxs to update price feeds
382462
+ * @param priceFeeds top-level price feeds, actual updatable price feeds will be derived. If not provided will use all price feeds that are attached
382463
+ * @param logContext extra information for logging
382464
+ * @returns
382465
+ */
382466
+ async generatePriceFeedsUpdateTxs(priceFeeds, logContext = {}) {
382467
+ const updateables = priceFeeds ? priceFeeds.flatMap((pf) => pf.updatableDependencies()) : this.#feeds.values();
382468
+ return this.#generatePriceFeedsUpdateTxs(updateables, logContext);
382469
+ }
382470
+ has(address) {
382471
+ return this.#feeds.has(address);
382472
+ }
382473
+ mustGet(address) {
382474
+ return this.#feeds.mustGet(address);
382475
+ }
382476
+ getOrCreate(data) {
382477
+ const existing = this.#feeds.get(data.baseParams.addr);
382478
+ if (existing?.loaded) {
382479
+ return existing;
382480
+ }
382481
+ const feed = this.#create(data);
382482
+ this.#feeds.upsert(data.baseParams.addr, feed);
382483
+ return feed;
382484
+ }
382485
+ /**
382486
+ * Set redstone historical timestamp
382487
+ * @param timestampMs in milliseconds, or true to use timestamp from attach block
382488
+ */
382489
+ setRedstoneHistoricalTimestamp(timestampMs) {
382490
+ const ts = timestampMs === true ? Number(this.sdk.timestamp) * 1e3 : timestampMs;
382491
+ this.#redstoneUpdater.setHistoricalTimestamp(ts);
382492
+ }
382493
+ /**
382494
+ * Loads PARTIAL information about all updatable price feeds from MarketCompressor
382495
+ * This can later be used to load price feed updates
382496
+ */
382497
+ async preloadUpdatablePriceFeeds(marketConfigurators, pools) {
382498
+ const feedsData = await this.#loadUpdatablePriceFeeds(
382499
+ marketConfigurators,
382500
+ pools
382501
+ );
382502
+ for (const data of feedsData) {
382503
+ const feed = this.#create({ baseParams: data });
382504
+ this.#feeds.upsert(feed.address, feed);
382505
+ }
382506
+ }
382507
+ /**
382508
+ * Generates price update transaction via multicall3 without any market data knowledge
382509
+ * @param marketConfigurators
382510
+ * @param pools
382511
+ * @returns
382512
+ */
382513
+ async getUpdatePriceFeedsTx(marketConfigurators, pools) {
382514
+ const feedsData = await this.#loadUpdatablePriceFeeds(
382515
+ marketConfigurators,
382516
+ pools
382517
+ );
382518
+ const feeds = feedsData.map((data) => this.#create({ baseParams: data }));
382519
+ const updates = await this.#generatePriceFeedsUpdateTxs(feeds);
382520
+ return createRawTx(
382521
+ getChainContractAddress({
382522
+ chain: this.sdk.provider.chain,
382523
+ contract: "multicall3"
382524
+ }),
382942
382525
  {
382943
- rewardToken: "CVX",
382944
- poolAddress: {
382945
- Mainnet: "0xac183F7cd62d5b04Fa40362EB67249A80339541A",
382946
- Arbitrum: NOT_DEPLOYED,
382947
- Optimism: NOT_DEPLOYED,
382948
- Base: NOT_DEPLOYED
382949
- }
382526
+ abi: multicall3Abi,
382527
+ functionName: "aggregate3",
382528
+ args: [
382529
+ updates.txs.map((tx) => ({
382530
+ target: tx.to,
382531
+ allowFailure: false,
382532
+ callData: tx.callData
382533
+ }))
382534
+ ]
382950
382535
  }
382951
- ]
382952
- },
382953
- CONVEX_CRVUSD_USDT_POOL: {
382954
- name: "Convex crvUSDUSDT",
382955
- protocol: 4,
382956
- type: 10,
382957
- stakedToken: "stkcvxcrvUSDUSDT",
382958
- extraRewards: [
382959
- {
382960
- rewardToken: "CVX",
382961
- poolAddress: {
382962
- Mainnet: "0xD490178B568b07c6DDbDfBBfaF9043772209Ec01",
382963
- Arbitrum: NOT_DEPLOYED,
382964
- Optimism: NOT_DEPLOYED,
382965
- Base: NOT_DEPLOYED
382966
- }
382536
+ );
382537
+ }
382538
+ async #generatePriceFeedsUpdateTxs(updateables, logContext = {}) {
382539
+ const txs = [];
382540
+ const redstonePFs = [];
382541
+ for (const pf of updateables) {
382542
+ if (pf instanceof RedstonePriceFeedContract) {
382543
+ redstonePFs.push(pf);
382967
382544
  }
382968
- ]
382969
- },
382970
- CONVEX_CRVUSD_FRAX_POOL: {
382971
- name: "Convex crvUSDFRAX",
382972
- protocol: 4,
382973
- type: 10,
382974
- stakedToken: "stkcvxcrvUSDFRAX",
382975
- extraRewards: [
382976
- {
382977
- rewardToken: "CVX",
382978
- poolAddress: {
382979
- Mainnet: "0x749cFfCb53e008841d7387ba37f9284BDeCEe0A9",
382980
- Arbitrum: NOT_DEPLOYED,
382981
- Optimism: NOT_DEPLOYED,
382982
- Base: NOT_DEPLOYED
382545
+ }
382546
+ let maxTimestamp = 0;
382547
+ if (redstonePFs.length > 0) {
382548
+ const redstoneUpdates = await this.#redstoneUpdater.getUpdateTxs(
382549
+ redstonePFs,
382550
+ logContext
382551
+ );
382552
+ for (const { tx, timestamp } of redstoneUpdates) {
382553
+ if (timestamp > maxTimestamp) {
382554
+ maxTimestamp = timestamp;
382983
382555
  }
382556
+ txs.push(tx);
382984
382557
  }
382985
- ]
382986
- },
382987
- CONVEX_TRI_CRV_POOL: {
382988
- name: "Convex TRICRV",
382989
- protocol: 4,
382990
- type: 10,
382991
- stakedToken: "stkcvxcrvUSDETHCRV",
382992
- extraRewards: [
382993
- {
382994
- rewardToken: "CVX",
382995
- poolAddress: {
382996
- Mainnet: "0x01eC96F1eEBF470E3fEAEEfB843fbC63424e668d",
382997
- Arbitrum: NOT_DEPLOYED,
382998
- Optimism: NOT_DEPLOYED,
382999
- Base: NOT_DEPLOYED
382558
+ }
382559
+ const result = { txs, timestamp: maxTimestamp };
382560
+ this.logger?.debug(
382561
+ logContext,
382562
+ `generated ${txs.length} price feed update transactions, timestamp: ${maxTimestamp}`
382563
+ );
382564
+ if (txs.length) {
382565
+ await this.#hooks.triggerHooks("updatesGenerated", result);
382566
+ }
382567
+ return result;
382568
+ }
382569
+ async #loadUpdatablePriceFeeds(marketConfigurators, pools) {
382570
+ const marketCompressorAddress = this.sdk.addressProvider.getAddress(
382571
+ AP_MARKET_COMPRESSOR,
382572
+ 310
382573
+ );
382574
+ const configurators = marketConfigurators ?? this.sdk.marketRegister.marketConfigurators.map((mc) => mc.address);
382575
+ this.logger?.debug(
382576
+ { configurators, pools },
382577
+ "calling getUpdatablePriceFeeds"
382578
+ );
382579
+ const result = await this.provider.publicClient.readContract({
382580
+ address: marketCompressorAddress,
382581
+ abi: iMarketCompressorAbi,
382582
+ functionName: "getUpdatablePriceFeeds",
382583
+ args: [
382584
+ {
382585
+ configurators,
382586
+ pools: pools ?? [],
382587
+ underlying: ADDRESS_0X0
383000
382588
  }
382589
+ ],
382590
+ // It's passed as ...rest in viem readContract action, but this might change
382591
+ // @ts-ignore
382592
+ gas: 500000000n
382593
+ });
382594
+ this.logger?.debug(`loaded ${result.length} updatable price feeds`);
382595
+ return result;
382596
+ }
382597
+ #create(data) {
382598
+ const contractType = bytes32ToString(
382599
+ data.baseParams.contractType
382600
+ );
382601
+ switch (contractType) {
382602
+ case "PF_CHAINLINK_ORACLE":
382603
+ return new ChainlinkPriceFeedContract(this.sdk, data);
382604
+ case "PF_YEARN_ORACLE":
382605
+ return new YearnPriceFeedContract(this.sdk, data);
382606
+ case "PF_CURVE_STABLE_LP_ORACLE":
382607
+ return new CurveStablePriceFeedContract(this.sdk, data);
382608
+ case "PF_WSTETH_ORACLE":
382609
+ return new WstETHPriceFeedContract(this.sdk, data);
382610
+ case "PF_BOUNDED_ORACLE":
382611
+ return new BoundedPriceFeedContract(this.sdk, data);
382612
+ case "PF_COMPOSITE_ORACLE":
382613
+ return new CompositePriceFeedContract(this.sdk, data);
382614
+ case "PF_BALANCER_STABLE_LP_ORACLE":
382615
+ return new BalancerStablePriceFeedContract(this.sdk, data);
382616
+ case "PF_BALANCER_WEIGHTED_LP_ORACLE":
382617
+ return new BalancerWeightedPriceFeedContract(this.sdk, data);
382618
+ case "PF_CURVE_CRYPTO_LP_ORACLE":
382619
+ return new CurveCryptoPriceFeedContract(this.sdk, data);
382620
+ case "PF_REDSTONE_ORACLE":
382621
+ return new RedstonePriceFeedContract(this.sdk, data);
382622
+ case "PF_ERC4626_ORACLE":
382623
+ return new Erc4626PriceFeedContract(this.sdk, data);
382624
+ case "PF_CURVE_USD_ORACLE":
382625
+ return new CurveUSDPriceFeedContract(this.sdk, data);
382626
+ case "PF_ZERO_ORACLE":
382627
+ return new ZeroPriceFeedContract(this.sdk, data);
382628
+ case "PF_MELLOW_LRT_ORACLE":
382629
+ return new MellowLRTPriceFeedContract(this.sdk, data);
382630
+ case "PF_PENDLE_PT_TWAP_ORACLE":
382631
+ return new PendleTWAPPTPriceFeed(this.sdk, data);
382632
+ default:
382633
+ throw new Error(`Price feed type ${contractType} not supported, `);
382634
+ }
382635
+ }
382636
+ };
382637
+ function rawTxToMulticallPriceUpdate(tx) {
382638
+ const { to, callData } = tx;
382639
+ const { args, functionName } = decodeFunctionData({
382640
+ abi: iUpdatablePriceFeedAbi,
382641
+ data: callData
382642
+ });
382643
+ return {
382644
+ abi: iUpdatablePriceFeedAbi,
382645
+ address: to,
382646
+ functionName,
382647
+ args
382648
+ };
382649
+ }
382650
+ var PriceOracleBaseContract = class extends BaseContract {
382651
+ /**
382652
+ * Underlying token of market to which this price oracle belongs
382653
+ */
382654
+ underlying;
382655
+ /**
382656
+ * Mapping Token => [PriceFeed Address, stalenessPeriod]
382657
+ */
382658
+ mainPriceFeeds = new AddressMap();
382659
+ /**
382660
+ * Mapping Token => [PriceFeed Address, stalenessPeriod]
382661
+ */
382662
+ reservePriceFeeds = new AddressMap();
382663
+ /**
382664
+ * Mapping Token => Price in underlying
382665
+ */
382666
+ mainPrices = new AddressMap();
382667
+ /**
382668
+ * Mapping Token => Price in underlying
382669
+ */
382670
+ reservePrices = new AddressMap();
382671
+ #priceFeedTree = [];
382672
+ constructor(sdk, args, data, underlying) {
382673
+ super(sdk, args);
382674
+ this.underlying = underlying;
382675
+ const { priceFeedMapping, priceFeedStructure } = data;
382676
+ this.#loadState(priceFeedMapping, priceFeedStructure);
382677
+ }
382678
+ /**
382679
+ * Returns main and reserve price feeds for given tokens
382680
+ * @param tokens
382681
+ * @param opts Option to include main/reserve feeds only, defaults to both
382682
+ * @returns
382683
+ */
382684
+ priceFeedsForTokens(tokens, opts) {
382685
+ const main = opts?.main ?? true;
382686
+ const reserve = opts?.reserve ?? true;
382687
+ return tokens.flatMap((t) => [
382688
+ main ? this.mainPriceFeeds.get(t)?.priceFeed : void 0,
382689
+ reserve ? this.reservePriceFeeds.get(t)?.priceFeed : void 0
382690
+ ]).filter((f) => !!f);
382691
+ }
382692
+ /**
382693
+ * Generates updates for all updateable price feeds in this oracle (including dependencies)
382694
+ * @returns
382695
+ */
382696
+ async updatePriceFeeds() {
382697
+ const updatables = [];
382698
+ for (const node of this.#priceFeedTree) {
382699
+ if (node.updatable) {
382700
+ updatables.push(this.sdk.priceFeeds.mustGet(node.baseParams.addr));
383001
382701
  }
383002
- ]
383003
- },
383004
- CONVEX_GHO_CRVUSD_POOL: {
383005
- name: "Convex GHOcrvUSD",
383006
- protocol: 4,
383007
- type: 10,
383008
- stakedToken: "stkcvxGHOcrvUSD",
383009
- extraRewards: [
383010
- {
383011
- rewardToken: "CVX",
383012
- poolAddress: {
383013
- Mainnet: "0xE7cC925739E41E2A03A53770F5E9Ed43afe13993",
383014
- Arbitrum: NOT_DEPLOYED,
383015
- Optimism: NOT_DEPLOYED,
383016
- Base: NOT_DEPLOYED
382702
+ }
382703
+ return this.sdk.priceFeeds.generatePriceFeedsUpdateTxs(updatables);
382704
+ }
382705
+ /**
382706
+ * Converts previously obtained price updates into CreditFacade multicall entries
382707
+ * @param creditFacade
382708
+ * @param updates
382709
+ * @returns
382710
+ */
382711
+ onDemandPriceUpdates(updates) {
382712
+ const result = [];
382713
+ if (!updates) {
382714
+ this.logger?.debug("empty updates list");
382715
+ return result;
382716
+ }
382717
+ const { txs } = updates;
382718
+ for (const tx of txs) {
382719
+ const { to: priceFeed, callData, description } = tx;
382720
+ const [token, reserve] = this.findTokenForPriceFeed(priceFeed);
382721
+ if (!token) {
382722
+ this.logger?.debug(
382723
+ `skipping onDemandPriceUpdate ${description}): token not found for price feed ${priceFeed} in oracle ${this.address}`
382724
+ );
382725
+ continue;
382726
+ }
382727
+ const { args } = decodeFunctionData({
382728
+ abi: iUpdatablePriceFeedAbi,
382729
+ data: callData
382730
+ });
382731
+ const data = args[0];
382732
+ result.push({
382733
+ priceFeed,
382734
+ token,
382735
+ reserve,
382736
+ data
382737
+ });
382738
+ }
382739
+ this.logger?.debug(
382740
+ `got ${result.length} onDemandPriceUpdates from ${txs.length} txs`
382741
+ );
382742
+ return result;
382743
+ }
382744
+ /**
382745
+ * Tries to convert amount of token into underlying of current market
382746
+ * @param token
382747
+ * @param amount
382748
+ * @param reserve
382749
+ * @returns
382750
+ */
382751
+ convertToUnderlying(token, amount, reserve = false) {
382752
+ return this.convert(token, this.underlying, amount, reserve);
382753
+ }
382754
+ /**
382755
+ * Tries to convert amount of from one token to another, using latest known prices
382756
+ * @param from
382757
+ * @param to
382758
+ * @param amount
382759
+ * @param reserve
382760
+ */
382761
+ convert(from, to, amount, reserve = false) {
382762
+ if (from === to) {
382763
+ return amount;
382764
+ }
382765
+ const fromPrice = reserve ? this.reservePrices.mustGet(from) : this.mainPrices.mustGet(from);
382766
+ const fromScale = 10n ** BigInt(this.sdk.tokensMeta.decimals(from));
382767
+ const toPrice = reserve ? this.reservePrices.mustGet(to) : this.mainPrices.mustGet(to);
382768
+ const toScale = 10n ** BigInt(this.sdk.tokensMeta.decimals(to));
382769
+ return amount * fromPrice * toScale / (toPrice * fromScale);
382770
+ }
382771
+ /**
382772
+ * Tries to convert amount of token to USD, using latest known prices
382773
+ * @param from
382774
+ * @param to
382775
+ * @param amount
382776
+ * @param reserve
382777
+ */
382778
+ convertToUSD(from, amount, reserve = false) {
382779
+ const price = reserve ? this.reservePrices.mustGet(from) : this.mainPrices.mustGet(from);
382780
+ const scale = 10n ** BigInt(this.sdk.tokensMeta.decimals(from));
382781
+ return amount * price / scale;
382782
+ }
382783
+ /**
382784
+ * Loads new prices for this oracle from PriceFeedCompressor
382785
+ * Does not update price feeds, only updates prices
382786
+ */
382787
+ async updatePrices() {
382788
+ await this.sdk.marketRegister.updatePrices([this.address]);
382789
+ }
382790
+ syncStateMulticall() {
382791
+ const args = [this.address];
382792
+ if (this.version === 300) {
382793
+ args.push(
382794
+ Array.from(
382795
+ /* @__PURE__ */ new Set([
382796
+ this.underlying,
382797
+ ...this.mainPriceFeeds.keys(),
382798
+ ...this.reservePriceFeeds.keys()
382799
+ ])
382800
+ )
382801
+ );
382802
+ }
382803
+ return {
382804
+ call: {
382805
+ abi: iPriceFeedCompressorAbi,
382806
+ address: this.sdk.addressProvider.getLatestVersion(
382807
+ AP_PRICE_FEED_COMPRESSOR
382808
+ ),
382809
+ functionName: "getPriceFeeds",
382810
+ args
382811
+ },
382812
+ onResult: ([entries, tree]) => {
382813
+ this.#loadState(entries, tree);
382814
+ }
382815
+ };
382816
+ }
382817
+ #loadState(entries, tree) {
382818
+ this.#priceFeedTree = tree;
382819
+ this.mainPriceFeeds.clear();
382820
+ this.reservePriceFeeds.clear();
382821
+ this.mainPrices.clear();
382822
+ this.reservePrices.clear();
382823
+ for (const node of tree) {
382824
+ this.sdk.priceFeeds.getOrCreate(node);
382825
+ }
382826
+ entries.forEach((node) => {
382827
+ const { token, priceFeed, reserve, stalenessPeriod } = node;
382828
+ const ref = new PriceFeedRef(this.sdk, priceFeed, stalenessPeriod);
382829
+ const price = this.#priceFeedTree.find(
382830
+ (n) => n.baseParams.addr === priceFeed
382831
+ )?.answer?.price;
382832
+ if (reserve) {
382833
+ this.reservePriceFeeds.upsert(token, ref);
382834
+ if (price) {
382835
+ this.reservePrices.upsert(token, price);
382836
+ }
382837
+ } else {
382838
+ this.mainPriceFeeds.upsert(token, ref);
382839
+ if (price) {
382840
+ this.mainPrices.upsert(token, price);
383017
382841
  }
383018
382842
  }
383019
- ]
383020
- },
383021
- CONVEX_LLAMA_THENA_POOL: {
383022
- name: "Convex todo",
383023
- protocol: 4,
383024
- type: 10,
383025
- stakedToken: "stkcvxllamathena",
383026
- extraRewards: [
383027
- {
383028
- rewardToken: "CVX",
383029
- poolAddress: {
383030
- Mainnet: "0xc66844E5788b7d7D6DFFa5EC1Db62d898c59D6e7",
383031
- Arbitrum: NOT_DEPLOYED,
383032
- Optimism: NOT_DEPLOYED,
383033
- Base: NOT_DEPLOYED
383034
- }
382843
+ this.#labelPriceFeed(priceFeed, reserve ? "Reserve" : "Main", token);
382844
+ });
382845
+ this.logger?.debug(
382846
+ `Got ${this.mainPriceFeeds.size} main and ${this.reservePriceFeeds.size} reserve price feeds`
382847
+ );
382848
+ }
382849
+ #labelPriceFeed(address, usage, token) {
382850
+ this.sdk.provider.addressLabels.set(address, (label) => {
382851
+ const symbol = this.sdk.tokensMeta.symbol(token);
382852
+ let pricefeedTag = `${symbol}.${usage}`;
382853
+ if (label) {
382854
+ pricefeedTag = `${label}, ${pricefeedTag}`;
383035
382855
  }
383036
- ]
383037
- },
383038
- CONVEX_BOOSTER_ARB: {
383039
- name: "Convex Booster (Arbitrum)",
383040
- protocol: 4,
383041
- type: 25
383042
- /* CONVEX_L2_BOOSTER */
383043
- },
383044
- CONVEX_CRVUSD_USDT_POOL_ARB: {
383045
- name: "Convex crvUSDT Pool",
383046
- protocol: 4,
383047
- type: 26,
383048
- rewards: ["CRV", "CVX", "crvUSD", "ARB"],
383049
- extraRewards: []
383050
- },
383051
- AURA_BOOSTER: {
383052
- name: "Aura BOOSTER",
383053
- protocol: 11,
383054
- type: 11
383055
- /* CONVEX_V1_BOOSTER */
383056
- },
383057
- AURA_B_RETH_STABLE_POOL: {
383058
- name: "Balancer rETH Stable Pool Aura Deposit",
383059
- protocol: 11,
383060
- type: 10,
383061
- stakedToken: "auraB_rETH_STABLE_vault",
383062
- extraRewards: [
383063
- {
383064
- rewardToken: "AURA",
383065
- poolAddress: {
383066
- Mainnet: "0xf66a72886749c96b18526E8E124cC2e18b7c72D2",
383067
- Arbitrum: NOT_DEPLOYED,
383068
- Optimism: NOT_DEPLOYED,
383069
- Base: NOT_DEPLOYED
383070
- }
382856
+ return pricefeedTag;
382857
+ });
382858
+ }
382859
+ /**
382860
+ * Helper method to find "attachment point" of price feed (makes sense for updatable price feeds only) -
382861
+ * returns token (in v3.0 can be ticker) and main/reserve flag
382862
+ *
382863
+ * @param priceFeed
382864
+ * @returns
382865
+ */
382866
+ findTokenForPriceFeed(priceFeed) {
382867
+ for (const [token, pf] of this.mainPriceFeeds.entries()) {
382868
+ if (pf.address === priceFeed) {
382869
+ return [token, false];
383071
382870
  }
383072
- ]
383073
- },
383074
- AURA_WEETH_RETH_POOL: {
383075
- name: "Balancer weETH-rETH Stable Pool Aura Deposit",
383076
- protocol: 11,
383077
- type: 10,
383078
- stakedToken: "auraweETH_rETH_vault",
383079
- extraRewards: [
383080
- {
383081
- rewardToken: "AURA",
383082
- poolAddress: {
383083
- Mainnet: "0x25d22C5191C67D63AAB70a37FAe06e1c1E1a830F",
383084
- Arbitrum: NOT_DEPLOYED,
383085
- Optimism: NOT_DEPLOYED,
383086
- Base: NOT_DEPLOYED
383087
- }
382871
+ }
382872
+ for (const [token, pf] of this.reservePriceFeeds.entries()) {
382873
+ if (pf.address === priceFeed) {
382874
+ return [token, true];
383088
382875
  }
383089
- ]
383090
- },
383091
- AURA_OSETH_WETH_POOL: {
383092
- name: "Balancer osETH-WETH Stable Pool Aura Deposit",
383093
- protocol: 11,
383094
- type: 10,
383095
- stakedToken: "auraosETH_wETH_BPT_vault",
383096
- extraRewards: [
382876
+ }
382877
+ return [void 0, false];
382878
+ }
382879
+ stateHuman(raw = true) {
382880
+ return {
382881
+ ...super.stateHuman(raw),
382882
+ mainPriceFeeds: Object.fromEntries(
382883
+ this.mainPriceFeeds.entries().map(([token, v]) => [
382884
+ this.labelAddress(token),
382885
+ v.stateHuman(raw)
382886
+ ])
382887
+ ),
382888
+ reservePriceFeeds: Object.fromEntries(
382889
+ this.reservePriceFeeds.entries().map(([token, v]) => [
382890
+ this.labelAddress(token),
382891
+ v.stateHuman(raw)
382892
+ ])
382893
+ )
382894
+ };
382895
+ }
382896
+ get priceFeedTree() {
382897
+ return this.#priceFeedTree;
382898
+ }
382899
+ };
382900
+ var PriceOracleV300Contract = class extends PriceOracleBaseContract {
382901
+ constructor(sdk, data, underlying) {
382902
+ super(
382903
+ sdk,
383097
382904
  {
383098
- rewardToken: "AURA",
383099
- poolAddress: {
383100
- Mainnet: "0x62e6D8dAe7089C8F2f2a5C328c710aa1788742fb",
383101
- Arbitrum: NOT_DEPLOYED,
383102
- Optimism: NOT_DEPLOYED,
383103
- Base: NOT_DEPLOYED
383104
- }
382905
+ ...data.baseParams,
382906
+ name: "PriceOracleV3",
382907
+ abi: priceOracleV3Abi
383105
382908
  },
382909
+ data,
382910
+ underlying
382911
+ );
382912
+ }
382913
+ processLog(log2) {
382914
+ switch (log2.eventName) {
382915
+ case "Paused":
382916
+ case "Unpaused":
382917
+ break;
382918
+ case "NewController":
382919
+ case "SetPriceFeed":
382920
+ case "SetReservePriceFeed":
382921
+ case "SetReservePriceFeedStatus":
382922
+ this.dirty = true;
382923
+ break;
382924
+ }
382925
+ }
382926
+ findTokenForPriceFeed(priceFeed) {
382927
+ const [token, reserve] = super.findTokenForPriceFeed(priceFeed);
382928
+ if (token) {
382929
+ return [token, reserve];
382930
+ }
382931
+ const tickers = Object.values(
382932
+ tickerInfoTokensByNetwork[this.sdk.provider.networkType]
382933
+ ).flat();
382934
+ const ticker = tickers.find(
382935
+ (t) => t.priceFeed.toLowerCase() === priceFeed.toLowerCase()
382936
+ );
382937
+ if (ticker) {
382938
+ this.logger?.debug(
382939
+ `will use ticker ${ticker.symbol} (${ticker.address}) for price feed ${priceFeed}`
382940
+ );
382941
+ return [ticker.address, false];
382942
+ }
382943
+ return [void 0, false];
382944
+ }
382945
+ };
382946
+ var PriceOracleV310Contract = class extends PriceOracleBaseContract {
382947
+ constructor(sdk, data, underlying) {
382948
+ super(
382949
+ sdk,
383106
382950
  {
383107
- rewardToken: "SWISE",
383108
- poolAddress: {
383109
- Mainnet: "0xC5E75ccd4d40e2Fb280f008f8AFB5EF3415EFA72",
383110
- Arbitrum: NOT_DEPLOYED,
383111
- Optimism: NOT_DEPLOYED,
383112
- Base: NOT_DEPLOYED
383113
- }
383114
- }
383115
- ]
383116
- },
383117
- AURA_BPT_RETH_ETH_POOL: {
383118
- name: "BeethovenX rETH-ETH Pool Aura Deposit",
383119
- protocol: 11,
383120
- type: 10,
383121
- stakedToken: "auraBPT_rETH_ETH_vault",
383122
- extraRewards: [
383123
- {
383124
- rewardToken: "OP",
383125
- poolAddress: {
383126
- Mainnet: NOT_DEPLOYED,
383127
- Arbitrum: NOT_DEPLOYED,
383128
- Optimism: "0x0A22Ae9D9D149C14f6c15A235e715bB6C1Cfa739",
383129
- Base: NOT_DEPLOYED
383130
- }
382951
+ ...data.baseParams,
382952
+ name: "PriceOracleV3",
382953
+ abi: iPriceOracleV310Abi
383131
382954
  },
383132
- {
383133
- rewardToken: "AURA",
383134
- poolAddress: {
383135
- Mainnet: NOT_DEPLOYED,
383136
- Arbitrum: NOT_DEPLOYED,
383137
- Optimism: "0x81673Cdd00c2839440f31575cCFa5B6ca4a87B2B",
383138
- Base: NOT_DEPLOYED
383139
- }
382955
+ data,
382956
+ underlying
382957
+ );
382958
+ }
382959
+ processLog(log2) {
382960
+ switch (log2.eventName) {
382961
+ case "AddUpdatablePriceFeed":
382962
+ case "NewController":
382963
+ case "SetPriceFeed":
382964
+ case "SetReservePriceFeed":
382965
+ this.dirty = true;
382966
+ break;
382967
+ }
382968
+ }
382969
+ };
382970
+ var MarketFactory = class extends SDKConstruct {
382971
+ acl;
382972
+ configurator;
382973
+ poolFactory;
382974
+ priceOracle;
382975
+ creditManagers = [];
382976
+ /**
382977
+ * Original data received from compressor
382978
+ */
382979
+ state;
382980
+ zappers;
382981
+ constructor(sdk, marketData) {
382982
+ super(sdk);
382983
+ this.state = marketData;
382984
+ let configurator = sdk.contracts.get(
382985
+ marketData.configurator
382986
+ );
382987
+ if (!configurator) {
382988
+ configurator = new MarketConfiguratorContract(
382989
+ sdk,
382990
+ marketData.configurator
382991
+ );
382992
+ }
382993
+ this.configurator = configurator;
382994
+ this.acl = marketData.acl;
382995
+ const allTokens = [
382996
+ ...marketData.tokens,
382997
+ ...marketData.zappers.flatMap((z2) => [z2.tokenIn, z2.tokenOut])
382998
+ ];
382999
+ for (const t of allTokens) {
383000
+ sdk.tokensMeta.upsert(t.addr, t);
383001
+ sdk.provider.addressLabels.set(t.addr, t.symbol);
383002
+ }
383003
+ this.poolFactory = new PoolFactory(sdk, marketData);
383004
+ this.zappers = marketData.zappers;
383005
+ for (let i = 0; i < marketData.creditManagers.length; i++) {
383006
+ this.creditManagers.push(new CreditFactory(sdk, marketData, i));
383007
+ }
383008
+ if (marketData.priceOracleData.baseParams.version < 310) {
383009
+ this.priceOracle = new PriceOracleV300Contract(
383010
+ sdk,
383011
+ marketData.priceOracleData,
383012
+ marketData.pool.underlying
383013
+ );
383014
+ } else {
383015
+ this.priceOracle = new PriceOracleV310Contract(
383016
+ sdk,
383017
+ marketData.priceOracleData,
383018
+ marketData.pool.underlying
383019
+ );
383020
+ }
383021
+ }
383022
+ get dirty() {
383023
+ return this.configurator.dirty || this.poolFactory.dirty || this.priceOracle.dirty || this.creditManagers.some((cm) => cm.dirty);
383024
+ }
383025
+ stateHuman(raw = true) {
383026
+ return {
383027
+ pool: this.poolFactory.stateHuman(raw),
383028
+ creditManagers: this.creditManagers.map((cm) => cm.stateHuman(raw)),
383029
+ priceOracle: this.priceOracle.stateHuman(raw),
383030
+ pausableAdmins: this.state.pausableAdmins.map((a) => this.labelAddress(a)),
383031
+ unpausableAdmins: this.state.unpausableAdmins.map(
383032
+ (a) => this.labelAddress(a)
383033
+ ),
383034
+ emergencyLiquidators: this.state.emergencyLiquidators.map(
383035
+ (a) => this.labelAddress(a)
383036
+ ),
383037
+ zappers: this.zappers.map((z2) => ({
383038
+ address: z2.baseParams.addr,
383039
+ contractType: z2.baseParams.contractType,
383040
+ version: Number(z2.baseParams.version),
383041
+ tokenIn: this.labelAddress(z2.tokenIn.addr),
383042
+ tokenOut: this.labelAddress(z2.tokenOut.addr)
383043
+ }))
383044
+ };
383045
+ }
383046
+ };
383047
+ var SUPPORTED_CHAINS = [
383048
+ "Mainnet",
383049
+ "Arbitrum",
383050
+ "Optimism",
383051
+ "Base"
383052
+ ];
383053
+ var chains = {
383054
+ Mainnet: mainnet,
383055
+ Arbitrum: arbitrum,
383056
+ Optimism: optimism,
383057
+ Base: base
383058
+ };
383059
+ var CHAINS_BY_ID = {
383060
+ [mainnet.id]: "Mainnet",
383061
+ [arbitrum.id]: "Arbitrum",
383062
+ [optimism.id]: "Optimism"
383063
+ // [base.id]: "Base",
383064
+ };
383065
+ async function detectChain(transportOrRPC) {
383066
+ const transport = typeof transportOrRPC === "string" ? http(transportOrRPC) : transportOrRPC;
383067
+ const tempClient = createPublicClient({ transport });
383068
+ const [networkType, chainId] = await Promise.all([
383069
+ detectNetwork(tempClient),
383070
+ tempClient.getChainId()
383071
+ ]);
383072
+ return defineChain({
383073
+ ...chains[networkType],
383074
+ id: chainId
383075
+ });
383076
+ }
383077
+ function createTransport2(opts) {
383078
+ const { timeout = 12e4, retryCount } = opts;
383079
+ if ("transport" in opts) {
383080
+ return opts.transport;
383081
+ }
383082
+ const rpcs = opts.rpcURLs.map((url) => http(url, { timeout, retryCount }));
383083
+ return rpcs.length ? fallback(rpcs) : rpcs[0];
383084
+ }
383085
+ var Provider = class {
383086
+ chainId;
383087
+ chain;
383088
+ networkType;
383089
+ addressLabels;
383090
+ #transport;
383091
+ #publicClient;
383092
+ constructor(opts) {
383093
+ const { chainId, networkType } = opts;
383094
+ this.chainId = chainId;
383095
+ this.networkType = networkType;
383096
+ this.chain = defineChain({
383097
+ ...chains[networkType],
383098
+ id: chainId
383099
+ });
383100
+ this.#transport = createTransport2(opts);
383101
+ this.#publicClient = createPublicClient({
383102
+ chain: this.chain,
383103
+ transport: this.#transport
383104
+ });
383105
+ this.addressLabels = new AddressLabeller();
383106
+ }
383107
+ get transport() {
383108
+ return this.#transport;
383109
+ }
383110
+ set transport(transport) {
383111
+ this.#transport = transport;
383112
+ this.#publicClient = createPublicClient({
383113
+ chain: this.chain,
383114
+ transport: this.#transport
383115
+ });
383116
+ }
383117
+ get publicClient() {
383118
+ return this.#publicClient;
383119
+ }
383120
+ };
383121
+ async function detectNetwork(client) {
383122
+ for (const chain of SUPPORTED_CHAINS) {
383123
+ try {
383124
+ await client.readContract({
383125
+ abi: ierc20MetadataAbi,
383126
+ address: USDC[chain],
383127
+ functionName: "symbol"
383128
+ });
383129
+ return chain;
383130
+ } catch {
383131
+ }
383132
+ }
383133
+ throw new Error("Unsupported network");
383134
+ }
383135
+ async function sendRawTx(client, params) {
383136
+ const { account, tx } = params;
383137
+ return getAction(
383138
+ client,
383139
+ sendTransaction,
383140
+ "sendTransaction"
383141
+ )({
383142
+ // @ts-expect-error
383143
+ account,
383144
+ data: tx.callData,
383145
+ to: tx.to,
383146
+ value: BigInt(tx.value)
383147
+ });
383148
+ }
383149
+ async function simulateMulticall(client, parameters) {
383150
+ const {
383151
+ account,
383152
+ allowFailure = true,
383153
+ batchSize: batchSize_,
383154
+ blockNumber,
383155
+ blockTag,
383156
+ gas,
383157
+ multicallAddress: multicallAddress_,
383158
+ stateOverride
383159
+ } = parameters;
383160
+ const contracts2 = parameters.contracts;
383161
+ const batchSize = batchSize_ ?? (typeof client.batch?.multicall === "object" && client.batch.multicall.batchSize || 1024);
383162
+ let multicallAddress = multicallAddress_;
383163
+ if (!multicallAddress) {
383164
+ if (!client.chain)
383165
+ throw new Error(
383166
+ "client chain not configured. multicallAddress is required."
383167
+ );
383168
+ multicallAddress = getChainContractAddress({
383169
+ blockNumber,
383170
+ chain: client.chain,
383171
+ contract: "multicall3"
383172
+ });
383173
+ }
383174
+ const chunkedCalls = [[]];
383175
+ let currentChunk = 0;
383176
+ let currentChunkSize = 0;
383177
+ for (const contract of contracts2) {
383178
+ const { abi: abi32, address, args, functionName } = contract;
383179
+ try {
383180
+ const callData = encodeFunctionData({ abi: abi32, args, functionName });
383181
+ currentChunkSize += (callData.length - 2) / 2;
383182
+ if (
383183
+ // Check if batching is enabled.
383184
+ batchSize > 0 && // Check if the current size of the batch exceeds the size limit.
383185
+ currentChunkSize > batchSize && // Check if the current chunk is not already empty.
383186
+ chunkedCalls[currentChunk].length > 0
383187
+ ) {
383188
+ currentChunk++;
383189
+ currentChunkSize = (callData.length - 2) / 2;
383190
+ chunkedCalls[currentChunk] = [];
383140
383191
  }
383141
- ]
383142
- },
383143
- AURA_BPT_WSTETH_ETH_POOL: {
383144
- name: "BeethovenX wstETH-ETH Pool Aura Deposit",
383145
- protocol: 11,
383146
- type: 10,
383147
- stakedToken: "auraBPT_WSTETH_ETH_vault",
383148
- extraRewards: [
383149
- {
383150
- rewardToken: "OP",
383151
- poolAddress: {
383152
- Mainnet: NOT_DEPLOYED,
383153
- Arbitrum: NOT_DEPLOYED,
383154
- Optimism: "0x903d716fe68e7e091eCC43AA93c0F8cfD7e7BC0a",
383155
- Base: NOT_DEPLOYED
383192
+ chunkedCalls[currentChunk] = [
383193
+ ...chunkedCalls[currentChunk],
383194
+ {
383195
+ allowFailure: true,
383196
+ callData,
383197
+ target: address
383156
383198
  }
383157
- },
383158
- {
383159
- rewardToken: "AURA",
383160
- poolAddress: {
383161
- Mainnet: NOT_DEPLOYED,
383162
- Arbitrum: NOT_DEPLOYED,
383163
- Optimism: "0xb0709c230C06BE6e2A84b2Ba877094EB9a4fA014",
383164
- Base: NOT_DEPLOYED
383199
+ ];
383200
+ } catch (err) {
383201
+ const error = getContractError(err, {
383202
+ abi: abi32,
383203
+ address,
383204
+ args,
383205
+ docsPath: "/docs/contract/multicall",
383206
+ functionName
383207
+ });
383208
+ if (!allowFailure) throw error;
383209
+ chunkedCalls[currentChunk] = [
383210
+ ...chunkedCalls[currentChunk],
383211
+ {
383212
+ allowFailure: true,
383213
+ callData: "0x",
383214
+ target: address
383165
383215
  }
383216
+ ];
383217
+ }
383218
+ }
383219
+ const aggregate3Results = await Promise.allSettled(
383220
+ chunkedCalls.map(
383221
+ (calls) => getAction(
383222
+ client,
383223
+ simulateContract,
383224
+ "simulateContract"
383225
+ )({
383226
+ account,
383227
+ abi: multicall3Abi,
383228
+ address: multicallAddress,
383229
+ args: [calls],
383230
+ blockNumber,
383231
+ blockTag,
383232
+ // does not infer well that either blockNumber or blockTag must be present
383233
+ functionName: "aggregate3",
383234
+ stateOverride,
383235
+ gas
383236
+ })
383237
+ )
383238
+ );
383239
+ const results = [];
383240
+ for (let i = 0; i < aggregate3Results.length; i++) {
383241
+ const result = aggregate3Results[i];
383242
+ if (result.status === "rejected") {
383243
+ if (!allowFailure) {
383244
+ throw result.reason;
383166
383245
  }
383167
- ]
383168
- },
383169
- AURA_WSTETH_WETH_POOL_ARB: {
383170
- name: "Balancer (Arbitrum) wstETH-WETH Aura Vault",
383171
- protocol: 11,
383172
- type: 10,
383173
- stakedToken: "aurawstETH_WETH_BPT_vault",
383174
- extraRewards: [
383175
- {
383176
- rewardToken: "AURA",
383177
- poolAddress: {
383178
- Mainnet: NOT_DEPLOYED,
383179
- Arbitrum: "0xC0353d05D3F2b6e14E36c5d3B4bF8d179890A001",
383180
- Optimism: NOT_DEPLOYED,
383181
- Base: NOT_DEPLOYED
383182
- }
383183
- },
383184
- {
383185
- rewardToken: "ARB",
383186
- poolAddress: {
383187
- Mainnet: NOT_DEPLOYED,
383188
- Arbitrum: "0x3a0beff39E243453960aD1198Fc3aAabdBDDe56C",
383189
- Optimism: NOT_DEPLOYED,
383190
- Base: NOT_DEPLOYED
383191
- }
383246
+ for (const _i of chunkedCalls[i]) {
383247
+ results.push({
383248
+ status: "failure",
383249
+ error: result.reason,
383250
+ result: void 0
383251
+ });
383192
383252
  }
383193
- ]
383194
- },
383195
- AURA_WSTETH_RETH_SFRXETH_POOL_ARB: {
383196
- name: "Balancer (Arbitrum) wstETH-rETH-sfrxETH Aura Vault",
383197
- protocol: 11,
383198
- type: 10,
383199
- stakedToken: "aurawstETH_rETH_sfrxETH_vault",
383200
- extraRewards: [
383201
- {
383202
- rewardToken: "AURA",
383203
- poolAddress: {
383204
- Mainnet: NOT_DEPLOYED,
383205
- Arbitrum: "0x5901ce1c3Bf6C97fC49ED0fF08A88a57ea6E4Ca4",
383206
- Optimism: NOT_DEPLOYED,
383207
- Base: NOT_DEPLOYED
383208
- }
383209
- },
383210
- {
383211
- rewardToken: "ARB",
383212
- poolAddress: {
383213
- Mainnet: NOT_DEPLOYED,
383214
- Arbitrum: "0x4601Ec46A285714e6F2A9466DA7f2BcB33646391",
383215
- Optimism: NOT_DEPLOYED,
383216
- Base: NOT_DEPLOYED
383217
- }
383253
+ continue;
383254
+ }
383255
+ const aggregate3Result = result.value.result;
383256
+ for (let j = 0; j < aggregate3Result.length; j++) {
383257
+ const { returnData, success } = aggregate3Result[j];
383258
+ const { callData } = chunkedCalls[i][j];
383259
+ const { abi: abi32, address, functionName, args } = contracts2[results.length];
383260
+ try {
383261
+ if (callData === "0x") throw new AbiDecodingZeroDataError();
383262
+ if (!success) throw new RawContractError({ data: returnData });
383263
+ const result2 = decodeFunctionResult({
383264
+ abi: abi32,
383265
+ args,
383266
+ data: returnData,
383267
+ functionName
383268
+ });
383269
+ results.push(allowFailure ? { result: result2, status: "success" } : result2);
383270
+ } catch (err) {
383271
+ const error = getContractError(err, {
383272
+ abi: abi32,
383273
+ address,
383274
+ args,
383275
+ docsPath: "/docs/contract/multicall",
383276
+ functionName
383277
+ });
383278
+ if (!allowFailure) throw error;
383279
+ results.push({ error, result: void 0, status: "failure" });
383218
383280
  }
383219
- ]
383220
- },
383221
- AURA_CBETH_RETH_WSTETH_POOL_ARB: {
383222
- name: "Balancer (Arbitrum) wstETH-rETH-cbETH Aura Vault",
383223
- protocol: 11,
383224
- type: 10,
383225
- stakedToken: "auracbETH_rETH_wstETH_vault",
383226
- extraRewards: [
383227
- {
383228
- rewardToken: "ARB",
383229
- poolAddress: {
383230
- Mainnet: NOT_DEPLOYED,
383231
- Arbitrum: "0xf0dcb30811228bED2b87b2753fabAfe80A9D0fb9",
383232
- Optimism: NOT_DEPLOYED,
383233
- Base: NOT_DEPLOYED
383281
+ }
383282
+ }
383283
+ if (results.length !== contracts2.length)
383284
+ throw new BaseError2("multicall results mismatch");
383285
+ return results;
383286
+ }
383287
+ var MarketRegister = class extends SDKConstruct {
383288
+ #logger;
383289
+ /**
383290
+ * Mapping pool.address -> MarketFactory
383291
+ */
383292
+ #markets = new AddressMap();
383293
+ constructor(sdk, markets) {
383294
+ super(sdk);
383295
+ this.#logger = childLogger("MarketRegister", sdk.logger);
383296
+ for (const data of markets ?? []) {
383297
+ this.#markets.upsert(
383298
+ data.pool.baseParams.addr,
383299
+ new MarketFactory(this.sdk, data)
383300
+ );
383301
+ }
383302
+ }
383303
+ async loadMarkets(marketConfigurators, ignoreUpdateablePrices) {
383304
+ if (!marketConfigurators.length) {
383305
+ this.#logger?.warn(
383306
+ "no market configurators provided, skipping loadMarkets"
383307
+ );
383308
+ return;
383309
+ }
383310
+ await this.#loadMarkets(marketConfigurators, [], ignoreUpdateablePrices);
383311
+ }
383312
+ async syncState() {
383313
+ const pools = this.markets.filter((m) => m.dirty).map((m) => m.poolFactory.pool.address);
383314
+ if (pools.length) {
383315
+ this.#logger?.debug(`need to reload ${pools.length} markets`);
383316
+ await this.#loadMarkets([], pools);
383317
+ }
383318
+ }
383319
+ async #loadMarkets(configurators, pools, ignoreUpdateablePrices) {
383320
+ const marketCompressorAddress = this.sdk.addressProvider.getAddress(
383321
+ AP_MARKET_COMPRESSOR,
383322
+ 310
383323
+ );
383324
+ let txs = [];
383325
+ if (!ignoreUpdateablePrices) {
383326
+ await this.sdk.priceFeeds.preloadUpdatablePriceFeeds(
383327
+ configurators,
383328
+ pools
383329
+ );
383330
+ const updates = await this.sdk.priceFeeds.generatePriceFeedsUpdateTxs();
383331
+ txs = updates.txs;
383332
+ }
383333
+ this.#logger?.debug({ configurators, pools }, "calling getMarkets");
383334
+ const resp = await simulateMulticall(this.provider.publicClient, {
383335
+ contracts: [
383336
+ ...txs.map(rawTxToMulticallPriceUpdate),
383337
+ {
383338
+ abi: iMarketCompressorAbi,
383339
+ address: marketCompressorAddress,
383340
+ functionName: "getMarkets",
383341
+ args: [
383342
+ {
383343
+ configurators,
383344
+ pools,
383345
+ underlying: ADDRESS_0X0
383346
+ }
383347
+ ]
383234
383348
  }
383235
- },
383236
- {
383237
- rewardToken: "AURA",
383238
- poolAddress: {
383239
- Mainnet: NOT_DEPLOYED,
383240
- Arbitrum: "0xE42D389058D820177b83E2863FEb13733d6Dd5f2",
383241
- Optimism: NOT_DEPLOYED,
383242
- Base: NOT_DEPLOYED
383349
+ ],
383350
+ allowFailure: false,
383351
+ gas: 550000000n,
383352
+ batchSize: 0
383353
+ // we cannot have price updates and compressor request in different batches
383354
+ });
383355
+ const markets = resp.pop();
383356
+ for (const data of markets) {
383357
+ this.#markets.upsert(
383358
+ data.pool.baseParams.addr,
383359
+ new MarketFactory(this.sdk, data)
383360
+ );
383361
+ }
383362
+ this.#logger?.info(`loaded ${markets.length} markets`);
383363
+ }
383364
+ /**
383365
+ * Loads new prices and price feeds for given oracles from PriceFeedCompressor, defaults to all oracles
383366
+ * Supports v300 and v310 oracles
383367
+ */
383368
+ async updatePrices(oracles) {
383369
+ const multicalls = this.markets.map((m) => m.priceOracle).filter((o) => !oracles || oracles.includes(o.address)).map((o) => o.syncStateMulticall());
383370
+ if (!multicalls.length) {
383371
+ return;
383372
+ }
383373
+ const { txs } = await this.sdk.priceFeeds.generatePriceFeedsUpdateTxs();
383374
+ const resp = await simulateMulticall(this.provider.publicClient, {
383375
+ contracts: [
383376
+ ...txs.map(rawTxToMulticallPriceUpdate),
383377
+ ...multicalls.map((mc) => mc.call)
383378
+ ],
383379
+ allowFailure: false,
383380
+ gas: 550000000n,
383381
+ batchSize: 0
383382
+ // we cannot have price updates and compressor request in different batches
383383
+ });
383384
+ const oraclesStates = resp.slice(txs.length);
383385
+ for (let i = 0; i < multicalls.length; i++) {
383386
+ const handler = multicalls[i].onResult;
383387
+ const result = oraclesStates[i];
383388
+ handler(result);
383389
+ }
383390
+ }
383391
+ get state() {
383392
+ return this.markets.map((market) => market.state);
383393
+ }
383394
+ stateHuman(raw = true) {
383395
+ return this.markets.map((market) => market.stateHuman(raw));
383396
+ }
383397
+ get pools() {
383398
+ return this.markets.map((market) => market.poolFactory);
383399
+ }
383400
+ get creditManagers() {
383401
+ return this.markets.flatMap((market) => market.creditManagers);
383402
+ }
383403
+ get marketConfigurators() {
383404
+ const result = /* @__PURE__ */ new Set();
383405
+ for (const m of this.markets) {
383406
+ result.add(m.configurator);
383407
+ }
383408
+ return Array.from(result);
383409
+ }
383410
+ findCreditManager(creditManager) {
383411
+ const addr = creditManager.toLowerCase();
383412
+ for (const market of this.markets) {
383413
+ for (const cm of market.creditManagers) {
383414
+ if (cm.creditManager.address.toLowerCase() === addr) {
383415
+ return cm;
383243
383416
  }
383244
383417
  }
383245
- ]
383246
- },
383247
- AURA_RETH_WETH_POOL_ARB: {
383248
- name: "Balancer (Arbitrum) rETH-WETH Aura Vault",
383249
- protocol: 11,
383250
- type: 10,
383251
- stakedToken: "aurarETH_wETH_BPT_vault",
383252
- extraRewards: [
383253
- {
383254
- rewardToken: "AURA",
383255
- poolAddress: {
383256
- Mainnet: NOT_DEPLOYED,
383257
- Arbitrum: "0xeA270927C226454452DDF80e24a02087D0D7089F",
383258
- Optimism: NOT_DEPLOYED,
383259
- Base: NOT_DEPLOYED
383260
- }
383261
- },
383262
- {
383263
- rewardToken: "ARB",
383264
- poolAddress: {
383265
- Mainnet: NOT_DEPLOYED,
383266
- Arbitrum: "0xB05Dc0b460Ca3ed5174b33A7dA2104388764F62D",
383267
- Optimism: NOT_DEPLOYED,
383268
- Base: NOT_DEPLOYED
383269
- }
383418
+ }
383419
+ throw new Error(`cannot find credit manager ${creditManager}`);
383420
+ }
383421
+ findByCreditManager(creditManager) {
383422
+ const addr = creditManager.toLowerCase();
383423
+ const market = this.markets.find(
383424
+ (m) => m.creditManagers.some(
383425
+ (cm) => cm.creditManager.address.toLowerCase() === addr
383426
+ )
383427
+ );
383428
+ if (!market) {
383429
+ throw new Error(`cannot find market for credit manager ${creditManager}`);
383430
+ }
383431
+ return market;
383432
+ }
383433
+ findByPriceOracle(address) {
383434
+ const addr = address.toLowerCase();
383435
+ for (const market of this.markets) {
383436
+ if (market.priceOracle.address.toLowerCase() === addr) {
383437
+ return market;
383270
383438
  }
383271
- ]
383272
- },
383273
- LIDO_STETH_GATEWAY: {
383274
- name: "Lido STETH",
383275
- protocol: 5,
383276
- type: 13,
383277
- oracle: {
383278
- Mainnet: "0x442af784A788A5bd6F42A01Ebe9F287a871243fb",
383279
- Arbitrum: NOT_DEPLOYED,
383280
- // LIDO_ORACLE
383281
- Optimism: NOT_DEPLOYED,
383282
- Base: NOT_DEPLOYED
383283
- },
383284
- lpToken: "steCRV"
383285
- },
383286
- LIDO_WSTETH: {
383287
- name: "Lido wstETH",
383288
- protocol: 5,
383289
- type: 15
383290
- /* LIDO_WSTETH_V1 */
383291
- },
383292
- UNIVERSAL_ADAPTER: {
383293
- name: "Gearbox universal adapter",
383294
- protocol: 6,
383295
- type: 14
383296
- /* UNIVERSAL */
383297
- },
383298
- BALANCER_VAULT: {
383299
- name: "Balancer Vault",
383300
- protocol: 7,
383301
- type: 16,
383302
- queries: {
383303
- Mainnet: "0xE39B5e3B6D74016b2F6A9673D7d7493B6DF549d5",
383304
- Arbitrum: "0xE39B5e3B6D74016b2F6A9673D7d7493B6DF549d5",
383305
- Optimism: "0xE39B5e3B6D74016b2F6A9673D7d7493B6DF549d5",
383306
- Base: NOT_DEPLOYED
383307
383439
  }
383308
- },
383309
- AAVE_V2_LENDING_POOL: {
383310
- name: "Aave V2 Lending Pool",
383311
- protocol: 8,
383312
- type: 17
383313
- /* AAVE_V2_LENDING_POOL */
383314
- },
383315
- AAVE_V2_DAI_TOKEN_WRAPPER: {
383316
- name: "Aave V2 DAI Token Wrapper",
383317
- protocol: 8,
383318
- type: 18,
383319
- underlying: "aDAI"
383320
- },
383321
- AAVE_V2_USDC_TOKEN_WRAPPER: {
383322
- name: "Aave V2 USDC Token Wrapper",
383323
- protocol: 8,
383324
- type: 18,
383325
- underlying: "aUSDC"
383326
- },
383327
- AAVE_V2_USDT_TOKEN_WRAPPER: {
383328
- name: "Aave V2 USDT Token Wrapper",
383329
- protocol: 8,
383330
- type: 18,
383331
- underlying: "aUSDT"
383332
- },
383333
- AAVE_V2_WETH_TOKEN_WRAPPER: {
383334
- name: "Aave V2 WETH Token Wrapper",
383335
- protocol: 8,
383336
- type: 18,
383337
- underlying: "aWETH"
383338
- },
383339
- AAVE_V3_LENDING_POOL: {
383340
- name: "Aave V3 Lending Pool",
383341
- protocol: 18,
383342
- type: 27
383343
- /* AAVE_V3_LENDING_POOL */
383344
- },
383345
- COMPOUND_V2_DAI_POOL: {
383346
- name: "Compound V2 DAI",
383347
- protocol: 9,
383348
- type: 19,
383349
- underlying: "DAI"
383350
- },
383351
- COMPOUND_V2_USDC_POOL: {
383352
- name: "Compound V2 DAI",
383353
- protocol: 9,
383354
- type: 19,
383355
- underlying: "USDT"
383356
- },
383357
- COMPOUND_V2_USDT_POOL: {
383358
- name: "Compound V2 DAI",
383359
- protocol: 9,
383360
- type: 19,
383361
- underlying: "USDT"
383362
- },
383363
- COMPOUND_V2_LINK_POOL: {
383364
- name: "Compound V2 LINK",
383365
- protocol: 9,
383366
- type: 19,
383367
- underlying: "LINK"
383368
- },
383369
- COMPOUND_V2_ETH_GATEWAY: {
383370
- name: "Compound V2 ETH",
383371
- protocol: 9,
383372
- type: 20,
383373
- underlying: "WETH"
383374
- },
383375
- FLUX_USDC_POOL: {
383376
- name: "Flux USDC",
383377
- protocol: 10,
383378
- type: 19,
383379
- underlying: "USDC"
383380
- },
383381
- ZIRCUIT_POOL: {
383382
- name: "Zircuit staking pool",
383383
- protocol: 20,
383384
- type: 28
383385
- /* ZIRCUIT_POOL */
383386
- },
383387
- MELLOW_STEAKHOUSE_VAULT: {
383388
- name: "Mellow Steakhouse steakLRT vault",
383389
- protocol: 21,
383390
- type: 30
383391
- /* MELLOW_LRT_VAULT */
383392
- },
383393
- MELLOW_RE7_LABS_VAULT: {
383394
- name: "Mellow Re7 Labs Re7LRT vault",
383395
- protocol: 21,
383396
- type: 30
383397
- /* MELLOW_LRT_VAULT */
383398
- },
383399
- MELLOW_AMPHOR_VAULT: {
383400
- name: "Mellow Amphor amphrETH vault",
383401
- protocol: 21,
383402
- type: 30
383403
- /* MELLOW_LRT_VAULT */
383404
- },
383405
- MELLOW_RESTAKING_VAULT: {
383406
- name: "Mellow Restaking rstETH vault",
383407
- protocol: 21,
383408
- type: 30
383409
- /* MELLOW_LRT_VAULT */
383410
- },
383411
- MELLOW_RENZO_VAULT: {
383412
- name: "Mellow Renzo pzETH vault",
383413
- protocol: 21,
383414
- type: 30
383415
- /* MELLOW_LRT_VAULT */
383416
- },
383417
- SKY_STAKING_REWARDS: {
383418
- name: "Sky StakingRewards contract",
383419
- protocol: 23,
383420
- type: 34,
383421
- stakedToken: "stkUSDS"
383422
- },
383423
- DAI_USDS: {
383424
- name: "DAI/USDS Exchange",
383425
- protocol: 23,
383426
- type: 33
383427
- /* DAI_USDS_EXCHANGE */
383440
+ throw new Error(`cannot find price oracle ${address}`);
383441
+ }
383442
+ get marketsMap() {
383443
+ return this.#markets;
383444
+ }
383445
+ get markets() {
383446
+ return this.#markets.values();
383447
+ }
383448
+ async tvl() {
383449
+ const creditManagers = this.creditManagers;
383450
+ const tvls = await Promise.all(creditManagers.map((cm) => cm.tvl()));
383451
+ return tvls.reduce(
383452
+ (acc, curr) => {
383453
+ acc.tvl += curr.tvl;
383454
+ acc.tvlUSD += curr.tvlUSD;
383455
+ return acc;
383456
+ },
383457
+ { tvl: 0n, tvlUSD: 0n }
383458
+ );
383428
383459
  }
383429
383460
  };
383430
- var contractsByAddress = Object.entries(contractsByNetwork).reduce(
383431
- (acc, [, contracts2]) => ({
383432
- ...acc,
383433
- ...Object.fromEntries(
383434
- Object.entries(contracts2).map(([k, v]) => [v.toLowerCase(), k]).filter((k) => !!k)
383435
- )
383436
- }),
383437
- {}
383438
- );
383439
- var PriceFeedType = /* @__PURE__ */ ((PriceFeedType2) => {
383440
- PriceFeedType2[PriceFeedType2["CHAINLINK_ORACLE"] = 0] = "CHAINLINK_ORACLE";
383441
- PriceFeedType2[PriceFeedType2["YEARN_ORACLE"] = 1] = "YEARN_ORACLE";
383442
- PriceFeedType2[PriceFeedType2["CURVE_2LP_ORACLE"] = 2] = "CURVE_2LP_ORACLE";
383443
- PriceFeedType2[PriceFeedType2["CURVE_3LP_ORACLE"] = 3] = "CURVE_3LP_ORACLE";
383444
- PriceFeedType2[PriceFeedType2["CURVE_4LP_ORACLE"] = 4] = "CURVE_4LP_ORACLE";
383445
- PriceFeedType2[PriceFeedType2["ZERO_ORACLE"] = 5] = "ZERO_ORACLE";
383446
- PriceFeedType2[PriceFeedType2["WSTETH_ORACLE"] = 6] = "WSTETH_ORACLE";
383447
- PriceFeedType2[PriceFeedType2["BOUNDED_ORACLE"] = 7] = "BOUNDED_ORACLE";
383448
- PriceFeedType2[PriceFeedType2["COMPOSITE_ORACLE"] = 8] = "COMPOSITE_ORACLE";
383449
- PriceFeedType2[PriceFeedType2["WRAPPED_AAVE_V2_ORACLE"] = 9] = "WRAPPED_AAVE_V2_ORACLE";
383450
- PriceFeedType2[PriceFeedType2["COMPOUND_V2_ORACLE"] = 10] = "COMPOUND_V2_ORACLE";
383451
- PriceFeedType2[PriceFeedType2["BALANCER_STABLE_LP_ORACLE"] = 11] = "BALANCER_STABLE_LP_ORACLE";
383452
- PriceFeedType2[PriceFeedType2["BALANCER_WEIGHTED_LP_ORACLE"] = 12] = "BALANCER_WEIGHTED_LP_ORACLE";
383453
- PriceFeedType2[PriceFeedType2["CURVE_CRYPTO_ORACLE"] = 13] = "CURVE_CRYPTO_ORACLE";
383454
- PriceFeedType2[PriceFeedType2["THE_SAME_AS"] = 14] = "THE_SAME_AS";
383455
- PriceFeedType2[PriceFeedType2["REDSTONE_ORACLE"] = 15] = "REDSTONE_ORACLE";
383456
- PriceFeedType2[PriceFeedType2["ERC4626_VAULT_ORACLE"] = 16] = "ERC4626_VAULT_ORACLE";
383457
- PriceFeedType2[PriceFeedType2["NETWORK_DEPENDENT"] = 17] = "NETWORK_DEPENDENT";
383458
- PriceFeedType2[PriceFeedType2["CURVE_USD_ORACLE"] = 18] = "CURVE_USD_ORACLE";
383459
- PriceFeedType2[PriceFeedType2["PYTH_ORACLE"] = 19] = "PYTH_ORACLE";
383460
- PriceFeedType2[PriceFeedType2["MELLOW_LRT_ORACLE"] = 20] = "MELLOW_LRT_ORACLE";
383461
- PriceFeedType2[PriceFeedType2["PENDLE_PT_TWAP_ORACLE"] = 21] = "PENDLE_PT_TWAP_ORACLE";
383462
- return PriceFeedType2;
383463
- })(PriceFeedType || {});
383464
383461
  var PathOptionFactory = class _PathOptionFactory {
383465
383462
  // TODO: get rid of token data from SDK
383466
383463
  static generatePathOptions(balances, network, loopsInTx) {
@@ -383903,12 +383900,14 @@ function assetsMap(assets) {
383903
383900
  var CreditAccountsService = class extends SDKConstruct {
383904
383901
  #compressor;
383905
383902
  #batchSize;
383903
+ #logger;
383906
383904
  constructor(sdk, options) {
383907
383905
  super(sdk);
383908
383906
  this.#compressor = sdk.addressProvider.getLatestVersion(
383909
383907
  AP_CREDIT_ACCOUNT_COMPRESSOR
383910
383908
  );
383911
383909
  this.#batchSize = options?.batchSize;
383910
+ this.#logger = childLogger("CreditAccountsService", sdk.logger);
383912
383911
  }
383913
383912
  /**
383914
383913
  * Returns single credit account data, or undefined if it's not found
@@ -384421,6 +384420,10 @@ var CreditAccountsService = class extends SDKConstruct {
384421
384420
  const tokens = Array.from(tokensByPool.get(pool2) ?? []);
384422
384421
  priceFeeds.push(...oracle.priceFeedsForTokens(tokens));
384423
384422
  }
384423
+ this.#logger?.debug(
384424
+ { account: creditAccount?.creditAccount, manager: cm.name },
384425
+ `generating price feed updates for ${priceFeeds.length} price feeds`
384426
+ );
384424
384427
  return this.sdk.priceFeeds.generatePriceFeedsUpdateTxs(
384425
384428
  priceFeeds,
384426
384429
  creditAccount ? { account: creditAccount.creditAccount } : void 0
@@ -384433,11 +384436,16 @@ var CreditAccountsService = class extends SDKConstruct {
384433
384436
  */
384434
384437
  async getOnDemandPriceUpdates(creditManager, creditAccount, desiredQuotas) {
384435
384438
  const market = this.sdk.marketRegister.findByCreditManager(creditManager);
384439
+ const cm = this.sdk.marketRegister.findCreditManager(creditManager);
384436
384440
  const update = await this.getUpdateForAccount(
384437
384441
  creditManager,
384438
384442
  creditAccount,
384439
384443
  desiredQuotas
384440
384444
  );
384445
+ this.#logger?.debug(
384446
+ { account: creditAccount?.creditAccount, manager: cm.name },
384447
+ `getting on demand price updates from ${update.txs.length} txs`
384448
+ );
384441
384449
  return market.priceOracle.onDemandPriceUpdates(update);
384442
384450
  }
384443
384451
  /**
@@ -417849,7 +417857,7 @@ function audit() {
417849
417857
  }
417850
417858
 
417851
417859
  // src/commands/open-accounts.ts
417852
- import { writeFile as writeFile5 } from "node:fs/promises";
417860
+ import { mkdir, writeFile as writeFile5 } from "node:fs/promises";
417853
417861
  import path8 from "node:path";
417854
417862
  function openAccounts() {
417855
417863
  return newCommand().name("open-accounts").description("Script to open accounts in v3.1").addOption(
@@ -417871,6 +417879,7 @@ function openAccounts() {
417871
417879
  anvilUrl = "http://127.0.0.1:8545",
417872
417880
  sharedDir = "."
417873
417881
  } = opts;
417882
+ await mkdir(path8.resolve(sharedDir, "deploy-state"), { recursive: true });
417874
417883
  const sdkExample2 = new SDKExample(log_default);
417875
417884
  await sdkExample2.run({
417876
417885
  addressProvider,
@@ -418003,7 +418012,7 @@ function getRenderer(opts) {
418003
418012
  var package_default = {
418004
418013
  name: "@gearbox-protocol/deploy-tools",
418005
418014
  description: "Gearbox deploy tools",
418006
- version: "5.3.17",
418015
+ version: "5.3.19",
418007
418016
  homepage: "https://gearbox.fi",
418008
418017
  keywords: [
418009
418018
  "gearbox"
@@ -418046,7 +418055,7 @@ var package_default = {
418046
418055
  "@gearbox-protocol/deploy-tools-node": "0.0.0",
418047
418056
  "@gearbox-protocol/deploy-tools-shared": "0.0.0",
418048
418057
  "@gearbox-protocol/deploy-tools-types": "0.0.0",
418049
- "@gearbox-protocol/sdk": "^3.0.0-vfour.164",
418058
+ "@gearbox-protocol/sdk": "^3.0.0-vfour.167",
418050
418059
  "@gearbox-protocol/sdk-gov": "^2.33.2",
418051
418060
  "@types/lodash-es": "^4.17.12",
418052
418061
  "@types/node": "^22.10.5",
@@ -418147,7 +418156,7 @@ function printSafeTx() {
418147
418156
  }
418148
418157
 
418149
418158
  // src/commands/sdk-example.ts
418150
- import { writeFile as writeFile7 } from "node:fs/promises";
418159
+ import { mkdir as mkdir2, writeFile as writeFile7 } from "node:fs/promises";
418151
418160
  import path10 from "node:path";
418152
418161
  function sdkExample() {
418153
418162
  return newCommand().name("sdk-example").description("SDK example for v3.1").addOption(
@@ -418169,6 +418178,7 @@ function sdkExample() {
418169
418178
  anvilUrl = "http://127.0.0.1:8545",
418170
418179
  sharedDir = "."
418171
418180
  } = opts;
418181
+ await mkdir2(path10.resolve(sharedDir, "deploy-state"), { recursive: true });
418172
418182
  const sdkExample2 = new SDKExample(log_default);
418173
418183
  await sdkExample2.run({
418174
418184
  addressProvider,