@diamondslab/diamonds 1.3.2 → 1.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.
- package/CHANGELOG.md +43 -0
- package/LICENSE +21 -0
- package/README.md +214 -369
- package/dist/cli/diamond-abi-cli.d.ts +3 -0
- package/dist/cli/diamond-abi-cli.d.ts.map +1 -0
- package/dist/cli/diamond-abi-cli.js +377 -0
- package/dist/cli/diamond-abi-cli.js.map +1 -0
- package/dist/resolution/index.d.ts +2 -0
- package/dist/resolution/index.d.ts.map +1 -0
- package/dist/resolution/index.js +18 -0
- package/dist/resolution/index.js.map +1 -0
- package/dist/resolution/selectorResolution.d.ts +65 -0
- package/dist/resolution/selectorResolution.d.ts.map +1 -0
- package/dist/resolution/selectorResolution.js +170 -0
- package/dist/resolution/selectorResolution.js.map +1 -0
- package/dist/strategies/BaseDeploymentStrategy.d.ts.map +1 -1
- package/dist/strategies/BaseDeploymentStrategy.js +15 -156
- package/dist/strategies/BaseDeploymentStrategy.js.map +1 -1
- package/dist/utils/signer.d.ts.map +1 -1
- package/dist/utils/signer.js +11 -2
- package/dist/utils/signer.js.map +1 -1
- package/package.json +11 -5
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.computeFacetSelectors = computeFacetSelectors;
|
|
4
|
+
exports.resolveFunctionSelectorRegistry = resolveFunctionSelectorRegistry;
|
|
5
|
+
const ethers_1 = require("ethers");
|
|
6
|
+
const types_1 = require("../types");
|
|
7
|
+
/**
|
|
8
|
+
* Compute a facet's candidate selectors: its raw ABI selectors **minus `deployExclude`**.
|
|
9
|
+
*
|
|
10
|
+
* `deployInclude` is **additive** (INV-3, M2-E1) — it does NOT reduce the candidate set; a facet keeps
|
|
11
|
+
* its other selectors. The override (force-ownership over a higher-priority facet) and the additive
|
|
12
|
+
* priority resolution both happen in `resolveFunctionSelectorRegistry`. Pure.
|
|
13
|
+
*
|
|
14
|
+
* @param facetSelectors the facet's raw ABI function selectors (4-byte, `0x…`)
|
|
15
|
+
* @param _deployInclude the facet's `deployInclude` signatures — accepted for API symmetry; additive
|
|
16
|
+
* (not used to filter the candidate set)
|
|
17
|
+
* @param deployExclude function signatures to remove
|
|
18
|
+
* @returns the candidate selector list (a new array; the input is not mutated)
|
|
19
|
+
*/
|
|
20
|
+
function computeFacetSelectors(facetSelectors, _deployInclude, deployExclude) {
|
|
21
|
+
const result = [...facetSelectors];
|
|
22
|
+
// Apply deployExclude (removal) only. deployInclude is additive — it does not filter here.
|
|
23
|
+
for (const excludeSelector of deployExclude) {
|
|
24
|
+
const selectorToExclude = ethers_1.ethers.id(excludeSelector).slice(0, 10);
|
|
25
|
+
const index = result.indexOf(selectorToExclude);
|
|
26
|
+
if (index !== -1) {
|
|
27
|
+
result.splice(index, 1);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return result;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Resolve ownership of every function selector across the newly-deployed facets and write
|
|
34
|
+
* the result (`Add`/`Replace`/`Remove`/`Deployed` actions) into `registry` **in place**.
|
|
35
|
+
* Pure — no Hardhat/provider. Extracted verbatim from
|
|
36
|
+
* `BaseDeploymentStrategy.updateFunctionSelectorRegistryTasks`.
|
|
37
|
+
*/
|
|
38
|
+
function resolveFunctionSelectorRegistry(args) {
|
|
39
|
+
const { registry, newDeployedFacets, facetNames } = args;
|
|
40
|
+
const zeroAddress = ethers_1.ethers.ZeroAddress;
|
|
41
|
+
const newDeployedFacetsByPriority = Object.entries(newDeployedFacets).sort(([, a], [, b]) => (a.priority || 1000) - (b.priority || 1000));
|
|
42
|
+
for (const [newFacetName, newFacetData] of newDeployedFacetsByPriority) {
|
|
43
|
+
const currentFacetAddress = newFacetData.address;
|
|
44
|
+
const priority = newFacetData.priority;
|
|
45
|
+
const includeFuncSelectors = newFacetData.deployInclude || [];
|
|
46
|
+
const excludeFuncSelectors = newFacetData.deployExclude || [];
|
|
47
|
+
// Convert function signatures to selectors
|
|
48
|
+
const includeFuncSelectorsAsSelectors = includeFuncSelectors.map((sig) => ethers_1.ethers.id(sig).slice(0, 10));
|
|
49
|
+
const excludeFuncSelectorsAsSelectors = excludeFuncSelectors.map((sig) => ethers_1.ethers.id(sig).slice(0, 10));
|
|
50
|
+
// Initialize funcSelectors if not present
|
|
51
|
+
if (!newFacetData.funcSelectors) {
|
|
52
|
+
newFacetData.funcSelectors = [];
|
|
53
|
+
}
|
|
54
|
+
const functionSelectors = newFacetData.funcSelectors;
|
|
55
|
+
/* ------------------ Exclusion Filter ------------------ */
|
|
56
|
+
for (const excludeFuncSelector of excludeFuncSelectorsAsSelectors) {
|
|
57
|
+
// remove from the facets functionSelectors
|
|
58
|
+
if (functionSelectors.includes(excludeFuncSelector)) {
|
|
59
|
+
functionSelectors.splice(functionSelectors.indexOf(excludeFuncSelector), 1);
|
|
60
|
+
}
|
|
61
|
+
// update action to remove if excluded from registry where a previous deployment associated with facetname
|
|
62
|
+
if (registry.has(excludeFuncSelector) &&
|
|
63
|
+
registry.get(excludeFuncSelector)?.facetName === newFacetName) {
|
|
64
|
+
const existing = registry.get(excludeFuncSelector);
|
|
65
|
+
if (existing?.facetName === newFacetName) {
|
|
66
|
+
registry.set(excludeFuncSelector, {
|
|
67
|
+
priority: priority,
|
|
68
|
+
// EIP-2535: a Remove cut MUST use address(0) (M3-E2 fix for M3-E1 S-3 —
|
|
69
|
+
// was currentFacetAddress, which reverts on-chain on deployExclude-on-upgrade).
|
|
70
|
+
address: zeroAddress,
|
|
71
|
+
action: types_1.RegistryFacetCutAction.Remove,
|
|
72
|
+
facetName: newFacetName,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/* ------------------ Inclusion Override Filter ------------------ */
|
|
78
|
+
for (const includeFuncSelector of includeFuncSelectorsAsSelectors) {
|
|
79
|
+
const existingEntry = registry.get(includeFuncSelector);
|
|
80
|
+
if (existingEntry?.address &&
|
|
81
|
+
existingEntry.address !== currentFacetAddress &&
|
|
82
|
+
existingEntry.action !== types_1.RegistryFacetCutAction.Add) {
|
|
83
|
+
// Selector already registered/deployed at a different facet address — a selector moved
|
|
84
|
+
// facets, or a redeployed facet at a new address (the upgrade case; verified M3-E1 S-1).
|
|
85
|
+
// Reconcile -> Replace, not Add (which would revert "Can't add function that already
|
|
86
|
+
// exists"). Subsumes the removed dead higherPrioritySplit branch (M3-E3).
|
|
87
|
+
registry.set(includeFuncSelector, {
|
|
88
|
+
priority: priority,
|
|
89
|
+
address: currentFacetAddress,
|
|
90
|
+
action: types_1.RegistryFacetCutAction.Replace,
|
|
91
|
+
facetName: newFacetName,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
// Add to the registry
|
|
96
|
+
registry.set(includeFuncSelector, {
|
|
97
|
+
priority: priority,
|
|
98
|
+
address: currentFacetAddress,
|
|
99
|
+
action: types_1.RegistryFacetCutAction.Add,
|
|
100
|
+
facetName: newFacetName,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
// remove from the funcSels so it is not modified in Priority Resolution Pass
|
|
104
|
+
const existing = newDeployedFacets[newFacetName];
|
|
105
|
+
if (existing &&
|
|
106
|
+
existing.funcSelectors &&
|
|
107
|
+
existing.funcSelectors.includes(includeFuncSelector)) {
|
|
108
|
+
existing.funcSelectors.splice(existing.funcSelectors.indexOf(includeFuncSelector), 1);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/* ------------------ Replace Facet and Priority Resolution Pass ------------- */
|
|
112
|
+
for (const selector of functionSelectors) {
|
|
113
|
+
const existing = registry.get(selector);
|
|
114
|
+
if (existing) {
|
|
115
|
+
const existingPriority = existing.priority;
|
|
116
|
+
if (existing.facetName === newFacetName) {
|
|
117
|
+
// Same facet, update the address
|
|
118
|
+
registry.set(selector, {
|
|
119
|
+
priority: priority,
|
|
120
|
+
address: currentFacetAddress,
|
|
121
|
+
action: types_1.RegistryFacetCutAction.Replace,
|
|
122
|
+
facetName: newFacetName,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
else if (priority < existingPriority) {
|
|
126
|
+
// Current facet has higher priority, Replace it
|
|
127
|
+
registry.set(selector, {
|
|
128
|
+
priority: priority,
|
|
129
|
+
address: currentFacetAddress,
|
|
130
|
+
action: types_1.RegistryFacetCutAction.Replace,
|
|
131
|
+
facetName: newFacetName,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
// New selector, simply add
|
|
137
|
+
registry.set(selector, {
|
|
138
|
+
priority: priority,
|
|
139
|
+
address: currentFacetAddress,
|
|
140
|
+
action: types_1.RegistryFacetCutAction.Add,
|
|
141
|
+
facetName: newFacetName,
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
/* ---------------- Remove Old Function Selectors from facets -------------- */
|
|
146
|
+
// Set functionselectors with the newFacetName and still different address to Remove
|
|
147
|
+
for (const [selector, entry] of registry.entries()) {
|
|
148
|
+
if (entry.facetName === newFacetName && entry.address !== currentFacetAddress) {
|
|
149
|
+
registry.set(selector, {
|
|
150
|
+
priority: entry.priority,
|
|
151
|
+
address: zeroAddress,
|
|
152
|
+
action: types_1.RegistryFacetCutAction.Remove,
|
|
153
|
+
facetName: newFacetName,
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
// `Remove` function selectors for facets no longer in config (deleted facets)
|
|
159
|
+
for (const [selector, entry] of registry.entries()) {
|
|
160
|
+
if (!facetNames.includes(entry.facetName)) {
|
|
161
|
+
registry.set(selector, {
|
|
162
|
+
priority: entry.priority,
|
|
163
|
+
address: zeroAddress,
|
|
164
|
+
action: types_1.RegistryFacetCutAction.Remove,
|
|
165
|
+
facetName: entry.facetName,
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=selectorResolution.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"selectorResolution.js","sourceRoot":"","sources":["../../src/resolution/selectorResolution.ts"],"names":[],"mappings":"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","sourcesContent":["import { ethers } from 'ethers';\nimport {\n\tFunctionSelectorRegistryEntry,\n\tNewDeployedFacets,\n\tRegistryFacetCutAction,\n} from '../types';\n\n/**\n * Pure selector-resolution core for ERC-2535 diamond deployments.\n *\n * Extracted from `BaseDeploymentStrategy` (M1-E1) so the resolution semantics can be\n * unit-tested without a chain and later promoted into the shared core used by both the\n * deployment strategy and the planned pre-launch config validator.\n *\n * Lifted from the strategy in M1-E1 (behavior-preserving). Status of the original quirks:\n * - the deploy-time `deployInclude` whitelist — **REMOVED in M2-E1**: `deployInclude` is now\n * **additive** (INV-3); a facet keeps its other selectors (the override is resolved below);\n * - the inverted/dead `registryHigherPrioritySplit` (`entry.priority > priority`) — **REMOVED in\n * M3-E3**: it never matched a real conflict; the cases it nominally handled fall through to the\n * `5b2f7af` Replace branch with the identical result;\n * - the `5b2f7af` `Replace`-instead-of-`Add` branch — **verified correct (M3-E1 S-1)**; kept as-is.\n *\n * The module takes NO Hardhat/provider dependency (only `ethers` for selector math).\n */\n\n/** Map<functionSelector, registry entry>. Mirrors `Diamond.functionSelectorRegistry`. */\nexport type SelectorRegistry = Map<string, FunctionSelectorRegistryEntry>;\n\n/**\n * Reserved for M3 upgrade/redeploy reconciliation. Today, prior deployed state is carried\n * by the pre-populated `registry` (entries whose action is `Deployed`). Shape aligned to\n * `DeployedDiamondData.DeployedFacets` to minimise adapter code when M3 wires it in.\n */\nexport type PriorDeployedState = Record<\n\tstring,\n\t{ address?: string; funcSelectors?: string[]; version?: number }\n>;\n\n/**\n * Compute a facet's candidate selectors: its raw ABI selectors **minus `deployExclude`**.\n *\n * `deployInclude` is **additive** (INV-3, M2-E1) — it does NOT reduce the candidate set; a facet keeps\n * its other selectors. The override (force-ownership over a higher-priority facet) and the additive\n * priority resolution both happen in `resolveFunctionSelectorRegistry`. Pure.\n *\n * @param facetSelectors the facet's raw ABI function selectors (4-byte, `0x…`)\n * @param _deployInclude the facet's `deployInclude` signatures — accepted for API symmetry; additive\n * (not used to filter the candidate set)\n * @param deployExclude function signatures to remove\n * @returns the candidate selector list (a new array; the input is not mutated)\n */\nexport function computeFacetSelectors(\n\tfacetSelectors: string[],\n\t_deployInclude: string[],\n\tdeployExclude: string[],\n): string[] {\n\tconst result = [...facetSelectors];\n\n\t// Apply deployExclude (removal) only. deployInclude is additive — it does not filter here.\n\tfor (const excludeSelector of deployExclude) {\n\t\tconst selectorToExclude = ethers.id(excludeSelector).slice(0, 10);\n\t\tconst index = result.indexOf(selectorToExclude);\n\t\tif (index !== -1) {\n\t\t\tresult.splice(index, 1);\n\t\t}\n\t}\n\n\treturn result;\n}\n\nexport interface ResolveRegistryArgs {\n\t/** The selector registry to resolve into. Mutated IN PLACE (same contract as before). */\n\tregistry: SelectorRegistry;\n\t/** The newly-deployed facets (with addresses, priorities, include/exclude, funcSelectors). */\n\tnewDeployedFacets: NewDeployedFacets;\n\t/** All facet names currently in the deploy config (used to Remove deleted facets). */\n\tfacetNames: string[];\n\t/**\n\t * Reserved for M3 upgrade/redeploy reconciliation. Unused today — prior deployed state\n\t * is carried by the pre-populated `registry` (entries with action `Deployed`).\n\t */\n\tpriorDeployedState?: PriorDeployedState;\n}\n\n/**\n * Resolve ownership of every function selector across the newly-deployed facets and write\n * the result (`Add`/`Replace`/`Remove`/`Deployed` actions) into `registry` **in place**.\n * Pure — no Hardhat/provider. Extracted verbatim from\n * `BaseDeploymentStrategy.updateFunctionSelectorRegistryTasks`.\n */\nexport function resolveFunctionSelectorRegistry(args: ResolveRegistryArgs): void {\n\tconst { registry, newDeployedFacets, facetNames } = args;\n\tconst zeroAddress = ethers.ZeroAddress;\n\n\tconst newDeployedFacetsByPriority = Object.entries(newDeployedFacets).sort(\n\t\t([, a], [, b]) => (a.priority || 1000) - (b.priority || 1000),\n\t);\n\n\tfor (const [newFacetName, newFacetData] of newDeployedFacetsByPriority) {\n\t\tconst currentFacetAddress = newFacetData.address;\n\t\tconst priority: number = newFacetData.priority;\n\t\tconst includeFuncSelectors: string[] = newFacetData.deployInclude || [];\n\t\tconst excludeFuncSelectors: string[] = newFacetData.deployExclude || [];\n\n\t\t// Convert function signatures to selectors\n\t\tconst includeFuncSelectorsAsSelectors = includeFuncSelectors.map((sig) =>\n\t\t\tethers.id(sig).slice(0, 10),\n\t\t);\n\t\tconst excludeFuncSelectorsAsSelectors = excludeFuncSelectors.map((sig) =>\n\t\t\tethers.id(sig).slice(0, 10),\n\t\t);\n\n\t\t// Initialize funcSelectors if not present\n\t\tif (!newFacetData.funcSelectors) {\n\t\t\tnewFacetData.funcSelectors = [];\n\t\t}\n\t\tconst functionSelectors: string[] = newFacetData.funcSelectors;\n\n\t\t/* ------------------ Exclusion Filter ------------------ */\n\t\tfor (const excludeFuncSelector of excludeFuncSelectorsAsSelectors) {\n\t\t\t// remove from the facets functionSelectors\n\t\t\tif (functionSelectors.includes(excludeFuncSelector)) {\n\t\t\t\tfunctionSelectors.splice(functionSelectors.indexOf(excludeFuncSelector), 1);\n\t\t\t}\n\t\t\t// update action to remove if excluded from registry where a previous deployment associated with facetname\n\t\t\tif (\n\t\t\t\tregistry.has(excludeFuncSelector) &&\n\t\t\t\tregistry.get(excludeFuncSelector)?.facetName === newFacetName\n\t\t\t) {\n\t\t\t\tconst existing = registry.get(excludeFuncSelector);\n\t\t\t\tif (existing?.facetName === newFacetName) {\n\t\t\t\t\tregistry.set(excludeFuncSelector, {\n\t\t\t\t\t\tpriority: priority,\n\t\t\t\t\t\t// EIP-2535: a Remove cut MUST use address(0) (M3-E2 fix for M3-E1 S-3 —\n\t\t\t\t\t\t// was currentFacetAddress, which reverts on-chain on deployExclude-on-upgrade).\n\t\t\t\t\t\taddress: zeroAddress,\n\t\t\t\t\t\taction: RegistryFacetCutAction.Remove,\n\t\t\t\t\t\tfacetName: newFacetName,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/* ------------------ Inclusion Override Filter ------------------ */\n\t\tfor (const includeFuncSelector of includeFuncSelectorsAsSelectors) {\n\t\t\tconst existingEntry = registry.get(includeFuncSelector);\n\t\t\tif (\n\t\t\t\texistingEntry?.address &&\n\t\t\t\texistingEntry.address !== currentFacetAddress &&\n\t\t\t\texistingEntry.action !== RegistryFacetCutAction.Add\n\t\t\t) {\n\t\t\t\t// Selector already registered/deployed at a different facet address — a selector moved\n\t\t\t\t// facets, or a redeployed facet at a new address (the upgrade case; verified M3-E1 S-1).\n\t\t\t\t// Reconcile -> Replace, not Add (which would revert \"Can't add function that already\n\t\t\t\t// exists\"). Subsumes the removed dead higherPrioritySplit branch (M3-E3).\n\t\t\t\tregistry.set(includeFuncSelector, {\n\t\t\t\t\tpriority: priority,\n\t\t\t\t\taddress: currentFacetAddress,\n\t\t\t\t\taction: RegistryFacetCutAction.Replace,\n\t\t\t\t\tfacetName: newFacetName,\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\t// Add to the registry\n\t\t\t\tregistry.set(includeFuncSelector, {\n\t\t\t\t\tpriority: priority,\n\t\t\t\t\taddress: currentFacetAddress,\n\t\t\t\t\taction: RegistryFacetCutAction.Add,\n\t\t\t\t\tfacetName: newFacetName,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// remove from the funcSels so it is not modified in Priority Resolution Pass\n\t\t\tconst existing = newDeployedFacets[newFacetName];\n\t\t\tif (\n\t\t\t\texisting &&\n\t\t\t\texisting.funcSelectors &&\n\t\t\t\texisting.funcSelectors.includes(includeFuncSelector)\n\t\t\t) {\n\t\t\t\texisting.funcSelectors.splice(\n\t\t\t\t\texisting.funcSelectors.indexOf(includeFuncSelector),\n\t\t\t\t\t1,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t/* ------------------ Replace Facet and Priority Resolution Pass ------------- */\n\t\tfor (const selector of functionSelectors) {\n\t\t\tconst existing = registry.get(selector);\n\t\t\tif (existing) {\n\t\t\t\tconst existingPriority = existing.priority;\n\n\t\t\t\tif (existing.facetName === newFacetName) {\n\t\t\t\t\t// Same facet, update the address\n\t\t\t\t\tregistry.set(selector, {\n\t\t\t\t\t\tpriority: priority,\n\t\t\t\t\t\taddress: currentFacetAddress,\n\t\t\t\t\t\taction: RegistryFacetCutAction.Replace,\n\t\t\t\t\t\tfacetName: newFacetName,\n\t\t\t\t\t});\n\t\t\t\t} else if (priority < existingPriority) {\n\t\t\t\t\t// Current facet has higher priority, Replace it\n\t\t\t\t\tregistry.set(selector, {\n\t\t\t\t\t\tpriority: priority,\n\t\t\t\t\t\taddress: currentFacetAddress,\n\t\t\t\t\t\taction: RegistryFacetCutAction.Replace,\n\t\t\t\t\t\tfacetName: newFacetName,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// New selector, simply add\n\t\t\t\tregistry.set(selector, {\n\t\t\t\t\tpriority: priority,\n\t\t\t\t\taddress: currentFacetAddress,\n\t\t\t\t\taction: RegistryFacetCutAction.Add,\n\t\t\t\t\tfacetName: newFacetName,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t/* ---------------- Remove Old Function Selectors from facets -------------- */\n\t\t// Set functionselectors with the newFacetName and still different address to Remove\n\t\tfor (const [selector, entry] of registry.entries()) {\n\t\t\tif (entry.facetName === newFacetName && entry.address !== currentFacetAddress) {\n\t\t\t\tregistry.set(selector, {\n\t\t\t\t\tpriority: entry.priority,\n\t\t\t\t\taddress: zeroAddress,\n\t\t\t\t\taction: RegistryFacetCutAction.Remove,\n\t\t\t\t\tfacetName: newFacetName,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\t// `Remove` function selectors for facets no longer in config (deleted facets)\n\tfor (const [selector, entry] of registry.entries()) {\n\t\tif (!facetNames.includes(entry.facetName)) {\n\t\t\tregistry.set(selector, {\n\t\t\t\tpriority: entry.priority,\n\t\t\t\taddress: zeroAddress,\n\t\t\t\taction: RegistryFacetCutAction.Remove,\n\t\t\t\tfacetName: entry.facetName,\n\t\t\t});\n\t\t}\n\t}\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseDeploymentStrategy.d.ts","sourceRoot":"","sources":["../../src/strategies/BaseDeploymentStrategy.ts"],"names":[],"mappings":"AAAA,OAAO,iCAAiC,CAAC;AAIzC,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE1C,OAAO,EAGN,SAAS,EAKT,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"BaseDeploymentStrategy.d.ts","sourceRoot":"","sources":["../../src/strategies/BaseDeploymentStrategy.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,6 +10,7 @@ const ethers_1 = require("ethers");
|
|
|
10
10
|
const hardhat_1 = __importDefault(require("hardhat"));
|
|
11
11
|
const types_1 = require("../types");
|
|
12
12
|
const utils_1 = require("../utils");
|
|
13
|
+
const resolution_1 = require("../resolution");
|
|
13
14
|
class BaseDeploymentStrategy {
|
|
14
15
|
verbose;
|
|
15
16
|
constructor(verbose = false) {
|
|
@@ -131,26 +132,14 @@ class BaseDeploymentStrategy {
|
|
|
131
132
|
facetContract.interface.forEachFunction((func) => {
|
|
132
133
|
facetSelectors.push(func.selector);
|
|
133
134
|
});
|
|
134
|
-
// Apply deployExclude
|
|
135
|
+
// Apply deployExclude (removal) + deployInclude (whitelist) via the pure
|
|
136
|
+
// resolution core. Behavior-preserving (M1-E1); deployInclude stays a
|
|
137
|
+
// whitelist here — M2 makes it additive.
|
|
135
138
|
const excludeFuncSelectors = facetConfig.versions?.[upgradeVersionKey]?.deployExclude || [];
|
|
136
|
-
for (const excludeSelector of excludeFuncSelectors) {
|
|
137
|
-
const selectorToExclude = ethers_1.ethers.id(excludeSelector).slice(0, 10);
|
|
138
|
-
const index = facetSelectors.indexOf(selectorToExclude);
|
|
139
|
-
if (index !== -1) {
|
|
140
|
-
facetSelectors.splice(index, 1);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
// Apply deployInclude filter to only include specified selectors
|
|
144
139
|
const includeFuncSelectors = facetConfig.versions?.[upgradeVersionKey]?.deployInclude || [];
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
// Filter facetSelectors to only include the specified ones
|
|
149
|
-
const filteredSelectors = facetSelectors.filter((selector) => includeSelectors.includes(selector));
|
|
150
|
-
// Replace facetSelectors with filtered list
|
|
151
|
-
facetSelectors.length = 0;
|
|
152
|
-
facetSelectors.push(...filteredSelectors);
|
|
153
|
-
}
|
|
140
|
+
const resolvedFacetSelectors = (0, resolution_1.computeFacetSelectors)(facetSelectors, includeFuncSelectors, excludeFuncSelectors);
|
|
141
|
+
facetSelectors.length = 0;
|
|
142
|
+
facetSelectors.push(...resolvedFacetSelectors);
|
|
154
143
|
// Initializer function Registry
|
|
155
144
|
const deployInit = facetConfig.versions?.[upgradeVersionKey]?.deployInit || '';
|
|
156
145
|
const upgradeInit = facetConfig.versions?.[upgradeVersionKey]?.upgradeInit || '';
|
|
@@ -200,144 +189,14 @@ class BaseDeploymentStrategy {
|
|
|
200
189
|
this.updateFunctionSelectorRegistryTasks(diamond);
|
|
201
190
|
}
|
|
202
191
|
async updateFunctionSelectorRegistryTasks(diamond) {
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
const excludeFuncSelectors = newFacetData.deployExclude || [];
|
|
212
|
-
// Convert function signatures to selectors
|
|
213
|
-
const includeFuncSelectorsAsSelectors = includeFuncSelectors.map((sig) => ethers_1.ethers.id(sig).slice(0, 10));
|
|
214
|
-
const excludeFuncSelectorsAsSelectors = excludeFuncSelectors.map((sig) => ethers_1.ethers.id(sig).slice(0, 10));
|
|
215
|
-
// Initialize funcSelectors if not present
|
|
216
|
-
if (!newFacetData.funcSelectors) {
|
|
217
|
-
newFacetData.funcSelectors = [];
|
|
218
|
-
}
|
|
219
|
-
const functionSelectors = newFacetData.funcSelectors;
|
|
220
|
-
/* ------------------ Exclusion Filter ------------------ */
|
|
221
|
-
for (const excludeFuncSelector of excludeFuncSelectorsAsSelectors) {
|
|
222
|
-
// remove from the facets functionSelectors
|
|
223
|
-
if (functionSelectors.includes(excludeFuncSelector)) {
|
|
224
|
-
functionSelectors.splice(functionSelectors.indexOf(excludeFuncSelector), 1);
|
|
225
|
-
}
|
|
226
|
-
// update action to remove if excluded from registry where a previous deployment associated with facetname
|
|
227
|
-
if (registry.has(excludeFuncSelector) &&
|
|
228
|
-
registry.get(excludeFuncSelector)?.facetName === newFacetName) {
|
|
229
|
-
const existing = registry.get(excludeFuncSelector);
|
|
230
|
-
if (existing?.facetName === newFacetName) {
|
|
231
|
-
registry.set(excludeFuncSelector, {
|
|
232
|
-
priority: priority,
|
|
233
|
-
address: currentFacetAddress,
|
|
234
|
-
action: types_1.RegistryFacetCutAction.Remove,
|
|
235
|
-
facetName: newFacetName,
|
|
236
|
-
});
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
/* ------------ Higher Priority Split of Registry ------------------ */
|
|
241
|
-
const registryHigherPrioritySplit = Array.from(registry.entries())
|
|
242
|
-
.filter(([_, entry]) => entry.priority > priority)
|
|
243
|
-
.reduce((acc, [selector, entry]) => {
|
|
244
|
-
if (!acc[entry.facetName]) {
|
|
245
|
-
acc[entry.facetName] = [];
|
|
246
|
-
}
|
|
247
|
-
acc[entry.facetName].push(selector);
|
|
248
|
-
return acc;
|
|
249
|
-
}, {});
|
|
250
|
-
/* ------------------ Inclusion Override Filter ------------------ */
|
|
251
|
-
for (const includeFuncSelector of includeFuncSelectorsAsSelectors) {
|
|
252
|
-
// Force Replace if already registered by higher priority facet
|
|
253
|
-
const higherPriorityFacet = Object.keys(registryHigherPrioritySplit).find((facetName) => {
|
|
254
|
-
return registryHigherPrioritySplit[facetName].includes(includeFuncSelector);
|
|
255
|
-
});
|
|
256
|
-
if (higherPriorityFacet) {
|
|
257
|
-
registry.set(includeFuncSelector, {
|
|
258
|
-
priority: priority,
|
|
259
|
-
address: currentFacetAddress,
|
|
260
|
-
action: types_1.RegistryFacetCutAction.Replace,
|
|
261
|
-
facetName: newFacetName,
|
|
262
|
-
});
|
|
263
|
-
}
|
|
264
|
-
else {
|
|
265
|
-
// Add to the registry
|
|
266
|
-
registry.set(includeFuncSelector, {
|
|
267
|
-
priority: priority,
|
|
268
|
-
address: currentFacetAddress,
|
|
269
|
-
action: types_1.RegistryFacetCutAction.Add,
|
|
270
|
-
facetName: newFacetName,
|
|
271
|
-
});
|
|
272
|
-
}
|
|
273
|
-
// remove from the funcSels so it is not modified in Priority Resolution Pass
|
|
274
|
-
const existing = newDeployedFacets[newFacetName];
|
|
275
|
-
if (existing &&
|
|
276
|
-
existing.funcSelectors &&
|
|
277
|
-
existing.funcSelectors.includes(includeFuncSelector)) {
|
|
278
|
-
existing.funcSelectors.splice(existing.funcSelectors.indexOf(includeFuncSelector), 1);
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
/* ------------------ Replace Facet and Priority Resolution Pass ------------- */
|
|
282
|
-
for (const selector of functionSelectors) {
|
|
283
|
-
const existing = registry.get(selector);
|
|
284
|
-
if (existing) {
|
|
285
|
-
const existingPriority = existing.priority;
|
|
286
|
-
if (existing.facetName === newFacetName) {
|
|
287
|
-
// Same facet, update the address
|
|
288
|
-
registry.set(selector, {
|
|
289
|
-
priority: priority,
|
|
290
|
-
address: currentFacetAddress,
|
|
291
|
-
action: types_1.RegistryFacetCutAction.Replace,
|
|
292
|
-
facetName: newFacetName,
|
|
293
|
-
});
|
|
294
|
-
}
|
|
295
|
-
else if (priority < existingPriority) {
|
|
296
|
-
// Current facet has higher priority, Replace it
|
|
297
|
-
registry.set(selector, {
|
|
298
|
-
priority: priority,
|
|
299
|
-
address: currentFacetAddress,
|
|
300
|
-
action: types_1.RegistryFacetCutAction.Replace,
|
|
301
|
-
facetName: newFacetName,
|
|
302
|
-
});
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
else {
|
|
306
|
-
// New selector, simply add
|
|
307
|
-
registry.set(selector, {
|
|
308
|
-
priority: priority,
|
|
309
|
-
address: currentFacetAddress,
|
|
310
|
-
action: types_1.RegistryFacetCutAction.Add,
|
|
311
|
-
facetName: newFacetName,
|
|
312
|
-
});
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
/* ---------------- Remove Old Function Selectors from facets -------------- */
|
|
316
|
-
// Set functionselectors with the newFacetName and still different address to Remove
|
|
317
|
-
for (const [selector, entry] of registry.entries()) {
|
|
318
|
-
if (entry.facetName === newFacetName && entry.address !== currentFacetAddress) {
|
|
319
|
-
registry.set(selector, {
|
|
320
|
-
priority: entry.priority,
|
|
321
|
-
address: zeroAddress,
|
|
322
|
-
action: types_1.RegistryFacetCutAction.Remove,
|
|
323
|
-
facetName: newFacetName,
|
|
324
|
-
});
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
// `Remove` function selectors for facets no longer in config (deleted facets)
|
|
329
|
-
const facetsConfig = diamond.getDeployConfig().facets;
|
|
330
|
-
const facetNames = Object.keys(facetsConfig);
|
|
331
|
-
for (const [selector, entry] of registry.entries()) {
|
|
332
|
-
if (!facetNames.includes(entry.facetName)) {
|
|
333
|
-
registry.set(selector, {
|
|
334
|
-
priority: entry.priority,
|
|
335
|
-
address: zeroAddress,
|
|
336
|
-
action: types_1.RegistryFacetCutAction.Remove,
|
|
337
|
-
facetName: entry.facetName,
|
|
338
|
-
});
|
|
339
|
-
}
|
|
340
|
-
}
|
|
192
|
+
// Delegates to the pure resolution core (M1-E1). Behavior-preserving: the dead
|
|
193
|
+
// `higherPrioritySplit` and the `5b2f7af` Replace branch live there verbatim and are
|
|
194
|
+
// reconciled in M3. The registry Map is mutated in place, exactly as before.
|
|
195
|
+
(0, resolution_1.resolveFunctionSelectorRegistry)({
|
|
196
|
+
registry: diamond.functionSelectorRegistry,
|
|
197
|
+
newDeployedFacets: diamond.getNewDeployedFacets(),
|
|
198
|
+
facetNames: Object.keys(diamond.getDeployConfig().facets),
|
|
199
|
+
});
|
|
341
200
|
}
|
|
342
201
|
async postUpdateFunctionSelectorRegistry(diamond) {
|
|
343
202
|
if (this.verbose) {
|