# RewardToken

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

**Inherits:** ContextUpgradeable, AccessControlDefaultAdminRulesUpgradeable, IERC20Errors, IERC20Metadata

The supply-side reward accounting portion of the protocol. A lender's balance is measured in two parts: a static balance and a dynamic "supply factor". Their true balance is the product of the two values. The dynamic portion is then able to be used to distribute interest accrued to the lender.

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

#### [ION](broken://pages/qDMAbQcPMqbn1CGoXurJ) <a href="#ion" id="ion"></a>

```
bytes32 public constant ION = keccak256("ION");
```

#### [RewardTokenStorageLocation](broken://pages/qDMAbQcPMqbn1CGoXurJ) <a href="#rewardtokenstoragelocation" id="rewardtokenstoragelocation"></a>

```
bytes32 private constant RewardTokenStorageLocation = 0xdb3a0d63a7808d7d0422c40bb62354f42bff7602a547c329c1453dbcbeef4900;
```

#### [EIP712\_REVISION](broken://pages/qDMAbQcPMqbn1CGoXurJ) <a href="#eip712_revision" id="eip712_revision"></a>

```
bytes private constant EIP712_REVISION = bytes("1");
```

#### [EIP712\_DOMAIN](broken://pages/qDMAbQcPMqbn1CGoXurJ) <a href="#eip712_domain" id="eip712_domain"></a>

```
bytes32 private constant EIP712_DOMAIN =
    keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)");
```

#### [PERMIT\_TYPEHASH](broken://pages/qDMAbQcPMqbn1CGoXurJ) <a href="#permit_typehash" id="permit_typehash"></a>

```
bytes32 public constant PERMIT_TYPEHASH =
    keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
```

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

#### [\_getRewardTokenStorage](broken://pages/qDMAbQcPMqbn1CGoXurJ) <a href="#getrewardtokenstorage" id="getrewardtokenstorage"></a>

```
function _getRewardTokenStorage() private pure returns (RewardTokenStorage storage $);
```

#### [\_initialize](broken://pages/qDMAbQcPMqbn1CGoXurJ) <a href="#initialize" id="initialize"></a>

```
function _initialize(
    address _underlying,
    address _treasury,
    uint8 decimals_,
    string memory name_,
    string memory symbol_
)
    internal
    onlyInitializing;
```

#### [\_burn](broken://pages/qDMAbQcPMqbn1CGoXurJ) <a href="#burn" id="burn"></a>

```
function _burn(address user, address receiverOfUnderlying, uint256 amount) internal returns (uint256);
```

**Parameters**

| Name                   | Type      | Description                  |
| ---------------------- | --------- | ---------------------------- |
| `user`                 | `address` | to burn tokens from          |
| `receiverOfUnderlying` | `address` | to send underlying tokens to |
| `amount`               | `uint256` | to burn                      |

#### [\_burnNormalized](broken://pages/qDMAbQcPMqbn1CGoXurJ) <a href="#burnnormalized" id="burnnormalized"></a>

```
function _burnNormalized(address account, uint256 amount) private;
```

**Parameters**

| Name      | Type      | Description                  |
| --------- | --------- | ---------------------------- |
| `account` | `address` | to decrease balance of       |
| `amount`  | `uint256` | of normalized tokens to burn |

#### [\_mint](broken://pages/qDMAbQcPMqbn1CGoXurJ) <a href="#mint" id="mint"></a>

```
function _mint(address user, address senderOfUnderlying, uint256 amount) internal returns (uint256);
```

**Parameters**

| Name                 | Type      | Description                                |
| -------------------- | --------- | ------------------------------------------ |
| `user`               | `address` | to mint tokens to                          |
| `senderOfUnderlying` | `address` | address to transfer underlying tokens from |
| `amount`             | `uint256` | of reward tokens to mint                   |

#### [\_mintNormalized](broken://pages/qDMAbQcPMqbn1CGoXurJ) <a href="#mintnormalized" id="mintnormalized"></a>

```
function _mintNormalized(address account, uint256 amount) private;
```

**Parameters**

| Name      | Type      | Description                  |
| --------- | --------- | ---------------------------- |
| `account` | `address` | to increase balance of       |
| `amount`  | `uint256` | of normalized tokens to mint |

#### [\_mintToTreasury](broken://pages/qDMAbQcPMqbn1CGoXurJ) <a href="#minttotreasury" id="minttotreasury"></a>

*This function does not perform any rounding checks.*

```
function _mintToTreasury(uint256 amount) internal;
```

**Parameters**

| Name     | Type      | Description                   |
| -------- | --------- | ----------------------------- |
| `amount` | `uint256` | of tokens to mint to treasury |

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

```
function approve(address spender, uint256 amount) external returns (bool);
```

**Parameters**

| Name      | Type      | Description |
| --------- | --------- | ----------- |
| `spender` | `address` | to approve  |
| `amount`  | `uint256` | to approve  |

#### [\_approve](broken://pages/qDMAbQcPMqbn1CGoXurJ) <a href="#approve" id="approve"></a>

```
function _approve(address owner, address spender, uint256 amount) internal;
```

**Parameters**

| Name      | Type      | Description |
| --------- | --------- | ----------- |
| `owner`   | `address` | of tokens   |
| `spender` | `address` | of tokens   |
| `amount`  | `uint256` | to approve  |

#### [\_spendAllowance](broken://pages/qDMAbQcPMqbn1CGoXurJ) <a href="#spendallowance" id="spendallowance"></a>

*Spends allowance*

```
function _spendAllowance(address owner, address spender, uint256 amount) private;
```

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

*Can only be called by owner of the tokens*

```
function transfer(address to, uint256 amount) public returns (bool);
```

**Parameters**

| Name     | Type      | Description |
| -------- | --------- | ----------- |
| `to`     | `address` | transfer to |
| `amount` | `uint256` | to transfer |

#### [transferFrom](broken://pages/qDMAbQcPMqbn1CGoXurJ) <a href="#transferfrom" id="transferfrom"></a>

*For use with `approve()`*

```
function transferFrom(address from, address to, uint256 amount) public returns (bool);
```

**Parameters**

| Name     | Type      | Description      |
| -------- | --------- | ---------------- |
| `from`   | `address` | to transfer from |
| `to`     | `address` | to transfer to   |
| `amount` | `uint256` | to transfer      |

#### [\_transfer](broken://pages/qDMAbQcPMqbn1CGoXurJ) <a href="#transfer" id="transfer"></a>

```
function _transfer(address from, address to, uint256 amount) private;
```

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

*implements the permit function as for <https://github.com/ethereum/EIPs/blob/8a34d644aacf0f9f8f00815307fd7dd5da07655f/EIPS/eip-2612.md>*

```
function permit(
    address owner,
    address spender,
    uint256 value,
    uint256 deadline,
    uint8 v,
    bytes32 r,
    bytes32 s
)
    public
    virtual;
```

**Parameters**

| Name       | Type      | Description                                                |
| ---------- | --------- | ---------------------------------------------------------- |
| `owner`    | `address` | The owner of the funds                                     |
| `spender`  | `address` | The spender                                                |
| `value`    | `uint256` | The amount                                                 |
| `deadline` | `uint256` | The deadline timestamp, type(uint256).max for max deadline |
| `v`        | `uint8`   | Signature param                                            |
| `r`        | `bytes32` | Signature param                                            |
| `s`        | `bytes32` | Signature param                                            |

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

*Returns current allowance*

```
function allowance(address owner, address spender) public view returns (uint256);
```

**Parameters**

| Name      | Type      | Description |
| --------- | --------- | ----------- |
| `owner`   | `address` | of tokens   |
| `spender` | `address` | of tokens   |

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

```
function nonces(address owner) public view returns (uint256);
```

#### [\_useNonce](broken://pages/qDMAbQcPMqbn1CGoXurJ) <a href="#usenonce" id="usenonce"></a>

*Consumes a nonce. Returns the current value and increments nonce.*

```
function _useNonce(address owner) internal virtual returns (uint256);
```

#### [\_setSupplyFactor](broken://pages/qDMAbQcPMqbn1CGoXurJ) <a href="#setsupplyfactor" id="setsupplyfactor"></a>

```
function _setSupplyFactor(uint256 newSupplyFactor) internal;
```

#### [updateTreasury](broken://pages/qDMAbQcPMqbn1CGoXurJ) <a href="#updatetreasury" id="updatetreasury"></a>

*Updates the treasury address*

```
function updateTreasury(address newTreasury) external onlyRole(ION);
```

**Parameters**

| Name          | Type      | Description             |
| ------------- | --------- | ----------------------- |
| `newTreasury` | `address` | address of new treasury |

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

*Address of underlying asset*

```
function underlying() public view returns (IERC20);
```

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

*Decimals of the position asset*

```
function decimals() public view returns (uint8);
```

#### [balanceOf](broken://pages/qDMAbQcPMqbn1CGoXurJ) <a href="#balanceof" id="balanceof"></a>

*Current claim of the underlying token inclusive of interest to be accrued.*

```
function balanceOf(address user) public view returns (uint256);
```

**Parameters**

| Name   | Type      | Description       |
| ------ | --------- | ----------------- |
| `user` | `address` | to get balance of |

#### [balanceOfUnaccrued](broken://pages/qDMAbQcPMqbn1CGoXurJ) <a href="#balanceofunaccrued" id="balanceofunaccrued"></a>

*Current claim of the underlying token without accounting for interest to be accrued.*

```
function balanceOfUnaccrued(address user) public view returns (uint256);
```

#### [normalizedBalanceOf](broken://pages/qDMAbQcPMqbn1CGoXurJ) <a href="#normalizedbalanceof" id="normalizedbalanceof"></a>

*Accounting is done in normalized balances*

```
function normalizedBalanceOf(address user) external view returns (uint256);
```

**Parameters**

| Name   | Type      | Description                  |
| ------ | --------- | ---------------------------- |
| `user` | `address` | to get normalized balance of |

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

*Name of the position asset*

```
function name() public view returns (string memory);
```

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

*Symbol of the position asset*

```
function symbol() public view returns (string memory);
```

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

*Current treasury address*

```
function treasury() public view returns (address);
```

#### [totalSupplyUnaccrued](broken://pages/qDMAbQcPMqbn1CGoXurJ) <a href="#totalsupplyunaccrued" id="totalsupplyunaccrued"></a>

*Total claim of the underlying asset belonging to lenders not inclusive of the new interest to be accrued.*

```
function totalSupplyUnaccrued() public view returns (uint256);
```

#### [totalSupply](broken://pages/qDMAbQcPMqbn1CGoXurJ) <a href="#totalsupply" id="totalsupply"></a>

*Total claim of the underlying asset belonging to lender inclusive of the new interest to be accrued.*

```
function totalSupply() public view returns (uint256);
```

#### [normalizedTotalSupplyUnaccrued](broken://pages/qDMAbQcPMqbn1CGoXurJ) <a href="#normalizedtotalsupplyunaccrued" id="normalizedtotalsupplyunaccrued"></a>

```
function normalizedTotalSupplyUnaccrued() public view returns (uint256);
```

#### [normalizedTotalSupply](broken://pages/qDMAbQcPMqbn1CGoXurJ) <a href="#normalizedtotalsupply" id="normalizedtotalsupply"></a>

*Normalized total supply.*

```
function normalizedTotalSupply() public view returns (uint256);
```

#### [supplyFactorUnaccrued](broken://pages/qDMAbQcPMqbn1CGoXurJ) <a href="#supplyfactorunaccrued" id="supplyfactorunaccrued"></a>

```
function supplyFactorUnaccrued() public view returns (uint256);
```

#### [supplyFactor](broken://pages/qDMAbQcPMqbn1CGoXurJ) <a href="#supplyfactor" id="supplyfactor"></a>

*Current supply factor*

```
function supplyFactor() public view returns (uint256);
```

#### [calculateRewardAndDebtDistribution](broken://pages/qDMAbQcPMqbn1CGoXurJ) <a href="#calculaterewardanddebtdistribution" id="calculaterewardanddebtdistribution"></a>

```
function calculateRewardAndDebtDistribution()
    public
    view
    virtual
    returns (
        uint256 totalSupplyFactorIncrease,
        uint256 totalTreasuryMintAmount,
        uint104[] memory rateIncreases,
        uint256 totalDebtIncrease,
        uint48[] memory timestampIncreases
    );
```

### [Events](broken://pages/qDMAbQcPMqbn1CGoXurJ) <a href="#events" id="events"></a>

#### [MintToTreasury](broken://pages/qDMAbQcPMqbn1CGoXurJ) <a href="#minttotreasury" id="minttotreasury"></a>

```
event MintToTreasury(address indexed treasury, uint256 amount, uint256 supplyFactor);
```

#### [TreasuryUpdate](broken://pages/qDMAbQcPMqbn1CGoXurJ) <a href="#treasuryupdate" id="treasuryupdate"></a>

```
event TreasuryUpdate(address treasury);
```

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

#### [InvalidBurnAmount](broken://pages/qDMAbQcPMqbn1CGoXurJ) <a href="#invalidburnamount" id="invalidburnamount"></a>

*Cannot burn amount whose normalized value is less than zero.*

```
error InvalidBurnAmount();
```

#### [InvalidMintAmount](broken://pages/qDMAbQcPMqbn1CGoXurJ) <a href="#invalidmintamount" id="invalidmintamount"></a>

*Cannot mint amount whose normalized value is less than zero.*

```
error InvalidMintAmount();
```

#### [InvalidUnderlyingAddress](broken://pages/qDMAbQcPMqbn1CGoXurJ) <a href="#invalidunderlyingaddress" id="invalidunderlyingaddress"></a>

```
error InvalidUnderlyingAddress();
```

#### [InvalidTreasuryAddress](broken://pages/qDMAbQcPMqbn1CGoXurJ) <a href="#invalidtreasuryaddress" id="invalidtreasuryaddress"></a>

```
error InvalidTreasuryAddress();
```

#### [InvalidSender](broken://pages/qDMAbQcPMqbn1CGoXurJ) <a href="#invalidsender" id="invalidsender"></a>

*Indicates a failure with the token `sender`. Used in transfers.*

```
error InvalidSender(address sender);
```

**Parameters**

| Name     | Type      | Description                                 |
| -------- | --------- | ------------------------------------------- |
| `sender` | `address` | Address whose tokens are being transferred. |

#### [InvalidReceiver](broken://pages/qDMAbQcPMqbn1CGoXurJ) <a href="#invalidreceiver" id="invalidreceiver"></a>

*Indicates a failure with the token `receiver`. Used in transfers.*

```
error InvalidReceiver(address receiver);
```

**Parameters**

| Name       | Type      | Description                                    |
| ---------- | --------- | ---------------------------------------------- |
| `receiver` | `address` | Address to which tokens are being transferred. |

#### [SelfTransfer](broken://pages/qDMAbQcPMqbn1CGoXurJ) <a href="#selftransfer" id="selftransfer"></a>

*Cannot transfer the token to address `self`*

```
error SelfTransfer(address self);
```

#### [ERC2612ExpiredSignature](broken://pages/qDMAbQcPMqbn1CGoXurJ) <a href="#erc2612expiredsignature" id="erc2612expiredsignature"></a>

*Signature cannot be submitted after `deadline` has passed. Designed to mitigate replay attacks.*

```
error ERC2612ExpiredSignature(uint256 deadline);
```

#### [ERC2612InvalidSigner](broken://pages/qDMAbQcPMqbn1CGoXurJ) <a href="#erc2612invalidsigner" id="erc2612invalidsigner"></a>

*`signer` does not match the `owner` of the tokens. `owner` did not approve.*

```
error ERC2612InvalidSigner(address signer, address owner);
```

#### [InsufficientBalance](broken://pages/qDMAbQcPMqbn1CGoXurJ) <a href="#insufficientbalance" id="insufficientbalance"></a>

*Indicates an error related to the current `balance` of a `sender`. Used in transfers.*

```
error InsufficientBalance(address account, uint256 balance, uint256 needed);
```

**Parameters**

| Name      | Type      | Description                                    |
| --------- | --------- | ---------------------------------------------- |
| `account` | `address` | Address whose token balance is insufficient.   |
| `balance` | `uint256` | Current balance for the interacting account.   |
| `needed`  | `uint256` | Minimum amount required to perform a transfer. |

### [Structs](broken://pages/qDMAbQcPMqbn1CGoXurJ) <a href="#structs" id="structs"></a>

#### [RewardTokenStorage](broken://pages/qDMAbQcPMqbn1CGoXurJ) <a href="#rewardtokenstorage" id="rewardtokenstorage"></a>

```
struct RewardTokenStorage {
    IERC20 underlying;
    uint8 decimals;
    string name;
    string symbol;
    address treasury;
    uint256 normalizedTotalSupply;
    uint256 supplyFactor;
    mapping(address account => uint256) _normalizedBalances;
    mapping(address account => mapping(address spender => uint256)) _allowances;
    mapping(address account => uint256) nonces;
}
```


---

# 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/token/rewardtoken.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.
