# AssetManager

@title AssetManager @author Union @dev Manage the token assets deposited by components and admins, and invest tokens to the integrated underlying lending protocols.

### marketRegistry

```solidity
address marketRegistry
```

*Address of market registry*

### withdrawSeq

```solidity
uint256[] withdrawSeq
```

*Withdraw Seuqence Priority sequence of money market indices for processing withdraws*

### balances

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

*Record admin or userManager balance Maps user to token to balance*

### totalPrincipal

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

*Total balance of a token Maps token to balance (deposited)*

### supportedMarkets

```solidity
mapping(address => bool) supportedMarkets
```

*Supported markets Mapping of tokens to boolean (isSupported)*

### moneyMarkets

```solidity
contract IMoneyMarketAdapter[] moneyMarkets
```

*Money Market Adapters*

### supportedTokensList

```solidity
address[] supportedTokensList
```

*Supported tokens*

### LogDeposit

```solidity
event LogDeposit(address token, address account, uint256 amount)
```

@dev Emit when making a deposit @param token Depositing token address @param account Account address @param amount Deposit amount, in wei

### LogWithdraw

```solidity
event LogWithdraw(address token, address account, uint256 amount, uint256 remaining)
```

@dev Emit when withdrawing from AssetManager @param token Depositing token address @param account Account address @param amount Withdraw amount, in wei @param remaining The amount cannot be withdrawn

### LogRebalance

```solidity
event LogRebalance(address tokenAddress, uint256[] percentages)
```

@dev Emit when rebalancing among the integrated money markets @param tokenAddress The address of the token to be rebalanced @param percentages Array of the percentages of the tokens to deposit to the money markets

### UnsupportedToken

```solidity
error UnsupportedToken()
```

### AuthFailed

```solidity
error AuthFailed()
```

### NotParity

```solidity
error NotParity()
```

### AmountZero

```solidity
error AmountZero()
```

### InsufficientBalance

```solidity
error InsufficientBalance()
```

### TokenExists

```solidity
error TokenExists()
```

### \_\_AssetManager\_init

```solidity
function __AssetManager_init(address _marketRegistry) external
```

### checkMarketSupported

```solidity
modifier checkMarketSupported(address token)
```

### onlyAuth

```solidity
modifier onlyAuth(address token)
```

### setMarketRegistry

```solidity
function setMarketRegistry(address _marketRegistry) external
```

### setWithdrawSequence

```solidity
function setWithdrawSequence(uint256[] newSeq) external
```

@dev Set withdraw sequence @param newSeq priority sequence of money market indices to be used while withdrawing

### getPoolBalance

```solidity
function getPoolBalance(address tokenAddress) public view returns (uint256)
```

@dev Get the balance of asset manager, plus the total amount of tokens deposited to all the underlying lending protocols @param tokenAddress ERC20 token address @return Pool balance

### getLoanableAmount

```solidity
function getLoanableAmount(address tokenAddress) public view returns (uint256)
```

@dev Returns the amount of the lending pool balance minus the amount of total staked. @param tokenAddress ERC20 token address @return loanAmount Amount can be borrowed

### totalSupply

```solidity
function totalSupply(address tokenAddress) external returns (uint256)
```

@dev Get the total amount of tokens deposited to all the integrated underlying protocols without side effects. @param tokenAddress ERC20 token address @return tokenSupply Total market balance

### totalSupplyView

```solidity
function totalSupplyView(address tokenAddress) public view returns (uint256)
```

@dev Get the total amount of tokens deposited to all the integrated underlying protocols, but without side effects. Safe to call anytime, but may not get the most updated number for the current block. Call totalSupply() for that purpose. @param tokenAddress ERC20 token address @return tokenSupply Total market balance

### isMarketSupported

```solidity
function isMarketSupported(address tokenAddress) public view returns (bool)
```

@dev Check if there is an underlying protocol available for the given ERC20 token. @param tokenAddress ERC20 token address @return Whether is supported

### moneyMarketsCount

```solidity
function moneyMarketsCount() external view returns (uint256)
```

@dev Get the number of supported underlying protocols. @return MoneyMarkets length

### supportedTokensCount

```solidity
function supportedTokensCount() external view returns (uint256)
```

@dev Get the count of supported tokens @return Number of supported tokens

### getMoneyMarket

```solidity
function getMoneyMarket(address tokenAddress, uint256 marketId) external view returns (uint256 rate, uint256 tokenSupply)
```

@dev Get the supported lending protocol @param tokenAddress ERC20 token address @param marketId MoneyMarkets array index @return rate tokenSupply, rate(compound is supplyRatePerBlock 1e18, aave is supplyRatePerYear 1e27)

### deposit

```solidity
function deposit(address token, uint256 amount) external returns (bool)
```

@dev Deposit tokens to AssetManager, and those tokens will be passed along to adapters to deposit to integrated asset protocols if any is available. @param token ERC20 token address @param amount ERC20 token address @return Deposited amount

### withdraw

```solidity
function withdraw(address token, address account, uint256 amount) external returns (bool)
```

@dev Withdraw from AssetManager @param token ERC20 token address @param account User address @param amount ERC20 token address @return Withdraw amount

### debtWriteOff

```solidity
function debtWriteOff(address token, uint256 amount) external
```

*Write of Debt*

### addToken

```solidity
function addToken(address tokenAddress) external
```

@dev Add a new ERC20 token to support in AssetManager @param tokenAddress ERC20 token address

### removeToken

```solidity
function removeToken(address tokenAddress) external
```

@dev Remove a ERC20 token to support in AssetManager @param tokenAddress ERC20 token address

### addAdapter

```solidity
function addAdapter(address adapterAddress) external
```

@dev Add a new adapter for the underlying lending protocol @param adapterAddress adapter address

### removeAdapter

```solidity
function removeAdapter(address adapterAddress) external
```

@dev Remove a adapter for the underlying lending protocol @param adapterAddress adapter address

### approveAllMarketsMax

```solidity
function approveAllMarketsMax(address tokenAddress) public
```

@dev For a give token set allowance for all integrated money markets @param tokenAddress ERC20 token address

### approveAllTokensMax

```solidity
function approveAllTokensMax(address adapterAddress) public
```

@dev For a give moeny market set allowance for all underlying tokens @param adapterAddress Address of adaptor for money market

### rebalance

```solidity
function rebalance(address tokenAddress, uint256[] percentages) external
```

\_Take all the supply of `tokenAddress` and redistribute it according to `percentages`.

Rejects if the token is not supported.\_

#### Parameters

| Name         | Type       | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| ------------ | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| tokenAddress | address    | Address of the token that is going to be rebalanced                                                                                                                                                                                                                                                                                                                                                                                                          |
| percentages  | uint256\[] | A list of percentages, expressed as units in 10000, indicating how to deposit the tokens in each underlying money market. The length of this array is one less than the amount of money markets: the last money market will receive the remaining tokens. For example, if there are 3 money markets, and you want to rebalance so that the first one has 10.5% of the tokens, the second one 55%, and the third one 34.5%, this param will be \[1050, 5500]. |

### \_checkSenderBalance

```solidity
function _checkSenderBalance(address sender, address tokenAddress, uint256 amount) private view returns (bool)
```

### \_isUToken

```solidity
function _isUToken(address sender, address token) private view returns (bool)
```

### \_isUserManager

```solidity
function _isUserManager(address sender, address token) private view returns (bool)
```
