> For the complete documentation index, see [llms.txt](https://docs.ionprotocol.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.ionprotocol.io/devs/smart-contract-architecture/token/rewardtoken.md).

# 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;
}
```
