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.