Skip to content

Commit 5b75921

Browse files
committed
adds facet helpers
1 parent 51c7abf commit 5b75921

File tree

1 file changed

+98
-0
lines changed

1 file changed

+98
-0
lines changed

lib/diamonds.ts

+98
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import { Contract } from 'ethers';
2+
3+
export interface Facet {
4+
target: string;
5+
selectors: string[];
6+
}
7+
8+
enum FacetCutAction {
9+
Add,
10+
Replace,
11+
Remove,
12+
}
13+
14+
export interface FacetCut extends Facet {
15+
action: FacetCutAction;
16+
}
17+
18+
export function getContractSignatures(contract: Contract) {
19+
return Object.keys(contract.interface.functions);
20+
}
21+
22+
export function getContractSelectors(contract: Contract) {
23+
const signatures = getContractSignatures(contract);
24+
const selectors = signatures.reduce((acc: string[], val: string) => {
25+
acc.push(contract.interface.getSighash(val));
26+
return acc;
27+
}, []);
28+
29+
return selectors;
30+
}
31+
32+
export function selectorExistsInFacet(selector: string, facets: Facet[]) {
33+
for (const facet of facets) {
34+
if (facet.selectors.includes(selector)) return true;
35+
}
36+
37+
return false;
38+
}
39+
40+
export function printFacetCuts(
41+
target: string,
42+
selectors: string[],
43+
action: number = 0,
44+
) {
45+
return {
46+
target: target,
47+
action: action,
48+
selectors: selectors,
49+
};
50+
}
51+
52+
// attempts to add a selector, if selector already exists, function will throw
53+
export async function insertUnregisteredSelector(
54+
diamond: Contract,
55+
facets: Contract[],
56+
) {}
57+
58+
// adds selectors, if selector already exists function will update with new address
59+
export async function upsertSelectors(diamond: Contract, facets: Contract[]) {}
60+
61+
// removes registered selectors if they are not present in the contracts
62+
export async function removeRegisteredSelectors(
63+
diamond: Contract,
64+
contracts: Contract[],
65+
) {
66+
const registeredFacets: Facet[] = await diamond.facets();
67+
68+
let facets: Facet[] = [];
69+
contracts.forEach((contract) => {
70+
facets.push({
71+
target: contract.address,
72+
selectors: getContractSelectors(contract),
73+
});
74+
});
75+
76+
let facetCuts: FacetCut[] = [];
77+
// if registered selector is not found in the contracts then it should be removed from the diamond
78+
registeredFacets.forEach((registeredFacet) => {
79+
registeredFacet.selectors.forEach((selector) => {
80+
const target = registeredFacet.target;
81+
if (
82+
target !== diamond.address &&
83+
!selectorExistsInFacet(selector, facets)
84+
) {
85+
// TODO: Group removed selectors together in a single object
86+
facetCuts.push(
87+
printFacetCuts(
88+
registeredFacet.target,
89+
[selector],
90+
FacetCutAction.Remove,
91+
),
92+
);
93+
}
94+
});
95+
});
96+
97+
return facetCuts;
98+
}

0 commit comments

Comments
 (0)