ModuleRegistry 계약은 Story 생태계 내에서 모듈을 등록하고 추적하는 데 사용됩니다. 이는 모든 프로토콜 모듈의 중앙 레지스트리 역할을 하여 다양한 모듈 유형과 구현의 쉬운 발견과 관리를 가능하게 합니다.

상태 변수

ModuleRegistryStorage

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

ModuleRegistry의 저장소 구조는 다음을 포함합니다:

  • modules: 모듈 이름을 해당 주소에 매핑
  • moduleTypes: 모듈 주소를 해당 유형에 매핑
  • allModuleTypes: 모듈 유형을 해당 인터페이스 ID에 매핑

ModuleRegistryStorageLocation

bytes32 private constant ModuleRegistryStorageLocation

ModuleRegistry 저장소 구조의 저장 위치로, ERC-7201의 네임스페이스 저장 패턴을 따릅니다.

함수

initialize

function initialize(address accessManager) public initializer

ModuleRegistry 계약을 초기화합니다.

Parameters:

  • accessManager: 거버넌스 계약의 주소.

registerModuleType

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

레지스트리에 인터페이스와 연관된 새로운 모듈 유형을 등록합니다.

Parameters:

  • name: 등록할 모듈 유형의 이름.
  • interfaceId: 모듈 유형과 연관된 인터페이스 ID.

removeModuleType

function removeModuleType(string memory name) external override restricted

레지스트리에서 모듈 유형을 제거합니다.

Parameters:

  • name: 제거할 모듈 유형의 이름.

registerModule (기본 유형)

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

기본 모듈 유형으로 레지스트리에 새 모듈을 등록합니다.

Parameters:

  • name: 모듈의 이름.
  • moduleAddress: 모듈의 주소.

registerModule (특정 유형)

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

특정 모듈 유형으로 레지스트리에 새 모듈을 등록합니다.

Parameters:

  • name: 등록할 모듈의 이름.
  • moduleAddress: 모듈의 주소.
  • moduleType: 등록되는 모듈의 유형.

removeModule

function removeModule(string memory name) external restricted

레지스트리에서 모듈을 제거합니다.

Parameters:

  • name: 제거할 모듈의 이름.

isRegistered

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

모듈이 프로토콜에 등록되어 있는지 확인합니다.

Parameters:

  • moduleAddress: 모듈의 주소.

Returns:

  • bool: 모듈이 등록되어 있으면 true, 그렇지 않으면 false.

getModule

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

모듈의 주소를 반환합니다.

Parameters:

  • name: 모듈의 이름.

Returns:

  • address: 모듈의 주소.

getModuleType

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

주어진 모듈 주소의 모듈 유형을 반환합니다.

Parameters:

  • moduleAddress: 모듈의 주소.

Returns:

  • string: 문자열로 된 모듈의 유형.

getModuleTypeInterfaceId

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

주어진 모듈 유형과 연관된 인터페이스 ID를 반환합니다.

Parameters:

  • moduleType: 문자열로 된 모듈의 유형.

Returns:

  • bytes4: 모듈 유형의 인터페이스 ID.

내부 함수

_registerModule

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

레지스트리에 새 모듈을 등록하는 내부 함수.

Parameters:

  • name: 모듈의 이름.
  • moduleAddress: 모듈의 주소.
  • moduleType: 등록되는 모듈의 유형.

_getModuleRegistryStorage

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

ModuleRegistry의 저장소 구조체를 반환합니다.

Returns:

  • ModuleRegistryStorage: ModuleRegistry의 저장소 구조.

_authorizeUpgrade

function _authorizeUpgrade(address newImplementation) internal override restricted

UUPSUpgradeable에 따라 업그레이드를 승인하는 훅.

Parameters:

  • newImplementation: 새 구현의 주소.

이벤트

ModuleAdded

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

새 모듈이 레지스트리에 추가될 때 발생하는 이벤트.

Parameters:

  • name: 모듈의 이름.
  • moduleAddress: 모듈의 주소.
  • moduleTypeInterfaceId: 모듈 유형의 인터페이스 ID.
  • moduleType: 모듈의 유형.

ModuleRemoved

event ModuleRemoved(string name, address moduleAddress)

모듈이 레지스트리에서 제거될 때 발생하는 이벤트.

Parameters:

  • name: 모듈의 이름.
  • moduleAddress: 모듈의 주소.

보안 고려사항

ModuleRegistry 계약은 여러 보안 조치를 구현합니다:

  1. 접근 제어: 대부분의 함수는 restricted 수정자를 통해 프로토콜 관리자만 호출할 수 있도록 제한됩니다.

  2. 입력 유효성 검사: 계약은 모든 입력이 필요한 기준을 충족하는지 확인하기 위해 유효성을 검사합니다:

    • 모듈 주소는 0이 아니어야 하며 계약이어야 합니다
    • 이름과 모듈 유형은 빈 문자열일 수 없습니다
    • 해당 유형의 모듈을 등록하기 전에 모듈 유형이 먼저 등록되어야 합니다
    • 모듈은 해당 유형에 대해 예상되는 인터페이스를 지원해야 합니다
  3. 중복 방지: 계약은 중복 등록을 방지합니다:

    • 동일한 이름으로 모듈 유형을 두 번 등록할 수 없습니다
    • 다른 이름으로 모듈을 두 번 등록할 수 없습니다
    • 하나의 이름을 여러 모듈에 사용할 수 없습니다
  4. 업그레이드 가능성: 계약은 UUPS 패턴을 사용하여 업그레이드 가능하며, 업그레이드 권한은 프로토콜 관리자로 제한됩니다.