EIP 2535: Diamonds, Multi-Facet Proxy
In Feb ‘20 Nick Mudge created the Diamond EIP, it was finalized in Oct ‘22. This proposal standardizes diamonds, which are modular smart contract systems that can be upgraded/extended after deployment, and have virtually no size limit.
What is a Diamond?
- A diamond is a smart contract, the address of the Diamond is used for software to interact with it.
- Internally a diamond uses a set of contracts called facets for its external functions.
- All state variable storage data is stored in a diamond, not in its facets.
- A facet is a contract whose external functions are added to a diamond for functionality.
- The external functions of facets can directly read and write data stored in a diamond.
- A diamond implements a fallback function using
delegatecallto route function calls to facets.
When to use a Diamond?
- You exceed the max size of a contract.
- You want to control complexity of multiple small contracts.
- You need or want greater control over when and what functions exist.
- Your development is incremental and your contracts will grow with your application.
- You want to organize your code with a diamond and facets.
- Diamonds are designed for tooling and user-interface software.
Why use a Diamond?
- Diamonds can be upgradeable or immutable.
- Diamonds overcome the maximum contract size limit of 24KB.
- Diamonds provide a single address with the functionality of multiple contracts (facets) that are independent from each other but can share internal functions, libraries and state variables.
- Diamonds can add, replace and remove multiple external functions atomically (in the same transaction).
- Diamonds can be large but modular because they are compartmented with facets.
- Diamonds are optimized to save gas, state variables are shared between facets.
- DAOs, multi-sig wallets, and other governance systems can be used to upgrade diamonds.
- Diamonds can be created from already deployed, existing onchain contracts.
- Diamonds enable zero, partial or full diamond immutability as desired, and when desired.
- Diamonds emit an event that shows what functions are added, replaced and removed.
- Increase trust over time by showing all changes made to a diamond.
- Upgrade diamonds to fix bugs, add functionality and implement new standards.
- Save gas by condensing contracts into a single diamond and accessing state variables directly.
- Save gas by converting external to internal functions, by sharing internal functions between facets.
- Save gas by creating external functions for gas-optimized specific use cases, such as bulk transfers.