githubEdit

Diamond Pattern

Introduction

The diamond pattern is a modular smart contract system that can be updated after deployment, with no size limit. It has been proposed in the EIP-2535arrow-up-right the 22nd of February 2020.

Specifications

  • The main contract is called a diamond. This contract is like a proxy that delegates all calls to facets.

  • Facets are contracts or libraries that implements functions that can be called by the diamond.

  • A diamond is stateful, meaning that it can store data, meanwhile the facets are stateless. It can read & write to the storage of the diamond.

  • A special facet is the loupe facet. It provides introspection functions (functions that return information about the diamond and its facets).

  • A diamond can have multiple facets, and a facet can be used by multiple diamonds.

Two diamonds using the same two facets

Benefits

  • A single address for unlimited contract functionality;

  • Can exceed the 24KB current smart contract size limit;

  • Better organization of contract code and storage;

  • Better upgradeability;

  • A diamond can be immutable;

  • A diamond can reuse deployed contracts;

  • Simplified event handling.

Structure of a diamond

  • A diamond implements a mapping of function selectors to facets. It takes the first 4 bytes of the function call and uses it as a key to find the facet that implements the function.

Structure of a diamond
  • All diamonds must implement the IDiamond interface. This interface contains the event DiamondCut that must be emitted when any external function is added, replaced or removed.

  • All diamonds must implement the IDiamondLoupe interface. This interface contains functions that return information about the diamond and its facets.

  • Diamonds should implement the IDiamondCut interface, which contains the function diamondCut that is used to add, replace or remove facets.

How function calls work

  1. Caller call a function to the diamond

  2. The EVM checks that the caller function is defined in the diamond.

  3. If yes, the caller function is executed & the result is returned to the caller.

  4. If not, the fallback function of the diamond is executed. This function iterates through a mapping defined in the diamond. This mapping maps function selectors to the address of the facet which contains the definition of the caller function.

  5. If the caller function isn't defined in any facet of the diamond, the call is reverted.

  6. If it's defined, the diamond delegates the call to the corresponding facet.

  7. Once the caller function is executed in the facet, the result is returned to the diamond.

  8. Finally, the result is returned to the caller.

Diamond pattern call sequence diagram

References

Last updated