> For the complete documentation index, see [llms.txt](https://dev.init.capital/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://dev.init.capital/contract-references/loopinghook.md).

# LoopingHook

Looping Hook contract, which uses the same implementation as [MarginTradingHook](/contract-references/margintradinghook.md) 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` |
