> For the complete documentation index, see [llms.txt](https://docs.inverter.network/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.inverter.network/contracts/technical-reference/modules/base/module_v1.sol.md).

# Module\_v1.sol

[Git Source](https://github.com/InverterNetwork/inverter-contracts/blob/649b450f02fc8b735c128ff0821467e71966c666/src/modules/base/Module_v1.sol)

**Inherits:** IModule\_v1, Initializable, ERC2771ContextUpgradeable, ERC165Upgradeable

**Author:** Inverter Network

*This Contract is the basic building block for all Modules in the Inverter Network. It contains references to other contracts, modifier for access restriction, metadata to identify the module type as well as utility functions for general module interactions. This contract provides a framework for triggering and receiving {Orchestrator\_v1} callbacks (via `call`) and a modifier to authenticate callers via the module's {Orchestrator\_v1}. Each module is identified via a unique identifier based on its major version, title, and url given in the metadata.*

### State Variables

#### \_\_Module\_orchestrator

*The module's orchestrator instance.*

```solidity
IOrchestrator_v1 internal __Module_orchestrator;
```

#### \_\_Module\_metadata

*The module's metadata.*

```solidity
Metadata internal __Module_metadata;
```

#### \_\_gap

*Storage gap for future upgrades.*

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

### Functions

#### supportsInterface

*See {IERC165-supportsInterface}.*

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

#### onlyOrchestratorAdmin

*Modifier to guarantee function is only callable by addresses authorized via {Orchestrator\_v1}.*

```solidity
modifier onlyOrchestratorAdmin();
```

#### onlyPaymentClient

*Modifier to guarantee function is only callable by a module registered within the workflows's {Orchestrator\_v1} and the module is implementing the {IERC20PaymentClientBase\_v1} interface.*

```solidity
modifier onlyPaymentClient();
```

#### onlyModuleRole

*Modifier to guarantee function is only callable by addresses that hold a specific module-assigned role.*

```solidity
modifier onlyModuleRole(bytes32 role);
```

#### onlyModuleRoleAdmin

*Modifier to guarantee function is only callable by addresses that hold a specific module-assigned role.*

```solidity
modifier onlyModuleRoleAdmin(bytes32 role);
```

#### onlyOrchestrator

*Modifier to guarantee function is only callable by the {Orchestrator\_v1}.*

*onlyOrchestrator functions MUST only access the module's storage, i.e. `__Module_` variables.*

*Note to use function prefix `__Module_`.*

```solidity
modifier onlyOrchestrator();
```

#### validAddress

*Checks if the given Address is valid.*

```solidity
modifier validAddress(address to);
```

**Parameters**

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

#### constructor

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

#### init

The module's initializer function.

*CAN be overridden by downstream contract.*

```solidity
function init(
    IOrchestrator_v1 orchestrator_,
    Metadata memory metadata,
    bytes memory
) external virtual initializer;
```

**Parameters**

| Name            | Type               | Description            |
| --------------- | ------------------ | ---------------------- |
| `orchestrator_` | `IOrchestrator_v1` |                        |
| `metadata`      | `Metadata`         | The module's metadata. |
| `<none>`        | `bytes`            |                        |

#### \_\_Module\_init

*The initialization function MUST be called by the upstream contract in their overridden `init()` function.*

```solidity
function __Module_init(IOrchestrator_v1 orchestrator_, Metadata memory metadata)
    internal
    onlyInitializing;
```

**Parameters**

| Name            | Type               | Description                      |
| --------------- | ------------------ | -------------------------------- |
| `orchestrator_` | `IOrchestrator_v1` | The module's {Orchestrator\_v1}. |
| `metadata`      | `Metadata`         |                                  |

#### identifier

Returns the module's identifier.

*The identifier is defined as the keccak256 hash of the module's abi packed encoded major version, url and title.*

```solidity
function identifier() public view returns (bytes32);
```

**Returns**

| Name     | Type      | Description              |
| -------- | --------- | ------------------------ |
| `<none>` | `bytes32` | The module's identifier. |

#### version

Returns the module's version.

```solidity
function version() public view returns (uint, uint, uint);
```

**Returns**

| Name     | Type      | Description                 |
| -------- | --------- | --------------------------- |
| `<none>` | `uint256` | The module's major version. |
| `<none>` | `uint256` |                             |
| `<none>` | `uint256` |                             |

#### url

Returns the module's URL.

```solidity
function url() public view returns (string memory);
```

**Returns**

| Name     | Type     | Description       |
| -------- | -------- | ----------------- |
| `<none>` | `string` | The module's URL. |

#### title

Returns the module's title.

```solidity
function title() public view returns (string memory);
```

**Returns**

| Name     | Type     | Description         |
| -------- | -------- | ------------------- |
| `<none>` | `string` | The module's title. |

#### orchestrator

Returns the module's {Orchestrator\_v1} interface, {IOrchestrator\_v1}.

```solidity
function orchestrator() public view returns (IOrchestrator_v1);
```

**Returns**

| Name     | Type               | Description                     |
| -------- | ------------------ | ------------------------------- |
| `<none>` | `IOrchestrator_v1` | The module's {Orchestrator\_1}. |

#### grantModuleRole

Grants a module role to a target address.

```solidity
function grantModuleRole(bytes32 role, address target)
    external
    onlyModuleRoleAdmin(role);
```

**Parameters**

| Name     | Type      | Description                              |
| -------- | --------- | ---------------------------------------- |
| `role`   | `bytes32` | The role to grant.                       |
| `target` | `address` | The target address to grant the role to. |

#### grantModuleRoleBatched

Grants a module role to multiple target addresses.

```solidity
function grantModuleRoleBatched(bytes32 role, address[] calldata targets)
    external
    onlyModuleRoleAdmin(role);
```

**Parameters**

| Name      | Type        | Description                                |
| --------- | ----------- | ------------------------------------------ |
| `role`    | `bytes32`   | The role to grant.                         |
| `targets` | `address[]` | The target addresses to grant the role to. |

#### revokeModuleRole

Revokes a module role from a target address.

```solidity
function revokeModuleRole(bytes32 role, address target)
    external
    onlyModuleRoleAdmin(role);
```

**Parameters**

| Name     | Type      | Description                                 |
| -------- | --------- | ------------------------------------------- |
| `role`   | `bytes32` | The role to revoke.                         |
| `target` | `address` | The target address to revoke the role from. |

#### revokeModuleRoleBatched

Revokes a module role from multiple target addresses.

```solidity
function revokeModuleRoleBatched(bytes32 role, address[] calldata targets)
    external
    onlyModuleRoleAdmin(role);
```

**Parameters**

| Name      | Type        | Description                                   |
| --------- | ----------- | --------------------------------------------- |
| `role`    | `bytes32`   | The role to revoke.                           |
| `targets` | `address[]` | The target addresses to revoke the role from. |

#### \_getFeeManagerCollateralFeeData

Returns the collateral fee for the specified workflow module function and the according treasury address of this workflow.

*FunctionSelector is always passed as selector of this module / address.*

```solidity
function _getFeeManagerCollateralFeeData(bytes4 functionSelector)
    internal
    view
    returns (uint fee, address treasury);
```

**Parameters**

| Name               | Type     | Description                                   |
| ------------------ | -------- | --------------------------------------------- |
| `functionSelector` | `bytes4` | The function selector of the target function. |

**Returns**

| Name       | Type      | Description                                                               |
| ---------- | --------- | ------------------------------------------------------------------------- |
| `fee`      | `uint256` | The collateral fee amount in relation to the BPS of the {FeeManager\_v1}. |
| `treasury` | `address` | The address of the treasury.                                              |

#### \_getFeeManagerIssuanceFeeData

Returns the issuance fee for the specified workflow module function and the according treasury address of this workflow.

*FunctionSelector is always passed as selector of this module / address.*

```solidity
function _getFeeManagerIssuanceFeeData(bytes4 functionSelector)
    internal
    view
    returns (uint fee, address treasury);
```

**Parameters**

| Name               | Type     | Description                                   |
| ------------------ | -------- | --------------------------------------------- |
| `functionSelector` | `bytes4` | The function selector of the target function. |

**Returns**

| Name       | Type      | Description                                                             |
| ---------- | --------- | ----------------------------------------------------------------------- |
| `fee`      | `uint256` | The issuance fee amount in relation to the BPS of the {FeeManager\_v1}. |
| `treasury` | `address` | The address of the treasury.                                            |

#### \_checkRoleModifier

*Checks if the caller has the specified role.*

```solidity
function _checkRoleModifier(bytes32 role, address addr) internal view;
```

**Parameters**

| Name   | Type      | Description           |
| ------ | --------- | --------------------- |
| `role` | `bytes32` | The role to check.    |
| `addr` | `address` | The address to check. |

#### \_onlyOrchestratorModifier

*Checks if the caller is the orchestrator.*

```solidity
function _onlyOrchestratorModifier() internal view;
```

#### \_validAddressModifier

*Checks if the given address is an valid address.*

```solidity
function _validAddressModifier(address to) internal view;
```

**Parameters**

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

#### \_onlyPaymentClientModifier

*Checks if the caller is an {ERC20PaymentClientBase\_v1} module.*

```solidity
function _onlyPaymentClientModifier() internal view;
```

#### isTrustedForwarder

Checks if the provided address is the trusted forwarder.

*We imitate here the EIP2771 Standard to enable metatransactions As it currently stands we dont want to feed the forwarder address to each module individually and we decided to move this to the orchestrator.*

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

**Parameters**

| Name        | Type      | Description                          |
| ----------- | --------- | ------------------------------------ |
| `forwarder` | `address` | The contract address to be verified. |

**Returns**

| Name     | Type   | Description                                      |
| -------- | ------ | ------------------------------------------------ |
| `<none>` | `bool` | bool Is the given address the trusted forwarder. |

#### trustedForwarder

Returns the trusted forwarder.

*We imitate here the EIP2771 Standard to enable metatransactions. As it currently stands we dont want to feed the forwarder address to each module individually and we decided to move this to the orchestrator.*

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

**Returns**

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