@gearbox-protocol/sdk 18.2.0-next.11 → 18.2.0-next.13

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 (76) hide show
  1. package/dist/cjs/abi/310/iKillSwitchProxy.js +130 -0
  2. package/dist/cjs/dev/AccountOpener.js +1 -1
  3. package/dist/cjs/dev/withdrawalUtils.js +1 -1
  4. package/dist/cjs/history/trace/extractTransfers.js +1 -1
  5. package/dist/cjs/onchain/accounts/CreditAccountsServiceV310.js +2 -2
  6. package/dist/cjs/onchain/accounts/liquidations/LiquidationsService.js +1 -1
  7. package/dist/cjs/onchain/accounts/withdrawal-compressor/RedemptionLoggerV310Contract.js +2 -1
  8. package/dist/cjs/onchain/accounts/withdrawal-compressor/WithdrawalCompressorV310Contract.js +2 -1
  9. package/dist/cjs/onchain/accounts/withdrawal-compressor/WithdrawalCompressorV311Contract.js +2 -1
  10. package/dist/cjs/onchain/accounts/withdrawal-compressor/WithdrawalCompressorV313Contract.js +1 -1
  11. package/dist/cjs/onchain/base/TokensMeta.js +3 -3
  12. package/dist/cjs/onchain/core/createAddressProvider.js +1 -1
  13. package/dist/cjs/onchain/market/adapters/contracts/AccountMigratorAdapterContract.js +1 -1
  14. package/dist/cjs/onchain/market/adapters/contracts/ERC4626AdapterContract.js +1 -1
  15. package/dist/cjs/onchain/market/credit/CreditFacadeV310BaseContract.js +1 -1
  16. package/dist/cjs/onchain/market/pool/PoolV310Contract.js +1 -1
  17. package/dist/cjs/onchain/market/rwa/createDegenNFT.js +1 -1
  18. package/dist/cjs/onchain/market/zapper/IETHZapperContract.js +2 -1
  19. package/dist/cjs/onchain/market/zapper/ZapperContract.js +1 -1
  20. package/dist/cjs/onchain/preview/preview/previewPoolPositionOperation.js +2 -2
  21. package/dist/cjs/onchain/utils/viem/simulateWithPriceUpdates.js +1 -1
  22. package/dist/cjs/permissionless/api/index.js +7 -3
  23. package/dist/cjs/permissionless/api/oracles/PermissionlessOracles.js +11 -11
  24. package/dist/cjs/permissionless/api/oracles/index.js +7 -3
  25. package/dist/cjs/permissionless/api/oracles/score/formula.js +44 -82
  26. package/dist/cjs/permissionless/api/oracles/score/index.js +6 -3
  27. package/dist/cjs/permissionless/api/oracles/score/run.js +129 -46
  28. package/dist/cjs/permissionless/api/oracles/stress/index.js +1 -0
  29. package/dist/cjs/permissionless/api/oracles/stress/run.js +5 -2
  30. package/dist/cjs/permissionless/bindings/bytecode-repository.js +8 -0
  31. package/dist/cjs/permissionless/bindings/governance/governor.js +1 -1
  32. package/dist/cjs/permissionless/bindings/index.js +7 -2
  33. package/dist/cjs/permissionless/bindings/kill-switch-proxy.js +188 -0
  34. package/dist/cjs/permissionless/bindings/market-configurator-factory.js +39 -1
  35. package/dist/cjs/permissionless/bindings/market-configurator.js +142 -0
  36. package/dist/cjs/permissionless/index.js +15 -5
  37. package/dist/cjs/permissionless/utils/index.js +1 -0
  38. package/dist/cjs/permissionless/utils/literals.js +2 -0
  39. package/dist/esm/abi/310/iKillSwitchProxy.js +129 -0
  40. package/dist/esm/permissionless/api/index.js +3 -3
  41. package/dist/esm/permissionless/api/oracles/PermissionlessOracles.js +11 -11
  42. package/dist/esm/permissionless/api/oracles/index.js +3 -3
  43. package/dist/esm/permissionless/api/oracles/score/formula.js +39 -80
  44. package/dist/esm/permissionless/api/oracles/score/index.js +2 -2
  45. package/dist/esm/permissionless/api/oracles/score/run.js +131 -48
  46. package/dist/esm/permissionless/api/oracles/stress/index.js +2 -2
  47. package/dist/esm/permissionless/api/oracles/stress/run.js +5 -3
  48. package/dist/esm/permissionless/bindings/bytecode-repository.js +8 -0
  49. package/dist/esm/permissionless/bindings/governance/governor.js +1 -1
  50. package/dist/esm/permissionless/bindings/index.js +4 -3
  51. package/dist/esm/permissionless/bindings/kill-switch-proxy.js +184 -0
  52. package/dist/esm/permissionless/bindings/market-configurator-factory.js +37 -0
  53. package/dist/esm/permissionless/bindings/market-configurator.js +143 -1
  54. package/dist/esm/permissionless/index.js +7 -6
  55. package/dist/esm/permissionless/utils/index.js +2 -2
  56. package/dist/esm/permissionless/utils/literals.js +2 -1
  57. package/dist/types/abi/310/iKillSwitchProxy.d.ts +114 -0
  58. package/dist/types/permissionless/api/index.d.ts +4 -4
  59. package/dist/types/permissionless/api/oracles/PermissionlessOracles.d.ts +11 -11
  60. package/dist/types/permissionless/api/oracles/index.d.ts +4 -4
  61. package/dist/types/permissionless/api/oracles/score/formula.d.ts +31 -38
  62. package/dist/types/permissionless/api/oracles/score/index.d.ts +3 -3
  63. package/dist/types/permissionless/api/oracles/score/run.d.ts +7 -4
  64. package/dist/types/permissionless/api/oracles/score/types.d.ts +50 -22
  65. package/dist/types/permissionless/api/oracles/stress/index.d.ts +2 -2
  66. package/dist/types/permissionless/api/oracles/stress/run.d.ts +17 -1
  67. package/dist/types/permissionless/bindings/bytecode-repository.d.ts +10 -1
  68. package/dist/types/permissionless/bindings/index.d.ts +4 -3
  69. package/dist/types/permissionless/bindings/kill-switch-proxy.d.ts +205 -0
  70. package/dist/types/permissionless/bindings/market-configurator-factory.d.ts +30 -0
  71. package/dist/types/permissionless/bindings/market-configurator.d.ts +30 -1
  72. package/dist/types/permissionless/bindings/types.d.ts +27 -0
  73. package/dist/types/permissionless/index.d.ts +8 -7
  74. package/dist/types/permissionless/utils/index.d.ts +2 -2
  75. package/dist/types/permissionless/utils/literals.d.ts +1 -0
  76. package/package.json +1 -1
@@ -2,7 +2,10 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_permissionless_api_oracles_score_formula = require("./formula.js");
3
3
  const require_permissionless_api_oracles_score_run = require("./run.js");
4
4
  require("./types.js");
5
- exports.BOUND_WEIGHT = require_permissionless_api_oracles_score_formula.BOUND_WEIGHT;
6
- exports.INDEPENDENCE_WEIGHT = require_permissionless_api_oracles_score_formula.INDEPENDENCE_WEIGHT;
5
+ exports.REVERT_SCORE = require_permissionless_api_oracles_score_formula.REVERT_SCORE;
6
+ exports.SCORE_MULTIPLIER = require_permissionless_api_oracles_score_formula.SCORE_MULTIPLIER;
7
+ exports.factorOf = require_permissionless_api_oracles_score_formula.factorOf;
8
+ exports.finalPrice = require_permissionless_api_oracles_score_formula.finalPrice;
7
9
  exports.runAssetScores = require_permissionless_api_oracles_score_run.runAssetScores;
8
- exports.scoreMarket = require_permissionless_api_oracles_score_formula.scoreMarket;
10
+ exports.scoreOfFactor = require_permissionless_api_oracles_score_formula.scoreOfFactor;
11
+ exports.worstOf = require_permissionless_api_oracles_score_formula.worstOf;
@@ -2,73 +2,156 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_permissionless_api_oracles_stress_classify = require("../stress/classify.js");
3
3
  const require_permissionless_api_oracles_stress_run = require("../stress/run.js");
4
4
  const require_permissionless_api_oracles_score_formula = require("./formula.js");
5
+ let viem = require("viem");
5
6
  //#region src/permissionless/api/oracles/score/run.ts
7
+ const ZERO_TYPE = "PRICE_FEED::ZERO";
8
+ /** Groups simulated at once: one `eth_call` each, all against one node. */
9
+ const CONCURRENCY = 6;
10
+ const feedOf = (slot) => slot.priceFeed.toLowerCase();
6
11
  /**
7
- * How a source is told apart from another when two feeds are compared.
12
+ * Every asset of one chain, scored by what each of its source groups can do
13
+ * to the price its running markets hold for it.
8
14
  *
9
- * A named source by its group, since two Chainlink aggregators are one
10
- * provider failing together. An unnamed one by its contract, since nothing
11
- * says what else it fails with — so the same contract on both sides is
12
- * shared, and two different ones are not.
13
- */
14
- function toScoreSource(source) {
15
- return {
16
- key: source.identified ? `group:${source.group}` : `contract:${source.target}`,
17
- name: source.group,
18
- identified: source.identified
19
- };
20
- }
21
- /**
22
- * Every asset of one chain, scored by how its running markets price it.
23
- *
24
- * One read of every oracle's feed tree and one of the LP feeds' rate
25
- * contracts, both multicalls: the score is a reading of the trees and needs
26
- * no simulation.
15
+ * One read of the oracles' feed trees, one of the LP feeds' rate contracts,
16
+ * one of every market feed as it stands — then one `eth_call` per source
17
+ * group, with the group's sources overridden to answer
18
+ * {@link SCORE_MULTIPLIER} times what they answer now and every market feed
19
+ * read under it.
27
20
  **/
28
21
  async function runAssetScores({ client, chainId, slots, compressor, logger }) {
29
22
  const running = slots.filter((slot) => !slot.isShutdown);
30
23
  const oracles = [...new Set(running.map((slot) => slot.priceOracle.toLowerCase()))];
31
- const { nodes, unreadableOracles } = await require_permissionless_api_oracles_stress_run.readForest(client, compressor, oracles);
24
+ const { nodes, answers, unreadableOracles } = await require_permissionless_api_oracles_stress_run.readForest(client, compressor, oracles);
32
25
  for (const oracle of unreadableOracles) logger?.warn(`price oracle ${oracle} of chain ${chainId} would not report its feed tree; the markets on it are not scored`);
33
- const { targets } = await require_permissionless_api_oracles_stress_run.readRateTargets(client, [...nodes.values()].filter((node) => require_permissionless_api_oracles_stress_run.RATE_FEED_TYPE.test(node.contractType)).map((node) => node.address));
34
- const { sources } = require_permissionless_api_oracles_stress_classify.classifySources(chainId, [...nodes.values()], targets, () => null);
35
- const byTarget = new Map(sources.filter((source) => source.perturbable).map((source) => [source.target, toScoreSource(source)]));
36
- const feedOf = (slot) => slot.priceFeed.toLowerCase();
37
- const reach = require_permissionless_api_oracles_stress_classify.sourcesByFeed([...new Set(running.map(feedOf))], nodes, sources);
38
- const sourcesOf = (feed) => [...reach.get(feed) ?? []].map((target) => byTarget.get(target)).filter((source) => source !== void 0);
39
- const positions = /* @__PURE__ */ new Map();
26
+ const { targets, baselines: rateBaselines } = await require_permissionless_api_oracles_stress_run.readRateTargets(client, [...nodes.values()].filter((node) => require_permissionless_api_oracles_stress_run.RATE_FEED_TYPE.test(node.contractType)).map((node) => node.address));
27
+ const { sources, unresolved } = require_permissionless_api_oracles_stress_classify.classifySources(chainId, [...nodes.values()], targets, (target) => rateBaselines.get(target) ?? answers.get(target) ?? null);
28
+ for (const node of unresolved) logger?.warn(`feed ${node.address} of chain ${chainId} would not say what it reads its rate from; its protocol is not perturbed`);
29
+ const slotsByPosition = /* @__PURE__ */ new Map();
40
30
  for (const slot of running) {
41
31
  const key = `${slot.market.toLowerCase()}:${slot.token.toLowerCase()}`;
42
- const position = positions.get(key) ?? {};
43
- position[slot.reserve ? "reserve" : "main"] = slot;
44
- positions.set(key, position);
32
+ const entry = slotsByPosition.get(key) ?? {};
33
+ entry[slot.reserve ? "reserve" : "main"] = slot;
34
+ slotsByPosition.set(key, entry);
45
35
  }
46
- const byAsset = /* @__PURE__ */ new Map();
47
- for (const { main, reserve } of positions.values()) {
36
+ const positions = [];
37
+ for (const { main, reserve } of slotsByPosition.values()) {
48
38
  if (!main || main.isUnderlying) continue;
39
+ const mainNode = nodes.get(feedOf(main));
40
+ if (!mainNode || mainNode.contractType === ZERO_TYPE) continue;
41
+ const notes = [];
42
+ let reserveFeed;
43
+ if (!reserve) notes.push("no reserve feed");
44
+ else if (nodes.get(feedOf(reserve))?.contractType === ZERO_TYPE) notes.push("reserve is a ZeroPriceFeed");
45
+ else {
46
+ reserveFeed = feedOf(reserve);
47
+ if (reserveFeed === feedOf(main)) notes.push("reserve is the main feed");
48
+ }
49
+ positions.push({
50
+ main,
51
+ reserve,
52
+ reserveFeed,
53
+ notes
54
+ });
55
+ }
56
+ const priced = [...new Set(positions.flatMap(({ main, reserveFeed }) => reserveFeed ? [feedOf(main), reserveFeed] : [feedOf(main)]))];
57
+ if (priced.length === 0) return [];
58
+ const underlyingOf = (slot) => slot.underlyingPriceFeed?.toLowerCase();
59
+ const roots = [.../* @__PURE__ */ new Set([...priced, ...positions.map(({ main }) => underlyingOf(main)).filter((feed) => feed !== void 0)])];
60
+ const updatedAt = BigInt(Math.floor(Date.now() / 1e3));
61
+ const drivable = (source) => source !== void 0 && source.perturbable && source.baseline !== null;
62
+ const fresh = sources.filter((source) => drivable(source) && source.kind === "feed");
63
+ const asIs = await require_permissionless_api_oracles_stress_run.readUnder(client, roots, [], 1, updatedAt);
64
+ const stale = roots.filter((root) => (asIs.get(root) ?? null) === null);
65
+ const freshened = stale.length > 0 ? await require_permissionless_api_oracles_stress_run.readUnder(client, stale, [], 1, updatedAt, fresh) : /* @__PURE__ */ new Map();
66
+ const base = new Map(roots.map((root) => [root, asIs.get(root) ?? freshened.get(root) ?? null]));
67
+ const asIsRoots = roots.filter((root) => (asIs.get(root) ?? null) !== null);
68
+ const freshRoots = stale.filter((root) => (freshened.get(root) ?? null) !== null);
69
+ /** Every root under a lie, each read the way its base was. */
70
+ const readLying = async (members) => {
71
+ const [plain, refreshed] = await Promise.all([asIsRoots.length > 0 ? require_permissionless_api_oracles_stress_run.readUnder(client, asIsRoots, members, 5, updatedAt) : /* @__PURE__ */ new Map(), freshRoots.length > 0 ? require_permissionless_api_oracles_stress_run.readUnder(client, freshRoots, members, 5, updatedAt, fresh) : /* @__PURE__ */ new Map()]);
72
+ return new Map([...plain, ...refreshed]);
73
+ };
74
+ for (const position of positions) if (position.reserveFeed && (base.get(position.reserveFeed) ?? null) === null) {
75
+ position.reserveFeed = void 0;
76
+ position.notes.push("reserve does not answer");
77
+ }
78
+ const reach = require_permissionless_api_oracles_stress_classify.sourcesByFeed(roots, nodes, sources);
79
+ const sourceByTarget = new Map(sources.map((source) => [source.target, source]));
80
+ const byGroup = /* @__PURE__ */ new Map();
81
+ for (const source of sources.filter(drivable)) byGroup.set(source.group, [...byGroup.get(source.group) ?? [], source]);
82
+ const reachedGroups = /* @__PURE__ */ new Set();
83
+ for (const root of priced) for (const target of reach.get(root) ?? []) {
84
+ const source = sourceByTarget.get(target);
85
+ if (drivable(source)) reachedGroups.add(source.group);
86
+ }
87
+ const stressed = /* @__PURE__ */ new Map();
88
+ const queue = [...reachedGroups];
89
+ for (let i = 0; i < queue.length; i += CONCURRENCY) await Promise.all(queue.slice(i, i + CONCURRENCY).map(async (group) => {
90
+ stressed.set(group, await readLying(byGroup.get(group) ?? []));
91
+ }));
92
+ const groupsOf = (feed) => {
93
+ const out = /* @__PURE__ */ new Map();
94
+ for (const target of feed ? reach.get(feed) ?? [] : []) {
95
+ const source = sourceByTarget.get(target);
96
+ if (drivable(source)) out.set(source.group, [...out.get(source.group) ?? [], source]);
97
+ }
98
+ return out;
99
+ };
100
+ const byAsset = /* @__PURE__ */ new Map();
101
+ for (const { main, reserve, reserveFeed, notes } of positions) {
102
+ const mainFeed = feedOf(main);
103
+ const before = require_permissionless_api_oracles_score_formula.finalPrice(base.get(mainFeed) ?? null, reserveFeed ? base.get(reserveFeed) ?? null : void 0);
104
+ if (before === null || before <= 0n) {
105
+ logger?.warn(`feed ${mainFeed} of chain ${chainId} does not answer; ${main.tokenSymbol ?? main.token} in ${main.marketName ?? main.market} is not scored`);
106
+ continue;
107
+ }
108
+ const onMain = groupsOf(mainFeed);
109
+ const onReserve = groupsOf(reserveFeed);
110
+ const impacts = [.../* @__PURE__ */ new Set([...onMain.keys(), ...onReserve.keys()])].map((group) => {
111
+ const under = stressed.get(group) ?? /* @__PURE__ */ new Map();
112
+ const after = require_permissionless_api_oracles_score_formula.finalPrice(under.get(mainFeed) ?? null, reserveFeed ? under.get(reserveFeed) ?? null : void 0);
113
+ const factor = require_permissionless_api_oracles_score_formula.factorOf(before, after);
114
+ const underlying = underlyingOf(main);
115
+ const debtBefore = underlying ? base.get(underlying) ?? null : null;
116
+ const debtFactor = debtBefore === null || debtBefore <= 0n || !underlying ? null : require_permissionless_api_oracles_score_formula.factorOf(debtBefore, under.get(underlying) ?? null);
117
+ const ratioFactor = factor === null || debtFactor === null || debtFactor === 0 ? null : factor / debtFactor;
118
+ const members = [...onMain.get(group) ?? [], ...onReserve.get(group) ?? []];
119
+ return {
120
+ group,
121
+ identified: members.every((source) => source.identified),
122
+ feeds: [...new Set(members.map((source) => source.description))],
123
+ reaches: onMain.has(group) ? onReserve.has(group) ? "both" : "main" : "reserve",
124
+ factor,
125
+ ratioFactor,
126
+ score: require_permissionless_api_oracles_score_formula.scoreOfFactor(factor)
127
+ };
128
+ });
129
+ const unverified = reserveFeed !== void 0 && impacts.some((impact) => !impact.identified && impact.reaches !== "both");
130
+ const side = (slot) => ({
131
+ feed: feedOf(slot),
132
+ name: slot.priceFeedName,
133
+ contractType: nodes.get(feedOf(slot))?.contractType ?? "",
134
+ sources: [...groupsOf(feedOf(slot)).keys()]
135
+ });
49
136
  const asset = main.token.toLowerCase();
50
137
  const entry = byAsset.get(asset) ?? {
51
138
  symbol: main.tokenSymbol,
52
139
  markets: []
53
140
  };
54
141
  byAsset.set(asset, entry);
55
- const mainNode = nodes.get(feedOf(main));
56
- if (!mainNode) continue;
57
- if (mainNode.contractType === "PRICE_FEED::ZERO") continue;
58
- const side = (slot) => ({
59
- feed: {
60
- feed: feedOf(slot),
61
- name: slot.priceFeedName,
62
- contractType: nodes.get(feedOf(slot))?.contractType ?? ""
63
- },
64
- sources: sourcesOf(feedOf(slot))
65
- });
66
- entry.markets.push(require_permissionless_api_oracles_score_formula.scoreMarket({
142
+ entry.markets.push({
67
143
  market: main.market,
68
144
  marketName: main.marketName,
69
145
  marketConfigurator: main.marketConfigurator,
70
- curatorName: main.curatorName
71
- }, side(main), reserve ? side(reserve) : null));
146
+ curatorName: main.curatorName,
147
+ main: side(main),
148
+ reserve: reserve ? side(reserve) : null,
149
+ hasReserve: reserveFeed !== void 0,
150
+ price: Number((0, viem.formatUnits)(before, 8)),
151
+ unverified,
152
+ notes,
153
+ ...require_permissionless_api_oracles_score_formula.worstOf(impacts)
154
+ });
72
155
  }
73
156
  return [...byAsset].map(([asset, { symbol, markets }]) => {
74
157
  const sorted = markets.sort((a, b) => a.score - b.score);
@@ -14,6 +14,7 @@ exports.perturb = require_permissionless_api_oracles_stress_override.perturb;
14
14
  exports.rateStub = require_permissionless_api_oracles_stress_override.rateStub;
15
15
  exports.readForest = require_permissionless_api_oracles_stress_run.readForest;
16
16
  exports.readRateTargets = require_permissionless_api_oracles_stress_run.readRateTargets;
17
+ exports.readUnder = require_permissionless_api_oracles_stress_run.readUnder;
17
18
  exports.roundDataStub = require_permissionless_api_oracles_stress_override.roundDataStub;
18
19
  exports.runStressTest = require_permissionless_api_oracles_stress_run.runStressTest;
19
20
  exports.scoreGroup = require_permissionless_api_oracles_stress_score.scoreGroup;
@@ -161,8 +161,10 @@ async function readRateTargets(client, feeds) {
161
161
  * scenario rather than a round trip per feed. A feed that reverts comes back
162
162
  * `null`, which is an outcome and not an error.
163
163
  */
164
- async function readUnder(client, feeds, sources, multiplier, updatedAt) {
165
- const overrides = require_permissionless_api_oracles_stress_override.groupOverride(sources, multiplier, updatedAt);
164
+ async function readUnder(client, feeds, sources, multiplier, updatedAt, freshen = []) {
165
+ const driven = require_permissionless_api_oracles_stress_override.groupOverride(sources, multiplier, updatedAt);
166
+ const taken = new Set(driven.map((override) => override.address.toLowerCase()));
167
+ const overrides = [...require_permissionless_api_oracles_stress_override.groupOverride(freshen, 1, updatedAt).filter((override) => !taken.has(override.address.toLowerCase())), ...driven];
166
168
  const results = await client.multicall({
167
169
  contracts: feeds.map((address) => ({
168
170
  address,
@@ -429,4 +431,5 @@ exports.DEFAULT_SCENARIOS = DEFAULT_SCENARIOS;
429
431
  exports.RATE_FEED_TYPE = RATE_FEED_TYPE;
430
432
  exports.readForest = readForest;
431
433
  exports.readRateTargets = readRateTargets;
434
+ exports.readUnder = readUnder;
432
435
  exports.runStressTest = runStressTest;
@@ -33,6 +33,14 @@ var BytecodeRepositoryContract = class BytecodeRepositoryContract extends requir
33
33
  async getLatestVersion(type_) {
34
34
  return await this.contract.read.getLatestVersion([(0, viem.stringToHex)(type_, { size: 32 })]);
35
35
  }
36
+ /**
37
+ * Returns the latest allowed patch version of the contract type within given minor version
38
+ * @throws if no bytecode of this contract type and minor version is allowed
39
+ */
40
+ async getLatestPatchVersion(type_, minorVersion) {
41
+ const version = await this.contract.read.getLatestPatchVersion([(0, viem.stringToHex)(type_, { size: 32 }), BigInt(minorVersion)]);
42
+ return Number(version);
43
+ }
36
44
  async getAllowedBytecodeHash(type_, version) {
37
45
  return await this.contract.read.getAllowedBytecodeHash([(0, viem.stringToHex)(type_, { size: 32 }), BigInt(version)]);
38
46
  }
@@ -6,8 +6,8 @@ require("../../../onchain/index.js");
6
6
  const require_permissionless_bindings_bytecode_repository = require("../bytecode-repository.js");
7
7
  require("../../deployment/addresses.js");
8
8
  const require_permissionless_bindings_treasury_splitter = require("../treasury-splitter.js");
9
- const require_abi_governance_governor = require("../../../abi/governance/governor.js");
10
9
  const require_permissionless_bindings_market_configurator = require("../market-configurator.js");
10
+ const require_abi_governance_governor = require("../../../abi/governance/governor.js");
11
11
  const require_permissionless_bindings_governance_batches_chain = require("./batches-chain.js");
12
12
  let viem = require("viem");
13
13
  let viem_utils = require("viem/utils");
@@ -10,10 +10,11 @@ const require_permissionless_bindings_router_routing_manager = require("./router
10
10
  require("./router/index.js");
11
11
  const require_permissionless_bindings_treasury_splitter = require("./treasury-splitter.js");
12
12
  const require_permissionless_bindings_instance_manager = require("./instance-manager.js");
13
- const require_permissionless_bindings_market_configurator_factory = require("./market-configurator-factory.js");
14
- const require_permissionless_bindings_cross_chain_multisig = require("./cross-chain-multisig.js");
15
13
  const require_permissionless_bindings_types = require("./types.js");
16
14
  const require_permissionless_bindings_market_configurator = require("./market-configurator.js");
15
+ const require_permissionless_bindings_kill_switch_proxy = require("./kill-switch-proxy.js");
16
+ const require_permissionless_bindings_market_configurator_factory = require("./market-configurator-factory.js");
17
+ const require_permissionless_bindings_cross_chain_multisig = require("./cross-chain-multisig.js");
17
18
  const require_permissionless_bindings_governance_governor = require("./governance/governor.js");
18
19
  const require_permissionless_bindings_governance_timelock = require("./governance/timelock.js");
19
20
  require("./governance/index.js");
@@ -23,6 +24,9 @@ exports.BytecodeRepositoryContract = require_permissionless_bindings_bytecode_re
23
24
  exports.CrossChainMultisigContract = require_permissionless_bindings_cross_chain_multisig.CrossChainMultisigContract;
24
25
  exports.GovernorContract = require_permissionless_bindings_governance_governor.GovernorContract;
25
26
  exports.InstanceManagerContract = require_permissionless_bindings_instance_manager.InstanceManagerContract;
27
+ exports.KILL_SWITCH_PROXY_MINOR_VERSION = require_permissionless_bindings_kill_switch_proxy.KILL_SWITCH_PROXY_MINOR_VERSION;
28
+ exports.KillSwitchProxyContract = require_permissionless_bindings_kill_switch_proxy.KillSwitchProxyContract;
29
+ exports.KillSwitchProxyNotAllowedError = require_permissionless_bindings_kill_switch_proxy.KillSwitchProxyNotAllowedError;
26
30
  exports.MarketConfiguratorContract = require_permissionless_bindings_market_configurator.MarketConfiguratorContract;
27
31
  exports.MarketConfiguratorFactoryContract = require_permissionless_bindings_market_configurator_factory.MarketConfiguratorFactoryContract;
28
32
  exports.PriceFeedStoreContract = require_permissionless_bindings_price_feed_store.PriceFeedStoreContract;
@@ -31,4 +35,5 @@ exports.TimeLockContract = require_permissionless_bindings_governance_timelock.T
31
35
  exports.TokenCompressorContract = require_permissionless_bindings_compressors_token_compressor.TokenCompressorContract;
32
36
  exports.TreasurySplitterContract = require_permissionless_bindings_treasury_splitter.TreasurySplitterContract;
33
37
  exports.WithdrawalCompressorContract = require_permissionless_bindings_compressors_withdrawal_compressor.WithdrawalCompressorContract;
38
+ exports.killSwitchProxySalt = require_permissionless_bindings_kill_switch_proxy.killSwitchProxySalt;
34
39
  exports.priceFeedSetupParams = require_permissionless_bindings_pricefeeds_index.priceFeedSetupParams;
@@ -0,0 +1,188 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_onchain_utils_json = require("../../onchain/utils/json.js");
3
+ const require_onchain_base_BaseContract = require("../../onchain/base/BaseContract.js");
4
+ require("../../onchain/index.js");
5
+ const require_permissionless_utils_literals = require("../utils/literals.js");
6
+ const require_abi_310_iKillSwitchProxy = require("../../abi/310/iKillSwitchProxy.js");
7
+ const require_permissionless_bindings_market_configurator = require("./market-configurator.js");
8
+ let viem = require("viem");
9
+ //#region src/permissionless/bindings/kill-switch-proxy.ts
10
+ const abi = require_abi_310_iKillSwitchProxy.iKillSwitchProxyAbi;
11
+ /**
12
+ * Minor version of kill switch proxy, the latest allowed patch of it is deployed
13
+ */
14
+ const KILL_SWITCH_PROXY_MINOR_VERSION = 310;
15
+ /**
16
+ * Salt of kill switch proxy deployed together with market configurator,
17
+ * makes each curator's market configurator get its own proxy
18
+ */
19
+ function killSwitchProxySalt(curatorName) {
20
+ return (0, viem.keccak256)((0, viem.toHex)(curatorName));
21
+ }
22
+ /**
23
+ * Thrown when bytecode repository has no allowed kill switch proxy bytecode,
24
+ * so its address can't be computed and it can't be deployed
25
+ */
26
+ var KillSwitchProxyNotAllowedError = class extends viem.BaseError {
27
+ name = "KillSwitchProxyNotAllowedError";
28
+ bytecodeRepository;
29
+ constructor(bytecodeRepository) {
30
+ super(`${require_permissionless_utils_literals.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."] });
31
+ this.bytecodeRepository = bytecodeRepository;
32
+ }
33
+ };
34
+ /**
35
+ * Kill switch proxy forwards calls of its `caller` via `proxyCall` until `owner` kills it.
36
+ * It is used as market configurator's emergency admin, so that emergency powers
37
+ * can be revoked instantly without going through the timelock.
38
+ */
39
+ var KillSwitchProxyContract = class KillSwitchProxyContract extends require_onchain_base_BaseContract.BaseContract {
40
+ constructor(addr, client) {
41
+ super({ client }, {
42
+ abi,
43
+ addr,
44
+ name: "KillSwitchProxy"
45
+ });
46
+ }
47
+ /**
48
+ * Encodes `constructor(address _owner, address _caller)` params
49
+ * @throws if any address is zero or owner equals caller (constructor reverts in that case)
50
+ */
51
+ static encodeConstructorParams(args) {
52
+ const { owner, caller } = args;
53
+ if ((0, viem.isAddressEqual)(owner, viem.zeroAddress) || (0, viem.isAddressEqual)(caller, viem.zeroAddress)) throw new Error(`${require_permissionless_utils_literals.KILL_SWITCH_PROXY} owner and caller must be non-zero`);
54
+ if ((0, viem.isAddressEqual)(owner, caller)) throw new Error(`${require_permissionless_utils_literals.KILL_SWITCH_PROXY} owner must differ from caller ${caller}, provide another kill switch owner`);
55
+ const [constructorAbi] = abi;
56
+ return (0, viem.encodeAbiParameters)(constructorAbi.inputs, [owner, caller]);
57
+ }
58
+ /**
59
+ * Returns whether some patch of kill switch proxy v3.10 is allowed in bytecode repository
60
+ */
61
+ static async isAvailable(bcr) {
62
+ try {
63
+ await KillSwitchProxyContract.#getVersion(bcr);
64
+ return true;
65
+ } catch (e) {
66
+ if (e instanceof KillSwitchProxyNotAllowedError) return false;
67
+ throw e;
68
+ }
69
+ }
70
+ /**
71
+ * Computes address of kill switch proxy and prepares its deployment via bytecode repository
72
+ * @param bcr - bytecode repository
73
+ * @param args.deployer - address that will send deployment transaction, it is mixed into the salt
74
+ * @param args.owner - address that can kill the proxy
75
+ * @param args.caller - address that can call through the proxy
76
+ * @param args.salt - deployment salt
77
+ * @throws {KillSwitchProxyNotAllowedError} if kill switch proxy is not allowed in bytecode repository
78
+ */
79
+ static async prepareDeploy(bcr, args) {
80
+ const { deployer, owner, caller, salt } = args;
81
+ const encodedParams = KillSwitchProxyContract.encodeConstructorParams({
82
+ owner,
83
+ caller
84
+ });
85
+ const version = await KillSwitchProxyContract.#getVersion(bcr);
86
+ const [isAlreadyDeployed, address] = await bcr.isAlreadyDeployedAddress({
87
+ contractType: require_permissionless_utils_literals.KILL_SWITCH_PROXY,
88
+ version,
89
+ encodedParams,
90
+ salt,
91
+ owner: deployer
92
+ });
93
+ return {
94
+ address,
95
+ version,
96
+ encodedParams,
97
+ salt,
98
+ isAlreadyDeployed,
99
+ isKilled: isAlreadyDeployed ? await new KillSwitchProxyContract(address, bcr.client).isKilled() : false,
100
+ tx: bcr.deployTx({
101
+ contractType: require_permissionless_utils_literals.KILL_SWITCH_PROXY,
102
+ version: BigInt(version),
103
+ encodedParams,
104
+ salt
105
+ })
106
+ };
107
+ }
108
+ static async #getVersion(bcr) {
109
+ try {
110
+ return await bcr.getLatestPatchVersion(require_permissionless_utils_literals.KILL_SWITCH_PROXY, 310);
111
+ } catch (e) {
112
+ const revert = e instanceof viem.BaseError ? e.walk((err) => err instanceof viem.ContractFunctionRevertedError) : null;
113
+ if (revert instanceof viem.ContractFunctionRevertedError && revert.data?.errorName === "VersionNotFoundException") throw new KillSwitchProxyNotAllowedError(bcr.address);
114
+ throw e;
115
+ }
116
+ }
117
+ async isKilled() {
118
+ return await this.contract.read.isKilled();
119
+ }
120
+ async state() {
121
+ const [caller, owner, isKilled] = await this.client.multicall({
122
+ allowFailure: false,
123
+ contracts: [
124
+ {
125
+ address: this.address,
126
+ abi,
127
+ functionName: "caller"
128
+ },
129
+ {
130
+ address: this.address,
131
+ abi,
132
+ functionName: "owner"
133
+ },
134
+ {
135
+ address: this.address,
136
+ abi,
137
+ functionName: "isKilled"
138
+ }
139
+ ],
140
+ batchSize: 0
141
+ });
142
+ return {
143
+ caller,
144
+ owner,
145
+ isKilled
146
+ };
147
+ }
148
+ /**
149
+ * Wraps transaction into `proxyCall`, must be sent by proxy's caller
150
+ */
151
+ proxyCallTx(tx) {
152
+ return this.createRawTx({
153
+ functionName: "proxyCall",
154
+ args: [tx.to, tx.callData],
155
+ description: tx.description ? `KillSwitchProxy.proxyCall(${tx.description})` : void 0
156
+ });
157
+ }
158
+ /**
159
+ * Permanently disables `proxyCall`, must be sent by proxy's owner
160
+ */
161
+ killTx() {
162
+ return this.createRawTx({ functionName: "kill" });
163
+ }
164
+ parseFunctionParams(params) {
165
+ const { functionName, args } = params;
166
+ switch (functionName) {
167
+ case "proxyCall": {
168
+ const [target, data] = args;
169
+ const decoded = new require_permissionless_bindings_market_configurator.MarketConfiguratorContract(target, this.client).parseFunctionData(data);
170
+ if (decoded.functionName.startsWith("Unknown function")) return {
171
+ target,
172
+ data
173
+ };
174
+ return {
175
+ target,
176
+ functionName: decoded.functionName,
177
+ data: require_onchain_utils_json.json_stringify(decoded.args)
178
+ };
179
+ }
180
+ default: return super.parseFunctionParams(params);
181
+ }
182
+ }
183
+ };
184
+ //#endregion
185
+ exports.KILL_SWITCH_PROXY_MINOR_VERSION = KILL_SWITCH_PROXY_MINOR_VERSION;
186
+ exports.KillSwitchProxyContract = KillSwitchProxyContract;
187
+ exports.KillSwitchProxyNotAllowedError = KillSwitchProxyNotAllowedError;
188
+ exports.killSwitchProxySalt = killSwitchProxySalt;
@@ -1,8 +1,13 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_onchain_base_BaseContract = require("../../onchain/base/BaseContract.js");
3
3
  require("../../onchain/index.js");
4
+ const require_permissionless_utils_literals = require("../utils/literals.js");
5
+ const require_permissionless_bindings_bytecode_repository = require("./bytecode-repository.js");
6
+ require("../deployment/addresses.js");
7
+ const require_abi_310_iMarketConfiguratorFactory = require("../../abi/310/iMarketConfiguratorFactory.js");
8
+ const require_permissionless_bindings_kill_switch_proxy = require("./kill-switch-proxy.js");
4
9
  //#region src/permissionless/bindings/market-configurator-factory.ts
5
- const abi = require("../../abi/310/iMarketConfiguratorFactory.js").iMarketConfiguratorFactoryAbi;
10
+ const abi = require_abi_310_iMarketConfiguratorFactory.iMarketConfiguratorFactoryAbi;
6
11
  var MarketConfiguratorFactoryContract = class extends require_onchain_base_BaseContract.BaseContract {
7
12
  constructor(addr, client) {
8
13
  super({ client }, {
@@ -22,6 +27,39 @@ var MarketConfiguratorFactoryContract = class extends require_onchain_base_BaseC
22
27
  ]
23
28
  });
24
29
  }
30
+ /**
31
+ * Builds transactions that deploy market configurator with kill switch proxy as its emergency admin:
32
+ * 1. kill switch proxy deployment via bytecode repository (skipped if already deployed)
33
+ * 2. market configurator creation with proxy as emergency admin
34
+ *
35
+ * Transactions must be sent in this order by `admin`, e.g. as one Safe batch.
36
+ * When `deployGovernor` is true, proxy also becomes governor's veto admin.
37
+ *
38
+ * @param args.admin - address that sends transactions, becomes market configurator admin
39
+ * @param args.emergencyAdmin - address that executes emergency actions through the proxy
40
+ * @param args.killSwitchOwner - address that can kill the proxy, defaults to `admin`
41
+ * @throws {KillSwitchProxyNotAllowedError} if kill switch proxy is not allowed in bytecode repository,
42
+ * use {@link createMarketConfiguratorTx} to deploy market configurator without it
43
+ */
44
+ async createMarketConfiguratorWithKillSwitchTxs(args) {
45
+ const { admin, emergencyAdmin, killSwitchOwner, ...rest } = args;
46
+ const bcr = new require_permissionless_bindings_bytecode_repository.BytecodeRepositoryContract("0x1cE2B1BE96a082b1b1539F80d5D8f82Ec06a0f9A", this.client);
47
+ const proxy = await require_permissionless_bindings_kill_switch_proxy.KillSwitchProxyContract.prepareDeploy(bcr, {
48
+ deployer: admin,
49
+ owner: killSwitchOwner ?? admin,
50
+ caller: emergencyAdmin,
51
+ salt: require_permissionless_bindings_kill_switch_proxy.killSwitchProxySalt(args.curatorName)
52
+ });
53
+ if (proxy.isKilled) throw new Error(`${require_permissionless_utils_literals.KILL_SWITCH_PROXY} ${proxy.address} is already deployed and killed`);
54
+ return {
55
+ killSwitchProxy: proxy.address,
56
+ isKillSwitchProxyDeployed: proxy.isAlreadyDeployed,
57
+ txs: [...proxy.isAlreadyDeployed ? [] : [proxy.tx], this.createMarketConfiguratorTx({
58
+ ...rest,
59
+ emergencyAdmin: proxy.address
60
+ })]
61
+ };
62
+ }
25
63
  async getMarketConfigurators() {
26
64
  return [...await this.contract.read.getMarketConfigurators()];
27
65
  }