# Router

## Contents

* [**Contract Details**](#contract-details)
* [**Structs**](#structs)
  * [ExactInputParams](#struct-exactinputparams)
  * [ExactOutputParams](#struct-exactoutputparams)
  * [PoolParams](#struct-poolparams)
* [**Functions**](#functions)
  * [factory()](#fn-factory)
  * [position()](#fn-position)
  * [exactInput()](#fn-exactinput)
  * [exactOutput()](#fn-exactoutput)
  * [getOrCreatePoolAndAddLiquidity()](#fn-getorcreatepoolandaddliquidity)
  * [addLiquidityToPool()](#fn-addliquiditytopool)
  * [addLiquidityWTickLimits()](#fn-addliquiditywticklimits)
  * [migrateBinsUpStack()](#fn-migratebinsupstack)
  * [removeLiquidity()](#fn-removeliquidity)

## **Contract Details** <a href="#contract-details" id="contract-details"></a>

* **Name :** *IRouter*
* **Solidity Version :** *^0.8.0*
* *SPDX License-Identifier : GPL-2.0-or-later*
* **`Router` is Deployed to**
  * Ethereum: [`0xbBF1EE38152E9D8e3470Dc47947eAa65DcA94913`](https://etherscan.io/address/0xbBF1EE38152E9D8e3470Dc47947eAa65DcA94913#code)
  * ZKSync Era: [`0x39E098A153Ad69834a9Dac32f0FCa92066aD03f4`](https://explorer.zksync.io/address/0x39E098A153Ad69834a9Dac32f0FCa92066aD03f4#contract)
* Code: [Github](https://github.com/maverickprotocol/router-v1/tree/main/contracts)

## **Structs** <a href="#structs" id="structs"></a>

### PoolParams <a href="#struct-poolparams" id="struct-poolparams"></a>

```solidity
struct PoolParams {
    uint256 fee;
    uint256 tickSpacing;
    int256 lookback;
    int32 activeTick;
    IERC20 tokenA;
    IERC20 tokenB;
}
```

* `fee` : The fee value `uint256` associated with the pool.
* `tickSpacing` : The tick spacing value `uint256` for the pool.
* `lookback` : The lookback value `int256` for the pool.
* `activeTick` : The active tick value `int32` for the pool.
* `tokenA` : The ERC20 token A `address` associated with the pool.
* `tokenB` : The ERC20 token B `address` associated with the pool.

### ExactInputParams <a href="#struct-exactinputparams" id="struct-exactinputparams"></a>

```solidity
struct ExactInputParams {
    bytes path;
    address recipient;
    uint256 deadline;
    uint256 amountIn;
    uint256 amountOutMinimum;
}
```

* `path` : A `bytes` string representing the path of tokens to swap.
* `recipient` : The `address` where the swapped tokens will be sent.
* `deadline` : The deadline timestamp (in seconds) `uint256` until which the swap can be executed.
* `amountIn` : The amount of the input token `uint256` to be swapped.
* `amountOutMinimum` : The minimum acceptable amount of the output token `uint256` specified to prevent infinite slippage.

### ExactOutputParams <a href="#struct-exactoutputparams" id="struct-exactoutputparams"></a>

```solidity
struct ExactOutputParams {
    bytes path;
    address recipient;
    uint256 deadline;
    uint256 amountOut;
    uint256 amountInMaximum;
}
```

* `path` : A `bytes` string representing the path of tokens to swap *(reversed)*.
* `recipient` : The `address` where the swapped tokens will be sent.
* `deadline` : The deadline timestamp (in seconds) `uint256` until which the swap can be executed.
* `amountOut` : The amount of the output token `uint256` desired.
* `amountInMaximum` : The maximum acceptable amount of the input token `uint256` required.

## **Functions** <a href="#functions" id="functions"></a>

### factory() <a href="#fn-factory" id="fn-factory"></a>

Returns the address of the factory.

```solidity
function factory() external view returns (IFactory);
```

* Returns :
  * IFactory : The `address` of the Factory

### position() <a href="#fn-position" id="fn-position"></a>

Returns the address of the Position NFT.

```solidity
function position() external view returns (IPosition);
```

* Returns
  * IPosition : The position NFT `address`

### exactInput() <a href="#fn-exactinput" id="fn-exactinput"></a>

Swaps `amountIn` of one token for as much as possible of another along the specified path.

```solidity
function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut);
```

* Parameters :
  * `params` : The parameters necessary for the multi-hop swap, encoded as `ExactInputParams` in calldata
* Returns :
  * `amountOut` : The amount of the received token in `uint256`

### exactOutput() <a href="#fn-exactoutput" id="fn-exactoutput"></a>

Swaps as little as possible of one token for `amountOut` of another along the specified path *(reversed)*.

```solidity
function exactOutput(ExactOutputParams calldata params) external payable returns (uint256 amountIn);
```

* Parameters :
  * `params` : The parameters necessary for the multi-hop swap, encoded as `ExactOutputParams` in calldata
* Returns :
  * `amountIn` : The amount of the input token in `uint256`

### getOrCreatePoolAndAddLiquidity() <a href="#fn-getorcreatepoolandaddliquidity" id="fn-getorcreatepoolandaddliquidity"></a>

Either gets an existing pool or creates a pool if it does not exist and adds liquidity to it.

```solidity
function getOrCreatePoolAndAddLiquidity(
    PoolParams calldata poolParams,
    uint256 tokenId,
    IPool.AddLiquidityParams[] calldata addParams,
    uint256 minTokenAAmount,
    uint256 minTokenBAmount,
    uint256 deadline
) external payable returns (uint256 receivingTokenId, uint256 tokenAAmount, uint256 tokenBAmount, IPool.BinDelta[] memory binDeltas);
```

* Parameters :
  * `poolParams` : Parameters of a pool with `poolParams`
  * `tokenId` : NFT ID of the token `uint256` that will hold LP balance. Use `0` to mint a new token
  * `addParams` : Parameters of liquidity addition with `addParams`
  * `minTokenAAmount` : Minimum amount of token A `uint256` to add. Reverts if not met
  * `minTokenBAmount` : Minimum amount of token B `uint256` to add. Reverts if not met
  * `deadline` : Epoch timestamp (in seconds) `uint256`
* Returns :
  * `receivingTokenId` : The ID `uint256` of the receiving token
  * `tokenAAmount` : The amount of token A `uint256`
  * `tokenBAmount` : The amount of token B `uint256`
  * `binDeltas` : An array of `BinDelta` structures

### addLiquidityToPool() <a href="#fn-addliquiditytopool" id="fn-addliquiditytopool"></a>

Adds liquidity to a pool.

```solidity
function addLiquidityToPool(
    IPool pool,
    uint256 tokenId,
    IPool.AddLiquidityParams[] calldata params,
    uint256 minTokenAAmount,
    uint256 minTokenBAmount,
    uint256 deadline
) external payable returns (uint256 receivingTokenId, uint256 tokenAAmount, uint256 tokenBAmount, IPool.BinDelta[] memory binDeltas);
```

* Parameters :
  * `pool` : Pool to add liquidity to `IPool`
  * `tokenId` : NFT ID of the token `uint256` that will hold LP balance. Use `0` to mint a new token
  * `params` : Parameters of liquidity addition with `params`
  * `minTokenAAmount` : Minimum amount of token A `uint256` to add. Reverts if not met
  * `minTokenBAmount` : Minimum amount of token B `uint256` to add. Reverts if not met
  * `deadline` : Epoch timestamp (in seconds) `uint256`
* Returns :
  * `receivingTokenId` : The ID of the receiving token `uint256`
  * `tokenAAmount` : The amount of token A `uint256`
  * `tokenBAmount` : The amount of token B `uint256`
  * `binDeltas` : An array of `BinDelta` structures

### addLiquidityWTickLimits() <a href="#fn-addliquiditywticklimits" id="fn-addliquiditywticklimits"></a>

Adds liquidity to a pool with active tick limits.

```solidity
function addLiquidityWTickLimits(
    IPool pool,
    uint256 tokenId,
    IPool.AddLiquidityParams[] calldata params,
    uint256 minTokenAAmount,
    uint256 minTokenBAmount,
    int32 minActiveTick,
    int32 maxActiveTick,
    uint256 deadline
) external payable returns (uint256 receivingTokenId, uint256 tokenAAmount, uint256 tokenBAmount, IPool.BinDelta[] memory binDeltas);
```

* Parameters :
  * `pool` : Pool to add liquidity to `IPool`
  * `tokenId` : NFT ID of the token `uint256` that will hold LP balance. Use `0` to mint a new token
  * `params` : Parameters of liquidity addition with `params`
  * `minTokenAAmount` : Minimum amount of token A `uint256` to add. Reverts if not met
  * `minTokenBAmount` : Minimum amount of token B `uint256` to add. Reverts if not met
  * `minActiveTick` : Lowest activeTick `int32` *(inclusive)* of the pool that will permit the transaction to pass
  * `maxActiveTick` : Highest activeTick `int32` *(inclusive)* of the pool that will permit the transaction to pass
  * `deadline` : Epoch timestamp *(in seconds)*
* Returns :
  * `receivingTokenId` : The ID of the receiving token `uint256`
  * `tokenAAmount` : The amount of token A `uint256`
  * `tokenBAmount` : The amount of token B `uint256`
  * `binDeltas` : An array of `BinDelta` structures

### migrateBinsUpStack() <a href="#fn-migratebinsupstack" id="fn-migratebinsupstack"></a>

Moves the head of input merged bins to the active bin.

```solidity
function migrateBinsUpStack(IPool pool, uint128[] calldata binIds, uint32 maxRecursion, uint256 deadline) external;
```

* Parameters :
  * `pool` : Pool to remove from with `IPool`
  * `binIds` : Array of `binIds` to migrate
  * `maxRecursion` : Maximum recursion depth `uint32` before returning; `0` means no maximum
  * `deadline` : Epoch timestamp *(in seconds)* `uint256`

### removeLiquidity() <a href="#fn-removeliquidity" id="fn-removeliquidity"></a>

Removes liquidity from a pool and receives WETH if one of the tokens is WETH.

```solidity
function removeLiquidity(
    IPool pool,
    address recipient,
    uint256 tokenId,
    IPool.RemoveLiquidityParams[] calldata params,
    uint256 minTokenAAmount,
    uint256 minTokenBAmount,
    uint256 deadline
) external returns (uint256 tokenAAmount, uint256 tokenBAmount, IPool.BinDelta[] memory binDeltas);
```

> Router must be approved for the withdrawing tokenId: `Position.approve(router, tokenId)`

* Parameters :
  * `pool` : Pool to remove from with `IPool`
  * `recipient` : `address` where the proceeds are sent. Use `zero` or router address to leave tokens in the router
  * `tokenId` : ID `uint256` of the position NFT that holds liquidity
  * `params` : Parameters of liquidity removal with `params`
  * `minTokenAAmount` : Minimum amount of token A `uint256` to receive. Reverts if not met
  * `minTokenBAmount` : Minimum amount of token B `uint256` to receive. Reverts if not met
  * `deadline` : Epoch timestamp *(in seconds)* `uint256`
* Returns :
  * `tokenAAmount` : The amount of token A `uint256` received
  * `tokenBAmount` : The amount of token B `uint256` received
  * `binDeltas` : An array of `BinDelta` structure
