Professional development environment for the Diamonds node modules, associated hardhat node modules, and the DevContainer.
This repository serves as a professional development environment for building, testing, and deploying the Diamonds node modules, associated hardhat node modules, and the DevContainer.
diamonds-dev-env/
βββ .devcontainer/ # DevContainer configuration
βββ .husky/ # DevContainer configuration
βββ .vscode/ # VSCode workspace settings
βββ packages/
| βββ diamonds/ # Diamonds Main NPM package
| βββ hardhat-diamonds-monitor/ # Diamonds monitoring NPM package
β βββ hardhat-diamonds/ # Hardhat Diamonds NPM package
β βββ src/ # TypeScript source code
β βββ dist/ # Compiled output
β βββ coverage/ # Test coverage reports
β βββ package.json # Package configuration
βββ contracts/ # Diamond proxy contracts
βββ test/ # Contract tests
βββ scripts/ # Development scripts
βββ deployments/ # Deployment artifacts- ποΈ Yarn Workspaces: Monorepo structure for managing multiple packages
- π§ͺ Comprehensive Testing: Unit tests, integration tests, fuzz tests, and coverage reporting
- π Advanced Fuzzing: Echidna, Medusa, and Forge fuzzing frameworks for comprehensive security testing
- π οΈ TypeScript Support: Full type safety with modern TypeScript features
- π Code Quality: ESLint, Prettier, and Husky for code formatting and git hooks
- π CI/CD Pipeline: Automated testing, building, and publishing via GitHub Actions
- π¦ Professional Packaging: Ready for NPM publication with proper versioning
- Node.js β₯ 18.0.0
- Yarn β₯ 4.0.0
- Git
- DevContainer Support: VS Code with Dev Containers extension (recommended)
- Includes all security tools pre-installed (Medusa, Echidna, Vyper, etc.)
- Cross-architecture support for ARM64/M1/M2 Macs via QEMU
- Automatic environment setup and configuration
# Clone the repository
git clone <repository-url>
cd diamonds-dev-env
# Install all dependencies
yarn install
# Build all packages
yarn workspace:build# Start development mode (watches for changes)
yarn dev
# Build the hardhat-diamonds package
yarn hardhat-diamonds:build
# Run hardhat-diamonds tests
yarn hardhat-diamonds:test
# Run hardhat-diamonds with coverage
yarn workspace hardhat-diamonds run test:coverage
# Lint all code
yarn lint
# Format all code
yarn format
# Clean all build artifacts
yarn workspace:clean# Build TypeScript to JavaScript
yarn tsc
# Build and deploy task files (required for Hardhat tasks)
yarn tsc && cp dist/scripts/setup/*.js scripts/setup/ && cp dist/scripts/utils/*.js scripts/utils/Important: Hardhat tasks use dynamic imports that require compiled .js files. After modifying TypeScript files in scripts/, you must rebuild and copy the compiled files. See docs/BUILD_AND_DEPLOYMENT.md for details.
# Compile contracts
yarn compile
# Run contract tests
yarn test
# Generate diamond ABI
yarn generate-diamond-abi
# Generate diamond ABI with TypeChain types
yarn generate-diamond-abi-typechain# Install package dependencies
yarn workspace hardhat-diamonds install
# Build the package
yarn workspace hardhat-diamonds run build
# Run package tests
yarn workspace hardhat-diamonds run test
# Run package linting
yarn workspace hardhat-diamonds run lint
# Watch mode for development
yarn workspace hardhat-diamonds run build:watchThe package is automatically published to NPM when changes are pushed to the main branch, provided the version has been updated.
# Manual publishing (from package directory)
cd packages/hardhat-diamonds
npm publish
# Beta release
npm publish --tag betaCreate a .env file in the root directory:
# RPC endpoints
MAINNET_RPC_URL=your_mainnet_rpc_url
GOERLI_RPC_URL=your_goerli_rpc_url
SEPOLIA_RPC_URL=your_sepolia_rpc_url
# Hardhat Private key for Account 0
TEST_PRIVATE_KEY=your_private_key
# API keys
ETHERSCAN_API_KEY=your_etherscan_api_key
COINMARKETCAP_API_KEY=your_coinmarketcap_api_keyThe project uses Yarn workspaces to manage multiple packages. Configuration is in:
package.json- Root workspace configurationpackages/hardhat-diamonds/package.json- Package-specific configurationtsconfig.json- TypeScript configuration with project references.yarnrc.yml- Yarn configuration
# Run all tests
yarn workspace:test
# Run specific package tests
yarn monitor:test
# Run with coverage
yarn workspace hardhat-diamonds run test:coverage
# Run tests in watch mode
yarn workspace hardhat-diamonds run test:watch- Unit tests:
packages/hardhat-diamonds/src/__tests__/ - Integration tests:
test/integration/ - Contract tests:
test/ - Fuzzing tests:
test/fuzzing/- Medusa fuzzing configurations and generated tests - Forge tests:
test/foundry/- Foundry fuzz, integration, and invariant tests
Run fuzzing tests on Diamond contracts using Medusa (Trail of Bits):
# Prerequisites: Install dependencies (if not in DevContainer)
pipx install solc-select crytic-compile
solc-select install 0.8.19 && solc-select use 0.8.19
# Run fuzzing campaign on ExampleDiamond
npx hardhat medusa:fuzz --diamond ExampleDiamond
# Custom workers and test limits
npx hardhat medusa:fuzz --diamond ExampleDiamond --workers 4 --limit 10000
# With timeout (in seconds)
npx hardhat medusa:fuzz --diamond ExampleDiamond --timeout 300Note: Medusa uses its own EVM and cannot fork from Hardhat node. Best for testing self-contained contract logic.
See docs/MEDUSA_FUZZING_GUIDE.md for comprehensive Medusa fuzzing documentation.
Run Foundry-based fuzz, integration, and invariant tests with chain forking:
# Prerequisites: Start Hardhat node
npx hardhat node # In separate terminal
# Deploy Diamond and generate helper library
npx hardhat forge:deploy --diamond ExampleDiamond --network localhost
# Run all Forge tests with forking (fuzz + integration + invariant)
npx hardhat forge:fuzz --diamond ExampleDiamond --network localhost
# Generate Solidity helpers from existing deployment
npx hardhat forge:generate-helpers --diamond ExampleDiamond --network localhost
# Or run directly with Forge (after deployment) using the correct hardhat port
forge test --fork-url http://127.0.0.1:${HARDHAT_PORT:-8545} -vvForge fuzzing supports testing against deployed state via chain forking, making it ideal for integration testing.
See docs/FORGE_FUZZING_GUIDE.md for comprehensive Forge fuzzing documentation.
# Lint all code
yarn lint
# Format all code
yarn format
# Check formatting
yarn format --checkHusky is configured to run checks before commits:
- pre-commit: Runs lint-staged to format and lint staged files
- pre-push: Runs tests to ensure code quality
GitHub Actions workflows are configured for automated quality checks and publishing.
The CI pipeline runs automatically on all pull requests to main and develop branches, ensuring code quality before merge.
All jobs run in parallel for fast feedback:
-
Compile - Builds workspace packages and compiles Hardhat contracts
- Verifies TypeScript compilation
- Validates Solidity contracts compile without errors
- Generates Diamond ABIs and TypeChain types
-
Test - Validates test framework (smoke test in Epic 1)
- Full test suite execution will be added in future epics
- Currently validates test infrastructure is working
-
Lint - Enforces code quality standards
- Runs ESLint with custom Diamond security rules
- Checks TypeScript and JavaScript code style
- Fails on errors, warns on style issues
-
Security - Security scanning (placeholder in Epic 1)
- Future integration with Slither, Semgrep, and other tools
- Will include dependency vulnerability scanning
- Contract-specific security analysis
- Parallel Execution: All jobs run simultaneously for faster feedback
- Dependency Caching: Yarn dependencies cached for faster subsequent runs
- Node.js 18: Runs on LTS version with Corepack for Yarn 4.x support
- Branch Protection: Failed checks block PR merging (when configured)
- 15-minute Timeout: Prevents stuck workflows from consuming resources
- Pull requests to
mainbranch - Pull requests to
developbranch - Does NOT trigger on pushes to feature branches
- Automatic: Publishes to NPM on main branch pushes (when version changes)
- Beta: Supports beta releases with
--tag beta
The hardhat-diamonds package provides comprehensive tools for monitoring ERC-2535 Diamond Proxy contracts. See the package README for detailed API documentation.
Key classes:
DiamondMonitor- Main monitoring functionalityFacetManager- Facet management tools- Utility functions for diamond development
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Commit your changes:
git commit -m 'Add amazing feature' - Push to the branch:
git push origin feature/amazing-feature - Open a Pull Request
- Follow TypeScript best practices
- Write comprehensive tests for new features
- Maintain 80%+ test coverage
- Use conventional commit messages
- Ensure all CI checks pass
| Script | Description |
|---|---|
yarn workspace:install |
Install all workspace dependencies |
yarn workspace:build |
Build all packages |
yarn workspace:test |
Run tests for all packages |
yarn workspace:lint |
Lint all packages |
yarn workspace:clean |
Clean all build artifacts |
| Script | Description |
|---|---|
yarn monitor:build |
Build hardhat-diamonds package |
yarn monitor:test |
Test hardhat-diamonds package |
yarn monitor:lint |
Lint hardhat-diamonds package |
yarn monitor:dev |
Development mode for hardhat-diamonds |
| Script | Description |
|---|---|
yarn compile |
Compile Solidity contracts |
yarn test |
Run contract tests |
yarn generate-diamond-abi |
Generate diamond ABI files |
This project is licensed under the MIT License - see the LICENSE file for details.
- π« Issues: GitHub Issues
- π¬ Discussions: GitHub Discussions
- π Documentation: Package Documentation
- DiamondCutFacet: Handles diamond upgrades (add/replace/remove facets)
- DiamondLoupeFacet: Inspection functions for facets and selectors
- ExampleOwnershipFacet: Ownership management and access control
- ExampleAccessControlFacet: Role-based access control system
- ExampleInitFacet: Initialization and upgrade logic
- Node.js >= 20.0.0
- Yarn (recommended) or npm
- Git
# Clone the repository
git clone https://github.com/diamondlabs/hardhat-diamonds-dev.git
cd hardhat-diamonds-dev
# Install dependencies
yarn install
# Copy environment template
cp .env.example .envSet up your environment variables in .env:
# Network Configuration
MAINNET_RPC=https://mainnet.infura.io/v3/your-key
SEPOLIA_RPC=https://sepolia.infura.io/v3/your-key
POLYGON_RPC=https://polygon-mainnet.g.alchemy.com/v2/your-key
# Deployment Keys
PRIVATE_KEY=your_private_key_here
TEST_PRIVATE_KEY=your_test_private_key_here
# API Keys for Verification
ETHERSCAN_API_KEY=your_etherscan_api_key
POLYGONSCAN_API_KEY=your_polygonscan_api_key# Compile all contracts and generate Diamond ABI with TypeScript types
yarn compile
# Build TypeScript and compile contracts with Diamond ABI generation
yarn build
# Clean compiled artifacts
yarn clean# Run all tests
yarn test
# Run tests with coverage
yarn coverageThe project includes the following yarn scripts defined in package.json:
# Development Scripts
yarn clean # Clean compiled artifacts
yarn compile # Compile contracts and generate Diamond ABI
yarn build # Build TypeScript, compile contracts, and generate ABI (β οΈ currently has TypeScript errors)
yarn test # Run all tests
yarn coverage # Run tests with coverage reportNote: The
yarn buildcommand currently has TypeScript compilation errors that need to be resolved. For development, useyarn compilewhich works correctly.
For deployment, you'll need to use the deployment scripts directly:
# Example: Deploy using TypeScript scripts
npx ts-node scripts/deploy/rpc/deploy-rpc.ts ExampleDiamond sepolia
# Example: Deploy using Defender
npx ts-node scripts/deploy/defender/deploy-defender.ts ExampleDiamond mainnetThe project includes several deployment strategies using TypeScript scripts:
# Basic deployment
npx ts-node scripts/deploy/rpc/deploy-rpc.ts ExampleDiamond sepolia
# With custom options (if supported by script)
npx ts-node scripts/deploy/rpc/deploy-rpc.ts ExampleDiamond sepolia --verbose
# Manual step-by-step deployment
npx ts-node scripts/deploy/rpc/deploy-rpc-manual.ts ExampleDiamond sepolia# Deploy via OpenZeppelin Defender
npx ts-node scripts/deploy/defender/deploy-defender.ts ExampleDiamond mainnet
# Check deployment status
npx ts-node scripts/deploy/defender/status-defender.ts ExampleDiamond mainnet# Check deployment status
npx ts-node scripts/deploy/rpc/status-rpc.ts ExampleDiamond sepolia --detailed
# Verify deployment integrity
npx ts-node scripts/deploy/rpc/verify-rpc.ts ExampleDiamond sepolia --etherscan
# Upgrade diamond (add new facets or update existing ones)
npx ts-node scripts/deploy/rpc/upgrade-rpc.ts ExampleDiamond sepoliaThe project automatically generates a combined Diamond ABI with TypeScript types:
# Generate Diamond ABI
yarn generate-diamond-abi
# Generate with TypeChain types
yarn generate-diamond-abi-typechain
# Build everything (compile + generate ABI)
yarn build# Run all tests
yarn test
# Run tests with coverage
yarn coverage
# Run specific test files
yarn test test/unit/diamond-abi-generator.test.ts
yarn test test/integration/defender/DefenderDeployment.test.ts
# Run Echidna property-based fuzzing tests
yarn echidna:setup # Prepare environment
yarn echidna:test # Run fuzzing tests
yarn echidna:clean # Clean artifacts
# Run Forge fuzzing tests
yarn forge:fuzz
# Run Medusa fuzzing tests
yarn medusa:fuzzFor detailed information about Echidna fuzzing, see echidna/README.md.
hardhat-diamonds-dev/
βββ contracts/ # Solidity smart contracts
β βββ examplediamond/ # Diamond facet contracts
β βββ facets/ # Individual facet implementations
β βββ interfaces/ # Solidity interfaces
β βββ libraries/ # Shared libraries
β βββ upgradeInitializers/ # Upgrade initialization contracts
βββ diamonds/ # Diamond configuration
β βββ ExampleDiamond/ # Diamond-specific config
β βββ deployments/ # Deployment records
β βββ callbacks/ # Post-deployment callbacks
β βββ examplediamond.config.json # Facet configuration
βββ scripts/ # Deployment and utility scripts
β βββ deploy/ # Deployment strategies
β β βββ rpc/ # Direct RPC deployment
β β βββ defender/ # OpenZeppelin Defender deployment
β βββ setup/ # Deployment infrastructure
β βββ utils/ # Utility functions
βββ test/ # Test suite
β βββ unit/ # Unit tests
β βββ integration/ # Integration tests
β βββ deployment/ # Deployment tests
βββ typechain-types/ # Generated TypeScript types
βββ diamond-typechain-types/ # Diamond-specific TypeScript types
βββ diamond-abi/ # Generated Diamond ABI artifactsThe diamond configuration is defined in diamonds/ExampleDiamond/examplediamond.config.json:
{
"protocolVersion": 1.0,
"protocolInitFacet": "ExampleInitFacet",
"facets": {
"DiamondCutFacet": {
"priority": 10,
"versions": { "0.0": {} }
},
"DiamondLoupeFacet": {
"priority": 20,
"versions": { "0.0": {} }
},
"ExampleOwnershipFacet": {
"priority": 30,
"versions": { "0.0": {} }
}
}
}Key configurations in hardhat.config.ts:
- Multi-chain support via
hardhat-multichain - Diamond configuration via
hardhat-diamonds - Network settings for multiple EVM chains
- Compiler optimization for gas efficiency
- Unit Tests: Individual facet testing
- Integration Tests: Cross-facet functionality
- Deployment Tests: End-to-end deployment validation
- Multi-chain Tests: Cross-network compatibility
# Run tests with Hardhat
yarn test
# Test with coverage
yarn coverage
# Test specific files
yarn test test/specific-test-file.test.ts- Diamond test helpers: Load and interact with deployed diamonds
- Network utilities: Multi-chain test orchestration
- Mock contracts: Isolated testing environments
- Multi-signature support via OpenZeppelin Defender
- Role-based access control with granular permissions
- Upgrade authorization with ownership verification
- Function selector collision prevention
- Comprehensive test coverage including edge cases
- Medusa: Advanced property-based fuzzing from Trail of Bits (pre-installed in Docker)
- Echidna: Property-based fuzzing for Ethereum smart contracts (pre-installed in Docker)
- Slither: Static analysis for vulnerability detection
- Vyper: Alternative smart contract language compiler for security-focused development
- pyevmasm (evmasm): EVM assembler/disassembler for low-level contract analysis
- crytic-compile: Multi-language smart contract compilation library
- OpenZeppelin Defender: Production-grade security monitoring
- Coverage reports: Ensure comprehensive testing
- Gas optimization: Efficient contract execution
Medusa is pre-installed in the DevContainer and ready to use immediately:
# Run Medusa fuzzing on a Diamond contract
npx hardhat medusa:fuzz --diamond ExampleDiamond
# Customize fuzzing parameters
npx hardhat medusa:fuzz --diamond ExampleDiamond --workers 4 --limit 10000 --timeout 300See docs/MEDUSA_FUZZING_GUIDE.md for detailed usage.
Echidna is pre-installed and can be used for property-based testing:
# Run Echidna on a contract (requires echidna.yaml config)
echidna contracts/YourContract.sol --contract YourContract
# Run with specific test mode
echidna contracts/YourContract.sol --contract YourContract --test-mode assertionVyper compiler is available for compiling Vyper smart contracts:
# Compile a Vyper contract
vyper contracts/MyContract.vy
# Get Vyper version
vyper --versionAnalyze EVM bytecode with the evmasm tool:
# Disassemble bytecode
echo "60606040" | evmasm -d
# Assemble EVM instructions
echo "PUSH1 0x60 PUSH1 0x40" | evmasm -a- Instant deployment and testing
- Full upgrade simulation
- Development-focused tooling
- Direct blockchain interaction
- Custom gas strategies
- Retry mechanisms for reliability
- Multi-signature workflow
- Automated monitoring
- Enterprise security features
// Example: Create a new facet
pragma solidity ^0.8.9;
import "../libraries/LibDiamond.sol";
contract CustomFacet {
function customFunction() external {
LibDiamond.enforceIsContractOwner();
// Your logic here
}
}# Add new facet
npx ts-node scripts/deploy/rpc/upgrade-rpc.ts ExampleDiamond sepolia
# Dry run upgrade (see what will change, if supported by script)
npx ts-node scripts/deploy/rpc/upgrade-rpc.ts ExampleDiamond sepolia --dry-runimport { ExampleDiamond } from "../diamond-typechain-types";
import { ethers } from "hardhat";
// Type-safe contract interaction
const diamond = (await ethers.getContractAt(
"ExampleDiamond",
diamondAddress,
)) as ExampleDiamond;
// All functions are typed and auto-completed
await diamond.transferOwnership(newOwner);We welcome contributions! Please see our Contributing Guide for details.
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Make your changes and add tests
- Run the test suite:
yarn test - Commit your changes:
git commit -m 'Add amazing feature' - Push to the branch:
git push origin feature/amazing-feature - Open a Pull Request
- Solidity: Follow official style guide
- TypeScript: ESLint + Prettier configuration
- Testing: Minimum 80% coverage required
- Documentation: Comprehensive inline documentation
- Diamond Standard (EIP-2535)
- OpenZeppelin Defender Docs
- Hardhat Documentation
- TypeChain Documentation
# The yarn build command currently has TypeScript compilation errors
# Use yarn compile instead for development:
yarn clean
yarn compile# Clean and regenerate
yarn clean
yarn compile
# OR
yarn build# Clean all artifacts and rebuild
yarn clean
yarn compile# Some tests may fail due to missing contract artifacts
# Ensure contracts are compiled first:
yarn compile
yarn testThis project is licensed under the MIT License - see the LICENSE file for details.
- EIP-2535 Diamond Standard by Nick Mudge
- OpenZeppelin for security standards
- Hardhat for development framework
- TypeChain for TypeScript integration