Files
gru_emoney_token-factory/docs/RUNBOOK.md
defiQUG 651ff4f7eb Initial project setup: Add contracts, API definitions, tests, and documentation
- Add Foundry project configuration (foundry.toml, foundry.lock)
- Add Solidity contracts (TokenFactory138, BridgeVault138, ComplianceRegistry, etc.)
- Add API definitions (OpenAPI, GraphQL, gRPC, AsyncAPI)
- Add comprehensive test suite (unit, integration, fuzz, invariants)
- Add API services (REST, GraphQL, orchestrator, packet service)
- Add documentation (ISO20022 mapping, runbooks, adapter guides)
- Add development tools (RBC tool, Swagger UI, mock server)
- Update OpenZeppelin submodules to v5.0.0
2025-12-12 10:59:41 -08:00

8.8 KiB

Operational Runbook: eMoney Token Factory

This runbook provides procedures for operating the eMoney Token Factory system on ChainID 138.

Table of Contents

  1. Role Rotation
  2. Emergency Pause Procedures
  3. Lien Dispute Handling
  4. Upgrade Procedures (UUPS)
  5. Bridge Operator Procedures

Role Rotation

Overview

All admin roles should be managed by multisigs. This section describes the process for rotating role assignments.

Prerequisites

  • Access to governance multisig
  • New role holder address(es)
  • Verification that new addresses are correct

Procedure: Rotate Governance Admin

Warning: Only rotate if absolutely necessary. Governance admin has root access.

  1. Prepare multisig transaction:

    • Call: ComplianceRegistry.revokeRole(DEFAULT_ADMIN_ROLE, oldAdmin)
    • Call: ComplianceRegistry.grantRole(DEFAULT_ADMIN_ROLE, newAdmin)
    • Repeat for all core contracts (DebtRegistry, PolicyManager, TokenFactory138, BridgeVault138)
  2. Submit multisig transaction

  3. Verify:

    • Old admin cannot execute admin functions
    • New admin can execute admin functions

Procedure: Rotate Other Roles

For non-admin roles (e.g., POLICY_OPERATOR_ROLE, COMPLIANCE_ROLE):

  1. Revoke old role holder
  2. Grant new role holder
  3. Verify functionality

Example for Compliance Role:

// Revoke
complianceRegistry.revokeRole(COMPLIANCE_ROLE, oldComplianceOperator);

// Grant
complianceRegistry.grantRole(COMPLIANCE_ROLE, newComplianceOperator);

// Verify
require(complianceRegistry.hasRole(COMPLIANCE_ROLE, newComplianceOperator));

Emergency Pause Procedures

Scenario: Pause a Single Token

When a vulnerability or incident affects a specific token:

  1. Identify Token Address

    • Confirm token contract address
  2. Pause Token

    policyManager.setPaused(tokenAddress, true);
    
    • Requires: POLICY_OPERATOR_ROLE
  3. Verify Pause

    • Attempt transfer should revert with PAUSED reason code
  4. Monitor

    • Monitor for any bypass attempts
    • Coordinate with token issuer
  5. Resume (after resolution)

    policyManager.setPaused(tokenAddress, false);
    

Scenario: System-Wide Emergency

If a critical vulnerability affects the entire system:

  1. Pause All Active Tokens

    • Iterate through all deployed tokens
    • Call setPaused for each
  2. Notify Stakeholders

    • Token issuers
    • Compliance team
    • Bridge operators
  3. Investigation

    • Root cause analysis
    • Impact assessment
  4. Resolution

    • Deploy fix if needed (see Upgrade Procedures)
    • Gradually resume tokens after verification

Lien Dispute Handling

Overview

Liens can be placed by authorized debt instruments or judicial/sovereign actors. This section covers dispute resolution.

Lien Lifecycle

  1. Placement: DebtRegistry.placeLien(debtor, amount, expiry, priority, reasonCode)

    • Requires: DEBT_AUTHORITY_ROLE
    • Emits: LienPlaced event
  2. Reduction: DebtRegistry.reduceLien(lienId, reduceBy)

    • Requires: DEBT_AUTHORITY_ROLE
    • Emits: LienReduced event
  3. Release: DebtRegistry.releaseLien(lienId)

    • Requires: DEBT_AUTHORITY_ROLE
    • Emits: LienReleased event

Dispute Resolution Process

Step 1: Gather Information

Query lien details:

Lien memory lien = debtRegistry.getLien(lienId);
// lien.debtor
// lien.amount
// lien.authority
// lien.reasonCode
// lien.expiry

Step 2: Verify Authority

  • Confirm lien.authority has DEBT_AUTHORITY_ROLE
  • Review reason code and supporting documentation

Step 3: Resolution Actions

If lien is invalid:

  • Contact authority to release: debtRegistry.releaseLien(lienId)
  • If authority is unresponsive, escalate to governance

If lien amount is incorrect:

  • Contact authority to reduce: debtRegistry.reduceLien(lienId, correctAmount)

If lien should be extended:

  • Authority can place additional lien if needed

Best Practices

  1. Documentation: All liens should have off-chain documentation
  2. Expiry Tracking: Monitor expiry dates (informational only - explicit release required)
  3. Audit Trail: All lien operations emit events for indexing

Upgrade Procedures (UUPS)

Overview

Token implementations use UUPS (Universal Upgradeable Proxy Standard). This allows upgrading token logic while preserving state.

Prerequisites

  • New implementation contract deployed
  • Governance multisig approval
  • Verification of new implementation

Upgrade Process

Step 1: Deploy New Implementation

eMoneyToken newImplementation = new eMoneyToken();

Step 2: Verify Implementation

  • Review new implementation code
  • Run test suite against new implementation
  • Verify storage layout compatibility (no storage variable changes)

Step 3: Execute Upgrade

For each token proxy:

eMoneyToken(tokenAddress).upgradeTo(address(newImplementation));

Requires: DEFAULT_ADMIN_ROLE on the token (held by issuer)

Step 4: Verify Upgrade

  1. Check implementation address:

    bytes32 slot = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
    address impl = address(uint160(uint256(vm.load(tokenAddress, slot))));
    require(impl == address(newImplementation));
    
  2. Test functionality:

    • Verify transfers work
    • Verify lien enforcement
    • Verify privileged functions

Storage Layout Safety

Critical: Never change storage variable order or types between upgrades. Only append new variables.

Safe Changes:

  • Adding new functions
  • Modifying function logic (not storage layout)
  • Adding new storage variables at the end

Unsafe Changes:

  • Reordering storage variables
  • Changing storage variable types
  • Removing storage variables

Rollback Procedure

If upgrade causes issues:

  1. Immediate: Pause affected tokens
  2. Deploy: Previous implementation (if not overwritten)
  3. Execute: upgradeTo(previousImplementation)
  4. Verify: Functionality restored

Bridge Operator Procedures

Overview

Bridge operators manage the lock/unlock process for public chain representation.

Lock Procedure

Users initiate locks:

bridgeVault.lock(token, amount, targetChain, targetRecipient);

This:

  1. Transfers tokens to BridgeVault138
  2. Checks PolicyManager for transfer authorization (enforces liens)
  3. Emits Locked event

Operator Actions:

  • Monitor Locked events
  • Initiate mint on target chain (off-chain)
  • Track lock records

Unlock Procedure

Operators authorize unlocks after verifying proof from source chain:

bridgeVault.unlock(token, recipient, amount, sourceChain, sourceTx);

Current Implementation: Placeholder for light client verification

Production Requirements:

  1. Integrate light client contract
  2. Verify proof via light client
  3. Check compliance status
  4. Transfer tokens to recipient

Light Client Integration

To integrate a light client:

  1. Deploy light client contract (or use existing)

  2. Set light client address:

    bridgeVault.setLightClient(lightClientAddress);
    

    Requires: DEFAULT_ADMIN_ROLE

  3. Update unlock function to pass proof data:

    // Modify unlock signature to include proof
    function unlock(
        address token,
        address to,
        uint256 amount,
        bytes32 sourceChain,
        bytes32 sourceTx,
        bytes calldata proof
    ) external onlyRole(BRIDGE_OPERATOR_ROLE) {
        require(lightClient.verifyProof(sourceChain, sourceTx, proof), "Invalid proof");
        // ... rest of unlock logic
    }
    

Security Considerations

  1. Proof Verification: Always verify proofs on-chain
  2. Operator Key Management: Use hardware wallets or multisig
  3. Rate Limiting: Consider rate limits for unlocks
  4. Monitoring: Monitor for suspicious unlock patterns

Appendix: Quick Reference

Common Operations

Pause Token:

policyManager.setPaused(token, true);

Place Lien:

debtRegistry.placeLien(debtor, amount, expiry, priority, reasonCode);

Check Free Balance:

token.freeBalanceOf(account);

Check Active Lien Amount:

debtRegistry.activeLienAmount(account);

Event Monitoring

Key events to monitor:

  • LienPlaced / LienReduced / LienReleased
  • TokenPaused
  • ComplianceUpdated / FrozenUpdated
  • Locked / Unlocked
  • TransferBlocked (custom error, check revert reasons)

Support Contacts

  • Governance: [Multisig Address]
  • Compliance: [Compliance Team Contact]
  • Technical: [Technical Team Contact]
  • Emergency: [Emergency Contact]

Document Version: 1.0
Last Updated: [Date]
Next Review: [Date]