# Whitelist

[Git Source](https://github.com/Ion-Protocol/ion-protocol/blob/88cc595825f1dc2eb738fb93e172a3e8ab7a5c43/src/Whitelist.sol)

**Inherits:** Ownable2Step

An external Whitelist module that Ion's system-wide contracts can use to verify that a user is permitted to borrow or lend. A merkle whitelist is used to allow for a large number of addresses to be whitelisted without consuming infordinate amounts of gas for the updates. There is also a protocol whitelist that can be used to allow for a protocol controlled address to bypass the merkle proof check. These protocol-controlled contract are expected to perform whitelist checks themsleves on their own entrypoints.

*The full merkle tree is stored off-chain and only the root is stored on-chain.*

### [State Variables](broken://pages/KCnGcKEa5JAVz4D3VtsH) <a href="#state-variables" id="state-variables"></a>

#### [protocolWhitelist](broken://pages/KCnGcKEa5JAVz4D3VtsH) <a href="#protocolwhitelist" id="protocolwhitelist"></a>

```
mapping(address protocolControlledAddress => bool) public protocolWhitelist;
```

#### [borrowersRoot](broken://pages/KCnGcKEa5JAVz4D3VtsH) <a href="#borrowersroot" id="borrowersroot"></a>

```
mapping(uint8 ilkIndex => bytes32) public borrowersRoot;
```

#### [lendersRoot](broken://pages/KCnGcKEa5JAVz4D3VtsH) <a href="#lendersroot" id="lendersroot"></a>

```
bytes32 public lendersRoot;
```

### [Functions](broken://pages/KCnGcKEa5JAVz4D3VtsH) <a href="#functions" id="functions"></a>

#### [constructor](broken://pages/KCnGcKEa5JAVz4D3VtsH) <a href="#constructor" id="constructor"></a>

Creates a new `Whitelist` instance.

```
constructor(bytes32[] memory _borrowersRoots, bytes32 _lendersRoot) Ownable(msg.sender);
```

**Parameters**

| Name              | Type        | Description                              |
| ----------------- | ----------- | ---------------------------------------- |
| `_borrowersRoots` | `bytes32[]` | List borrower merkle roots for each ilk. |
| `_lendersRoot`    | `bytes32`   | The lender merkle root.                  |

#### [updateBorrowersRoot](broken://pages/KCnGcKEa5JAVz4D3VtsH) <a href="#updateborrowersroot" id="updateborrowersroot"></a>

Updates the borrower merkle root for a specific ilk.

```
function updateBorrowersRoot(uint8 ilkIndex, bytes32 _borrowersRoot) external onlyOwner;
```

**Parameters**

| Name             | Type      | Description                   |
| ---------------- | --------- | ----------------------------- |
| `ilkIndex`       | `uint8`   | of the ilk.                   |
| `_borrowersRoot` | `bytes32` | The new borrower merkle root. |

#### [updateLendersRoot](broken://pages/KCnGcKEa5JAVz4D3VtsH) <a href="#updatelendersroot" id="updatelendersroot"></a>

Updates the lender merkle root.

```
function updateLendersRoot(bytes32 _lendersRoot) external onlyOwner;
```

**Parameters**

| Name           | Type      | Description                 |
| -------------- | --------- | --------------------------- |
| `_lendersRoot` | `bytes32` | The new lender merkle root. |

#### [approveProtocolWhitelist](broken://pages/KCnGcKEa5JAVz4D3VtsH) <a href="#approveprotocolwhitelist" id="approveprotocolwhitelist"></a>

Approves a protocol controlled address to bypass the merkle proof check.

```
function approveProtocolWhitelist(address addr) external onlyOwner;
```

**Parameters**

| Name   | Type      | Description             |
| ------ | --------- | ----------------------- |
| `addr` | `address` | The address to approve. |

#### [revokeProtocolWhitelist](broken://pages/KCnGcKEa5JAVz4D3VtsH) <a href="#revokeprotocolwhitelist" id="revokeprotocolwhitelist"></a>

Revokes a protocol controlled address to bypass the merkle proof check.

```
function revokeProtocolWhitelist(address addr) external onlyOwner;
```

**Parameters**

| Name   | Type      | Description                         |
| ------ | --------- | ----------------------------------- |
| `addr` | `address` | The address to revoke approval for. |

#### [isWhitelistedBorrower](broken://pages/KCnGcKEa5JAVz4D3VtsH) <a href="#iswhitelistedborrower" id="iswhitelistedborrower"></a>

Called by external modifiers to prove inclusion as a borrower.

*If the root is just zero, then the whitelist is effectively turned off as every address will be allowed.*

```
function isWhitelistedBorrower(
    uint8 ilkIndex,
    address poolCaller,
    address addr,
    bytes32[] calldata proof
)
    external
    view
    returns (bool);
```

**Returns**

| Name     | Type   | Description                                                                                    |
| -------- | ------ | ---------------------------------------------------------------------------------------------- |
| `<none>` | `bool` | True if the addr is part of the borrower whitelist or the protocol whitelist. False otherwise. |

#### [isWhitelistedLender](broken://pages/KCnGcKEa5JAVz4D3VtsH) <a href="#iswhitelistedlender" id="iswhitelistedlender"></a>

Called by external modifiers to prove inclusion as a lender.

*If the root is just zero, then the whitelist is effectively turned off as every address will be allowed.*

```
function isWhitelistedLender(address poolCaller, address addr, bytes32[] calldata proof) external view returns (bool);
```

**Returns**

| Name     | Type   | Description                                                                                  |
| -------- | ------ | -------------------------------------------------------------------------------------------- |
| `<none>` | `bool` | True if the addr is part of the lender whitelist or the protocol whitelist. False otherwise. |

### [Errors](broken://pages/KCnGcKEa5JAVz4D3VtsH) <a href="#errors" id="errors"></a>

#### [NotWhitelistedBorrower](broken://pages/KCnGcKEa5JAVz4D3VtsH) <a href="#notwhitelistedborrower" id="notwhitelistedborrower"></a>

```
error NotWhitelistedBorrower(uint8 ilkIndex, address addr);
```

#### [NotWhitelistedLender](broken://pages/KCnGcKEa5JAVz4D3VtsH) <a href="#notwhitelistedlender" id="notwhitelistedlender"></a>

```
error NotWhitelistedLender(address addr);
```


---

# Agent Instructions: Querying This Documentation

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

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

```
GET https://docs.ionprotocol.io/devs/smart-contract-architecture/whitelist.md?ask=<question>
```

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

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