# Facets and methods

Gemforge excels at reconciling your current compiled facets and methods with what's on-chain in a Diamond and then making the necessary changes to bring the two into sync.

To ensure things run smoothly we recommend adhering to the following rules:

  • Each facet should be named <anything you want>Facet and be contained in its own file called <anything you want>Facet.sol in the same folder as all of your other facet files.
  • Function polymorphism is only supported for functions which don't have any struct parameters (read more).

# Directory tree

As seen in the demo repos, we recommend the following directory structure inside the folder which contains your contracts:

./facades # facades
./facets # facets
./generated # all code generated by Gemforge goes in here
./init # custom initialization code
./libs # shared code - libraries
./shared # shared code - base contract, structs, etc

This wil help keep your code neatly organized and easy to navigate.

# Core facets

You can override core facets with your own, in case you need to customize the default upgrade and ownership mechanisms.

Be very careful when doing this, however, as you do not want to introduce bugs which disrupt either of these critical mechanisms.

# Shared code - base contract

If one or more of your facets share common code it might be worth creating a base contract your facets inherit from. Note that this base contract should ideally be abstract and not follow the same naming scheme as your facet contracts so that Gemforge doesn't think its a facet.

For example:

// file: src/shared/FacetBase.sol
abstract contract FacetBase {
  function calculateVal(uint i) internal pure returns (uint) {
    return 123 + i;
  }
}

// file: src/facets/FirstFacet.sol
contract FirstFacet is FacetBase {
  function getVal1(uint a) external pure returns (uint) {
    return calculateVal(a);
  }
}

// file: src/facets/SecondFacet.sol
contract SecondFacet is FacetBase {
  function getVal2(uint b) external pure returns (uint) {
    return calculateVal(b);
  }
}

# Shared code - libraries

Another approach to sharing code between facets is to use non-deployed libraries:

// file: src/libs/LibCalculator.sol
library LibCalculator {
  function calculateVal(uint i) internal pure returns (uint) {
    return 123 + i;
  }
}

// file: src/facets/FirstFacet.sol
contract FirstFacet {
  function getVal1(uint a) external pure returns (uint) {
    return LibCalculator.calculateVal(a);
  }
}

// file: src/facets/SecondFacet.sol
contract SecondFacet {
  function getVal2(uint b) external pure returns (uint) {
    return LibCalculator.calculateVal(b);
  }
}

# Facades

Facades are a very powerful abstraction for deploying multiple ERC20s/NFTs/etc. all backed by a single Diamond instance:

The demo projects demonstrate facades using ERC20 tokens. For a more detailed explanation of the workings of facades please see this blog post.