@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.
- package/dist/cjs/abi/310/iKillSwitchProxy.js +130 -0
- package/dist/cjs/dev/AccountOpener.js +1 -1
- package/dist/cjs/dev/withdrawalUtils.js +1 -1
- package/dist/cjs/history/trace/extractTransfers.js +1 -1
- package/dist/cjs/onchain/accounts/CreditAccountsServiceV310.js +2 -2
- package/dist/cjs/onchain/accounts/liquidations/LiquidationsService.js +1 -1
- package/dist/cjs/onchain/accounts/withdrawal-compressor/RedemptionLoggerV310Contract.js +2 -1
- package/dist/cjs/onchain/accounts/withdrawal-compressor/WithdrawalCompressorV310Contract.js +2 -1
- package/dist/cjs/onchain/accounts/withdrawal-compressor/WithdrawalCompressorV311Contract.js +2 -1
- package/dist/cjs/onchain/accounts/withdrawal-compressor/WithdrawalCompressorV313Contract.js +1 -1
- package/dist/cjs/onchain/base/TokensMeta.js +3 -3
- package/dist/cjs/onchain/core/createAddressProvider.js +1 -1
- package/dist/cjs/onchain/market/adapters/contracts/AccountMigratorAdapterContract.js +1 -1
- package/dist/cjs/onchain/market/adapters/contracts/ERC4626AdapterContract.js +1 -1
- package/dist/cjs/onchain/market/credit/CreditFacadeV310BaseContract.js +1 -1
- package/dist/cjs/onchain/market/pool/PoolV310Contract.js +1 -1
- package/dist/cjs/onchain/market/rwa/createDegenNFT.js +1 -1
- package/dist/cjs/onchain/market/zapper/IETHZapperContract.js +2 -1
- package/dist/cjs/onchain/market/zapper/ZapperContract.js +1 -1
- package/dist/cjs/onchain/preview/preview/previewPoolPositionOperation.js +2 -2
- package/dist/cjs/onchain/utils/viem/simulateWithPriceUpdates.js +1 -1
- package/dist/cjs/permissionless/api/index.js +7 -3
- package/dist/cjs/permissionless/api/oracles/PermissionlessOracles.js +11 -11
- package/dist/cjs/permissionless/api/oracles/index.js +7 -3
- package/dist/cjs/permissionless/api/oracles/score/formula.js +44 -82
- package/dist/cjs/permissionless/api/oracles/score/index.js +6 -3
- package/dist/cjs/permissionless/api/oracles/score/run.js +129 -46
- package/dist/cjs/permissionless/api/oracles/stress/index.js +1 -0
- package/dist/cjs/permissionless/api/oracles/stress/run.js +5 -2
- package/dist/cjs/permissionless/bindings/bytecode-repository.js +8 -0
- package/dist/cjs/permissionless/bindings/governance/governor.js +1 -1
- package/dist/cjs/permissionless/bindings/index.js +7 -2
- package/dist/cjs/permissionless/bindings/kill-switch-proxy.js +188 -0
- package/dist/cjs/permissionless/bindings/market-configurator-factory.js +39 -1
- package/dist/cjs/permissionless/bindings/market-configurator.js +142 -0
- package/dist/cjs/permissionless/index.js +15 -5
- package/dist/cjs/permissionless/utils/index.js +1 -0
- package/dist/cjs/permissionless/utils/literals.js +2 -0
- package/dist/esm/abi/310/iKillSwitchProxy.js +129 -0
- package/dist/esm/permissionless/api/index.js +3 -3
- package/dist/esm/permissionless/api/oracles/PermissionlessOracles.js +11 -11
- package/dist/esm/permissionless/api/oracles/index.js +3 -3
- package/dist/esm/permissionless/api/oracles/score/formula.js +39 -80
- package/dist/esm/permissionless/api/oracles/score/index.js +2 -2
- package/dist/esm/permissionless/api/oracles/score/run.js +131 -48
- package/dist/esm/permissionless/api/oracles/stress/index.js +2 -2
- package/dist/esm/permissionless/api/oracles/stress/run.js +5 -3
- package/dist/esm/permissionless/bindings/bytecode-repository.js +8 -0
- package/dist/esm/permissionless/bindings/governance/governor.js +1 -1
- package/dist/esm/permissionless/bindings/index.js +4 -3
- package/dist/esm/permissionless/bindings/kill-switch-proxy.js +184 -0
- package/dist/esm/permissionless/bindings/market-configurator-factory.js +37 -0
- package/dist/esm/permissionless/bindings/market-configurator.js +143 -1
- package/dist/esm/permissionless/index.js +7 -6
- package/dist/esm/permissionless/utils/index.js +2 -2
- package/dist/esm/permissionless/utils/literals.js +2 -1
- package/dist/types/abi/310/iKillSwitchProxy.d.ts +114 -0
- package/dist/types/permissionless/api/index.d.ts +4 -4
- package/dist/types/permissionless/api/oracles/PermissionlessOracles.d.ts +11 -11
- package/dist/types/permissionless/api/oracles/index.d.ts +4 -4
- package/dist/types/permissionless/api/oracles/score/formula.d.ts +31 -38
- package/dist/types/permissionless/api/oracles/score/index.d.ts +3 -3
- package/dist/types/permissionless/api/oracles/score/run.d.ts +7 -4
- package/dist/types/permissionless/api/oracles/score/types.d.ts +50 -22
- package/dist/types/permissionless/api/oracles/stress/index.d.ts +2 -2
- package/dist/types/permissionless/api/oracles/stress/run.d.ts +17 -1
- package/dist/types/permissionless/bindings/bytecode-repository.d.ts +10 -1
- package/dist/types/permissionless/bindings/index.d.ts +4 -3
- package/dist/types/permissionless/bindings/kill-switch-proxy.d.ts +205 -0
- package/dist/types/permissionless/bindings/market-configurator-factory.d.ts +30 -0
- package/dist/types/permissionless/bindings/market-configurator.d.ts +30 -1
- package/dist/types/permissionless/bindings/types.d.ts +27 -0
- package/dist/types/permissionless/index.d.ts +8 -7
- package/dist/types/permissionless/utils/index.d.ts +2 -2
- package/dist/types/permissionless/utils/literals.d.ts +1 -0
- 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.
|
|
6
|
-
exports.
|
|
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.
|
|
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
|
-
*
|
|
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
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
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
|
|
36
|
-
const
|
|
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
|
|
43
|
-
|
|
44
|
-
|
|
32
|
+
const entry = slotsByPosition.get(key) ?? {};
|
|
33
|
+
entry[slot.reserve ? "reserve" : "main"] = slot;
|
|
34
|
+
slotsByPosition.set(key, entry);
|
|
45
35
|
}
|
|
46
|
-
const
|
|
47
|
-
for (const { main, reserve } of
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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 =
|
|
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
|
}
|