# UserManager

*Manages the Union members stake and vouches.*

### Vouch

```solidity
struct Vouch {
  address staker;
  uint96 trust;
  uint96 locked;
  uint64 lastUpdated;
}
```

### Staker

```solidity
struct Staker {
  bool isMember;
  uint96 stakedAmount;
  uint96 locked;
}
```

### Index

```solidity
struct Index {
  bool isSet;
  uint128 idx;
}
```

### Vouchee

```solidity
struct Vouchee {
  address borrower;
  uint96 voucherIndex;
}
```

### maxStakeAmount

```solidity
uint96 maxStakeAmount
```

@dev Max amount that can be staked of the staking token

### stakingToken

```solidity
address stakingToken
```

@dev The staking token that is staked in the comptroller

### unionToken

```solidity
address unionToken
```

@dev Address of the UNION token contract

### assetManager

```solidity
address assetManager
```

@dev Address of the asset manager contract

### uToken

```solidity
contract IUToken uToken
```

@dev uToken contract

### comptroller

```solidity
contract IComptroller comptroller
```

@dev Comptroller contract

### effectiveCount

```solidity
uint256 effectiveCount
```

*Number of vouches needed to become a member*

### newMemberFee

```solidity
uint256 newMemberFee
```

@dev New member fee

### totalStaked

```solidity
uint256 totalStaked
```

@dev Total amount of staked staked token

### totalFrozen

```solidity
uint256 totalFrozen
```

@dev Total amount of stake frozen

### maxOverdueBlocks

```solidity
uint256 maxOverdueBlocks
```

@dev Max blocks can be overdue for

### maxVouchers

```solidity
uint256 maxVouchers
```

*Max voucher limit*

### stakers

```solidity
mapping(address => struct UserManager.Staker) stakers
```

@dev Union Stakers

### vouchers

```solidity
mapping(address => struct UserManager.Vouch[]) vouchers
```

@dev Staker (borrower) mapped to recieved vouches (staker)

### voucherIndexes

```solidity
mapping(address => mapping(address => struct UserManager.Index)) voucherIndexes
```

*Borrower mapped to Staker mapped to index in vouchers array*

### vouchees

```solidity
mapping(address => struct UserManager.Vouchee[]) vouchees
```

@dev Staker (staker) mapped to vouches given (borrower)

### voucheeIndexes

```solidity
mapping(address => mapping(address => struct UserManager.Index)) voucheeIndexes
```

*Borrower mapped to Staker mapped to index in vochee array*

### memberFrozen

```solidity
mapping(address => uint256) memberFrozen
```

*Stakers frozen amounts*

### AuthFailed

```solidity
error AuthFailed()
```

### ErrorSelfVouching

```solidity
error ErrorSelfVouching()
```

### TrustAmountLtLocked

```solidity
error TrustAmountLtLocked()
```

### NoExistingMember

```solidity
error NoExistingMember()
```

### NotEnoughStakers

```solidity
error NotEnoughStakers()
```

### StakeLimitReached

```solidity
error StakeLimitReached()
```

### AssetManagerDepositFailed

```solidity
error AssetManagerDepositFailed()
```

### AssetManagerWithdrawFailed

```solidity
error AssetManagerWithdrawFailed()
```

### InsufficientBalance

```solidity
error InsufficientBalance()
```

### LockedStakeNonZero

```solidity
error LockedStakeNonZero()
```

### NotOverdue

```solidity
error NotOverdue()
```

### ExceedsLocked

```solidity
error ExceedsLocked()
```

### AmountZero

```solidity
error AmountZero()
```

### LockedRemaining

```solidity
error LockedRemaining()
```

### VoucherNotFound

```solidity
error VoucherNotFound()
```

### VouchWhenOverdue

```solidity
error VouchWhenOverdue()
```

### MaxVouchees

```solidity
error MaxVouchees()
```

### InvalidParams

```solidity
error InvalidParams()
```

### LogAddMember

```solidity
event LogAddMember(address member)
```

@dev Add new member event @param member New member address

### LogUpdateTrust

```solidity
event LogUpdateTrust(address staker, address borrower, uint256 trustAmount)
```

@dev Update vouch for existing member event @param staker Trustee address @param borrower The address gets vouched for @param trustAmount Vouch amount

### LogRegisterMember

```solidity
event LogRegisterMember(address account, address borrower)
```

@dev New member application event @param account New member's voucher address @param borrower New member address

### LogCancelVouch

```solidity
event LogCancelVouch(address account, address borrower)
```

@dev Cancel vouching for other member event @param account New member's voucher address @param borrower The address gets vouched for

### LogStake

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

@dev Stake event @param account The staker's address @param amount The amount of tokens to stake

### LogUnstake

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

@dev Unstake event @param account The staker's address @param amount The amount of tokens to unstake

### LogDebtWriteOff

```solidity
event LogDebtWriteOff(address staker, address borrower, uint256 amount)
```

@dev DebtWriteOff event @param staker The staker's address @param borrower The borrower's address @param amount The amount of write off

### LogSetUToken

```solidity
event LogSetUToken(address uToken)
```

@dev set utoken address @param uToken new uToken address

### LogSetNewMemberFee

```solidity
event LogSetNewMemberFee(uint256 oldMemberFee, uint256 newMemberFee)
```

@dev set new member fee @param oldMemberFee old member fee @param newMemberFee new member fee

### LogSetMaxStakeAmount

```solidity
event LogSetMaxStakeAmount(uint256 oldMaxStakeAmount, uint256 newMaxStakeAmount)
```

@dev set max stake amount @param oldMaxStakeAmount Old amount @param newMaxStakeAmount New amount

### LogSetMaxOverdueBlocks

```solidity
event LogSetMaxOverdueBlocks(uint256 oldMaxOverdueBlocks, uint256 newMaxOverdueBlocks)
```

@dev set max overdue blocks @param oldMaxOverdueBlocks Old value @param newMaxOverdueBlocks New value

### LogSetEffectiveCount

```solidity
event LogSetEffectiveCount(uint256 oldEffectiveCount, uint256 newEffectiveCount)
```

@dev set effective count @param oldEffectiveCount Old value @param newEffectiveCount New value

### LogSetMaxVouchers

```solidity
event LogSetMaxVouchers(uint256 maxVouchers)
```

*Set max voucher*

#### Parameters

| Name        | Type    | Description           |
| ----------- | ------- | --------------------- |
| maxVouchers | uint256 | new max voucher limit |

### \_\_UserManager\_init

```solidity
function __UserManager_init(address assetManager_, address unionToken_, address stakingToken_, address comptroller_, address admin_, uint256 maxOverdueBlocks_, uint256 effectiveCount_, uint256 maxVouchers_) public
```

### onlyMember

```solidity
modifier onlyMember(address account)
```

### onlyMarket

```solidity
modifier onlyMarket()
```

### onlyComptroller

```solidity
modifier onlyComptroller()
```

### setMaxStakeAmount

```solidity
function setMaxStakeAmount(uint96 maxStakeAmount_) external
```

*Set the max amount that a user can stake Emits {LogSetMaxStakeAmount} event*

#### Parameters

| Name             | Type   | Description          |
| ---------------- | ------ | -------------------- |
| maxStakeAmount\_ | uint96 | The max stake amount |

### setUToken

```solidity
function setUToken(address uToken_) external
```

*set the UToken contract address Emits {LogSetUToken} event*

#### Parameters

| Name     | Type    | Description             |
| -------- | ------- | ----------------------- |
| uToken\_ | address | UToken contract address |

### setNewMemberFee

```solidity
function setNewMemberFee(uint256 amount) external
```

*set New Member fee The amount of UNION an account must burn to become a member Emits {LogSetNewMemberFee} event*

#### Parameters

| Name   | Type    | Description           |
| ------ | ------- | --------------------- |
| amount | uint256 | New member fee amount |

### setMaxOverdueBlocks

```solidity
function setMaxOverdueBlocks(uint256 _maxOverdueBlocks) external
```

*set New max overdue blocks Emits {LogSetMaxOverdueBlocks} event*

#### Parameters

| Name               | Type    | Description                |
| ------------------ | ------- | -------------------------- |
| \_maxOverdueBlocks | uint256 | New maxOverdueBlocks value |

### setEffectiveCount

```solidity
function setEffectiveCount(uint256 _effectiveCount) external
```

*set New effective count this is the number of vouches an account needs in order to register as a member Emits {LogSetEffectiveCount} event*

#### Parameters

| Name             | Type    | Description              |
| ---------------- | ------- | ------------------------ |
| \_effectiveCount | uint256 | New effectiveCount value |

### setMaxVouchers

```solidity
function setMaxVouchers(uint256 _maxVouchers) external
```

### checkIsMember

```solidity
function checkIsMember(address account) public view returns (bool)
```

@dev Check if the account is a valid member @param account Member address @return Address whether is member

### getCreditLimit

```solidity
function getCreditLimit(address borrower) external view returns (uint256 total)
```

@dev Get the member's available credit limit @dev IMPORTANT: This function can take up a tonne of gas as the vouchers\[address] array grows in size. the maxVoucher limit will ensure this function can always run within a single block but it is intended only to be used as a view function called from a UI @param borrower Member address @return total Credit line amount

### getVoucherCount

```solidity
function getVoucherCount(address borrower) external view returns (uint256)
```

@dev Get the count of vouchers Vouchers are addresses that this borrower is recieving a vouch from. @param borrower Address of borrower

### getVoucheeCount

```solidity
function getVoucheeCount(address staker) external view returns (uint256)
```

@dev Get the count of vouchees Voucheers are addresses that this staker is vouching for @param staker Address of staker

### getStakerBalance

```solidity
function getStakerBalance(address account) external view returns (uint256)
```

@dev Get the user's deposited stake amount @param account Member address @return Deposited stake amount

### getFrozenInfo

```solidity
function getFrozenInfo(address staker, uint256 pastBlocks) public view returns (uint256 memberTotalFrozen, uint256 memberFrozenCoinAge)
```

@dev Get frozen coin age @param staker Address of staker @param pastBlocks Number of blocks past to calculate coin age from coin age = min(block.number - lastUpdated, pastBlocks) \* amount

### getTotalLockedStake

```solidity
function getTotalLockedStake(address staker) external view returns (uint256)
```

@dev Get Total locked stake @param staker Staker address

### getLockedStake

```solidity
function getLockedStake(address staker, address borrower) external view returns (uint256)
```

@dev Get staker locked stake for a borrower @param staker Staker address @param borrower Borrower address @return LockedStake

### getVouchingAmount

```solidity
function getVouchingAmount(address _staker, address borrower) external view returns (uint256)
```

@dev Get vouching amount @param \_staker Staker address @param borrower Borrower address

### addMember

```solidity
function addMember(address account) external
```

@dev Manually add union members and bypass all the requirements of `registerMember` Only accepts calls from the admin Emit {LogAddMember} event @param account Member address

### updateTrust

```solidity
function updateTrust(address borrower, uint96 trustAmount) external
```

@dev Update the trust amount for exisitng members. @dev Trust is the amount of the underlying token you would in theory be happy to lend to another member. Vouch is derived from trust and stake. Vouch is the minimum of trust and staked amount. Emits {LogUpdateTrust} event @param borrower Account address @param trustAmount Trust amount

### cancelVouch

```solidity
function cancelVouch(address staker, address borrower) public
```

@dev Remove voucher for memeber Can be called by either the borrower or the staker. It will remove the voucher from the voucher array by replacing it with the last item of the array and reseting the array size to -1 by poping off the last item Only callable by a member when the contract is not paused Emit {LogCancelVouch} event @param staker Staker address @param borrower borrower address

### registerMemberWithPermit

```solidity
function registerMemberWithPermit(address newMember, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external
```

@notice Register a a member using a signed permit @dev See registerMember @param newMember New member address @param value Amount approved by permit @param deadline Timestamp for when the permit expires @param v secp256k1 signature part @param r secp256k1 signature part @param s secp256k1 signature part

### registerMember

```solidity
function registerMember(address newMember) public virtual
```

@notice Register a a member, and burn an application fees @dev In order to register as a member an address must be recieving x amount of vouches greater than 0 from stakers. x is defined by `effectiveCount` Emits {LogRegisterMember} event @param newMember New member address

### stake

```solidity
function stake(uint96 amount) public
```

@notice Stake staking tokens @dev Stake is used to underwrite loans and becomes locked if a member a staker has vouched for borrows against it. Stake also earns rewards from the comptroller Emits a {LogStake} event. @param amount Amount to stake

### unstake

```solidity
function unstake(uint96 amount) external
```

@notice Unstake staking token @dev Tokens can only be unstaked if they are not locked. ie a vouchee is not borrowing against them. Emits {LogUnstake} event @param amount Amount to unstake

### withdrawRewards

```solidity
function withdrawRewards() external
```

@dev collect staker rewards from the comptroller

### debtWriteOff

```solidity
function debtWriteOff(address staker, address borrower, uint96 amount) external
```

@notice Write off a borrowers debt @dev Used the stakers locked stake to write off the loan, transfering the Stake to the AssetManager and adjusting balances in the AssetManager and the UToken to repay the principal @dev Emits {LogDebtWriteOff} event @param borrower address of borrower @param amount amount to writeoff

### updateLocked

```solidity
function updateLocked(address borrower, uint96 amount, bool lock) external
```

@notice Borrowing from the market @dev Locks/Unlocks the borrowers stakers staked amounts in a first in First out order. Meaning the members that vouched for this borrower first will be the first members to get their stake locked or unlocked following a borrow or repayment. @param borrower The address of the borrower @param amount Lock/Unlock amount @param lock If the amount is being locked or unlocked

### \_updateFrozen

```solidity
function _updateFrozen(address staker, uint256 pastBlocks) internal returns (uint256, uint256)
```

*Update the frozen info for a single staker*

#### Parameters

| Name       | Type    | Description     |
| ---------- | ------- | --------------- |
| staker     | address | Staker address  |
| pastBlocks | uint256 | The past blocks |

#### Return Values

| Name | Type    | Description                                                                                                     |
| ---- | ------- | --------------------------------------------------------------------------------------------------------------- |
| \[0] | uint256 | memberTotalFrozen Total frozen amount for this staker memberFrozenCoinAge Total frozen coin age for this staker |
| \[1] | uint256 |                                                                                                                 |

### updateFrozenInfo

```solidity
function updateFrozenInfo(address staker, uint256 pastBlocks) external returns (uint256, uint256)
```

*Update the frozen info by the comptroller*

#### Parameters

| Name       | Type    | Description     |
| ---------- | ------- | --------------- |
| staker     | address | Staker address  |
| pastBlocks | uint256 | The past blocks |

#### Return Values

| Name | Type    | Description                                                                                                     |
| ---- | ------- | --------------------------------------------------------------------------------------------------------------- |
| \[0] | uint256 | memberTotalFrozen Total frozen amount for this staker memberFrozenCoinAge Total frozen coin age for this staker |
| \[1] | uint256 |                                                                                                                 |

### batchUpdateFrozenInfo

```solidity
function batchUpdateFrozenInfo(address[] stakers) external
```

*Update the frozen info for external scripts*

#### Parameters

| Name    | Type       | Description     |
| ------- | ---------- | --------------- |
| stakers | address\[] | Stakers address |

### \_min

```solidity
function _min(uint96 a, uint96 b) private pure returns (uint96)
```


---

# 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/usermanager.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.
