# 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. |
