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

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