# Overview

[INIT Capital](https://init.capital/) is a non-custodial decentralized lending protocol that caters to DeFi users – including lenders, borrowers, and liquidators – and protocols through 'Liquidity Hooks'.&#x20;

## Key Concepts

The following contains the key concepts to understand how INIT works:

* [Multi-silo Position](#multi-silo-position)
* [Mode](#mode)
* [Liquidity Hook](#liquidity-hook)
* [LP as collateral (Coming Soon)](#lp-as-collateral-tbd)

### Multi-silo Position

Users can create many siloed and isolated positions on INIT by using only a single account, unlike other major lending protocols that use account-based position that only allows one cross-margin position per account.

Each position contains information on its ID, mode, collaterals, borrows, rewards, and their corresponding amounts.

### Mode

Each position has its corresponding mode. Each mode has different allowed collateral and borrow tokens, token collateral and borrow factors, and debt ceilings.

### Liquidity Hook

Liquidity Hook allows integrated protocols to utilize INIT's liquidity and make external contract calls to perform arbitrary liquidity strategies. During the process, the interacted positions' healths are bypassed and finally checked to be healthy at the end of the process.

### LP as collateral (Coming Soon)


# Core Contracts

The following contracts are the main contracts for INIT:

* [InitCore](#initcore)
* [PosManager](#posmanager)
* [LendingPool](#lendingpool)
* [Config](#config)
* [RiskManager](#riskmanager)
* [Miscellaneous](#miscellaneous)

### InitCore <a href="#initcore" id="initcore"></a>

InitCore is the main entry point to interact with INIT. Users can lend and withdraw from lending pools, create positions, collateralize and de-collateralize, and borrow and repay on their positions. InitCore allows liquidity hooks to call external contracts via `callback` function.

### PosManager

PosManager stores positions created by InitCore. When users adjust their positions through InitCore, their actions update the position storages in PosManager.

### LendingPool

Lending pools, like other lending protocols, serve as the liquidity market for lenders and borrowers. Borrowers pay borrow interests while lenders earn lending interests configured by the pool's interest rate model.

Lending pools only accept ERC-20 tokens as their underlying tokens. Hence, native and rebase tokens must be wrapped into ERC-20 tokens before being transferred into the pools.&#x20;

### Config

Config stores parameters on all INIT contracts including lending pools, modes, token collateral and borrow factors, etc. The parameters can only be set by access controllers which are governed by INIT's guardian and governor roles.

### RiskManager

RiskManager oversees the risk on different modes of INIT. It disallows positions in a mode to borrow tokens more than the allowed debt ceiling from the lending pools.

### Miscellaneous

Other contracts that build up INIT such as a liquidation incentive calculator, lending pools' interest rate models, and oracles.


# Guides


# Basic Interaction


# Deposit and Withdraw

Deposits to & Withdraws from the specified lending pool. When you deposit to the lending pool, the corresponding "inToken" will be minted as a receipt token that represents your shares of the pool.

## Deposit

To deposit to a lending pool, users must perform 2 steps:

1. transfer underlying token to the pool
2. call `mintTo` on InitCore

The action returns `shares` of the lending pool.

{% hint style="info" %}
inToken decimals may be different from the underlying token's decimals. Currently, it is set to `8 + underlyingToken.decimals()` to conform to the ERC-4626 standard.
{% endhint %}

{% hint style="warning" %}
The above 2 steps must be performed in a single transaction (atomically) to avoid potential front-run attack.
{% endhint %}

<pre class="language-solidity"><code class="lang-solidity">// Example deposit function
function deposit(address lendingPool, uint256 amount, address receiver) external returns (uint256 shares) {
<strong>    // .. transfer in the tokens to this address ..
</strong><strong>    
</strong><strong>    // 1. transfer tokens to the lending pool
</strong>    IERC20(underlyingToken).safeTransfer(lendingPool, amount);

    // 2. call mintTo
    shares = IInitCore(INIT_CORE).mintTo(lendingPool, receiver);
}
</code></pre>

## Withdraw

To withdraw from a lending pool, users must perform 2 steps:

1. transfer inToken to the pool
2. call `burnTo` on InitCore

The action returns `amount` of underlying token to be received.

{% hint style="warning" %}
The above 2 steps must be performed in a single transaction (atomically) to avoid potential front-run attack.
{% endhint %}

```solidity
// Example withdraw function
function withdraw(address lendingPool, uint256 sharesToBurn, address receiver) external returns (uint256 amount) {
    // 1. transfer inTokens to the lending pool
    IERC20(lendingPool).safeTransfer(lendingPool, sharesToBurn);

    // 2. call burnTo
    amount = IInitCore(INIT_CORE).burnTo(lendingPool, receiver);
}
```


# Create Position

Create a new position in InitCore.

## Create Position

To create a position, call `createPos` with a mode and position "viewer". The viewer is an address for the position creator to store extra information about the position. For example, an integrated protocol that creates a position on behalf of its user can store its user address as the viewer to distinguish many positions of its users.

{% hint style="info" %}
The action creates an "empty position" without any collaterals or borrows. The function returns `posId` which must be specified later when adjusting this specific position.
{% endhint %}

```solidity
// Example create position function
function createInitPosition(uint16 mode, address viewer) external returns (uint256 posId) {
    // create position and returns posId
    posId = IInitCore(INIT_CORE).createPos(mode, viewer);
}
```


# Add and Remove Collateral

Adding & Removing collaterals to/from an existing position.

## Add Collateral

To add collateral to a position, users must already create the position and specify the position ID. The collateral token must be an inToken from lending pools.&#x20;

{% hint style="info" %}
The position must be in a mode that allows the collateral to be used.
{% endhint %}

{% hint style="warning" %}
The above 2 steps must be performed in a single transaction (atomically) to avoid potential front-run attack.
{% endhint %}

```solidity
// Example add collateral function
function addCollateral(uint256 posId, address lendingPool, uint256 shares) external {
    // 0. .. pull in lending pool tokens from the caller ..

    // 1. transfer inToken to PosManager
    IERC20(lendingPool).safeTransfer(POS_MANAGER, shares);

    // 2. add collateral to position
    IInitCore(INIT_CORE).collateralize(posId, lendingPool);
}
```

## Remove Collateral

To remove collateral, specify the position ID to remove from, shares of collateral to remove, and also the receiver address. The caller must be the position owner or approved party to modify the position.

{% hint style="info" %}
Always check that the position's health is over 1 after removing collateral to avoid transaction revert.
{% endhint %}

```solidity
// Example remove collateral function
function removeCollateral(uint256 posId, address lendingPool, uint256 shares, address receiver) external {
    // 1. remove collateral from position
    IInitCore(INIT_CORE).decollateralize(posId, lendingPool, shares, receiver);
}
```


# Borrow and Repay

Borrow & Repay tokens on InitCore's position.

## Borrow

Users can borrow tokens into their positions. Only the position owner or approved party to modify can call this function. The function returns a user's debt shares from the total borrows of the lending pool. Users can specify the receiver address to receive the tokens.

{% hint style="info" %}
The position must be in a mode that allows the borrow token to be used.
{% endhint %}

```solidity
// Example borrow function
function borrow(uint256 posId, address lendingPool, uint256 amount, address receiver) external returns (uint256 debtShares) {
    // 1. borrow tokens to a position
    debtShares = IInitCore(INIT_CORE).borrow(lendingPool, amount, posId, receiver);
}
```

## Repay

Users can repay their positions to increase the position's health factor.

{% hint style="info" %}
Users must have underlying tokens in their wallet and pre-approve the token to InitCore.
{% endhint %}

{% hint style="info" %}
For best practice, it is recommended that the caller approves the contract with an amount slightly higher than the pre-calculated debt amount, since the interest may accrue over time between the transaction submission to the network and the actual execution and inclusion onto the blockchain.
{% endhint %}

```solidity
// Example repay function
function repay(uint256 posId, address lendingPool, uint256 repayShares) external returns (uint256 repaidAmount) {
    // 0. .. pull in repay tokens from the caller ..
    
    // 1. calculate the token amount to repay
    uint256 repayAmount = ILendingPool(lendingPool).debtShareToAmtCurrent(repayShares);
    
    // 2. user approves underlying token with a bit extra amount
    IERC20(underlyingToken).safeApprove(INIT_CORE, repayAmount);
    
    // 3. repay
    repaidAmount = IInitCore(INIT_CORE).repay(lendingPool, repayShares, posId);
}
```


# Changing Position Mode

Change a position's mode.

Users can change their positions to another mode to increase the positions' health factors from better token factors.&#x20;

{% hint style="info" %}
Users may not always be able to change mode if the new mode debt ceiling in the target mode is reached or if the new mode does not support the current position's collaterals and borrows.
{% endhint %}

```solidity
// Example change mode function
function changeMode(uint256 posId, uint16 newMode) external {
    // 1. change position mode
    IInitCore(INIT_CORE).setPosMode(posId, newMode);
}
```


# Advanced Interaction


# Liquidate Position

Liquidating unhealthy positions.

Liquidator can liquidate a position if its health factor falls below 1 (unhealthy). The liquidator pays some position debt and, in return, receives inToken from the position's collateral. Liquidation can be partial – partially repays the debt and receives a portion of the position's collateral.

{% hint style="info" %}
Liquidation incentive differs for each pair of repaid debt token and inToken to receive.
{% endhint %}

{% hint style="info" %}
A position can only be liquidated up to a certain health factor to prevent over-liquidation. After the liquidation, the position's health factor cannot be over `MAX_HEALTH_AFTER_LIQ`.
{% endhint %}

```solidity
// Example liquidate function
function liquidate(uint256 posId, address lendingPoolToRepay, uint256 repayShares, address lendingPoolCollateralToReceive, uint256 minInCollateralTokenOut) external {
    // 0. .. pull repay tokens from the caller ..
    
    // 1. approve repay tokens to InitCore
    IERC20(lendingPoolToRepay).safeApprove(INIT_CORE, repayShares);

    // 2. liquidate
    IInitCore(INIT_CORE).liquidate(posId, lendingPoolToRepay, repayShares, lendingPoolCollateralToReceive, minInCollateralTokenOut);
}
```


# Flashloan

Flashloan tokens from the lending pool.

INIT offers a 0% fee flashloan for users to atomically use the available liquidity from lending pools to use elsewhere. The caller of `flash` function must be a contract that implements `flashCallback` function.&#x20;

During the flashloan, the caller receives flashloan from lending pools and can execute arbitrary logic from bytes `data` through `flashCallback` which is called to the caller by InitCore. At the end of the flashloan, the caller must return the loan to the borrowed lending pools.

{% hint style="info" %}
It is recommended to check that the sender is the InitCore in the `flashCallback` function to prevent unauthorized calls.
{% endhint %}

```solidity
// Example Flashloan contract
contract FlashloanContract {
    function flashCallback(address[] calldata lendingPools, uint256[] calldata amounts, bytes calldata data) external {
        // check that the caller is InitCore
        require(msg.sender == INIT_CORE, 'unauthorized'); 
        
        // do some logic 
        
        // transfer back amounts to corresponding lending pools
    }
    
    function flash(address[] calldata lendingPools, uint256[] calldata amounts, bytes calldata data) external {
        // initiate flash loan
        IInitCore(INIT_CORE).flash(lendingPools, amounts, data);
    }
}


```


# Multicall

Batch transaction with InitCore's multicall.

Multicall is a way to perform multiple interactions with a position (or multiple positions) while bypassing the health checks until the end of the multicall transaction. The function can only call methods in InitCore since the multicall uses `delegatecall` to itself.&#x20;

The function creates a convenient way for users to perform multiple actions on their positions such as collateral or debt swaps, and debt rebalancing in a single transaction. One key use-case of the multicall is "flash borrow". The caller can borrow out the tokens first and eventually put collaterals back at the end of the multicall function.

Multicall also returns a bytes array of `results`.

{% hint style="info" %}
Multicall accepts a list of bytes data as arguments. Each bytes data represents the encoded multicall data to be executed to InitCore.
{% endhint %}

```solidity
// Example multicall function
function executeMulticall(uint256 posId, address lendingPoolA, uint256 borrowAAmount, address lendingPoolB, uint256 lendingBAmount) external returns (bytes[] memory results) {
    // 0. .. perform necessary actions for example pulling tokens from the caller ..
    
    // 1. build multicall bytes data
    //    Example: 1) borrow tokenA, 2) lend tokenB, 3) collateralize the deposited tokenB
    bytes[] memory calls = new bytes[](3);
    
    // build data for step 1) 
    calls[0] = abi.encodeWithSelector(IInitCore.borrow.selector, lendingPoolA, borrowAAmount, posId, address(this));
    
    // build data for step 2) – mint directly to position manager
    IERC20(ILendingPool(lendingPoolB).underlyingToken()).safeTransfer(lendingPoolB, lendingBAmount); // transfer underlying token to lending pool directly for mint
    calls[1] = abi.encodeWithSelector(IInitCore.mintTo.selector, lendingPoolB, POS_MANAGER);
    
    // build data for step 3)
    calls[2] = abi.encodeWithSelector(IInitCore.collateralize.selector, posId, lendingPoolB);
    
    results = IInitCore(INIT_CORE).multicall(calls);
}
```


# Callback

Callback is used to make a function call to an external contract. The external contract can perform an arbitrary logic using the bytes `data` and payable `value` provided by the call arguments.

One key usage for the callback is to make a token swap from a DEX contract outside of INIT.

{% hint style="info" %}
The external contract must implement `coreCallback payable` function.
{% endhint %}

{% hint style="info" %}
It is recommended to check that `msg.sender` of `coreCallback` is `INIT_CORE` to avoid unintended external calls from other users.
{% endhint %}

```solidity
// Example external contract that uses InitCore's callback
contract ExternalContract {
    function coreCallback(address sender, bytes calldata data) external payable returns (bytes memory result) {
        // check msg.sender is InitCore
        require(msg.sender == INIT_CORE, 'sender not allowed');

        // perform a swap on a DEX
        
        // returns bytes result
    }
    
    function executeCallback(bytes calldata data) payable {
        IInitCore(INIT_CORE).callback{value: msg.value}(msg.sender, data);
    }
}
```


# Liquidity Hook


# Multicall with Callback

Multicall with callback are used together to perform actions on InitCore and external contracts. This combination of calls creates a liquidity hook to utilize liquidity on INIT to execute other logic outside of INIT.

One main usage of multicall with callback is to "one-click leverage" a position in a single transaction compared to having to perform multiple collateralize and borrow to attain the same amount of leverage.

```solidity
// Example external contract that
// create INIT position from
// 1. borrow token from borrowing from INIT lending pool
// 2. collateral token from token out from swapping borrowed token
contract ExternalContract {
    function coreCallback(address _sender, bytes calldata _data) external payable returns (bytes memory result) {
        // check msg.sender is InitCore
        require(msg.sender == INIT_CORE, 'sender not allowed');

        // perform a swap on a DEX
        
        // returns bytes result
    }
    
    // use callback to swap borrowed token and collateralize to an INIT position
    function createInitPosition() external payable {
        // 1. create position on INIT
        uint256 posId = IInitCore(INIT_CORE).createPos(_mode, msg.sender);
        
        // 2. transfer in token from user
        IERC20(_tokenIn).safeTransferFrom(msg.sender, address(this), _amtIn);
        
        bytes[] memory calls = new bytes[](4);

        // 3. borrow from lending pool
        calls[0] = abi.encodeWithSelector(IInitCore(INIT_CORE).borrow.selector, _borrowPool, _borrowAmt, posId, address(this));
        
        // 4. callback to swap borrowed token 
        calls[1] = abi.encodeWithSelector(IInitCore(INIT_CORE).callback.selector, address(this), msg.value, abi.encode(_tokenIn, _borrowPool, _mintPool));
        
        // 5. mint inToken from the result token of swap
        calls[2] = abi.encodeWithSelector(IInitCore(INIT_CORE).mintTo.selector, _mintPool, POS_MANAGER);
        
        // 6. collateralize inToken
        calls[3] = abi.encodeWithSelector(IInitCore(INIT_CORE).collateralize.selector, posId, _mintPool);
        
        // 7. make a multicall
        IInitCore(INIT_CORE).multicall{value: msg.value}(calls);
    }
}
```


# Money Market Hook

Money market hook is a liquidity hook contract to **handle basic interactions** (create position, deposit/withdraw, add/remove collateral, and borrow/repay) via `multicall` to InitCore **in a single transaction**. Money market hook stores its running position id for each user, starting from 1, when a user creates a new position via the contract.

The interaction flow consists of:

1. Create a position on the hook and InitCore, if not existed
2. Perform `multicall` to InitCore, which performs:
   1. Decollateralize inToken from the position and redeem token in lending pool
   2. Withdraw from lending pool
   3. Change position mode, if specified
   4. Borrow tokens from lending pool
   5. Mint inToken from lending pool and collateralize to the position
3. Unwrap rebase tokens, if specified
4. Unwrap wrapped native token to native token, if specified

The interaction is done via [`execute`](/contract-references/moneymarkethook#execute) function.

```solidity
struct OperationParams {
    uint posId; //  position id to execute (0 to create new position)
    address viewer; // address to view position
    uint16 mode; // position mode to be used
    DepositParams[] depositParams; // deposit parameters
    WithdrawParams[] withdrawParams; // withdraw parameters
    BorrowParams[] borrowParams; // borrow parameters
    RepayParams[] repayParams; // repay parameters
    uint minHealth_e18; // minimum health to maintain after execute
    bool returnNative; // return native token or not (using balanceOf(address(this)))
}

function execute(OperationParams calldata _params)
    external
    payable
    nonReentrant
    returns (uint posId, uint initPosId, bytes[] memory results)
{
    // create position if not exist
    if (_params.posId == 0) {
        (posId, initPosId) = createPos(_params.mode, _params.viewer);
    } else {
        // for existing position, only owner can execute
        posId = _params.posId;
        initPosId = initPosIds[msg.sender][posId];
        _require(IERC721(POS_MANAGER).ownerOf(initPosId) == address(this), Errors.NOT_OWNER);
    }
    results = _handleMulticall(initPosId, _params);
    // check slippage
    _require(_params.minHealth_e18 <= IInitCore(CORE).getPosHealthCurrent_e18(initPosId), Errors.SLIPPAGE_CONTROL);
    // unwrap token if needed
    for (uint i; i < _params.withdrawParams.length; i = i.uinc()) {
        address helper = _params.withdrawParams[i].rebaseHelperParams.helper;
        if (helper != address(0)) IRebaseHelper(helper).unwrap(_params.withdrawParams[i].to);
    }
    // return native token
    if (_params.returnNative) {
        uint wNativeBal = IERC20(WNATIVE).balanceOf(address(this));
        // NOTE: no need receive function since we will use TransparentUpgradeableProxyReceiveETH
        if (wNativeBal != 0) IWNative(WNATIVE).withdraw(wNativeBal);
        uint nativeBal = address(this).balance;
        if (nativeBal != 0) {
            (bool success,) = payable(msg.sender).call{value: address(this).balance}('');
            _require(success, Errors.CALL_FAILED);
        }
    }
}
```


# Looping Hook

A liquidity hook to create **a leveraged position** with 1 collateral token and 1 borrow token **in a single transaction**. For example, a user can open an mETH-ETH looping position by collateralizing $5 worth of inmETH and borrowing $4 worth of WETH to earn a leveraged yield on mETH staking rewards. The function utilizes "Flash Borrow", swap the borrowed token to collateral token, and collateralize into a position.

Users can adjust their positions (increase/decrease leverage, increase/decrease position size, etc.).

The looping hook must swap a position's borrow token into a collateral token, and the hook utilizes a [swapHelper](/contract-references/loopinghook#swaphelper) to perform the swap action. Currently, there are 3 looping hook contracts, each with a different swap helper, that perform swaps on Merchant Moe, Agni Finance, and FusionX Finance.


# Margin Trading Hook

Coming Soon...


# Contract References


# InitCore

The main entry point of INIT.

## View Functions

### POS\_MANAGER

PosManager contract address.

```solidity
function POS_MANAGER() external returns (address posManager);
```

### config

Config contract address

```solidity
function config() external returns (address config);
```

### oracle

InitOracle contract address

```solidity
function oracle() external returns (address initOracle);
```

### liqIncentiveCalculator

LiqIncentiveCalculator contract address

```solidity
function liqIncentiveCalculator() external returns (address liqIncentiveCalculator);
```

### riskManager

RiskManager contract address

```solidity
function riskManager() external returns (address riskManager);
```

## External Functions

### mintTo

Mint inToken from a lending pool using the balance difference (∆balance) between the current and last stored balances. Users should transfer in the pool's underlying token before calling this function.

{% hint style="info" %}
This is a low-level function call. Make sure to atomically send tokens and call mintTo.
{% endhint %}

```solidity
function mintTo(address _pool, address _to) external returns (uint256 shares);
```

Parameters:

| Name    | Type      | Description                  |
| ------- | --------- | ---------------------------- |
| `_pool` | `address` | lending pool to mint inToken |
| `_to`   | `address` | address to mint inTokens to  |

Returns:

| Name     | Type      | Description              |
| -------- | --------- | ------------------------ |
| `shares` | `uint256` | amount of inToken minted |

### burnTo

Burn inToken for the pool's underlying token. Lending pool must have enough idle liquidity to transfer out the converted amount of underlying token.

{% hint style="info" %}
This is a low-level function call. Make sure to atomically send inTokens and call burnTo.
{% endhint %}

```solidity
function burnTo(address _pool, address _to) external returns (uint256 amt);
```

Parameters:

| Name    | Type      | Description                          |
| ------- | --------- | ------------------------------------ |
| `_pool` | `address` | lending pool to burn inToken         |
| `_to`   | `address` | address to receive underlying tokens |

Returns:

| Name  | Type      | Description                     |
| ----- | --------- | ------------------------------- |
| `amt` | `uint256` | amount of underlying tokens out |

### borrow

Borrow pool's underlying tokens from InitCore. Lending pool must have enough idle liquidity to borrow. Debt ceiling and borrow cap must also not be reached for the borrowing to succeed. Position health must also be healthy after the borrowing.

{% hint style="info" %}
The position's health factor will increase after a successful borrow.
{% endhint %}

```solidity
function borrow(address _pool, uint256 _amt, uint256 _posId, address _to) external returns (uint256 shares);
```

Parameters:

| Name     | Type      | Description                            |
| -------- | --------- | -------------------------------------- |
| `_pool`  | `address` | lending pool to borrow from            |
| `_amt`   | `uint256` | token amount to borrow                 |
| `_posId` | `uint256` | position id to account the borrow from |
| `_to`    | `address` | address to receive underlying tokens   |

Returns:

| Name     | Type      | Description                |
| -------- | --------- | -------------------------- |
| `shares` | `uint256` | debt shares for the borrow |

### repay

Repay pool's underlying tokens to InitCore.&#x20;

{% hint style="info" %}
The position's health factor will decrease after a successful repay.
{% endhint %}

```solidity
function repay(address _pool, uint256 _shares, uint256 _posId) external returns (uint256 amt);
```

Parameters:

| Name      | Type      | Description              |
| --------- | --------- | ------------------------ |
| `_pool`   | `address` | lending pool to repay to |
| `_shares` | `uint256` | shares amount to repay   |
| `_posId`  | `uint256` | position id to repay to  |

Returns:

| Name  | Type      | Description                       |
| ----- | --------- | --------------------------------- |
| `amt` | `uint256` | corresponding token amount repaid |

### createPos

Create a new position under the specified mode.&#x20;

{% hint style="info" %}
`viewer` address does not have any effect on the on-chain logic. It is only used for tracking the actual position owner in case the integrating protocol interacts with InitCore on behalf of the user.
{% endhint %}

```solidity
function createPos(uint16 _mode, address _viewer) external returns (uint256 posId);
```

Parameters:

| Name      | Type      | Description                                              |
| --------- | --------- | -------------------------------------------------------- |
| `_mode`   | `uint16`  | mode for the position                                    |
| `_viewer` | `address` | viewer address that represents the actual position owner |

Returns:

| Name    | Type      | Description     |
| ------- | --------- | --------------- |
| `posId` | `uint256` | new position id |

### setPosMode

Set a new position mode to an existing position.&#x20;

{% hint style="info" %}
The mode change might be invalid due to several reasons, for example, the debt ceiling reached on the new mode or some tokens are not supported on the new mode.
{% endhint %}

```solidity
function setPosMode(uint _posId, uint16 _mode) external;
```

Parameters:

| Name     | Type      | Description                |
| -------- | --------- | -------------------------- |
| `_posId` | `uint256` | position id to change mode |
| `_mode`  | `uint16`  | new mode to change to      |

### collateralize

Collateralize inTokens to InitCore.&#x20;

{% hint style="info" %}
The position's health factor will increase after a successful collateralization.
{% endhint %}

```solidity
function collateralize(uint256 _posId, address _pool) external;
```

Parameters:

| Name     | Type      | Description                     |
| -------- | --------- | ------------------------------- |
| `_posId` | `uint256` | position id to collateralize to |
| `_pool`  | `address` | lending pool to collateralize   |

### decollateralize

Decollateralize inTokens from InitCore.

{% hint style="info" %}
The position's health factor will decrease after a successful decollateralization.
{% endhint %}

{% hint style="info" %}
Decollateralize will transfer inTokens to the specified receiver address. If the underlying token is desired, users can `burn` the received inTokens.
{% endhint %}

```solidity
function decollateralize(uint256 _posId, address _pool, uint256 _shares, address _to) external;
```

Parameters:

| Name      | Type      | Description                         |
| --------- | --------- | ----------------------------------- |
| `_posId`  | `uint256` | position id to decollateralize from |
| `_pool`   | `address` | lending pool to decollateralize     |
| `_shares` | `uint256` | shares amount to decollateralize    |
| `_to`     | `address` | address to receive the inTokens     |

### collateralizeWLp

Collateralize supported wrapped LPs to InitCore.&#x20;

{% hint style="info" %}
The position's health factor will increase after a successful collateralization.
{% endhint %}

```solidity
function collateralizeWLp(uint256 _posId, address _wLp, uint256 _tokenId) external;
```

Parameters:

| Name       | Type\`    | Description                         |
| ---------- | --------- | ----------------------------------- |
| `_posId`   | `uint256` | position id to collateralize wLp to |
| `_wLp`     | `address` | wrapped LP contract address         |
| `_tokenId` | `uint256` | wrapped LP token id                 |

### decollateralizeWLp

Decollateralize supported wrapped LPs from InitCore.

{% hint style="info" %}
The position's health factor will decrease after a successful decollateralization.
{% endhint %}

```solidity
function decollateralizeWLp(
    uint256 _posId, 
    address _wLp, 
    uint256 _tokenId, 
    uint256 _amt, 
    address _to
) external;
```

Parameters:

| Name       | Type      | Description                             |
| ---------- | --------- | --------------------------------------- |
| `_posId`   | `uint256` | position id to decollateralize wLp from |
| `_wLp`     | `address` | wrapped LP contract address             |
| `_tokenId` | `uint256` | wrapped LP token id to decollateralize  |
| `_amt`     | `uint256` | wrapped LP amount to decollateralize    |
| `_to`      | `address` | address to receive the underlying LP.   |

### liquidate

Liquidate unhealthy position by repaying partial debt and receiving a portion of the collateral, with a small liquidation premium.&#x20;

{% hint style="info" %}
A position can only be liquidated if the position is unhealthy (health factor < 1).
{% endhint %}

{% hint style="info" %}
A liquidator can only liquidate a position until the position's health factor does not exceed the `Config.maxHealthAfterLiq_e18` value.
{% endhint %}

```solidity
function liquidate(
    uint256 _posId, 
    address _poolToRepay, 
    uint256 _repayShares, 
    address _poolOut, 
    uint256 _minShares
) external returns (uint256 shares);
```

Parameters:

| Name           | Type      | Description                                                         |
| -------------- | --------- | ------------------------------------------------------------------- |
| `_posId`       | `uint256` | position id to liquidate                                            |
| `_poolToRepay` | `address` | lending pool address to repay  for liquidation                      |
| `_repayShares` | `uint256` | shares amount for repay                                             |
| `_poolOut`     | `address` | lending pool address to receive inToken collateral from liquidation |
| `_minShares`   | `uint256` | min shares for liquidation (slippage control)                       |

Returns:

| Name     | Type      | Description                   |
| -------- | --------- | ----------------------------- |
| `shares` | `uint256` | shares of `_poolOut` received |

### liquidateWLp

Liquidate unhealthy position by repaying partial debt and receiving a portion of the WLp collateral, with a small liquidation premium.

{% hint style="info" %}
A position can only be liquidated if the position is unhealthy (health factor < 1).
{% endhint %}

{% hint style="info" %}
&#x20;A liquidator can only liquidate a position until the position's health factor does not exceed the `Config.maxHealthAfterLiq_e18` value.
{% endhint %}

```solidity
function liquidateWLp(
    uint256 _posId,
    address _poolToRepay,
    uint256 _repayShares,
    address _wLp,
    uint256 _tokenId,
    uint256 _minlpOut
) external returns (uint256 lpAmtOut);
```

Parameters:

| Name           | Type      | Description                                                |
| -------------- | --------- | ---------------------------------------------------------- |
| `_posId`       | `uint256` | position id to liquidate                                   |
| `_poolToRepay` | `address` | lending pool address to repay for liquidation              |
| `_repayShares` | `uint256` | shares amount for repay                                    |
| `_wLp`         | `address` | wrapped LP address to receive collateral from liquidation  |
| `_tokenId`     | `uint256` | wrapped LP token id to receive collateral from liquidation |
| `_minlpOut`    | `uint256` | min LP amount for liquidation (slippage control)           |

Returns:

| Name       | Type      | Description        |
| ---------- | --------- | ------------------ |
| `lpAmtOut` | `uint256` | LP amount received |

### flash

Flashloan tokens from InitCore and return them in the same transaction.

{% hint style="info" %}
`flash` will invoke `flashCallback` to the `msg.sender` to execute arbitrary data.
{% endhint %}

{% hint style="info" %}
The caller must implement `flashCallback` function. It is also recommended that the `flashCallback` function validates that the caller is InitCore. (`require(msg.ender == INIT_CORE);)`
{% endhint %}

```solidity
function flash(address[] calldata _pools, uint256[] calldata _amts, bytes calldata _data) external;
```

Parameters:

| Name     | Type        | Description                                 |
| -------- | ----------- | ------------------------------------------- |
| `_pools` | `address`   | array of pools to borrow tokens from        |
| `_amts`  | `uint256[]` | array of token amounts to borrow            |
| `_data`  | `bytes`     | custom data to be passed to `flashCallback` |

### multicall

Multicall to allow batched transactions from the caller. Any positions interacted in the multicall will delay the health check to the end of the multicall. This allows users to be able to borrow tokens out before providing collaterals to InitCore.

```solidity
function multicall(bytes[] calldata data) external payable returns (bytes[] memory results);
```

Parameters:&#x20;

| Name    | Type      | Description                         |
| ------- | --------- | ----------------------------------- |
| `_data` | `bytes[]` | array of bytes to perform multicall |

Returns:

| Name      | Type      | Description                                                |
| --------- | --------- | ---------------------------------------------------------- |
| `results` | `bytes[]` | array of bytes containing the return data of each sub-call |

### getCollateralCreditCurrent\_e36

Get a position's collateral credit (with borrow interest accrual) with `10^36` precision.

{% hint style="warning" %}
This is not a view function.&#x20;
{% endhint %}

```solidity
function getCollateralCreditCurrent_e36(uint256 _posId) external returns (uint256 collCredit_e36);
```

Parameters:

| Name     | Type      | Description                          |
| -------- | --------- | ------------------------------------ |
| `_posId` | `uint256` | position id to get collateral credit |

Returns:

| Name             | Type      | Description                                                  |
| ---------------- | --------- | ------------------------------------------------------------ |
| `collCredit_e36` | `uint256` | collateral credit in `10^36` precision with interest accrual |

### getBorrowCreditCurrent\_e36

Get a position's borrow credit (with borrow interest accrual) with `10^36` precision.

{% hint style="warning" %}
This is not a view function.
{% endhint %}

```solidity
function getBorrowCreditCurrent_e36(uint256 _posId) external returns (uint256 borrowCredit_e36);
```

Parameters:

| Name     | Type      | Description                      |
| -------- | --------- | -------------------------------- |
| `_posId` | `uint256` | position id to get borrow credit |

Returns:

| Name               | Type      | Description                                              |
| ------------------ | --------- | -------------------------------------------------------- |
| `borrowCredit_e36` | `uint256` | borrow credit in `10^36` precision with interest accrual |

### getPosHealthCurrent\_e18

Get a position's health factor (with borrow interest accrual) with `10^18` precision.

{% hint style="warning" %}
This is not a view function.
{% endhint %}

```solidity
function getPosHealthCurrent_e18(uint256 _posId) external returns (uint256 health_e18);
```

Parameters:

| Name     | Type      | Description                      |
| -------- | --------- | -------------------------------- |
| `_posId` | `uint256` | position id to get health factor |

Returns:

| Name         | Type      | Description                                              |
| ------------ | --------- | -------------------------------------------------------- |
| `health_e18` | `uint256` | health factor in `10^18` precision with interest accrual |

### callback

Execute a callback function from InitCore to the target address with custom data and `msg.value`. This should be used in conjunction with `multicall`.

{% hint style="info" %}
The target address must implement `coreCallback` function. It is also recommended that `coreCallback` function validates that the caller is InitCore. (`require(msg.ender == INIT_CORE);`&#x20;
{% endhint %}

```solidity
function callback(address _to, uint256 _value, bytes memory _data) external returns (bytes memory result);
```

Parameters:

| Name     | Type      | Description                                                                        |
| -------- | --------- | ---------------------------------------------------------------------------------- |
| `_to`    | `address` | call target address                                                                |
| `_value` | `uint256` | `msg.value` to pass to the call                                                    |
| `_data`  | `bytes`   | bytes data of the low-level function call (should also include function signature) |

Returns:

| Name     | Type    | Description                           |
| -------- | ------- | ------------------------------------- |
| `result` | `bytes` | bytes-encoded return data of the call |

### transferToken

Transfer tokens from the caller to the specified address. This should be used in conjunction with `multicall` to facilitate token transfers for depositing to lending pools.

{% hint style="info" %}
The caller must pre-approves the InitCore before the function call.
{% endhint %}

```solidity
function transferToken(address _token, address _to, uint _amt) external;
```

Parameters:

| Name     | Type      | Description                  |
| -------- | --------- | ---------------------------- |
| `_token` | `address` | token address to transfer    |
| `_to`    | `address` | address to receive the token |
| `_amt`   | `uint256` | token amount to transfer     |


# PosManager

Position manager is responsible for managing individual positions, including debt shares and collaterals.&#x20;

## View Functions

### nextNonces

Get a user's next nonce for calculating the creation of position id.

```solidity
function nextNonces(address _user) external view returns (uint256 nonce);
```

### core

InitCore contract address.

```solidity
function core() external view returns (address initCore);
```

### maxCollCount

Max collateral count allowed.

```solidity
function maxCollCount() external view returns (uint8 count);
```

### pendingRewards

Position's pending reward token amounts.

```solidity
function pendingRewards(uint256 _posId, address _rewardToken) external view returns (uint256 rewardAmount);
```

### isCollateralized

Get whether the wrapped LP token id is already collateralized to the position.

```solidity
function isCollateralized(address _wLp, uint _tokenId) external view returns (bool collateralized);
```

### getPosBorrInfo

Get a position's borrow information.

```solidity
function getPosBorrInfo(uint _posId) external view returns (address[] memory pools, uint[] memory debtShares);
```

Parameters:

| Name     | Type      | Description                    |
| -------- | --------- | ------------------------------ |
| `_posId` | `uint256` | position id to get borrow info |

Returns:

| Name         | Type        | Description                                                    |
| ------------ | ----------- | -------------------------------------------------------------- |
| `pools`      | `address[]` | array of lending pool addresses that the position borrows from |
| `debtShares` | `uint256[]` | array of debt shares of each borrow token                      |

### getPosBorrExtraInfo

Get a position's borrow extra information.&#x20;

{% hint style="warning" %}
`totalInterest` may not be exact. Use with caution.
{% endhint %}

```solidity
function getPosBorrExtraInfo(uint _posId, address _pool) external view returns (uint totalInterest, uint lastDebtAmt);
```

Parameters:

| Name     | Type      | Description                                   |
| -------- | --------- | --------------------------------------------- |
| `_posId` | `uint256` | position id to get borrow extra info          |
| `_pool`  | `address` | lending pool address to get borrow extra info |

Returns:

| Name            | Type      | Description                                                      |
| --------------- | --------- | ---------------------------------------------------------------- |
| `totalInterest` | `uint256` | total interest that the lending pool has accrued borrow interest |
| `lastDebtAmt`   | `uint256` | the last known debt amount                                       |

### getPosCollInfo

Get a position's collateral information.

```solidity
function getPosCollInfo(uint _posId) external view returns (address[] memory pools, uint[] memory amts, address[] memory wLps, uint[][] memory ids, uint[][] memory wLpAmts);
```

Parameters:

| Name     | Type      | Description                        |
| -------- | --------- | ---------------------------------- |
| `_posId` | `uint256` | position id to get collateral info |

Returns:

| Name      | Type          | Description                                                     |
| --------- | ------------- | --------------------------------------------------------------- |
| `pools`   | `address[]`   | array of lending addresses that the position puts as collateral |
| `amts`    | `uint256[]`   | array of lending pool collateralization amounts                 |
| `wLps`    | `address[]`   | array of wrapped LP addresses                                   |
| `ids`     | `uint256[][]` | array of array of wrapped LP's token ids                        |
| `wLpAmts` | `uint256[][]` | array of array of wrapped LP's token amount for each token id   |

### getCollAmt

Get a position's collateral amount of the specified lending pool.

```solidity
function getCollAmt(uint _posId, address _pool) external view returns (uint amt);
```

Parameters:

| Name     | Type      | Description                           |
| -------- | --------- | ------------------------------------- |
| `_posId` | `uint256` | position id to get collateral amount  |
| `_pool`  | `address` | lending pool to get collateral amount |

Returns:

| Name  | Type      | Description       |
| ----- | --------- | ----------------- |
| `amt` | `uint256` | collateral amount |

### getCollWLpAmt

Get a position's collateral amount of the specified wrapped LP.

```solidity
function getCollWLpAmt(uint _posId, address _wLp, uint _tokenId) external view returns (uint amt);
```

&#x20;Parameters:

| Name       | Type      | Description                                          |
| ---------- | --------- | ---------------------------------------------------- |
| `_posId`   | `uint256` | position id to get collateral wLp amount             |
| `_wLp`     | `address` | wrapped LP contract address to get collateral amount |
| `_tokenId` | `uint256` | wrapped LP token id to get collateral amount         |

Returns:

| Name  | Type      | Description       |
| ----- | --------- | ----------------- |
| `amt` | `uint256` | collateral amount |

### getPosCollCount

Get a position's collateral count of a given position id.&#x20;

{% hint style="info" %}
This count does not include wLp collaterals.
{% endhint %}

```solidity
function getPosCollCount(uint _posId) external view returns (uint8 count);
```

Parameters:

| Name     | Type      | Description                         |
| -------- | --------- | ----------------------------------- |
| `_posId` | `uint256` | position id to get collateral count |

Returns:

| Name    | Type    | Description      |
| ------- | ------- | ---------------- |
| `count` | `uint8` | collateral count |

### getPosCollWLpCount

Get a position's wrapped LP collateral count of a given position id.&#x20;

{% hint style="info" %}
This count does not include regular lending pool collaterals.
{% endhint %}

```solidity
function getPosCollWLpCount(uint _posId) external view returns (uint8 count);
```

Parameters:

| Name     | Type      | Description                             |
| -------- | --------- | --------------------------------------- |
| `_posId` | `uint256` | position id to get wLp collateral count |

Returns:

| Name    | Type    | Description      |
| ------- | ------- | ---------------- |
| `count` | `uint8` | collateral count |

### getPosInfo

Get a position's general information.

{% hint style="info" %}
If the position does not exist, the viewer will be `address(0)` and mode will be 0.
{% endhint %}

```solidity
function getPosInfo(uint _posId) external view returns (address viewer, uint16 mode);
```

Parameters:

| Name     | Type      | Description                    |
| -------- | --------- | ------------------------------ |
| `_posId` | `uint256` | position id to get information |

Returns:

| Name     | Type      | Description                    |
| -------- | --------- | ------------------------------ |
| `viewer` | `address` | viewer address of the position |
| `mode`   | `uint16`  | position's current mode        |

### getPosMode

Get a position's mode.

{% hint style="info" %}
If a position does not exist, the mode will be 0.
{% endhint %}

```solidity
function getPosMode(uint _posId) external view returns (uint16 mode);
```

Parameters:

| Name     | Type      | Description             |
| -------- | --------- | ----------------------- |
| `_posId` | `uint256` | position id to get mode |

Returns:

| Name   | Type     | Description   |
| ------ | -------- | ------------- |
| `mode` | `uint16` | position mode |

### getPosDebtShares

Get a position's debt shares (without borrow interest accrual).

```solidity
function getPosDebtShares(uint _posId, address _pool) external view returns (uint debtShares);
```

Parameters:

| Name     | Type      | Description                                |
| -------- | --------- | ------------------------------------------ |
| `_posId` | `uint256` | position id to get debt shares information |
| `_pool`  | `address` | lending pool address to get debt shares of |

Returns:

| Name         | Type      | Description                              |
| ------------ | --------- | ---------------------------------------- |
| `debtShares` | `uint256` | lending pool debt shares of the position |

### getViewerPosIdsAt

Get a reverse-mapping lookup for the specified viewer address and the array index.

{% hint style="info" %}
If the index can be out-of-bounds if it exceeds the array length.
{% endhint %}

```solidity
function getViewerPosIdsAt(address _viewer, uint _index) external view returns (uint posId);
```

Parameters:

| Name      | Type      | Description                       |
| --------- | --------- | --------------------------------- |
| `_viewer` | `address` | viewer address to get position id |
| `_index`  | `uint256` | array index to query              |

Returns:

| Name    | Type      | Description |
| ------- | --------- | ----------- |
| `posId` | `uint256` | position id |

### getViewerPosIdsLength

Get a reverse-mapping lookup array length for the specified viewer address.

```solidity
function getViewerPosIdsLength(address _viewer) external view returns (uint length);
```

Parameters:

| Name      | Type      | Description                             |
| --------- | --------- | --------------------------------------- |
| `_viewer` | `address` | viewer address to get position id count |

Returns:

| Name     | Type      | Description                                   |
| -------- | --------- | --------------------------------------------- |
| `length` | `uint256` | position id count corresponding to the viewer |

### isAuthorized

Check whether the account is authorized for modifying the position.

```solidity
function isAuthorized(address _account, uint _posId) external view returns (bool);
```

Parameters:

| Name       | Type      | Description                        |
| ---------- | --------- | ---------------------------------- |
| `_account` | `address` | address to check authorization     |
| `_posId`   | `uint256` | position id to check authorization |

Returns:

| Name           | Type   | Description                                                 |
| -------------- | ------ | ----------------------------------------------------------- |
| `isAuthorized` | `bool` | whether the account is authorized to modify the position id |

## External Functions

### harvestTo

Harvest reward tokens of the specified wrapped LP to the target address.&#x20;

{% hint style="info" %}
Can only be called by an authorized party of the position.
{% endhint %}

```solidity
function harvestTo(uint _posId, address _wLp, uint _tokenId, address _to) external returns (address[] memory tokens, uint[] memory amts);
```

Parameters:

| Name       | Type      | Description                                    |
| ---------- | --------- | ---------------------------------------------- |
| `_posId`   | `uint256` | position id to harvest rewards from            |
| `_wLp`     | `address` | wrapped LP contract address to harvest rewards |
| `_tokenId` | `uint256` | wrapped LP token id to harvest rewards         |
| `_to`      | `address` | address to receive the reward tokens           |

Returns:

| Name     | Type        | Description                               |
| -------- | ----------- | ----------------------------------------- |
| `tokens` | `address[]` | array of reward token addresses           |
| `amts`   | `uint256[]` | array of reward token amounts transferred |

### claimPendingRewards

Claim pending reward tokens from the position.

{% hint style="info" %}
This function is intended to be called in cases when the position gets liquidated, and reward tokens get accrued in the position.
{% endhint %}

```solidity
function claimPendingRewards(uint _posId, address[] calldata _tokens, address _to) external returns (uint[] memory amts);
```

Parameters:

| Name      | Type        | Description                          |
| --------- | ----------- | ------------------------------------ |
| `_posId`  | `uint256`   | position id to claim pending rewards |
| `_tokens` | `address[]` | array of reward tokens to claim      |
| `_to`     | `address`   | address to receive the reward tokens |

Returns:

| Name   | Type        | Description                   |
| ------ | ----------- | ----------------------------- |
| `amts` | `uint256[]` | array of reward token amounts |

### setPosViewer

Set a new viewer to the position.

{% hint style="info" %}
Can only be called by an authorized party of the position.
{% endhint %}

```solidity
function setPosViewer(uint _posId, address _viewer) external;
```

Parameters:

| Name      | Type      | Description                           |
| --------- | --------- | ------------------------------------- |
| `_posId`  | `uint256` | position id to set new viewer address |
| `_viewer` | `address` | new viewer address to set             |


# LendingPool

INIT lending pool contract.

## View Functions

### core

InitCore contract address.

```solidity
function core() external view returns (address initCore);
```

### underlyingToken

Underlying token of the lending pool.

```solidity
function underlyingToken() external view returns (address underlyingToken);
```

### cash

Current liquidity available for borrow.

```solidity
function cash() external view returns (uint256 amt);
```

### totalDebt

Last stored total borrowed amount of underlying token amount, including borrow interest.

```solidity
function totalDebt() external view returns (uint256 totalDebt);
```

### totalDebtShares

Last stored total debt shares.

```solidity
function totalDebtShares() external view returns (uint256 totalDebtShares);
```

### irm

Interest rate model contract address of lending pool.

```solidity
function irm() external view returns (address interestRateModel);
```

### lastAccruedTime

Last stored timestamp that accrue borrow interest.

```solidity
function lastAccruedTime() external view returns (uint256 lastAccruedTimestamp);
```

### reserveFactor\_e18

Reserve factor in `10^18` precision.

```solidity
function reserveFactor_e18() external view returns (uint256 factor);
```

### treasury

INIT treasury contract address.

```solidity
function treasury() external view returns (address treasury);
```

### decimals

inToken decimal (currently equals to`8 + underlyingToken.decimals()`).

```solidity
function decimals() external view returns (uint256 decimal);
```

### debtAmtToShareStored

Convert debt amount to debt shares (rounded up) without interest accrual. For interest accrual, use [debtAmtToShareCurrent](#debtamttosharecurrent).

```solidity
function debtAmtToShareStored(uint _amt) external view returns (uint shares);
```

### debtShareToAmtStored

Convert debt amount to debt shares (rounded up) without interest accrual. For interest accrual, use [debtShareToAmtCurrent](#debtsharetoamtcurrent).

```solidity
function debtShareToAmtStored(uint _shares) external view returns (uint amt);
```

### toShares

Convert the underlying token amount to inToken amount (rounded down) without interest accrual. For interest accrual, use [toShareCurrent](#tosharecurrent).

```solidity
function toShares(uint _amt) external view returns (uint shares);
```

### toAmt

Convert inToken amount to underlying token amount (rounded down) without interest accrual. For interest accrual, use [toAmtCurrent](#toamtcurrent).

```solidity
function toAmt(uint _shares) external view returns (uint amt);
```

### getBorrowRate\_e18

Get current borrow interest in `10^18` precision.

```solidity
function getBorrowRate_e18() external view returns (uint borrowRate_e18);
```

### getSupplyRate\_e18

Get current supply interest in `10^18` precision.

```solidity
function getSupplyRate_e18() external view returns (uint supplyRate_e18);
```

### totalAsset

Get the total underlying token amount lent into the lending pool, including borrow interest since last accrued timestamp.

```solidity
function totalAssets() external view returns (uint totalAsset);
```

## External Functions

### accrueInterest

Accrue borrow interest and update last accrued timestamp.

```solidity
function accrueInterest() external;
```

### debtAmtToShareCurrent

Accrue interest and convert debt amount to debt shares (rounded up).

```solidity
function debtAmtToShareCurrent(uint256 _amt) external returns (shares);
```

Parameters:

| Name   | Type      | Description                           |
| ------ | --------- | ------------------------------------- |
| `_amt` | `uint256` | debt amount to convert to debt shares |

Returns:

| Name     | Type      | Description                                     |
| -------- | --------- | ----------------------------------------------- |
| `shares` | `uint256` | corresponding debt shares after accrue interest |

### debtShareToAmtCurrent

Accrue interest and convert debt shares to debt amount (rounded up).

```solidity
function debtShareToAmtCurrent(uint _shares) external returns (uint amt);
```

Parameters:

| Name      | Type      | Description                           |
| --------- | --------- | ------------------------------------- |
| `_shares` | `uint256` | debt shares to convert to debt amount |

Returns:

| Name  | Type      | Description                                     |
| ----- | --------- | ----------------------------------------------- |
| `amt` | `uint256` | corresponding debt amount after accrue interest |

### toSharesCurrent

Accrue borrow interest and convert the underlying token amount to inToken amount (rounded down).

{% hint style="warning" %}
This is not a view function.
{% endhint %}

```solidity
function toSharesCurrent(uint _amt) external returns (uint shares);
```

Parameters:

| Name   | Type      | Description                        |
| ------ | --------- | ---------------------------------- |
| `_amt` | `uint256` | underlying token amount to convert |

Returns:

| Name     | Type      | Description                                        |
| -------- | --------- | -------------------------------------------------- |
| `shares` | `uint256` | corresponding inToken amount after accrue interest |

### toAmtCurrent

Accrue borrow interest and convert the inToken amount to the underlying token amount (rounded down).

{% hint style="warning" %}
This is not a view function.
{% endhint %}

```solidity
function toAmtCurrent(uint _shares) external returns (uint amt);
```

Parameters:

| Name      | Type      | Description               |
| --------- | --------- | ------------------------- |
| `_shares` | `uint256` | inToken amount to convert |

Returns:

| Name  | Type      | Description                                                 |
| ----- | --------- | ----------------------------------------------------------- |
| `amt` | `uint256` | corresponding underlying token amount after accrue interest |


# Config

INIT Configuration contract.

## View Functions

### whitelistedWLps

Get whether the wrapped LP contract address is supported.

```solidity
function whitelistedWLps(address _wlp) external view returns (bool);
```

### getModeConfig

Get mode's configuration.

{% hint style="info" %}
If the mode does not exist, then the return values will be Solidity's default values (0 values).
{% endhint %}

```solidity
function getModeConfig(uint16 _mode) external view returns (address[] memory collTokens, address[] memory borrTokens, uint maxHealthAfterLiq_e18, uint8 maxCollWLpCount);
```

Parameters:

| Name    | Type     | Description        |
| ------- | -------- | ------------------ |
| `_mode` | `uint16` | mode to get config |

Returns:

| Name                    | Type        | Description                                      |
| ----------------------- | ----------- | ------------------------------------------------ |
| `collTokens`            | `address[]` | supported collateral tokens in the mode          |
| `borrTokens`            | `address[]` | supported borrow tokens in the mode              |
| `maxHealthAfterLiq_e18` | `uint256`   | max health after liquidation allowed in the mode |
| `maxCollWLpCount`       | `uint8`     | max wLp collateral count allowed in the mode     |

### getPoolConfig

Get lending pool's configuration.

{% hint style="info" %}
If the lending pool does not exist, then the return values will be Solidity's default values (0 values).
{% endhint %}

```solidity
struct PoolConfig {
    uint128 supplyCap; // pool supply cap
    uint128 borrowCap; // pool borrow cap
    bool canMint; // pool mint status
    bool canBurn; // pool burn status
    bool canBorrow; // pool borrow status
    bool canRepay; // pool repay status
    bool canFlash; // pool flash status
}

function getPoolConfig(address _pool) external view returns (PoolConfig memory config);
```

Parameters:

| Name    | Type      | Description                               |
| ------- | --------- | ----------------------------------------- |
| `_pool` | `address` | lending pool address to get configuration |

Returns:

| Name     | Type         | Description                                                                                                                                                               |
| -------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `config` | `PoolConfig` | <p>pool configuration, containing:<br>- supply cap<br>- borrow cap<br>- can mint flag<br>- can burn flag<br>- can borrow flag<br>- can repay flag<br>- can flash flag</p> |

### isAllowedForBorrow

Get whether the lending pool is allowed to borrow in the specified mode.

```solidity
function isAllowedForBorrow(uint16 _mode, address _pool) external view returns (bool flag);
```

Parameters:

| Name    | Type      | Description                   |
| ------- | --------- | ----------------------------- |
| `_mode` | `uint16`  | mode to check                 |
| `_pool` | `address` | lending pool address to check |

Returns:

| Name   | Type   | Description                                                             |
| ------ | ------ | ----------------------------------------------------------------------- |
| `flag` | `bool` | boolean flag whether the lending pool is allowed for borrow in the mode |

### isAllowedForCollateral

Get whether the lending pool is allowed for collateral in the specified mode.

```solidity
function isAllowedForCollateral(uint16 _mode, address _pool) external view returns (bool flag);
```

Parameters:

| Name    | Type      | Description                   |
| ------- | --------- | ----------------------------- |
| `_mode` | `uint16`  | mode to check                 |
| `_pool` | `address` | lending pool address to check |

Returns:

| Name   | Type   | Description                                                                 |
| ------ | ------ | --------------------------------------------------------------------------- |
| `flag` | `bool` | boolean flag whether the lending pool is allowed for collateral in the mode |

### getTokenFactors

Get token factors for the specified mode and lending pool.

{% hint style="info" %}
If the mode does not exist, then the return values will be Solidity's default values (0 values).
{% endhint %}

```solidity
struct TokenFactors {
    uint128 collFactor_e18; // collateral factor in 1e18 (1e18 = 100%)
    uint128 borrFactor_e18; // borrow factor in 1e18 (1e18 = 100%)
}

function getTokenFactors(uint16 _mode, address _pool) external view returns (TokenFactors memory factors);
```

Parameters:

| Name    | Type      | Description                               |
| ------- | --------- | ----------------------------------------- |
| `_mode` | `uint16`  | mode to get token factors                 |
| `_pool` | `address` | lending pool address to get token factors |

Returns:

| Name           | Type           | Description                                                               |
| -------------- | -------------- | ------------------------------------------------------------------------- |
| `tokenFactors` | `TokenFactors` | <p>token factors including:<br>- collFactor\_e18<br>- borrFactor\_e18</p> |

### getMaxHealthAfterLiq\_e18

Get mode's max health allowed after liquidation with `10^18` precision.

{% hint style="info" %}
If the mode does not exist, then the return values will be Solidity's default values (0 values).
{% endhint %}

```solidity
function getMaxHealthAfterLiq_e18(uint16 _mode) external view returns (uint maxHealthAfterLiq_e18);
```

Parameters:

| Name    | Type     | Description                              |
| ------- | -------- | ---------------------------------------- |
| `_mode` | `uint16` | mode to get max health after liquidation |

Returns:

| Name                    | Type      | Description                                                         |
| ----------------------- | --------- | ------------------------------------------------------------------- |
| `maxHealthAfterLiq_e18` | `uint256` | mode's max health allowed after liquidation with `10^18` precision. |

### getModeStatus

Get the mode's status.

{% hint style="info" %}
If the mode does not exist, then the return values will be Solidity's default values (0 values).
{% endhint %}

```solidity
struct ModeStatus {
    bool canCollateralize; // mode collateralize status
    bool canDecollateralize; // mode decollateralize status
    bool canBorrow; // mode borrow status
    bool canRepay; // mode repay status
}

function getModeStatus(uint16 _mode) external view returns (ModeStatus memory modeStatus);
```

Parameters:

| Name    | Type     | Description        |
| ------- | -------- | ------------------ |
| `_mode` | `uint16` | mode to get status |

Returns:

| Name         | Type         | Description                                                                                                                      |
| ------------ | ------------ | -------------------------------------------------------------------------------------------------------------------------------- |
| `modeStatus` | `ModeStatus` | <p>mode status including:<br>- can collateralize flag<br>- can decollateralize flag<br>- can borrow flag<br>- can repay flag</p> |

### getModeMaxCollWLpCount

Get a mode's max collateral wrapped LP count

```solidity
function getModeMaxCollWLpCount(uint16 _mode) external view returns (uint8 count);
```

Parameters:

| Name    | Type     | Description                                 |
| ------- | -------- | ------------------------------------------- |
| `_mode` | `uint16` | mode to get max collateral wrapped LP count |

Returns:

| Name    | Type    | Description                     |
| ------- | ------- | ------------------------------- |
| `count` | `uint8` | max collateral wrapped LP count |


# RiskManager

INIT risk manager contract.

## View Functions

### CORE

InitCore contract address.

```solidity
function CORE() external view returns (address initCore);
```

### getModeDebtShares

Get current mode debt shares.

```solidity
function getModeDebtShares(uint16 _mode, address _pool) external view returns (uint debtShares);
```

### getModeDebtAmtStored

Get mode debt amount without interest accrual. For interest accrual, use [getModeDebtAmtCurrent](#getmodedebtamtcurrent).

```solidity
function getModeDebtAmtStored(uint16 _mode, address _pool) external view returns (uint debtAmount);
```

### getModeDebtCeilingAmt

Get mode debt ceiling amount. Positions in a mode cannot have a total borrow more than the debt ceiling amount.

```solidity
function getModeDebtCeilingAmt(uint16 _mode, address _pool) external view returns (uint debtCeiling);
```

## External Functions

### getModeDebtAmtCurrent

Accrue interest and get mode debt amount.

```solidity
function getModeDebtAmtCurrent(uint16 _mode, address _pool) external returns (uint debtAmount);
```

Parameters:

| Name    | Type      | Description                     |
| ------- | --------- | ------------------------------- |
| `_mode` | `uint16`  | mode to get debt amount         |
| `_pool` | `address` | lending pool to get debt amount |

Returns:

| Name         | Type      | Description                                                |
| ------------ | --------- | ---------------------------------------------------------- |
| `debtAmount` | `uint256` | underlying token debt amount of mode after accrue interest |


# InitOracle

INIT oracle contract.

## View Functions

### primarySources

Get the primary oracle source for the given token address.

{% hint style="info" %}
If the token is not supported, the primary source will be Solidity's default value (0 value).
{% endhint %}

```solidity
function primarySources(address _token) external view returns (address primarySource);
```

Parameters:

| Name     | Type      | Description                                |
| -------- | --------- | ------------------------------------------ |
| `_token` | `address` | token address to get primary oracle source |

Returns:

| Name            | Type      | Description                   |
| --------------- | --------- | ----------------------------- |
| `primarySource` | `address` | primary source oracle address |

### secondarySources

Get the secondary oracle source for the given token address.

{% hint style="info" %}
If the token is not supported, the secondary source will be Solidity's default value (0 value).
{% endhint %}

```solidity
function secondarySources(address _token) external view returns (address secondarySource);
```

Parameters:

| Name     | Type      | Description                                  |
| -------- | --------- | -------------------------------------------- |
| `_token` | `address` | token address to get secondary oracle source |

Returns:

| Name              | Type      | Description                    |
| ----------------- | --------- | ------------------------------ |
| `secondarySource` | `address` | seconary source oracle address |

### maxPriceDeviations\_e18

Get the maximum price deviation allowed between the sources for the given token address, with `10^18` precision.

```solidity
function maxPriceDeviations_e18(address _token) external view returns (uint maxPriceDeviation_e18);
```

Parameters:

| Name     | Type      | Description                              |
| -------- | --------- | ---------------------------------------- |
| `_token` | `address` | token address to get max price deviation |

Returns:

| Name                    | Type      | Description                                    |
| ----------------------- | --------- | ---------------------------------------------- |
| `maxPriceDeviation_e18` | `uint256` | maximum price deviation with `10^18` precision |

## External Functions

### getPrice\_e36

Get the price for a specified token, with `10^36` precision.

```solidity
function getPrice_e36(address _token) external view returns (uint price_e36);
```

Parameters:

| Name     | Type      | Description                |
| -------- | --------- | -------------------------- |
| `_token` | `address` | token address to get price |

Results:

| Name        | Type      | Description                        |
| ----------- | --------- | ---------------------------------- |
| `price_e36` | `uint256` | token price with `10^36` precision |

### getPrices\_e36

Get prices for the specified tokens, with `10^36` precision.

```solidity
function getPrices_e36(address[] calldata _tokens) external view returns (uint[] memory prices_e36);
```

Parameters:

| Name      | Type        | Description                         |
| --------- | ----------- | ----------------------------------- |
| `_tokens` | `address[]` | array of token address to get price |

Results:

| Name         | Type        | Description                                  |
| ------------ | ----------- | -------------------------------------------- |
| `prices_e36` | `uint256[]` | array of token prices with `10^36` precision |


# LiqIncentiveCalculator

Liquidation Incentive Calculator contract.

## View Functions

### maxLiqIncentiveMultiplier\_e18

Get maximum liquidation incentive multiplier with `10^18` precision. (`1e18 = 100%`)

{% hint style="info" %}
This configuration is global and applies to all modes.
{% endhint %}

```solidity
function maxLiqIncentiveMultiplier_e18() external returns (uint maxLiqIncentiveMultiplier_e18);
```

### minLiqIncentiveMultiplier\_e18

Get a mode's minimum liquidation incentive multiplier with `10^18` precision. (`1e18 = 100%`)

```solidity
function minLiqIncentiveMultiplier_e18(uint16 _mode) external returns (uint minLiqIncentiveMultiplier_e18);
```

### modeLiqIncentiveMultiplier\_e18

Get a mode's liquidation incentive multiplier with `10^18` precision. (`1e18 = 100%`)

{% hint style="info" %}
This should be used in conjunction with `tokenLiqIncentiveMultiplier_e18`.
{% endhint %}

```solidity
function modeLiqIncentiveMultiplier_e18(uint16 _mode) external returns (uint modeLiqIncentiveMultiplier_e18);
```

### tokenLiqIncentiveMultiplier\_e18

Get a mode's token liquidation incentive multiplier with `10^18` precision. (`1e18 = 100%`)

{% hint style="info" %}
This should be used in conjunction with `modeLiqIncentiveMultiplier_e18`.&#x20;
{% endhint %}

```solidity
function tokenLiqIncentiveMultiplier_e18(uint16 _mode) external returns (uint tokenLiqIncentiveMultiplier_e18);
```


# DoubleSlopeIRM

Interest Rate Model contract.&#x20;

## View Functions

### BASE\_BORR\_RATE\_E18

Base borrow rate with `10^18` precision (in rate per second).

```solidity
function BASE_BORR_RATE_E18() external view returns (uint256);
```

### BORR\_RATE\_MULTIPLIER\_E18

Borrow rate multiplier for utilization rate below the optimal utilization rate, with `10^18` precision (in rate per second).

```solidity
function BORR_RATE_MULTIPLIER_E18() external view returns (uint256);
```

### JUMP\_UTIL\_E18

Jump utilization rate with `10^18` precision.&#x20;

```solidity
function JUMP_UTIL_E18() external view returns (uint256);
```

### JUMP\_MULTIPLIER\_E18

Jump multiplier with `10^18` precision. This is a jump multiplier increment from the jump utilization point.

```solidity
function JUMP_MULTIPLIER_E18() external view returns (uint256);
```


# InitErrors

INIT error codes (e.g. `INC#123`) and reasons.

```solidity
// Common
uint internal constant ZERO_VALUE = 100;
uint internal constant NOT_INIT_CORE = 101;
uint internal constant SLIPPAGE_CONTROL = 102;
uint internal constant CALL_FAILED = 103;
uint internal constant NOT_OWNER = 104;
uint internal constant NOT_WNATIVE = 105;
uint internal constant ALREADY_SET = 106;
uint internal constant NOT_WHITELISTED = 107;

// Input
uint internal constant ARRAY_LENGTH_MISMATCHED = 200;
uint internal constant INPUT_TOO_LOW = 201;
uint internal constant INPUT_TOO_HIGH = 202;
uint internal constant INVALID_INPUT = 203;
uint internal constant INVALID_TOKEN_IN = 204;
uint internal constant INVALID_TOKEN_OUT = 205;
uint internal constant NOT_SORTED_OR_DUPLICATED_INPUT = 206;

// Core
uint internal constant POSITION_NOT_HEALTHY = 300;
uint internal constant POSITION_NOT_FOUND = 301;
uint internal constant LOCKED_MULTICALL = 302;
uint internal constant POSITION_HEALTHY = 303;
uint internal constant INVALID_HEALTH_AFTER_LIQUIDATION = 304;
uint internal constant FLASH_PAUSED = 305;
uint internal constant INVALID_FLASHLOAN = 306;
uint internal constant NOT_AUTHORIZED = 307;
uint internal constant INVALID_CALLBACK_ADDRESS = 308;

// Lending Pool
uint internal constant MINT_PAUSED = 400;
uint internal constant REDEEM_PAUSED = 401;
uint internal constant BORROW_PAUSED = 402;
uint internal constant REPAY_PAUSED = 403;
uint internal constant NOT_ENOUGH_CASH = 404;
uint internal constant INVALID_AMOUNT_TO_REPAY = 405;
uint internal constant SUPPLY_CAP_REACHED = 406;
uint internal constant BORROW_CAP_REACHED = 407;

// Config
uint internal constant INVALID_MODE = 500;
uint internal constant TOKEN_NOT_WHITELISTED = 501;
uint internal constant INVALID_FACTOR = 502;

// Position Manager
uint internal constant COLLATERALIZE_PAUSED = 600;
uint internal constant DECOLLATERALIZE_PAUSED = 601;
uint internal constant MAX_COLLATERAL_COUNT_REACHED = 602;
uint internal constant NOT_CONTAIN = 603;
uint internal constant ALREADY_COLLATERALIZED = 604;

// Oracle
uint internal constant NO_VALID_SOURCE = 700;
uint internal constant TOO_MUCH_DEVIATION = 701;
uint internal constant MAX_PRICE_DEVIATION_TOO_LOW = 702;
uint internal constant NO_PRICE_ID = 703;
uint internal constant PYTH_CONFIG_NOT_SET = 704;
uint internal constant DATAFEED_ID_NOT_SET = 705;
uint internal constant MAX_STALETIME_NOT_SET = 706;
uint internal constant MAX_STALETIME_EXCEEDED = 707;
uint internal constant PRIMARY_SOURCE_NOT_SET = 708;

// Risk Manager
uint internal constant DEBT_CEILING_EXCEEDED = 800;

// Misc
uint internal constant UNIMPLEMENTED = 999;
```


# MoneyMarketHook

## View Functions

### CORE

InitCore contract address.

```solidity
function CORE() external view returns (address initCore);
```

### POS\_MANAGER

PosManager contract address.

```solidity
function POS_MANAGER() external view returns (address posManager);
```

### lastPosIds

Last opened position id (increasing from 0) of a user.

```solidity
function lastPosIds(address _user) external view returns (uint256 lastPosId);
```

### initPosIds

Mapped user's position id on money market hook to InitCore's position id.

```solidity
function initPosIds(address _user, uint256 _posId) external view returns (uint256 initPosId);
```

## External Functions

### execute

Main function to interact with the contract to handle interactions to InitCore.&#x20;

The function:

1. Create a position, if not existed
2. Perform `multicall` to InitCore, which performs:
   1. Decollateralize inToken from the position and redeem token in lending pool
   2. Withdraw from lending pool
   3. Change position mode, if specified
   4. Borrow tokens from lending pool
   5. Mint inToken from lending pool and collateralize to the position
3. Unwrap rebase tokens, if specified
4. Unwrap wrapped native token to native token, if specified

```solidity
function execute(OperationParams calldata _params) external payable returns (uint256 posId, uint256 initPosId, bytes[] memory results);
```

```solidity
struct RebaseHelperParams {
    address helper; // wrap helper address if address(0) then not wrap
    address tokenIn; // token to use in rebase helper
}

// NOTE: there is 3 types of deposit
// 1. deposit native token use msg.value for native token
// if amt > 0 mean user want to use wNative too
// 2. wrap rebase token to non-rebase token and deposit (using rebase helper)
// 3. deposit normal erc20 token
struct DepositParams {
    address pool; // lending pool to deposit
    uint amt; // token amount to deposit
    RebaseHelperParams rebaseHelperParams; // wrap params
}

struct WithdrawParams {
    address pool; // lending pool to withdraw
    uint shares; // shares to withdraw
    RebaseHelperParams rebaseHelperParams; // wrap params
    address to; // receiver to receive withdraw tokens
}

struct RepayParams {
    address pool; // lending pool to repay
    uint shares; // shares to repay
}

struct BorrowParams {
    address pool; // lending pool to borrow
    uint amt; // token amount to borrow
    address to; // receiver to receive borrow tokens
}

struct OperationParams {
    uint posId; //  position id to execute (0 to create new position)
    address viewer; // address to view position
    uint16 mode; // position mode to be used
    DepositParams[] depositParams; // deposit parameters
    WithdrawParams[] withdrawParams; // withdraw parameters
    BorrowParams[] borrowParams; // borrow parameters
    RepayParams[] repayParams; // repay parameters
    uint minHealth_e18; // minimum health to maintain after execute
    bool returnNative; // return native token or not (using balanceOf(address(this)))
}
```

Parameters:

| Name      | Type              | Description                        |
| --------- | ----------------- | ---------------------------------- |
| `_params` | `OperationParams` | parameters to execute the fucntion |

Returns:

| Name        | Type      | Description                                              |
| ----------- | --------- | -------------------------------------------------------- |
| `posId`     | `uint256` | running position id (per each user) on money market hook |
| `initPosId` | `uint256` | position id on InitCore                                  |
| `results[]` | `bytes`   | results of multicall to InitCore                         |


# LoopingHook

Looping Hook contract, which uses the same implementation as [MarginTradingHook](/contract-references/margintradinghook) contract.

## View Functions

### swapHelper

Get the swap helper contract that this contract swaps between quote and base assets.

```solidity
function swapHelper() external view returns (address swapHelper);
```

### lastOrderId

Last running order (take profit or stop loss) id.

```solidity
function lastOrderId() external view returns (uint256 orderId);
```

### getBaseAssetAndQuoteAsset

Get a unique base and quote assets from a pair of tokens.

```solidity
function getBaseAssetAndQuoteAsset(address _tokenA, address _tokenB) external view returns (address baseAsset, address quoteAsset);
```

### getMarginPos

Get a looping position.

```solidity
function getMarginPos(uint256 _initPosId) external view returns (MarginPos memory pos);
```

```solidity
struct MarginPos {
    address collPool; // lending pool to deposit holdToken
    address borrPool; // lending pool to borrow borrowToken
    address baseAsset; // base asset of position
    address quoteAsset; // quote asset of position
    bool isLongBaseAsset; // long base asset or not
}
```

## External Functions

### openPos

Open a new looping position by swapping `borrPool`'s underlying token into `collPool`'s underlying token via swap data `_data`.&#x20;

The fucntion perform `multicall` to InitCore:

1. borrow tokens&#x20;
2. callback (perform swap from borrow token to collateral token)&#x20;
3. deposit collateral tokens to lending pool
4. collateralize inTokens

The swap callback is routed back to this contract's `coreCallback` which performs a swap using `_data` on [`swapHelper`](#swaphelper) contract with slippage control `amtOut`.

```solidity
SwapInfo memory swapInfo = SwapInfo(_param.initPosId, SwapType.OpenExactIn, borrToken, collToken, _param.minAmtOut, _param.data);
multicallData[1] = abi.encodeWithSelector(IInitCore(CORE).callback.selector, address(this), 0, abi.encode(swapInfo));

struct SwapInfo {
    uint initPosId; // nft id
    SwapType swapType; // swap type
    address tokenIn; // token to swap
    address tokenOut; // token to receive from swap
    uint amtOut; // token amount out info for the swap
    bytes data; // swap data
}

enum SwapType {
    OpenExactIn,
    CloseExactIn,
    CloseExactOut
}
```

{% hint style="info" %}
NOTE: `_tokenIn` must be either `_borrPool`'s underlying token or `_collPool`'s underlying token.
{% endhint %}

```solidity
function openPos(
    uint16 _mode,
    address _viewer,
    address _tokenIn,
    uint256 _amtIn,
    address _borrPool,
    uint256 _borrAmt,
    address _collPool,
    bytes calldata _data,
    uint256 _minAmtOut
) external payable returns (uint256 posId, uint256 initPosId, uint256 amtOut);
```

| Name         | Type      | Description                                              |
| ------------ | --------- | -------------------------------------------------------- |
| `_mode`      | `uint16`  | mode to open a looping position                          |
| `_viewer`    | `address` | viewer address that represents the actual position owner |
| `_tokenIn`   | `address` | token to take from position owner                        |
| `_amtIn`     | `uint256` | amount of `tokenIn` to take from position owner          |
| `_borrPool`  | `address` | lending pool to borrow                                   |
| `_borrAmt`   | `uint256` | amount of `_borrPool`'s underlying token to borrow       |
| `_collPool`  | `address` | lending pool to use as collateral                        |
| `_data`      | `bytes`   | swap data to be used in InitCore's `callback` function   |
| `_minAmtOut` | `uint256` | min amount out from swap as slippage control             |

Returns:

| Name        | Type      | Description                                      |
| ----------- | --------- | ------------------------------------------------ |
| `posId`     | `uint256` | running position id for position owner           |
| `initPosId` | `uint256` | InitCore's position id                           |
| `amtOut`    | `uint256` | amount of token received from swap using `_data` |

### increasePos

Increase an existing position's size by taking token from position owner and/or borrow more tokens.

{% hint style="info" %}
`_collPool` and `borrPool` are fixed from the existing position.&#x20;
{% endhint %}

```solidity
function increasePos(
    uint256 _posId,
    address _tokenIn,
    uint256 _amtIn,
    uint256 _borrAmt,
    bytes calldata _data,
    uint256 _minAmtOut
) external payable returns (uint256 amtOut);
```

| Name         | Type      | Description                                                |
| ------------ | --------- | ---------------------------------------------------------- |
| `_posId`     | `uint256` | owner's position id on this hook to increase position size |
| `_tokenIn`   | `address` | token to take from position owner                          |
| `_amtIn`     | `uint256` | amount of `tokenIn` to take from position owner            |
| `_borrAmt`   | `uint256` | amount of `_borrPool`'s underlying token to borrow         |
| `_data`      | `bytes`   | swap data to be used in InitCore's `callback` function     |
| `_minAmtOut` | `uint256` | min amount out from swap as slippage control               |

Returns:

| Name     | Type      | Description                                      |
| -------- | --------- | ------------------------------------------------ |
| `amtOut` | `uint256` | amount of token received from swap using `_data` |

### addCollateral

Decrease position's leverage by adding more collateral token.

```solidity
function addCollateral(uint256 _posId, uint256 _amtIn) external payable;
```

Parameters:

| Name     | Type      | Description                                                       |
| -------- | --------- | ----------------------------------------------------------------- |
| `_posId` | `uint256` | owner's position id on this hook                                  |
| `_amtIn` | `uint256` | amount of collateral token's underlying token to take from  owner |

### removeCollateral

Increase position's leverage by removing collateral token.&#x20;

```solidity
function removeCollateral(uint _posId, uint256 _shares, bool _returnNative) external;
```

Parameters:

| Name            | Type      | Description                                                                        |
| --------------- | --------- | ---------------------------------------------------------------------------------- |
| `_posId`        | `uint256` | owner's position id on this hook                                                   |
| `_shares`       | `uint256` | amount of shares to remove collateral token                                        |
| `_returnNative` | `bool`    | whether to unwrap wrapped native token to native token to return to position owner |

### repayDebt

Decrease position's leverage by repaying borrow token.

```solidity
function repayDebt(uint256 _posId, uint256 _repayShares) external returns (uint256 repayAmt);
```

Parameters:

| Name           | Type      | Description                                                   |
| -------------- | --------- | ------------------------------------------------------------- |
| `_posId`       | `uint256` | owner's position id on this hook                              |
| `_repayShares` | `uint256` | amount of shares to repay borrow token to borrow lending pool |

Returns:

| Name       | Type      | Description                                              |
| ---------- | --------- | -------------------------------------------------------- |
| `repayAmt` | `uint256` | amount of underlying token of borrow lending pool repaid |

### reducePos

Reduce an existing position's size by withdrawing collateral and repaying borrow token. The withdrawn collateral token can be swapped to repay borrow token using `_data`. The user can specify which token to receive, if there is still left after swap.

```solidity
function reducePos(
    uint256 _posId,
    uint256 _collAmt,
    uint256 _repayShares,
    address _tokenOut,
    uint256 _minAmtOut,
    bool _returnNative,
    bytes calldata _data
) external returns (uint256 amtOut);
```

Parameters:

| Name            | Type      | Description                                                                                                  |
| --------------- | --------- | ------------------------------------------------------------------------------------------------------------ |
| `_posId`        | `uint256` | owner's position id on this hook                                                                             |
| `_collAmt`      | `uint256` | collateral amount to reduce from position                                                                    |
| `_repayShares`  | `uint256` | amount of shares to repay borrow token to borrow lending pool                                                |
| `_tokenOut`     | `address` | token to receive from reducing position (either collalteral's underlying token or borrow's underlying token) |
| `_minAmtOut`    | `uint256` | min amount out from swap as slippage control                                                                 |
| `_returnNative` | `bool`    | whether to unwrap wrapped native token to native token to return to position owner                           |
| `_data`         | `bytes`   | swap data to be used in InitCore's `callback` function                                                       |

Returns:

| Name     | Type      | Description                                      |
| -------- | --------- | ------------------------------------------------ |
| `amtOut` | `uint256` | amount of token received from swap using `_data` |


# MarginTradingHook

Coming Soon...


# Contract Addresses

##


# Blast

## Blast Specific Contracts

<table><thead><tr><th width="273">Contract</th><th>Address</th></tr></thead><tbody><tr><td>PointOperator (Multisig Point Operator Contract)</td><td><code>0xf62E7c831fc41C93B61C04c24152c433D6553236</code></td></tr><tr><td>WWETH  (Blast Gold Receiver Contract)</td><td><code>0xf683Ce59521AA464066783d78e40CD9412f33D21</code></td></tr><tr><td>WUSDB </td><td><code>0x4B246c4C41c4e5eC1d4A8453c313cbc57Bf0993A</code></td></tr></tbody></table>

## Core Contracts

<table><thead><tr><th width="341">Contract</th><th width="460">Proxy Address</th></tr></thead><tbody><tr><td>InitCore (Blast Gold Receiver Contract)</td><td><code>0xa7d36f2106b5a5D528a7e2e7a3f436d703113A10</code></td></tr><tr><td>PosManager</td><td><code>0xA0e172f8BdC18854903959b8f7f73F0D332633fe</code></td></tr><tr><td>Config</td><td><code>0x57200D2B0C36244B3c8EBf99e5724c7536cea2F7</code></td></tr><tr><td>RiskManager</td><td><code>0xD97Bb363b5B925cF95acD7c463045750514C68C1</code></td></tr><tr><td>InitOracle</td><td><code>0xe31686E5590E4FD5D5418Fe3c4e9368EfD75e2eF</code></td></tr><tr><td>LiqIncentiveCalculator</td><td><code>0xed9d7E89309B060e876098F4695aB9fd3011904b</code></td></tr><tr><td>AccessControlManager</td><td><code>0x265DAA697489968AEbd650c665F4Fb241b560785</code></td></tr><tr><td>InitLens</td><td><code>0x56Fba2cC045C02d7adAE5A9dfDce795900b2860E</code></td></tr><tr><td>MoneyMarketHook</td><td><code>0xC02819a157320Ba2859951A1dfc1a5E76c424dD4</code></td></tr><tr><td>LoopingHook</td><td><code>0x85babafa73c3499247d937F7ABB877e0e6250f68</code></td></tr><tr><td>MarginTradingHook</td><td><code>0x5313428dF205273dCD4100B2fbC0803ABa13FF28</code></td></tr></tbody></table>

## Lending Pools and Interest Rate Models

<table><thead><tr><th width="146">Lending Pool</th><th width="452">Address</th><th width="458">Interest Rate Model</th></tr></thead><tbody><tr><td>ETH</td><td><code>0xD20989EB39348994AA99F686bb4554090d0C09F3</code></td><td><code>0x72eE68Fc1D6650b32314188321e92a8B4F3b552A</code></td></tr><tr><td>USDB</td><td><code>0xc5EaC92633aF47c0023Afa0116500ab86FAB430F</code></td><td><code>0x95b8640e5a9a496427D089b14F6736de212852D0</code></td></tr><tr><td>ezETH</td><td><code>0x027296054F8181fbC0Df26174E7640652bB28b40</code></td><td><code>0xD501a57d404a4beDB2c911512D79b9087Ad6bf39</code></td></tr><tr><td>wrsETH</td><td><code>0x17f18794ecE38EE3F17Ab7Bcc41CF99486A3B85c</code></td><td><code>0xD501a57d404a4beDB2c911512D79b9087Ad6bf39</code></td></tr><tr><td>weETH</td><td><code>0xCd5fC13390B55aAA21A2C92aC3ff37FB2E22012E</code></td><td><code>0xD501a57d404a4beDB2c911512D79b9087Ad6bf39</code></td></tr></tbody></table>


# Mantle

## Core Contracts

<table><thead><tr><th width="368">Contract</th><th width="460">Proxy Address</th><th width="188">Mantlescan (Proxy)</th><th width="176">Mantlescan (Impl)</th></tr></thead><tbody><tr><td>InitCore</td><td><code>0x972BcB0284cca0152527c4f70f8F689852bCAFc5</code></td><td><a href="https://explorer.mantle.xyz/address/0x972BcB0284cca0152527c4f70f8F689852bCAFc5">Mantlescan</a></td><td><a href="https://explorer.mantle.xyz/address/0xf8B8552D52986F06Ffaf14Bc88bfCF6DCBDbA05D">Mantlescan</a></td></tr><tr><td>PosManager</td><td><code>0x0e7401707CD08c03CDb53DAEF3295DDFb68BBa92</code></td><td><a href="https://explorer.mantle.xyz/address/0x0e7401707CD08c03CDb53DAEF3295DDFb68BBa92">Mantlescan</a></td><td><a href="https://explorer.mantle.xyz/address/0x995b3D3CF83d5A0040b56b0201d3d2Db6E369DBF">Mantlescan</a></td></tr><tr><td>Config</td><td><code>0x007F91636E0f986068Ef27c950FA18734BA553Ac</code></td><td><a href="https://explorer.mantle.xyz/address/0x007F91636E0f986068Ef27c950FA18734BA553Ac">Mantlescan</a></td><td><a href="https://explorer.mantle.xyz/address/0x1dBD1e94373b3163F4376d6ae1A39DB9fdA334cB">Mantlescan</a></td></tr><tr><td>LendingPool</td><td><code>0x423bB7577BCf594df986D9646B44D3144b3329FD</code></td><td></td><td><a href="https://explorer.mantle.xyz/address/0x423bB7577BCf594df986D9646B44D3144b3329FD">Mantlescan</a></td></tr><tr><td>RiskManager</td><td><code>0x0c03cd3e8b669680Bf306Fc72F1dc2cAC592f951</code></td><td><a href="https://explorer.mantle.xyz/address/0x0c03cd3e8b669680Bf306Fc72F1dc2cAC592f951">Mantlescan</a></td><td><a href="https://explorer.mantle.xyz/address/0xf3416748553EA93643aa8B5A7879F2C40018002b">Mantlescan</a></td></tr><tr><td>InitOracle</td><td><code>0x4E195A32b2f6eBa9c4565bA49bef34F23c2C0350</code></td><td><a href="https://explorer.mantle.xyz/address/0x4E195A32b2f6eBa9c4565bA49bef34F23c2C0350">Mantlescan</a></td><td><a href="https://explorer.mantle.xyz/address/0x7928419135cE5427858F0F5c0cbA3151b9b14f81">Mantlescan</a></td></tr><tr><td>LiqIncentiveCalculator</td><td><code>0x66BDbf2Eefc84f83b476dB238574ca5Cb00550aD</code></td><td><a href="https://explorer.mantle.xyz/address/0x66BDbf2Eefc84f83b476dB238574ca5Cb00550aD">Mantlescan</a></td><td><a href="https://explorer.mantle.xyz/address/0xDDC99aeef7D5F87118A3A2636F7D0FB6c60daCF3">Mantlescan</a></td></tr><tr><td>AccessControlManager</td><td><code>0xCE3292cA5AbbdFA1Db02142A67CFFc708530675a</code></td><td></td><td><a href="https://explorer.mantle.xyz/address/0xCE3292cA5AbbdFA1Db02142A67CFFc708530675a">Mantlescan</a></td></tr><tr><td>InitLens</td><td><code>0x7d2b278b8ef87bEb83AeC01243ff2Fed57456042</code></td><td></td><td><a href="https://explorer.mantle.xyz/address/0x7d2b278b8ef87bEb83AeC01243ff2Fed57456042">Mantlescan</a></td></tr><tr><td>MoneyMarketHook</td><td><code>0xf82CBcAB75C1138a8F1F20179613e7C0C8337346</code></td><td><a href="https://explorer.mantle.xyz/address/0xf82CBcAB75C1138a8F1F20179613e7C0C8337346">Mantlescan</a></td><td><a href="https://explorer.mantle.xyz/address/0x06cAb8cbD9bb02dB40eBa963A8C38d4C5924dA84">Mantlescan</a></td></tr><tr><td>LoopingHook (swap via MerchantMoe)</td><td><code>0xEfB43E833058Cd3464497e57428eFb00dB000763</code></td><td><a href="https://explorer.mantle.xyz/address/0xEfB43E833058Cd3464497e57428eFb00dB000763">Mantlescan</a></td><td><a href="https://explorer.mantle.xyz/address/0x497949e7a3cD1352980a1b2c27dA27b5A71C94bD">Mantlescan</a></td></tr><tr><td>LoopingHook (swap via Agni)</td><td><code>0x9567940746fdA24aa98160Ae3dACdbD51dae7D33</code></td><td><a href="https://explorer.mantle.xyz/address/0x9567940746fdA24aa98160Ae3dACdbD51dae7D33">Mantlescan</a></td><td><a href="https://explorer.mantle.xyz/address/0x497949e7a3cD1352980a1b2c27dA27b5A71C94bD">Mantlescan</a></td></tr><tr><td>LoopingHook (swap via FusionX)</td><td><code>0xe4Fe22F64F37bA62BDDFeD3B05DaBcc1F01Ad1Ad</code></td><td><a href="https://explorer.mantle.xyz/address/0xe4Fe22F64F37bA62BDDFeD3B05DaBcc1F01Ad1Ad">Mantlescan</a></td><td><a href="https://explorer.mantle.xyz/address/0x497949e7a3cD1352980a1b2c27dA27b5A71C94bD">Mantlescan</a></td></tr><tr><td>Looping Hook (swap via Universal router)</td><td><code>0x7fa704E73262e5A9f48382087F69C6Aba0408eAA</code></td><td><a href="https://explorer.mantle.xyz/address/0x7fa704E73262e5A9f48382087F69C6Aba0408eAA">Mantlescan</a></td><td><a href="https://explorer.mantle.xyz/address/0x917A9fA5606e7Bb6a9Bf7eb0AbB00FE152D3DC14?tab=txs">Mantlescan</a></td></tr></tbody></table>

## Lending Pools and Interest Rate Models

<table><thead><tr><th width="146">Lending Pool</th><th width="452">Address</th><th width="138">Mantlescan</th><th width="458">Interest Rate Model</th></tr></thead><tbody><tr><td>WETH</td><td><code>0x51AB74f8B03F0305d8dcE936B473AB587911AEC4</code></td><td><a href="https://explorer.mantle.xyz/address/0x51AB74f8B03F0305d8dcE936B473AB587911AEC4">Mantlescan</a></td><td><code>0x59448551523A4d244f26759e48d83e432Ed1FDBF</code></td></tr><tr><td>WBTC</td><td><code>0x9c9F28672C4A8Ad5fb2c9Aca6d8D68B02EAfd552</code></td><td><a href="https://explorer.mantle.xyz/address/0x9c9F28672C4A8Ad5fb2c9Aca6d8D68B02EAfd552">Mantlescan</a></td><td><code>0x71e0B2E5DDcDd509D1dA7029b09D310c108B2cF6</code></td></tr><tr><td>WMNT</td><td><code>0x44949636f778fAD2b139E665aee11a2dc84A2976</code></td><td><a href="https://explorer.mantle.xyz/address/0x44949636f778fAD2b139E665aee11a2dc84A2976">Mantlescan</a></td><td><code>0xF25E438eFad5a865A72f9FE39Ffd9aeC1F18398e</code></td></tr><tr><td>USDC</td><td><code>0x00A55649E597d463fD212fBE48a3B40f0E227d06</code></td><td><a href="https://explorer.mantle.xyz/address/0x00A55649E597d463fD212fBE48a3B40f0E227d06">Mantlescan</a></td><td><code>0x0959a65AB35cbF335AbAdC7793e2E8CAC81aE7e4</code></td></tr><tr><td>USDT</td><td><code>0xadA66a8722B5cdfe3bC504007A5d793e7100ad09</code></td><td><a href="https://explorer.mantle.xyz/address/0xadA66a8722B5cdfe3bC504007A5d793e7100ad09">Mantlescan</a></td><td><code>0x00fA41248F6c3A26863ec56634Fe78Ad4E4748EC</code></td></tr><tr><td>METH</td><td><code>0x5071c003bB45e49110a905c1915EbdD2383A89dF</code></td><td><a href="https://explorer.mantle.xyz/address/0x5071c003bB45e49110a905c1915EbdD2383A89dF">Mantlescan</a></td><td><code>0x32f533EAbD0B128e7EbE391DcC3F012701618B62</code></td></tr><tr><td>USDY</td><td><code>0xf084813F1be067d980a0171F067f084f27B3F63A</code></td><td><a href="https://explorer.mantle.xyz/address/0xf084813F1be067d980a0171F067f084f27B3F63A">Mantlescan</a></td><td><code>0xEEd8A04876ceeE12DDaf4Fd1eb59663A62D9BE34</code></td></tr><tr><td>USDe</td><td><code>0x3282437C436eE6AA9861a6A46ab0822d82581b1c</code></td><td><a href="https://explorer.mantle.xyz/address/0x3282437C436eE6AA9861a6A46ab0822d82581b1c">Mantlescan</a></td><td><code>0xF525F9a23DB5Fa9BeA0f64E5427A103752977A0C</code></td></tr><tr><td>fBTC</td><td><code>0x233493e9dc68e548ac27e4933a600a3a4682c0c3</code></td><td><a href="https://explorer.mantle.xyz/address/0x233493e9dc68e548ac27e4933a600a3a4682c0c3">Mantlescan</a></td><td><code>0xc01c9933763C8105f4510BCD486CCC9Fb82Ae25B</code></td></tr></tbody></table>


