# ModuleManagerBase\_v1.sol

[Git Source](https://github.com/InverterNetwork/inverter-contracts/blob/2a8a4c80ff4f24a59546d4e6126b81bc51228c94/src/orchestrator/abstracts/ModuleManagerBase_v1.sol)

**Inherits:** [IModuleManagerBase\_v1](https://docs.inverter.network/contracts/technical-reference/orchestrator/interfaces/imodulemanagerbase_v1.sol), [Initializable](https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/22489db15621b9a42ebddb1facade6962034e9b9/contracts/proxy/utils/Initializable.sol), [ERC2771ContextUpgradeable](https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/f1b3e103cd6d48861e71357a7ac32b416c1b066f/contracts/metatx/ERC2771ContextUpgradeable.sol), [ERC165Upgradeable](https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/52f6007348edc34304e9de9dc39cfbeb9ef314b9/contracts/utils/introspection/ERC165Upgradeable.sol)

**Author:** Inverter Network Adapted from Gnosis Safe

*A contract to manage Inverter Network modules. It allows for adding and removing modules in a local registry for reference. Additional functionality includes the execution of calls from this contract. The transaction execution and module management is copied from Gnosis Safe's* [*ModuleManager*](https://github.com/safe-global/safe-contracts/blob/main/contracts/base/ModuleManager.sol)*.*

### State Variables

#### MAX\_MODULE\_AMOUNT

*Marks the maximum amount of Modules a* [*{Orchestrator\_v1}*](https://docs.inverter.network/contracts/technical-reference/orchestrator/orchestrator_v1.sol) *can have to avoid out-of-gas risk.*

```solidity
uint private constant MAX_MODULE_AMOUNT = 128;
```

#### MODULE\_UPDATE\_TIMELOCK

*Timelock used between initiating adding or removing a module and executing it.*

```solidity
uint public constant MODULE_UPDATE_TIMELOCK = 72 hours;
```

#### moduleFactory

[*{ModuleFactory\_v1}*](https://docs.inverter.network/contracts/technical-reference/factories/modulefactory_v1.sol)*.*

```solidity
address public moduleFactory;
```

#### \_modules

*List of modules.*

```solidity
address[] private _modules;
```

#### \_isModule

*Mapping to keep track of whether a module is used in the* [*{Orchestrator\_v1}*](https://docs.inverter.network/contracts/technical-reference/orchestrator/orchestrator_v1.sol) *address => isModule.*

```solidity
mapping(address => bool) private _isModule;
```

#### moduleAddressToTimelock

*Mapping to keep track of active timelocks for updating modules module => timelock.*

```solidity
mapping(address module => ModuleUpdateTimelock timelock) public
    moduleAddressToTimelock;
```

#### \_\_gap

*Storage gap for future upgrades.*

```solidity
uint[50] private __gap;
```

### Functions

#### supportsInterface

*See* [*{IERC165-supportsInterface}*](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/19a657bef8354f2a655900654955739b70dfbde9/contracts/utils/introspection/IERC165.sol#L24)*.*

```solidity
function supportsInterface(bytes4 interfaceId)
    public
    view
    virtual
    override(ERC165Upgradeable)
    returns (bool);
```

#### \_\_ModuleManager\_onlyAuthorized

*Modifier to guarantee function is only callable by authorized address.*

```solidity
modifier __ModuleManager_onlyAuthorized();
```

#### onlyModule

*Modifier to guarantee that the caller is a module.*

```solidity
modifier onlyModule();
```

#### validModule

*Modifier to guarantee that the given module is a valid module.*

```solidity
modifier validModule(address module);
```

#### isModule\_

*Modifier to guarantee that the given module is a registered module.*

```solidity
modifier isModule_(address module);
```

#### isNotModule

*Modifier to guarantee that the given module is not a registered module.*

```solidity
modifier isNotModule(address module);
```

#### moduleLimitNotExceeded

*Modifier to guarantee that the number of modules is not exceeded.*

```solidity
modifier moduleLimitNotExceeded();
```

#### updatingModuleAlreadyStarted

*Modifier to guarantee that the given module is not already being updated.*

```solidity
modifier updatingModuleAlreadyStarted(address _module);
```

#### timelockExpired

*Modifier to guarantee that the timelock for the given module is expired.*

```solidity
modifier timelockExpired(address _module);
```

#### constructor

```solidity
constructor(address _trustedForwarder)
    ERC2771ContextUpgradeable(_trustedForwarder);
```

#### \_\_ModuleManager\_init

Initialization function.

*Only callable during initialization.*

```solidity
function __ModuleManager_init(
    address _moduleFactory,
    address[] calldata modules
) internal onlyInitializing;
```

**Parameters**

| Name             | Type        | Description                                            |
| ---------------- | ----------- | ------------------------------------------------------ |
| `_moduleFactory` | `address`   | The address of the module factory.                     |
| `modules`        | `address[]` | The addresses of the modules used in the orchestrator. |

#### \_\_ModuleManager\_addModule

Adds address `module` as module.

```solidity
function __ModuleManager_addModule(address module)
    internal
    isNotModule(module)
    validModule(module)
    moduleLimitNotExceeded;
```

**Parameters**

| Name     | Type      | Description                |
| -------- | --------- | -------------------------- |
| `module` | `address` | The module address to add. |

#### \_\_ModuleManager\_isAuthorized

*Returns whether address `who` is authorized to mutate module manager's state.*

*MUST be overridden in downstream contract.*

```solidity
function __ModuleManager_isAuthorized(address who)
    internal
    view
    virtual
    returns (bool);
```

**Parameters**

| Name  | Type      | Description           |
| ----- | --------- | --------------------- |
| `who` | `address` | The address to check. |

**Returns**

| Name     | Type   | Description                                         |
| -------- | ------ | --------------------------------------------------- |
| `<none>` | `bool` | True if the address is authorized, false otherwise. |

#### isModule

Returns whether the address `module` is added as module.

```solidity
function isModule(address module)
    public
    view
    override(IModuleManagerBase_v1)
    returns (bool);
```

**Parameters**

| Name     | Type      | Description          |
| -------- | --------- | -------------------- |
| `module` | `address` | The module to check. |

**Returns**

| Name     | Type   | Description                            |
| -------- | ------ | -------------------------------------- |
| `<none>` | `bool` | True if module added, false otherwise. |

#### listModules

Returns the list of all modules.

```solidity
function listModules() public view returns (address[] memory);
```

**Returns**

| Name     | Type        | Description          |
| -------- | ----------- | -------------------- |
| `<none>` | `address[]` | List of all modules. |

#### modulesSize

Returns the number of modules.

```solidity
function modulesSize() external view returns (uint8);
```

**Returns**

| Name     | Type    | Description            |
| -------- | ------- | ---------------------- |
| `<none>` | `uint8` | The number of modules. |

#### \_cancelModuleUpdate

Cancels an initiated update for a module.

*Only callable by authorized address.*

*Fails if module update has not been initiated.*

```solidity
function _cancelModuleUpdate(address module)
    internal
    __ModuleManager_onlyAuthorized
    updatingModuleAlreadyStarted(module);
```

**Parameters**

| Name     | Type      | Description                   |
| -------- | --------- | ----------------------------- |
| `module` | `address` | The module address to remove. |

#### \_initiateAddModuleWithTimelock

Initiates adding of a module to the [{Orchestrator\_v1}](https://docs.inverter.network/contracts/technical-reference/orchestrator/orchestrator_v1.sol) on a timelock.

*Only callable by authorized address.*

*Fails of adding module exeeds max modules limit.*

*Fails if address invalid or address already added as module.*

```solidity
function _initiateAddModuleWithTimelock(address module)
    internal
    __ModuleManager_onlyAuthorized
    isNotModule(module)
    validModule(module);
```

**Parameters**

| Name     | Type      | Description                |
| -------- | --------- | -------------------------- |
| `module` | `address` | The module address to add. |

#### \_initiateRemoveModuleWithTimelock

Initiates removing of a module from the [{Orchestrator\_v1}](https://docs.inverter.network/contracts/technical-reference/orchestrator/orchestrator_v1.sol) on a timelock.

*Only callable by authorized address.*

*Fails if address not added as module.*

```solidity
function _initiateRemoveModuleWithTimelock(address module)
    internal
    __ModuleManager_onlyAuthorized
    isModule_(module);
```

**Parameters**

| Name     | Type      | Description                   |
| -------- | --------- | ----------------------------- |
| `module` | `address` | The module address to remove. |

#### \_executeAddModule

Executes adding of a module to the [{Orchestrator\_v1}](https://docs.inverter.network/contracts/technical-reference/orchestrator/orchestrator_v1.sol).

*Only callable by authorized address.*

*Fails if adding of module has not been initiated.*

*Fails if timelock has not been expired yet.*

```solidity
function _executeAddModule(address module)
    internal
    __ModuleManager_onlyAuthorized
    updatingModuleAlreadyStarted(module)
    timelockExpired(module);
```

**Parameters**

| Name     | Type      | Description                |
| -------- | --------- | -------------------------- |
| `module` | `address` | The module address to add. |

#### \_executeRemoveModule

Executes removing of a module from the [{Orchestrator\_v1}](https://docs.inverter.network/contracts/technical-reference/orchestrator/orchestrator_v1.sol).

*Only callable by authorized address.*

*Fails if removing of module has not been initiated.*

*Fails if timelock has not been expired yet.*

```solidity
function _executeRemoveModule(address module)
    internal
    __ModuleManager_onlyAuthorized
    updatingModuleAlreadyStarted(module)
    timelockExpired(module);
```

**Parameters**

| Name     | Type      | Description                   |
| -------- | --------- | ----------------------------- |
| `module` | `address` | The module address to remove. |

#### \_commitAddModule

*Expects `module` to be valid module address.*

*Expects `module` to not be enabled module.*

```solidity
function _commitAddModule(address module) internal;
```

**Parameters**

| Name     | Type      | Description                |
| -------- | --------- | -------------------------- |
| `module` | `address` | The module address to add. |

#### \_commitRemoveModule

*Expects address arguments to be consecutive in the modules list.*

*Expects address `module` to be enabled module.*

```solidity
function _commitRemoveModule(address module) private;
```

**Parameters**

| Name     | Type      | Description                   |
| -------- | --------- | ----------------------------- |
| `module` | `address` | The module address to remove. |

#### \_ensureValidModule

*Ensures that the given module is a valid module.*

*Reverts if the module is invalid.*

```solidity
function _ensureValidModule(address module) private view;
```

**Parameters**

| Name     | Type      | Description                  |
| -------- | --------- | ---------------------------- |
| `module` | `address` | The module address to check. |

#### \_ensureNotModule

*Ensures that the given module is not a registered module.*

*Reverts if the module is registered.*

```solidity
function _ensureNotModule(address module) private view;
```

**Parameters**

| Name     | Type      | Description                  |
| -------- | --------- | ---------------------------- |
| `module` | `address` | The module address to check. |

#### \_startModuleUpdateTimelock

*Starts the timelock for the given module.*

```solidity
function _startModuleUpdateTimelock(address _module) internal;
```

**Parameters**

| Name      | Type      | Description                                   |
| --------- | --------- | --------------------------------------------- |
| `_module` | `address` | The module address to start the timelock for. |

#### isTrustedForwarder

Returns wether the given address is the trusted forwarder or not.

*Exposes the ERC2771 isTrusted Forwarder.*

```solidity
function isTrustedForwarder(address forwarder)
    public
    view
    virtual
    override(IModuleManagerBase_v1, ERC2771ContextUpgradeable)
    returns (bool);
```

**Parameters**

| Name        | Type      | Description           |
| ----------- | --------- | --------------------- |
| `forwarder` | `address` | The address to check. |

**Returns**

| Name     | Type   | Description                                                    |
| -------- | ------ | -------------------------------------------------------------- |
| `<none>` | `bool` | True if the address is the trusted forwarder, false otherwise. |

#### trustedForwarder

Returns the trusted forwarder for metatransactions.

*Exposes the ERC2771 isTrusted Forwarder.*

```solidity
function trustedForwarder()
    public
    view
    virtual
    override(IModuleManagerBase_v1, ERC2771ContextUpgradeable)
    returns (address);
```

**Returns**

| Name     | Type      | Description                    |
| -------- | --------- | ------------------------------ |
| `<none>` | `address` | The trusted forwarder address. |


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.inverter.network/contracts/technical-reference/orchestrator/abstracts/modulemanagerbase_v1.sol.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
