In the dynamic realm of blockchain technology, the Ethereum Virtual Machine (EVM) stands as a vital platform, powering the development and execution of decentralized applications (dApps) and smart contracts. That said, the demand to address challenges of upgradability, gas efficiency, and modularity within the EVM ecosystem also grows more pressing.
This is where the Ethereum Improvement Proposal EIP 2535 Diamond Standard comes into play- an innovative solution that unlocks the potential for creating modular and easily upgradeable contracts.
Several protocols, including Aavegotchi, BarnBridge, DerivaDEX, and Oncyber, have already embraced this Diamond standard.
So, the main objective of this blog is to decode the Diamond Standard alongside underlining its advantages in building robust Dapps. Let’s get started.
An Evaluative Study on Diamond Standard Vs. Proxy Contracts
Smart contracts come with a core trait – immutability. And here’s where the upgrade proxy pattern becomes critical in addressing the challenge of dealing with the immutability to make updates in the smart contract.
To achieve this, it employs two contracts: a proxy contract and a logic contract.
A proxy contract is where the user interacts with and holds immutable data. It has a fallback function that captures function calls and utilizes delegatecall to transfer them to a secondary logic contract.
Now the logic can be defined separately from the data in the logic contract.
As said before, delegatecall executes functions from the logic contract within the context of the proxy contract. This enables logic changes without altering underlying data, accomplished by adding the logic contract’s address to the proxy contract.
While the proxy contract indeed facilitates upgradability, there are certain inherent limitations.
- As the data in the proxy contract remains unaltered, it is crucial to handle the data in the logic contract carefully.
- Logic contracts can easily reach the maximum 24kb contract size limit.
- The modular approach grants specific permission to upgrade a subset of existing functions which the proxy pattern doesn’t facilitate.
This is where the “Diamond” gains the upper hand. A Diamond contract differentiates functionality and storage into separate contracts. The Diamond standard enables controlling multiple implementation contracts(logic) through a single Diamond contract(resembling proxy).
This approach curtails the complexities of adding or removing functionality and other associated upgrade challenges.
Now, let’s explore the foundational components of Diamond standards underlying its operation.
Specifications of the EIP 2535 standard
In the context of Diamond(proxy) contracts, it involves employing logic smart contracts, often referred to as Facets, which are invoked through delegatecall calls.
Let’s first comprehend the concept of delegate call and facet.
A delegate call entails an external function invocation, wherein a diamond contract borrows code from another smart contract and aligns it with its own context—specifically, its individual state variables.
Facet
The Facet component in the diamond standard framework enables developers to organize their implementation logic into distinct solidity files, thus allowing for modularization and subsequent upgrades as required.
The advantage is that you can focus on updating specific segments of code without affecting the entirety of the smart contract and also do it in multiple facets.
They are deployed independently from the Diamond contract itself. The integration of Facets into the Diamond is facilitated through DiamondCut.
Any modifications to a Facet can be effortlessly executed by directing the contract to the respective Facet address. These addresses are efficiently managed through a mapping structure, SelectorToFacet.
The figure above symbolises the DiamondStorage Structs in Diamond. In this, you can observe func1 and func2 belongs to FacetA, funct3, func4 and func5 to FacetB, func6 and func7 to FacetC.
And this is how a Facet contract will look like
With these insights into Facets, we can now explore the execution of external functions within a Diamond contract.
DiamondCut
Essentially, the DiamondCut function allows adding or replacing functions in the diamond contract. In short, it is analogous to the “upgrade” feature, allowing you to update the mapping in diamond contracts to redirect to new destinations of function signatures or addresses.
This is how a DiamondCut interface will look like
DiamondStorage
Solidity automatically stores data in consecutive slots as defined by state variables. However, a specific storage slot can be explicitly designated using an assembly code. This ensures that the storage slot is uniquely positioned to prevent clashes with other facets. A practical approach to achieving this is by hashing the facet name.
Another alternative to this is AppStorage. This approach proves valuable when sharing state variables among facets dedicated to a particular project.
An example of Facet using DiamondStorage
DiamondLoupe
DiamondLoupe function effectively identifies the defined functions within the diamond. DiamondLoupe provides visibility into the specifics of Facets, function selectors, and facet addresses within the Diamond contract.
This is how the DiamondLoupe interface will be
Why Should we use diamonds?
- Organizing Contract Code and Data Efficiently: Diamonds allow you to modularize help in isolating functions and organize it for easier maintenance and upgrades.
- Contract Size Limitations: Unlike traditional contracts, diamonds do not face the 24KB maximum contract size limitation.
- Flexible Upgrade: Diamonds allow to make atomic changes such as adding, replacing, or removing features without disrupting their existing components.
- Gas efficiency: Having only the relevant facets or reducing the external function calls, you can optimise the gas costs cutting down unnecessary expenditures.
- Make multiple calls: This standard favours calling the implementation logic multiple times in the diamond contract.
Final Thoughts
Diamonds are now in the developing stage but come with an advantage for organising contract functionalities and modularization. With the development of more tools and frameworks supporting the Diamond standard, it is more likely to be used widely in the future.
For any contracts that you develop, having the code thoroughly revised by security experts adds extra points to its trustworthiness.
Get your projects audited right away by connecting with QuillAudits experts now!