What is ERC-2535

What is a diamond?

Diamond is the more user friendly name for ERC-2535 (opens in a new tab) and it is an extension of a well-known solidity pattern called proxies. Diamonds are a way of writing smart contracts, with one contract (the diamond) at its heart. This diamond does not contain any code except the ability to call code of other contracts. This makes the contract effectively infinitely flexible and upgradable. Before diving deeper into Diamonds, you will first have to understand proxies.

Proxies

Data on the blockchain is immutable, and thus, so are smart contracts. However, sometimes the need to update contracts after their initial deployment arises, e.g., when a bug is discovered. Unfortunately, this means you would have to deploy a new smart contract to fix the bug, losing all of the data contained in your old smart contract in the process.

Proxies provide a solution for this limitation by separating the logic from the data, similar to the model-view-controller pattern in classical software engineering. The logic contract provides the functionality, while the data contract stores all of the values along with a pointer to the logic contract. When function calls are made to the data contract, it will forward them to the logic contract using a Solidity feature called delegatecall (opens in a new tab). A delegatecall does not execute the code on the data contract that is being called, but instead retrieves the code and executes it in the data contract. This means that the variable references in the logic contract will read the value of the same variable in the data contract instead and updates to these variables are also made in the data contract. When the logic needs to be updated, a new logic contract can be deployed and the owner of the proxy can change the variable of the logic contract pointer stored inside the data contract to the newly deployed logic contract. This way all variable values are retained, but all subsequent calls made to the contract use the new logic.

Diamonds

Diamonds, also known as "Multi-Facet Proxies" have significant differences compared to regular proxies. The key distinction lies in the fact that diamonds do not have a single logic contract like proxies do. Instead, diamonds can have numerous logic contracts known as facets, offering a high degree of flexibility.

A handy website that allows you to inspect and cut diamonds, developed by Nick Mudge, the creator of the diamond standard, can be found at https://louper.dev/ (opens in a new tab).

What is a Facet?

A facet is a smart contract containing the logic functions that can be called by the diamond. Facets are added, removed or replaced using the diamond cut function, which is explained in more detail in the diamond cut and loupe section. The name facet originates from the diamond industry, where it represents one face of a diamond.

Diamond storage

Diamonds also introduce changes related to storage, taking inspiration from ERC-1967 (opens in a new tab). This enhancement allows variable definitions to be stored in separate contracts. In regular proxies, the order of variables in the data contract must match that in the logic contract. If the order is different, the variables will be stored in different slots, leading to unexpected behavior. However, diamond storage assigns slots to variables manually based on their hashed descriptions. This approach ensures consistent slot assignments and avoids collisions. It's worth noting that diamond storage is exclusive to diamonds, and regular variables cannot be used alongside it. Therefore, existing contracts intended for inclusion in a diamond need to be rewritten as facets using diamond storage. Fortunately, this conversion process is straightforward and may be automated in the future.

Diamond cut and loupe

Modifying a diamond requires two essential components. The first is the diamond cut, which allows changes to the diamond's logic contracts. Using the diamond cut, methods can be added, replaced, or removed from logic contracts, enabling updates or upgrades to the diamond's functionality. However, to make changes to the diamond, it's helpful to understand its current configuration. This is where the diamond loupe comes in. The diamond loupe provides functions to inspect the diamond, revealing available methods and the contracts to which they are currently associated. The terms diamond cut and diamond loupe draw inspiration from the diamond industry.

Contract size limit

Another advantage of the diamond standard is its ability to bypass the Ethereum contract size limit introduced in ERC-170 (opens in a new tab) during the spurious dragon hard fork. When a contract becomes too large in terms of functionality, it may exceed the 24kb contract limit, preventing deployment on the Ethereum network. However, diamonds overcome this limitation by dividing their functionality into smaller logic contracts. As a result, diamonds are not restricted by the size limit.