defiQUG c32fcf48e8 Add authentication and idempotency middleware, implement graceful shutdown, and update dependencies
- Introduced `authMiddleware` for request authentication and `optionalAuthMiddleware` for optional authentication.
- Added `idempotencyMiddleware` to ensure idempotent requests are processed correctly, including Redis caching.
- Implemented graceful shutdown for the REST API server to close Redis connections on termination signals.
- Updated `package.json` to include `jsonwebtoken` and its type definitions.
2025-12-12 11:17:59 -08:00

eMoney Token Factory (ChainID 138)

A comprehensive ERC-20 eMoney Token Factory system with policy-controlled transfers, lien enforcement, compliance management, and bridge functionality.

Overview

This system enables the deployment and management of restricted ERC-20 tokens on ChainID 138 with the following key features:

  • Policy-Controlled Transfers: All transfers are validated through a centralized PolicyManager
  • Lien Enforcement: Two modes supported
    • Hard Freeze Mode: Any active lien blocks all outbound transfers
    • Encumbered Mode: Transfers allowed up to freeBalance = balance - encumbrance
  • Compliance Registry: Track account compliance status, risk tiers, and jurisdiction
  • Debt Registry: Multi-lien support with aggregation and priority
  • Bridge Vault: Optional public chain bridge with light client verification
  • UUPS Upgradable: Token implementations use UUPS proxy pattern for upgradeability

Architecture

Contract Relationships

graph TB
    subgraph "Registry Layer"
        CR[ComplianceRegistry]
        DR[DebtRegistry]
    end
    
    subgraph "Policy Layer"
        PM[PolicyManager]
    end
    
    subgraph "Token Layer"
        TF[TokenFactory138]
        EMT[eMoneyToken]
        IMPL[eMoneyToken<br/>Implementation]
    end
    
    subgraph "Bridge Layer"
        BV[BridgeVault138]
    end
    
    CR -->|checks compliance| PM
    DR -->|provides lien info| PM
    PM -->|authorizes transfers| EMT
    PM -->|authorizes transfers| BV
    TF -->|deploys| EMT
    IMPL -->|used by| TF
    EMT -->|uses| PM
    EMT -->|uses| DR
    EMT -->|uses| CR
    BV -->|uses| PM
    BV -->|uses| CR
    
    style CR fill:#e1f5ff
    style DR fill:#e1f5ff
    style PM fill:#fff4e1
    style TF fill:#e8f5e9
    style EMT fill:#e8f5e9
    style BV fill:#f3e5f5

Transfer Authorization Flow

sequenceDiagram
    participant User
    participant Token as eMoneyToken
    participant PM as PolicyManager
    participant CR as ComplianceRegistry
    participant DR as DebtRegistry
    
    User->>Token: transfer(to, amount)
    Token->>PM: canTransfer(from, to, amount)
    
    alt Token Paused
        PM-->>Token: (false, PAUSED)
    else Account Frozen
        PM->>CR: isFrozen(from/to)
        CR-->>PM: true
        PM-->>Token: (false, FROM_FROZEN/TO_FROZEN)
    else Not Compliant
        PM->>CR: isAllowed(from/to)
        CR-->>PM: false
        PM-->>Token: (false, FROM_NOT_COMPLIANT/TO_NOT_COMPLIANT)
    else Bridge Only Mode
        PM->>PM: check bridge address
        PM-->>Token: (false, BRIDGE_ONLY)
    else Lien Check
        alt Hard Freeze Mode
            Token->>DR: hasActiveLien(from)
            DR-->>Token: true
            Token-->>User: TransferBlocked(LIEN_BLOCK)
        else Encumbered Mode
            Token->>DR: activeLienAmount(from)
            DR-->>Token: encumbrance
            Token->>Token: freeBalance = balance - encumbrance
            alt amount > freeBalance
                Token-->>User: TransferBlocked(INSUFF_FREE_BAL)
            else
                Token->>Token: _update(from, to, amount)
                Token-->>User: Transfer succeeded
            end
        end
    end

Contracts

Core Contracts

  1. TokenFactory138: Factory contract for deploying new eMoney tokens as UUPS proxies
  2. eMoneyToken: Restricted ERC-20 token with transfer hooks and lien enforcement
  3. PolicyManager: Central rule engine for transfer authorization
  4. DebtRegistry: Lien management and aggregation engine
  5. ComplianceRegistry: Compliance status and freeze management
  6. BridgeVault138: Lock/unlock portal for public chain representation

Installation

Prerequisites

  • Foundry (forge, cast, anvil)
  • OpenZeppelin Contracts v5
  • Node.js 18+ (for API layer)
  • pnpm 8+ (package manager for API layer)

Setup

  1. Clone the repository
  2. Install Solidity dependencies:
forge install OpenZeppelin/openzeppelin-contracts@v5.0.0
forge install OpenZeppelin/openzeppelin-contracts-upgradeable@v5.0.0
  1. Install API dependencies (if using API layer):
# Install pnpm (if not installed)
npm install -g pnpm

# Install all API dependencies
cd api
pnpm install

See API Getting Started for detailed API setup instructions.

  1. Build:
forge build
  1. Run tests:
forge test

Usage

Environment Variables

Before deploying, you need to set up environment variables. A template file .env.example is provided as a reference.

Required Variables

  • PRIVATE_KEY: Private key for deployment (without 0x prefix)

    • SECURITY WARNING: This key will have admin access to deployed contracts
    • Use a dedicated deployment wallet with minimal funds
    • Never commit this key to version control
  • RPC_URL: RPC endpoint URL for ChainID 138

Post-Deployment Variables (Required for Configure.s.sol)

Set these after initial deployment:

  • COMPLIANCE_REGISTRY: Address of deployed ComplianceRegistry contract
  • POLICY_MANAGER: Address of deployed PolicyManager contract
  • TOKEN_FACTORY: Address of deployed TokenFactory138 contract

Optional Variables

  • INFURA_API_KEY: For Infura RPC endpoints (optional)
  • ETHERSCAN_API_KEY: For contract verification (optional)
  • GOVERNANCE_MULTISIG: Multisig address for governance (production)

Setting Up Environment Variables

  1. Copy the example file:
cp .env.example .env
  1. Edit .env and fill in your actual values:
# Edit .env file with your editor
nano .env  # or vim, code, etc.
  1. Alternatively, export variables directly:
export PRIVATE_KEY=<your_private_key>
export RPC_URL=<chain_rpc_url>

Security Best Practices:

  • Never commit .env to version control (it's in .gitignore)
  • Use different keys for development, staging, and production
  • Rotate keys regularly
  • Use hardware wallets for production deployments
  • Store sensitive values in secure key management services

Deploying the System

  1. Set up environment variables (see above)

  2. Deploy contracts:

forge script script/Deploy.s.sol:DeployScript --rpc-url $RPC_URL --broadcast --verify
  1. Configure roles and initial settings:
export COMPLIANCE_REGISTRY=<deployed_address>
export POLICY_MANAGER=<deployed_address>
export TOKEN_FACTORY=<deployed_address>
forge script script/Configure.s.sol:ConfigureScript --rpc-url $RPC_URL --broadcast

Deploying a New Token

TokenFactory138 factory = TokenFactory138(factoryAddress);

ITokenFactory138.TokenConfig memory config = ITokenFactory138.TokenConfig({
    issuer: issuerAddress,
    decimals: 18,
    defaultLienMode: 2, // 1 = hard freeze, 2 = encumbered
    bridgeOnly: false,
    bridge: bridgeAddress
});

address token = factory.deployToken("My Token", "MTK", config);

Managing Liens

DebtRegistry registry = DebtRegistry(debtRegistryAddress);

// Place a lien
uint256 lienId = registry.placeLien(
    debtor,
    1000, // amount
    0, // expiry (0 = no expiry)
    1, // priority
    reasonCode
);

// Reduce a lien
registry.reduceLien(lienId, 300); // reduce by 300

// Release a lien
registry.releaseLien(lienId);

Transfer Modes

Mode 1: Hard Freeze

When a token is in hard freeze mode (lienMode = 1), any active lien on an account blocks all outbound transfers.

When a token is in encumbered mode (lienMode = 2), accounts can transfer up to their freeBalance:

  • freeBalance = balanceOf(account) - activeLienAmount(account)
  • Transfers exceeding freeBalance are blocked with INSUFF_FREE_BAL reason code

Roles

  • GOVERNANCE_ADMIN_ROLE: Root governance (should be multisig)
  • TOKEN_DEPLOYER_ROLE: Deploy new tokens via factory
  • POLICY_OPERATOR_ROLE: Configure token policies (pause, bridgeOnly, lienMode)
  • ISSUER_ROLE: Mint/burn tokens
  • ENFORCEMENT_ROLE: Clawback and forceTransfer
  • COMPLIANCE_ROLE: Update compliance registry
  • DEBT_AUTHORITY_ROLE: Place/reduce/release liens
  • BRIDGE_OPERATOR_ROLE: Authorize bridge unlocks

Reason Codes

All transfer blocks emit a bytes32 reason code:

  • OK: Transfer allowed
  • PAUSED: Token is paused
  • FROM_FROZEN / TO_FROZEN: Account is frozen
  • FROM_NOT_COMPLIANT / TO_NOT_COMPLIANT: Account not compliant
  • LIEN_BLOCK: Hard freeze mode - lien blocks transfer
  • INSUFF_FREE_BAL: Encumbered mode - insufficient free balance
  • BRIDGE_ONLY: Token in bridge-only mode
  • UNAUTHORIZED: Unauthorized operation
  • CONFIG_ERROR: Configuration error

Testing

Run All Tests

forge test

Run Specific Test Suite

forge test --match-contract ComplianceRegistryTest
forge test --match-contract DebtRegistryTest
forge test --match-contract PolicyManagerTest
forge test --match-contract eMoneyTokenTest
forge test --match-contract TokenFactoryTest

Run Invariant Tests

forge test --match-contract DebtRegistryInvariants
forge test --match-contract TransferInvariants

Run Fuzz Tests

forge test --match-contract DebtRegistryFuzz
forge test --match-contract TransferFuzz

Generate Coverage Report

forge coverage

Security Considerations

  1. Admin Roles: All admin roles should be assigned to multisigs in production
  2. Timelock: Consider adding timelock for privileged operations
  3. Audits: External security audit recommended before mainnet deployment
  4. Upgrades: UUPS upgradeability requires careful governance control

Documentation

See RUNBOOK.md for operational procedures including:

  • Role rotation
  • Emergency pause procedures
  • Lien dispute handling
  • Upgrade procedures
  • Bridge operator procedures

License

MIT

Description
No description provided
Readme 355 KiB
Languages
TypeScript 90.1%
JavaScript 2.9%
HCL 2.6%
Shell 1.9%
HTML 1.2%
Other 1.3%