# 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](https://docs.ionprotocol.io/devs/smart-contract-architecture/broken-reference) <a href="#state-variables" id="state-variables"></a>

#### [protocolWhitelist](https://docs.ionprotocol.io/devs/smart-contract-architecture/broken-reference) <a href="#protocolwhitelist" id="protocolwhitelist"></a>

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

#### [borrowersRoot](https://docs.ionprotocol.io/devs/smart-contract-architecture/broken-reference) <a href="#borrowersroot" id="borrowersroot"></a>

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

#### [lendersRoot](https://docs.ionprotocol.io/devs/smart-contract-architecture/broken-reference) <a href="#lendersroot" id="lendersroot"></a>

```
bytes32 public lendersRoot;
```

### [Functions](https://docs.ionprotocol.io/devs/smart-contract-architecture/broken-reference) <a href="#functions" id="functions"></a>

#### [constructor](https://docs.ionprotocol.io/devs/smart-contract-architecture/broken-reference) <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](https://docs.ionprotocol.io/devs/smart-contract-architecture/broken-reference) <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](https://docs.ionprotocol.io/devs/smart-contract-architecture/broken-reference) <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](https://docs.ionprotocol.io/devs/smart-contract-architecture/broken-reference) <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](https://docs.ionprotocol.io/devs/smart-contract-architecture/broken-reference) <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](https://docs.ionprotocol.io/devs/smart-contract-architecture/broken-reference) <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](https://docs.ionprotocol.io/devs/smart-contract-architecture/broken-reference) <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](https://docs.ionprotocol.io/devs/smart-contract-architecture/broken-reference) <a href="#errors" id="errors"></a>

#### [NotWhitelistedBorrower](https://docs.ionprotocol.io/devs/smart-contract-architecture/broken-reference) <a href="#notwhitelistedborrower" id="notwhitelistedborrower"></a>

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

#### [NotWhitelistedLender](https://docs.ionprotocol.io/devs/smart-contract-architecture/broken-reference) <a href="#notwhitelistedlender" id="notwhitelistedlender"></a>

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