I'm trying to implement EIP-2535. For now just testing, trying to delegate the functionality of EIP-165 ("supportsInterface") from the Diamond "proxy" to an existing ERC165Facet.sol.

The idea I have in mind is to create something with next code "layout".

   contract ERC165Common: Defines structs / state shared by DiamondProxy and ERC165Facet. 
   contract DiamondProxy is IERC165, ERC165Common ... 

   contract ERC165Facet  is IERC165, ERC165Common, ...  

I don't want to implement supportsInterface in DiamondProxy in order to force its fallback function to be invoked, that will in turn invoke the final implementation in ERC165Facet.

The problem is that if I don't implement the interface in DiamondProxy, the compiler forces me to declare the class as abstract, and so, I can NOT deploy it. If I implement it, then the fallback function is not invoked and I need to duplicate code, with supportsInterface(@DiamondProxy) forwarding through delegatecall to supportsInterface(@ERC165Facet).

I can also just remove the is IERC165 on DiamondProxy and then "cheat" clients to invoke the supportInterface at the deployed instance, but then I have to "hack" my client Dapp javascript code since web3.js is not able to properly generate client code from *json instances and actually. I also think that removing is IERC165 just to make things work is sort of a "patchy" solution that will cause other type of problems in the future.

Question: I am wondering whether there is some more straightforward/clean method to implement the diamond standard thanks to some Solidity "trick" I'm not aware or some other simple way to confront this problem.

  • Why do you want to implement it from scratch? I'm sure that Nick (the author of the diamond pattern) has many tutorials/ code snippets shared on the Internet. Nov 17, 2021 at 11:57
  • @Paul Razvan Berg. Not sure what do you mean. In fact I read the tutorials and code samples, but I now want to transform a "sort-of-complex" already existing smart-contract into a proxy contract compliant with ERC-2535, so that it will become a Diamon (proxy) contract supported by facet implementations. Maybe I'm taking the wrong approach. ¿?
    – earizon
    Nov 17, 2021 at 13:13
  • 1
    @earizon You can look at how the diamond-3-hardhat implementation implements ERC165 using a facet. It does it in the DiamondLoupeFacet.sol facet. There is no need to make the diamond proxy inherit IERC165. github.com/mudgen/diamond-3-hardhat/blob/main/contracts/facets/…
    – mudgen
    Nov 18, 2021 at 0:52
  • @mudge. In the end it looks it was much more simple that I though. I was using truffle APIs That API is "too much" automated and do NOT allow for for simple tricks (in web3.js API) like (or maybe it does my it's not obvious to me): jsContractObject = new web3.eth.Contract( ERC165Facet.abi , diamond.address ) This alone solves the problem I had allowing me to remove the dependency on interfaces for the the proxy diamond.
    – earizon
    Nov 18, 2021 at 7:31
  • @earizon, that's great.
    – mudgen
    Nov 18, 2021 at 14:45

1 Answer 1


Answering myself:

  • Diamond proxy MUST NOT implement the interfaces.

  • Client code using contract-like code-style to build the transaction (vs building them manually) need to instantiate the contract-like client object in a way similar to:

    erc165Facet    = await ERC165Facet.deployed()                                                                                 
    diamond        = await Diamond.deployed()
    jsDiamonObject = new web3.eth.Contract(ERC165Facet.abi, diamond.address)

The way to build the diamonObject in client apps can be slightly more tricky with other libraries. (truffle, web3j, C#,...)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.