solidstate-solidity
solidstate-solidity copied to clipboard
`diamondCut` utilities
The diamondCut
function is complex, and many users would benefit from a package to assist with adding/replacing/removing function selectors from diamond proxies.
Include a FacetCut
TS interface.
Just to summarize the problem statement here. The Diamond proxy is becoming an increasingly popular standard but managing deployments and upgrades is a challenging task with limited developer tooling available. Some of the key issues underlying are as follows:
- The
diamondCut
is a complex function with many failure modes, this requires a user to have a deep understanding of the function logic. - There is no standard practice for generating a
FacetCut
. Some users may choose toREPLACE
all existing selectors when upgrading aFacet
others may simplyREPLACE
only the selectors needed. A tool should not make this decision for the developer, but rather empower them to make the decision they choose. - There are no tools available that provide the selectors needed or verify the
FacetCut
once it has been structured.
Some goals I believe are worthwhile pursuing here is to provide a package or plugin for developers to create a valid FacetCut
. I have some ideas for implementation, however, I want to align on the problem statement and goals before proposing solutions.
Awesome PR and definitely a useful thing to add. Just wanted to link to Nick Mudge's diamond util's that he puts in his hardhat template repos. They've been useful when writing update/deploy scripts. The sample deploy script uses the Util Functions. Although I think @0xCourtney's work is great.
There are some cool features in the official sample utils, though. An example would be when I'm trying to implement solidstate libraries into my code. I'll often create a facet for a specific area, like an ERC1155Facet which isn't that different than the SolidStateERC1155Mock (but with no constructor). If I tried to add all selectors from that Facet it would error because DiamondLoupe's have to implement 165. So with the official sample tool you could do something like this in your deploy, using Nick's getSelectors method.
cut.push({
facetAddress: facet.address,
action: FacetCutAction.Add,
functionSelectors: getSelectors(facet).remove("supportsInterface(bytes4)"),
})
Thanks for the feedback, I would agree that having the getSelector
, get
and remove
functions are potential enhancements here. The getSelectors
and getSignatures
functions were actually copied from Nicks Diamond Util script which is similar to the ones you referenced.
Alternatively, you could also add the selector which you don't want into the exclude
list when adding a facet.
// async function addUnregisteredSelectors(diamond: Diamond, contracts: Contract[], exclude: string[] = []): Promise<FacetCut[]>
let facetCut = await addUnregisteredSelectors(Diamond, [Test1Facet, Test2Facet], ["0x01234567"]);