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


---

# 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.rei.network/developer/system-contracts/fee.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.
