# 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 ```mermaid 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
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 ```mermaid 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: ```bash forge install OpenZeppelin/openzeppelin-contracts@v5.0.0 forge install OpenZeppelin/openzeppelin-contracts-upgradeable@v5.0.0 ``` 3. Install API dependencies (if using API layer): ```bash # Install pnpm (if not installed) npm install -g pnpm # Install all API dependencies cd api pnpm install ``` See [API Getting Started](api/GETTING_STARTED.md) for detailed API setup instructions. 3. Build: ```bash forge build ``` 4. Run tests: ```bash 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: ```bash cp .env.example .env ``` 2. Edit `.env` and fill in your actual values: ```bash # Edit .env file with your editor nano .env # or vim, code, etc. ``` 3. Alternatively, export variables directly: ```bash export PRIVATE_KEY= export 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: ```bash forge script script/Deploy.s.sol:DeployScript --rpc-url $RPC_URL --broadcast --verify ``` 3. Configure roles and initial settings: ```bash export COMPLIANCE_REGISTRY= export POLICY_MANAGER= export TOKEN_FACTORY= forge script script/Configure.s.sol:ConfigureScript --rpc-url $RPC_URL --broadcast ``` ### Deploying a New Token ```solidity 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 ```solidity 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. #### Mode 2: Encumbered (Recommended) 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 ```bash forge test ``` ### Run Specific Test Suite ```bash 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 ```bash forge test --match-contract DebtRegistryInvariants forge test --match-contract TransferInvariants ``` ### Run Fuzz Tests ```bash forge test --match-contract DebtRegistryFuzz forge test --match-contract TransferFuzz ``` ### Generate Coverage Report ```bash 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](docs/RUNBOOK.md) for operational procedures including: - Role rotation - Emergency pause procedures - Lien dispute handling - Upgrade procedures - Bridge operator procedures ## License MIT