# Comptroller

@author Compound -> Union Finance @title Comptroller @dev For the time being, only the reward calculation of a single token is supported, and the contract needs to be revised after determining the reward calculation scheme of multiple tokens

### Info

```solidity
struct Info {
  uint256 updatedBlock;
  uint256 inflationIndex;
  uint256 accrued;
}
```

### UserManagerState

```solidity
struct UserManagerState {
  uint256 totalFrozen;
  uint256 totalStaked;
}
```

### UserManagerAccountState

```solidity
struct UserManagerAccountState {
  uint256 totalStaked;
  uint256 totalFrozen;
  uint256 totalLocked;
  uint256 pastBlocksFrozenCoinAge;
  bool isMember;
}
```

### INIT\_INFLATION\_INDEX

```solidity
uint256 INIT_INFLATION_INDEX
```

*Initial inflation index*

### nonMemberRatio

```solidity
uint256 nonMemberRatio
```

*Non member reward multiplier rate (75%)*

### memberRatio

```solidity
uint256 memberRatio
```

*Member reward multiplier rate (100%)*

### halfDecayPoint

```solidity
uint256 halfDecayPoint
```

*Half decay point to reduce rewards at*

### gInflationIndex

```solidity
uint256 gInflationIndex
```

*store the latest inflation index*

### gLastUpdatedBlock

```solidity
uint256 gLastUpdatedBlock
```

*block number when updating the inflation index*

### unionToken

```solidity
contract IERC20Upgradeable unionToken
```

*$UNION token contract*

### marketRegistry

```solidity
contract IMarketRegistry marketRegistry
```

*The market registry contract*

### users

```solidity
mapping(address => mapping(address => struct Comptroller.Info)) users
```

*Map account to token to Info*

### LogWithdrawRewards

```solidity
event LogWithdrawRewards(address account, uint256 amount)
```

@dev Withdraw rewards event @param account The staker's address @param amount The amount of Union tokens to withdraw

### SenderNotUserManager

```solidity
error SenderNotUserManager()
```

### NotZero

```solidity
error NotZero()
```

### FrozenCoinAge

```solidity
error FrozenCoinAge()
```

### InflationIndexTooSmall

```solidity
error InflationIndexTooSmall()
```

### \_\_Comptroller\_init

```solidity
function __Comptroller_init(address unionToken_, address marketRegistry_, uint256 _halfDecayPoint) public
```

### onlyUserManager

```solidity
modifier onlyUserManager(address token)
```

### setHalfDecayPoint

```solidity
function setHalfDecayPoint(uint256 point) public
```

*Set the half decay point*

### getRewardsMultiplier

```solidity
function getRewardsMultiplier(address account, address token) external view returns (uint256)
```

@dev Get the reward multipier based on the account status @param account Account address @param token ERC20 token address @return Multiplier number (in wei)

### calculateRewardsByBlocks

```solidity
function calculateRewardsByBlocks(address account, address token, uint256 futureBlocks) public view returns (uint256)
```

@dev Calculate unclaimed rewards based on blocks @param account User address @param token Staking token address @param futureBlocks Number of blocks in the future @return Unclaimed rewards

### calculateRewards

```solidity
function calculateRewards(address account, address token) external view returns (uint256)
```

@dev Calculate currently unclaimed rewards @param account Account address @param token Staking token address @return Unclaimed rewards

### inflationPerBlock

```solidity
function inflationPerBlock(uint256 effectiveTotalStake) public view returns (uint256)
```

@dev Calculate inflation per block @param effectiveTotalStake Effective total stake @return Inflation amount, div totalSupply is the inflation rate

### withdrawRewards

```solidity
function withdrawRewards(address account, address token) external returns (uint256)
```

@dev Withdraw rewards @param token Staking token address @return Amount of rewards

### updateTotalStaked

```solidity
function updateTotalStaked(address token, uint256 totalStaked) external returns (bool)
```

@dev When total staked change update inflation index @param totalStaked totalStaked amount @return Whether succeeded

### \_getUserManagerState

```solidity
function _getUserManagerState(contract IUserManager userManager) internal view returns (struct Comptroller.UserManagerState)
```

*Get UserManager global state values*

### \_getUserInfoView

```solidity
function _getUserInfoView(contract IUserManager userManager, address account, address token, uint256 futureBlocks) internal view returns (struct Comptroller.UserManagerAccountState, struct Comptroller.Info, uint256)
```

*Get UserManager user specific state (view function does NOT update UserManage state)*

#### Parameters

| Name         | Type                  | Description          |
| ------------ | --------------------- | -------------------- |
| userManager  | contract IUserManager | UserManager contract |
| account      | address               | Account address      |
| token        | address               | Token address        |
| futureBlocks | uint256               | Blocks in the future |

### \_getUserInfo

```solidity
function _getUserInfo(contract IUserManager userManager, address account, address token, uint256 futureBlocks) internal returns (struct Comptroller.UserManagerAccountState, struct Comptroller.Info, uint256)
```

*Get UserManager user specific state (function does update UserManage state)*

#### Parameters

| Name         | Type                  | Description          |
| ------------ | --------------------- | -------------------- |
| userManager  | contract IUserManager | UserManager contract |
| account      | address               | Account address      |
| token        | address               | Token address        |
| futureBlocks | uint256               | Blocks in the future |

### \_calculateRewardsByBlocks

```solidity
function _calculateRewardsByBlocks(address account, address token, uint256 pastBlocks, struct Comptroller.Info userInfo, struct Comptroller.UserManagerState userManagerState, struct Comptroller.UserManagerAccountState userManagerAccountState) internal view returns (uint256)
```

@dev Calculate currently unclaimed rewards @param account Account address @param token Staking token address @param userManagerState User manager global state @return Unclaimed rewards

### \_getInflationIndexNew

```solidity
function _getInflationIndexNew(uint256 totalStaked_, uint256 blockDelta) internal view returns (uint256)
```

@dev Calculate new inflation index based on # of blocks @param totalStaked\_ Number of total staked tokens in the system @param blockDelta Number of blocks @return New inflation index

### \_calculateRewards

```solidity
function _calculateRewards(address account, address token, uint256 totalStaked, uint256 userStaked, uint256 frozenCoinAge, uint256 pastBlocks, uint256 inflationIndex) internal view returns (uint256)
```

### \_getUserManager

```solidity
function _getUserManager(address token) internal view returns (contract IUserManager)
```

*Get the UserManager contract. First try and load it from state if it has been previously saved and fallback to loading it from the marketRegistry*

#### Return Values

| Name | Type                  | Description          |
| ---- | --------------------- | -------------------- |
| \[0] | contract IUserManager | userManager contract |

### \_inflationPerBlock

```solidity
function _inflationPerBlock(uint256 effectiveTotalStake) internal view returns (uint256)
```

@dev See Comptroller.inflationPerBlock

### \_lookup

```solidity
function _lookup(uint256 index) internal pure returns (uint256)
```

### \_getInflationIndex

```solidity
function _getInflationIndex(uint256 effectiveAmount, uint256 inflationIndex, uint256 blockDelta) internal view returns (uint256)
```

### \_getRewardsMultiplier

```solidity
function _getRewardsMultiplier(uint256 userStaked, uint256 lockedStake, uint256 totalFrozen_, bool isMember_) internal pure returns (uint256)
```


---

# 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.union.finance/developers/core/comptroller.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.
