# Getting Started

Inverter Protocol is a token programmability protocol that enables programmable issuance and tokens flows between parties. The protocol is designed to support any project or use case that requires launching a token and defining its economy between participating entities while ensuring openness, adaptability, and ease of use.

<table data-card-size="large" data-view="cards" data-full-width="true"><thead><tr><th></th><th></th><th data-hidden data-card-cover data-type="files"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Concepts</strong></td><td>Learn more about how Inverter works</td><td><a href="/files/qPwBC8UpsfNJ7Kgd4Vrp">/files/qPwBC8UpsfNJ7Kgd4Vrp</a></td><td><a href="/pages/zWs3QLUGqrPUGdXTgV2o">/pages/zWs3QLUGqrPUGdXTgV2o</a></td></tr><tr><td><strong>SDK</strong></td><td>Start using our various SDK's </td><td><a href="/files/7Lto0K0D1ltFzBBDOyiV">/files/7Lto0K0D1ltFzBBDOyiV</a></td><td><a href="/pages/uFZzIuomULyj58h6bBOb">/pages/uFZzIuomULyj58h6bBOb</a></td></tr><tr><td><strong>Contracts</strong></td><td>Explore Inverter’s smart contracts</td><td><a href="/files/5H78wQEtzK3kg8fsEFHA">/files/5H78wQEtzK3kg8fsEFHA</a></td><td><a href="/pages/km63vXg39p9hoGwLyqn2">/pages/km63vXg39p9hoGwLyqn2</a></td></tr><tr><td><strong>Support</strong></td><td>Get help and find answers to your questions</td><td><a href="/files/fEsEbmv1LdTzwPXa1ObL">/files/fEsEbmv1LdTzwPXa1ObL</a></td><td><a href="/pages/Ugadk1zP8bg0hEXkF9gn">/pages/Ugadk1zP8bg0hEXkF9gn</a></td></tr></tbody></table>


# Concepts


# What is Inverter Network

<figure><img src="/files/gcJ5XNOdbvRxLmQ9olF9" alt=""><figcaption></figcaption></figure>

### What is Inverter Protocol?

The Inverter Protocol is a novel framework built on the Ethereum blockchain, enabling customizable and dynamic token economies. Its primary aim is to address the complexities and rigidities of current decentralized systems by providing a scalable and modular solution adaptable to various use cases.

### Vision

We belive that dynamic issuance plays a foundation role in making tokens more effective, efficient, and expressive. It is via dynamic issuance that a robust groundwork for tokens' wider utility and application is established. With this foundation, tokens can be capable of adapting to ever-evolving market conditions and extending capabilities based on new goals while maintaining coherence and sustainability throughout their lifecycle. Such dynamism unlocks the full potential of tokenization and can foster a future where blockchain genuinely transforms economies and coordination systems worldwide. With this realization, Inverter emerges as a protocol to enable fully programmable tokens.

### Mission

Inverter's mission is to advance token economies and modular system designs through its Primary Issuance Market (PIM) stack and Open Library of Modules. By minimizing barriers to innovation, Inverter enables developers, mechanism designers, and researchers to create sophisticated, effective systems. Inverter is committed to fostering an ecosystem where tools are accessible, supporting initiatives to advance the ecosystem.

The Inverter Network promotes a community-driven approach, where collaborators contribute to and maintain the Module Library, enriching the ecosystem and ensuring that every workflow benefits from shared innovation. The overarching goal is to transform global economies through tokenization and modular blockchain solutions.


# The Inverter Protocol

<figure><img src="/files/YfwBGNxgTifok3BkQ28w" alt=""><figcaption></figcaption></figure>

### Key Protocol Features

The design and functionality of the Inverter Protocol are shaped by its high and low-level requirements:

* [**Modular Protocol Architecture**](/contracts/technical-paper): Enables deployment and iteration of token economies by combining various modules in a plug & play fashion, providing flexibility and adaptability without custom development.
* [**Module Library**](/concepts/protocol-concepts/module-library): Offers a collection of pre-audited, interoperable smart contract modules that can be utilized within the protocol.
* [**Inverter Security Standard:**](/concepts/protocol-concepts/security) Incorporates comprehensive off-chain and on-chain security measures, including rigorous audits, secure development practices, and built-in safeguards to protect assets and transactions.

### Architecture Components

The Inverter Protocol's architecture comprises of several key components that form the foundation of each token economy:

* [**Core Orchestrator Contract**](/concepts/protocol-concepts/workflow-model/orchestrator): The core contract that coordinates the interactions between various modules for a token economy workflow to ensure seamless operation and maintain system integrity.
* [**Module Types and Interfaces**](/concepts/protocol-concepts/module-library): Defines the standard interfaces for all modules to facilitate smooth integration and interoperability.
* [**Beacon Proxy Pattern**](/concepts/protocol-concepts/security/upgradeability): Upgrade mechanism that allows for system-wide updates without requiring redeployment of individual contracts, improving maintenance and gas efficiency.
* [**Deployment Factories**](/concepts/protocol-concepts/workflow-model/factories): Allow for permissionless deployments of all the workflow contracts.&#x20;

#### Architecture Diagram

<figure><img src="/files/F6wBvd3lVbpAv2HM5oBI" alt=""><figcaption></figcaption></figure>

### Token Economy Workflow

Inverter Protocol workflows consist of various modules, each serving a specific purpose in a token economy:&#x20;

* **Orchestrator**: Acts as the core engine that integrates all modules and manages their interactions within a workflow
* **Authorizer**: Controls access and permissions across a workflow, ensuring that only authorized entities can execute specific operations.
* **Funding Manager**: Handles token issuance and redemption against asset inflows, serving as the primary mechanism for managing the token supply.
* **Payment Processor**: Manages the distribution and processing of token payments according to predefined rules and conditions set within the workflow.
* **Logic Modules**: Execute specific business logic and functionalities required by different token utilities and behaviors.

For further details on how these components operate within a token economy, please visit our [Workflow Model Page](/concepts/protocol-concepts/workflow-model).


# Protocol Concepts


# Workflow Model

<figure><img src="/files/Q15y2jZivWOT0iiDbNYW" alt=""><figcaption></figcaption></figure>

### What is a workflow?

A workflow is a unique configuration of various interconnected Inverter Protocol contracts, designed to achieve a specific goal. It functions like a blueprint, detailing the roles and interactions of different components and modules, allowing for customized solutions tailored to diverse use cases and requirements.

### Components of a Workflow

In practical terms, a workflow in the Inverter Protocol involves a core Orchestrator contract that coordinates and directs activities among specialized modules like the Funding Manager, Authorizer, Payment Processor, and Logic Modules.

Additionally, Factories play a crucial part as they facilitate the permissionless deployment of all contracts within a workflow.

Each type within the workflow model performs dedicated functions:

* **Factories**: Allow for permissionless deployments of all the contracts of the workflow.
* **Orchestrator**: The central contract that holds the references to all integrated modules and allows for the addition and removal of other modules into the workflow.
* **Funding Manager**: Contains the funds of the workflow that can be accessed by other modules. Based on which module fills this role the funding manager can handle user deposits and withdrawals, as well as take on the role of a Primary Issuance Market (PIM).
* **Authorizer**: Controls access and permissions within the workflow, ensuring that only authorized users and modules can perform certain actions.
* **Payment Processor**: Handles the outgoing token flows of the workflow based on so-called payment orders.
* **Logic Modules**: This category includes the remaining modules in the system. They implement the specific business logic a user may wish to apply to their contract, such as requesting funds from the Funding Manager, creating payment orders, or performing any other tasks they are designed to do.

### Security and Governance

The security of modules is critical to the entire workflow. All contracts undergo rigorous [security audits](/concepts/protocol-concepts/security/audits) and continuous reviews to ensure their integrity and safety. Updates and modifications to the modules are managed through established [governance](/concepts/protocol-concepts/governance) mechanisms, involving community input and decentralized decision processes.


# Factories

### Importance of the Factories

The purpose of our factories is to enable users to easily deploy workflows on their own. We use a combination of two factories to deploy workflows:

* **Module Factory**: Enables the creation of the Inverter Modules. Users can choose from a list of deployable modules the so-called module library.
* **Orchestrator Factory**: Enables the creation of an orchestrator and uses the Module factory to attach and create the predefined workflow modules.

### **Workflow deployment**

Our factory setup enables us to provide permissionless deployments of custom workflows. The user should be able to have complete control of how their workflow should look and how to configure it.

As described within the [Upgradeability page](/concepts/protocol-concepts/security/upgradeability) and[ Intervention Mechanism](/concepts/protocol-concepts/security/intervention#intervention-mechanisms)[ sections](/concepts/protocol-concepts/security/intervention#intervention-mechanisms), we use a beacon proxy structure to deploy our workflows. This enables us to efficiently update all contracts at once as well as to pause functionality in case of emergency.

For some users or use cases this might not be the ideal solution so we provide a non-beacon proxy deployment variant. In that case, the users can decide for themselves if they want to upgrade to the newest version, but they don't profit from the maintenance and emergency solutions of the beacon proxy pattern.

### **Module Library**

As described above the Module Library is a register of all available modules that the module factory can deploy. As it currently stands the listing of new modules can only be done through the Governor contract see[ Governance page](/concepts/protocol-concepts/governance). This is to hold up our quality and security level in the early stages of the inverter protocol. At a later point in time, we are planning to open up the registration of new modules to the community.


# Orchestrator

### Importance of the Orchestrator

The Orchestrator lies at the core of the Inverter Protocol. It defines the structure relationships of any specific workflow deployment.

It lists all active Modules and handles the addition and removal of new modules on a live deployment while enabling direct calls via the `executeTxFromModule()` function. In addition, it also stores relevant metadata and, crucially, specifies which modules are responsible for the core functions of the system:

* Management of Funds (`IFundingManger`)
* Authorization `(IAuthorizer`)
* Processing of Payments (`IPaymentProcessor`)

Modules in charge of these functionalities must implement the specific interfaces on which the system can rely.

### Implementation Interface

The Orchestrator implements the `IOrchestrator`  Interface. In addition, since it inherits the `ModulesManagerBase` contract, it also implements the `IModuleManagerBase` Interface.

The core functionalities of these interfaces are:

* `initiate[Action]WithTimelock`
* `cancel[Action]Update`&#x20;
* `execute[Action]`

These functions manage adding and removing Modules as well as swapping out the core Modules of a workflow. There is one variant for each core Module (setAuthorizer, setFundingManager, setPaymentProcessor), and general "addModule/removeModule" for logic Modules.

* `executeTxFromModule` : Allows one Module to call a different module to perform a transaction.
* `executeTx`: General transaction execution for the Orchestrator, for example, to rescue funds.

For an example Orchestrator implementation, please refer to the [\[Protocol Github\]](https://github.com/InverterNetwork/contracts/tree/main/src/orchestrator)

### Orchestrator Features and Functionalities

* **Module Management**: The Orchestrator is in charge of adding and removing Modules, as well as specifying which Modules will perform the core functionalities of the workflow.
* **Call Execution**: The Orchestrator is not only able to execute arbitrary calls for itself but also enables Modules to perform calls on other Modules inside the same workflow
* **Workflow Data**: The Orchestrator has a set of getters to easily query the full Module list, Core Workflow Modules, and other metadata relevant to the deployment.


# Authorizer

### Importance of the Authorizer Module

The Authorizer module type is integral to managing permissions and authorizations within the Inverter Protocol workflows. It ensures that interactions adhere to predefined authorization policies, protecting the system from unauthorized access and enhancing security.

### Implementation Interface

The Authorizer module implements the `IAuthorizer` interface, which primarily includes the function `hasRole(role, address)`. This function checks if a specific address holds a designated role, thereby authorizing it to perform certain actions within the system.

For examples of the Authorizer Module implementations, please refer to the [Modules Library Page](/concepts/protocol-concepts/module-library).

### General Authorizer Features and Functionalities

* **Role-Based Access Control (RBAC)**: Implements a dual-tiered system where global roles affect the entire system and module-specific roles are confined to particular functionalities.
* **Dynamic Permission Management**: Allows for the dynamic updating and management of roles to adapt to evolving system needs and governance changes.
* **Custom Role Support**: Supports the creation of custom roles to cater to specific operational requirements, facilitating unique governance structures.


# Funding Manager

### Importance of the Funding Manager Module

The Funding Manager is a central component of the Inverter Protocol, designed to manage inflows into workflows and facilitate the dynamic issuance of tokens. This module is integral to the [Primary Issuance Market (PIM)](/concepts/protocol-concepts/primary-issuance-markets), which leverages algorithms to adjust token supply based on real-time data and market conditions.

### Implementation Interface

The Funding Manager Module implements the `IFundingManager` interface, which primarily includes the function :

* `transferOrchestratorToken(module, amount)`: Facilitates the transfer of tokens to other modules within the workflow.

For examples of Funding Manager implementations, please refer to the [Modules Library Page](/concepts/protocol-concepts/module-library).

### General Funding Manager Features and Functionalities

* **Facilitating Asset Inflow**: The Funding Manager is instrumental in managing the inflow of assets into a workflow, thereby laying the foundation for a robust token economy. It integrates seamlessly with other workflow modules, enabling dynamic interactions that drive the creation and sustenance of token economies.
* **Customizable Issuance Logic**: Each Funding Manager can be designed to support unique dynamic token issuance and redemption schemes based on real-time data and market conditions


# Payment Processor

### Importance of the Payment Processor Module

The Payment Processor module type is a crucial component of the Inverter Protocol, designed to manage outflows from workflows and facilitate the execution of payment orders. This module is integral to the orchestration of financial transactions across various modules, ensuring that payments are processed accurately and efficiently.

### Implementation Interface

The Payment Processor Module implements the `IPaymentProcessor` interface, which primarily includes the following functions:

* `processPayments(module)`: Fetches and processes payment orders from specified modules.
* `cancelRunningPayments(module)`: Cancels any ongoing payment orders from specified modules.

For examples of Payment Processor implementations, please refer to the [Modules Library Page](/concepts/protocol-concepts/module-library).

### General Payment Processor Features and Functionalities

* **Payment Order Management**: Manages the lifecycle of payment orders, ensuring that all payments are executed according to the predefined conditions.
* **Execution of Financial Transactions**: Facilitates the execution of payments, managing the outflow of tokens or funds from the workflow.
* **Cancellation and Adjustment of Payments**: Provides mechanisms to cancel or adjust ongoing payments, enhancing the flexibility and control over financial transactions within the ecosystem.


# Logic Module

### Importance of Logic Modules

Logic Modules are essential components of the Inverter Protocol, designed to implement specific business logic and policies within workflows.

These modules enable the customization and extension of workflows, allowing developers to tailor the protocol to diverse use cases and requirements. Logic Modules play an important role in defining the conditions under which certain actions within the workflow are executed, thereby driving the functionality and versatility of the Inverter Protocol workflow.

### Implementation Interface

Logic Modules implement diverse interfaces depending on their specific functionalities.

For examples of Logic Modules implementations, please refer to the [Modules Library Page](/concepts/protocol-concepts/module-library).

### General Logic Modules Features and Functionalities

* **Customizable Business Logic**: Each Logic Module can be designed to perform unique operations, from managing Key Performance Indicators (KPIs) to executing complex governance protocols.
* **Interoperability with Other Modules**: Designed to work seamlessly with the Funding Manager, Authorizer, and Payment Processor modules, Logic Modules can trigger actions across these components based on specific business rules.
* **Adaptability to Changing Conditions**: Logic Modules can be updated or replaced without disrupting the overall workflow, allowing for continuous adaptation to new requirements or opportunities.


# Module Library

### What is the Module Library

The Module Library features a collection of audited, trusted modules accessible through our workflow factory. Managed through our governance mechanism the library facilitates easy deployment of workflow contracts.

### Contributions to the Module Library

Interest in contributing to the Inverter Protocol contracts is valued, as each contribution enhances the protocol's robustness and usability. Open-source projects like this depend on community collaboration to thrive. Contributions of all sizes help advance the collective goals.

Please see our [Contribution Guidelines](https://github.com/InverterNetwork/contracts/blob/dev/CONTRIBUTING.md) for more information.

### Modules

**Authorizers**:

This module defines and enforces the system's permission structure. It specifies the different roles and actions each stakeholder is allowed to take. Stakeholders can be users or other modules.

* [Role Authorizer](/concepts/protocol-concepts/module-library/authorizers/role-authorizer)
* [Token Gated Role Authorizer](/concepts/protocol-concepts/module-library/authorizers/token-gated-role-authorizer)

**Funding Managers**:

This module holds the funds of each workflow and manages user deposits and withdrawals. In addition to the basic functionality, the Funding Manager module ultimately takes the role of a Primary Issuance Market (PIM), enabling dynamic token issuance and redemption based on predefined algorithms and market conditions.

* PIMs
  * [Bancor Based PIM: Virtual Supply](/concepts/protocol-concepts/module-library/funding-managers/pims/bonding-curve)
  * [Bancor Based PIM: Virtual Supply Buy Restriction](/concepts/protocol-concepts/module-library/funding-managers/pims/bonding-curve-1)
* [Deposit Vault Funding Manager](/concepts/protocol-concepts/module-library/funding-managers/rebasing-funding-manager)

**Payment Processors**:

This module receives and processes payment orders from other modules. It acts as a funnel through which all the value outflows of the system can be managed. It implements the individual distribution policy of the workflows’ token economy, handling the monetary flows that are taking place.

* [Simple Payment Processor](/concepts/protocol-concepts/module-library/payment-processors/simple-payment-processor)
* [Streaming Payment Processor](/concepts/protocol-concepts/module-library/payment-processors/streaming-payment-processor)

**Logic Modules**:

This category includes the remaining modules in the system. They implement the individual utility policies of the workflows’ token economy, defining the conditions under which certain monetary flows occur.

* [Bounty Manager](/concepts/protocol-concepts/module-library/logic-modules/bounty-manager)
* [Recurring Payment Manager](/concepts/protocol-concepts/module-library/logic-modules/recurring-payment-manager)
* [KPI Rewarder](/concepts/protocol-concepts/module-library/logic-modules/kpi-rewarder)
* [Staking Manager](/concepts/protocol-concepts/module-library/logic-modules/staking-manager)


# Authorizers


# Role Authorizer

#### Module Category: Authorizer

The role Authorizer module authorizes actions and governance permissions through a managed list of whitelisted addresses.

It provides an authorization framework that supports various governance structures, from individual wallets to multi-signature accounts. Different roles and addresses can be defined for different authorizations in module interactions or the overall governance of the workflow.

## Module Functions:

**Role Management:** Toggle self-management of roles, grant roles to addresses, and revoke roles.

**Admin Role Control:** Transfer or permanently remove admin rights for governing the roles.


# Single Vote Governance Module

#### Module Category: Authorizer

Single Vote Governance Module implements a threshold-based voting system for authorizing smart contract functions. It holds a list of authorized addresses that can initiate votes. Other addresses can support or reject these votes, which remain open for a specified period.

Each address is allowed only one vote, and votes cannot be modified. If a vote does not reach a quorum by the end of the voting period, it cannot be executed later, even if the quorum is later lowered. Actions related to the votes can only be executed after the voting period ends, even if the quorum was reached earlier.

## Module Functionalities:

#### Parameters to Set:

**Starting Quorum:** Defines the minimum percentage of eligible voters required to participate in a vote for it to be valid.

**Voting Duration:** Specifies the duration for which a vote remains open, allowing voters to cast their decisions.

**Authorized Voters List:** Sets a list of addresses authorized to participate in governance activities.


# Token Gated Role Authorizer

#### Module Category: Authorizer

Token Gated Role Authorizer allows governing permissions for roles and access rights for contract interactions based on the ownership of specified tokens.

With Token Gated Role Authorizer, token addresses can be whitelisted for specific roles in addition to whitelisting a user or a contract address. Token based whitelisting gives all the holders of those tokens the relevant permissions. Token addresses can be ERC20, NFTs, or other token standards.

## Module Functions:

#### Parameters to set:

**Role Setup:** Grant roles that are gated by token ownership.

**Token Specification:** Specifies which tokens are linked to the roles.

**Threshold:** Sets the minimum token balance required to access specific roles.


# Funding Managers


# PIMs


# Bancor Based PIM: Virtual Supply

#### Module Category: Funding Manager

The Bonding Curve Bancor Funding Manager provides algorithmic pricing for minting & redeeming tokens. It enables dynamic pricing of tokens in response to their supply by utilizing the Bancor Formula.

Projects can utilize this module to set a primary market for their assets without needing liquidity while benefiting from the native yield that primary markets unlock for tokens.

\# Module Functionalities:

### Parameters to set:

**Bonding Curve Formula:** The Bonding Curve shall utilize the Bancor formula to create two distinct bonding curves for funding to mint and burning to withdraw.

**Reserve Ratio for Buying/Selling:** Specifies two different exchange rates for buying and selling, effectively having two different curves.

**Buy and Sell Fee:** Projects can apply a fee to transactions in which tokens are bought and sold.

**Buying Open or Closed:** Controls whether tokens can be currently bought, allowing administrators to control the availability of their tokens. Tokens can be opened and closed to buying depending on the administrators’ decision.

**Selling Open or Closed:** Controls whether tokens can be currently sold, allowing administrators to control the availability of their tokens. Tokens can be opened and closed to buying depending on the administrators’ decision.

**Virtual Collateral/Token Supply:** Allows the use of virtual balances for backing collateral, thus making the collateral available to utilize for DeFi strategies or spending.

**Minting & Redeeming:** Allows users to mint new tokens by providing collateral, with amounts determined by current bonding curve pricing. Users can also redeem tokens by burning them and returning the original deposit.

**Cap/Uncap Supply:** Sets the supply cap beyond which no further minting can occur.

**Permissioning:** Restricts the bonding curve to a whitelisted group of actors.


# Bancor Based PIM: Virtual Supply Buy Restriction

#### Module Category: Funding Manager

The Bonding Curve Bancor Funding Manager provides algorithmic pricing for minting & redeeming tokens. It enables dynamic pricing of tokens in response to their supply by utilizing the Bancor Formula.

Projects can utilize this module to set a primary market for their assets without needing liquidity while benefiting from the native yield that primary markets unlock for tokens.

\# Module Functionalities:

### Parameters to set:

**Bonding Curve Formula:** The Bonding Curve shall utilize the Bancor formula to create two distinct bonding curves for funding to mint and burning to withdraw.

**Reserve Ratio for Buying/Selling:** Specifies two different exchange rates for buying and selling, effectively having two different curves.

**Buy and Sell Fee:** Projects can apply a fee to transactions in which tokens are bought and sold.

**Buying Open or Closed:** Controls whether tokens can be currently bought, allowing administrators to control the availability of their tokens. Tokens can be opened and closed to buying depending on the administrators’ decision.

**Selling Open or Closed:** Controls whether tokens can be currently sold, allowing administrators to control the availability of their tokens. Tokens can be opened and closed to buying depending on the administrators’ decision.

**Virtual Collateral/Token Supply:** Allows the use of virtual balances for backing collateral, thus making the collateral available to utilize for DeFi strategies or spending.

**Minting & Redeeming:** Allows users to mint new tokens by providing collateral, with amounts determined by current bonding curve pricing. Users can also redeem tokens by burning them and returning the original deposit.

**Cap/Uncap Supply:** Sets the supply cap beyond which no further minting can occur.

**Permissioning:** Restricts the bonding curve to a whitelisted group of actors.


# Deposit Vault Funding Manager

#### Module Category: Funding Manager

The Deposit Vault Funding Manager is a simple Funding Manager which enables users to deposit tokens into the Workflow.

## Module Functionalities:

**Deposit Tokens**: Enables Users to deposit tokens into the Funding Manager.

**Withdraw to Payment Client**: Enables modules which implement the Payment Client interface to withdraw tokens from the Funding Manager for use in the workflow.


# Payment Processors


# Streaming Payment Processor

#### Module Category: Payment Processor

The Streaming Payment Processor enables streaming assets to recipients with cliff and vesting options.

It provides a vested payment option for modules that facilitate the transfer of funds or issuance of assets to a set of addresses when certain conditions are met. It offers the flexibility in choosing custom cliff and vesting terms. Unvested streams can be stopped while the recipients are guaranteed to claim their already vested assets.

## Module Functionalities:

#### Parameters to Set:

**Cliff duration:** Sets a time period that has to pass before the vested assets can be claimed.

**Vesting Duration:** Sets the exact date and time for vesting. This determines when tokens can be fully claimed.

## Module Interactions:

#### For Administrators

**Remove Payment:** Cancels payment for a specific recipient, transferring any unlocked funds to the recipient before removal.

**Cancel Running Payments:** Cancels all payments associated with a particular payment client, affecting all recipients.

\### For Claimers

**Claim Vests:** Enables users to claim vested assets for all the recipients, or to claim vested assets for a specific recipient.


# Simple Payment Processor

#### Module Category: Payment Processor

Simple Payment Processor facilitates direct, one-time payments to designated recipients. Once initiated, payments are final and irreversible.

It provides a simple payment mechanism for modules that facilitate the transfer of funds or issuance of assets to a set of addresses when certain conditions are met.


# Logic Modules


# Bounty Manager

**Module Category**: Logic Module

**Smart Contract Name**: LM\_PC\_Bounties\_v1

### Introduction

The Bounty Manager module offers a structured way to manage bounties, enabling users to propose, update, and claim payouts for bounties in a secure and transparent manner. It integrates seamlessly within a workflow, allowing for dynamic bounty management and secure payment processing.

### Module Purpose

* **Manage Bounties**: Create and update bounties with specific requirements and payment ranges.
* **Process Claims**: Securely process and verify claims to ensure contributors are compensated appropriately.
* **Role-based Access Control**: Assign roles like Bounty Issuer, Claimant, and Verifier to manage different aspects of bounties and claims, ensuring that only authorized users can perform certain actions.

### Module Interactions

* **For Bounty Administrators**:
  * **Create a Bounty**: Specify bounty details along with minimum and maximum payout amounts.
  * **Lock Bounty**: Close a bounty to new submissions, suitable for tasks meant to be completed once.
  * **Grant Admin Roles**: Assign or revoke administrative privileges.
* **For Bounty Submitters**:
  * **Submit and Update Claim**: Submit claims for bounties, including details and contributors' information.
  * **Add and Edit Contributors**: Manage contributor details for a bounty claim.
* **For Bounty Verifiers**:
  * **Verify Claim**: Review and approve claims to trigger payouts, ensuring compliance with bounty requirements.


# Recurring Payment Manager

**Module Category**: Logic Module

**Smart Contract Name**: LM\_PC\_RecurringPayments\_v1

### Introduction

The Recurring Payment Manager module facilitates the creation, management, and execution of scheduled recurring payments. This module operates within a workflow, allowing organizations to set up systematic and timed financial commitments or subscriptions with ease.

### Module Purpose

* **Schedule Recurring Payments**: Define payment schedules based on specific periods known as epochs.
* **Manage Payments**: Add, remove, and update recurring payments for different recipients.
* **Automate Payments**: Automatically trigger payments at the start of each new epoch.
* **Flexible Payment Periods**: Set epoch lengths between one week to one year, ensuring flexibility in payment timing.

### Module Interactions

* **For Administrators**:
  * **Set Up Payment**: Define the recipient address, amount, and start epoch for recurring payments.
  * **Remove Payment**: Remove an existing recurring payment by specifying the payment ID.
  * **Trigger Payments**: Manually trigger payments if needed, ensuring all due payments are processed.
  * **Adjust Epoch Length**: Set the length of epochs during initialization to suit the organization's payment cycle.
* **For Recipients**:
  * **Receive Payments**: Automatically receive payments at the end of each epoch, based on the defined schedule.


# KPI Rewarder

#### Module Category: Logic Module

**Smart Contract Name**:&#x20;

KPI Rewarder allows dynamic payments based on on/off-chain KPIs set by the project. It leverages UMA’s Optimistic Oracle to verify the KPI data.

KPI Rewarder checks and validates KPIs, generates payment orders, and manages the distribution of those payments. It enables the distribution of payments or rewards according to defined performance outcomes.

## Modules Functionalities

### Parameters to set:

#### KPI-Based Payment Parameters

**Reward Structure:** Supports various reward structures, including proportional payouts and tiered rewards. These structures can be adjusted based on total value locked or specific performance metrics, allowing for flexibility in reward distribution.

**Maximum Payout:** Sets the upper limit on rewards for a given period.

**Recurring Query Periods:** Defines the recurring period for the KPIs to be checked with the Oracle.

#### UMA Oracle Parameters

**Bonding Amount:** Sets the bonding amount for each query, which is collateral required to secure an Oracle query within the UMA system.

**Recurring Query Periods:** Specifies the intervals at which the system will automatically ask the UMA Oracle for KPI evaluations.

**Maximum Payout:** Sets the maximum payout limit for each period, which helps control the disbursement of rewards.

#### Automated Module Interactions:

**Oracle Queries:** Periodically queries the UMA Oracle to retrieve KPI data, which it then uses to determine the reward payout amount.

**Payment Order Generation:** Based on the results from the UMA Oracle, the module generates Payment Orders. These orders are determined by whether the Oracle's responses are binary (Yes/No), numerical, or address-based, affecting how rewards are calculated and distributed.

**Dispute Management:** In case of disputes in Oracle responses, the module holds the payment until the dispute is resolved.


# Staking Manager

#### Module category: Funding Manager

This module enables users to stake tokens in return for rewards. Its main function is to facilitate the staking process, where users can deposit and withdraw their tokens.

## Module Functionalities:

#### Parameters to set:

**Token address:** The address of the ERC20 token that will be staked.

**Amount of Rewards:** Sets the total amount of rewards to be distributed during the reward period.

**Duration of the Reward Period:** Sets the length of time over which the reward amount will be distributed.


# Primary Issuance Markets (PIMs)

<figure><img src="/files/iBVa5NLGOmApTLHNZ7hO" alt=""><figcaption></figcaption></figure>

### What is a Primary Issuance Market (PIM)?

A Primary Issuance Market (PIM) is a blockchain technology that allows projects to issue and manage their tokens dynamically. It helps projects adapt to changing market conditions by enabling them to issue or redeem tokens as needed. This is different from traditional methods where all tokens are usually created at once and distributed according to a fixed plan.

<figure><img src="/files/eeBd4Y1M1Xo4qPe2OZps" alt=""><figcaption></figcaption></figure>

#### Key Features of PIMs:

1. **Dynamic Token Issuance and Pricing**: PIMs use algorithms that adjust token supply based on specific goals and performance indicators. This flexibility allows projects to respond to market demands effectively.
2. **Stable Financial Reserves**: Money earned from issuing tokens through PIMs can be used to build up a project’s reserves. This helps maintain a stable token price and supports the project financially without needing to sell tokens frequently.
3. **Token Launch without Initial Liquidity**: PIMs let projects launch tokens and figure out how many are needed without the pressure of securing large amounts of initial liquidity. This makes it easier for new projects to get started and match their token supply with actual demand.

### How PIMs Work:

PIMs are powered by algorithms that link the token supply to reserve assets, ensuring that the relation between supply and issuance are predictable. This setup allows for adjustments in token supply based on economic conditions, which helps projects meet their specific needs and adapt to market changes.

### Innovation in Tokenomics: Dynamic Versus Static Models

PIMs mark a significant shift from static to dynamic economic models in tokenomics, characterized by:

* **Responsive Token Supply**: Unlike static pre-minting, PIMs enable on-demand token creation, aligning supply with market needs.
* **Economic Resilience**: The ability to adjust token supply dynamically aids in maintaining stability even in volatile conditions.
* **Lifecycle Management**: Provides comprehensive tools for managing the entire lifecycle of tokens, from issuance to secondary market activities.

In summary, PIMs offer a sophisticated and adaptable framework for managing token economics, aligning closely with the strategic needs of projects and enhancing economic autonomy and sustainability.


# Governance

<figure><img src="/files/BS2BjJ4p0WvEoVMFflhW" alt=""><figcaption></figcaption></figure>

The Inverter protocol uses governance mechanisms to control its crucial administrative functions, which are only executable by specific multisig addresses. This strategy boosts the system's security by ensuring that only authorized parties can implement significant changes.

### Multisig

We have set up two different Multisigs, each with specific authorization levels to ensure security within our system.

#### Inverter Team Multisig

The Inverter Team Multisig is managed by our team members and primarily handles quick responses and maintenance tasks.

#### Community Multisig

The Community Multisig is managed by community members and primarily focuses on major decision-making and high-impact activities.

#### Multisg Addresses

| Network Name | Chain ID    | Multisig Permission | Address     |
| ------------ | ----------- | ------------------- | ----------- |
| Coming Soon  | Coming Soon | Coming Soon         | Coming Soon |

### Governor Contract

The Governor contract serves as the central hub for on-chain governance. It is the primary entry point through which crucial administrative functions are governed. The contract includes administrative functions that can only be executed by the previously mentioned multisig authorization levels. These functionalities are:

#### Beacon Upgrade

**Authorization Level**: Inverter Team & Community Multisig

The Beacon Upgrade functionality allows for the [upgrading of contracts at the protocol level](https://docs.inverter.network/concepts/protocol-concepts/www.todo.com). Regular upgrades, categorized as maintenance tasks, can be initiated by either of the multisig authorization levels. After a specified time lock period has passed, these upgrades can be executed, providing users with the opportunity to review the upcoming changes in advance.

#### Beacon Pauseability

**Authorization Level**: Inverter Team & Community Multisig

The Beacon Pauseability functionality allows for the [pausing of beacons and their respective contracts at the protocol level](https://docs.inverter.network/concepts/protocol-concepts/www.todo.com). To quickly address faults in the system, both multisig authorization levels have the authority to pause the beacon systems.

#### Forced Upgrades and Unpausing

**Authorization Level**: Community Multisig

The community multisig has the exclusive authority to lift a pause that was initiated in response to a fault in the system, ensuring that any updates or changes align with the community's consensus on the protocol's status.

#### RegisterModule in Factory

**Authorization Level**: Inverter Team & Community Multisig

Registering new Modules in the Module Factory can only be done through the Governor contract. As this process is considered a maintenance task, both multisig authorization levels are authorized to use this functionality.

#### Fee Setting

**Authorization Level Overal Fees**: Community Multisig

**Authorization Level Workflow Fees**: Inverter Team & Community Multisig

The fee settings, as a category of high-impact actions, are primarily governed by the Community Multisig. This governance includes:

* Designating the Default Treasury Address, where all collected fees are directed.
* Establishing a default fee applicable to all workflows unless a specific fee is assigned.
* Implementing a maximum fee limit that cannot be exceeded for any fee adjustments.

In cases where specific fees are assigned to certain workflows (referred to as [Workflow Fees](/concepts/protocol-concepts/fees#workflow-specific-fees)), both multisig authorization levels are permitted to modify these fee values. However, these adjustments are still subject to the maximum fee cap previously mentioned.


# Security

<figure><img src="/files/pM8xYKg5KQ9sZQ3O7J0B" alt=""><figcaption></figcaption></figure>


# Upgradeability

The Inverter Network employs a robust upgradability framework that ensures our contracts remain secure, efficient, and aligned with the latest technological advancements and community needs. This page outlines the types of upgrades, when and how these upgrades occur, and who is authorized to implement them.

### Types of Upgrades

We defined two types of upgrade: Minor and Major Version Upgrades:

#### Minor Version Upgrades

Minor upgrades are non-breaking changes that improve functionality or correct issues without altering the contract's interface or core logic. These upgrades increment the minor version number (e.g., from 1.3 to 1.4) and are applied automatically to all contracts using the beacon proxy pattern. This ensures all workflows utilizing the updated module benefit from the latest improvements without manual intervention.

#### Major Version Upgrades

Major upgrades involve significant changes that may alter the contract's interface or internal logic. Unlike minor upgrades, major version upgrades are not automatically applied. Instead, a new module version is registered in the module factory starting with a major version that is incremented by one and starts with minor Version zero. Users can swap to these new Modules by adding them separately into their workflows.

### **Beacon Proxy Pattern**

One goal for our modules was to simplify the maintenance of them significantly, enabling Inverter Protocol maintainers to easily deploy fixes to malfunctioning modules by updating the module implementation directly instead of each individual module.

To implement this we made use of a so called beacon proxy pattern. In this pattern a module stores the address of its implementation in a separate “beacon” contract. In a typical deployment setup, when the implementation needs to be upgraded, all of the contracts that use this implementation need to be updated. However, with the Beacon proxy pattern, only the beacon contract itself needs to direct the modules to the new implementation. This is very efficient when dealing with large quantities of modules and their implementations.

In addition to that we can use this structure in the [Intervention Mechanisms](/concepts/protocol-concepts/security/intervention#intervention-mechanisms) too.

### Authorization to Upgrade

Upgrades are governed by two multisig wallets:

* **Community Multisig:** Comprises team members, community representatives, and advisors. This group handles critical decisions, including approving major upgrades.
* **Inverter Team Multisig:** Consists of Inverter team members and is used for more routine tasks and minor upgrades.

For a detailed explanation of the governance process and multisig responsibilities, refer to our [Governance Page](/concepts/protocol-concepts/governance).

### Security Measures

To safeguard against unauthorized or abrupt changes, and to ensure community trust, we implement the following security measures:

* **Timelock Mechanisms:** All major upgrades are subject to a delay before activation, during which users can review and contest the changes.
* **Beacon Proxy Pattern:** Used for all contracts to allow efficient and secure upgrades by updating a single beacon contract rather than each individual proxy.

For more information on the security protocols and user options during upgrades, please visit our [Security Guidelines](/contracts/security-guidelines).

### Upgrade Timing

Upgrades are typically initiated under the following circumstances:

* **Routine Maintenance and Improvements:** Scheduled updates to enhance functionality or efficiency, adhering to the [SemVer](https://semver.org/) principles.
* **Emergency Responses:** In the event of a discovered vulnerability or bug that poses a risk to user funds or system integrity, an emergency upgrade may be initiated. For more details on emergency handling, see Emergency Protocol.
* **Community Feedback and Requests:** Based on user feedback or feature requests that align with the Inverter Network’s roadmap.

Before any upgrade is deployed to live networks, it is thoroughly tested on public testnets, and a public announcement is made for community feedback. The upgrade process includes a timelock delay to allow user verification and feedback.

\---

For further details on our security practices and how we handle specific scenarios, please visit our [Security Guidelines](/contracts/security-guidelines).


# Emergency Protocol

In the Inverter Network, maintaining the highest security standards and swiftly responding to threats is paramount. This section describes the conditions that trigger our emergency protocol, our monitoring systems, the procedural steps we take in response to threats, and the specific mechanisms employed during these events.

### What Triggers the Emergency Protocol

The emergency protocol is activated under several critical conditions that potentially endanger the platform's integrity and user funds:

* **Security Breaches:** Any detected vulnerability or bug within our smart contracts that poses a risk to user assets.
* **Underlying Protocol Threats:** Vulnerabilities in any underlying protocols or systems that our dApp utilizes.
* **Third-party Failures:** Issues arising from third-party infrastructure such as oracles, wallet generators, and bridges.
* **External Threats:** Any active exploits, hacks, or unauthorized access reported by users or identified by our monitoring systems.
* **Compromise of Internal Systems:** Such as theft of private keys that could jeopardize control over contracts.

### Monitoring and Detection

To preemptively detect and respond to threats, we employ a comprehensive monitoring system:

* **Alert System:** We utilize tools akin to OpenZeppelin Defender 2.0, which provide instant alerts on unusual activities, ensuring that any potential threats are addressed immediately.
* **War Room Operations:** A dedicated monitoring center equipped to assess and respond to security threats in real-time will be setup as soon as a threat is detected.

### Procedural Response Steps

Upon identification of a threat, our response follows these critical steps:

1. **Immediate Assessment:** Our team assesses the extent of the breach in the War Room, determining whether and how much of our protocol is compromised.
2. **Selective or Full System Pause:** Depending on the severity and reach of the incident, we may pause individual modules or the entire system to mitigate any ongoing risk.
   * **Selective Pausing:** Targets only the affected modules, minimizing disruption to the overall network.
   * **Full System Pause:** Used in extreme cases where a widespread threat is detected.
3. **Communication with Stakeholders:** We maintain clear, ongoing communication with our users and stakeholders throughout the incident. This includes initial alerts, progress updates, and a comprehensive postmortem.
4. **Post-Incident Analysis and Reporting:** A thorough investigation is conducted, resulting in a detailed report that outlines the incident, the response actions taken, and future preventative measures.

### Intervention Mechanisms

As mentioned in the [Beacon Proxy Pattern](/concepts/protocol-concepts/security/upgradeability#beacon-proxy-pattern) section, we also use the Beacon Proxy Pattern to start our Intervention Mechanism. Should one of the [Triggers](/concepts/protocol-concepts/security/intervention#what-triggers-the-emergency-protocol) be set off, then we are able to pause the implementation of all or individual contracts. This means that we set the implementation address that the beacon points to to address zero. This prevents all further interactions with the contracts that are linked to these specific beacons.

This gives us room to breathe and make cool headed decisions based on the current circumstances. When we are sure that the triggers are not active anymore or don't pose any threat, then we can either return to a normal functioning state or we update the according implementations to fix bugs or to update general features.

It's important to note that this pausing mechanism comes with an opt-out option. Some users or use cases might opt for an immutable workflow, where pausing is not an option, while others may not trust an un-pausable system. This is further explained in the [Factories page](/concepts/protocol-concepts/workflow-model/factories).

\---

For further details on our security practices and how we handle specific scenarios, please visit our [Security Guidelines](/contracts/security-guidelines).


# Audits

Auditing serve as a critical checkpoint for blockchain projects, providing external validation of the protocol's security and functionality. At Inverter Protocol, we view audits not as a mere formality but as an essential component of our commitment to transparency and security.

### Multilayered Audit Approach

Recognizing the diverse nature of potential vulnerabilities, we employ a multi-layered audit strategy that starts with engaging professional auditing firms and solo researchers to regularly review our code, then hosting regular public audit competitions tap into the collective wisdom of the community, and having a continuous bug bounty pool offer a clear path for white hats to report discovered vulnerabilities.

* **In-development review:** Early bug detection through regular security reviews with our auditing partners Team Omega.
* **Pre-release audit:** Comprehensive auditing before any deployment, including a public audit competition and dedicated industry leading auditing teams.
* **Periodic and Post-Update Audits** We schedule regular audits to maintain security integrity as the protocol evolves with every new module, significant updates (major version), or additions to the core protocol.

### Security Reviews

Code security is not a one-time achievement but an ongoing task. As such, we subject our code to a continuous auditing through a concept of Security Reviews, done by [Team Omega](https://teamomega.eth.limo/):

* <https://github.com/InverterNetwork/contracts/pull/350>
* <https://github.com/InverterNetwork/contracts/pull/426>

### Dedicated Audits

#### 0xMacro Audit

* **Socials**: [Website](https://0xmacro.com/), [X](https://x.com/0xMacroSecurity)
* **Final Report Date**: July 19th, 2024
* **Protocol Version**: Inverter Protocol V1 pre-release
* **Final Audit Report**: [Inverter Github](https://github.com/InverterNetwork/contracts/blob/main/audits/2024-06-19-macro.pdf) - [O*riginal*](https://kolektivo.gitbook.io/kolektivo-docs/introduction/the-kolektivo-framework)

#### Hats Finance Public Audit

* **Contact Information:** [Website](https://hats.finance/), [X](https://x.com/HatsFinance)
* **Final Report Date**: August 12th, 2024
* **Protocol Version**: Inverter Protocol V1 pre-release
* **Final Audit Report**: [Inverter Github](https://github.com/hats-finance/Inverter-Network-0xe47e52c4fea05e555920f1dcdcc6fb8eca103eeb/blob/main/report.md) - [Original](https://github.com/InverterNetwork/contracts/blob/main/audits/2024-08-12-hats.pdf)

#### Omega Contract Audit: FM\_DepositVault\_v1

* **Contact Information:** [Website](https://teamomega.eth.limo/), [X](https://x.com/OmegaAudits)
* **Final Report Date:** July 29th, 2024
* **Protocol Version:** Inverter Protocol V1 pre-release
* **Final Audit Report:** [Inverter Github](https://github.com/InverterNetwork/contracts/blob/main/audits/2024-07-29-team-omega-issuance-token.pdf)

\----------------------------------------

For further details on our security practices and how we handle specific scenarios, please visit our [Security Guidelines](/contracts/security-guidelines).


# Bug Bounties

We are currently in the process of setting up a bug bounty program to incentivize and reward security researchers for their contributions.

Further details about the program will be announced once it is officially launched.


# Fees

<figure><img src="/files/Xjj4EAjLuHpX15MsnGgu" alt=""><figcaption></figcaption></figure>

Inverter Protocol adopts a simplified yet flexible fee structure to facilitate both ease of use and adaptation to diverse operational needs within the protocol.

### Fee Strategy

The protocol employs a two-tier fee system consisting of:

* Global Default Fee
* Workflow-Specific Fee

**Note:** Not all functions incur fees. Function which collect fee have to have this feature added explictly.

#### Global Default Fees

These baseline fees percentages are applied across the functions implementing a fee deduction, unless overridden by specific conditions.

* **Default Collateral Fee:** Applies to transactions involving collateral, such as depositing collateral to mint the issuance token or other collateralized operations.
* **Default Issuance Fee:** Applies to transactions involving the workflow's issuance token, such as redeeming the issuance token for collateral.

#### Workflow-Specific Fees

The protocol allows for fee customization on a per-workflow, per function basis to accommodate diverse needs within the ecosystem. This flexibility ensures fees can be tailored to specific economic and operational conditions.

* **Collateral Workflow Fee:** This fee can be set for specific workflow functions to handle collateral differently than standard operations.
* **Issuance Workflow Fee:** Similar to collateral fees, issuance fees can also be adjusted for particular workflow functions.

#### Fee Decision Logic

A clear and streamlined process determines which fee to apply:

1. **Workflow-Specific Check:** The system first checks if a workflow-specific function fee has been set for the.
2. **Global Default Fallback:** If no specific setting is found, the transaction defaults to the global fee.

This approach minimizes complexity while offering the flexibility to address specific scenarios effectively.

### Governance of Fee Settings

Control over fee settings is rigorously governed to align with broader community interests and protocol security standards. See our dedicated [Governance](/concepts/protocol-concepts/governance) page for more information.


# SDK's

<figure><img src="/files/HlLWs7UqpCW6QWi8QZRa" alt=""><figcaption></figcaption></figure>

## Introduction

Inverter SDK's enable the developers to interact with our contracts in a seamless manner. They take care of auto `parse` inputs,  `format` outputs and `approve`.

## TypeScript SDK

You can view the [Quick Start Here](/sdk/typescript-sdk)

## React SDK

You can view the [Quick Start Here](/sdk/react-sdk)

## Indexer SDK

You can view the [Quick Start Here](/sdk/graphql-sdk)

{% hint style="info" %}
Once you are done setting up your desired environment you can view our Workflow Guides
{% endhint %}

## Workflow Guides

These guides use the SDK software [API](/sdk/api) the entry points differ by the chosen environment but the behavior is exactly the same after retrieving the API object, [these guides can be found here](/sdk/guides).


# TypeScript SDK

## Installation

To install the SDK, use your preferred package manager from the command line. For example, if you use bun, execute the following command:

```bash
bun add @inverter-network/sdk
```

***

## Initializing the TypeScript SDK

Import the class and pass the parameters and initialize the class instance

{% code overflow="wrap" %}

```typescript
// Import public and wallet client creation functions
import { createPublicClient, createWalletClient, http } from 'viem'
// Import function to create account
import { privateKeyToAccount } from 'viem/accounts'
// Import the chain info. See all the possible chains to import: 
import { sepolia } from 'viem/chains'
// Import the Inverter class
import { Inverter, getERPCTransport } from '@inverter-network/sdk'

// Setup Public Client
// -----------------------------------------

const publicClient = createPublicClient({ 
  chain: sepolia,
  transport: getERPCTransport(sepolia.id)
})

// Setup Wallet Client
// -----------------------------------------

// Create account. PLEASE NOTE: do not store you private key in plain sight like the example
const account = privateKeyToAccount(process.env.PRIVATE_KEY) 
// Setup Wallet Client
const walletClient = createWalletClient({
  account, 
  chain: sepolia,
  transport: getERPCTransport(sepolia.id)
})


// Setup Inverter SDK
// -----------------------------------------

export const sdk = Inverter.getInstance({ publicClient, walletClient })
```

{% endcode %}


# Deploy a Workflow

## **Setup Requirements**

1. **Set up Inverter Network SDK**: Refer to the[ Quick Start](/sdk/typescript-sdk) Guide for detailed instructions.

{% hint style="info" %}
*( optional )* You can pass in a ModuleData typed object into the `requestedModules` constant's fields, this makes it so that you can work with your self managed inverter modules
{% endhint %}

```typescript
// EXEMPLE MixedRequestedModules USAGE
import type { ModuleData, MixedRequestedModules } from '@inverter-network/sdk'

const AUT_Roles_v1 = {'<your_module_data>'} as const satisifies ModuleData

const requestedModules = {
    fundingManager: 'FM_DepositVault_v1',
    paymentProcessor: 'PP_Simple_v1',
    authorizer: AUT_Roles_v1,
} as const satisfies MixedRequestedModules
```

***

## Retrieve the Deployment Functions

To deploy your initial workflow, you will need to retrieve the deployment functions. Please ensure that you adjust the [`requestedModules`](/sdk/api/deployworkflow) to match the ones you want to include in your workflow. Retrieve the `deployWorkflow` function as shown below:

**Parameters**

* **`requestedModules` (required)**:\
  This parameter defines the modules which will be deployed.
* `tagConfig` **(optional)**:\
  This parameter is to provide the deployment with parser metadata.
* `useTags` **(optional):**\
  This parameter is to optionally disable auto format parse for inputs and outputs (default true).

{% code overflow="wrap" %}

```typescript
import { sdk } from '<your_sdk_export>'
import type { MixedRequestedModules } from '@inverter-network/sdk'

const { deployWorkflow } = sdk

// Should either be `as const` or be passed dirrectly in the `requestedModules`
const requestedModules = {
    fundingManager: 'FM_DepositVault_v1',
    paymentProcessor: 'PP_Simple_v1',
    authorizer: 'AUT_Roles_v1',
    optionalModules: [
        'LM_PC_Bounties_v1', 'LM_PC_RecurringPayments_v1'
    ]
} as const satisfies MixedRequestedModules

const { inputs, estimateGas, run, simulate } = await deployWorkflow({
    requestedModules
})
```

{% endcode %}

## Deploying the Workflow

After setting up your deployment with the `deployWorkflow` function, you can proceed to deploy the workflow with the specified modules by calling the `run` function and passing the configuration arguments, as shown below:

**Parameters**

* **`args` (required)**:\
  These arguments will be strongly typed by the inverter types library, you need to prove the arguments required by the modules.
* `options` **(optional)**:\
  These are contract executions options, i.e. which can define the number of confirmations...

{% code overflow="wrap" %}

```typescript
import type { GetDeployWorkflowArgs } from '@inverter-network/sdk'

// Should either be `as const` or be passed dirrectly in the `estimateGas`, `run`, `simulate` or `bytecode` function args
const args = {
    // orchestrator section is optional
    orchestrator: {
        independentUpdates: true,
        independentUpdatesAdmin: "0x5eb14c2e7D0cD925327d74ae4ce3fC692ff8ABEF",
    },
    fundingManager: {
        orchestratorTokenAddress: "0x5eb14c2e7D0cD925327d74ae4ce3fC692ff8ABEF",
    },
    authorizer: {
        initialAdmin: "0x7AcaF5360474b8E40f619770c7e8803cf3ED1053",
    },
    optionalModules: {
        LM_PC_RecurringPayments_v1: {
            epochLength: "70000000",
        },
    },
} as const satisfies GetDeployWorkflowArgs<typeof requestedModules>

const { orchestratorAddress, transactionHash } = await run(args);
```

{% endcode %}


# Operate a Workflow

## **Setup Requirements**

* **Set up Inverter Network SDK**: Refer to the[ Quick Start](/sdk/typescript-sdk) guide for detailed instructions.
* **Deploy a Workflow**: Refer to the[ Deploy a Workflow](/sdk/typescript-sdk/deploy-a-workflow) guide for detailed instructions.

{% hint style="info" %}
*( optional )* You can pass in a ModuleData typed object into the `requestedModules` constant's fields, this makes it so that you can work with your self managed inverter modules
{% endhint %}

```typescript
// EXEMPLE MixedRequestedModules USAGE
import type { ModuleData, MixedRequestedModules } from '@inverter-network/sdk'

const AUT_Roles_v1 = {'<your_module_data>'} as const satisifies ModuleData

const requestedModules = {
    fundingManager: 'FM_DepositVault_v1',
    paymentProcessor: 'PP_Simple_v1',
    authorizer: AUT_Roles_v1,
} as const satisfies MixedRequestedModules
```

***

## Retrieving a Workflow

**Parameters**

1. **`orchestratorAddress` (required)**:\
   The address of the orchestrator responsible for managing the workflow. This parameter must always be provided.
2. **`requestedModules` (optional)**:\
   Suggested to be included for end-to-end TypeScript coverage. This parameter provides additional context or configuration for the workflow's orientation.
3. `useTags` **(optional):**\
   This parameter is to optionally disable auto format parse for inputs and outputs (default true).

{% code overflow="wrap" %}

```typescript
import { sdk } from '<your_sdk_export>'

const { getWorkflow } = sdk

// Should either be `as const` or be passed dirrectly in the `requestedModules`
const requestedModules = {
    fundingManager: 'FM_DepositVault_v1',
    paymentProcessor: 'PP_Simple_v1',
    authorizer: 'AUT_Roles_v1',
    optionalModules: [
        'LM_PC_Bounties_v1', 'LM_PC_RecurringPayments_v1'
    ]
} as const satisfies MixedRequestedModules

const workflow = await getWorkflow({
    orchestratorAddress: '0x8a1897E6Fa0236F68f86240C391D2a7bED3Cf85c',
    requestedModules
});

const { 
    orchestrator, 
    authorizer,
    fundingManager,
    optionalModule,
    fundingToken
} = workflow
```

{% endcode %}

## Reading Data

You can read data from any of the modules as shown below. In this example, we are retrieving the `totalSupply` of the fundingToken:

{% code overflow="wrap" %}

```typescript
const totalSupply = await workflow.fundingToken.module.read.totalSupply.run();
```

{% endcode %}

## Writing Data

You can write data to any of the modules as shown below. In this example, we are making a deposit to the funding manager:

{% code overflow="wrap" %}

```typescript
const txHash = await workflow.fundingManager.write.deposit.run('100', {
    confirmations: 1,
    onHash: (hash) => {console.log(hash)},
    onConfirmation: (receipt) => {console.log(receipt)},
    onApprove: (receipts) => {console.log(receipts)}
});
```

{% endcode %}


# Deploy a Contract

## **Setup Requirements**

* **Set up Inverter Network SDK**: Refer to the[ Quick Start](/sdk/typescript-sdk) guide for detailed instructions.

As we have some in house headless contracts and they can be used as dependancies to our `Worfklow`'s we have an SDK api for the deployment of contracts.

## Deploying the Contract

**Parameters**

* **`name` (required)**:\
  This parameter selects which contract to deploy.
* `args` **(required)**:\
  This parameter is used to tell the deployment what the contract arguments are.
* `useTags` **(optional):**\
  This parameter is to optionally disable auto format parse for inputs and outputs (default true).

{% code overflow="wrap" %}

```typescript
import { sdk } from '<your_sdk_export>'

const { deploy } = sdk

const { contractAddress, transactionHash } = await sdk.deploy.write({
      name: 'ERC20Issuance_Blacklist_v1', // Type safe names you can prompt the intellisense
      args: {
        name: 'My Token',
        symbol: 'MT',
        decimals: 18,
        maxSupply: '1000000',
        initialAdmin: deployer,
      },
    })
```

{% endcode %}


# Simulate a Workflow

## **Setup Requirements**

* **Set up Inverter Network SDK**: Refer to the[ Quick Start](/sdk/typescript-sdk) guide for detailed instructions.

As we support multicall functionality there is a case for simulating a workflow deployment which enables us to retreive certain addresses before they exist.

{% hint style="info" %}
*( optional )* You can pass in a ModuleData typed object into the `requestedModules` constant's fields, this makes it so that you can work with your self managed inverter modules
{% endhint %}

```typescript
// EXEMPLE MixedRequestedModules USAGE
import type { ModuleData, MixedRequestedModules } from '@inverter-network/sdk'

const AUT_Roles_v1 = {'<your_module_data>'} as const satisifies ModuleData

const requestedModules = {
    fundingManager: 'FM_DepositVault_v1',
    paymentProcessor: 'PP_Simple_v1',
    authorizer: AUT_Roles_v1,
} as const satisfies MixedRequestedModules
```

***

## Simulating the Workflow Deployment

**Parameters**

* **`requestedModules` (required)**:\
  This parameter defines the modules which will be simulated.
* `args` **(required)**:\
  This parameter is used to tell the simulations what the modules arguments are.
* `tagConfig` **(optional)**:\
  This parameter is to tell the arg's parser how to parse the arguments.
* `useTags` **(optional):**\
  This parameter is to optionally disable auto format parse for inputs and outputs (default true).

{% code overflow="wrap" %}

```typescript
import { sdk } from '<your_sdk_export>'
import type { GetDeployWorkflowArgs } from '@inverter-network/sdk'

const { getSimulatedWorkflow } = sdk

// Should either be `as const` or be passed dirrectly in the `requestedModules`
const requestedModules = {
    fundingManager: 'FM_DepositVault_v1',
    paymentProcessor: 'PP_Simple_v1',
    authorizer: 'AUT_Roles_v1'
} as const satisfies MixedRequestedModules

// Should either be `as const` or be passed dirrectly in to `args`
const args = {
    fundingManager: {
        orchestratorTokenAddress: "0x5eb14c2e7D0cD925327d74ae4ce3fC692ff8ABEF",
    },
    authorizer: {
        initialAdmin: "0x7AcaF5360474b8E40f619770c7e8803cf3ED1053",
    }
} as const satisfies GetDeployWorkflowArgs<typeof requestedModules>

const {
      orchestratorAddress,
      logicModuleAddresses,
      fundingManagerAddress,
      authorizerAddress,
      paymentProcessorAddress,
      bytecode,
      factoryAddress,
      trustedForwarderAddress,
    } = await sdk.getSimulatedWorkflow({
      requestedModules,
      args,
      tagConfig: {
        decimals: 18,
        issuanceTokenDecimals: 18,
      }
    })
```

{% endcode %}


# Perform a Multicall

## **Setup Requirements**

* **Set up Inverter Network SDK**: Refer to the[ Quick Start](/sdk/typescript-sdk) guide for detailed instructions.
* **Retrieve workflow simulation (optional)**: If you are going to batch the workflow deployment itself you can retrieve the preliminary data from [here](/sdk/typescript-sdk/simulate-a-workflow).&#x20;

Inverter has a module multicall provider called `trustedForwarder` which enables developers to batch write calls for inverter managed contracts.

## Executing Module Multicall

In this section we will use a already deployed workflow to showcase the execution.

**Parameters**

* **`trustedForwarderAddress` | `orchestratorAddress` (required)**:\
  This parameter is used to locate the batcher.
* `calls` **(required)**:\
  These parameters are the metadata of the bathed write functions.

{% code overflow="wrap" %}

```typescript
import { sdk } from '<your_sdk_export>'
import type { MixedRequestedModules } from '@inverter-network/sdk'

const { getWorkflow, moduleMulticall } = sdk

const deployer = sdk.walletClient.account.address
const TOTAL_DEPOSIT_AMOUNT = '1000'

// Should either be `as const` or be passed dirrectly in the `requestedModules`
const requestedModules = {
    fundingManager: 'FM_DepositVault_v1',
    paymentProcessor: 'PP_Simple_v1',
    authorizer: 'AUT_Roles_v1'
} as const satisfies MixedRequestedModules

const workflow = await getWorkflow({
    orchestratorAddress: '0x8a1897E6Fa0236F68f86240C391D2a7bED3Cf85c',
    requestedModules,
    fundingTokenType: 'ERC20Issuance_v1'
})

// We will first mint the TOTAL_DEPOSIT_AMOUNT
await workflow.fundingToken.module.write.mint.run([deployer, TOTAL_DEPOSIT_AMOUNT])

// Now we will call deposit twice in one transaction
// NOTE: The bytecode run will handle the needed 2 approves, if you want to handle it yourself, pass in the skipApprove method option at the second index of the params `{skipApprove: true}`
const { returnDatas, statuses, transactionHash } =
        await sdk.moduleMulticall.write(
          {
            orchestratorAddress: workflow.orchestrator.address,
            calls: [
              {
                address: workflow.fundingManager.address,
                allowFailure: false,
                callData: await workflow.fundingManager.bytecode.deposit.run('500')
              },
              {
                address: workflow.fundingManager.address,
                allowFailure: false,
                callData: await workflow.fundingManager.bytecode.deposit.run('500')
              }
            ],
          }
        )
        
```

{% endcode %}


# React SDK

## Installation <a href="#installation" id="installation"></a>

To install the React SDK, use your preferred package manager from the command line. For example, if you use bun, execute the following command:

{% code overflow="wrap" %}

```bash
bun add @inverter-network/react wagmi@^2.14.11 viem@^2.24.2 @tanstack/react-query@^5.59.0
```

{% endcode %}

***

## Initializing the React SDK <a href="#initializing-the-sdk" id="initializing-the-sdk"></a>

Since our React SDK uses `@tanstack/react-query`, `wagmi` and `viem` we need these instances to be present at the parent level.

`@inverter-network/react` SDK has the export paths `@inverter-network/react` and `@inverter-network/react/client` Client components and hooks are exported from `*/client` this is done to ensure `Next.js` users have a separate import path for server components .

{% code overflow="wrap" %}

```typescript
'use client'

import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { getERPCTransport } from '@inverter-network/sdk'
import { WagmiProvider, createConfig, http } from 'wagmi'
import { sepolia } from 'viem/chains'

const chains = [sepolia]

const queryClient = new QueryClient()

const wagmiConfig = createConfig({
    chains,
    multiInjectedProviderDiscovery: false,
    transports: {
        [sepolia.id]: getERPCTransport(sepolia.id),
    },
    ssr: true, // If the user is using a SSR supporting framework
    cacheTime: 5000, // 5 seconds
  })

export function Providers({ children }: { children: React.ReactNode }) {
  return (
    <QueryClientProvider client={queryClient}>
      <WagmiProvider config={wagmiConfig} reconnectOnMount>
        {children}
      </WagmiProvider>
    </QueryClientProvider>
  )
}
```

{% endcode %}


# Deploy a Workflow

## **Setup Requirements**

1. **Set up Inverter Network SDK**: Refer to the[ Quick Start](/sdk/react-sdk) Guide for detailed instructions.

{% hint style="info" %}
*( optional )* You can pass in a ModuleData typed object into the `requestedModules` constant's fields, this makes it so that you can work with your self managed inverter modules
{% endhint %}

```typescript
// EXEMPLE MixedRequestedModules USAGE
import type { ModuleData, MixedRequestedModules } from '@inverter-network/sdk'

const AUT_Roles_v1 = {'<your_module_data>'} as const satisifies ModuleData

const requestedModules = {
    fundingManager: 'FM_DepositVault_v1',
    paymentProcessor: 'PP_Simple_v1',
    authorizer: AUT_Roles_v1,
} as const satisfies MixedRequestedModules
```

***

## Deploying the Workflow

All we have to do is decide on the `requestedModules` retrieve the `runDeployment` mutation and fill in the typesafe `arg` then we can run the mutation in our UI.

**Parameters**

* **`requestedModules` (required)**:\
  This parameter defines the modules which will be deployed.
* `useTags` **(optional):**\
  This parameter is to optionally disable auto format parse for inputs and outputs (default true).

{% code overflow="wrap" %}

```typescript
'use client'

import { useDeployWorkflow } from '@inverter-network/react/client'
import type {
  MixedRequestedModules,
  GetDeployWorkflowArgs,
} from '@inverter-network/sdk'

import { Button } from '@/components/ui/button'
import { useAccount } from 'wagmi'

// Defined the modules to be deployed in typesafe manner
const requestedModules = {
  fundingManager: 'FM_DepositVault_v1',
  paymentProcessor: 'PP_Simple_v1',
  authorizer: 'AUT_Roles_v1',
  optionalModules: ['LM_PC_Bounties_v1'],
} as const satisfies MixedRequestedModules

export default function Page() {
  const { address } = useAccount()

  const { runDeployment } = useDeployWorkflow({ requestedModules })

  // Define the args for the modules in typesafe manner
  const args = {
    fundingManager: {
      orchestratorTokenAddress: '<your_funding_token_address>',
    },
    authorizer: {
      initialAdmin: address,
    },
  } as const satisfies GetDeployWorkflowArgs<typeof requestedModules>

  // Return a simple ui to trigger the flow
  return (
    <form
      className="w-screen h-screen flex flex-col items-center justify-center gap-3"
      onSubmit={(e) => {
        e.preventDefault()
        runDeployment.mutate(args)
      }}
    >
      <h1>Orchestrator Address: {runDeployment.data?.orchestratorAddress}</h1>

      <h1>Transaction Hash: {runDeployment.data?.transactionHash}</h1>

      <Button type="submit" loading={runDeployment.isPending}>
        Deploy
      </Button>
    </form>
  )
}
```

{% endcode %}


# Operate a Workflow

## **Setup Requirements**

* **Set up Inverter Network SDK**: Refer to the[ Quick Start](/sdk/react-sdk) guide for detailed instructions.
* **Deploy a Workflow**: Refer to the[ Deploy a Workflow](/sdk/react-sdk/deploy-a-workflow) guide for detailed instructions.

{% hint style="info" %}
*( optional )* You can pass in a ModuleData typed object into the `requestedModules` constant's fields, this makes it so that you can work with your self managed inverter modules
{% endhint %}

```typescript
// EXEMPLE MixedRequestedModules USAGE
import type { ModuleData, MixedRequestedModules } from '@inverter-network/sdk'

const AUT_Roles_v1 = {'<your_module_data>'} as const satisifies ModuleData

const requestedModules = {
    fundingManager: 'FM_DepositVault_v1',
    paymentProcessor: 'PP_Simple_v1',
    authorizer: AUT_Roles_v1,
} as const satisfies MixedRequestedModules
```

***

## Retrieving a Workflow

We strongly recommend passing in a `readonly requestedModules` since this ensures that your `workflow` response will be strongly typed. Also you will have to pass in a `orchestratorAddress` in to the query.

**Parameters**

* **`requestedModules` (required)**:\
  This parameter defines the modules which will be deployed.
* `useTags` **(optional):**\
  This parameter is to optionally disable auto format parse for inputs and outputs (default true).

{% code overflow="wrap" %}

```typescript
'use client'

import { useWorkflow } from '@inverter-network/react/client'
import type { MixedRequestedModules } from '@inverter-network/sdk'

import { Button } from '@/components/ui/button'
import { useMutation } from '@tanstack/react-query'

// Defined the modules to be used in the workflow in typesafe manner
const requestedModules = {
  fundingManager: 'FM_DepositVault_v1',
  paymentProcessor: 'PP_Simple_v1',
  authorizer: 'AUT_Roles_v1',
  optionalModules: ['LM_PC_Bounties_v1'],
} as const satisfies MixedRequestedModules

export default function Page() {
  const workflow = useWorkflow({
    orchestratorAddress: '<your_orchestrator_address>',
    requestedModules,
  })

  // Setup a read mutation to run the workflow function
  const readTitle = useMutation({
    mutationFn: async () => {
      if (!workflow.data) throw new Error('No workflow instance found')

      return await workflow.data.fundingManager.read.title.run()
    },
  })
  
  // Setup a write mutation to run the workflow function
  const deposit = useMutation({
    mutationFn: async () => {
      if (!workflow.data) throw new Error('No workflow instance found')

      return await workflow.fundingManager.write.deposit.run('100', {
          confirmations: 1,
          onHash: (hash) => {console.log(hash)},
          onConfirmation: (receipt) => {console.log(receipt)},
          onApprove: (receipts) => {console.log(receipts)}
      })
    },
  })
  

  // Return a simple ui to trigger the flow
  return (
    <form
      className="w-screen h-screen flex flex-col items-center justify-center gap-3"
      onSubmit={(e) => {
        e.preventDefault()
        readTitle.mutate()
        deposit.mutate()
      }}
    >
      <h1>Funding Manager Title: {readTitle?.data ?? 'No Data Yet...'}</h1>
      
      <h1>Deposit Transaction Hash: {deposit?.data ?? 'No Data Yet...'}</h1>

      <Button type="submit" loading={readTitle.isPending}>
        Read
      </Button>
    </form>
  )
}
```

{% endcode %}


# Deploy a Contract

## **Setup Requirements**

* **Set up Inverter Network SDK**: Refer to the[ Quick Start](/sdk/react-sdk) guide for detailed instructions.

As we have some in house headless contracts and they can be used as dependancies to our `Worfklow`'s we have a React SDK api for the deployment of contracts.

## Deploying the Contract

**Parameters**

* **`name` (required)**:\
  This parameter points to the contract to be deployed.
* `kind` **(optional)**:\
  This parameter is to select return type 'write' | 'bytecode' (default 'write').
* `useTags` **(optional):**\
  This parameter is to optionally disable auto format parse for inputs and outputs (default true).

{% code overflow="wrap" %}

```typescript
'use client'

import { useDeploy } from '@inverter-network/react/client'

import { Button } from '@/components/ui/buttom'
import { FloatingLabelInput } from '@/components/ui/floating-label-input'

export default function Page() {
  const { mutate, isPending, userArgs, handleSetUserArgs } = useDeploy({
    kind: 'write'
    name: 'ERC20Issuance_Blacklist_v1', // Type safe names you can prompt intellisense
  })

  // Return a simple ui to trigger the flow
  return (
    <form
      className="w-screen h-screen flex flex-col items-center gap-3 justify-center"
      onSubmit={(e) => {
        e.preventDefault()
        mutate()
      }}
    >
      <h1>
        Transaction Hash: {mutate.data?.transactionHash ?? 'Not Deployed'}
      </h1>

      <h1>
        Contract Address: {mutate.data?.contractAddress ?? 'Not Deployed'}
      </h1>

      <FloatingLabelInput
        label="Token Name"
        name="name"
        value={userArgs.name}
        onChange={(e) => handleSetUserArgs('name', e.target.value)}
      />

      <FloatingLabelInput
        label="Token Symbol"
        name="symbol"
        value={userArgs.symbol}
        onChange={(e) => handleSetUserArgs('symbol', e.target.value)}
      />

      <FloatingLabelInput
        label="Token Decimals"
        name="decimals"
        value={userArgs.decimals}
        onChange={(e) => handleSetUserArgs('decimals', e.target.value)}
      />

      <FloatingLabelInput
        label="Token Max Supply"
        name="maxSupply"
        value={userArgs.maxSupply}
        onChange={(e) => handleSetUserArgs('maxSupply', e.target.value)}
      />

      <FloatingLabelInput
        label="Token Initial Admin"
        name="initialAdmin"
        value={userArgs.initialAdmin}
      />

      <Button type="submit" loading={isPending}>
        Deploy
      </Button>
    </form>
  )
}

```

{% endcode %}


# Query the Indexer

Makes a query to the indexer and handles states, uses `@tanstack/react-query` under the hood, hence you don't need to think about caching the results and utilize the indexer in your client side application.

{% hint style="info" %}
Currently `turbo` can cause problems with graphql parsers. ( with the latest turbo releases this was resolved )
{% endhint %}

{% code overflow="wrap" %}

```typescript
'use client'

import { useGraphQLQuery } from '@inverter-network/react/client'
import type { GraphQLQueryArgs } from '@inverter-network/graphql'

export default function Page() {
    // Defined the fields which will make the query
    const fields = {
      Token: {
        __args: {
          where: {
            address: {
              _eq: '0x961bB3932A7efAa9aDcc7409e1fea090479E8312',
            },
            chainId: {
              _eq: 1101,
            },
          },
        },
        chainId: 1,
        address: 1,
        name: 1,
        decimals: 1,
        symbol: 1,
        totalSupply: 1,
      }
  } as const satisfies GraphQLQueryArgs
    
    const query = useGraphQLQuery({
        // Optional: dependencies, these determine if the query should update upon the change in the array
        dependencies: [],
        // Optional: options, i.e. enabled
        options: {},
        fields,
    })
    
    // Return a simple ui to trigger the flow
    return (
        <div className="w-screen h-screen flex flex-col gap-3 items-center justify-center">
            <h1>
                Token Name: {query.data?.Token[0].name ?? 'No Data Yet...'}
            </h1>
            
            <h1>
                Token Symbol: {query.data?.Token[0].symbol ?? 'No Data Yet...'}
            </h1>
        </div>
    )
}
```

{% endcode %}


# Subscribe to the Indexer

Subscribes to the indexer using Web Socket, handles the client cache by using `React.useMemo` just plug it in your client side application and you have a live data feed.

{% hint style="info" %}
Currently `turbo` can cause problems with graphql parsers.
{% endhint %}

{% code overflow="wrap" %}

```typescript
'use client'

import { useGraphQLSubscription } from '@inverter-network/react/client'
import type { GraphQLQueryArgs } from '@inverter-network/graphql'

export default function Page() {
    // Defined the fields which will make the sub query
    const fields = {
      Token: {
        __args: {
          where: {
            address: {
              _eq: '0x961bB3932A7efAa9aDcc7409e1fea090479E8312',
            },
            chainId: {
              _eq: 1101,
            },
          },
        },
        chainId: 1,
        address: 1,
        name: 1,
        decimals: 1,
        symbol: 1,
        totalSupply: 1,
      }
  } as const satisfies GraphQLQueryArgs
    
    const { data, error, isLoading } = useGraphQLSubscription({
        // Optional: enabled, determines if the sub will run
        enabled: true
        fields,
    })
    
    // Return a simple ui to trigger the flow
    return (
        <div className="w-screen h-screen flex flex-col gap-3 items-center justify-center">
            <h1>
                Token Name: {data?.Token[0].name ?? 'No Data Yet...'}
            </h1>
            
            <h1>
                Token Symbol: {data?.Token[0].symbol ?? 'No Data Yet...'}
            </h1>
        </div>
    )
}
```

{% endcode %}


# Simulate a Workflow

## **Setup Requirements**

1. **Set up Inverter Network SDK**: Refer to the[ Quick Start](/sdk/react-sdk) Guide for detailed instructions.

{% hint style="info" %}
*( optional )* You can pass in a ModuleData typed object into the `requestedModules` constant's fields, this makes it so that you can work with your self managed inverter modules
{% endhint %}

```typescript
// EXEMPLE MixedRequestedModules USAGE
import type { ModuleData, MixedRequestedModules } from '@inverter-network/sdk'

const AUT_Roles_v1 = {'<your_module_data>'} as const satisifies ModuleData

const requestedModules = {
    fundingManager: 'FM_DepositVault_v1',
    paymentProcessor: 'PP_Simple_v1',
    authorizer: AUT_Roles_v1,
} as const satisfies MixedRequestedModules
```

***

## Simulating the Workflow

All we have to do is decide on the `requestedModules` and we can display or use the output of the simulation. This simulation lets us retrieve the preliminary addresses of a workflow before it is deployed.

**Parameters**

* **`requestedModules` (required)**:\
  This parameter defines the modules which will be deployed.
* `args` **(required)**:\
  This parameter is the arguments for simulated workflow deployment.
* `useTags` **(optional):**\
  This parameter is to optionally disable auto format parse for inputs and outputs (default true).

{% code overflow="wrap" %}

```typescript
'use client'

import { useGetSimulatedWorkflow } from '@inverter-network/react/client'
import type {
  MixedRequestedModules,
  GetDeployWorkflowArgs,
} from '@inverter-network/sdk'
import { useAccount } from 'wagmi'

import { Spinner } from '@/components/ui/spinner'

// Defined the modules to be deployed in typesafe manner
const requestedModules = {
  fundingManager: 'FM_DepositVault_v1',
  paymentProcessor: 'PP_Simple_v1',
  authorizer: 'AUT_Roles_v1',
  optionalModules: ['LM_PC_Bounties_v1'],
} as const satisfies MixedRequestedModules

export default function Page() {
  const { address } = useAccount()
  
  // Define the args for the modules in typesafe manner
  const args = {
    fundingManager: {
      orchestratorTokenAddress: '<your_funding_token_address>',
    },
    authorizer: {
      initialAdmin: address,
    },
  } as const satisfies GetDeployWorkflowArgs<typeof requestedModules>
  
  const { data, isPending } = useGetSimulatedWorkflow({ requestedModules, args })
  
  if (isPending) return (
    <div className="w-screen h-screen flex flex-col items-center justify-center">
      <Spinner />
    </div>
  )

  // Return a simple ui to display the results
  return (
    <div className="w-screen h-screen flex flex-col items-center justify-center gap-3">
      <h1>Orchestrator Address: {data?.orchestratorAddress}</h1>

      <h1>Authorizer Address: {data?.authorizerAddress}</h1>
      
      <h1>Funding Manager Address: {data?.fundingManagerAddress}</h1>
      
      <h1>Payment Processor Address: {data?.paymentProcessorAddress}</h1>
      
      <h1>Logic Module Addresses: {data?.logicModuleAddresses.join(', ')}</h1>
      
      <h1>Deployment Bytecode: {data?.bytecode.slice(0, 100)}...</h1>
      
      <h1>Trusted Forwared Address: {data?.trustedForwarderAddress}</h1>
      
      <h1>Factory Address: {data?.factoryAddress}</h1>
    </form>
  )
}
```

{% endcode %}


# Perform a Multicall

## **Setup Requirements**

1. **Set up Inverter Network SDK**: Refer to the[ Quick Start](/sdk/react-sdk) Guide for detailed instructions.

## Performing the Multicall

We will demonstrate the multicall mutation hook with the aid of `useWorkflow` since we need some bytecode to batch into the multicall.&#x20;

**Parameters**

* `kind` **(optional)**:\
  This parameter is to select return type 'write' | 'simulate' (default 'write').

{% code overflow="wrap" %}

```typescript
'use client'

import { useModuleMulticall } from '@inverter-network/react/client'
import type {
  MixedRequestedModules,
  GetDeployWorkflowArgs,
} from '@inverter-network/sdk'

import { Button } from '@/components/ui/button'

// Defined the modules to be used in the workflow in typesafe manner
const requestedModules = {
  fundingManager: 'FM_DepositVault_v1',
  paymentProcessor: 'PP_Simple_v1',
  authorizer: 'AUT_Roles_v1',
  optionalModules: ['LM_PC_Bounties_v1'],
} as const satisfies MixedRequestedModules

export default function Page() {
  const workflow = useWorkflow({
    orchestratorAddress: '<your_orchestrator_address>',
    requestedModules,
  })
  
  const { mutate, data, isPending } = useModuleMulticall({
    kind: 'write',
    orchestratorAddress: workflow.data!.orchestrator.address,
  })
  
  const { returnDatas, statuses, transactionHash } = data || {
    returnDatas: [],
    statuses: [],
    transactionHash: '',
  }

  // Return a simple ui to trigger the flow
  return (
    <form
      className="w-screen h-screen flex flex-col items-center justify-center gap-3"
      onSubmit={async (e) => {
        e.preventDefault()
        runDeployment.mutate({
          calls: [
            {
              address: workflow.data!.fundingManager.address,
              allowFailure: false,
              callData: await workflow.data!.fundingManager.bytecode.deposit.run('500'),
            },
            {
              address: workflow.fundingManager.address,
              allowFailure: false,
              callData: await workflow.data!.fundingManager.bytecode.deposit.run('500'),
            },
          ],
        })
      }}
    >
      <h1>Transaction Hash: {transactionHash}</h1>
    
      <h1>Statuses: {statuses.join(', ')}</h1>
      
      <h1>Return Datas: {returnDatas.map((i) => i.slice(0, 100)).join(', ')}</h1>

      <Button type="submit" loading={isPending}>
        Deploy
      </Button>
    </form>
  )
}
```

{% endcode %}


# Graphql SDK

## Installation <a href="#installation" id="installation"></a>

To install the Graphql SDK, use your preferred package manager from the command line. For example, if you use bun, execute the following command:

```bash
bun add @inverter-network/graphql
```

***

## Initializing the Graphql SDK <a href="#initializing-the-sdk" id="initializing-the-sdk"></a>

@inverter-network/graphql utilizes a singleton class instance hence the main initialization is **optionally** updating the graphql endpoint.

<pre class="language-typescript"><code class="lang-typescript">import { Client } from '@inverter-network/graphql'

<strong>const devUrl = 'https://dev.indexer.inverter.network/v1/graphql'
</strong>const prodUrl = 'https://indexer.inverter.network/v1/graphql'

<strong>Client.updateUrl(devUrl) // By default the Client uses `prodUrl`
</strong></code></pre>

***

## Subscribing and Querying

Both Subscription and Query utilizes the same fields object, all we have to do is import query or subscription functions from the package.

{% code overflow="wrap" %}

```typescript
import { type GraphQLQueryArgs, query, subscription } from '@inverter-network/graphql'

const fields = {
  Token: {
    __args: {
      where: {
        address: {
          _eq: '0x961bB3932A7efAa9aDcc7409e1fea090479E8312',
        },
        chainId: {
          _eq: 1101,
        },
      },
    },
    chainId: 1,
    address: 1,
    name: 1,
    decimals: 1,
    symbol: 1,
    totalSupply: 1,
  },
} as const satisfies GraphQLQueryArgs

// Query
const tokens = await query(fields)

// Subscription
const sub = subscription(fields)

// You can add as many callbacks to a subscription
sub.addCallback((data) => {
  console.log(data)
})
```

{% endcode %}


# Workflow Guides

This section guides the users of the SDK of the many use cases between modules and workflows.


# Grant/Revoke Roles

## **Introduction**

There is a common role flow in inverter network, this guide guides you on how to manage granting / revoking and checking different roles throughout our protocol.

## **Setup Requirements**

The guide includes code snippets for Inverter Network's TypeScript SDK. Please refer to the relevant code snippets based on the SDK you are using.

1. **Set up Inverter Network SDK**: Refer to the Quick Start guides for detailed instructions. See the [React SDK Guide](/sdk/react-sdk) or [TypeScript SDK Guide](/sdk/typescript-sdk) for more information.
2. **Deploy a Workflow**: Refer to the Deploy a Workflow guide for detailed instructions. See the [React SDK Guide ](/sdk/react-sdk/deploy-a-workflow)or [TypeScript SDK Guide](/sdk/typescript-sdk/deploy-a-workflow) for more information.
3. **Retrieve a deployed Workflow**: Refer to the Operate a Workflow guide for detailed instructions. See the [React SDK Guide](/sdk/react-sdk/operate-a-workflow) or [TypeScript SDK Guide](/sdk/typescript-sdk/operate-a-workflow) for more information.

* **Optionally if your setup needs a specific contract**: Refer to the Deploy a Contract Guide for detailed instructions. See the [React SDK](/sdk/react-sdk/deploy-a-contract) Guide or [TypeScript SDK](/sdk/typescript-sdk/deploy-a-contract) Guide for more information.

## Retrieve Workflow Args

The chosen modules for the workflows should be specified for type safety.

{% code overflow="wrap" %}

```typescript
import type { RequestedModules } from '@inverter-network/sdk'

// Should either be `as const` or be passed dirrectly in the `requestedModules` param
const requestedModules = {
    fundingManager: 'FM_DepositVault_v1',
    paymentProcessor: 'PP_Simple_v1',
    authorizer: 'AUT_Roles_v1',
    optionalModules: [
        'LM_PC_Bounties_v1'
    ]
} as const satisfies RequestedModules
```

{% endcode %}

## Fetch Role Hexes

To begin with the process we need the role hexes from the authorizer.

{% code overflow="wrap" %}

```typescript
const adminRole = await workflow.authorizer.read.getAdminRole.run()

const verifierRole = await workflow.optionalModule.LM_PC_Bounties_v1.read.VERIFIER_ROLE.run()
```

{% endcode %}

## Admin Role

### Check Role

For checking the status of the role we need to use the role hex.

```typescript
const hasAdminRole = await workflow.authorizer.read.hasRole.run([
    adminRole,
    walletClient.account.address,
])
```

### Grant or Revoke Role

For admin roles we need to use the `grantRole` or `revokeRole` function from the authorizer.

{% code overflow="wrap" %}

```typescript
const args = [
    adminRole,
    walletClient.account.address,
] as const

// Grant role
const grantTransactionHash = await workflow.authorizer.write.grantRole.run(args)

// Revoke role
const revokeTransactionHash = await workflow.authorizer.write.revokeRole.run(args)
```

{% endcode %}

## Module Role

For any role which is not a `orchestrator` admin role we need to generate a role id using the `authorizer` this generation is necessary to have a unique identifier since every workflow has different modules with different addresses.

### Generate Role

Note that this is only to check the status of a module role.

{% code overflow="wrap" %}

```typescript
const generatedVerifierRole = await workflow.authorizer.read.generateRoleId.run([
    workflow.optionalModule.LM_PC_Bounties_v1.address,
    verifierRole,
])
```

{% endcode %}

### Check Role

For checking the status of the role we need to use the generated role.

{% code overflow="wrap" %}

```typescript
const hasVerifierRole = await workflow.authorizer.read.hasRole.run([
    generatedVerifierRole,
    walletClient.account.address,
])
```

{% endcode %}

### Grant or Revoke Role

For module roles we need to use the `grantModuleRole` or `revokeModuleRole` function from the module itself not the authorizer function.

For the granting or revoking we are using the non generated role.

{% code overflow="wrap" %}

```typescript
const args = [
    verifierRole,
    walletClient.account.address,
] as const

// Grant role
const grantTransactionHash = await workflow.optionalModule.LM_PC_Bounties_v1.write.grantModuleRole.run(args)

// Revoke role
const revokeTransactionHash = await workflow.optionalModule.LM_PC_Bounties_v1.write.revokeModuleRole.run(args)
```

{% endcode %}


# Bounty Manager

## **Introduction**

This guide focusses on the most common patterns of interactions with the Bounty Manager Module. Please refer to the [Technical Reference](/contracts/technical-reference/modules/logic-module/lm_pc_bounties_v1.sol#public-functions) section to see all public getters and setters.

## **Setup Requirements**

The guide includes code snippets for Inverter Network's TypeScript SDK. Please refer to the relevant code snippets based on the SDK you are using.

1. **Set up Inverter Network SDK**: Refer to the Quick Start guides for detailed instructions. See the [React SDK Guide](/sdk/react-sdk) or [TypeScript SDK Guide](/sdk/typescript-sdk) for more information.
2. **Deploy a Workflow**: Refer to the Deploy a Workflow guide for detailed instructions. See the [React SDK Guide ](/sdk/react-sdk/deploy-a-workflow)or [TypeScript SDK Guide](/sdk/typescript-sdk/deploy-a-workflow) for more information.
3. **Retrieve a deployed Workflow**: Refer to the Operate a Workflow guide for detailed instructions. See the [React SDK Guide](/sdk/react-sdk/operate-a-workflow) or [TypeScript SDK Guide](/sdk/typescript-sdk/operate-a-workflow) for more information.

* **Optionally if your setup needs a specific contract**: Refer to the Deploy a Contract Guide for detailed instructions. See the [React SDK](/sdk/react-sdk/deploy-a-contract) Guide or [TypeScript SDK](/sdk/typescript-sdk/deploy-a-contract) Guide for more information.

## Managing Bounty Manager Roles <a href="#grant-or-revoke-role-1" id="grant-or-revoke-role-1"></a>

Managing roles for the Bounty Manager involves several steps, including reading role, generating role IDs, assigning roles, and revoking them.

### Retrieving the roles

The Bounty Manager utilizes several roles to handle the issuance, verification, and claiming of bounties. The first step is to retrieve the available roles in the Bounty Manager, as demonstrated below:

{% code overflow="wrap" %}

```typescript
const VERIFIER_ROLE = await workflow.optionalModule.LM_PC_Bounties_v1.read.VERIFIER_ROLE.run()

const BOUNTY_ISSUER_ROLE = await workflow.optionalModule.LM_PC_Bounties_v1.read.BOUNTY_ISSUER_ROLE.run()

const CLAIMANT_ROLE = await workflow.optionalModule.LM_PC_Bounties_v1.read.CLAIMANT_ROLE.run()
```

{% endcode %}

## **Check If User Has Module Roles**

The following two-step process validates whether a given address has roles assigned to it:

{% code overflow="wrap" %}

```typescript
// Step 1. Generate the role ids
const [GEN_VERIFIER_ROLE, GEN_BOUNTY_ISSUER_ROLE, GEN_CLAIMANT_ROLE] =
      await Promise.all(
        [VERIFIER_ROLE, BOUNTY_ISSUER_ROLE, CLAIMANT_ROLE].map((id) => {
          return workflow.authorizer.read.generateRoleId.run([
            workflow.optionalModule.LM_PC_Bounties_v1.address,
            id,
          ])
        })
      )
      
// Step 2. Check if the user has the role
const [HAS_VERIFIER_ROLE, HAS_BOUNTY_ISSUER_ROLE, HAS_CLAIMANT_ROLE] =
      await Promise.all(
        [GEN_VERIFIER_ROLE, GEN_BOUNTY_ISSUER_ROLE, GEN_CLAIMANT_ROLE].map(
          (genId) => {
            return workflow.authorizer.read.hasRole.run([
              genId,
              <wallet_address>,
            ])
          }
        )
      )
```

{% endcode %}

## Grant and Revoke Role

The following section demonstrates how to grant and revoke roles for a wallet address.

{% code overflow="wrap" %}

```typescript
const walletAddress = sdk.walletClient.account.address

const args = [ 
    <VERIFIER_ROLE | BOUNTY_ISSUER_ROLE | CLAIMANT_ROLE>,
    walletAddress
] as const

// Grant role
const grantRoleTransactionHash = await workflow.optionalModule.LM_PC_Bounties_v1.write.grantModuleRole.run(args)

// Revoke role
const revokeRoleTransactionHash = await workflow.optionalModule.LM_PC_Bounties_v1.write.revokeModuleRole.run(args)
```

{% endcode %}

## Bounty Creation

### Add a Bounty

The following section explains how to add a bounty to the Bounty Manager:

{% code overflow="wrap" %}

```typescript
import { decodeEventLog } from 'viem'
import { getModuleData } from '@inverter-network/abis'

let bountyId = string

const bounty = [
    // Minimum Payment Amount
    '1000',
    // Maximum Payment Amount
    '10000',
    // Details ( type any )
    {
        timestamp: 1734448333
        message: 'hello' 
    }
] as const

const addBountyTransactionHash =
  await workflow.optionalModule.LM_PC_Bounties_v1.write.addBounty.run(bounty, {
    confirmations: 1,
    // !Optional! You can get the list of bounty id's from a different endpoint
    onConfirmation: (receipt) => {
      // Define the ABI for the BountyAdded event
      const BountyAddedAbi = [
        getModuleData('LM_PC_Bounties_v1').abi.find(
          (i) => i.name === 'BountyAdded'
        ),
      ]

      // Decode the logs using the ABI
      const decodedLogs = decodeEventLog({
        abi: BountyAddedAbi,
        data: receipt.logs[0].data,
        topics: receipt.logs[0].topics,
      })

      // Retrieve the bountyId from the decoded logs
      bountyId = decodedLogs.args.bountyId.toString()
    },
  })
```

{% endcode %}

### Add Bounty in Batches

The following section explains how to add multiple bounties in batches

{% code overflow="wrap" %}

```typescript
const bounties = [
    // Minimum Payment Amounts
    ['1000`, '2000', '3000'],
    // Maximum Payment Amount
    ['10000', '20000', '30000'],
    // Details ( type any )
    [{
        timestamp: 1734448333
        message: 'hello' 
    },
    {
        timestamp: 1734448334
        message: 'hello1' 
    },
    {
        timestamp: 1734448335
        message: 'hello2' 
    }]
] as const

const addBountyTransactionHash = await workflow.optionalModule.LM_PC_Bounties_v1.write.addBountyBatch.run(bounties)
```

{% endcode %}

### Read Bounty

The following section explains how to read a given bounty information based on the `bountyId`

{% code overflow="wrap" %}

```typescript
const bountyInformation = await workflow.optionalModule.LM_PC_Bounties_v1.read.getBountyInformation.run(bountyId)

const {
    minimumPayoutAmount
    maximumPayoutAmount
    details: {
        timestamp,
        message
    }
    locked
} = bountyInformation
```

{% endcode %}

## Bounty Claim

### Add Bounty Claim

The following section explains how to submit a bounty claim:

{% code overflow="wrap" %}

```typescript
import { decodeEventLog, parseAbiItem } from 'viem'

let claimId = string

const contributers = 
  [
    // Bounty Id
    bountyId,
    // Contributers
    [{ addr: <wallet_address>, claimAmount: '100' }],
    // Details ( type any )
    {
      claimUrl: 'https://www.google.com',
    },
  ] as const

const claimTransactionHash =
  await workflow.optionalModule.LM_PC_Bounties_v1.write.addClaim.run(
    contributers,
    {
      confirmations: 1,
      // !Optional! You can get the list of claim id's from a different endpoint
      onConfirmation: (receipt) => {
        const claimAddedAbi = parseAbiItem(
          'event ClaimAdded(uint256 indexed claimId,uint256 indexed bountyId,(address,uint256)[] contributors,bytes details)'
        )

        const decodedLogs = decodeEventLog({
          abi: [claimAddedAbi],
          data: receipt.logs[0].data,
          topics: receipt.logs[0].topics,
        })

        claimId = decodedLogs.args.claimId.toString()
      },
    }
  )
```

{% endcode %}

### Read Bounty Claim

The following section explains how to read a submitted bounty claim

{% code overflow="wrap" %}

```typescript
const claimInformation = await workflow.optionalModule.LM_PC_Bounties_v1.read.getClaimInformation.run(claimId)

const {
  details: { claimUrl },
  bountyId,
  claimed,
  contributors,
} = claimInformation
```

{% endcode %}

## Verify Bounty Claim

### Verify a Claim

The following section explains how to verify a claim providing the `claimId` and `contributors` as parameters:

{% code overflow="wrap" %}

```typescript
const transactionHash = await workflow.optionalModule.LM_PC_Bounties_v1.write.verifyClaim.run([
    claimId,
    contributors,
])
```

{% endcode %}


# Bonding Curve

## **Introduction**

This guide focusses on the most common patterns of interactions with the Bonding Curve Modules. Please refer to the [Technical Reference](/contracts/technical-reference/modules/funding-manager/bonding-curve/fm_bc_bancor_redeeming_virtualsupply_v1.sol) section to see all public getters and setters.

## **Setup Requirements**

The guide includes code snippets for Inverter Network's TypeScript SDK. Please refer to the relevant code snippets based on the SDK you are using.

1. **Set up Inverter Network SDK**: Refer to the Quick Start guides for detailed instructions. See the [React SDK Guide](/sdk/react-sdk) or [TypeScript SDK Guide](/sdk/typescript-sdk) for more information.
2. **Deploy a Workflow**: Refer to the Deploy a Workflow guide for detailed instructions. See the [React SDK Guide ](/sdk/react-sdk/deploy-a-workflow)or [TypeScript SDK Guide](/sdk/typescript-sdk/deploy-a-workflow) for more information.
3. **Retrieve a deployed Workflow**: Refer to the Operate a Workflow guide for detailed instructions. See the [React SDK Guide](/sdk/react-sdk/operate-a-workflow) or [TypeScript SDK Guide](/sdk/typescript-sdk/operate-a-workflow) for more information.

* **Optionally if your setup needs a specific contract**: Refer to the Deploy a Contract Guide for detailed instructions. See the [React SDK](/sdk/react-sdk/deploy-a-contract) Guide or [TypeScript SDK](/sdk/typescript-sdk/deploy-a-contract) Guide for more information.

Bancor formula and supported chains can be found here: <https://github.com/InverterNetwork/deployments/tree/main/deployments>&#x20;

### Deployment Setup

* Deploy the `Issuance Token`
* Deploy the `Workflow`
* Retrieve the `Workflow`

### Post Deployment: Set the Curve as a minter

In order to perform this action you should be the deployer of the token

```typescript
await workflow.issuanceToken.module.write.setMinter([
    workflow.fundingManager.address, true
], { confirmations: 1 })
```

### Admin Actions

These actions can be preformed by the workflow admin role

```typescript
// Close/Open Buy/Sell
await workflow.fundingManager.write.closeBuy.run()
await workflow.fundingManager.write.openBuy.run()
await workflow.fundingManager.write.closeSell.run()
await workflow.fundingManager.write.openSell.run()

// Grant/Revoke Workflow Admin Role
const adminRole = await workflow.authorizer.read.DEFAULT_ADMIN_ROLE.run()
await workflow.authorizer.write.grantRole.run([adminRole, deployer])
await workflow.authorizer.write.revokeRole.run([adminRole, deployer])

// Fee Withdrawal
await workflow.fundingManager.write.withdrawProjectCollateralFee.run([
  '<address>' as `0x${string}`,
  '1000', // amount
])

// Update Parameters
await workflow.fundingManager.write.setBuyFee.run(
  '1000' // Fee in ( BPS ) Basis Points
)
await workflow.fundingManager.write.setSellFee.run(
  '1000' // Fee in ( BPS ) Basis Points
)
await workflow.fundingManager.write.setReserveRatioForBuying.run(
  333_333 // Reserve Ratio in ( PPM ) Parts Per Million
)
await workflow.fundingManager.write.setReserveRatioForSelling.run(
  333_333 // Reserve Ratio in ( PPM ) Parts Per Million
)
 await workflow.fundingManager.write.setVirtualCollateralSupply.run(
  '1000' // New Virtual Collateral Supply
)
await workflow.fundingManager.write.setVirtualIssuanceSupply.run(
  '1000' // New Virtual Issuance Supply
)
```

### Curve Actions

These actions can be performed by the users of the product | app. The bonding curve funding managers have a calculate function which uses the formula contract to define the minimum amount out from either buy or sell method.

```typescript
// Buy/Sell

// Amount to buy
const purchaseAmount = '1000'
// Min amount received from the buy
const purchaseReturn =
  await workflow.fundingManager.read.calculatePurchaseReturn.run(
    purchaseAmount
  )

// Buy using the connected account
await workflow.fundingManager.write.buy.run([
  purchaseAmount,
  purchaseReturn,
])
// Buy for another account
await workflow.fundingManager.write.buyFor.run([
  '<address>' as `0x${string}`,
  purchaseAmount,
  purchaseReturn,
])

// Amount to sell
const saleAmount = '1000'
// Min amount out of the sell
const saleReturn =
  await workflow.fundingManager.read.calculateSaleReturn.run(saleAmount)

// Sell using the connected account
await workflow.fundingManager.write.sell.run([saleAmount, saleReturn])
// Sell to another account
await workflow.fundingManager.write.sellTo.run([
  '<address>' as `0x${string}`,
  saleAmount,
  saleReturn,
])
```


# Deposit Vault

## **Introduction**

This guide focusses on the most common patterns of interactions with the Bounty Manager Module. Please refer to the [Technical Reference](/contracts/technical-reference/modules/funding-manager/deposit-vault/fm_depositvault_v1#public-functions) section to see all public getters and setters.

## **Setup Requirements**

The guide includes code snippets for Inverter Network's TypeScript SDK. Please refer to the relevant code snippets based on the SDK you are using.

1. **Set up Inverter Network SDK**: Refer to the Quick Start guides for detailed instructions. See the [React SDK Guide](/sdk/react-sdk) or [TypeScript SDK Guide](/sdk/typescript-sdk) for more information.
2. **Deploy a Workflow**: Refer to the Deploy a Workflow guide for detailed instructions. See the [React SDK Guide ](/sdk/react-sdk/deploy-a-workflow)or [TypeScript SDK Guide](/sdk/typescript-sdk/deploy-a-workflow) for more information.
3. **Retrieve a deployed Workflow**: Refer to the Operate a Workflow guide for detailed instructions. See the [React SDK Guide](/sdk/react-sdk/operate-a-workflow) or [TypeScript SDK Guide](/sdk/typescript-sdk/operate-a-workflow) for more information.

* **Optionally if your setup needs a specific contract**: Refer to the Deploy a Contract Guide for detailed instructions. See the [React SDK](/sdk/react-sdk/deploy-a-contract) Guide or [TypeScript SDK](/sdk/typescript-sdk/deploy-a-contract) Guide for more information.

## Deposit Funding

Deposits a specified amount of tokens into the contract from the sender's account.

{% code overflow="wrap" %}

```typescript
const transactionHash = await workflow.fundingManager.write.deposit.run('1000')
```

{% endcode %}


# Deploy Restricted PIM Factory

## Introduction

The restricted pim factory deployment is almost the same process as the default factory. The only difference being that the user has to pass `factoryType: 'restricted-pim'`  approve their collateral tokens for the pim-factory and pass the extra parameters required by the factory.

## **Setup Requirements**

The guide includes code snippets for Inverter Network's TypeScript SDK. Please refer to the relevant code snippets based on the SDK you are using.

1. **Set up Inverter Network SDK**: Refer to the Quick Start guides for detailed instructions. See the [React SDK Guide](/sdk/react-sdk) or [TypeScript SDK Guide](/sdk/typescript-sdk) for more information.
2. **Deploy a Workflow**: Refer to the Deploy a Workflow guide for detailed instructions. See the [React SDK Guide ](/sdk/react-sdk/deploy-a-workflow)or [TypeScript SDK Guide](/sdk/typescript-sdk/deploy-a-workflow) for more information.
3. **Retrieve a deployed Workflow**: Refer to the Operate a Workflow guide for detailed instructions. See the [React SDK Guide](/sdk/react-sdk/operate-a-workflow) or [TypeScript SDK Guide](/sdk/typescript-sdk/operate-a-workflow) for more information.

* **Optionally if your setup needs a specific contract**: Refer to the Deploy a Contract Guide for detailed instructions. See the [React SDK](/sdk/react-sdk/deploy-a-contract) Guide or [TypeScript SDK](/sdk/typescript-sdk/deploy-a-contract) Guide for more information.

## Args

<pre class="language-typescript" data-overflow="wrap"><code class="lang-typescript">import type { RequestedModule } from '@inverter-network/sdk'

const requestedModules = {
    fundingManager: 'FM_BC_Restricted_Bancor_Redeeming_VirtualSupply_v1',
    authorizer: 'AUT_Roles_v1',
    paymentProcessor: 'PP_Simple_v1',
  } as const satisfies RequestedModules&#x3C;'restricted-pim'>

<strong>const deploymentParameters = (
</strong>  factoryType: 'restricted-pim',
  requestedModules
}
</code></pre>

## Set Up Arguments

Bancor formula and supported chains can be found here: <https://github.com/InverterNetwork/deployments/tree/main/deployments>&#x20;

{% code overflow="wrap" %}

```typescript
const FORMATTED_MAX_UINT = '115792089237316195423570985008687907853269984665640564039457.584007913129639935' as const // Human Readable MAX_UINT

const curveShape = {
  Basic: {
    reserveRatioForBuying: 333_333, // PPM
    reserveRatioForSelling: 333_333, // PPM
    initialIssuanceSupply: '200002.999999999999998676',
    initialCollateralSupply: '296.306333665498798599',
  },
} as const

const args = {
    authorizer: {
      initialAdmin: <admin_address>,
    },
    fundingManager: {
      bondingCurveParams: {
        formula: <bancor_formula>,
        buyFee: <BPS_Amount>,
        sellFee: <BPS_Amount>,
        buyIsOpen: true,
        sellIsOpen: true,
        ...curveShape.Basic,
      },
      collateralToken: <collateral_token_address>,
    },
    issuanceToken: {
      name: <name_of_the_token>,
      symbol: <symbol_of_the_token>,
      decimals: <decimals_of_the_token>,
      maxSupply: FORMATTED_MAX_UINT
    },
    beneficiary: <beneficiary_address>
  } as const satisfies GeDeployWorkflowArgs<typeof requestedModules, 'restricted-pim'>
```

{% endcode %}

## Run The Deployment

Note: Approving of the initial collateral deposit is handled by the run&#x20;

```typescript
const {
    orchestratorAddress,
    transactionHash
} = await run(args, {
    confirmations: 1,
    onHash: (hash) => {console.log(hash)},
    onConfirmation: (receipt) => {console.log(receipt)},
    onApprove: (receipts) => {console.log(receipts)}
})
```


# API

This section lists all methods that are exported by the SDK. For each method it describes what the method is for, lists the import statement, input parameters and return values, and notes anything that might be noteworthy.


# Inverter

The `Inverter` class is the most efficient entry point to the sdk, it provides the main API's with the preliminary required param's pre-filled.

**Import**: imported as follows

```typescript
import { Inverter } from '@inverter-network/sdk'
```

**Usage:**

```typescript
Inverter.getInstance({
    publicClient: PublicClient,
    walletClient?: WalletClient
})
```

**Returns:** Inverter instance

{% code overflow="wrap" %}

```typescript
{
  publicClient: PublicClient
  walletClient: WalletClient

  getWorkflow: (params: {
    orchestratorAddress: `0x${string}`
    requestedModules?: MixedRequestedModules
    fundingTokenType?: WorkflowToken
    issuanceTokenType?: WorkflowIssuanceToken
  }) => Promise<Workflow>

  getDeployWorklowOptions: () => {
    fundingManager: string[]
    authorizer: string[]
    paymentProcessor: string[]
    optionalModules: string[]
  }

  deployWorkflow: (params: {
    requestedModules: MixedRequestedModules,
  }) => Promise<{
    inputs: GetDeployWorkflowInputs,
    run,
    simulate,
    estimateGas
  }>
  
  deploy: {
    write: (params: {name, args}, options?: MethodOptions) => Promise<DeployWriteReturnType>
    bytecode: (params: {name, args}) => Promise<DeployBytecodeReturnType>
  }
  
  getModule: (
    params: Omit<GetModuleParams, 'walletClient' | 'publicClient' | 'self'>
  ) => GetModuleReturnType
  
  getSimulatedWorkflow: (
    params: Omit<
      GetSimulatedWorkflowParams,
      'publicClient' | 'walletClient'
    >
  ): Promise<GetSimulatedWorkflowReturnType>
  
  moduleMulticall: {
    write: (
      params: Omit<ModuleMulticallParams, 'publicClient' | 'walletClient'>,
      options?: MethodOptions
    ) => Promise<ModuleMulticallWriteReturnType>
    simulate: (
      params: Omit<ModuleMulticallParams, 'publicClient' | 'walletClient'>
    ) => Promise<ModuleMulticallSimulateReturnType>
  }
}
```

{% endcode %}


# getDeployWorkflowOptions

Returns the names of all available modules.

**Import**: imported as follows

```typescript
import { getDeployWorkflowOptions } from '@inverter-network/sdk'
```

**Parameters**: expects the following parameters

```typescript
void
```

**Returns**: an object with the following properties

```ts
{
    fundingManager: RequestedModule<'fundingManager'>[]
    authorizer: RequestedModule<'authorizer'>[]
    paymentProcessor: RequestedModule<'paymentProcessor'>[]
    optionalModules: RequestedModule<'optionalModule'>[]
}
```


# deployWorkflow

The `deployWorkflow` method is used to deploy a fresh workflow.

**Import**: imported as follows

```typescript
import { deployWorkflow } from '@inverter-network/sdk'
```

**Parameters**: expects the following parameters

{% code overflow="wrap" %}

```ts
{
    // the public client / provider to make RPC calls
    publicClient: PublicClient
    // the wallet client to sign and submit transactions
    walletClient: WalletClient
    // The modules which will be deployed
    requestedModules: MixedRequestedModules
    // The parser config, in charge of decimals, ...
    tagConfig?: TagConfig
    // The Inverter instance in charge of cache
    self?: Inverter
}
```

{% endcode %}

**Returns**: an object with the following properties

{% code overflow="wrap" %}

```ts
{
    // returns a schema of the inputs required for deploying, e.g. can be used to render input fields
    inputs: GetDeployWorkflowInputs
    
    // a function that takes in deployment parameters, submits a deployment
    run(args: GeDeployWorkflowArgs, options?: MethodOptions): Promise<DeployWorkflowWriteReturnType>
    
    // a function that takes in deployment parameters, simulates a deployment transaction and returns the orchestratorAddress
    simulate: (userArgs: GeDeployWorkflowArgs) => Promise<DeployWorkflowSimulateReturnType>
    
    // a function that takes in deployment parameters, estimates the deployment gas and return value and formatted value
    estimateGas: (userArgs: GeDeployWorkflowArgs) => Promise<DeployWorkflowEstimateGasReturnType>
    
    // a function that returns the bytecode which can be used to deploy the workflow
    bytecode: (userArgs: GeDeployWorkflowArgs) => Promise<DeployWorkflowBytecodeReturnType>
}
```

{% endcode %}


# getModule

The `getModule` method is the most basic way to get the interact-able contract instance for a given module.

**Import**: imported as follows

```typescript
import { getModule } from '@inverter-network/sdk'
```

**Parameters**: an object with the following properties

```ts
({
  // the name of the module
  name: ModuleName
} | {
  // manually passed module data
  moduleData: ModuleData
}) & {
    // the address of the deployed module
    address: `0x${string}`
    // the public client or provider to make RPC calls
    publicClient: PublicClient
    // the wallet client to sign and submit transactions
    walletClient?: WalletClient
    // The parser config, in charge of decimals, ...
    tagConfig?: TagConfig
    // The Inverter instance in charge of cache
    self?: Inverter
}
```

**Returns**: a `Module` object with the following properties

{% code overflow="wrap" %}

```ts
{
    // the name of the module
    name: ModuleName | ModuleData['name']
    // the address of the deployed module
    address: `0x${string}`
    // the type of the module (e.g. authorizer)
    moduleType: ModuleType
    // short description of the module taken from the contract NatSpec documentation
    description: string
    // the write method
    write: {
        [functionName: string]: {
            // name of the function
            name: string
            // description of what the function does taken from NatSpec
            description: string
            // inputs of the abi item
            inputs: ExtendedAbiParameter[]
            // outputs of the abi member
            outputs: ExtendedAbiParameter[]
            // an asynchronous function that whose parameters are of type Primitive<`inputs`> and return values are of type Primitive<`outputs`>
            run: (args: GetMethodArgs, options?: MethodOptions) => Promise<GetMethodResponse>
        }
    }
    estimateGas: // same as write ...
    simulate: // same as write ...
    read: // same as write ...
    bytecode: // same as write ...
}
```

{% endcode %}


# getWorkflow

The `getWorkflow` method is the standard way of getting a whole workflow with instances of all associated modules.

**Import**: imported as follows

```typescript
import { getWorkflow } from '@inverter-network/sdk'
```

**Parameters**: an object with the following properties

{% code overflow="wrap" %}

```ts
{
    // the public client / provider to make RPC calls
    publicClient: PublicClient
    // the wallet client to sign and submit transactions
    walletClient?: WalletClient
    // the address of a deployed orchestrator proxy contract
    orchestratorAddress: 0x${string}
    // includes a specification of the modules used by the workflow. That is which Authorizer, Funding Manager, Payment Processor and optional logic modules are used.
    requestedModules?: MixedRequestedModules
    // name of the issuance token - strongly types the return
    issuanceTokenType?: WorkflowIssuanceToken
    // name of the funding token - strongly types the return
    fundingTokenType?: WorkflowToken
}
```

{% endcode %}

*Note*: passing a requestedModules will ensure typesafety and type completion.

**Returns**: on object with the following properties

```ts
// each ModuleName corresponds to the name of a module (e.g. FM_DepositVault_v1) 
// and each Module is a module instance as described in the previous section
{
    orchestrator: GetModuleReturnType
    fundingManager: GetModuleReturnType
    authorizer: GetModuleReturnType
    paymentProcessor: GetModuleReturnType
    optionalModule: {
        [name: ModuleName]: GetModuleReturnType
    }
    fundingToken: {
        address: `0x${string}`
        module: GetModuleReturnType
        decimals: number
        symbol: string
    }
    // issuance token is conditional based on modules which use issuance logic
    issuanceToken: {
        address: `0x${string}`
        module: GetModuleReturnType
        decimals: number
        symbol: string
    }
}
```


# deploy

The `deploy` object is meant to be used individual contracts, it only supports the bytecode's provided by the abis pkg

**Import**: imported as follows

```typescript
import { deploy } from '@inverter-network/sdk'
```

**Parameters**: a nested object with the following properties

{% code overflow="wrap" %}

```ts
deploy.write: (params: DeployParams, options?: MethodOptions)
deploy.bytecode: (params: DeployParams)
```

{% endcode %}

**Returns**: a nested object with the following properties

```ts
deploy.write: Promise<DeployWriteReturnType>
deploy.bytecode: Promise<DeployBytecodeReturnType>
```


# getSimulatedWorkflow

The `getSimulatedWorkflow` method is used to simulate a non-existing workflow.

**Import**: imported as follows

```typescript
import { getSimulatedWorkflow } from '@inverter-network/sdk'
```

**Parameters**: expects the following parameters

{% code overflow="wrap" %}

```ts
{
    // the public client / provider to make RPC calls
    publicClient: PublicClient,
    // the wallet client to sign and submit transactions
    walletClient: WalletClient,
    // The modules which will be deployed
    requestedModules: MixedRequestedModules,
    // The parser config, in charge of decimals, ...
    tagConfig?: TagConfig
    // If there is a token deployment included the bytecode object
    tokenBytecode?: TokenBytecode
}
```

{% endcode %}

**Returns**: an object with the following properties

{% code overflow="wrap" %}

```ts
{
  // Address of the simulated orchestrator
  orchestratorAddress: `0x${string}`
  // Address of the simulated authorizer
  authorizerAddress: `0x${string}`
  // Address of the simulated funding manager
  fundingManagerAddress: `0x${string}`
  // Address of the simulated payment proccessor
  paymentProcessorAddress: `0x${string}`
  // Addresses of the simulated logic modules
  logicModuleAddresses: `0x${string}`[]
  // Bytecode which can be used to deploy the simulated workflow
  bytecode: `0x${string}`
  // The address of the trusted forwarder for said chain
  trustedForwarderAddress: `0x${string}`
  // The address of the inverter factory
  factoryAddress: `0x${string}`
}
```

{% endcode %}


# moduleMulticall

The `moduleMulticall` method is used to execute or simulate multiple transactions in batch.

**Import**: imported as follows

```typescript
import { moduleMulticall } from '@inverter-network/sdk'
```

**Parameters**: expects the following parameters

{% code overflow="wrap" %}

```ts
moduleMulticall.write: (params: ModuleMulticallParams, options?: MethodOptions)
moduleMulticall.simulate: (params: ModuleMulticallParams)
```

{% endcode %}

**Returns**: an object with the following properties

{% code overflow="wrap" %}

```ts
moduleMulticall.write: Promise<ModuleMulticallWriteReturnType>
moduleMulticall.simulate: Promise<ModuleMulticallSimulateReturnType>
```

{% endcode %}


# Contracts

<figure><img src="/files/dHmOavACE9vJINGTkjvP" alt=""><figcaption></figcaption></figure>


# Technical Specification

[You can find the Inverter Protocol's smart contracts technical specification through this link](https://docs.google.com/document/d/1j6WXBZzyYCOfO36ZYvKkgqrO2UAcy0kW5eJeZousn7E/edit?usp=sharing).


# Security Guidelines

[You can find the Inverter Protocol's security guidelines through this link.](https://docs.google.com/document/d/1CZgM9OEuibNrimbNeActve5n9ro3Ydu03OfSnZfRo_s/edit?usp=sharing)


# Deployment Addresses

## Deterministic Deployment

Inverter's factories and core contracts are deployed through a deterministic method. This ensures that the addresses are the same across all EVM-based networks. This includes zkEVM-based networks which are fully EVM equivalent.&#x20;

**Please Note**: The addresses of deployed contracts intentionally differ between Mainnet and Testnet. However, they are consistent across all Mainnets and across all Testnets.

## Mainnet

### Deployed Networks

The Inverter Protocol contracts have been deployed on the following mainnet networks to date:

* [Optimism](https://optimistic.etherscan.io/)

### Main Contracts

Some contracts have been deployed through Inverter's beacon proxy pattern. In these cases, the address listed directs to the beacon proxy contract.

<table><thead><tr><th width="465">Contract Name</th><th>Address</th></tr></thead><tbody><tr><td>ModuleFactory_v1</td><td>0x5Da8231feE106f4A43e07f2EEE95564467A1Ee58</td></tr><tr><td>OrchestratorFactory_v1</td><td>0x6ecA5f791d9635e4a1874cCD95564F914fBCF73d</td></tr><tr><td>Governor_v1</td><td>0x0B7c73e778d04533286752BEb7d4BA42AEa2f57D</td></tr><tr><td>TransactionForwarder_v1</td><td>0xfa3FEb13B0DE1C9bD183AB287c6f13aa5a51a593</td></tr><tr><td>FeeManager_v1</td><td>0xCA9617E5CdB9ecA339A4CBe3913FAe25a9aEcc74</td></tr><tr><td>InverterReverter_v1</td><td>0x6270b15Ac19eeC3d62920ed7f3a635a93E9C8B4C</td></tr><tr><td>BancorFormula</td><td>0xaAA597779bdbC7D54836FCdDDd38690787d04d6d</td></tr></tbody></table>

### Module Beacons

The addresses below are [InverterBeacon\_v1](/contracts/technical-reference/proxies/inverterbeacon_v1.sol) contracts, pointing to the actual implementations.

<table><thead><tr><th width="468">Beacon Name</th><th>Address</th></tr></thead><tbody><tr><td>Orchestrator_v1</td><td>0x166e76D9674EE6c4737fd061c774cCe7339233a8</td></tr><tr><td>AUT_Roles_v1</td><td>0x388F903f6d1B6110c2CaCD805Ac3F6B981e983Cb</td></tr><tr><td>AUT_TokenGated_Roles_v1</td><td>0x9b045D144e40f7ed11686E60ebfb7ABB0f62286e</td></tr><tr><td>AUT_EXT_VotingRoles_v1</td><td>0xafa02C2C70515A68d347D8F0F5dCEe76d9BaA5DF</td></tr><tr><td>FM_BC_Bancor_Redeeming_VirtualSupply_v1 </td><td>0xbBF78C0eA0CC98B385a8E3DDed1c78912d3D4caD</td></tr><tr><td>FM_BC_Restricted_Bancor_Redeeming_VirtualSupply_v1</td><td>0x7a4E51419AA4E8FF5174a26CC6389F335698a874</td></tr><tr><td>FM_DepositVault_v1</td><td>0x5e0f6e9a6dfE9Bd67B86212866c8aCabd594ba26</td></tr><tr><td>LM_PC_Bounties_v1</td><td>0x11FFB6AdCFA7EfEbCB4D4424d9595e6F7Fa03722</td></tr><tr><td>LM_PC_KPIRewarder_v1</td><td>0x6e2AfC4a763B45EA13Efb4822c285997A80c1f47</td></tr><tr><td>LM_PC_PaymentRouter_v1</td><td>0x117Aae86d7d7FC4F26d4961B47Af35e66cc58B49</td></tr><tr><td>LM_PC_RecurringPayments_v1</td><td>0x214447828E0C93803094c5A7D690F3290F5e54f9</td></tr><tr><td>LM_PC_Staking_v1</td><td>0xA4b35db352aD95AA96971dbCed86935585386734</td></tr><tr><td>PP_Simple_v1</td><td>0xFFafB77E4e4341E8B9446e20999cB81AadeE93E2</td></tr><tr><td>PP_Streaming_v1</td><td>0x5c205C0bDB952e3b807A83d9C0B6d57403EB6718</td></tr></tbody></table>

### Governance & Treasury

<table><thead><tr><th width="471">Contract Name</th><th>Address</th></tr></thead><tbody><tr><td>Community Multisig</td><td>0x945349AE62630bFDa197a4601883F4F7CBB07Fb5</td></tr><tr><td>Team Multisig</td><td>0x14bCe41bb3Bce98aBb02bA56BB8626f99ACc6Ace</td></tr><tr><td>Treasury</td><td>0x0D3edA53332b9fDf4d4e9FB4C1C940A80B16eD9D</td></tr></tbody></table>

### Protocol Deployment Factory

<table><thead><tr><th width="477">Contract Name</th><th>Address</th></tr></thead><tbody><tr><td>DeterministicFactory</td><td>0x471A946CeE9EF64068861A0aB151d1feE1047FD7</td></tr></tbody></table>

## Testnet

### Deployed Networks

The Inverter Protocol contracts have been deployed on the following testnet networks to date:

* [Optimism Sepolia](https://sepolia-optimism.etherscan.io/)
* [Base Sepolia](https://sepolia.basescan.org/)
* [Ethereum Sepolia](https://sepolia.etherscan.io/)
* [Polygon Amoy](https://amoy.polygonscan.com/)
* [Polygon zkEVM Cardona](https://cardona-zkevm.polygonscan.com/)

### Main Contracts

**Please note**: Some contracts have been deployed through Inverter's beacon proxy pattern. In these cases, the address listed directs to the beacon proxy contract.

<table><thead><tr><th width="465">Contract Name</th><th>Address</th></tr></thead><tbody><tr><td>ModuleFactory_v1</td><td>0xcEB82D3FA367cE3563e07763765bB1ae7B5Ba3d5</td></tr><tr><td>OrchestratorFactory_v1</td><td>0x535BdbC1D369d43fed8546024D273eE5274fFF65</td></tr><tr><td>Governor_v1</td><td>0x38D712491cC8A9B725AB867D56A4B0b25D9E0E3B</td></tr><tr><td>TransactionForwarder_v1</td><td>0x6384D968b1c3f5Cc4265D51417545b0EfE9BEd09</td></tr><tr><td>FeeManager_v1</td><td>0x356C7cA2D50C301ba3E172B3ec5C5d94050DD239</td></tr><tr><td>InverterReverter_v1</td><td>0x54C1116BE44184619A8CB37Ef6E924f737C8F734</td></tr><tr><td>BancorFormula</td><td>0xfaf6c989dB0582D7b31e40343dd4A41a1848E038</td></tr><tr><td>ERC20Mock</td><td>0x065775C7aB4E60ad1776A30DCfB15325d231Ce4F</td></tr></tbody></table>

### Module Beacons

**Please note**: The addresses below are [InverterBeacon\_v1](/contracts/technical-reference/proxies/inverterbeacon_v1.sol) contracts, pointing to the actual implementations.

<table><thead><tr><th width="468">Beacon Name</th><th>Address</th></tr></thead><tbody><tr><td>Orchestrator_v1</td><td>0xdA0348aA497462ABbB8631248f026c615B51984c</td></tr><tr><td>AUT_Roles_v1</td><td>0x13441ABDf893A4A506616FD8b0De52Af0bF725e9</td></tr><tr><td>AUT_TokenGated_Roles_v1</td><td>0x9120fd86aE69480b4B5f57AF86cBA90736521f55</td></tr><tr><td>AUT_EXT_VotingRoles_v1</td><td>0x50140C8230fF5d6868Ef20Be068b0c14Bc145245</td></tr><tr><td>FM_BC_Bancor_Redeeming_VirtualSupply_v1 </td><td>0x9fA5a461262A268F3cC696BcE75f7549dc6583C8</td></tr><tr><td>FM_BC_Restricted_Bancor_Redeeming_VirtualSupply_v1</td><td>0x5f1062A29932f55619968340859cfe97a8b0E1a4</td></tr><tr><td>FM_DepositVault_v1</td><td>0xcAaA9567725fdeE04E1Bd03999Dc977F14DA1A39</td></tr><tr><td>LM_PC_Bounties_v1</td><td>0xbEAACeB8AD171a3f351b1Ecaf8c3df7981D623c5</td></tr><tr><td>LM_PC_KPIRewarder_v1</td><td>0x388d523539f785b4563aeb15583d3b084a30f711</td></tr><tr><td>LM_PC_PaymentRouter_v1</td><td>0x93b4e2739154eDfD7309996cF41e2AC7ACe68343</td></tr><tr><td>LM_PC_RecurringPayments_v1</td><td>0x991cf3d0d5d61e74A741D43780A60ed5e53548B6</td></tr><tr><td>LM_PC_Staking_v1</td><td>0x1d4c13113E610F770D42427A78E5256A7303Ca08</td></tr><tr><td>PP_Simple_v1</td><td>0x2c002cf0Fa7b221A890a0E9fa8dEE36b5Cc01600</td></tr><tr><td>PP_Streaming_v1</td><td>0x614822f5877F814931511b19765a96A066F0eeAA</td></tr></tbody></table>

### Governance & Treasury

All of the multisigs are functioning as deployer, as other use cases are not necessary within the Testnet context

<table><thead><tr><th width="471">Contract Name</th><th>Address</th></tr></thead><tbody><tr><td>Community Multisig</td><td>0x9999a41CA9db8eD970845c813231B6d1bb59fD6b</td></tr><tr><td>Team Multisig</td><td>0x9999a41CA9db8eD970845c813231B6d1bb59fD6b</td></tr><tr><td>Treasury</td><td>0x9999a41CA9db8eD970845c813231B6d1bb59fD6b</td></tr></tbody></table>

### Protocol Deployment Factory

<table><thead><tr><th width="477">Contract Name</th><th>Address</th></tr></thead><tbody><tr><td>DeterministicFactory</td><td>0xC13B0c57eEF57B6052C924478e4d1fB61fdB0470</td></tr></tbody></table>


# Technical Reference


# Factories


# Interfaces


# IModuleFactory\_v1.sol

[Git Source](https://github.com/InverterNetwork/inverter-contracts/blob/2a8a4c80ff4f24a59546d4e6126b81bc51228c94/src/factories/interfaces/IModuleFactory_v1.sol)

### Functions

#### reverter

Returns the address of the [{InverterReverter\_v1}](https://docs.inverter.network/contracts/technical-reference/external/reverter/inverterreverter_v1.sol) contract.

```solidity
function reverter() external view returns (address);
```

**Returns**

| Name     | Type      | Description                                                                                                                                                                          |
| -------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `<none>` | `address` | reverterAddress Returns the address of the [{InverterReverter\_v1}](https://docs.inverter.network/contracts/technical-reference/external/reverter/inverterreverter_v1.sol) contract. |

#### governor

Returns the [{Governor\_v1}](https://docs.inverter.network/contracts/technical-reference/external/governance/governor_v1.sol) contract address.

```solidity
function governor() external view returns (address);
```

**Returns**

| Name     | Type      | Description                                                                                                                                                             |
| -------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `<none>` | `address` | govnernorAddress Returns the address of the [{Governor\_v1}](https://docs.inverter.network/contracts/technical-reference/external/governance/governor_v1.sol) contract. |

#### createAndInitModule

Creates a module instance identified by given `metadata` and initiates it.

```solidity
function createAndInitModule(
    IModule_v1.Metadata memory metadata,
    IOrchestrator_v1 orchestrator,
    bytes memory configData,
    IOrchestratorFactory_v1.WorkflowConfig memory workflowConfig
) external returns (address);
```

**Parameters**

| Name             | Type                                     | Description                                                                                                                                    |
| ---------------- | ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `metadata`       | `IModule_v1.Metadata`                    | The module's `metadata`.                                                                                                                       |
| `orchestrator`   | `IOrchestrator_v1`                       | The [{Orchestrator\_v1}](https://docs.inverter.network/contracts/technical-reference/orchestrator/orchestrator_v1.sol) instance of the module. |
| `configData`     | `bytes`                                  | The configData of the module.                                                                                                                  |
| `workflowConfig` | `IOrchestratorFactory_v1.WorkflowConfig` | The configData of the workflow.                                                                                                                |

**Returns**

| Name     | Type      | Description                                                         |
| -------- | --------- | ------------------------------------------------------------------- |
| `<none>` | `address` | moduleProxyAddress Returns the address of the created module proxy. |

#### createModuleProxy

Creates a module proxy instance identified by given `metadata`.

```solidity
function createModuleProxy(
    IModule_v1.Metadata memory metadata,
    IOrchestrator_v1 orchestrator,
    IOrchestratorFactory_v1.WorkflowConfig memory workflowConfig
) external returns (address);
```

**Parameters**

| Name             | Type                                     | Description                                                                                                                                    |
| ---------------- | ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `metadata`       | `IModule_v1.Metadata`                    | The module's metadata.                                                                                                                         |
| `orchestrator`   | `IOrchestrator_v1`                       | The [{Orchestrator\_v1}](https://docs.inverter.network/contracts/technical-reference/orchestrator/orchestrator_v1.sol) instance of the module. |
| `workflowConfig` | `IOrchestratorFactory_v1.WorkflowConfig` | The configData of the workflow.                                                                                                                |

**Returns**

| Name     | Type      | Description                                      |
| -------- | --------- | ------------------------------------------------ |
| `<none>` | `address` | Returns the address of the created module proxy. |

#### getBeaconAndId

Returns the [{IInverterBeacon\_v1}](https://docs.inverter.network/contracts/technical-reference/proxies/interfaces/iinverterbeacon_v1.sol) instance registered and the `id` for given `metadata`.

```solidity
function getBeaconAndId(IModule_v1.Metadata memory metadata)
    external
    view
    returns (IInverterBeacon_v1, bytes32);
```

**Parameters**

| Name       | Type                  | Description            |
| ---------- | --------------------- | ---------------------- |
| `metadata` | `IModule_v1.Metadata` | The module's metadata. |

**Returns**

| Name     | Type                 | Description                                                                                                                                                             |
| -------- | -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `<none>` | `IInverterBeacon_v1` | beacon The module's [{IInverterBeacon\_v1}](https://docs.inverter.network/contracts/technical-reference/proxies/interfaces/iinverterbeacon_v1.sol) instance registered. |
| `<none>` | `bytes32`            | id The metadata's id.                                                                                                                                                   |

#### getOrchestratorOfProxy

Returns the [{Orchestrator\_v1}](https://docs.inverter.network/contracts/technical-reference/orchestrator/orchestrator_v1.sol) address of a beacon proxy.

```solidity
function getOrchestratorOfProxy(address proxy)
    external
    view
    returns (address);
```

**Parameters**

| Name    | Type      | Description               |
| ------- | --------- | ------------------------- |
| `proxy` | `address` | The beacon proxy address. |

**Returns**

| Name     | Type      | Description                                                                                                                                                                              |
| -------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `<none>` | `address` | orchestratorAddress The corresponding [{Orchestrator\_v1}](https://docs.inverter.network/contracts/technical-reference/orchestrator/orchestrator_v1.sol) address for the provided proxy. |

#### registerMetadata

Registers metadata `metadata` with [{IInverterBeacon\_v1}](https://docs.inverter.network/contracts/technical-reference/proxies/interfaces/iinverterbeacon_v1.sol) implementation `beacon`.

*Only callable by owner.*

```solidity
function registerMetadata(
    IModule_v1.Metadata memory metadata,
    IInverterBeacon_v1 beacon
) external;
```

**Parameters**

| Name       | Type                  | Description                                                                                                                                           |
| ---------- | --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| `metadata` | `IModule_v1.Metadata` | The module's metadata.                                                                                                                                |
| `beacon`   | `IInverterBeacon_v1`  | The module's [{IInverterBeacon\_v1}](https://docs.inverter.network/contracts/technical-reference/proxies/interfaces/iinverterbeacon_v1.sol) instance. |

### Events

#### MetadataRegistered

Event emitted when new beacon registered for metadata.

```solidity
event MetadataRegistered(
    IModule_v1.Metadata metadata, IInverterBeacon_v1 indexed beacon
);
```

**Parameters**

| Name       | Type                  | Description              |
| ---------- | --------------------- | ------------------------ |
| `metadata` | `IModule_v1.Metadata` | The registered Metadata. |
| `beacon`   | `IInverterBeacon_v1`  | The registered Beacon.   |

#### ModuleCreated

Event emitted when new module created for an [{Orchestrator\_v1}](https://docs.inverter.network/contracts/technical-reference/orchestrator/orchestrator_v1.sol).

```solidity
event ModuleCreated(
    address indexed orchestrator,
    address indexed module,
    IModule_v1.Metadata metadata
);
```

**Parameters**

| Name           | Type                  | Description                                                                                                                           |
| -------------- | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `orchestrator` | `address`             | The corresponding [{Orchestrator\_v1}](https://docs.inverter.network/contracts/technical-reference/orchestrator/orchestrator_v1.sol). |
| `module`       | `address`             | The created module instance.                                                                                                          |
| `metadata`     | `IModule_v1.Metadata` | The registered metadata.                                                                                                              |

#### GovernorSet

Event emitted when [{Governor\_v1}](https://docs.inverter.network/contracts/technical-reference/external/governance/governor_v1.sol) is set.

```solidity
event GovernorSet(address indexed governor);
```

**Parameters**

| Name       | Type      | Description                                                                                                                           |
| ---------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `governor` | `address` | The address of the [{Governor\_v1}](https://docs.inverter.network/contracts/technical-reference/external/governance/governor_v1.sol). |

### Errors

#### ModuleFactory\_\_InvalidMetadata

Given metadata invalid.

```solidity
error ModuleFactory__InvalidMetadata();
```

#### ModuleFactory\_\_InvalidInitialRegistrationData

Given metadata invalid.

```solidity
error ModuleFactory__InvalidInitialRegistrationData();
```

#### ModuleFactory\_\_InvalidInverterBeacon

Given beacon invalid.

```solidity
error ModuleFactory__InvalidInverterBeacon();
```

#### ModuleFactory\_\_UnregisteredMetadata

Given metadata unregistered.

```solidity
error ModuleFactory__UnregisteredMetadata();
```

#### ModuleFactory\_\_MetadataAlreadyRegistered

Given metadata already registered.

```solidity
error ModuleFactory__MetadataAlreadyRegistered();
```

#### ModuleFactory\_\_ModuleIsSunset

Given module version is sunset.

```solidity
error ModuleFactory__ModuleIsSunset();
```


# IOrchestratorFactory\_v1.sol

[Git Source](https://github.com/InverterNetwork/inverter-contracts/blob/2a8a4c80ff4f24a59546d4e6126b81bc51228c94/src/factories/interfaces/IOrchestratorFactory_v1.sol)

### Functions

#### createOrchestrator

Creates a new [{Orchestrator\_v1}](https://docs.inverter.network/contracts/technical-reference/orchestrator/orchestrator_v1.sol).

```solidity
function createOrchestrator(
    WorkflowConfig memory workflowConfig,
    ModuleConfig memory fundingManagerConfig,
    ModuleConfig memory authorizerConfig,
    ModuleConfig memory paymentProcessorConfig,
    ModuleConfig[] memory moduleConfigs
) external returns (IOrchestrator_v1);
```

**Parameters**

| Name                     | Type             | Description                                                                                                                                                                                                                                      |
| ------------------------ | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `workflowConfig`         | `WorkflowConfig` | The workflow's config data.                                                                                                                                                                                                                      |
| `fundingManagerConfig`   | `ModuleConfig`   | The config data for the orchestrator's [{IFundingManager\_v1} ](/contracts/technical-reference/modules/funding-manager/ifundingmanager_v1.sol)instance.                                                                                          |
| `authorizerConfig`       | `ModuleConfig`   | The config data for the [{Orchestrator\_v1}](https://docs.inverter.network/contracts/technical-reference/orchestrator/orchestrator_v1.sol)'s [{IAuthorizer\_v1} ](/contracts/technical-reference/modules/authorizer/iauthorizer_v1.sol)instance. |
| `paymentProcessorConfig` | `ModuleConfig`   | The config data for the orchestrator's [{IPaymentProcessor\_v1} ](/contracts/technical-reference/modules/payment-processor/ipaymentprocessor_v1.sol)instance.                                                                                    |
| `moduleConfigs`          | `ModuleConfig[]` | Variable length set of optional module's config data.                                                                                                                                                                                            |

**Returns**

| Name     | Type               | Description                                                   |
| -------- | ------------------ | ------------------------------------------------------------- |
| `<none>` | `IOrchestrator_v1` | CreatedOrchestrator Returns the created orchestrator instance |

#### beacon

Returns the [{IOrchestrator\_v1}](https://docs.inverter.network/contracts/technical-reference/orchestrator/interfaces/iorchestrator_v1.sol) [{IInverterBeacon\_v1}](https://docs.inverter.network/contracts/technical-reference/proxies/interfaces/iinverterbeacon_v1.sol) address.

```solidity
function beacon() external view returns (IInverterBeacon_v1);
```

**Returns**

| Name     | Type                 | Description                                                                                                                                                                                                                                                                                                   |
| -------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `<none>` | `IInverterBeacon_v1` | OrchestratorImplementationBeacon The [{IInverterBeacon\_v1}](https://docs.inverter.network/contracts/technical-reference/proxies/interfaces/iinverterbeacon_v1.sol) of the [{Orchestrator\_v1}](https://docs.inverter.network/contracts/technical-reference/orchestrator/orchestrator_v1.sol) Implementation. |

#### moduleFactory

Returns the [{IModuleFactory\_v1} ](/contracts/technical-reference/factories/interfaces/imodulefactory_v1.sol)implementation address.

```solidity
function moduleFactory() external view returns (address);
```

**Returns**

| Name     | Type      | Description                                                                                                                                                                   |
| -------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `<none>` | `address` | ModuleFactoryAddress The address of the linked [{ModuleFactory\_v1}](https://docs.inverter.network/contracts/technical-reference/factories/interfaces/imodulefactory_v1.sol). |

#### getOrchestratorByID

Returns the [{IOrchestrator\_v1}](https://docs.inverter.network/contracts/technical-reference/orchestrator/interfaces/iorchestrator_v1.sol) address that corresponds to the given id.

```solidity
function getOrchestratorByID(uint id) external view returns (address);
```

**Parameters**

| Name | Type      | Description                      |
| ---- | --------- | -------------------------------- |
| `id` | `uint256` | The requested orchestrator's id. |

**Returns**

| Name     | Type      | Description                                                                                                                                                              |
| -------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `<none>` | `address` | orchestratorAddress The address of the corresponding [{Orchestrator\_v1}](https://docs.inverter.network/contracts/technical-reference/orchestrator/orchestrator_v1.sol). |

#### getOrchestratorIDCounter

Returns the counter of the current [{Orchestrator\_v1}](https://docs.inverter.network/contracts/technical-reference/orchestrator/orchestrator_v1.sol) id.

```solidity
function getOrchestratorIDCounter() external view returns (uint);
```

**Returns**

| Name     | Type      | Description                                                                                                                                       |
| -------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `<none>` | `uint256` | id The id of the next created [{Orchestrator\_v1}](https://docs.inverter.network/contracts/technical-reference/orchestrator/orchestrator_v1.sol). |

### Events

#### OrchestratorCreated

Event emitted when a new [{Orchestrator\_v1}](https://docs.inverter.network/contracts/technical-reference/orchestrator/orchestrator_v1.sol) is created.

```solidity
event OrchestratorCreated(
    uint indexed orchestratorId, address indexed orchestratorAddress
);
```

**Parameters**

| Name                  | Type      | Description                                                                                                                       |
| --------------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `orchestratorId`      | `uint256` | The id of the [{Orchestrator\_v1}](https://docs.inverter.network/contracts/technical-reference/orchestrator/orchestrator_v1.sol). |
| `orchestratorAddress` | `address` | The address of the {Orchestrator.                                                                                                 |

#### OrchestratorFactoryInitialized

Event emitted when a new [{OrchestratorFactory\_v1}](/contracts/technical-reference/factories/interfaces/iorchestratorfactory_v1.sol) is initialized.

```solidity
event OrchestratorFactoryInitialized(
    address indexed beacon, address indexed moduleFactory
);
```

**Parameters**

| Name            | Type      | Description                                                                                                                                                                    |
| --------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `beacon`        | `address` | The address of the [{IInverterBeacon\_v1}](https://docs.inverter.network/contracts/technical-reference/proxies/interfaces/iinverterbeacon_v1.sol) associated with the factory. |
| `moduleFactory` | `address` | The address of the [{ModuleFactory\_v1}](https://docs.inverter.network/contracts/technical-reference/factories/interfaces/imodulefactory_v1.sol).                              |

### Errors

#### OrchestratorFactory\_\_InvalidBeacon

The provided beacon address doesnt support the interface [{IInverterBeacon\_v1}](https://docs.inverter.network/contracts/technical-reference/proxies/interfaces/iinverterbeacon_v1.sol).

```solidity
error OrchestratorFactory__InvalidBeacon();
```

#### OrchestratorFactory\_\_InvalidId

Given id is invalid.

```solidity
error OrchestratorFactory__InvalidId();
```

#### OrchestratorFactory\_\_ModuleDataLengthMismatch

The module's data arrays length mismatch.

```solidity
error OrchestratorFactory__ModuleDataLengthMismatch();
```

#### OrchestratorFactory\_\_OrchestratorAdminIsInvalid

The orchestrator admin is address(0).

```solidity
error OrchestratorFactory__OrchestratorAdminIsInvalid();
```

### Structs

#### WorkflowConfig

Struct used to store information about a workflow configuration.

*When the `independentUpdates` is true, the `independentUpdateAdmin` will be disregarded.*

```solidity
struct WorkflowConfig {
    bool independentUpdates;
    address independentUpdateAdmin;
}
```

**Properties**

| Name                     | Type      | Description                                                                                                                                  |
| ------------------------ | --------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| `independentUpdates`     | `bool`    | bool wether the workflow should use the independent proxy structure. In case of true it will not use the standard beacon proxy structure.    |
| `independentUpdateAdmin` | `address` | The address that will be assigned the admin role of the independent update proxy. Will be disregarded in case `independentUpdates` is false. |

#### ModuleConfig

Struct used to store information about a module configuration.

```solidity
struct ModuleConfig {
    IModule_v1.Metadata metadata;
    bytes configData;
}
```

**Properties**

| Name         | Type                  | Description                                               |
| ------------ | --------------------- | --------------------------------------------------------- |
| `metadata`   | `IModule_v1.Metadata` | The module's metadata.                                    |
| `configData` | `bytes`               | Variable config data for specific module implementations. |


# ModuleFactory\_v1.sol

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

**Inherits:** [IModuleFactory\_v1](/contracts/technical-reference/factories/interfaces/imodulefactory_v1.sol), [ERC2771ContextUpgradeable](<https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/f1b3e103cd6d48861e71357a7ac32b416c1b066f/contracts/metatx/ERC2771ContextUpgradeable.sol&#xA;>), [Ownable2StepUpgradeable](<https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/52f6007348edc34304e9de9dc39cfbeb9ef314b9/contracts/access/Ownable2StepUpgradeable.sol&#xA;>), [ERC165Upgradeable](<https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/52f6007348edc34304e9de9dc39cfbeb9ef314b9/contracts/utils/introspection/ERC165Upgradeable.sol&#xA;>)

**Author:** Inverter Network

Enables the creation and registration of Inverter Modules, facilitating the deployment of module instances linked to specific beacons. Allows for configuration of modules starting state via provided deployment data.

*An owned factory for deploying modules. The owner can register module metadata's to an* [*{IInverterBeacon\_v1}*](https://docs.inverter.network/contracts/technical-reference/proxies/interfaces/iinverterbeacon_v1.sol) *implementations. Note that a metadata's registered* [*{IInverterBeacon\_v1}*](https://docs.inverter.network/contracts/technical-reference/proxies/interfaces/iinverterbeacon_v1.sol) *implementation can not be changed after registration!*

### State Variables

#### reverter

Returns the address of the [{InverterReverter\_v1}](https://docs.inverter.network/contracts/technical-reference/external/reverter/inverterreverter_v1.sol) contract.

```solidity
address public immutable reverter;
```

#### governor

Returns the [{Governor\_v1}](https://docs.inverter.network/contracts/technical-reference/external/governance/governor_v1.sol) contract address.

```solidity
address public governor;
```

#### \_beacons

*Mapping of metadata identifier to* [*{IInverterBeacon\_v1}*](https://docs.inverter.network/contracts/technical-reference/proxies/interfaces/iinverterbeacon_v1.sol) *instance.*

\_MetadataLib.identifier(metadata) => [{IInverterBeacon\_v1}.](https://docs.inverter.network/contracts/technical-reference/proxies/interfaces/iinverterbeacon_v1.sol)

```solidity
mapping(bytes32 => IInverterBeacon_v1) private _beacons;
```

#### \_orchestratorOfProxy

*Mapping of proxy address to orchestrator address.*

*moduleProxy =>* [*{IOrchestrator\_v1}*](https://docs.inverter.network/contracts/technical-reference/orchestrator/interfaces/iorchestrator_v1.sol)*.*

```solidity
mapping(address => address) private _orchestratorOfProxy;
```

#### \_deploymentNonces

*Maps a users address to a nonce used for the create2-based deployment.*

```solidity
mapping(address => uint) private _deploymentNonces;
```

#### \_\_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);
```

#### validMetadata

*Modifier to guarantee function is only callable with valid metadata.*

```solidity
modifier validMetadata(IModule_v1.Metadata memory data);
```

#### validBeacon

*Modifier to guarantee function is only callable with valid* [*{IInverterBeacon\_v1}*](https://docs.inverter.network/contracts/technical-reference/proxies/interfaces/iinverterbeacon_v1.sol) *instance and if the owner of the beacon. is same as the* [*{Governor\_v1}*](https://docs.inverter.network/contracts/technical-reference/external/governance/governor_v1.sol) *of this contract.*

```solidity
modifier validBeacon(IInverterBeacon_v1 beacon);
```

#### constructor

The factories initializer function.

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

**Parameters**

| Name                | Type      | Description                                                                                                                                                  |
| ------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `_reverter`         | `address` | The address of the [{InverterReverter\_v1}](https://docs.inverter.network/contracts/technical-reference/external/reverter/inverterreverter_v1.sol) contract. |
| `_trustedForwarder` | `address` | The address of the trusted forwarder contract.                                                                                                               |

#### init

The factories initializer function.

```solidity
function init(
    address _governor,
    IModule_v1.Metadata[] memory initialMetadataRegistration,
    IInverterBeacon_v1[] memory initialBeaconRegistration
) external initializer;
```

**Parameters**

| Name                          | Type                    | Description                                                                                                                                    |
| ----------------------------- | ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `_governor`                   | `address`               | The address of the [{Governor\_v1}](https://docs.inverter.network/contracts/technical-reference/external/governance/governor_v1.sol) contract. |
| `initialMetadataRegistration` | `IModule_v1.Metadata[]` | List of metadata that will be registered during the initialization.                                                                            |
| `initialBeaconRegistration`   | `IInverterBeacon_v1[]`  |                                                                                                                                                |

#### createAndInitModule

Creates a module instance identified by given `metadata` and initiates it.

```solidity
function createAndInitModule(
    IModule_v1.Metadata memory metadata,
    IOrchestrator_v1 orchestrator,
    bytes memory configData,
    IOrchestratorFactory_v1.WorkflowConfig memory workflowConfig
) external returns (address);
```

**Parameters**

| Name             | Type                                     | Description                                                                                                                                    |
| ---------------- | ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `metadata`       | `IModule_v1.Metadata`                    | The module's `metadata`.                                                                                                                       |
| `orchestrator`   | `IOrchestrator_v1`                       | The [{Orchestrator\_v1}](https://docs.inverter.network/contracts/technical-reference/orchestrator/orchestrator_v1.sol) instance of the module. |
| `configData`     | `bytes`                                  | The configData of the module.                                                                                                                  |
| `workflowConfig` | `IOrchestratorFactory_v1.WorkflowConfig` | The configData of the workflow.                                                                                                                |

**Returns**

| Name     | Type      | Description                                                         |
| -------- | --------- | ------------------------------------------------------------------- |
| `<none>` | `address` | moduleProxyAddress Returns the address of the created module proxy. |

#### createModuleProxy

Creates a module proxy instance identified by given `metadata`.

```solidity
function createModuleProxy(
    IModule_v1.Metadata memory metadata,
    IOrchestrator_v1 orchestrator,
    IOrchestratorFactory_v1.WorkflowConfig memory workflowConfig
) public returns (address);
```

**Parameters**

| Name             | Type                                     | Description                                                                                                                                    |
| ---------------- | ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `metadata`       | `IModule_v1.Metadata`                    | The module's metadata.                                                                                                                         |
| `orchestrator`   | `IOrchestrator_v1`                       | The [{Orchestrator\_v1}](https://docs.inverter.network/contracts/technical-reference/orchestrator/orchestrator_v1.sol) instance of the module. |
| `workflowConfig` | `IOrchestratorFactory_v1.WorkflowConfig` | The configData of the workflow.                                                                                                                |

**Returns**

| Name     | Type      | Description                                      |
| -------- | --------- | ------------------------------------------------ |
| `<none>` | `address` | Returns the address of the created module proxy. |

#### getBeaconAndId

Returns the [{IInverterBeacon\_v1}](https://docs.inverter.network/contracts/technical-reference/proxies/interfaces/iinverterbeacon_v1.sol) instance registered and the `id` for given `metadata`.

```solidity
function getBeaconAndId(IModule_v1.Metadata memory metadata)
    public
    view
    returns (IInverterBeacon_v1, bytes32);
```

**Parameters**

| Name       | Type                  | Description            |
| ---------- | --------------------- | ---------------------- |
| `metadata` | `IModule_v1.Metadata` | The module's metadata. |

**Returns**

| Name     | Type                 | Description                                                                                                                                                             |
| -------- | -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `<none>` | `IInverterBeacon_v1` | beacon The module's [{IInverterBeacon\_v1}](https://docs.inverter.network/contracts/technical-reference/proxies/interfaces/iinverterbeacon_v1.sol) instance registered. |
| `<none>` | `bytes32`            | id The metadata's id.                                                                                                                                                   |

#### getOrchestratorOfProxy

Returns the [{Orchestrator\_v1}](https://docs.inverter.network/contracts/technical-reference/orchestrator/orchestrator_v1.sol) address of a beacon proxy.

```solidity
function getOrchestratorOfProxy(address proxy) public view returns (address);
```

**Parameters**

| Name    | Type      | Description               |
| ------- | --------- | ------------------------- |
| `proxy` | `address` | The beacon proxy address. |

**Returns**

| Name     | Type      | Description                                                                                                                                                                              |
| -------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `<none>` | `address` | orchestratorAddress The corresponding [{Orchestrator\_v1}](https://docs.inverter.network/contracts/technical-reference/orchestrator/orchestrator_v1.sol) address for the provided proxy. |

#### registerMetadata

Registers metadata `metadata` with [{IInverterBeacon\_v1}](https://docs.inverter.network/contracts/technical-reference/proxies/interfaces/iinverterbeacon_v1.sol) implementation `beacon`.

*Only callable by owner.*

```solidity
function registerMetadata(
    IModule_v1.Metadata memory metadata,
    IInverterBeacon_v1 beacon
) external onlyOwner;
```

**Parameters**

| Name       | Type                  | Description                                                                                                                                           |
| ---------- | --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| `metadata` | `IModule_v1.Metadata` | The module's metadata.                                                                                                                                |
| `beacon`   | `IInverterBeacon_v1`  | The module's [{IInverterBeacon\_v1}](https://docs.inverter.network/contracts/technical-reference/proxies/interfaces/iinverterbeacon_v1.sol) instance. |

#### \_registerMetadata

*Internal function to register metadata.*

```solidity
function _registerMetadata(
    IModule_v1.Metadata memory metadata,
    IInverterBeacon_v1 beacon
) internal validMetadata(metadata) validBeacon(beacon);
```

**Parameters**

| Name       | Type                  | Description                                                                                                                                                     |
| ---------- | --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `metadata` | `IModule_v1.Metadata` | The metadata to register.                                                                                                                                       |
| `beacon`   | `IInverterBeacon_v1`  | The [{IInverterBeacon\_v1}](https://docs.inverter.network/contracts/technical-reference/proxies/interfaces/iinverterbeacon_v1.sol) to register the metadata to. |

#### \_createSalt

*Internal function to generate a salt for the create2-based deployment flow. This salt is the hash of (msgSender, nonce), where the nonce is an increasing number for each user.*

```solidity
function _createSalt() internal returns (bytes32);
```

#### \_msgSender

Needs to be overridden, because they are imported via the Ownable2Step as well.

```solidity
function _msgSender()
    internal
    view
    virtual
    override(ERC2771ContextUpgradeable, ContextUpgradeable)
    returns (address sender);
```

#### \_msgData

Needs to be overridden, because they are imported via the Ownable2Step as well.

```solidity
function _msgData()
    internal
    view
    virtual
    override(ERC2771ContextUpgradeable, ContextUpgradeable)
    returns (bytes calldata);
```

#### \_contextSuffixLength

```solidity
function _contextSuffixLength()
    internal
    view
    virtual
    override(ERC2771ContextUpgradeable, ContextUpgradeable)
    returns (uint);
```


# OrchestratorFactory\_v1.sol

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

**Inherits:** [IOrchestratorFactory\_v1](/contracts/technical-reference/factories/interfaces/iorchestratorfactory_v1.sol), [ERC2771ContextUpgradeable](<https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/f1b3e103cd6d48861e71357a7ac32b416c1b066f/contracts/metatx/ERC2771ContextUpgradeable.sol&#xA;>), [Ownable2StepUpgradeable](<https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/52f6007348edc34304e9de9dc39cfbeb9ef314b9/contracts/access/Ownable2StepUpgradeable.sol&#xA;>), [ERC165Upgradeable](<https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/52f6007348edc34304e9de9dc39cfbeb9ef314b9/contracts/utils/introspection/ERC165Upgradeable.sol&#xA;>)

**Author:** Inverter Network

OrchestratorFactory\_v1 facilitates the deployment of [{Orchestrator\_v1}](https://docs.inverter.network/contracts/technical-reference/orchestrator/orchestrator_v1.sol)s and their associated modules for the Inverter Network, ensuring seamless creation and configuration of various components in a single transaction.

*Utilizes* [*{ERC2771ContextUpgradeable}*](<https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/f1b3e103cd6d48861e71357a7ac32b416c1b066f/contracts/metatx/ERC2771ContextUpgradeable.sol&#xA;>) *for meta-transaction capabilities and* [*{ERC165Upgradeable}*](<https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/52f6007348edc34304e9de9dc39cfbeb9ef314b9/contracts/utils/introspection/ERC165Upgradeable.sol&#xA;>) *for interface detection.* [*{Orchestrator\_v1}*](https://docs.inverter.network/contracts/technical-reference/orchestrator/orchestrator_v1.sol)*s are deployed through EIP-1167 minimal proxies for efficiency. Integrates with the module factory to instantiate necessary modules with custom configurations, supporting complex setup with interdependencies among modules.*

### State Variables

#### beacon

Returns the [{IOrchestrator\_v1}](https://docs.inverter.network/contracts/technical-reference/orchestrator/interfaces/iorchestrator_v1.sol) [{IInverterBeacon\_v1}](https://docs.inverter.network/contracts/technical-reference/proxies/interfaces/iinverterbeacon_v1.sol) address.

```solidity
IInverterBeacon_v1 public override beacon;
```

#### moduleFactory

Returns the [{IModuleFactory\_v1}](https://docs.inverter.network/contracts/technical-reference/factories/interfaces/imodulefactory_v1.sol) implementation address.

```solidity
address public override moduleFactory;
```

#### \_orchestrators

*Maps the `id` to the* [*{Orchestrator\_v1}*](https://docs.inverter.network/contracts/technical-reference/orchestrator/orchestrator_v1.sol)*s.*

```solidity
mapping(uint => address) private _orchestrators;
```

#### \_orchestratorIdCounter

*The counter of the current* [*{Orchestrator\_v1}*](https://docs.inverter.network/contracts/technical-reference/orchestrator/orchestrator_v1.sol) *`id`.*

*Starts counting from 1.*

```solidity
uint private _orchestratorIdCounter;
```

#### \_deploymentNonces

*Maps a users address to a nonce. Used for the create2-based deployment.*

```solidity
mapping(address => uint) private _deploymentNonces;
```

#### \_\_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);
```

#### validOrchestratorId

*Modifier to guarantee that the given id is valid.*

```solidity
modifier validOrchestratorId(uint id);
```

#### constructor

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

#### init

The factories initializer function.

```solidity
function init(
    address governor_,
    IInverterBeacon_v1 beacon_,
    address moduleFactory_
) external initializer;
```

**Parameters**

| Name             | Type                 | Description                                                                                                                                                                                                                                                                                         |
| ---------------- | -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `governor_`      | `address`            | The address of the [{Governor\_v1}](https://docs.inverter.network/contracts/technical-reference/external/governance/governor_v1.sol) contract.                                                                                                                                                      |
| `beacon_`        | `IInverterBeacon_v1` | The address of the [{IInverterBeacon\_v1}](https://docs.inverter.network/contracts/technical-reference/proxies/interfaces/iinverterbeacon_v1.sol) containing the [{Orchestrator\_v1}](https://docs.inverter.network/contracts/technical-reference/orchestrator/orchestrator_v1.sol) implementation. |
| `moduleFactory_` | `address`            | The address of the [{ModuleFactory\_v1}](https://docs.inverter.network/contracts/technical-reference/factories/modulefactory_v1.sol) contract.                                                                                                                                                      |

#### createOrchestrator

Creates a new [{Orchestrator\_v1}](https://docs.inverter.network/contracts/technical-reference/orchestrator/orchestrator_v1.sol).

```solidity
function createOrchestrator(
    WorkflowConfig memory workflowConfig,
    ModuleConfig memory fundingManagerConfig,
    ModuleConfig memory authorizerConfig,
    ModuleConfig memory paymentProcessorConfig,
    ModuleConfig[] memory moduleConfigs
) external returns (IOrchestrator_v1);
```

**Parameters**

| Name                     | Type             | Description                                                                                                                                                                                                                                      |
| ------------------------ | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `workflowConfig`         | `WorkflowConfig` | The workflow's config data.                                                                                                                                                                                                                      |
| `fundingManagerConfig`   | `ModuleConfig`   | The config data for the orchestrator's [{IFundingManager\_v1} ](/contracts/technical-reference/modules/funding-manager/ifundingmanager_v1.sol)instance.                                                                                          |
| `authorizerConfig`       | `ModuleConfig`   | The config data for the [{Orchestrator\_v1}](https://docs.inverter.network/contracts/technical-reference/orchestrator/orchestrator_v1.sol)'s [{IAuthorizer\_v1}](/contracts/technical-reference/modules/authorizer/iauthorizer_v1.sol) instance. |
| `paymentProcessorConfig` | `ModuleConfig`   | The config data for the orchestrator's [{IPaymentProcessor\_v1} ](/contracts/technical-reference/modules/payment-processor/ipaymentprocessor_v1.sol)instance.                                                                                    |
| `moduleConfigs`          | `ModuleConfig[]` | Variable length set of optional module's config data.                                                                                                                                                                                            |

**Returns**

| Name     | Type               | Description                                                   |
| -------- | ------------------ | ------------------------------------------------------------- |
| `<none>` | `IOrchestrator_v1` | CreatedOrchestrator Returns the created orchestrator instance |

#### getOrchestratorByID

Returns the [{IOrchestrator\_v1}](https://docs.inverter.network/contracts/technical-reference/orchestrator/interfaces/iorchestrator_v1.sol) address that corresponds to the given id.

```solidity
function getOrchestratorByID(uint id)
    external
    view
    validOrchestratorId(id)
    returns (address);
```

**Parameters**

| Name | Type      | Description                      |
| ---- | --------- | -------------------------------- |
| `id` | `uint256` | The requested orchestrator's id. |

**Returns**

| Name     | Type      | Description                                                                                                                                                              |
| -------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `<none>` | `address` | orchestratorAddress The address of the corresponding [{Orchestrator\_v1}](https://docs.inverter.network/contracts/technical-reference/orchestrator/orchestrator_v1.sol). |

#### getOrchestratorIDCounter

Returns the counter of the current [{Orchestrator\_v1}](https://docs.inverter.network/contracts/technical-reference/orchestrator/orchestrator_v1.sol) id.

```solidity
function getOrchestratorIDCounter() external view returns (uint);
```

**Returns**

| Name     | Type      | Description                                                                                                                                       |
| -------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `<none>` | `uint256` | id The id of the next created [{Orchestrator\_v1}](https://docs.inverter.network/contracts/technical-reference/orchestrator/orchestrator_v1.sol). |

#### \_createModuleProxies

*Creates the modules based on their \`moduleConfigs\`.*

```solidity
function _createModuleProxies(
    ModuleConfig[] memory moduleConfigs,
    address orchestratorProxy,
    WorkflowConfig memory workflowConfig
) internal returns (address[] memory);
```

**Parameters**

| Name                | Type             | Description                                                                                                                                                                     |
| ------------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `moduleConfigs`     | `ModuleConfig[]` | The config data of the modules that will be created with this function call.                                                                                                    |
| `orchestratorProxy` | `address`        | The address of the [{Orchestrator\_v1}](https://docs.inverter.network/contracts/technical-reference/orchestrator/orchestrator_v1.sol) Proxy that will be linked to the modules. |
| `workflowConfig`    | `WorkflowConfig` | The workflow's config data.                                                                                                                                                     |

#### \_initModules

*Internal function to initialize the modules.*

```solidity
function _initModules(
    address[] memory modules,
    ModuleConfig[] memory moduleConfigs,
    address proxy
) internal;
```

**Parameters**

| Name            | Type             | Description                                                                                                                                                                     |
| --------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `modules`       | `address[]`      | The modules to initialize.                                                                                                                                                      |
| `moduleConfigs` | `ModuleConfig[]` | The config data of the modules that will be initialized.                                                                                                                        |
| `proxy`         | `address`        | The address of the [{Orchestrator\_v1}](https://docs.inverter.network/contracts/technical-reference/orchestrator/orchestrator_v1.sol) Proxy that will be linked to the modules. |

#### \_createSalt

*Internal function to generate salt for the create2-based deployment flow. This salt is the hash of (msgSender, nonce), where the nonce is an increasing number for each user.*

```solidity
function _createSalt() internal returns (bytes32);
```

#### \_msgSender

Needs to be overridden, because they are imported via the Ownable2Step as well.

```solidity
function _msgSender()
    internal
    view
    virtual
    override(ERC2771ContextUpgradeable, ContextUpgradeable)
    returns (address sender);
```

#### \_msgData

Needs to be overridden, because they are imported via the Ownable2Step as well.

```solidity
function _msgData()
    internal
    view
    virtual
    override(ERC2771ContextUpgradeable, ContextUpgradeable)
    returns (bytes calldata);
```

#### \_contextSuffixLength

```solidity
function _contextSuffixLength()
    internal
    view
    virtual
    override(ERC2771ContextUpgradeable, ContextUpgradeable)
    returns (uint);
```


# Orchestrator


# Abstracts


# ModuleManagerBase\_v1.sol

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

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

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


# Interfaces


# IModuleManagerBase\_v1.sol

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

**Inherits:** [IERC2771Context](/contracts/technical-reference/external/interfaces/ierc2771context.sol)

### Functions

#### isModule

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

```solidity
function isModule(address module) external view 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() external 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. |

#### isTrustedForwarder

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

*Exposes the ERC2771 isTrusted Forwarder.*

```solidity
function isTrustedForwarder(address forwarder) external view 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() external view returns (address);
```

**Returns**

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

### Events

#### ModuleAdded

Event emitted when module added.

```solidity
event ModuleAdded(address indexed module);
```

**Parameters**

| Name     | Type      | Description           |
| -------- | --------- | --------------------- |
| `module` | `address` | The module's address. |

#### ModuleRemoved

Event emitted when module removed.

```solidity
event ModuleRemoved(address indexed module);
```

**Parameters**

| Name     | Type      | Description           |
| -------- | --------- | --------------------- |
| `module` | `address` | The module's address. |

#### ModuleTimelockStarted

Event emitted when updating a module is initiated, and the timelock starts;.

```solidity
event ModuleTimelockStarted(address module, uint timelockUntil);
```

**Parameters**

| Name            | Type      | Description                                      |
| --------------- | --------- | ------------------------------------------------ |
| `module`        | `address` | The module's address.                            |
| `timelockUntil` | `uint256` | The unix timestamp until the timelock is active. |

#### ModuleUpdateCanceled

Event emitted when a module update is canceled.

```solidity
event ModuleUpdateCanceled(address module);
```

**Parameters**

| Name     | Type      | Description           |
| -------- | --------- | --------------------- |
| `module` | `address` | The module's address. |

### Errors

#### ModuleManagerBase\_\_CallerNotAuthorized

Function is only callable by authorized address.

```solidity
error ModuleManagerBase__CallerNotAuthorized();
```

#### ModuleManagerBase\_\_OnlyCallableByModule

Function is only callable by modules.

```solidity
error ModuleManagerBase__OnlyCallableByModule();
```

#### ModuleManagerBase\_\_InvalidModuleAddress

Given module address invalid.

```solidity
error ModuleManagerBase__InvalidModuleAddress();
```

#### ModuleManagerBase\_\_IsModule

Given address is a module.

```solidity
error ModuleManagerBase__IsModule();
```

#### ModuleManagerBase\_\_IsNotModule

Given address is not a module.

```solidity
error ModuleManagerBase__IsNotModule();
```

#### ModuleManagerBase\_\_ModuleAmountOverLimits

The {ModuleManagerBase\_v1} has reached the maximum amount of modules.

```solidity
error ModuleManagerBase__ModuleAmountOverLimits();
```

#### ModuleManagerBase\_\_ModuleUpdateTimelockStillActive

Timelock still active for the given module address.

```solidity
error ModuleManagerBase__ModuleUpdateTimelockStillActive(
    address _module, uint _timelockUntil
);
```

**Parameters**

| Name             | Type      | Description                                      |
| ---------------- | --------- | ------------------------------------------------ |
| `_module`        | `address` | The module address.                              |
| `_timelockUntil` | `uint256` | The unix timestamp until the timelock is active. |

#### ModuleManagerBase\_\_ModuleUpdateAlreadyStarted

Module update is already in progress.

```solidity
error ModuleManagerBase__ModuleUpdateAlreadyStarted();
```

#### ModuleManagerBase\_\_ModuleNotRegistered

Module has not been registered in our factory.

```solidity
error ModuleManagerBase__ModuleNotRegistered();
```

#### ModuleManagerBase\_\_ModuleFactoryInvalid

Referenced {ModuleFactory\_v1} is invalid.

```solidity
error ModuleManagerBase__ModuleFactoryInvalid();
```

### Structs

#### ModuleUpdateTimelock

The timelock struct to keep track of updating the registered modules.

```solidity
struct ModuleUpdateTimelock {
    bool timelockActive;
    uint timelockUntil;
}
```

**Properties**

| Name             | Type      | Description                                                        |
| ---------------- | --------- | ------------------------------------------------------------------ |
| `timelockActive` | `bool`    | Is the timelock currently active.                                  |
| `timelockUntil`  | `uint256` | Timestamp that represents from when the update can be carried out. |


# IOrchestrator\_v1.sol

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

**Inherits:** [IModuleManagerBase\_v1](/contracts/technical-reference/orchestrator/interfaces/imodulemanagerbase_v1.sol)

### Functions

#### init

Initialization function.

```solidity
function init(
    uint orchestratorId,
    address moduleFactory_,
    address[] calldata modules,
    IFundingManager_v1 fundingManager,
    IAuthorizer_v1 authorizer,
    IPaymentProcessor_v1 paymentProcessor,
    IGovernor_v1 governor
) external;
```

**Parameters**

| Name               | Type                   | Description                                                                                                                                                              |
| ------------------ | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `orchestratorId`   | `uint256`              | The id of the [{Orchestrator\_v1}](https://docs.inverter.network/contracts/technical-reference/orchestrator/interfaces/iorchestrator_v1.sol).                            |
| `moduleFactory_`   | `address`              | The address of the module factory.                                                                                                                                       |
| `modules`          | `address[]`            | The addresses of the modules used in the [{Orchestrator\_v1}](https://docs.inverter.network/contracts/technical-reference/orchestrator/interfaces/iorchestrator_v1.sol). |
| `fundingManager`   | `IFundingManager_v1`   | The address of the [{IFundingManager\_v1} ](/contracts/technical-reference/modules/funding-manager/ifundingmanager_v1.sol)module.                                        |
| `authorizer`       | `IAuthorizer_v1`       | The address of the [{IAuthorizer\_v1}](/contracts/technical-reference/modules/authorizer/iauthorizer_v1.sol) module.                                                     |
| `paymentProcessor` | `IPaymentProcessor_v1` | The address of the [{IPaymentProcessor\_v1} ](/contracts/technical-reference/modules/payment-processor/ipaymentprocessor_v1.sol)module.                                  |
| `governor`         | `IGovernor_v1`         | The address of the governor contract.                                                                                                                                    |

#### initiateSetAuthorizerWithTimelock

Initiates replacing the current authorizer with `_authorizer` on a timelock.

*Only callable by authorized caller.*

```solidity
function initiateSetAuthorizerWithTimelock(IAuthorizer_v1 authorizer_)
    external;
```

**Parameters**

| Name          | Type             | Description                                                                                                              |
| ------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------ |
| `authorizer_` | `IAuthorizer_v1` | The address of the new [{IAuthorizer\_v1}](/contracts/technical-reference/modules/authorizer/iauthorizer_v1.sol) module. |

#### initiateSetFundingManagerWithTimelock

Initiates replaces the current funding manager with `fundingManager_` on a timelock.

*Only callable by authorized caller.*

```solidity
function initiateSetFundingManagerWithTimelock(
    IFundingManager_v1 fundingManager_
) external;
```

**Parameters**

| Name              | Type                 | Description                                                                                                                           |
| ----------------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `fundingManager_` | `IFundingManager_v1` | The address of the new [{IFundingManager\_v1}](/contracts/technical-reference/modules/funding-manager/ifundingmanager_v1.sol) module. |

#### initiateSetPaymentProcessorWithTimelock

Initiates replaces the current payment processor with `paymentProcessor_` on a timelock.

*Only callable by authorized caller.*

```solidity
function initiateSetPaymentProcessorWithTimelock(
    IPaymentProcessor_v1 paymentProcessor_
) external;
```

**Parameters**

| Name                | Type                   | Description                                                                                                                                |
| ------------------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `paymentProcessor_` | `IPaymentProcessor_v1` | The address of the new [{PaymentProcessor\_v1}](/contracts/technical-reference/modules/payment-processor/ipaymentprocessor_v1.sol) module. |

#### cancelAuthorizerUpdate

Cancels the replacement of the current authorizer with `authorizer_`.

*Only callable by authorized caller.*

```solidity
function cancelAuthorizerUpdate(IAuthorizer_v1 authorizer_) external;
```

**Parameters**

| Name          | Type             | Description                                                                                                                                                |
| ------------- | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `authorizer_` | `IAuthorizer_v1` | The address of the new [{IAuthorizer\_v1}](/contracts/technical-reference/modules/authorizer/iauthorizer_v1.sol) module, for which the update is canceled. |

#### cancelFundingManagerUpdate

Cancels the replacement of the current funding manager with `fundingManager_`.

*Only callable by authorized caller.*

```solidity
function cancelFundingManagerUpdate(IFundingManager_v1 fundingManager_)
    external;
```

**Parameters**

| Name              | Type                 | Description                                                                                                                                                             |
| ----------------- | -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `fundingManager_` | `IFundingManager_v1` | The address of the new [{IFundingManager\_v1}](/contracts/technical-reference/modules/funding-manager/ifundingmanager_v1.sol) module, for which the update is canceled. |

#### cancelPaymentProcessorUpdate

Cancels the replacement of the current payment processor with `paymentProcessor_`.

*Only callable by authorized caller.*

```solidity
function cancelPaymentProcessorUpdate(IPaymentProcessor_v1 paymentProcessor_)
    external;
```

**Parameters**

| Name                | Type                   | Description                                                                                                                                                                   |
| ------------------- | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `paymentProcessor_` | `IPaymentProcessor_v1` | The address of the new [{IPaymentProcessor\_v1} ](/contracts/technical-reference/modules/payment-processor/ipaymentprocessor_v1.sol)module, for which the update is canceled. |

#### executeSetAuthorizer

Executes replacing the current authorizer with `_authorizer`.

!!! IMPORTANT !!! When changing the Authorizer the current set of assigned addresses to Roles are lost. Make sure initial owners are set properly.

*Only callable by authorized caller.*

```solidity
function executeSetAuthorizer(IAuthorizer_v1 authorizer_) external;
```

**Parameters**

| Name          | Type             | Description                                                                                                              |
| ------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------ |
| `authorizer_` | `IAuthorizer_v1` | The address of the new [{IAuthorizer\_v1}](/contracts/technical-reference/modules/authorizer/iauthorizer_v1.sol) module. |

#### executeSetFundingManager

Executes replaces the current funding manager with `fundingManager_`.

!!! IMPORTANT !!! When changing the FundingManager the current funds still contained in the module might not be retrievable. Make sure to clean the FundingManager properly beforehand.

*Only callable by authorized caller.*

```solidity
function executeSetFundingManager(IFundingManager_v1 fundingManager_)
    external;
```

**Parameters**

| Name              | Type                 | Description                                                                                                                           |
| ----------------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `fundingManager_` | `IFundingManager_v1` | The address of the new [{IFundingManager\_v1}](/contracts/technical-reference/modules/funding-manager/ifundingmanager_v1.sol) module. |

#### executeSetPaymentProcessor

Executes replaces the current payment processor with `paymentProcessor_`.

!!! IMPORTANT !!! When changing the PaymentProcessor the current ongoing payment orders are lost. Make sure to resolve those payments properly beforehand.

*Only callable by authorized caller.*

```solidity
function executeSetPaymentProcessor(IPaymentProcessor_v1 paymentProcessor_)
    external;
```

**Parameters**

| Name                | Type                   | Description                                                                                                                                 |
| ------------------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `paymentProcessor_` | `IPaymentProcessor_v1` | The address of the new [{IPaymentProcessor\_v1}](/contracts/technical-reference/modules/payment-processor/ipaymentprocessor_v1.sol) module. |

#### initiateAddModuleWithTimelock

Initiates the adding of a module to the [{Orchestrator\_v](https://docs.inverter.network/contracts/technical-reference/orchestrator/interfaces/iorchestrator_v1.sol)[1}](/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) external;
```

**Parameters**

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

#### initiateRemoveModuleWithTimelock

Initiate the removal of a module from the[ {Orchestrator\_v1}](/contracts/technical-reference/orchestrator/orchestrator_v1.sol) on a timelock.

*Reverts if module to be removed is the current authorizer/fundingManager/paymentProcessor. The functions specific to updating these 3 module categories should be used instead.*

*Only callable by authorized address.*

*Fails if address not added as module.*

```solidity
function initiateRemoveModuleWithTimelock(address module) external;
```

**Parameters**

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

#### executeAddModule

Adds address `module` as module.

*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) external;
```

**Parameters**

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

#### executeRemoveModule

Removes address `module` as module.

*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) external;
```

**Parameters**

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

#### cancelModuleUpdate

Cancels an initiated update for a module. Can be adding or removing a module from the [{Orchestrator\_v1](https://docs.inverter.network/contracts/technical-reference/orchestrator/interfaces/iorchestrator_v1.sol)[}](/contracts/technical-reference/orchestrator/orchestrator_v1.sol).

*Only callable by authorized address.*

*Fails if module update has not been initiated.*

```solidity
function cancelModuleUpdate(address module) external;
```

**Parameters**

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

#### orchestratorId

Returns the [{Orchestrator\_v1](https://docs.inverter.network/contracts/technical-reference/orchestrator/interfaces/iorchestrator_v1.sol)[}](/contracts/technical-reference/orchestrator/orchestrator_v1.sol)'s id.

*Unique id set by the {OrchestratorFactory\_v1} during initialization.*

```solidity
function orchestratorId() external view returns (uint);
```

**Returns**

| Name     | Type      | Description                                                                                                                              |
| -------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `<none>` | `uint256` | The [{Orchestrator\_v1](https://docs.inverter.network/contracts/technical-reference/orchestrator/interfaces/iorchestrator_v1.sol)}'s id. |

#### fundingManager

The [{IFundingManager\_v1}](/contracts/technical-reference/modules/funding-manager/ifundingmanager_v1.sol) implementation used to hold and distribute Funds.

```solidity
function fundingManager() external view returns (IFundingManager_v1);
```

**Returns**

| Name     | Type                 | Description                                                                                                                |
| -------- | -------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| `<none>` | `IFundingManager_v1` | The [{IFundingManager\_v1} ](/contracts/technical-reference/modules/funding-manager/ifundingmanager_v1.sol)implementation. |

#### authorizer

The [{IAuthorizer\_v1} ](/contracts/technical-reference/modules/authorizer/iauthorizer_v1.sol)implementation used to authorize addresses.

```solidity
function authorizer() external view returns (IAuthorizer_v1);
```

**Returns**

| Name     | Type             | Description                                                                                                   |
| -------- | ---------------- | ------------------------------------------------------------------------------------------------------------- |
| `<none>` | `IAuthorizer_v1` | The [{IAuthorizer\_v1} ](/contracts/technical-reference/modules/authorizer/iauthorizer_v1.sol)implementation. |

#### paymentProcessor

The [{IPaymentProcessor\_v1}](/contracts/technical-reference/modules/payment-processor/ipaymentprocessor_v1.sol) implementation used to process module payments.

```solidity
function paymentProcessor() external view returns (IPaymentProcessor_v1);
```

**Returns**

| Name     | Type                   | Description                                                                                                                      |
| -------- | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `<none>` | `IPaymentProcessor_v1` | The [{IPaymentProcessor\_v1} ](/contracts/technical-reference/modules/payment-processor/ipaymentprocessor_v1.sol)implementation. |

#### governor

The [{IGovernor\_v1}](/contracts/technical-reference/external/governance/interfaces/igovernor_v1.sol) implementation used for protocol level interactions.

```solidity
function governor() external view returns (IGovernor_v1);
```

**Returns**

| Name     | Type           | Description                                                                                                           |
| -------- | -------------- | --------------------------------------------------------------------------------------------------------------------- |
| `<none>` | `IGovernor_v1` | The [{IGovernor\_v1} ](/contracts/technical-reference/external/governance/interfaces/igovernor_v1.sol)implementation. |

### Events

#### AuthorizerUpdated

Authorizer updated to new address.

```solidity
event AuthorizerUpdated(address indexed _address);
```

**Parameters**

| Name       | Type      | Description      |
| ---------- | --------- | ---------------- |
| `_address` | `address` | The new address. |

#### FundingManagerUpdated

FundingManager updated to new address.

```solidity
event FundingManagerUpdated(address indexed _address);
```

**Parameters**

| Name       | Type      | Description      |
| ---------- | --------- | ---------------- |
| `_address` | `address` | The new address. |

#### PaymentProcessorUpdated

PaymentProcessor updated to new address.

```solidity
event PaymentProcessorUpdated(address indexed _address);
```

**Parameters**

| Name       | Type      | Description      |
| ---------- | --------- | ---------------- |
| `_address` | `address` | The new address. |

#### OrchestratorInitialized

[{Orchestrator\_v](https://docs.inverter.network/contracts/technical-reference/orchestrator/interfaces/iorchestrator_v1.sol)1} has been initialized with the corresponding modules.

```solidity
event OrchestratorInitialized(
    uint indexed orchestratorId_,
    address fundingManager,
    address authorizer,
    address paymentProcessor,
    address[] modules,
    address governor
);
```

**Parameters**

| Name               | Type        | Description                                                                                                                                                                    |
| ------------------ | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `orchestratorId_`  | `uint256`   | The id of the [{Orchestrator\_v1}](https://docs.inverter.network/contracts/technical-reference/orchestrator/interfaces/iorchestrator_v1.sol).                                  |
| `fundingManager`   | `address`   | The address of the [{IFundingManager\_v1}](/contracts/technical-reference/modules/funding-manager/ifundingmanager_v1.sol) module.                                              |
| `authorizer`       | `address`   | The address of the [{IAuthorizer\_v1}](/contracts/technical-reference/modules/authorizer/iauthorizer_v1.sol) module.                                                           |
| `paymentProcessor` | `address`   | The address of the [{IPaymentProcessor\_v1} ](/contracts/technical-reference/modules/payment-processor/ipaymentprocessor_v1.sol)module.                                        |
| `modules`          | `address[]` | The addresses of the other modules used in the [{Orchestrator\_v1}](https://docs.inverter.network/contracts/technical-reference/orchestrator/interfaces/iorchestrator_v1.sol). |
| `governor`         | `address`   | The address of the [{Governor\_v1}](/contracts/technical-reference/external/governance/governor_v1.sol) contract used to reference protocol level interactions.                |

### Errors

#### Orchestrator\_\_CallerNotAuthorized

Function is only callable by authorized caller.

```solidity
error Orchestrator__CallerNotAuthorized(bytes32 role, address caller);
```

**Parameters**

| Name     | Type      | Description             |
| -------- | --------- | ----------------------- |
| `role`   | `bytes32` | The role of the caller. |
| `caller` | `address` | The caller address.     |

#### Orchestrator\_\_InvalidModuleType

The given module is not used in the [{Orchestrator\_v1](https://docs.inverter.network/contracts/technical-reference/orchestrator/interfaces/iorchestrator_v1.sol)[}](/contracts/technical-reference/orchestrator/orchestrator_v1.sol).

```solidity
error Orchestrator__InvalidModuleType(address module);
```

**Parameters**

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

#### Orchestrator\_\_MismatchedTokenForFundingManager

The token of the new funding manager is not the same as the current funding manager.

```solidity
error Orchestrator__MismatchedTokenForFundingManager(
    address currentToken, address newToken
);
```

**Parameters**

| Name           | Type      | Description        |
| -------------- | --------- | ------------------ |
| `currentToken` | `address` | The current token. |
| `newToken`     | `address` | The new token.     |

#### Orchestrator\_\_DependencyInjection\_\_ModuleNotUsedInOrchestrator

The given module is not used in the [{Orchestrator\_v1](https://docs.inverter.network/contracts/technical-reference/orchestrator/interfaces/iorchestrator_v1.sol)[}](/contracts/technical-reference/orchestrator/orchestrator_v1.sol).

```solidity
error Orchestrator__DependencyInjection__ModuleNotUsedInOrchestrator();
```

#### Orchestrator\_\_InvalidRemovalOfAuthorizer

The Authorizer can not be removed through this function.

```solidity
error Orchestrator__InvalidRemovalOfAuthorizer();
```

#### Orchestrator\_\_InvalidRemovalOfFundingManager

The FundingManager can not be removed through this function.

```solidity
error Orchestrator__InvalidRemovalOfFundingManager();
```

#### Orchestrator\_\_InvalidRemovalOfPaymentProcessor

The PaymentProcessor can not be removed through this function.

```solidity
error Orchestrator__InvalidRemovalOfPaymentProcessor();
```


# Orchestrator\_v1.sol


# Modules


# Authorizer


# Role


# Interfaces


# IAUT\_EXT\_VotingRoles\_v1.sol

[Git Source](https://github.com/InverterNetwork/inverter-contracts/blob/649b450f02fc8b735c128ff0821467e71966c666/src/modules/authorizer/role/interfaces/IAUT_EXT_VotingRoles_v1.sol)

### Functions

#### MAX\_VOTING\_DURATION

The maximum voting duration.

```solidity
function MAX_VOTING_DURATION() external view returns (uint);
```

**Returns**

| Name     | Type      | Description                  |
| -------- | --------- | ---------------------------- |
| `<none>` | `uint256` | The maximum voting duration. |

#### MIN\_VOTING\_DURATION

The minimum voting duration.

```solidity
function MIN_VOTING_DURATION() external view returns (uint);
```

**Returns**

| Name     | Type      | Description                  |
| -------- | --------- | ---------------------------- |
| `<none>` | `uint256` | The minimum voting duration. |

#### isVoter

Checks whether an address is a voter.

```solidity
function isVoter(address who) external view returns (bool);
```

**Parameters**

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

**Returns**

| Name     | Type   | Description                     |
| -------- | ------ | ------------------------------- |
| `<none>` | `bool` | Whether the address is a voter. |

#### addVoter

Adds a voter.

```solidity
function addVoter(address who) external;
```

**Parameters**

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

#### addVoterAndUpdateThreshold

Adds a voter and updates the threshold.

```solidity
function addVoterAndUpdateThreshold(address who, uint newThreshold) external;
```

**Parameters**

| Name           | Type      | Description         |
| -------------- | --------- | ------------------- |
| `who`          | `address` | The address to add. |
| `newThreshold` | `uint256` | The new threshold.  |

#### removeVoter

Removes a voter.

```solidity
function removeVoter(address who) external;
```

**Parameters**

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

#### removeVoterAndUpdateThreshold

Removes a voter and updates the threshold.

```solidity
function removeVoterAndUpdateThreshold(address who, uint newThreshold)
    external;
```

**Parameters**

| Name           | Type      | Description            |
| -------------- | --------- | ---------------------- |
| `who`          | `address` | The address to remove. |
| `newThreshold` | `uint256` | The new threshold.     |

#### motions

Gets the motion data.

```solidity
function motions(bytes32 motionId)
    external
    view
    returns (
        address,
        bytes memory,
        uint,
        uint,
        uint,
        uint,
        uint,
        uint,
        uint,
        bool,
        bytes memory
    );
```

**Parameters**

| Name       | Type      | Description           |
| ---------- | --------- | --------------------- |
| `motionId` | `bytes32` | The ID of the motion. |

**Returns**

| Name     | Type      | Description                                                           |
| -------- | --------- | --------------------------------------------------------------------- |
| `<none>` | `address` | target The address of the contract to execute the action on.          |
| `<none>` | `bytes`   | action The action data to execute on the target contract.             |
| `<none>` | `uint256` | startTimestamp The timestamp at which the motion starts.              |
| `<none>` | `uint256` | endTimestamp The timestamp at which the motion ends.                  |
| `<none>` | `uint256` | requiredThreshold The required threshold of votes to pass the motion. |
| `<none>` | `uint256` | forVotes The number of votes in favor of the motion.                  |
| `<none>` | `uint256` | againstVotes The number of votes against the motion.                  |
| `<none>` | `uint256` | abstainVotes The number of votes abstaining from the motion.          |
| `<none>` | `uint256` | executedAt The timestamp at which the motion was executed.            |
| `<none>` | `bool`    | executionResult The result of the execution.                          |
| `<none>` | `bytes`   | executionReturnData The return data of the execution.                 |

#### motionCount

Gets the number of motions.

```solidity
function motionCount() external view returns (uint);
```

**Returns**

| Name     | Type      | Description            |
| -------- | --------- | ---------------------- |
| `<none>` | `uint256` | The number of motions. |

#### voterCount

Gets the number of voters.

```solidity
function voterCount() external view returns (uint);
```

**Returns**

| Name     | Type      | Description           |
| -------- | --------- | --------------------- |
| `<none>` | `uint256` | The number of voters. |

#### threshold

Gets the threshold.

```solidity
function threshold() external view returns (uint);
```

**Returns**

| Name     | Type      | Description    |
| -------- | --------- | -------------- |
| `<none>` | `uint256` | The threshold. |

#### getReceipt

Gets the receipt of a voter for a motion.

```solidity
function getReceipt(bytes32 _ID, address voter)
    external
    view
    returns (Receipt memory);
```

**Parameters**

| Name    | Type      | Description               |
| ------- | --------- | ------------------------- |
| `_ID`   | `bytes32` | The ID of the motion.     |
| `voter` | `address` | The address of the voter. |

**Returns**

| Name     | Type      | Description               |
| -------- | --------- | ------------------------- |
| `<none>` | `Receipt` | The receipt of the voter. |

#### voteDuration

Gets the voting duration.

```solidity
function voteDuration() external view returns (uint);
```

**Returns**

| Name     | Type      | Description          |
| -------- | --------- | -------------------- |
| `<none>` | `uint256` | The voting duration. |

#### setThreshold

Sets the threshold.

```solidity
function setThreshold(uint newThreshold) external;
```

**Parameters**

| Name           | Type      | Description        |
| -------------- | --------- | ------------------ |
| `newThreshold` | `uint256` | The new threshold. |

#### setVotingDuration

Sets the voting duration.

```solidity
function setVotingDuration(uint newVoteDuration) external;
```

**Parameters**

| Name              | Type      | Description              |
| ----------------- | --------- | ------------------------ |
| `newVoteDuration` | `uint256` | The new voting duration. |

#### createMotion

Creates a motion.

```solidity
function createMotion(address target, bytes calldata action)
    external
    returns (bytes32);
```

**Parameters**

| Name     | Type      | Description                                           |
| -------- | --------- | ----------------------------------------------------- |
| `target` | `address` | The address of the contract to execute the action on. |
| `action` | `bytes`   | The action data to execute on the target contract.    |

**Returns**

| Name     | Type      | Description                   |
| -------- | --------- | ----------------------------- |
| `<none>` | `bytes32` | The ID of the created motion. |

#### castVote

Casts a vote for a motion.

```solidity
function castVote(bytes32 motionId, uint8 support) external;
```

**Parameters**

| Name       | Type      | Description                                                    |
| ---------- | --------- | -------------------------------------------------------------- |
| `motionId` | `bytes32` | The ID of the motion.                                          |
| `support`  | `uint8`   | The value that indicates wether the voter supports the motion. |

#### executeMotion

Executes a motion.

```solidity
function executeMotion(bytes32 motionId) external;
```

**Parameters**

| Name       | Type      | Description           |
| ---------- | --------- | --------------------- |
| `motionId` | `bytes32` | The ID of the motion. |

### Events

#### VoterAdded

Event emitted when a new voter address gets added.

```solidity
event VoterAdded(address indexed who);
```

**Parameters**

| Name  | Type      | Description        |
| ----- | --------- | ------------------ |
| `who` | `address` | The added address. |

#### VoterRemoved

Event emitted when a voter address gets removed.

```solidity
event VoterRemoved(address indexed who);
```

**Parameters**

| Name  | Type      | Description          |
| ----- | --------- | -------------------- |
| `who` | `address` | The removed address. |

#### ThresholdUpdated

Event emitted when the required threshold changes.

```solidity
event ThresholdUpdated(uint oldThreshold, uint newThreshold);
```

**Parameters**

| Name           | Type      | Description        |
| -------------- | --------- | ------------------ |
| `oldThreshold` | `uint256` | The old threshold. |
| `newThreshold` | `uint256` | The new threshold. |

#### VoteDurationUpdated

Event emitted when the voting duration changes.

```solidity
event VoteDurationUpdated(uint oldVotingDuration, uint newVotingDuration);
```

**Parameters**

| Name                | Type      | Description              |
| ------------------- | --------- | ------------------------ |
| `oldVotingDuration` | `uint256` | The old voting duration. |
| `newVotingDuration` | `uint256` | The new voting duration. |

#### MotionCreated

Event emitted when a motion is created.

```solidity
event MotionCreated(bytes32 indexed motionId);
```

**Parameters**

| Name       | Type      | Description    |
| ---------- | --------- | -------------- |
| `motionId` | `bytes32` | The motion ID. |

#### VoteCast

Event emitted when a vote is cast for a motion.

```solidity
event VoteCast(
    bytes32 indexed motionId, address indexed voter, uint8 indexed support
);
```

**Parameters**

| Name       | Type      | Description             |
| ---------- | --------- | ----------------------- |
| `motionId` | `bytes32` | The motion ID.          |
| `voter`    | `address` | The address of a voter. |
| `support`  | `uint8`   |                         |

#### MotionExecuted

Event emitted when a motion is executed.

```solidity
event MotionExecuted(bytes32 indexed motionId);
```

**Parameters**

| Name       | Type      | Description    |
| ---------- | --------- | -------------- |
| `motionId` | `bytes32` | The motion ID. |

### Errors

#### Module\_\_VotingRoleManager\_\_EmptyVoters

The action would leave an empty voter list.

```solidity
error Module__VotingRoleManager__EmptyVoters();
```

#### Module\_\_VotingRoleManager\_\_InvalidVoterAddress

The supplied voter address is invalid.

```solidity
error Module__VotingRoleManager__InvalidVoterAddress();
```

#### Module\_\_VotingRoleManager\_\_InvalidThreshold

The threshold cannot exceed the amount of voters. or be too low to be considered safe.

```solidity
error Module__VotingRoleManager__InvalidThreshold();
```

#### Module\_\_VotingRoleManager\_\_InvalidVotingDuration

The supplied voting duration is invalid.

```solidity
error Module__VotingRoleManager__InvalidVotingDuration();
```

#### Module\_\_VotingRoleManager\_\_CallerNotVoter

The function can only be called by a voter.

```solidity
error Module__VotingRoleManager__CallerNotVoter();
```

#### Module\_\_VotingRoleManager\_\_IsAlreadyVoter

The address is already a voter.

```solidity
error Module__VotingRoleManager__IsAlreadyVoter();
```

#### Module\_\_VotingRoleManager\_\_InvalidSupport

The value given as vote is invalid.

```solidity
error Module__VotingRoleManager__InvalidSupport();
```

#### Module\_\_VotingRoleManager\_\_InvalidMotionId

The supplied ID is referencing a motion that doesn't exist.

```solidity
error Module__VotingRoleManager__InvalidMotionId();
```

#### Module\_\_VotingRoleManager\_\_AttemptedDoubleVote

A user cannot vote twice.

```solidity
error Module__VotingRoleManager__AttemptedDoubleVote();
```

#### Module\_\_VotingRoleManager\_\_MotionInVotingPhase

A motion cannot be executed if the voting duration hasn't passed.

```solidity
error Module__VotingRoleManager__MotionInVotingPhase();
```

#### Module\_\_VotingRoleManager\_\_MotionVotingPhaseClosed

A motion cannot be voted on if the duration has been exceeded.

```solidity
error Module__VotingRoleManager__MotionVotingPhaseClosed();
```

#### Module\_\_VotingRoleManager\_\_MotionAlreadyExecuted

A motion cannot be executed twice.

```solidity
error Module__VotingRoleManager__MotionAlreadyExecuted();
```

#### Module\_\_VotingRoleManager\_\_ThresholdNotReached

A motion cannot be executed if it didn't reach the threshold.

```solidity
error Module__VotingRoleManager__ThresholdNotReached();
```

### Structs

#### Motion

A motion is a proposal to execute an action on a target contract.

```solidity
struct Motion {
    address target;
    bytes action;
    uint startTimestamp;
    uint endTimestamp;
    uint requiredThreshold;
    uint forVotes;
    uint againstVotes;
    uint abstainVotes;
    mapping(address => Receipt) receipts;
    uint executedAt;
    bool executionResult;
    bytes executionReturnData;
}
```

**Properties**

| Name                  | Type                          | Description                                             |
| --------------------- | ----------------------------- | ------------------------------------------------------- |
| `target`              | `address`                     | The address of the contract to execute the action on.   |
| `action`              | `bytes`                       | The action data to execute on the target contract.      |
| `startTimestamp`      | `uint256`                     | The timestamp at which the motion starts.               |
| `endTimestamp`        | `uint256`                     | The timestamp at which the motion ends.                 |
| `requiredThreshold`   | `uint256`                     | The required threshold of votes to pass the motion.     |
| `forVotes`            | `uint256`                     | The number of votes in favor of the motion.             |
| `againstVotes`        | `uint256`                     | The number of votes against the motion.                 |
| `abstainVotes`        | `uint256`                     | The number of votes abstaining from the motion.         |
| `receipts`            | `mapping(address => Receipt)` | The receipts of votes for the motion address => Receipt |
| `executedAt`          | `uint256`                     | The timestamp at which the motion was executed.         |
| `executionResult`     | `bool`                        | The result of the execution.                            |
| `executionReturnData` | `bytes`                       | The return data of the execution.                       |

#### Receipt

A receipt is a vote cast for a motion.

```solidity
struct Receipt {
    bool hasVoted;
    uint8 support;
}
```

**Properties**

| Name       | Type    | Description                                                    |
| ---------- | ------- | -------------------------------------------------------------- |
| `hasVoted` | `bool`  | Whether the voter has already voted.                           |
| `support`  | `uint8` | The value that indicates wether the voter supports the motion. |


# IAUT\_TokenGated\_Roles\_v1.sol

[Git Source](https://github.com/InverterNetwork/inverter-contracts/blob/649b450f02fc8b735c128ff0821467e71966c666/src/modules/authorizer/role/interfaces/IAUT_TokenGated_Roles_v1.sol)

**Inherits:** IAuthorizer\_v1

### Functions

#### hasTokenRole

Checks if an account qualifies for a token-gated role.

```solidity
function hasTokenRole(bytes32 role, address who) external view returns (bool);
```

**Parameters**

| Name   | Type      | Description                |
| ------ | --------- | -------------------------- |
| `role` | `bytes32` | The role to be checked.    |
| `who`  | `address` | The account to be checked. |

**Returns**

| Name     | Type   | Description                                 |
| -------- | ------ | ------------------------------------------- |
| `<none>` | `bool` | True if the account qualifies for the role. |

#### getThresholdValue

Returns the threshold balance for a given token necessary to qualify for a specific role. If the value is 0, the supplied token is not part of the. role's token gating.

*In case the queried role is not token gated, all calls will return 0.*

```solidity
function getThresholdValue(bytes32 roleId, address token)
    external
    returns (uint);
```

**Parameters**

| Name     | Type      | Description                           |
| -------- | --------- | ------------------------------------- |
| `roleId` | `bytes32` | The role to be checked on.            |
| `token`  | `address` | The token to check the threshold for. |

**Returns**

| Name     | Type      | Description                                                       |
| -------- | --------- | ----------------------------------------------------------------- |
| `<none>` | `uint256` | The threshold amount necessary to qualify for a given token role. |

#### makeRoleTokenGatedFromModule

Sets up a token-gated empty role.

*This function is only callable by an active Module for itself. Admin should use `setTokenGated()`.*

*Calling this function does not specify WHICH token to use for gating. That has to be done with 'grantTokenFromModule()'.*

```solidity
function makeRoleTokenGatedFromModule(bytes32 role) external;
```

**Parameters**

| Name   | Type      | Description                      |
| ------ | --------- | -------------------------------- |
| `role` | `bytes32` | The role to be made token-gated. |

#### grantTokenRoleFromModule

One-step setup for Modules to create a token-gated role and set its threshold. Please be aware that using tokens that are transferable and have active markets could make the token-gated authorization vulnerable to flash loans, potentially bypassing. the authorization mechanism.

```solidity
function grantTokenRoleFromModule(bytes32 role, address token, uint threshold)
    external;
```

**Parameters**

| Name        | Type      | Description                                                        |
| ----------- | --------- | ------------------------------------------------------------------ |
| `role`      | `bytes32` | The role to be made token-gated.                                   |
| `token`     | `address` | The token for which the threshold will be set.                     |
| `threshold` | `uint256` | The minimum balance of the token required to qualify for the role. |

#### setThresholdFromModule

Allows a Module to set the threshold of one of it's roles.

```solidity
function setThresholdFromModule(bytes32 role, address token, uint threshold)
    external;
```

**Parameters**

| Name        | Type      | Description                                                            |
| ----------- | --------- | ---------------------------------------------------------------------- |
| `role`      | `bytes32` | The token-gated role.                                                  |
| `token`     | `address` | The token for which the threshold will be set.                         |
| `threshold` | `uint256` | The new minimum balance of the token required to qualify for the role. |

#### setTokenGated

Sets if a role is token-gated or not.

*Admin access for rescue purposes. If the role has active members, they need to be reovked first.*

```solidity
function setTokenGated(bytes32 role, bool to) external;
```

**Parameters**

| Name   | Type      | Description                        |
| ------ | --------- | ---------------------------------- |
| `role` | `bytes32` | The ID of the role to be modified. |
| `to`   | `bool`    | The new value to be set.           |

#### setThreshold

Sets the minimum threshold for a token-gated role.

*This function does not validate the threshold. It is technically possible to set a threshold above the total supply of the token.*

```solidity
function setThreshold(bytes32 roleId, address token, uint threshold) external;
```

**Parameters**

| Name        | Type      | Description                                                              |
| ----------- | --------- | ------------------------------------------------------------------------ |
| `roleId`    | `bytes32` | The ID of the role to be modified.                                       |
| `token`     | `address` | The token for which to the threshold.                                    |
| `threshold` | `uint256` | The user will need to have at least this number to qualify for the role. |

### Events

#### ChangedTokenGating

Event emitted when the token-gating of a role changes.

```solidity
event ChangedTokenGating(bytes32 role, bool newValue);
```

**Parameters**

| Name       | Type      | Description                 |
| ---------- | --------- | --------------------------- |
| `role`     | `bytes32` | The role that was modified. |
| `newValue` | `bool`    | The new value of the role.  |

#### ChangedTokenThreshold

Event emitted when the threshold of a token-gated role changes.

```solidity
event ChangedTokenThreshold(bytes32 role, address token, uint newValue);
```

**Parameters**

| Name       | Type      | Description                                     |
| ---------- | --------- | ----------------------------------------------- |
| `role`     | `bytes32` | The role that was modified.                     |
| `token`    | `address` | The token for which the threshold was modified. |
| `newValue` | `uint256` | The new value of the threshold.                 |

### Errors

#### Module\_\_AUT\_TokenGated\_Roles\_\_RoleNotTokenGated

The function is only callable by an active Module.

```solidity
error Module__AUT_TokenGated_Roles__RoleNotTokenGated();
```

#### Module\_\_AUT\_TokenGated\_Roles\_\_RoleNotEmpty

The function is only callable if the Module is self-managing its roles.

```solidity
error Module__AUT_TokenGated_Roles__RoleNotEmpty();
```

#### Module\_\_AUT\_TokenGated\_Roles\_\_InvalidToken

The token doesn't support balance query.

```solidity
error Module__AUT_TokenGated_Roles__InvalidToken(address token);
```

**Parameters**

| Name    | Type      | Description                              |
| ------- | --------- | ---------------------------------------- |
| `token` | `address` | The token address that is not supported. |

#### Module\_\_AUT\_TokenGated\_Roles\_\_InvalidThreshold

The given threshold is invalid.

```solidity
error Module__AUT_TokenGated_Roles__InvalidThreshold(uint threshold);
```

**Parameters**

| Name        | Type      | Description                      |
| ----------- | --------- | -------------------------------- |
| `threshold` | `uint256` | The threshold that is not valid. |

#### Module\_\_AUT\_TokenGated\_Roles\_\_TokenRoleMustHaveThreshold

The role is token-gated but no threshold is set.

```solidity
error Module__AUT_TokenGated_Roles__TokenRoleMustHaveThreshold(
    bytes32 role, address token
);
```

**Parameters**

| Name    | Type      | Description                                    |
| ------- | --------- | ---------------------------------------------- |
| `role`  | `bytes32` | The role that doesnt have threshold.           |
| `token` | `address` | The token for which the threshold was not set. |


# AUT\_EXT\_VotingRoles\_v1.sol

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

**Inherits:** IAUT\_EXT\_VotingRoles\_v1, Module\_v1

**Author:** Inverter Network

Facilitates voting and motion management within the Inverter Network, allowing designated voters to participate in governance through proposals, voting, and execution of decisions.

*Supports setting thresholds for decision-making, managing voter lists, creating motions, casting votes, and executing actions based on collective decisions. This structure enhances governance transparency and efficacy.*

### State Variables

#### MAX\_VOTING\_DURATION

The maximum voting duration.

```solidity
uint public constant MAX_VOTING_DURATION = 2 weeks;
```

#### MIN\_VOTING\_DURATION

The minimum voting duration.

```solidity
uint public constant MIN_VOTING_DURATION = 1 days;
```

#### isVoter

Checks whether an address is a voter.

```solidity
mapping(address => bool) public isVoter;
```

#### motions

Gets the motion data.

```solidity
mapping(bytes32 => Motion) public motions;
```

#### motionCount

Gets the number of motions.

```solidity
uint public motionCount;
```

#### voterCount

Gets the number of voters.

```solidity
uint public voterCount;
```

#### threshold

Gets the threshold.

```solidity
uint public threshold;
```

#### voteDuration

Gets the voting duration.

```solidity
uint public voteDuration;
```

#### \_\_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(Module_v1)
    returns (bool);
```

#### onlySelf

*Reverts if caller is not the module itself.*

```solidity
modifier onlySelf();
```

#### onlyVoter

*Reverts if caller is not a voter.*

```solidity
modifier onlyVoter();
```

#### isValidVoterAddress

*Reverts if voter address is invalid.*

```solidity
modifier isValidVoterAddress(address voter);
```

**Parameters**

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

#### init

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

#### getReceipt

Gets the receipt of a voter for a motion.

```solidity
function getReceipt(bytes32 _ID, address voter)
    public
    view
    returns (Receipt memory);
```

**Parameters**

| Name    | Type      | Description               |
| ------- | --------- | ------------------------- |
| `_ID`   | `bytes32` | The ID of the motion.     |
| `voter` | `address` | The address of the voter. |

**Returns**

| Name     | Type      | Description               |
| -------- | --------- | ------------------------- |
| `<none>` | `Receipt` | The receipt of the voter. |

#### setThreshold

Sets the threshold.

```solidity
function setThreshold(uint newThreshold) public onlySelf;
```

**Parameters**

| Name           | Type      | Description        |
| -------------- | --------- | ------------------ |
| `newThreshold` | `uint256` | The new threshold. |

#### setVotingDuration

Sets the voting duration.

```solidity
function setVotingDuration(uint newVoteDuration) external onlySelf;
```

**Parameters**

| Name              | Type      | Description              |
| ----------------- | --------- | ------------------------ |
| `newVoteDuration` | `uint256` | The new voting duration. |

#### addVoter

Adds a voter.

```solidity
function addVoter(address who) public onlySelf isValidVoterAddress(who);
```

**Parameters**

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

#### addVoterAndUpdateThreshold

Adds a voter and updates the threshold.

```solidity
function addVoterAndUpdateThreshold(address who, uint newThreshold) external;
```

**Parameters**

| Name           | Type      | Description         |
| -------------- | --------- | ------------------- |
| `who`          | `address` | The address to add. |
| `newThreshold` | `uint256` | The new threshold.  |

#### removeVoter

Removes a voter.

```solidity
function removeVoter(address who) public onlySelf;
```

**Parameters**

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

#### removeVoterAndUpdateThreshold

Removes a voter and updates the threshold.

```solidity
function removeVoterAndUpdateThreshold(address who, uint newThreshold)
    external
    onlySelf;
```

**Parameters**

| Name           | Type      | Description            |
| -------------- | --------- | ---------------------- |
| `who`          | `address` | The address to remove. |
| `newThreshold` | `uint256` | The new threshold.     |

#### \_removeVoter

*Removes a voter from the list of voters.*

```solidity
function _removeVoter(address who) internal;
```

**Parameters**

| Name  | Type      | Description                         |
| ----- | --------- | ----------------------------------- |
| `who` | `address` | The address of the voter to remove. |

#### createMotion

Creates a motion.

```solidity
function createMotion(address target, bytes calldata action)
    external
    onlyVoter
    returns (bytes32);
```

**Parameters**

| Name     | Type      | Description                                           |
| -------- | --------- | ----------------------------------------------------- |
| `target` | `address` | The address of the contract to execute the action on. |
| `action` | `bytes`   | The action data to execute on the target contract.    |

**Returns**

| Name     | Type      | Description                   |
| -------- | --------- | ----------------------------- |
| `<none>` | `bytes32` | The ID of the created motion. |

#### castVote

Casts a vote for a motion.

```solidity
function castVote(bytes32 motionId, uint8 support) external onlyVoter;
```

**Parameters**

| Name       | Type      | Description                                                    |
| ---------- | --------- | -------------------------------------------------------------- |
| `motionId` | `bytes32` | The ID of the motion.                                          |
| `support`  | `uint8`   | The value that indicates wether the voter supports the motion. |

#### executeMotion

Executes a motion.

```solidity
function executeMotion(bytes32 motionId) external;
```

**Parameters**

| Name       | Type      | Description           |
| ---------- | --------- | --------------------- |
| `motionId` | `bytes32` | The ID of the motion. |

#### \_validateThreshold

*Internal function to validate the threshold.*

```solidity
function _validateThreshold(uint _voters, uint _threshold) internal pure;
```

**Parameters**

| Name         | Type      | Description           |
| ------------ | --------- | --------------------- |
| `_voters`    | `uint256` | The number of voters. |
| `_threshold` | `uint256` | The threshold.        |


# AUT\_Roles\_v1.sol

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

**Inherits:** IAuthorizer\_v1, AccessControlEnumerableUpgradeable, Module\_v1

**Author:** Inverter Network

Provides a robust access control mechanism for managing roles and permissions across different modules within the Inverter Network, ensuring secure and controlled access to critical functionalities.

*Extends {AccessControlEnumerableUpgradeable} and integrates with {Module\_v1} to offer fine-grained access control through role-based permissions. Utilizes ERC2771 for meta-transactions to enhance module interaction experiences.*

### State Variables

#### BURN\_ADMIN\_ROLE

The role that is used as a placeholder for a burned admin role.

```solidity
bytes32 public constant BURN_ADMIN_ROLE =
    0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;
```

#### \_\_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(Module_v1, AccessControlEnumerableUpgradeable)
    returns (bool);
```

#### onlyModule

*Verifies that the caller is an active module.*

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

**Parameters**

| Name     | Type      | Description                |
| -------- | --------- | -------------------------- |
| `module` | `address` | The address of the module. |

#### notLastAdmin

*Verifies that the admin being removed is not the last one.*

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

**Parameters**

| Name   | Type      | Description                |
| ------ | --------- | -------------------------- |
| `role` | `bytes32` | The id number of the role. |

#### noSelfAdmin

*Verifies that the admin being added is not the {Orchestrator\_v1}.*

```solidity
modifier noSelfAdmin(bytes32 role, address who);
```

**Parameters**

| Name   | Type      | Description                   |
| ------ | --------- | ----------------------------- |
| `role` | `bytes32` | The id number of the role.    |
| `who`  | `address` | The user we want to check on. |

### Public Functions

#### init

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

#### checkForRole

Checks whether an address holds the required role to execute the current transaction.

*The calling contract needs to generate the right role ID using its own address and the role identifier. In modules, this function should be used instead of `hasRole`, as there are Authorizer-specific checks that need to be performed.*

```solidity
function checkForRole(bytes32 role, address who)
    external
    view
    virtual
    returns (bool);
```

**Parameters**

| Name   | Type      | Description                                 |
| ------ | --------- | ------------------------------------------- |
| `role` | `bytes32` | The identifier of the role we want to check |
| `who`  | `address` | The address on which to perform the check.  |

**Returns**

| Name     | Type   | Description                                |
| -------- | ------ | ------------------------------------------ |
| `<none>` | `bool` | bool Returns if the address holds the role |

#### generateRoleId

Helper function to generate a bytes32 role hash for a module role.

```solidity
function generateRoleId(address module, bytes32 role)
    public
    pure
    returns (bytes32);
```

**Parameters**

| Name     | Type      | Description                                         |
| -------- | --------- | --------------------------------------------------- |
| `module` | `address` | The address of the module to generate the hash for. |
| `role`   | `bytes32` | The ID number of the role to generate the hash for. |

**Returns**

| Name     | Type      | Description                              |
| -------- | --------- | ---------------------------------------- |
| `<none>` | `bytes32` | bytes32 Returns the generated role hash. |

#### grantRoleFromModule

Used by a Module to grant a role to a user.

```solidity
function grantRoleFromModule(bytes32 role, address target)
    external
    onlyModule(_msgSender());
```

**Parameters**

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

#### grantRoleFromModuleBatched

Used by a Module to grant a role to a set of users.

```solidity
function grantRoleFromModuleBatched(bytes32 role, address[] calldata targets)
    external
    onlyModule(_msgSender());
```

**Parameters**

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

#### revokeRoleFromModule

Used by a Module to revoke a role from a user.

```solidity
function revokeRoleFromModule(bytes32 role, address target)
    external
    onlyModule(_msgSender());
```

**Parameters**

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

#### revokeRoleFromModuleBatched

Used by a Module to revoke a role from a set of users.

```solidity
function revokeRoleFromModuleBatched(bytes32 role, address[] calldata targets)
    external
    onlyModule(_msgSender());
```

**Parameters**

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

#### transferAdminRole

Transfer the admin rights to a given role.

```solidity
function transferAdminRole(bytes32 roleId, bytes32 newAdmin)
    external
    onlyRole(getRoleAdmin(roleId));
```

**Parameters**

| Name       | Type      | Description                                        |
| ---------- | --------- | -------------------------------------------------- |
| `roleId`   | `bytes32` | The role on which to peform the admin transfer.    |
| `newAdmin` | `bytes32` | The new role to which to transfer admin access to. |

#### burnAdminFromModuleRole

Irreversibly burns the admin of a given role.

*The module itself can still grant and revoke it's own roles. This only burns third-party access to the role.*

```solidity
function burnAdminFromModuleRole(bytes32 role)
    external
    onlyModule(_msgSender());
```

**Parameters**

| Name   | Type      | Description                           |
| ------ | --------- | ------------------------------------- |
| `role` | `bytes32` | The role to remove admin access from. |

#### grantGlobalRole

Grants a global role to a target.

*Only the addresses with the Admin role should be able to call this function.*

```solidity
function grantGlobalRole(bytes32 role, address target)
    external
    onlyRole(DEFAULT_ADMIN_ROLE);
```

**Parameters**

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

#### grantGlobalRoleBatched

Grants a global role to a set of targets.

*Only the addresses with the Admin role should be able to call this function.*

```solidity
function grantGlobalRoleBatched(bytes32 role, address[] calldata targets)
    external
    onlyRole(DEFAULT_ADMIN_ROLE);
```

**Parameters**

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

#### revokeGlobalRole

Revokes a global role from a target.

*Only the addresses with the Admin role should be able to call this function.*

```solidity
function revokeGlobalRole(bytes32 role, address target)
    external
    onlyRole(DEFAULT_ADMIN_ROLE);
```

**Parameters**

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

#### revokeGlobalRoleBatched

Revokes a global role from a set of targets.

*Only the addresses with the Admin role should be able to call this function.*

```solidity
function revokeGlobalRoleBatched(bytes32 role, address[] calldata targets)
    external
    onlyRole(DEFAULT_ADMIN_ROLE);
```

**Parameters**

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

#### getAdminRole

Returns the role ID of the admin role.

```solidity
function getAdminRole() public pure returns (bytes32);
```

**Returns**

| Name     | Type      | Description  |
| -------- | --------- | ------------ |
| `<none>` | `bytes32` | The role ID. |

### Internal Functions

#### \_\_RoleAuthorizer\_init

Initializes the role authorizer.

```solidity
function __RoleAuthorizer_init(address initialAdmin)
    internal
    onlyInitializing;
```

**Parameters**

| Name           | Type      | Description                               |
| -------------- | --------- | ----------------------------------------- |
| `initialAdmin` | `address` | The initial admin of the role authorizer. |

#### \_revokeRole

Overrides \_revokeRole to prevent having an empty `ADMIN` role.

```solidity
function _revokeRole(bytes32 role, address who)
    internal
    virtual
    override
    notLastAdmin(role)
    returns (bool);
```

**Parameters**

| Name   | Type      | Description                   |
| ------ | --------- | ----------------------------- |
| `role` | `bytes32` | The id number of the role.    |
| `who`  | `address` | The user we want to check on. |

**Returns**

| Name     | Type   | Description                                |
| -------- | ------ | ------------------------------------------ |
| `<none>` | `bool` | bool Returns if revoke has been succesful. |

#### \_grantRole

Overrides \_grantRole to prevent having the {Orchestrator\_v1} having the `OWNER` role.

```solidity
function _grantRole(bytes32 role, address who)
    internal
    virtual
    override
    noSelfAdmin(role, who)
    returns (bool);
```

**Parameters**

| Name   | Type      | Description                   |
| ------ | --------- | ----------------------------- |
| `role` | `bytes32` | The id of the role.           |
| `who`  | `address` | The user we want to check on. |

**Returns**

| Name     | Type   | Description                               |
| -------- | ------ | ----------------------------------------- |
| `<none>` | `bool` | bool Returns if grant has been succesful. |

#### \_msgSender

Needs to be overridden, because they are imported via the AccessControlEnumerableUpgradeable as well.

```solidity
function _msgSender()
    internal
    view
    virtual
    override(ContextUpgradeable, ERC2771ContextUpgradeable)
    returns (address sender);
```

#### \_msgData

Needs to be overridden, because they are imported via the AccessControlEnumerableUpgradeable as well.

```solidity
function _msgData()
    internal
    view
    virtual
    override(ContextUpgradeable, ERC2771ContextUpgradeable)
    returns (bytes calldata);
```

#### \_contextSuffixLength

```solidity
function _contextSuffixLength()
    internal
    view
    virtual
    override(ContextUpgradeable, ERC2771ContextUpgradeable)
    returns (uint);
```


# AUT\_TokenGated\_Roles\_v1.sol

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

**Inherits:** IAUT\_TokenGated\_Roles\_v1, AUT\_Roles\_v1

**Author:** Inverter Network

Extends the Inverter's role-based access control to include token gating, enabling roles to be conditionally assigned based on token ownership. This mechanism allows for dynamic permissioning tied to specific token holdings.

*Builds on {AUT\_Roles\_v1} by integrating token-based access checks before role assignment. Utilizes checks on token balances to gate access, supporting both {ERC20} and {ERC721} tokens as qualifiers for role eligibility.*

### State Variables

#### isTokenGated

*Stores if a role is token gated.*

```solidity
mapping(bytes32 => bool) public isTokenGated;
```

#### thresholdMap

*Stores the threshold amount for each token in a role.*

```solidity
mapping(bytes32 => uint) public thresholdMap;
```

#### \_\_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(AUT_Roles_v1)
    returns (bool);
```

#### onlyEmptyRole

*Modifier to guarantee function is only callable when the role is empty.*

```solidity
modifier onlyEmptyRole(bytes32 roleId);
```

**Parameters**

| Name     | Type      | Description                       |
| -------- | --------- | --------------------------------- |
| `roleId` | `bytes32` | The ID of the role to be checked. |

#### onlyTokenGated

*Modifier to guarantee function is only callable when the role is token-gated.*

```solidity
modifier onlyTokenGated(bytes32 roleId);
```

**Parameters**

| Name     | Type      | Description                       |
| -------- | --------- | --------------------------------- |
| `roleId` | `bytes32` | The ID of the role to be checked. |

#### validThreshold

*Modifier to guarantee function is only callable when the threshold is valid.*

```solidity
modifier validThreshold(uint threshold);
```

**Parameters**

| Name        | Type      | Description                  |
| ----------- | --------- | ---------------------------- |
| `threshold` | `uint256` | The threshold to be checked. |

#### hasTokenRole

Checks if an account qualifies for a token-gated role.

```solidity
function hasTokenRole(bytes32 role, address who)
    external
    view
    onlyTokenGated(role)
    returns (bool);
```

**Parameters**

| Name   | Type      | Description                |
| ------ | --------- | -------------------------- |
| `role` | `bytes32` | The role to be checked.    |
| `who`  | `address` | The account to be checked. |

**Returns**

| Name     | Type   | Description                                 |
| -------- | ------ | ------------------------------------------- |
| `<none>` | `bool` | True if the account qualifies for the role. |

#### getThresholdValue

Returns the threshold balance for a given token necessary to qualify for a specific role. If the value is 0, the supplied token is not part of the. role's token gating.

*In case the queried role is not token gated, all calls will return 0.*

```solidity
function getThresholdValue(bytes32 roleId, address token)
    public
    view
    returns (uint);
```

**Parameters**

| Name     | Type      | Description                           |
| -------- | --------- | ------------------------------------- |
| `roleId` | `bytes32` | The role to be checked on.            |
| `token`  | `address` | The token to check the threshold for. |

**Returns**

| Name     | Type      | Description                                                       |
| -------- | --------- | ----------------------------------------------------------------- |
| `<none>` | `uint256` | The threshold amount necessary to qualify for a given token role. |

#### makeRoleTokenGatedFromModule

Sets up a token-gated empty role.

*This function is only callable by an active Module for itself. Admin should use `setTokenGated()`.*

```solidity
function makeRoleTokenGatedFromModule(bytes32 role)
    public
    onlyModule(_msgSender())
    onlyEmptyRole(generateRoleId(_msgSender(), role));
```

**Parameters**

| Name   | Type      | Description                      |
| ------ | --------- | -------------------------------- |
| `role` | `bytes32` | The role to be made token-gated. |

#### grantTokenRoleFromModule

One-step setup for Modules to create a token-gated role and set its threshold. Please be aware that using tokens that are transferable and have active markets could make the token-gated authorization vulnerable to flash loans, potentially bypassing. the authorization mechanism.

```solidity
function grantTokenRoleFromModule(bytes32 role, address token, uint threshold)
    external
    onlyModule(_msgSender());
```

**Parameters**

| Name        | Type      | Description                                                        |
| ----------- | --------- | ------------------------------------------------------------------ |
| `role`      | `bytes32` | The role to be made token-gated.                                   |
| `token`     | `address` | The token for which the threshold will be set.                     |
| `threshold` | `uint256` | The minimum balance of the token required to qualify for the role. |

#### setThresholdFromModule

Allows a Module to set the threshold of one of it's roles.

```solidity
function setThresholdFromModule(bytes32 role, address token, uint threshold)
    public
    onlyModule(_msgSender());
```

**Parameters**

| Name        | Type      | Description                                                            |
| ----------- | --------- | ---------------------------------------------------------------------- |
| `role`      | `bytes32` | The token-gated role.                                                  |
| `token`     | `address` | The token for which the threshold will be set.                         |
| `threshold` | `uint256` | The new minimum balance of the token required to qualify for the role. |

#### setTokenGated

Sets if a role is token-gated or not.

*Admin access for rescue purposes. If the role has active members, they need to be reovked first.*

```solidity
function setTokenGated(bytes32 role, bool to)
    public
    onlyRole(getRoleAdmin(role))
    onlyEmptyRole(role);
```

**Parameters**

| Name   | Type      | Description                        |
| ------ | --------- | ---------------------------------- |
| `role` | `bytes32` | The ID of the role to be modified. |
| `to`   | `bool`    | The new value to be set.           |

#### setThreshold

Sets the minimum threshold for a token-gated role.

*This function does not validate the threshold. It is technically possible to set a threshold above the total supply of the token.*

```solidity
function setThreshold(bytes32 roleId, address token, uint threshold)
    public
    onlyRole(getRoleAdmin(roleId));
```

**Parameters**

| Name        | Type      | Description                                                              |
| ----------- | --------- | ------------------------------------------------------------------------ |
| `roleId`    | `bytes32` | The ID of the role to be modified.                                       |
| `token`     | `address` | The token for which to the threshold.                                    |
| `threshold` | `uint256` | The user will need to have at least this number to qualify for the role. |

#### \_grantRole

Grants a role to an address.

*Overrides \_grantRole from {AUT\_ROLES\_v1} to enforce interface implementation and threshold existence when role is token-gated.*

*Please note: current check for validating a valid token is not conclusive and could be circumvented through a `callback()` function.*

```solidity
function _grantRole(bytes32 role, address who)
    internal
    virtual
    override
    returns (bool);
```

**Parameters**

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

**Returns**

| Name     | Type   | Description                                                 |
| -------- | ------ | ----------------------------------------------------------- |
| `<none>` | `bool` | bool Returns true if the role has been granted succesfully. |

#### \_revokeRole

*Overrides \_revokeRole to clean up threshold data on revoking.*

```solidity
function _revokeRole(bytes32 role, address who)
    internal
    virtual
    override
    returns (bool);
```

**Parameters**

| Name   | Type      | Description                   |
| ------ | --------- | ----------------------------- |
| `role` | `bytes32` | The id number of the role.    |
| `who`  | `address` | The user we want to check on. |

**Returns**

| Name     | Type   | Description                                |
| -------- | ------ | ------------------------------------------ |
| `<none>` | `bool` | bool Returns if revoke has been succesful. |

#### \_setThreshold

Sets the minimum threshold for a token-gated role.

*This function does not validate the threshold. It is technically possible to set a threshold above the total supply of the token.*

```solidity
function _setThreshold(bytes32 roleId, address token, uint threshold)
    internal
    onlyTokenGated(roleId)
    validThreshold(threshold);
```

**Parameters**

| Name        | Type      | Description                                                              |
| ----------- | --------- | ------------------------------------------------------------------------ |
| `roleId`    | `bytes32` | The ID of the role to be modified.                                       |
| `token`     | `address` | The token for which to the threshold.                                    |
| `threshold` | `uint256` | The user will need to have at least this number to qualify for the role. |

#### \_hasTokenRole

Internal function that checks if an account qualifies for a token-gated role.

```solidity
function _hasTokenRole(bytes32 role, address who)
    internal
    view
    returns (bool);
```

**Parameters**

| Name   | Type      | Description                |
| ------ | --------- | -------------------------- |
| `role` | `bytes32` | The role to be checked.    |
| `who`  | `address` | The account to be checked. |

#### checkForRole

In case the role is token gated, it will check if {who} holds a balance above the threshold for at least one of the required tokens.

*The calling contract needs to generate the right role ID using its own address and the role identifier. In modules, this function should be used instead of `hasRole`, as there are Authorizer-specific checks that need to be performed.*

```solidity
function checkForRole(bytes32 role, address who)
    external
    view
    virtual
    override(AUT_Roles_v1, IAuthorizer_v1)
    returns (bool);
```

**Parameters**

| Name   | Type      | Description                                 |
| ------ | --------- | ------------------------------------------- |
| `role` | `bytes32` | The identifier of the role we want to check |
| `who`  | `address` | The address on which to perform the check.  |

**Returns**

| Name     | Type   | Description                                |
| -------- | ------ | ------------------------------------------ |
| `<none>` | `bool` | bool Returns if the address holds the role |


# IAuthorizer\_v1.sol

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

**Inherits:** IAccessControlEnumerable

### Functions

#### checkForRole

Checks whether an address holds the required role to execute the current transaction.

*The calling contract needs to generate the right role ID using its own address and the role identifier. In modules, this function should be used instead of `hasRole`, as there are Authorizer-specific checks that need to be performed.*

```solidity
function checkForRole(bytes32 role, address who) external view returns (bool);
```

**Parameters**

| Name   | Type      | Description                                 |
| ------ | --------- | ------------------------------------------- |
| `role` | `bytes32` | The identifier of the role we want to check |
| `who`  | `address` | The address on which to perform the check.  |

**Returns**

| Name     | Type   | Description                                |
| -------- | ------ | ------------------------------------------ |
| `<none>` | `bool` | bool Returns if the address holds the role |

#### generateRoleId

Helper function to generate a bytes32 role hash for a module role.

```solidity
function generateRoleId(address module, bytes32 role)
    external
    pure
    returns (bytes32);
```

**Parameters**

| Name     | Type      | Description                                         |
| -------- | --------- | --------------------------------------------------- |
| `module` | `address` | The address of the module to generate the hash for. |
| `role`   | `bytes32` | The ID number of the role to generate the hash for. |

**Returns**

| Name     | Type      | Description                              |
| -------- | --------- | ---------------------------------------- |
| `<none>` | `bytes32` | bytes32 Returns the generated role hash. |

#### grantRoleFromModule

Used by a Module to grant a role to a user.

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

**Parameters**

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

#### grantRoleFromModuleBatched

Used by a Module to grant a role to a set of users.

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

**Parameters**

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

#### revokeRoleFromModule

Used by a Module to revoke a role from a user.

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

**Parameters**

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

#### revokeRoleFromModuleBatched

Used by a Module to revoke a role from a set of users.

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

**Parameters**

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

#### transferAdminRole

Transfer the admin rights to a given role.

```solidity
function transferAdminRole(bytes32 roleId, bytes32 newAdmin) external;
```

**Parameters**

| Name       | Type      | Description                                        |
| ---------- | --------- | -------------------------------------------------- |
| `roleId`   | `bytes32` | The role on which to peform the admin transfer.    |
| `newAdmin` | `bytes32` | The new role to which to transfer admin access to. |

#### burnAdminFromModuleRole

Irreversibly burns the admin of a given role.

*The module itself can still grant and revoke it's own roles. This only burns third-party access to the role.*

```solidity
function burnAdminFromModuleRole(bytes32 role) external;
```

**Parameters**

| Name   | Type      | Description                           |
| ------ | --------- | ------------------------------------- |
| `role` | `bytes32` | The role to remove admin access from. |

#### grantGlobalRole

Grants a global role to a target.

*Only the addresses with the Admin role should be able to call this function.*

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

**Parameters**

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

#### grantGlobalRoleBatched

Grants a global role to a set of targets.

*Only the addresses with the Admin role should be able to call this function.*

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

**Parameters**

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

#### revokeGlobalRole

Revokes a global role from a target.

*Only the addresses with the Admin role should be able to call this function.*

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

**Parameters**

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

#### revokeGlobalRoleBatched

Revokes a global role from a set of targets.

*Only the addresses with the Admin role should be able to call this function.*

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

**Parameters**

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

#### getAdminRole

Returns the role ID of the admin role.

```solidity
function getAdminRole() external view returns (bytes32);
```

**Returns**

| Name     | Type      | Description  |
| -------- | --------- | ------------ |
| `<none>` | `bytes32` | The role ID. |

### Errors

#### Module\_\_Authorizer\_\_NotActiveModule

The function is only callable by an active Module.

```solidity
error Module__Authorizer__NotActiveModule(address module);
```

**Parameters**

| Name     | Type      | Description                |
| -------- | --------- | -------------------------- |
| `module` | `address` | The address of the module. |

#### Module\_\_Authorizer\_\_ModuleNotSelfManaged

The function is only callable if the Module is self-managing its roles.

```solidity
error Module__Authorizer__ModuleNotSelfManaged();
```

#### Module\_\_Authorizer\_\_AdminRoleCannotBeEmpty

There always needs to be at least one admin.

```solidity
error Module__Authorizer__AdminRoleCannotBeEmpty();
```

#### Module\_\_Authorizer\_\_OrchestratorCannotHaveAdminRole

The orchestrator cannot own itself.

```solidity
error Module__Authorizer__OrchestratorCannotHaveAdminRole();
```

#### Module\_\_Authorizer\_\_InvalidInitialAdmin

The provided initial admin address is invalid.

```solidity
error Module__Authorizer__InvalidInitialAdmin();
```


# Base


# IModule\_v1.sol

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

### Functions

#### init

The module's initializer function.

*CAN be overridden by downstream contract.*

*MUST call `__Module_init()`.*

```solidity
function init(
    IOrchestrator_v1 orchestrator,
    Metadata memory metadata,
    bytes memory configData
) external;
```

**Parameters**

| Name           | Type               | Description                                               |
| -------------- | ------------------ | --------------------------------------------------------- |
| `orchestrator` | `IOrchestrator_v1` | The module's {Orchestrator\_v1} instance.                 |
| `metadata`     | `Metadata`         | The module's metadata.                                    |
| `configData`   | `bytes`            | Variable config data for specific module implementations. |

#### 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() external view returns (bytes32);
```

**Returns**

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

#### version

Returns the module's version.

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

**Returns**

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

#### url

Returns the module's URL.

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

**Returns**

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

#### title

Returns the module's title.

```solidity
function title() external 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() external 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;
```

**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;
```

**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;
```

**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;
```

**Parameters**

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

### Events

#### ModuleInitialized

Module has been initialized.

```solidity
event ModuleInitialized(address indexed parentOrchestrator, Metadata metadata);
```

**Parameters**

| Name                 | Type       | Description                                                    |
| -------------------- | ---------- | -------------------------------------------------------------- |
| `parentOrchestrator` | `address`  | The address of the {Orchestrator\_v1} the module is linked to. |
| `metadata`           | `Metadata` | The metadata of the module.                                    |

#### ProtocolFeeTransferred

Event emitted when protocol fee has been transferred to the treasury.

```solidity
event ProtocolFeeTransferred(
    address indexed token, address indexed treasury, uint feeAmount
);
```

**Parameters**

| Name        | Type      | Description                                                   |
| ----------- | --------- | ------------------------------------------------------------- |
| `token`     | `address` | The token received as protocol fee.                           |
| `treasury`  | `address` | The protocol treasury address receiving the token fee amount. |
| `feeAmount` | `uint256` | The fee amount transferred to the treasury.                   |

### Errors

#### Module\_\_CallerNotAuthorized

Function is only callable by authorized caller.

```solidity
error Module__CallerNotAuthorized(bytes32 role, address caller);
```

**Parameters**

| Name     | Type      | Description                                    |
| -------- | --------- | ---------------------------------------------- |
| `role`   | `bytes32` | The role that is required.                     |
| `caller` | `address` | The address that is required to have the role. |

#### Module\_\_OnlyCallableByOrchestrator

Function is only callable by the {Orchestrator\_v1}.

```solidity
error Module__OnlyCallableByOrchestrator();
```

#### Module\_\_OnlyCallableByPaymentClient

Function is only callable by a {IERC20PaymentClientBase\_v1}.

```solidity
error Module__OnlyCallableByPaymentClient();
```

#### Module\_\_InvalidOrchestratorAddress

Given {Orchestrator\_v1} address invalid.

```solidity
error Module__InvalidOrchestratorAddress();
```

#### Module\_\_InvalidMetadata

Given metadata invalid.

```solidity
error Module__InvalidMetadata();
```

#### Module\_OrchestratorCallbackFailed

{Orchestrator\_v1} callback triggered failed.

```solidity
error Module_OrchestratorCallbackFailed(string funcSig);
```

**Parameters**

| Name      | Type     | Description                           |
| --------- | -------- | ------------------------------------- |
| `funcSig` | `string` | The signature of the function called. |

#### Module\_\_InvalidAddress

*Invalid Address.*

```solidity
error Module__InvalidAddress();
```

### Structs

#### Metadata

The module's metadata.

```solidity
struct Metadata {
    uint majorVersion;
    uint minorVersion;
    uint patchVersion;
    string url;
    string title;
}
```

**Properties**

| Name           | Type      | Description                 |
| -------------- | --------- | --------------------------- |
| `majorVersion` | `uint256` | The module's major version. |
| `minorVersion` | `uint256` | The module's minor version. |
| `patchVersion` | `uint256` | The module's patch version. |
| `url`          | `string`  | The module's URL.           |
| `title`        | `string`  | The module's title.         |


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




---

[Next Page](/llms-full.txt/1)

