The ModuleRegistry contract is used to register and track modules within the Story ecosystem. It serves as a central registry for all protocol modules, allowing for easy discovery and management of different module types and implementations.

State Variables

ModuleRegistryStorage

struct ModuleRegistryStorage {
    mapping(string moduleName => address moduleAddress) modules;
    mapping(address moduleAddress => string moduleType) moduleTypes;
    mapping(string moduleType => bytes4 moduleTypeInterface) allModuleTypes;
}

Storage structure for the ModuleRegistry containing:

  • modules: Maps module names to their addresses
  • moduleTypes: Maps module addresses to their types
  • allModuleTypes: Maps module types to their interface IDs

ModuleRegistryStorageLocation

bytes32 private constant ModuleRegistryStorageLocation

The storage location for the ModuleRegistry storage structure, following ERC-7201 for namespace storage pattern.

Functions

initialize

function initialize(address accessManager) public initializer

Initializes the ModuleRegistry contract.

Parameters:

  • accessManager: The address of the governance contract.

registerModuleType

function registerModuleType(string memory name, bytes4 interfaceId) external override restricted

Registers a new module type in the registry associated with an interface.

Parameters:

  • name: The name of the module type to be registered.
  • interfaceId: The interface ID associated with the module type.

removeModuleType

function removeModuleType(string memory name) external override restricted

Removes a module type from the registry.

Parameters:

  • name: The name of the module type to be removed.

registerModule (Default Type)

function registerModule(string memory name, address moduleAddress) external restricted

Registers a new module in the registry with the default module type.

Parameters:

  • name: The name of the module.
  • moduleAddress: The address of the module.

registerModule (Specific Type)

function registerModule(string memory name, address moduleAddress, string memory moduleType) external restricted

Registers a new module in the registry with a specific module type.

Parameters:

  • name: The name of the module to be registered.
  • moduleAddress: The address of the module.
  • moduleType: The type of the module being registered.

removeModule

function removeModule(string memory name) external restricted

Removes a module from the registry.

Parameters:

  • name: The name of the module to be removed.

isRegistered

function isRegistered(address moduleAddress) external view returns (bool)

Checks if a module is registered in the protocol.

Parameters:

  • moduleAddress: The address of the module.

Returns:

  • bool: True if the module is registered, false otherwise.

getModule

function getModule(string memory name) external view returns (address)

Returns the address of a module.

Parameters:

  • name: The name of the module.

Returns:

  • address: The address of the module.

getModuleType

function getModuleType(address moduleAddress) external view returns (string memory)

Returns the module type of a given module address.

Parameters:

  • moduleAddress: The address of the module.

Returns:

  • string: The type of the module as a string.

getModuleTypeInterfaceId

function getModuleTypeInterfaceId(string memory moduleType) external view returns (bytes4)

Returns the interface ID associated with a given module type.

Parameters:

  • moduleType: The type of the module as a string.

Returns:

  • bytes4: The interface ID of the module type.

Internal Functions

_registerModule

function _registerModule(string memory name, address moduleAddress, string memory moduleType) internal

Internal function to register a new module in the registry.

Parameters:

  • name: The name of the module.
  • moduleAddress: The address of the module.
  • moduleType: The type of the module being registered.

_getModuleRegistryStorage

function _getModuleRegistryStorage() private pure returns (ModuleRegistryStorage storage $)

Returns the storage struct of the ModuleRegistry.

Returns:

  • ModuleRegistryStorage: The storage structure for the ModuleRegistry.

_authorizeUpgrade

function _authorizeUpgrade(address newImplementation) internal override restricted

Hook to authorize the upgrade according to UUPSUpgradeable.

Parameters:

  • newImplementation: The address of the new implementation.

Events

ModuleAdded

event ModuleAdded(string name, address moduleAddress, bytes4 moduleTypeInterfaceId, string moduleType)

Emitted when a new module is added to the registry.

Parameters:

  • name: The name of the module.
  • moduleAddress: The address of the module.
  • moduleTypeInterfaceId: The interface ID of the module type.
  • moduleType: The type of the module.

ModuleRemoved

event ModuleRemoved(string name, address moduleAddress)

Emitted when a module is removed from the registry.

Parameters:

  • name: The name of the module.
  • moduleAddress: The address of the module.

Security Considerations

The ModuleRegistry contract implements several security measures:

  1. Access Control: Most functions are restricted to be called only by the protocol admin through the restricted modifier.

  2. Input Validation: The contract validates all inputs to ensure they meet the required criteria:

    • Module addresses must be non-zero and must be contracts
    • Names and module types cannot be empty strings
    • Module types must be registered before modules of that type can be registered
    • Modules must support the expected interface for their type
  3. Duplicate Prevention: The contract prevents duplicate registrations:

    • A module type cannot be registered twice with the same name
    • A module cannot be registered twice with different names
    • A name cannot be used for multiple modules
  4. Upgradability: The contract is upgradable using the UUPS pattern, with upgrade authorization restricted to the protocol admin.