A modular on-chain framework for NFT primary sales and secondary markets. This repository contains the core Solidity implementations, testing suites, and deployment tooling for the Digital Original protocol.
The DO protocol is built on a modular, upgradeable architecture designed for security and scalability.
- Signature-Based Authorization: Most protocol actions (minting, auctions, market orders) are authorized off-chain via EIP-712 permits and executed on-chain.
- Upgradeable Core: Contracts utilize a proxy-implementation pattern with explicit storage layouts to allow for seamless protocol upgrades.
- Unified Role System: Granular access control is managed through a central
RoleSysteminherited by all core components. - Multi-Currency Support: A
CurrencyManagermodule allows the protocol to interact with an arbitrary list of approved ERC-20 tokens.
An upgradeable ERC-721 implementation with integrated primary-sale logic.
- Token Minting: Requires cryptographic authorization from designated signers.
- Transfer Restrictions: Optional enforcement for regulated collections.
- Revenue Distribution: Automatic on-chain splits for primary sale proceeds.
Manages English-style auctions for primary NFT releases.
- Auction Creation: Requires cryptographic authorization from designated signers.
- Escrow-less Bidding: Refunds are handled automatically during the bidding process.
A secondary marketplace facilitating peer-to-peer trading.
- Off-chain Orders: Supports EIP-712 signed 'Asks' and 'Bids'.
- Fees: Supports maker and taker fee.
- Node.js: ^24.6.0
- Python: ^3.13.7 (for Slither)
npm installThis will automatically run the prepare script, initializing your configuration files from templates.
The project uses four YAML-based configuration files:
config.env.yaml: API keys for Etherscan, CoinMarketCap, and Gas Reporter.config.chain.yaml: RPC URLs and deployer wallet aliases per network.config.collection.yaml: Parameters for the NFT collection.config.market.yaml: Parameters for the marketplace.
Actual private keys are not stored in YAML files. Instead, they are managed via Hardhat Configuration Variables.
To set a private key for a specific wallet alias (e.g., sepolia-deployer-wallet), run:
npx hardhat vars set sepolia-deployer-walletYou will be prompted to enter the private key value.
npm run compilenpm run testTo start a local node forking a network defined in your config:
npm run forkIn a separate terminal, you can then use hardhat tasks:
npx hardhat deploy-collection --network forkTo run Slither for smart contract security analysis, you need to set up a Python virtual environment first:
# Create a virtual environment
python3 -m venv venv
# Activate the virtual environment
source venv/bin/activate
# Install Python dependencies (including slither-analyzer)
pip install -r requirements.txt
# Compile contracts
npm run compile
# Run Slither analysis
npm run slitherThe Slither configuration is defined in slither.config.json. After running, you can deactivate the virtual environment with:
deactivateDeployments are handled via Hardhat tasks. Always specify the --network flag.
- Deploy Full Suite:
npx hardhat deploy-collection --network <network>
npx hardhat deploy-market --network <network>- Deploy Individual Implementations:
npx hardhat deploy-art-token-impl --network <network>
npx hardhat deploy-auction-house-impl --network <network>
npx hardhat deploy-market-impl --network <network>- Verification:
npx hardhat verify-art-token --network <network>
npx hardhat verify-auction-house --network <network>
npx hardhat verify-market --network <network>├── contracts/
│ ├── art-token/ # ERC-721 and minting logic
│ ├── auction-house/ # Primary auction logic
│ ├── market/ # Secondary trading logic
│ └── utils/ # Shared modules (Roles, Currency, etc.)
├── scripts/ # Deployment scripts
├── tasks/ # Hardhat tasks (deploy/verify)
└── tests/ # TypeScript test suite
Licensed under GPL-3.0 – see LICENSE for details.