RealTokenFactory.sol

Overview

RealTokenFactory standardizes deployment of RealFractionalToken series. The base version uses a plain new constructor for simplicity; you can extend it to CREATE2 or minimal proxies (clones) if you need deterministic addresses or cheaper deployments.


Responsibilities

  • Deploy a new token with the correct admin and compliance registry wired in the constructor.

  • Emit a structured event so indexers (subgraphs, ETLs) can track the new series.


Contract Boundary and Data Flow

(deployer/admin) ──> RealTokenFactory.deployToken(name, symbol, admin, registry)

                        └─ deploys RealFractionalToken(name, symbol, admin, registry)

                              └─ emits TokenDeployed(token, name, symbol, admin, registry)

Key Components

  • Constructor Deployment: new RealFractionalToken(...) (straightforward and auditable).

  • Events: TokenDeployed includes all relevant metadata to bootstrap off-chain systems.


Optional Extensions (Patterns)

  • CREATE2 (Deterministic): pre-compute addresses for downstream wiring (e.g., granting roles before the token exists).

    • Add salt = keccak256(abi.encode(...)) and a bytecode deploy wrapper.

  • Minimal Proxy (Clones): if you deploy many series, use OZ Clones to reduce gas.

    • Convert token to an initialize pattern (or an upgradeable proxy) and add clone/initialize flow in the factory.

  • Registry Pinning: add allowlist of registries the factory can use.


Interactions With Other Modules

  • After deploying the token, your OfferingFactory (or ops script) should:

    • Grant MINTER_ROLE to RealOffering (or to the address predicted with CREATE2).

    • Optionally, grant BURNER_ROLE to redemption contracts or admin.

    • Grant PAUSER_ROLE to ops/multisig.


Security Considerations

  • If you add access control to the factory (e.g., only approved issuers), gate deployToken.

  • Validate constructor args (non-zero admin/registry).

  • If you adopt CREATE2, ensure salts don’t collide across issuers.


Gas Notes

  • The simple new path has predictable gas and minimal runtime overhead.

  • Clones reduce deployment gas drastically but add an initializer call—be careful with initializer-only-once guards.


Minimal Usage Examples

// deploy a new series
address token = factory.deployToken(
  "Asset A Fractions", "ASST-A", admin, complianceRegistry
);

// wire roles to primary market
RealFractionalToken(token).grantRole(MINTER_ROLE, offering);

Example: CREATE2 Sketch (if you choose to extend)

// pseudo: using a deployer that supports create2
function deployTokenDeterministic(
  string calldata name_,
  string calldata symbol_,
  address admin_,
  address registry_,
  bytes32 salt
) external returns (address token) {
  // build creationCode: type(RealFractionalToken).creationCode ++ encoded ctor args
  // call create2(salt)
}

How They Fit Together

  1. Factory deploys Token

    • RealTokenFactory.deployToken(...) → emits TokenDeployed.

  2. Grant Roles

    • Admin grants MINTER_ROLE to RealOffering (primary), RealStakingDistributor (yield), RealLending (liquidations or redemptions, if needed).

  3. Operations

    • Transfers, mints, and burns always call into the Compliance Registry.

    • Ops can pause during critical events.

  4. Evolution

    • Swap out registry as rules evolve (REGISTRY_ADMIN_ROLE).

    • Introduce fees/timelocks/snapshots as optional, contained changes.


RealTokenFactory.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import {RealFractionalToken} from "./RealFractionalToken.sol";

/// @title RealTokenFactory
/// @notice Deploys new RealFractionalToken contracts for asset series.
/// @dev Keeps deployments standardized with consistent admin and registry setup.
contract RealTokenFactory {
    /// @notice Emitted when a new token is deployed.
    event TokenDeployed(
        address indexed token,
        string name,
        string symbol,
        address indexed admin,
        address indexed registry
    );

    /// @notice Deploy a new RealFractionalToken for a specific asset.
    /// @param name_ Token name (e.g. "Asset A Fractions")
    /// @param symbol_ Token symbol (e.g. "ASST-A")
    /// @param admin_ Address to receive DEFAULT_ADMIN_ROLE and other roles
    /// @param registry_ Address of the compliance registry
    /// @return token Address of the newly deployed RealFractionalToken
    function deployToken(
        string calldata name_,
        string calldata symbol_,
        address admin_,
        address registry_
    ) external returns (address token) {
        RealFractionalToken t = new RealFractionalToken(
            name_,
            symbol_,
            admin_,
            registry_
        );
        token = address(t);

        emit TokenDeployed(token, name_, symbol_, admin_, registry_);
    }
}

Last updated