Skip to content

holographxyz/holograph-doppler

Repository files navigation

Holograph Protocol v2

A protocol for deploying omnichain tokens with deterministic addresses across multiple blockchains. Built on Doppler Airlock technology and LayerZero V2 for secure cross-chain messaging.

Overview

Holograph Protocol enables the creation of ERC-20 tokens with deterministic addresses across supported chains. The protocol integrates with Doppler's token factory system for secure token launches and automates fee collection through LayerZero V2 cross-chain messaging.

Key Features

  • Deterministic Addresses: CREATE2-based deployment ensures consistent addresses across chains
  • Doppler Integration: Authorized token factory for Doppler Airlock launches
  • Fee Automation: Automated fee collection and cross-chain distribution
  • LayerZero V2: Cross-chain fee bridging infrastructure
  • HolographDeployer: Deterministic contract deployment system with salt validation

Architecture

Base Chain                   LayerZero V2              Ethereum Chain
┌─────────────────┐         ┌─────────────┐          ┌─────────────────┐
│ Doppler Airlock │────────▶│             │          │                 │
│       ↓         │         │   Message   │          │                 │
│ HolographFactory│         │   Passing   │          │                 │
│                 │         │             │          │                 │
│ FeeRouter       │────────▶│   (Fees)    │─────────▶│ Fee Processing  │
│                 │         │             │          │                 │
│ HolographERC20  │         │             │          │ StakingRewards  │
└─────────────────┘         └─────────────┘          └─────────────────┘

Primary Chains: Base (token creation) and Ethereum (fee processing/staking)
Additional Support: Unichain deployment available for expanded reach

Note: Cross-chain token bridging is temporarily deferred. Currently, only fee bridging is supported through LayerZero V2.

Development & Deployment

Quick Start with Makefile

The project includes a streamlined Makefile for common development tasks. All deployment operations default to dry-run mode for safety - no real transactions are sent unless explicitly enabled.

Basic Commands

# Development
make build          # Compile all contracts
make test           # Run the full test suite
make fmt            # Format Solidity code
make clean          # Clean build artifacts

# View all available commands
make help

Deployment Commands

Dry-run mode (default - safe for testing):

# Primary chains
make deploy-base        # Simulate Base deployment
make deploy-eth         # Simulate Ethereum deployment

# Additional chains
make deploy-unichain    # Simulate Unichain deployment

# Configuration
make configure-base     # Simulate Base configuration
make configure-eth      # Simulate Ethereum configuration
make configure-unichain # Simulate Unichain configuration

# Operations
make fee-ops            # Simulate fee operations

Live deployment mode:

# Set environment variables
export BROADCAST=true
export DEPLOYER_PK=0x...  # For deploy-* commands
export OWNER_PK=0x...     # For configure-* commands
export OWNER_PK=0x...      # For fee operations (owner-only)

# Required RPC URLs
export BASE_RPC_URL=https://mainnet.base.org
export ETHEREUM_RPC_URL=https://eth-mainnet.alchemyapi.io/v2/YOUR_KEY
export UNICHAIN_RPC_URL=https://mainnet.unichain.org

# Required API keys for verification
export BASESCAN_API_KEY=your_basescan_key
export ETHERSCAN_API_KEY=your_etherscan_key
export UNISCAN_API_KEY=your_uniscan_key

# Deploy to primary chains
make deploy-base        # Deploy to Base mainnet  
make deploy-eth         # Deploy to Ethereum mainnet

# Optionally deploy to additional chains
make deploy-unichain    # Deploy to Unichain mainnet

Environment Variables

Variable Required For Description
BROADCAST Live deployments Set to true to send real transactions
DEPLOYER_PK deploy-* commands Private key for contract deployment
OWNER_PK configure-* commands Private key for contract administration
OWNER_PK fee-* commands Private key for fee operations (owner-only)
BASE_RPC_URL Base operations RPC endpoint for Base network
ETHEREUM_RPC_URL Ethereum operations RPC endpoint for Ethereum network
UNICHAIN_RPC_URL Unichain operations RPC endpoint for Unichain network
BASESCAN_API_KEY Base verification API key for Basescan contract verification
ETHERSCAN_API_KEY Ethereum verification API key for Etherscan contract verification
UNISCAN_API_KEY Unichain verification API key for Uniscan contract verification

Typical Deployment Flow

  1. Test everything in dry-run mode first:

    # Primary chains (required)
    make deploy-base deploy-eth
    make configure-base configure-eth
    
    # Additional chains (optional)
    make deploy-unichain configure-unichain
  2. Deploy to mainnet:

    export BROADCAST=true
    export DEPLOYER_PK=0x...
    
    # Primary chains
    make deploy-base deploy-eth
    
    # Additional chains (optional)  
    make deploy-unichain
  3. Verify deployment consistency:

    make verify-addresses  # Check addresses match across chains
  4. Configure the deployed contracts:

    export OWNER_PK=0x...  # Different key for admin operations
    
    # Primary chains
    make configure-base configure-eth
    
    # Additional chains (if deployed)
    make configure-unichain
  5. Configure LayerZero V2 DVN security:

    # Required for cross-chain fee bridging
    make configure-dvn-base configure-dvn-eth
  6. Set up automation:

    export OWNER_PK=0x...
    make fee-ops  # Test fee operations

Contract Verification

Contracts are automatically verified during deployment when BROADCAST=true and the appropriate API keys are set. If verification fails during deployment, you can retry later:

# Re-run deployment with --resume --verify
forge script script/DeployBase.s.sol --rpc-url $BASE_RPC_URL --resume --verify --etherscan-api-key $BASESCAN_API_KEY

Deployment Artifacts

Deployed contract addresses are automatically saved to:

  • deployments/base/ - Base network deployments
  • deployments/ethereum/ - Ethereum network deployments
  • deployments/unichain/ - Unichain network deployments
  • broadcast/ - Complete transaction logs and artifacts

Each deployment directory contains:

  • deployment.json - Complete deployment information
  • Individual .txt files for each contract address

Safety Features

  • Dry-run by default: Scripts never broadcast without explicit BROADCAST=true
  • Environment validation: Scripts check for required environment variables
  • Chain validation: Scripts warn when deploying to unexpected networks
  • Role separation: Different private keys for deployment vs. administration
  • Colored output: Clear visual feedback on operation status

Core Contracts

HolographDeployer

Deterministic contract deployment system using CREATE2 for cross-chain address consistency.

function deploy(bytes memory creationCode, bytes32 salt) external returns (address deployed);
function deployAndInitialize(bytes memory creationCode, bytes32 salt, bytes memory initData) external returns (address deployed);
function computeAddress(bytes memory creationCode, bytes32 salt) external view returns (address);

HolographFactory

Doppler-authorized token factory implementing ITokenFactory for omnichain token creation.

// Called by Doppler Airlock contracts only
function create(
    uint256 initialSupply,
    address recipient,
    address owner,
    bytes32 salt,
    bytes calldata tokenData
) external returns (address token);

function setAirlockAuthorization(address airlock, bool authorized) external; // Owner only
function isTokenCreator(address token, address user) external view returns (bool);

FeeRouter

Handles fee collection from Doppler Airlock contracts and cross-chain fee distribution.

function collectAirlockFees(address airlock, address token, uint256 amt) external; // Owner only
function bridge(uint256 minGas, uint256 minHlg) external; // Owner only
function setTrustedAirlock(address airlock, bool trusted) external; // Owner only

StakingRewards

Single-token HLG staking with reward distribution, cooldown periods, and emergency controls.

function stake(uint256 amount) external; // Stake HLG tokens
function withdraw(uint256 amount) external; // Withdraw after cooldown (default 7 days)
function claim() external; // Claim accumulated rewards
function addRewards(uint256 amount) external; // FeeRouter only

Token Launch Process

  1. Create token through Doppler Airlock (which calls HolographFactory.create())
  2. Airlock handles auction mechanics and initial distribution
  3. HolographFactory deploys HolographERC20 with deterministic CREATE2 address
  4. FeeRouter automatically set as integrator for trading fee collection
  5. Token address consistent across supported chains (primarily Base and Ethereum)

Fee Model

  • Source: Trading fees from Doppler auctions (collected by Airlock contracts)
  • Protocol Split: 50% of collected fees (HOLO_FEE_BPS = 5000)
  • Treasury Split: 50% of collected fees forwarded to treasury address
  • HLG Distribution: Protocol fees bridged to Ethereum, swapped WETH→HLG, 50% burned / 50% staked
  • Security: Trusted Airlock whitelist prevents unauthorized ETH transfers to FeeRouter

Integration

Token Launch via TypeScript

Use the provided TypeScript utility in the script/ directory to create tokens through Doppler:

# Set environment variables
export PRIVATE_KEY=0x...
export BASESCAN_API_KEY=your_api_key

# Create a token
npm run create-token

Or programmatically:

import { createToken, TokenConfig } from './script/create-token.js'
import { parseEther } from 'viem'

const config: TokenConfig = {
  name: "MyToken",
  symbol: "MTK",
  initialSupply: parseEther("1000000"),
  minProceeds: parseEther("100"),
  maxProceeds: parseEther("10000"),
  auctionDurationDays: 3
}

const result = await createToken(config, process.env.PRIVATE_KEY)

Direct Factory Authorization

For authorized Airlock contracts:

// Only callable by authorized Doppler Airlock contracts
bytes memory tokenData = abi.encode(
    name,
    symbol,
    yearlyMintCap,
    vestingDuration,
    recipients,
    amounts,
    tokenURI
);

address token = holographFactory.create(
    initialSupply,
    recipient,
    owner,
    salt,
    tokenData
);

Owner Operations

// Collect fees from Doppler Airlock (Owner only)
feeRouter.collectAirlockFees(airlockAddress, tokenAddress, amount);

// Bridge accumulated fees (Owner only)
feeRouter.bridge(minGas, minHlgOut);

Security

Access Control

  • Owner: Contract administration, trusted remote management, treasury updates
  • Owner-Only Operations: All fee operations now require owner permissions (no keeper role)
  • FeeRouter Authorization: Only designated FeeRouter can add rewards to StakingRewards
  • Airlock Authorization: Only whitelisted Doppler Airlock contracts can create tokens

Deployment Security

  • Salt Validation: HolographDeployer requires first 20 bytes of salt to match sender address
  • Deterministic Addresses: CREATE2 ensures consistent addresses, preventing address confusion
  • Griefing Protection: Salt validation prevents malicious actors from front-running deployments
  • Signed Deployments: Support for gasless deployment with signature verification

Cross-Chain Security

  • Trusted Remotes: Per-endpoint whitelist of authorized cross-chain message senders
  • Endpoint Validation: LayerZero V2 endpoint verification for all cross-chain messages
  • Trusted Airlocks: Whitelist preventing unauthorized ETH transfers to FeeRouter
  • Replay Protection: Nonce-based system preventing message replay attacks

Economic Security

  • Dust Protection: MIN_BRIDGE_VALUE (0.01 ETH) prevents uneconomical bridging
  • Slippage Protection: Configurable minimum HLG output for swaps
  • Cooldown Period: 7-day default withdrawal cooldown prevents staking manipulation
  • Emergency Controls: Owner can pause all major contract functions

Testing

# Run all tests
forge test

# Unit tests
forge test --match-path test/unit/

# Integration tests
forge test --match-path test/integration/

# Gas reports
forge test --gas-report

Environment Setup

Set up the following environment variables for deployment and operations:

# Network RPCs
export BASE_RPC="https://mainnet.base.org"
export ETH_RPC="https://eth-mainnet.alchemyapi.io/v2/YOUR_KEY"

# Private Keys
export DEPLOYER_PK="0x..."      # Contract deployment
export OWNER_PK="0x..."         # Contract administration
export KEEPER_PK="0x..."        # Automation operations

# LayerZero Endpoint IDs
export BASE_EID=30184           # Base mainnet
export ETH_EID=30101            # Ethereum mainnet

# Contract Addresses (update after deployment)
export DOPPLER_AIRLOCK="0x..."
export LZ_ENDPOINT="0x..."      # LayerZero V2 endpoint
export TREASURY="0x..."         # Treasury multisig
export HLG="0x..."              # HLG token address
export WETH="0x..."             # WETH address
export SWAP_ROUTER="0x..."      # Uniswap V3 SwapRouter
export STAKING_REWARDS="0x..."  # StakingRewards contract

# Addresses (set after deployment)
export FEE_ROUTER="0x..."
export HOLOGRAPH_FACTORY="0x..."
export KEEPER_ADDRESS="0x..."

Deployment Infrastructure

HolographDeployer

All Holograph contracts are deployed through the HolographDeployer system, which ensures deterministic addresses across chains:

  • CREATE2 Deployment: Contracts have identical addresses on all chains
  • Salt Validation: First 20 bytes of salt must match deployer address to prevent griefing
  • Batch Operations: Deploy and initialize contracts in a single transaction
  • Signed Deployments: Support for gasless deployment via signed messages

Deployment Process

💡 Quick Start: Use the simplified Makefile commands documented in the Development & Deployment section above for streamlined deployment.

Using Makefile (Recommended)

# Set up environment
export BROADCAST=true
export DEPLOYER_PK=0x...
export BASE_RPC_URL=https://mainnet.base.org
export ETHEREUM_RPC_URL=https://eth-mainnet.alchemyapi.io/v2/YOUR_KEY
export UNICHAIN_RPC_URL=https://mainnet.unichain.org

# Deploy to primary chains
make deploy-base deploy-eth

# Optionally add Unichain
make deploy-unichain

Manual Deployment (Advanced)

For advanced users who need more control over deployment parameters:

Base Chain

# Deploy using deployment script
forge script script/DeployBase.s.sol \
  --rpc-url $BASE_RPC_URL \
  --broadcast --private-key $DEPLOYER_PK \
  --verify --etherscan-api-key $BASESCAN_API_KEY

Ethereum Chain

# Deploy using deployment script
forge script script/DeployEthereum.s.sol \
  --rpc-url $ETHEREUM_RPC_URL \
  --broadcast --private-key $DEPLOYER_PK \
  --verify --etherscan-api-key $ETHERSCAN_API_KEY

Unichain

# Deploy using deployment script
forge script script/DeployUnichain.s.sol \
  --rpc-url $UNICHAIN_RPC_URL \
  --broadcast --private-key $DEPLOYER_PK \
  --verify --etherscan-api-key $UNISCAN_API_KEY

Operations

Initial Setup

After deployment, configure the system using the fee operations script:

# 1. Update script/FeeOperations.s.sol with actual Airlock addresses
# 2. Whitelist Airlock contracts (Owner only)
make fee-setup BROADCAST=true

# Note: All operations are owner-only (no keeper role needed)

# 4. Configure LayerZero trusted remotes
cast send $FEE_ROUTER "setTrustedRemote(uint32,bytes32)" \
  $ETH_EID $(cast address-to-bytes32 $ETH_FEE_ROUTER) \
  --rpc-url $BASE_RPC --private-key $OWNER_PK

cast send $FEE_ROUTER "setTrustedRemote(uint32,bytes32)" \
  $BASE_EID $(cast address-to-bytes32 $BASE_FEE_ROUTER) \
  --rpc-url $ETH_RPC --private-key $OWNER_PK

Keeper Automation

# Monitor system status
make fee-status

# Run fee collection and bridging (automated/cron)
make fee-ops BROADCAST=true

# Set up automated execution (example cron)
echo "*/10 * * * * cd /path/to/holograph && make fee-ops BROADCAST=true" | crontab -

Emergency Controls

# Emergency treasury redirection (Owner only)
forge script script/FeeOperations.s.sol \
  --sig "emergencyRedirect(address)" $EMERGENCY_TREASURY \
  --rpc-url $BASE_RPC --broadcast --private-key $OWNER_PK

# Unpause operations (Owner only)
cast send $FEE_ROUTER "unpause()" \
  --rpc-url $BASE_RPC --private-key $OWNER_PK

# Update treasury address (Owner only)
cast send $FEE_ROUTER "setTreasury(address)" $NEW_TREASURY \
  --rpc-url $BASE_RPC --private-key $OWNER_PK

Dependencies

  • LayerZero V2: Cross-chain messaging protocol
  • Doppler Airlock: Token launch mechanism
  • OpenZeppelin: Access control and security utilities
  • Uniswap V3: WETH/HLG swapping on Ethereum

Quick Reference

Common Tasks

# Check system status
make fee-status

# Manual fee collection
make fee-collect BROADCAST=true

# Emergency treasury redirect
forge script script/FeeOperations.s.sol --sig "emergencyRedirect(address)" $EMERGENCY_TREASURY --rpc-url $BASE_RPC --broadcast --private-key $OWNER_PK

# Check FeeRouter ETH balance
cast balance $FEE_ROUTER --rpc-url $BASE_RPC

# Check if Airlock is whitelisted
cast call $FEE_ROUTER "trustedAirlocks(address)" $AIRLOCK_ADDRESS --rpc-url $BASE_RPC

# Setup trusted Airlocks
make fee-setup BROADCAST=true

Monitoring

  • FeeRouter Balance: Should accumulate fees between fee operations
  • Trusted Airlocks: Must be whitelisted before fee collection
  • LayerZero Messages: Monitor cross-chain message delivery
  • HLG Distribution: Verify burn/stake operations on Ethereum

Troubleshooting

  • "UntrustedSender" Error: Airlock not whitelisted - run setupTrustedAirlocks()
  • "AccessControl" Error: Address missing owner permissions (all operations are owner-only)
  • Bridge Failures: Check LayerZero trusted remotes configuration
  • Low HLG Output: Adjust slippage protection or check Uniswap liquidity

Documentation

Additional technical documentation is available in the docs/ directory:

License

MIT

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •