> For the complete documentation index, see [llms.txt](https://docs.rei.network/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.rei.network/developer/system-contracts/fee.md).

# Fee

## Contents

## Globals

| Var             | Type                                                            |
| --------------- | --------------------------------------------------------------- |
| userTotalAmount | mapping(address => uint256)                                     |
| userUsage       | mapping(address => struct IFee.UsageInfo)                       |
| userDeposit     | mapping(address => mapping(address => struct IFee.DepositInfo)) |
| totalAmount     | uint256                                                         |

## Functions

### constructor

No description

**Declaration:**

```solidity
  function constructor(
  ) public Only
```

**Modifiers:**

| Modifier |
| -------- |
| Only     |

### deposit

Deposit amount to target user.

**Declaration:**

```solidity
  function deposit(
    address user
  ) external nonReentrant
```

**Modifiers:**

| Modifier     |
| ------------ |
| nonReentrant |

**Args:**

| Arg    | Type    | Description         |
| ------ | ------- | ------------------- |
| `user` | address | Target user address |

### withdraw

Withdraw amount from target user.

**Declaration:**

```solidity
  function withdraw(
    address user,
    uint256 desiredAmount,
    uint256 minAmount
  ) external nonReentrant
```

**Modifiers:**

| Modifier     |
| ------------ |
| nonReentrant |

**Args:**

| Arg             | Type    | Description             |
| --------------- | ------- | ----------------------- |
| `user`          | address | Target user address     |
| `desiredAmount` | uint256 | Desired withdraw amount |
| `minAmount`     | uint256 | Min withdraw amount     |

### estimateWithdrawableTimestamp

Estimate wtihdrawable timestamp, if the estimation fails, return 0.

**Declaration:**

```solidity
  function estimateWithdrawableTimestamp(
    address user,
    address from
  ) external returns (uint256 timestamp)
```

**Modifiers:** No modifiers

**Args:**

| Arg    | Type    | Description         |
| ------ | ------- | ------------------- |
| `user` | address | Target user address |
| `from` | address | From user address   |

### estimateWithdrawableAmount

Estimate wtihdrawable amount.

**Declaration:**

```solidity
  function estimateWithdrawableAmount(
    address user,
    uint256 timestamp
  ) public returns (uint256)
```

**Modifiers:** No modifiers

**Args:**

| Arg         | Type    | Description         |
| ----------- | ------- | ------------------- |
| `user`      | address | Target user address |
| `timestamp` | uint256 | Current timestamp   |

### estimateFee

Estimate user fee.

```
 userFee = userTotalAmount * dailyFee / totalAmount - userUsage
```

**Declaration:**

```solidity
  function estimateFee(
    address user,
    uint256 timestamp
  ) public returns (uint256 fee)
```

**Modifiers:** No modifiers

**Args:**

| Arg         | Type    | Description       |
| ----------- | ------- | ----------------- |
| `user`      | address | User address      |
| `timestamp` | uint256 | Current timestamp |

### estimateUsage

Estimate user usage

```
 T: current timestamp
 T': last timestamp
 userUsage': last fee usage

 if T - T' < feeRecoverInterval
     userUsage = (1 - (T - T') / feeRecoverInterval) * userUsage'
 else
     userUsage = 0
```

**Declaration:**

```solidity
  function estimateUsage(
    struct IFee.UsageInfo ui,
    uint256 timestamp
  ) public returns (uint256 usage)
```

**Modifiers:** No modifiers

**Args:**

| Arg         | Type                  | Description       |
| ----------- | --------------------- | ----------------- |
| `ui`        | struct IFee.UsageInfo | Usage information |
| `timestamp` | uint256               | Current timestamp |

### consume

Consume user fee, can only be called by the system caller.

**Declaration:**

```solidity
  function consume(
    address user,
    uint256 usage
  ) external nonReentrant onlyRouter
```

**Modifiers:**

| Modifier     |
| ------------ |
| nonReentrant |
| onlyRouter   |

**Args:**

| Arg     | Type    | Description         |
| ------- | ------- | ------------------- |
| `user`  | address | User address        |
| `usage` | uint256 | Number of usage fee |

## Events

### Deposit

Emit when user deposits.

#### Params:

| Param                     | Type    |        Indexed       | Description    |
| ------------------------- | ------- | :------------------: | -------------- |
| `by`                      | address | :white\_check\_mark: | Deposit user   |
| `to`                      | address | :white\_check\_mark: | Receiver user  |
| `amount`                  | uint256 | :white\_check\_mark: | Deposit amount |
| ### Withdraw              |         |                      |                |
| Emit when user withdraws. |         |                      |                |

#### Params:

| Param    | Type    |        Indexed       | Description     |
| -------- | ------- | :------------------: | --------------- |
| `by`     | address | :white\_check\_mark: | Withdraw user   |
| `from`   | address | :white\_check\_mark: | From user       |
| `amount` | uint256 | :white\_check\_mark: | Withdraw amount |
