Skip to content
Public template

About

πŸ’Ž ERC-2535: Diamonds, Multi-Facet Proxy Library

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

1 watching

Forks

Latest commit

Β 

History

219 Commits

Folders and files

Repository files navigation


Warning

Pending Security Audits This library is currently under active development and security review. Do not use in production until formal security audits are completed.


A production-grade, modular smart contract framework built on the EIP-2535 Diamond Standard. This library provides a battle-tested foundation for building composable, upgradeable, and gas-efficient smart contracts using facet-based architecture.


πŸ“š Documentation

Document Purpose
SPECIFICATION.md Complete architecture, storage layout, and design decisions
DEVELOPER_GUIDE.md Practical examples for common tasks and patterns
GLOSSARY.md Terminology reference and core concepts
SECURITY.md Security policies and vulnerability reporting
CONTRIBUTING.md Guidelines for contributing to the project

🎯 Overview

The Diamond pattern enables upgradeable smart contracts through facetsβ€”modular contracts that share storage while maintaining independent logic and upgradeable implementations.

✨ Key Features

  • βš™οΈ Modular Facets: Organize functionality into focused, independent modules
  • πŸ” Runtime Upgrades: Add, replace, or remove functions without contract migration
  • πŸ” Introspection: Built-in loupe functions to query Diamond composition
  • πŸ‘‘ Ownership Control: EIP-173 compatible single-owner access control
  • πŸ“š ERC165 Support: Standardized interface detection
  • πŸ§ͺ Comprehensive Tests: Foundry-based test suite with mutation testing
  • πŸš€ Deployment Scripts: Ready-to-use initialization and deployment tooling

πŸ› οΈ Project Structure

src/
β”œβ”€β”€ Diamond.sol                 # Core Diamond proxy contract
β”œβ”€β”€ facets/
β”‚   β”œβ”€β”€ DiamondCutFacet.sol    # Modify Diamond structure
β”‚   β”œβ”€β”€ DiamondLoupeFacet.sol  # Introspect Diamond composition
β”‚   β”œβ”€β”€ OwnableFacet.sol       # Ownership management
β”‚   └── ERC165Facet.sol        # Interface registration
β”œβ”€β”€ initializer/
β”‚   β”œβ”€β”€ DiamondInit.sol        # Initial setup contract
β”‚   └── MultiInit.sol          # Multi-step initialization
β”œβ”€β”€ interfaces/
β”‚   β”œβ”€β”€ IDiamondCut.sol        # Diamond cut standard
β”‚   β”œβ”€β”€ IDiamondLoupe.sol      # Loupe functions standard
β”‚   └── IERC165.sol            # Interface detection
β”œβ”€β”€ libraries/
β”‚   β”œβ”€β”€ DiamondLib.sol         # Core Diamond logic
β”‚   β”œβ”€β”€ OwnableLib.sol         # Ownership primitives
β”‚   └── ERC165Lib.sol          # Interface registration
└── script/
    └── DeployDiamond.s.sol    # Foundry deployment script

test/
β”œβ”€β”€ DiamondTest.t.sol          # Core Diamond tests
└── helpers/                   # Reusable test fixtures

πŸš€ Quick Start

1. Install the Library

forge install dadadave80/diamond-lib

2. Import Diamond Components

import {Diamond} from "@diamond/Diamond.sol";
import {DiamondCutFacet} from "@diamond/facets/DiamondCutFacet.sol";
import {DiamondLoupeFacet} from "@diamond/facets/DiamondLoupeFacet.sol";
import {OwnableFacet} from "@diamond/facets/OwnableFacet.sol";
import {DiamondInit} from "@diamond/initializer/DiamondInit.sol";

3. Deploy and Initialize

forge script script/DeployDiamond.s.sol:DeployDiamond \
  --rpc-url <RPC_URL> \
  --private-key <PRIVATE_KEY> \
  --broadcast

4. Run Tests

forge test -v

πŸ“– Common Tasks

Create a Custom Facet

See DEVELOPER_GUIDE.md for detailed instructions.

Add a Facet to Diamond

See DEVELOPER_GUIDE.md for complete example.

Verify Diamond Composition

Use the built-in loupe functions:

IDiamondLoupe loupe = IDiamondLoupe(diamond);
Facet[] memory facets = loupe.facets();
address facetAddr = loupe.facetAddress(selector);

See GLOSSARY.md for more on introspection.


🧩 Core Facets

Facet Purpose Reference
DiamondCutFacet Execute diamond cuts (add/replace/remove functions) Spec
DiamondLoupeFacet Query Diamond composition Spec
OwnableFacet Manage Diamond ownership (EIP-173) Spec
ERC165Facet Register supported interfaces Spec

Multi-step initialization

MultiInit.multiInit(address[],bytes[]) delegatecalls the supplied initializers in order, in the diamond's context. The arrays must have equal lengths and contain exactly the intended steps. An empty batch is an explicit no-op; zero addresses are invalid entries, rather than a sentinel that ends the batch.

Any invalid or failing step reverts the whole transaction, including earlier writes and the enclosing facet cut:

Failure Error
Different array lengths AddressAndCalldataLengthMismatch()
Zero initializer MultiInit__ZeroInit(uint256 index)
Initializer without code NoBytecodeAtAddress(uint256 index, address initAddress)
Delegatecall reverted MultiInit__StepFailed(uint256 index, address init, bytes reason)

Indexes are zero-based. Decode reason to inspect the original custom error, revert string, panic or empty data. For a nested MultiInit, the outer error identifies that batch and its reason contains the inner indexed error. Code that matched a bare inner revert or InitializeReverted must decode this wrapper instead. DiamondLib keeps its separate address-only NoBytecodeAtAddress(address) error. See the changelog for the compatibility changes.


πŸ” Storage & Architecture

The library uses ERC-7201 namespaced storage to prevent collisions between facets:

// Each component gets isolated storage
bytes32 constant STORAGE_LOCATION = 
  uint256(keccak256(abi.encode(uint256(keccak256("namespace")) - 1))) 
  & ~bytes32(uint256(0xff));

Learn more:


πŸ”„ Upgrade Workflow

  1. Design new facet or changes
  2. Test on local fork: forge test --fork-url <RPC_URL>
  3. Deploy new facet: forge create --rpc-url <RPC_URL> ...
  4. Cut facet into Diamond: Call diamondCut() with cuts array
  5. Verify with loupe functions
  6. Monitor DiamondCut event for audit trail

See DEVELOPER_GUIDE.md for practical examples.


πŸ“‹ Standards Compliance

This library implements and supports:


🀝 Contributing

We welcome contributions! Please see CONTRIBUTING.md for guidelines.

Security

Please report security vulnerabilities privately. See SECURITY.md for details.


πŸ“š Learning Resources


πŸ“„ License

MIT Β© 2025
Built with β™₯ by David Dada


⬆ back to top

About

πŸ’Ž ERC-2535: Diamonds, Multi-Facet Proxy Library

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

1 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages