@gearbox-protocol/sdk 18.3.0 → 18.4.0

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 (181) hide show
  1. package/dist/cjs/abi/310/iKillSwitchProxy.js +130 -0
  2. package/dist/cjs/onchain/accounts/intents/maxBorrowAndWithdraw.js +3 -1
  3. package/dist/cjs/onchain/index.js +18 -0
  4. package/dist/cjs/onchain/market/adapters/abi/adapters/iTreehouseFastlaneAdapter.js +113 -0
  5. package/dist/cjs/onchain/market/adapters/abi/adapters/iTreehouseRedemptionGatewayAdapter.js +258 -0
  6. package/dist/cjs/onchain/market/adapters/abi/adapters/iTreehouseRouterAdapter.js +161 -0
  7. package/dist/cjs/onchain/market/adapters/abi/adapters/index.js +6 -0
  8. package/dist/cjs/onchain/market/adapters/abi/index.js +13 -0
  9. package/dist/cjs/onchain/market/adapters/abi/treehouse/iTreehouseFastlane.js +39 -0
  10. package/dist/cjs/onchain/market/adapters/abi/treehouse/iTreehouseRedemptionGateway.js +230 -0
  11. package/dist/cjs/onchain/market/adapters/abi/treehouse/iTreehouseRouter.js +29 -0
  12. package/dist/cjs/onchain/market/adapters/abi/treehouse/index.js +7 -0
  13. package/dist/cjs/onchain/market/adapters/contracts/TreehouseFastlaneAdapterContract.js +72 -0
  14. package/dist/cjs/onchain/market/adapters/contracts/TreehouseRedemptionGatewayAdapterContract.js +117 -0
  15. package/dist/cjs/onchain/market/adapters/contracts/TreehouseRouterAdapterContract.js +61 -0
  16. package/dist/cjs/onchain/market/adapters/contracts/index.js +6 -0
  17. package/dist/cjs/onchain/market/adapters/createAdapter.js +6 -0
  18. package/dist/cjs/onchain/market/adapters/index.js +18 -0
  19. package/dist/cjs/onchain/market/index.js +18 -0
  20. package/dist/cjs/permissionless/api/index.js +31 -0
  21. package/dist/cjs/permissionless/api/oracles/PermissionlessOracles.js +637 -65
  22. package/dist/cjs/permissionless/api/oracles/enrich.js +99 -0
  23. package/dist/cjs/permissionless/api/oracles/index.js +33 -0
  24. package/dist/cjs/permissionless/api/oracles/onchain-feed.js +25 -0
  25. package/dist/cjs/permissionless/api/oracles/schemas.js +84 -59
  26. package/dist/cjs/permissionless/api/oracles/score/formula.js +56 -0
  27. package/dist/cjs/permissionless/api/oracles/score/index.js +11 -0
  28. package/dist/cjs/permissionless/api/oracles/score/run.js +252 -0
  29. package/dist/cjs/permissionless/api/oracles/score/types.js +1 -0
  30. package/dist/cjs/permissionless/api/oracles/stress/classify.js +258 -0
  31. package/dist/cjs/permissionless/api/oracles/stress/index.js +24 -0
  32. package/dist/cjs/permissionless/api/oracles/stress/override.js +125 -0
  33. package/dist/cjs/permissionless/api/oracles/stress/run.js +485 -0
  34. package/dist/cjs/permissionless/api/oracles/stress/score.js +98 -0
  35. package/dist/cjs/permissionless/api/oracles/stress/types.js +1 -0
  36. package/dist/cjs/permissionless/api/schemas.js +0 -3
  37. package/dist/cjs/permissionless/api/transactions/InstanceOwnerTransactions.js +14 -3
  38. package/dist/cjs/permissionless/api/transactions/lp-price-feeds.js +10 -4
  39. package/dist/cjs/permissionless/bindings/bytecode-repository.js +8 -0
  40. package/dist/cjs/permissionless/bindings/governance/governor.js +1 -1
  41. package/dist/cjs/permissionless/bindings/index.js +8 -3
  42. package/dist/cjs/permissionless/bindings/kill-switch-proxy.js +188 -0
  43. package/dist/cjs/permissionless/bindings/market-configurator-factory.js +39 -1
  44. package/dist/cjs/permissionless/bindings/market-configurator.js +142 -0
  45. package/dist/cjs/permissionless/index.js +42 -3
  46. package/dist/cjs/permissionless/utils/index.js +3 -0
  47. package/dist/cjs/permissionless/utils/literals.js +2 -0
  48. package/dist/cjs/permissionless/utils/price-update/get-prices.js +64 -0
  49. package/dist/cjs/permissionless/utils/price-update/index.js +2 -0
  50. package/dist/cjs/testnets/TestnetsAPI.js +179 -0
  51. package/dist/cjs/testnets/errors/TestnetNotFoundError.js +15 -0
  52. package/dist/cjs/testnets/errors/TestnetRequestFailedError.js +24 -0
  53. package/dist/cjs/testnets/errors/TestnetStatusError.js +19 -0
  54. package/dist/cjs/testnets/errors/TestnetValidationError.js +24 -0
  55. package/dist/cjs/testnets/errors/TestnetWaitTimeoutError.js +30 -0
  56. package/dist/cjs/testnets/errors/TestnetsError.js +34 -0
  57. package/dist/cjs/testnets/errors/index.js +13 -0
  58. package/dist/cjs/testnets/index.js +32 -0
  59. package/dist/cjs/testnets/package.json +1 -0
  60. package/dist/cjs/testnets/schemas.js +242 -0
  61. package/dist/cjs/testnets/types.js +1 -0
  62. package/dist/esm/abi/310/iKillSwitchProxy.js +129 -0
  63. package/dist/esm/onchain/accounts/intents/maxBorrowAndWithdraw.js +3 -1
  64. package/dist/esm/onchain/index.js +10 -1
  65. package/dist/esm/onchain/market/adapters/abi/adapters/iTreehouseFastlaneAdapter.js +112 -0
  66. package/dist/esm/onchain/market/adapters/abi/adapters/iTreehouseRedemptionGatewayAdapter.js +257 -0
  67. package/dist/esm/onchain/market/adapters/abi/adapters/iTreehouseRouterAdapter.js +160 -0
  68. package/dist/esm/onchain/market/adapters/abi/adapters/index.js +4 -1
  69. package/dist/esm/onchain/market/adapters/abi/index.js +8 -1
  70. package/dist/esm/onchain/market/adapters/abi/treehouse/iTreehouseFastlane.js +38 -0
  71. package/dist/esm/onchain/market/adapters/abi/treehouse/iTreehouseRedemptionGateway.js +229 -0
  72. package/dist/esm/onchain/market/adapters/abi/treehouse/iTreehouseRouter.js +28 -0
  73. package/dist/esm/onchain/market/adapters/abi/treehouse/index.js +4 -0
  74. package/dist/esm/onchain/market/adapters/contracts/TreehouseFastlaneAdapterContract.js +71 -0
  75. package/dist/esm/onchain/market/adapters/contracts/TreehouseRedemptionGatewayAdapterContract.js +116 -0
  76. package/dist/esm/onchain/market/adapters/contracts/TreehouseRouterAdapterContract.js +60 -0
  77. package/dist/esm/onchain/market/adapters/contracts/index.js +4 -1
  78. package/dist/esm/onchain/market/adapters/createAdapter.js +6 -0
  79. package/dist/esm/onchain/market/adapters/index.js +10 -1
  80. package/dist/esm/onchain/market/index.js +10 -1
  81. package/dist/esm/permissionless/api/index.js +7 -1
  82. package/dist/esm/permissionless/api/oracles/PermissionlessOracles.js +639 -67
  83. package/dist/esm/permissionless/api/oracles/enrich.js +94 -0
  84. package/dist/esm/permissionless/api/oracles/index.js +10 -1
  85. package/dist/esm/permissionless/api/oracles/onchain-feed.js +24 -0
  86. package/dist/esm/permissionless/api/oracles/schemas.js +80 -58
  87. package/dist/esm/permissionless/api/oracles/score/formula.js +51 -0
  88. package/dist/esm/permissionless/api/oracles/score/index.js +4 -0
  89. package/dist/esm/permissionless/api/oracles/score/run.js +250 -0
  90. package/dist/esm/permissionless/api/oracles/score/types.js +1 -0
  91. package/dist/esm/permissionless/api/oracles/stress/classify.js +256 -0
  92. package/dist/esm/permissionless/api/oracles/stress/index.js +6 -0
  93. package/dist/esm/permissionless/api/oracles/stress/override.js +119 -0
  94. package/dist/esm/permissionless/api/oracles/stress/run.js +478 -0
  95. package/dist/esm/permissionless/api/oracles/stress/score.js +95 -0
  96. package/dist/esm/permissionless/api/oracles/stress/types.js +1 -0
  97. package/dist/esm/permissionless/api/schemas.js +2 -4
  98. package/dist/esm/permissionless/api/transactions/InstanceOwnerTransactions.js +14 -3
  99. package/dist/esm/permissionless/api/transactions/lp-price-feeds.js +10 -4
  100. package/dist/esm/permissionless/bindings/bytecode-repository.js +8 -0
  101. package/dist/esm/permissionless/bindings/governance/governor.js +1 -1
  102. package/dist/esm/permissionless/bindings/index.js +5 -4
  103. package/dist/esm/permissionless/bindings/kill-switch-proxy.js +184 -0
  104. package/dist/esm/permissionless/bindings/market-configurator-factory.js +37 -0
  105. package/dist/esm/permissionless/bindings/market-configurator.js +143 -1
  106. package/dist/esm/permissionless/index.js +13 -6
  107. package/dist/esm/permissionless/utils/index.js +3 -3
  108. package/dist/esm/permissionless/utils/literals.js +2 -1
  109. package/dist/esm/permissionless/utils/price-update/get-prices.js +63 -1
  110. package/dist/esm/permissionless/utils/price-update/index.js +2 -2
  111. package/dist/esm/testnets/TestnetsAPI.js +178 -0
  112. package/dist/esm/testnets/errors/TestnetNotFoundError.js +14 -0
  113. package/dist/esm/testnets/errors/TestnetRequestFailedError.js +23 -0
  114. package/dist/esm/testnets/errors/TestnetStatusError.js +18 -0
  115. package/dist/esm/testnets/errors/TestnetValidationError.js +23 -0
  116. package/dist/esm/testnets/errors/TestnetWaitTimeoutError.js +29 -0
  117. package/dist/esm/testnets/errors/TestnetsError.js +33 -0
  118. package/dist/esm/testnets/errors/index.js +7 -0
  119. package/dist/esm/testnets/index.js +11 -0
  120. package/dist/esm/testnets/package.json +1 -0
  121. package/dist/esm/testnets/schemas.js +228 -0
  122. package/dist/esm/testnets/types.js +1 -0
  123. package/dist/types/abi/310/iKillSwitchProxy.d.ts +114 -0
  124. package/dist/types/onchain/index.d.ts +10 -1
  125. package/dist/types/onchain/market/adapters/abi/adapters/iTreehouseFastlaneAdapter.d.ts +101 -0
  126. package/dist/types/onchain/market/adapters/abi/adapters/iTreehouseRedemptionGatewayAdapter.d.ts +237 -0
  127. package/dist/types/onchain/market/adapters/abi/adapters/iTreehouseRouterAdapter.d.ts +146 -0
  128. package/dist/types/onchain/market/adapters/abi/adapters/index.d.ts +4 -1
  129. package/dist/types/onchain/market/adapters/abi/index.d.ts +8 -1
  130. package/dist/types/onchain/market/adapters/abi/treehouse/iTreehouseFastlane.d.ts +33 -0
  131. package/dist/types/onchain/market/adapters/abi/treehouse/iTreehouseRedemptionGateway.d.ts +207 -0
  132. package/dist/types/onchain/market/adapters/abi/treehouse/iTreehouseRouter.d.ts +27 -0
  133. package/dist/types/onchain/market/adapters/abi/treehouse/index.d.ts +4 -0
  134. package/dist/types/onchain/market/adapters/contracts/TreehouseFastlaneAdapterContract.d.ts +156 -0
  135. package/dist/types/onchain/market/adapters/contracts/TreehouseRedemptionGatewayAdapterContract.d.ts +481 -0
  136. package/dist/types/onchain/market/adapters/contracts/TreehouseRouterAdapterContract.d.ts +193 -0
  137. package/dist/types/onchain/market/adapters/contracts/index.d.ts +4 -1
  138. package/dist/types/onchain/market/adapters/index.d.ts +10 -1
  139. package/dist/types/onchain/market/index.d.ts +10 -1
  140. package/dist/types/permissionless/api/index.d.ts +10 -2
  141. package/dist/types/permissionless/api/oracles/PermissionlessOracles.d.ts +237 -47
  142. package/dist/types/permissionless/api/oracles/enrich.d.ts +59 -0
  143. package/dist/types/permissionless/api/oracles/index.d.ts +12 -2
  144. package/dist/types/permissionless/api/oracles/onchain-feed.d.ts +15 -0
  145. package/dist/types/permissionless/api/oracles/schemas.d.ts +147 -41
  146. package/dist/types/permissionless/api/oracles/score/formula.d.ts +36 -0
  147. package/dist/types/permissionless/api/oracles/score/index.d.ts +4 -0
  148. package/dist/types/permissionless/api/oracles/score/run.d.ts +42 -0
  149. package/dist/types/permissionless/api/oracles/score/types.d.ts +118 -0
  150. package/dist/types/permissionless/api/oracles/stress/classify.d.ts +57 -0
  151. package/dist/types/permissionless/api/oracles/stress/index.d.ts +6 -0
  152. package/dist/types/permissionless/api/oracles/stress/override.d.ts +59 -0
  153. package/dist/types/permissionless/api/oracles/stress/run.d.ts +100 -0
  154. package/dist/types/permissionless/api/oracles/stress/score.d.ts +57 -0
  155. package/dist/types/permissionless/api/oracles/stress/types.d.ts +272 -0
  156. package/dist/types/permissionless/api/oracles/types.d.ts +320 -125
  157. package/dist/types/permissionless/api/schemas.d.ts +0 -2
  158. package/dist/types/permissionless/api/transactions/lp-price-feeds.d.ts +9 -1
  159. package/dist/types/permissionless/bindings/bytecode-repository.d.ts +10 -1
  160. package/dist/types/permissionless/bindings/index.d.ts +4 -3
  161. package/dist/types/permissionless/bindings/kill-switch-proxy.d.ts +205 -0
  162. package/dist/types/permissionless/bindings/market-configurator-factory.d.ts +30 -0
  163. package/dist/types/permissionless/bindings/market-configurator.d.ts +30 -1
  164. package/dist/types/permissionless/bindings/types.d.ts +27 -0
  165. package/dist/types/permissionless/index.d.ts +15 -6
  166. package/dist/types/permissionless/utils/index.d.ts +3 -3
  167. package/dist/types/permissionless/utils/literals.d.ts +1 -0
  168. package/dist/types/permissionless/utils/price-update/get-prices.d.ts +33 -0
  169. package/dist/types/permissionless/utils/price-update/index.d.ts +2 -2
  170. package/dist/types/testnets/TestnetsAPI.d.ts +108 -0
  171. package/dist/types/testnets/errors/TestnetNotFoundError.d.ts +12 -0
  172. package/dist/types/testnets/errors/TestnetRequestFailedError.d.ts +11 -0
  173. package/dist/types/testnets/errors/TestnetStatusError.d.ts +15 -0
  174. package/dist/types/testnets/errors/TestnetValidationError.d.ts +16 -0
  175. package/dist/types/testnets/errors/TestnetWaitTimeoutError.d.ts +21 -0
  176. package/dist/types/testnets/errors/TestnetsError.d.ts +47 -0
  177. package/dist/types/testnets/errors/index.d.ts +7 -0
  178. package/dist/types/testnets/index.d.ts +11 -0
  179. package/dist/types/testnets/schemas.d.ts +554 -0
  180. package/dist/types/testnets/types.d.ts +717 -0
  181. package/package.json +6 -1
@@ -5,8 +5,8 @@ import "../../../onchain/index.js";
5
5
  import { BytecodeRepositoryContract } from "../bytecode-repository.js";
6
6
  import "../../deployment/addresses.js";
7
7
  import { TreasurySplitterContract } from "../treasury-splitter.js";
8
- import { governorAbi } from "../../../abi/governance/governor.js";
9
8
  import { MarketConfiguratorContract } from "../market-configurator.js";
9
+ import { governorAbi } from "../../../abi/governance/governor.js";
10
10
  import { BatchesChainContract } from "./batches-chain.js";
11
11
  import { encodeAbiParameters, formatEther, keccak256, toBytes } from "viem";
12
12
  import { formatAbiItem } from "viem/utils";
@@ -1,6 +1,7 @@
1
1
  import { BytecodeRepositoryContract } from "./bytecode-repository.js";
2
2
  import { priceFeedSetupParams } from "./pricefeeds/index.js";
3
3
  import { PriceFeedStoreContract } from "./price-feed-store.js";
4
+ import { AddressProviderContract } from "./address-provider.js";
4
5
  import { TokenCompressorContract } from "./compressors/token-compressor.js";
5
6
  import { WithdrawalCompressorContract } from "./compressors/withdrawal-compressor.js";
6
7
  import "./compressors/index.js";
@@ -8,12 +9,12 @@ import { RoutingManagerContract } from "./router/routing-manager.js";
8
9
  import "./router/index.js";
9
10
  import { TreasurySplitterContract } from "./treasury-splitter.js";
10
11
  import { InstanceManagerContract } from "./instance-manager.js";
11
- import { AddressProviderContract } from "./address-provider.js";
12
- import { MarketConfiguratorFactoryContract } from "./market-configurator-factory.js";
13
- import { CrossChainMultisigContract } from "./cross-chain-multisig.js";
14
12
  import { AccessMode } from "./types.js";
15
13
  import { MarketConfiguratorContract } from "./market-configurator.js";
14
+ import { KILL_SWITCH_PROXY_MINOR_VERSION, KillSwitchProxyContract, KillSwitchProxyNotAllowedError, killSwitchProxySalt } from "./kill-switch-proxy.js";
15
+ import { MarketConfiguratorFactoryContract } from "./market-configurator-factory.js";
16
+ import { CrossChainMultisigContract } from "./cross-chain-multisig.js";
16
17
  import { GovernorContract } from "./governance/governor.js";
17
18
  import { TimeLockContract } from "./governance/timelock.js";
18
19
  import "./governance/index.js";
19
- export { AccessMode, AddressProviderContract, BytecodeRepositoryContract, CrossChainMultisigContract, GovernorContract, InstanceManagerContract, MarketConfiguratorContract, MarketConfiguratorFactoryContract, PriceFeedStoreContract, RoutingManagerContract, TimeLockContract, TokenCompressorContract, TreasurySplitterContract, WithdrawalCompressorContract, priceFeedSetupParams };
20
+ export { AccessMode, AddressProviderContract, BytecodeRepositoryContract, CrossChainMultisigContract, GovernorContract, InstanceManagerContract, KILL_SWITCH_PROXY_MINOR_VERSION, KillSwitchProxyContract, KillSwitchProxyNotAllowedError, MarketConfiguratorContract, MarketConfiguratorFactoryContract, PriceFeedStoreContract, RoutingManagerContract, TimeLockContract, TokenCompressorContract, TreasurySplitterContract, WithdrawalCompressorContract, killSwitchProxySalt, priceFeedSetupParams };
@@ -0,0 +1,184 @@
1
+ import { json_stringify } from "../../onchain/utils/json.js";
2
+ import { BaseContract } from "../../onchain/base/BaseContract.js";
3
+ import "../../onchain/index.js";
4
+ import { KILL_SWITCH_PROXY } from "../utils/literals.js";
5
+ import { iKillSwitchProxyAbi } from "../../abi/310/iKillSwitchProxy.js";
6
+ import { MarketConfiguratorContract } from "./market-configurator.js";
7
+ import { BaseError, ContractFunctionRevertedError, encodeAbiParameters, isAddressEqual, keccak256, toHex, zeroAddress } from "viem";
8
+ //#region src/permissionless/bindings/kill-switch-proxy.ts
9
+ const abi = iKillSwitchProxyAbi;
10
+ /**
11
+ * Minor version of kill switch proxy, the latest allowed patch of it is deployed
12
+ */
13
+ const KILL_SWITCH_PROXY_MINOR_VERSION = 310;
14
+ /**
15
+ * Salt of kill switch proxy deployed together with market configurator,
16
+ * makes each curator's market configurator get its own proxy
17
+ */
18
+ function killSwitchProxySalt(curatorName) {
19
+ return keccak256(toHex(curatorName));
20
+ }
21
+ /**
22
+ * Thrown when bytecode repository has no allowed kill switch proxy bytecode,
23
+ * so its address can't be computed and it can't be deployed
24
+ */
25
+ var KillSwitchProxyNotAllowedError = class extends BaseError {
26
+ name = "KillSwitchProxyNotAllowedError";
27
+ bytecodeRepository;
28
+ constructor(bytecodeRepository) {
29
+ super(`${KILL_SWITCH_PROXY} v310 is not allowed in bytecode repository ${bytecodeRepository}.`, { metaMessages: ["Its bytecode must be uploaded, audited and allowed before it can be deployed."] });
30
+ this.bytecodeRepository = bytecodeRepository;
31
+ }
32
+ };
33
+ /**
34
+ * Kill switch proxy forwards calls of its `caller` via `proxyCall` until `owner` kills it.
35
+ * It is used as market configurator's emergency admin, so that emergency powers
36
+ * can be revoked instantly without going through the timelock.
37
+ */
38
+ var KillSwitchProxyContract = class KillSwitchProxyContract extends BaseContract {
39
+ constructor(addr, client) {
40
+ super({ client }, {
41
+ abi,
42
+ addr,
43
+ name: "KillSwitchProxy"
44
+ });
45
+ }
46
+ /**
47
+ * Encodes `constructor(address _owner, address _caller)` params
48
+ * @throws if any address is zero or owner equals caller (constructor reverts in that case)
49
+ */
50
+ static encodeConstructorParams(args) {
51
+ const { owner, caller } = args;
52
+ if (isAddressEqual(owner, zeroAddress) || isAddressEqual(caller, zeroAddress)) throw new Error(`${KILL_SWITCH_PROXY} owner and caller must be non-zero`);
53
+ if (isAddressEqual(owner, caller)) throw new Error(`${KILL_SWITCH_PROXY} owner must differ from caller ${caller}, provide another kill switch owner`);
54
+ const [constructorAbi] = abi;
55
+ return encodeAbiParameters(constructorAbi.inputs, [owner, caller]);
56
+ }
57
+ /**
58
+ * Returns whether some patch of kill switch proxy v3.10 is allowed in bytecode repository
59
+ */
60
+ static async isAvailable(bcr) {
61
+ try {
62
+ await KillSwitchProxyContract.#getVersion(bcr);
63
+ return true;
64
+ } catch (e) {
65
+ if (e instanceof KillSwitchProxyNotAllowedError) return false;
66
+ throw e;
67
+ }
68
+ }
69
+ /**
70
+ * Computes address of kill switch proxy and prepares its deployment via bytecode repository
71
+ * @param bcr - bytecode repository
72
+ * @param args.deployer - address that will send deployment transaction, it is mixed into the salt
73
+ * @param args.owner - address that can kill the proxy
74
+ * @param args.caller - address that can call through the proxy
75
+ * @param args.salt - deployment salt
76
+ * @throws {KillSwitchProxyNotAllowedError} if kill switch proxy is not allowed in bytecode repository
77
+ */
78
+ static async prepareDeploy(bcr, args) {
79
+ const { deployer, owner, caller, salt } = args;
80
+ const encodedParams = KillSwitchProxyContract.encodeConstructorParams({
81
+ owner,
82
+ caller
83
+ });
84
+ const version = await KillSwitchProxyContract.#getVersion(bcr);
85
+ const [isAlreadyDeployed, address] = await bcr.isAlreadyDeployedAddress({
86
+ contractType: KILL_SWITCH_PROXY,
87
+ version,
88
+ encodedParams,
89
+ salt,
90
+ owner: deployer
91
+ });
92
+ return {
93
+ address,
94
+ version,
95
+ encodedParams,
96
+ salt,
97
+ isAlreadyDeployed,
98
+ isKilled: isAlreadyDeployed ? await new KillSwitchProxyContract(address, bcr.client).isKilled() : false,
99
+ tx: bcr.deployTx({
100
+ contractType: KILL_SWITCH_PROXY,
101
+ version: BigInt(version),
102
+ encodedParams,
103
+ salt
104
+ })
105
+ };
106
+ }
107
+ static async #getVersion(bcr) {
108
+ try {
109
+ return await bcr.getLatestPatchVersion(KILL_SWITCH_PROXY, 310);
110
+ } catch (e) {
111
+ const revert = e instanceof BaseError ? e.walk((err) => err instanceof ContractFunctionRevertedError) : null;
112
+ if (revert instanceof ContractFunctionRevertedError && revert.data?.errorName === "VersionNotFoundException") throw new KillSwitchProxyNotAllowedError(bcr.address);
113
+ throw e;
114
+ }
115
+ }
116
+ async isKilled() {
117
+ return await this.contract.read.isKilled();
118
+ }
119
+ async state() {
120
+ const [caller, owner, isKilled] = await this.client.multicall({
121
+ allowFailure: false,
122
+ contracts: [
123
+ {
124
+ address: this.address,
125
+ abi,
126
+ functionName: "caller"
127
+ },
128
+ {
129
+ address: this.address,
130
+ abi,
131
+ functionName: "owner"
132
+ },
133
+ {
134
+ address: this.address,
135
+ abi,
136
+ functionName: "isKilled"
137
+ }
138
+ ],
139
+ batchSize: 0
140
+ });
141
+ return {
142
+ caller,
143
+ owner,
144
+ isKilled
145
+ };
146
+ }
147
+ /**
148
+ * Wraps transaction into `proxyCall`, must be sent by proxy's caller
149
+ */
150
+ proxyCallTx(tx) {
151
+ return this.createRawTx({
152
+ functionName: "proxyCall",
153
+ args: [tx.to, tx.callData],
154
+ description: tx.description ? `KillSwitchProxy.proxyCall(${tx.description})` : void 0
155
+ });
156
+ }
157
+ /**
158
+ * Permanently disables `proxyCall`, must be sent by proxy's owner
159
+ */
160
+ killTx() {
161
+ return this.createRawTx({ functionName: "kill" });
162
+ }
163
+ parseFunctionParams(params) {
164
+ const { functionName, args } = params;
165
+ switch (functionName) {
166
+ case "proxyCall": {
167
+ const [target, data] = args;
168
+ const decoded = new MarketConfiguratorContract(target, this.client).parseFunctionData(data);
169
+ if (decoded.functionName.startsWith("Unknown function")) return {
170
+ target,
171
+ data
172
+ };
173
+ return {
174
+ target,
175
+ functionName: decoded.functionName,
176
+ data: json_stringify(decoded.args)
177
+ };
178
+ }
179
+ default: return super.parseFunctionParams(params);
180
+ }
181
+ }
182
+ };
183
+ //#endregion
184
+ export { KILL_SWITCH_PROXY_MINOR_VERSION, KillSwitchProxyContract, KillSwitchProxyNotAllowedError, killSwitchProxySalt };
@@ -1,6 +1,10 @@
1
1
  import { BaseContract } from "../../onchain/base/BaseContract.js";
2
2
  import "../../onchain/index.js";
3
+ import { KILL_SWITCH_PROXY } from "../utils/literals.js";
4
+ import { BytecodeRepositoryContract } from "./bytecode-repository.js";
5
+ import "../deployment/addresses.js";
3
6
  import { iMarketConfiguratorFactoryAbi } from "../../abi/310/iMarketConfiguratorFactory.js";
7
+ import { KillSwitchProxyContract, killSwitchProxySalt } from "./kill-switch-proxy.js";
4
8
  //#region src/permissionless/bindings/market-configurator-factory.ts
5
9
  const abi = iMarketConfiguratorFactoryAbi;
6
10
  var MarketConfiguratorFactoryContract = class extends BaseContract {
@@ -22,6 +26,39 @@ var MarketConfiguratorFactoryContract = class extends BaseContract {
22
26
  ]
23
27
  });
24
28
  }
29
+ /**
30
+ * Builds transactions that deploy market configurator with kill switch proxy as its emergency admin:
31
+ * 1. kill switch proxy deployment via bytecode repository (skipped if already deployed)
32
+ * 2. market configurator creation with proxy as emergency admin
33
+ *
34
+ * Transactions must be sent in this order by `admin`, e.g. as one Safe batch.
35
+ * When `deployGovernor` is true, proxy also becomes governor's veto admin.
36
+ *
37
+ * @param args.admin - address that sends transactions, becomes market configurator admin
38
+ * @param args.emergencyAdmin - address that executes emergency actions through the proxy
39
+ * @param args.killSwitchOwner - address that can kill the proxy, defaults to `admin`
40
+ * @throws {KillSwitchProxyNotAllowedError} if kill switch proxy is not allowed in bytecode repository,
41
+ * use {@link createMarketConfiguratorTx} to deploy market configurator without it
42
+ */
43
+ async createMarketConfiguratorWithKillSwitchTxs(args) {
44
+ const { admin, emergencyAdmin, killSwitchOwner, ...rest } = args;
45
+ const bcr = new BytecodeRepositoryContract("0x1cE2B1BE96a082b1b1539F80d5D8f82Ec06a0f9A", this.client);
46
+ const proxy = await KillSwitchProxyContract.prepareDeploy(bcr, {
47
+ deployer: admin,
48
+ owner: killSwitchOwner ?? admin,
49
+ caller: emergencyAdmin,
50
+ salt: killSwitchProxySalt(args.curatorName)
51
+ });
52
+ if (proxy.isKilled) throw new Error(`${KILL_SWITCH_PROXY} ${proxy.address} is already deployed and killed`);
53
+ return {
54
+ killSwitchProxy: proxy.address,
55
+ isKillSwitchProxyDeployed: proxy.isAlreadyDeployed,
56
+ txs: [...proxy.isAlreadyDeployed ? [] : [proxy.tx], this.createMarketConfiguratorTx({
57
+ ...rest,
58
+ emergencyAdmin: proxy.address
59
+ })]
60
+ };
61
+ }
25
62
  async getMarketConfigurators() {
26
63
  return [...await this.contract.read.getMarketConfigurators()];
27
64
  }
@@ -1,8 +1,11 @@
1
1
  import { iMarketConfiguratorV310Abi } from "../../abi/310/generated.js";
2
2
  import { json_stringify } from "../../onchain/utils/json.js";
3
+ import { createRawTx } from "../../onchain/utils/createRawTx.js";
3
4
  import { BaseContract } from "../../onchain/base/BaseContract.js";
4
5
  import "../../onchain/index.js";
6
+ import { KILL_SWITCH_PROXY } from "../utils/literals.js";
5
7
  import { AddressProviderContract } from "./address-provider.js";
8
+ import { iKillSwitchProxyAbi } from "../../abi/310/iKillSwitchProxy.js";
6
9
  import { creditFacadeParamsAbi, creditManagerParamsAbi } from "../../abi/310/configure/creditSuiteParams.js";
7
10
  import { parseIrmDeployParams } from "../plugins/irm/constructor-params-abi.js";
8
11
  import { parseLossPolicyDeployParams } from "../plugins/loss-policies/constructor-params-abi.js";
@@ -15,7 +18,7 @@ import { LossPolicyFactory } from "./factory/loss-policy-factory.js";
15
18
  import { PoolFactory } from "./factory/pool-factory.js";
16
19
  import { PriceOracleFactory } from "./factory/price-oracle-factory.js";
17
20
  import { RateKeeperFactory } from "./factory/rate-keeper-factory.js";
18
- import { decodeAbiParameters, encodeAbiParameters, encodeFunctionData, erc20Abi, erc4626Abi, hexToString, keccak256, parseAbi, stringToHex, toBytes } from "viem";
21
+ import { decodeAbiParameters, encodeAbiParameters, encodeFunctionData, erc20Abi, erc4626Abi, hexToString, isAddressEqual, keccak256, parseAbi, stringToHex, toBytes } from "viem";
19
22
  //#region src/permissionless/bindings/market-configurator.ts
20
23
  const PERIPHERY_DOMAINS = ["ZAPPER", "DEGEN_NFT"];
21
24
  const abi = iMarketConfiguratorV310Abi;
@@ -395,6 +398,83 @@ var MarketConfiguratorContract = class extends BaseContract {
395
398
  return;
396
399
  }
397
400
  }
401
+ /**
402
+ * Returns emergency admin of the market configurator.
403
+ * If it is a `KILL_SWITCH_PROXY`, emergency transactions must be sent by proxy's caller via `proxyCall`,
404
+ * otherwise directly by emergency admin itself
405
+ * @param emergencyAdmin - emergency admin address, read from the market configurator if not provided
406
+ */
407
+ async getEmergencyAdmin(emergencyAdmin) {
408
+ const address = emergencyAdmin ?? await this.contract.read.emergencyAdmin();
409
+ const [contractType, caller, owner, isKilled] = await this.client.multicall({
410
+ allowFailure: true,
411
+ contracts: [
412
+ {
413
+ address,
414
+ abi: iKillSwitchProxyAbi,
415
+ functionName: "contractType"
416
+ },
417
+ {
418
+ address,
419
+ abi: iKillSwitchProxyAbi,
420
+ functionName: "caller"
421
+ },
422
+ {
423
+ address,
424
+ abi: iKillSwitchProxyAbi,
425
+ functionName: "owner"
426
+ },
427
+ {
428
+ address,
429
+ abi: iKillSwitchProxyAbi,
430
+ functionName: "isKilled"
431
+ }
432
+ ],
433
+ batchSize: 0
434
+ });
435
+ let isKillSwitch = false;
436
+ if (contractType.status === "success") try {
437
+ isKillSwitch = hexToString(contractType.result, { size: 32 }) === KILL_SWITCH_PROXY;
438
+ } catch {}
439
+ if (!isKillSwitch) return {
440
+ type: "direct",
441
+ address,
442
+ executor: address
443
+ };
444
+ if (caller.status !== "success" || owner.status !== "success" || isKilled.status !== "success") throw new Error(`failed to read state of ${KILL_SWITCH_PROXY} emergency admin ${address}`);
445
+ return {
446
+ type: "killSwitch",
447
+ address,
448
+ caller: caller.result,
449
+ owner: owner.result,
450
+ isKilled: isKilled.result,
451
+ executor: caller.result
452
+ };
453
+ }
454
+ /**
455
+ * Routes emergency transaction to the market configurator through its emergency admin:
456
+ * returns transaction as is for direct emergency admin, or wraps it into `proxyCall` of kill switch proxy
457
+ * @param tx - emergency transaction to the market configurator, e.g. built by `emergencyConfigurePool`
458
+ * @param emergencyAdmin - result of {@link getEmergencyAdmin}
459
+ * @throws if transaction is not addressed to this market configurator or kill switch proxy is killed
460
+ */
461
+ wrapEmergencyTx(tx, emergencyAdmin) {
462
+ if (!isAddressEqual(tx.to, this.address)) throw new Error(`emergency tx target ${tx.to} is not market configurator ${this.address}`);
463
+ if (emergencyAdmin.type === "direct") return tx;
464
+ if (emergencyAdmin.isKilled) throw new Error(`${KILL_SWITCH_PROXY} ${emergencyAdmin.address} of market configurator ${this.address} is killed`);
465
+ return createRawTx(emergencyAdmin.address, {
466
+ abi: iKillSwitchProxyAbi,
467
+ functionName: "proxyCall",
468
+ args: [this.address, tx.callData]
469
+ }, tx.description ? `KillSwitchProxy.proxyCall(${tx.description})` : void 0);
470
+ }
471
+ /**
472
+ * Reads emergency admin and routes emergency transaction through it, see {@link wrapEmergencyTx}
473
+ * @param tx - emergency transaction to the market configurator, e.g. built by `emergencyConfigurePool`
474
+ */
475
+ async emergencyTx(tx) {
476
+ return this.wrapEmergencyTx(tx, await this.getEmergencyAdmin());
477
+ }
398
478
  grantRole(role, address) {
399
479
  return this.createRawTx({
400
480
  functionName: "grantRole",
@@ -608,9 +688,53 @@ var MarketConfiguratorContract = class extends BaseContract {
608
688
  role: hexToString(role, { size: 32 })
609
689
  };
610
690
  }
691
+ case "emergencyConfigurePool":
692
+ case "emergencyConfigurePriceOracle":
693
+ case "emergencyConfigureLossPolicy":
694
+ case "emergencyConfigureRateKeeper":
695
+ case "emergencyConfigureInterestRateModel": {
696
+ const [pool, calldata] = args;
697
+ const decoded = this.#decodeEmergencyConfig(functionName, calldata);
698
+ return decoded ? {
699
+ pool,
700
+ data: json_stringify(decoded)
701
+ } : {
702
+ pool,
703
+ calldata
704
+ };
705
+ }
706
+ case "emergencyConfigureCreditSuite": {
707
+ const [creditManager, calldata] = args;
708
+ const decoded = this.#decodeEmergencyConfig(functionName, calldata);
709
+ return decoded ? {
710
+ creditManager,
711
+ data: json_stringify(decoded)
712
+ } : {
713
+ creditManager,
714
+ calldata
715
+ };
716
+ }
611
717
  default: return super.parseFunctionParams(params);
612
718
  }
613
719
  }
720
+ /**
721
+ * Emergency actions share selectors with regular configuration actions only partially
722
+ * (e.g., `pause`, `forbidToken`, `setPriceFeed`), so decoding is best-effort
723
+ */
724
+ #decodeEmergencyConfig(functionName, calldata) {
725
+ const factory = {
726
+ emergencyConfigurePool: this.poolFactory,
727
+ emergencyConfigureCreditSuite: this.creditFactory,
728
+ emergencyConfigurePriceOracle: this.priceOracleFactory,
729
+ emergencyConfigureLossPolicy: this.lossPolicyFactory,
730
+ emergencyConfigureRateKeeper: this.rateKeeperFactory
731
+ }[functionName];
732
+ try {
733
+ return factory?.decodeConfig(calldata) ?? null;
734
+ } catch {
735
+ return null;
736
+ }
737
+ }
614
738
  emergencyConfigurePool(pool, calldata) {
615
739
  return this.createRawTx({
616
740
  functionName: "emergencyConfigurePool",
@@ -635,6 +759,24 @@ var MarketConfiguratorContract = class extends BaseContract {
635
759
  args: [pool, calldata]
636
760
  });
637
761
  }
762
+ /**
763
+ * Note: current interest rate model factory forbids all emergency configuration calls
764
+ */
765
+ emergencyConfigureInterestRateModel(pool, calldata) {
766
+ return this.createRawTx({
767
+ functionName: "emergencyConfigureInterestRateModel",
768
+ args: [pool, calldata]
769
+ });
770
+ }
771
+ /**
772
+ * Note: current rate keeper factory forbids all emergency configuration calls
773
+ */
774
+ emergencyConfigureRateKeeper(pool, calldata) {
775
+ return this.createRawTx({
776
+ functionName: "emergencyConfigureRateKeeper",
777
+ args: [pool, calldata]
778
+ });
779
+ }
638
780
  };
639
781
  //#endregion
640
782
  export { MarketConfiguratorContract };
@@ -2,7 +2,7 @@ import { PermissionlessAnalytics } from "./api/analytics/PermissionlessAnalytics
2
2
  import { PermissionlessChainUnreachableError, PermissionlessNotAttachedError, PriceFeedNotInStoreError, PriceFeedSaltMissingError, PriceFeedStalenessUnknownError } from "./api/errors.js";
3
3
  import { ChainsNamespace } from "./api/chains/ChainsNamespace.js";
4
4
  import { deriveEffectiveStalenessPeriod } from "./api/deploy/effective-staleness.js";
5
- import { BYTECODE_REPOSITORY, CROSS_CHAIN_GOVERNANCE, CROSS_CHAIN_MULTISIG, INSTANCE_MANAGER, MARKET_CONFIGURATOR_FACTORY, PRICE_FEED_STORE, TOKEN_COMPRESSOR } from "./utils/literals.js";
5
+ import { BYTECODE_REPOSITORY, CROSS_CHAIN_GOVERNANCE, CROSS_CHAIN_MULTISIG, INSTANCE_MANAGER, KILL_SWITCH_PROXY, MARKET_CONFIGURATOR_FACTORY, PRICE_FEED_STORE, TOKEN_COMPRESSOR } from "./utils/literals.js";
6
6
  import { normalizeSignature } from "./utils/signature.js";
7
7
  import { BytecodeRepositoryContract } from "./bindings/bytecode-repository.js";
8
8
  import { priceFeedSetupParams } from "./bindings/pricefeeds/index.js";
@@ -10,7 +10,14 @@ import { PriceFeedStoreContract } from "./bindings/price-feed-store.js";
10
10
  import { Addresses } from "./deployment/addresses.js";
11
11
  import { encodeFunctionParams } from "./utils/abi-encoder.js";
12
12
  import { DEFAULT_DEPLOY_SALT, PermissionlessDeploy, priceFeedSalt } from "./api/deploy/PermissionlessDeploy.js";
13
- import { getPrices } from "./utils/price-update/get-prices.js";
13
+ import { AddressProviderContract } from "./bindings/address-provider.js";
14
+ import { getFeedDecimals, getLatestPrices, getPrices } from "./utils/price-update/get-prices.js";
15
+ import { classifySources, sourcesByFeed } from "./api/oracles/stress/classify.js";
16
+ import { UNBOUNDED_DOWN, UNBOUNDED_UP, groupOverride, perturb, rateStub, roundDataStub } from "./api/oracles/stress/override.js";
17
+ import { scoreGroup, slotHarm, verdictOf } from "./api/oracles/stress/score.js";
18
+ import { DEFAULT_SCENARIOS, RATE_FEED_TYPE, readFeedTrees, readForest, readRateTargets, readUnder, runStressTest } from "./api/oracles/stress/run.js";
19
+ import { SCORE_MULTIPLIER, factorOf, finalPrice, scoreOfFactor, worstOf } from "./api/oracles/score/formula.js";
20
+ import { runAssetScores, runFeedPairScore } from "./api/oracles/score/run.js";
14
21
  import { GET_PRICES_CHUNK_SIZE, GET_PRICES_GAS_LIMIT_BY_CHAIN_ID, PermissionlessOracles } from "./api/oracles/PermissionlessOracles.js";
15
22
  import { TokenCompressorContract } from "./bindings/compressors/token-compressor.js";
16
23
  import { WithdrawalCompressorContract } from "./bindings/compressors/withdrawal-compressor.js";
@@ -22,14 +29,14 @@ import { getUpdatablePriceFeeds } from "./utils/price-update/get-updatable-feeds
22
29
  import { InstanceOwnerTransactions } from "./api/transactions/InstanceOwnerTransactions.js";
23
30
  import { GearboxPermissionless } from "./api/GearboxPermissionless.js";
24
31
  import "./api/index.js";
25
- import { AddressProviderContract } from "./bindings/address-provider.js";
26
- import { MarketConfiguratorFactoryContract } from "./bindings/market-configurator-factory.js";
27
- import { CrossChainMultisigContract } from "./bindings/cross-chain-multisig.js";
28
32
  import { PUBLIC_CREATE2_FACTORY, checkCreate2Deployment, checkCreate2DeploymentAddress, createCreate2DeployRawTx, deployUsingPublicCreate2, getCreate2AddressPublicFactory, getCreate2DeploymentAddress, handleSalt } from "./utils/create2.js";
29
33
  import { convertPercent, deepJsonParse, formatBytecodeSize, formatBytecodeVersion, shortenHash, significantTrunc } from "./utils/format.js";
30
34
  import { createCallData } from "./core/raw-tx.js";
31
35
  import { AccessMode } from "./bindings/types.js";
32
36
  import { MarketConfiguratorContract } from "./bindings/market-configurator.js";
37
+ import { KILL_SWITCH_PROXY_MINOR_VERSION, KillSwitchProxyContract, KillSwitchProxyNotAllowedError, killSwitchProxySalt } from "./bindings/kill-switch-proxy.js";
38
+ import { MarketConfiguratorFactoryContract } from "./bindings/market-configurator-factory.js";
39
+ import { CrossChainMultisigContract } from "./bindings/cross-chain-multisig.js";
33
40
  import { GovernorContract } from "./bindings/governance/governor.js";
34
41
  import { TimeLockContract } from "./bindings/governance/timelock.js";
35
42
  import "./bindings/index.js";
@@ -41,4 +48,4 @@ import { getBlockNumberByTimestamp } from "./utils/block-utils.js";
41
48
  import { convertQueueBatchToExecuteTx } from "./utils/governance/timelock-txs.js";
42
49
  import { getPriceUpdateTx } from "./utils/price-update/get-price-update-tx.js";
43
50
  import "./utils/index.js";
44
- export { AccessMode, AddressProviderContract, Addresses, ArchiveTransport, BYTECODE_REPOSITORY, BytecodeRepositoryContract, CROSS_CHAIN_GOVERNANCE, CROSS_CHAIN_MULTISIG, ChainsNamespace, CrossChainMultisigContract, DEFAULT_DEPLOY_SALT, GET_PRICES_CHUNK_SIZE, GET_PRICES_GAS_LIMIT_BY_CHAIN_ID, GearboxPermissionless, GovernorContract, INSTANCE_MANAGER, InstanceManagerContract, InstanceOwnerTransactions, MAINNET_CCM_CONSTRUCTOR_PARAMS, MAINNET_DEPLOYMENT_BLOCK, MAINNET_DEPLOYMENT_CCM_SALT, MAINNET_DEPLOYMENT_IM_SALT, MARKET_CONFIGURATOR_FACTORY, MarketConfiguratorContract, MarketConfiguratorFactoryContract, PRICE_FEED_STORE, PUBLIC_CREATE2_FACTORY, PermissionlessAnalytics, PermissionlessChainUnreachableError, PermissionlessDeploy, PermissionlessNotAttachedError, PermissionlessOracles, PriceFeedNotInStoreError, PriceFeedSaltMissingError, PriceFeedStalenessUnknownError, PriceFeedStoreContract, RoutingManagerContract, TOKEN_COMPRESSOR, TimeLockContract, TokenCompressorContract, TreasurySplitterContract, WithdrawalCompressorContract, calculateChecksum, checkCreate2Deployment, checkCreate2DeploymentAddress, chunkedLogsTransport, convertPercent, convertQueueBatchToExecuteTx, convertRawTxToSafeMultisigTx, createCallData, createCreate2DeployRawTx, deepJsonParse, deployUsingPublicCreate2, deriveEffectiveStalenessPeriod, encodeFunctionParams, formatBytecodeSize, formatBytecodeVersion, getBlockNumberByTimestamp, getCreate2AddressPublicFactory, getCreate2DeploymentAddress, getPriceUpdateTx, getPrices, getSafeBatch, getSafeBatches, getUpdatablePriceFeeds, handleSalt, normalizeSignature, priceFeedSalt, priceFeedSetupParams, shortenHash, significantTrunc };
51
+ export { AccessMode, AddressProviderContract, Addresses, ArchiveTransport, BYTECODE_REPOSITORY, BytecodeRepositoryContract, CROSS_CHAIN_GOVERNANCE, CROSS_CHAIN_MULTISIG, ChainsNamespace, CrossChainMultisigContract, DEFAULT_DEPLOY_SALT, DEFAULT_SCENARIOS, GET_PRICES_CHUNK_SIZE, GET_PRICES_GAS_LIMIT_BY_CHAIN_ID, GearboxPermissionless, GovernorContract, INSTANCE_MANAGER, InstanceManagerContract, InstanceOwnerTransactions, KILL_SWITCH_PROXY, KILL_SWITCH_PROXY_MINOR_VERSION, KillSwitchProxyContract, KillSwitchProxyNotAllowedError, MAINNET_CCM_CONSTRUCTOR_PARAMS, MAINNET_DEPLOYMENT_BLOCK, MAINNET_DEPLOYMENT_CCM_SALT, MAINNET_DEPLOYMENT_IM_SALT, MARKET_CONFIGURATOR_FACTORY, MarketConfiguratorContract, MarketConfiguratorFactoryContract, PRICE_FEED_STORE, PUBLIC_CREATE2_FACTORY, PermissionlessAnalytics, PermissionlessChainUnreachableError, PermissionlessDeploy, PermissionlessNotAttachedError, PermissionlessOracles, PriceFeedNotInStoreError, PriceFeedSaltMissingError, PriceFeedStalenessUnknownError, PriceFeedStoreContract, RATE_FEED_TYPE, RoutingManagerContract, SCORE_MULTIPLIER, TOKEN_COMPRESSOR, TimeLockContract, TokenCompressorContract, TreasurySplitterContract, UNBOUNDED_DOWN, UNBOUNDED_UP, WithdrawalCompressorContract, calculateChecksum, checkCreate2Deployment, checkCreate2DeploymentAddress, chunkedLogsTransport, classifySources, convertPercent, convertQueueBatchToExecuteTx, convertRawTxToSafeMultisigTx, createCallData, createCreate2DeployRawTx, deepJsonParse, deployUsingPublicCreate2, deriveEffectiveStalenessPeriod, encodeFunctionParams, factorOf, finalPrice, formatBytecodeSize, formatBytecodeVersion, getBlockNumberByTimestamp, getCreate2AddressPublicFactory, getCreate2DeploymentAddress, getFeedDecimals, getLatestPrices, getPriceUpdateTx, getPrices, getSafeBatch, getSafeBatches, getUpdatablePriceFeeds, groupOverride, handleSalt, killSwitchProxySalt, normalizeSignature, perturb, priceFeedSalt, priceFeedSetupParams, rateStub, readFeedTrees, readForest, readRateTargets, readUnder, roundDataStub, runAssetScores, runFeedPairScore, runStressTest, scoreGroup, scoreOfFactor, shortenHash, significantTrunc, slotHarm, sourcesByFeed, verdictOf, worstOf };
@@ -1,7 +1,7 @@
1
- import { BYTECODE_REPOSITORY, CROSS_CHAIN_GOVERNANCE, CROSS_CHAIN_MULTISIG, INSTANCE_MANAGER, MARKET_CONFIGURATOR_FACTORY, PRICE_FEED_STORE, TOKEN_COMPRESSOR } from "./literals.js";
1
+ import { BYTECODE_REPOSITORY, CROSS_CHAIN_GOVERNANCE, CROSS_CHAIN_MULTISIG, INSTANCE_MANAGER, KILL_SWITCH_PROXY, MARKET_CONFIGURATOR_FACTORY, PRICE_FEED_STORE, TOKEN_COMPRESSOR } from "./literals.js";
2
2
  import { normalizeSignature } from "./signature.js";
3
3
  import { encodeFunctionParams } from "./abi-encoder.js";
4
- import { getPrices } from "./price-update/get-prices.js";
4
+ import { getFeedDecimals, getLatestPrices, getPrices } from "./price-update/get-prices.js";
5
5
  import { calculateChecksum, convertRawTxToSafeMultisigTx, getSafeBatch, getSafeBatches } from "./governance/batch.js";
6
6
  import { getUpdatablePriceFeeds } from "./price-update/get-updatable-feeds.js";
7
7
  import { PUBLIC_CREATE2_FACTORY, checkCreate2Deployment, checkCreate2DeploymentAddress, createCreate2DeployRawTx, deployUsingPublicCreate2, getCreate2AddressPublicFactory, getCreate2DeploymentAddress, handleSalt } from "./create2.js";
@@ -11,4 +11,4 @@ import { convertQueueBatchToExecuteTx } from "./governance/timelock-txs.js";
11
11
  import "./governance/index.js";
12
12
  import { getPriceUpdateTx } from "./price-update/get-price-update-tx.js";
13
13
  import "./price-update/index.js";
14
- export { BYTECODE_REPOSITORY, CROSS_CHAIN_GOVERNANCE, CROSS_CHAIN_MULTISIG, INSTANCE_MANAGER, MARKET_CONFIGURATOR_FACTORY, PRICE_FEED_STORE, PUBLIC_CREATE2_FACTORY, TOKEN_COMPRESSOR, calculateChecksum, checkCreate2Deployment, checkCreate2DeploymentAddress, convertPercent, convertQueueBatchToExecuteTx, convertRawTxToSafeMultisigTx, createCreate2DeployRawTx, deepJsonParse, deployUsingPublicCreate2, encodeFunctionParams, formatBytecodeSize, formatBytecodeVersion, getBlockNumberByTimestamp, getCreate2AddressPublicFactory, getCreate2DeploymentAddress, getPriceUpdateTx, getPrices, getSafeBatch, getSafeBatches, getUpdatablePriceFeeds, handleSalt, normalizeSignature, shortenHash, significantTrunc };
14
+ export { BYTECODE_REPOSITORY, CROSS_CHAIN_GOVERNANCE, CROSS_CHAIN_MULTISIG, INSTANCE_MANAGER, KILL_SWITCH_PROXY, MARKET_CONFIGURATOR_FACTORY, PRICE_FEED_STORE, PUBLIC_CREATE2_FACTORY, TOKEN_COMPRESSOR, calculateChecksum, checkCreate2Deployment, checkCreate2DeploymentAddress, convertPercent, convertQueueBatchToExecuteTx, convertRawTxToSafeMultisigTx, createCreate2DeployRawTx, deepJsonParse, deployUsingPublicCreate2, encodeFunctionParams, formatBytecodeSize, formatBytecodeVersion, getBlockNumberByTimestamp, getCreate2AddressPublicFactory, getCreate2DeploymentAddress, getFeedDecimals, getLatestPrices, getPriceUpdateTx, getPrices, getSafeBatch, getSafeBatches, getUpdatablePriceFeeds, handleSalt, normalizeSignature, shortenHash, significantTrunc };
@@ -6,5 +6,6 @@ const TOKEN_COMPRESSOR = "GLOBAL::TOKEN_COMPRESSOR";
6
6
  const CROSS_CHAIN_MULTISIG = "CROSS_CHAIN_MULTISIG";
7
7
  const PRICE_FEED_STORE = "PRICE_FEED_STORE";
8
8
  const MARKET_CONFIGURATOR_FACTORY = "MARKET_CONFIGURATOR_FACTORY";
9
+ const KILL_SWITCH_PROXY = "KILL_SWITCH_PROXY";
9
10
  //#endregion
10
- export { BYTECODE_REPOSITORY, CROSS_CHAIN_GOVERNANCE, CROSS_CHAIN_MULTISIG, INSTANCE_MANAGER, MARKET_CONFIGURATOR_FACTORY, PRICE_FEED_STORE, TOKEN_COMPRESSOR };
11
+ export { BYTECODE_REPOSITORY, CROSS_CHAIN_GOVERNANCE, CROSS_CHAIN_MULTISIG, INSTANCE_MANAGER, KILL_SWITCH_PROXY, MARKET_CONFIGURATOR_FACTORY, PRICE_FEED_STORE, TOKEN_COMPRESSOR };
@@ -31,6 +31,16 @@ const latestRoundDataAbi = [{
31
31
  stateMutability: "view",
32
32
  type: "function"
33
33
  }];
34
+ const decimalsAbi = [{
35
+ inputs: [],
36
+ name: "decimals",
37
+ outputs: [{
38
+ name: "",
39
+ type: "uint8"
40
+ }],
41
+ stateMutability: "view",
42
+ type: "function"
43
+ }];
34
44
  function getLatestRoundDataCall(priceFeed) {
35
45
  return {
36
46
  address: priceFeed,
@@ -39,6 +49,58 @@ function getLatestRoundDataCall(priceFeed) {
39
49
  args: []
40
50
  };
41
51
  }
52
+ /**
53
+ * The scale each feed's answer is in, in one multicall.
54
+ *
55
+ * Part of the Chainlink interface every feed in a Gearbox tree implements,
56
+ * and the only way to read an answer that is not an oracle's own: a feed an
57
+ * oracle holds reports 8 decimals by construction, while the feeds beneath a
58
+ * composite are whatever was deployed — an ETH/USD aggregator at 8 and a
59
+ * rate leg at 18 sit under the same parent.
60
+ *
61
+ * `null` is a feed that would not answer, which a caller should treat as
62
+ * unknown rather than defaulting it to 8.
63
+ */
64
+ async function getFeedDecimals({ client, priceFeeds }) {
65
+ if (priceFeeds.length === 0) return {};
66
+ const results = await client.multicall({
67
+ contracts: priceFeeds.map((priceFeed) => ({
68
+ address: priceFeed,
69
+ abi: decimalsAbi,
70
+ functionName: "decimals",
71
+ args: []
72
+ })),
73
+ allowFailure: true
74
+ });
75
+ return Object.fromEntries(priceFeeds.map((priceFeed, index) => {
76
+ const result = results[index];
77
+ return [priceFeed, result?.status === "success" ? Number(result.result) : null];
78
+ }));
79
+ }
80
+ /**
81
+ * What the feeds report as they stand, in one multicall.
82
+ *
83
+ * What {@link getPrices} does without the part that makes it expensive: no
84
+ * `OnchainSDK` to attach and no update transactions to assemble, which is the
85
+ * whole cost of that call and is wasted on a feed that answers already. A feed
86
+ * that needs a fresh answer before it will be read comes back `null` here, so
87
+ * a caller that must price those falls back to {@link getPrices} for them and
88
+ * pays once for the few rather than once for all.
89
+ *
90
+ * `null` is also a feed whose read reverted for any other reason, which is not
91
+ * a zero.
92
+ */
93
+ async function getLatestPrices({ client, priceFeeds }) {
94
+ if (priceFeeds.length === 0) return {};
95
+ const results = await client.multicall({
96
+ contracts: priceFeeds.map(getLatestRoundDataCall),
97
+ allowFailure: true
98
+ });
99
+ return Object.fromEntries(priceFeeds.map((priceFeed, index) => {
100
+ const result = results[index];
101
+ return [priceFeed, result?.status === "success" ? result.result[1] : null];
102
+ }));
103
+ }
42
104
  async function getPricesChunk({ client, priceFeeds, sdk }) {
43
105
  const updateCall = priceFeeds.map((priceFeed) => getLatestRoundDataCall(priceFeed));
44
106
  const multicallCalls = (await sdk.priceFeeds.generateExternalPriceFeedsUpdateTxs(priceFeeds)).txs.map((tx) => ({
@@ -82,4 +144,4 @@ async function getPrices({ client, priceFeeds, chunkSize = 10, gasLimit }) {
82
144
  }), {});
83
145
  }
84
146
  //#endregion
85
- export { getPrices };
147
+ export { getFeedDecimals, getLatestPrices, getPrices };
@@ -1,4 +1,4 @@
1
- import { getPrices } from "./get-prices.js";
1
+ import { getFeedDecimals, getLatestPrices, getPrices } from "./get-prices.js";
2
2
  import { getUpdatablePriceFeeds } from "./get-updatable-feeds.js";
3
3
  import { getPriceUpdateTx } from "./get-price-update-tx.js";
4
- export { getPriceUpdateTx, getPrices, getUpdatablePriceFeeds };
4
+ export { getFeedDecimals, getLatestPrices, getPriceUpdateTx, getPrices, getUpdatablePriceFeeds };