# Router

## Overview

The `Router.sol`  allows for complex transaction sequences to be executed in a single transaction. It inherits from [`Dispatcher.sol`](#dispatcher) and `IERC3156FlashBorrower`. It primarily handles the execution of a sequence of commands, including flash loans within Spectra [Principal Tokens](https://dev.spectra.finance/technical-reference/contract-functions/principal-token).&#x20;

## Router Methods

### execute

Handles the execution of command sequence.

```solidity
function execute(
        bytes calldata commands,
        bytes[] calldata inputs
) external payable
```

<table><thead><tr><th width="185.33333333333331">Input Parameter</th><th width="188">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>commands</code></td><td>bytes calldata</td><td>A set of concatenated commands, each 1 byte in length</td></tr><tr><td><code>inputs</code></td><td>bytes[] calldata</td><td>An array of byte strings containing ABI encoded inputs for each command</td></tr></tbody></table>

### execute

Processes a batch of `commands` before a specified `deadline`. This method checks for deadline and then forwards the call to [`execute()`](#execute-1).

```solidity
function execute(
        bytes calldata commands,
        bytes[] calldata inputs,
        uint256 deadline
) external payable
```

<table><thead><tr><th width="190.33333333333331">Input Parameter</th><th width="190">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>commands</code></td><td>bytes calldata</td><td>A set of concatenated commands, each 1 byte in length</td></tr><tr><td><code>inputs</code></td><td>bytes[] calldata</td><td>An array of byte strings containing ABI encoded inputs for each command</td></tr><tr><td><code>deadline</code></td><td>uint256</td><td>The deadline by which the transaction must be executed</td></tr></tbody></table>

## View Methods

### previewRate

Simulates encoded commands along with provided inputs, and return the resulting rate.

```solidity
function previewRate(
        bytes calldata commands,
        bytes[] calldata inputs
) external view returns (uint256 output)
```

<table><thead><tr><th width="190.33333333333331">Input Parameter</th><th width="190">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>commands</code></td><td>bytes calldata</td><td>A set of concatenated commands, each 1 byte in length</td></tr><tr><td><code>inputs</code></td><td>bytes[] calldata</td><td>An array of byte strings containing ABI encoded inputs for each command</td></tr><tr><td><code>outputRate</code></td><td>uint256</td><td>The preview rate value, which represents the amount of output token obtained at the end of execution for each wei of input token spent at the start of execution, multiplied by 1 ray unit.</td></tr></tbody></table>

{% hint style="warning" %}
The following commands are not supported by `previewRate():`

* `FLASH_LOAN`
* `CURVE_SPLIT_IBT_LIQUIDITY`
* `CURVE_ADD_LIQUIDITY`
* `CURVE_REMOVE_LIQUIDITY`
* `CURVE_REMOVE_LIQUIDITY_ONE_COIN`
  {% endhint %}

### previewSpotRate

Simulates encoded commands along with provided inputs, and return the resulting spot rate.

```solidity
function previewSpotRate(
        bytes calldata commands,
        bytes[] calldata inputs
    ) external view returns (uint256 output)
```

<table><thead><tr><th width="190.33333333333331">Input Parameter</th><th width="190">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>commands</code></td><td>bytes calldata</td><td>A set of concatenated commands, each 1 byte in length</td></tr><tr><td><code>inputs</code></td><td>bytes[] calldata</td><td>An array of byte strings containing ABI encoded inputs for each command</td></tr><tr><td>outputSpotRate</td><td>uint256</td><td>The preview spot rate value, which represents the amount of output token obtained at the end of execution for each wei of input token spent at the start of execution, multiplied by 1 ray unit.</td></tr></tbody></table>

{% hint style="info" %}
As opposed to `previewRate`, spot exchange rates will be used for swaps. Additionally for all commands, input amounts are disregarded, and one unit of the token of interest is used instead.
{% endhint %}

{% hint style="warning" %}
Same than for `previewRate()`, the following commands are not supported by `previewSpotRate():`

* `FLASH_LOAN`
* `CURVE_SPLIT_IBT_LIQUIDITY`
* `CURVE_ADD_LIQUIDITY`
* `CURVE_REMOVE_LIQUIDITY`
* `CURVE_REMOVE_LIQUIDITY_ONE_COIN`
  {% endhint %}

### onFlashLoan

Implements the flash loan callback, handling the loan repayment and potential shortfall from the original sender.

```solidity
function onFlashLoan(
        address initiator,
        address token,
        uint256 amount,
        uint256 fee,
        bytes calldata data
    ) external returns (bytes32)
```

<table><thead><tr><th width="190.33333333333331">Input Parameter</th><th width="190">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>initiator</code></td><td>address</td><td>The initiator of the loan.</td></tr><tr><td><code>token</code></td><td>address</td><td>The loan currency.</td></tr><tr><td><code>amount</code></td><td>uint256</td><td>The amount of tokens to borrow.</td></tr><tr><td><code>fee</code></td><td>uint256</td><td>The additional amount of tokens to repay.</td></tr><tr><td><code>data</code></td><td>bytes calldata</td><td>Arbitrary data structure, intended to contain user-defined parameters.</td></tr></tbody></table>

<table><thead><tr><th width="214.33333333333331">Return Parameter</th><th width="125">Type</th><th>Description</th></tr></thead><tbody><tr><td></td><td>bool</td><td>If successful, onFlashLoan return the keccak256 hash of “ERC3156FlashBorrower.onFlashLoan”.</td></tr></tbody></table>

*Conforms to* [*EIP-3156*](https://eips.ethereum.org/EIPS/eip-3156) *standards.*

## Dispatcher

The `Dispatcher.sol` is an abstract contract that facilitates a variety of financial operations, including token transfers, swaps, and flash loans. Each command has specific input requirements and functionalities.

### `TRANSFER_FROM` Command

Transfers the specified amount of the ERC20 token from the message sender (`msgSender`) to the contract itself. It's crucial for security that the transfer originates only from the message sender.

<table><thead><tr><th width="190.33333333333331">Input Parameter</th><th width="190">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>address</code></td><td>address</td><td>The address of the token to transfer</td></tr><tr><td><code>value</code></td><td>uint256</td><td>The amount of token to transfer</td></tr></tbody></table>

### `TRANSFER_FROM_WITH_PERMIT` Command

Transfers the specified amount of the ERC20 token from the message sender (`msgSender`) to the contract itself using the [EIP-2612 signed approvals](https://eips.ethereum.org/EIPS/eip-2612).

<table><thead><tr><th width="190.33333333333331">Input Parameter</th><th width="190">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>address</code></td><td>address</td><td>The address of the token to transfer</td></tr><tr><td><code>value</code></td><td>uint256</td><td>The amount of token to transfer</td></tr><tr><td><code>deadline</code></td><td>uint256</td><td>The deadline for the transaction</td></tr><tr><td><code>v</code></td><td>uint8</td><td>Signature</td></tr><tr><td><code>r</code></td><td>bytes32</td><td>Signature</td></tr><tr><td><code>s</code></td><td>bytes32</td><td>Signature</td></tr></tbody></table>

### `TRANSFER` Command

Transfers a specified amount of the ERC20 token from the contract to the provided recipient address. If a special value indicating the contract's entire balance is provided, it transfers the entire token balance of the contract to the recipient.

<table><thead><tr><th width="190.33333333333331">Input Parameter</th><th width="190">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>token</code></td><td>address</td><td>The address of the token to transfer</td></tr><tr><td><code>recipient</code></td><td>address</td><td>The address of the transfer receiver</td></tr><tr><td><code>value</code></td><td>uint256</td><td>The amount of token to transfer</td></tr></tbody></table>

### `CURVE_SWAP` Command

Executes a token swap using a Curve finance pool. The command involves specifying the tokens within the pool to swap, the amount to swap, and the minimum acceptable amount for the output token, ensuring slippage protection.

<table><thead><tr><th width="190.33333333333331">Input Parameter</th><th width="190">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>pool</code></td><td>address</td><td>The address of the pool</td></tr><tr><td><code>i</code></td><td>uint256</td><td>The token index to input from the swap </td></tr><tr><td><code>j</code></td><td>uint256</td><td>The token index to output from the swap </td></tr><tr><td><code>amountIn</code></td><td>uint256</td><td>The amount of token in</td></tr><tr><td><code>minAmountOut</code></td><td>uint256</td><td>The minimum amount of token out (slippage protection)</td></tr><tr><td><code>recipient</code></td><td>address</td><td>The address of the swap recipient</td></tr></tbody></table>

### `WRAP_VAULT_IN_4626_ADAPTER` Command

Wraps shares of an interest-bearing vault into an ERC4626 compliant wrapper (Spectra4626Wrapper.wrap()). The operation deposits the interest-bearing vault shares into a Spectra4626Wrapper instance and transfers the resulting wrapper shares to the specified recipient.

<table><thead><tr><th width="190.33333333333331">Input Parameter</th><th width="190">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>wrapper</code></td><td>address</td><td>The address of the Spectra4626Wrapper</td></tr><tr><td><code>vaultShares</code></td><td>uint256</td><td>The amount of vaults shares to wrap</td></tr><tr><td><code>recipient</code></td><td>address</td><td>The receiver of wrapper shares</td></tr></tbody></table>

### `UNWRAP_VAULT_FROM_4626_ADAPTER` Command

Unwraps shares of an interest-bearing vault from an ERC4626 wrapper (Spectra4626Wrapper.unwrap()). The operation redeems shares of an Spectra4626Wrapper instance and transfers the resulting vault shares to the specified recipient.

<table><thead><tr><th width="190.33333333333331">Input Parameter</th><th width="190">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>wrapper</code></td><td>address</td><td>The address of the Spectra4626Wrapper</td></tr><tr><td><code>wrapperShares</code></td><td>uint256</td><td>The amount of wrapper shares to redeem</td></tr><tr><td><code>recipient</code></td><td>address</td><td>The receiver of vault shares</td></tr></tbody></table>

### `DEPOSIT_ASSET_IN_IBT` Command

Deposits the specified amount of an underlying ERC20 token into an ERC4626 compliant tokenized vault  ([`ERC4626.deposit()`](https://eips.ethereum.org/EIPS/eip-4626#deposit)). The operation deposits the underlying token into the 4626 vault and transfers the resulting vault shares to the specified recipient.

<table><thead><tr><th width="190.33333333333331">Input Parameter</th><th width="190">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>ibt</code></td><td>address</td><td>The address of the IBT token</td></tr><tr><td><code>assets</code></td><td>uint256</td><td>The amount of token to deposit</td></tr><tr><td><code>recipient</code></td><td>address</td><td>The address of the transfer receiver</td></tr></tbody></table>

### `DEPOSIT_ASSET_IN_PT` Command

Deposits the specified amount of an underlying ERC20 token in the PT ([`deposit()`](https://dev.spectra.finance/technical-reference/principal-token#deposit)).&#x20;

<table><thead><tr><th width="190.33333333333331">Input Parameter</th><th width="190">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>pt</code></td><td>address</td><td>The address of the PT token</td></tr><tr><td><code>assets</code></td><td>uint256</td><td>The amount of token to deposit</td></tr><tr><td><code>ptRecipient</code></td><td>address</td><td>The address of the receiver of PTs</td></tr><tr><td><code>ytRecipient</code></td><td>address</td><td>The address of the receiver of YTs</td></tr><tr><td><code>minShares</code></td><td>uint256</td><td>The minimum amount of minted shares from this deposit</td></tr></tbody></table>

### `DEPOSIT_IBT_IN_PT` Command

Deposits the specified amount of an IBT token in the PT ([`depositIBT()`](https://dev.spectra.finance/technical-reference/principal-token#depositibt)).&#x20;

<table><thead><tr><th width="190.33333333333331">Input Parameter</th><th width="190">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>pt</code></td><td>address</td><td>The address of the PT token</td></tr><tr><td><code>ibts</code></td><td>uint256</td><td>The amount of token to deposit</td></tr><tr><td><code>ptRecipient</code></td><td>address</td><td>The address of the receiver of PTs</td></tr><tr><td><code>ytRecipient</code></td><td>address</td><td>The address of the receiver of YTs</td></tr><tr><td><code>minShares</code></td><td>uint256</td><td>The minimum amount of minted shares from this deposit</td></tr></tbody></table>

### `REDEEM_IBT_FOR_ASSET` Command

Redeems the specified amount of the ERC4626 vault shares for the underlying token ([`ERC4626.redeem()`](https://eips.ethereum.org/EIPS/eip-4626#redeem)). The withdrawn tokens are then transferred to the specified recipient.

<table><thead><tr><th width="190.33333333333331">Input Parameter</th><th width="190">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>token</code></td><td>address</td><td>The address of the token</td></tr><tr><td><code>shares</code></td><td>uint256</td><td>The amount of shares to burn</td></tr><tr><td><code>recipient</code></td><td>address</td><td>The address of the transfer receiver</td></tr></tbody></table>

### `REDEEM_PT_FOR_ASSET` Command

&#x20;Redeems the specified amount of PT shares for the underlying token ([`redeem()`](https://dev.spectra.finance/technical-reference/principal-token#redeem)).

{% hint style="info" %}
Before expiry, the PT shares amount is both the PT and YT amount. After expiry, only the PT shares are burnt.
{% endhint %}

<table><thead><tr><th width="190.33333333333331">Input Parameter</th><th width="190">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>pt</code></td><td>address</td><td>The address of the PT</td></tr><tr><td><code>shares</code></td><td>uint256</td><td>The amount of shares to burn</td></tr><tr><td><code>recipient</code></td><td>address</td><td>The address of the transfer receiver</td></tr><tr><td><code>minAssets</code></td><td>uint256</td><td>The minimum amount of asset to be returned to the user</td></tr></tbody></table>

### `REDEEM_PT_FOR_IBT` Command

Redeems the specified amount of PT share for the associated IBT token ([`redeemForIBT()`](https://dev.spectra.finance/technical-reference/principal-token#redeemforibt)).

{% hint style="info" %}
Before expiry, the PT shares amount is both the PT and YT amount. After expiry, only the PT shares are burnt.
{% endhint %}

<table><thead><tr><th width="190.33333333333331">Input Parameter</th><th width="190">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>pt</code></td><td>address</td><td>The address of the PT</td></tr><tr><td><code>shares</code></td><td>uint256</td><td>The amount of shares to burn</td></tr><tr><td><code>recipient</code></td><td>address</td><td>The address of the transfer receiver</td></tr><tr><td><code>minIbts</code></td><td>uint256</td><td>The minimum amount of IBT to be returned to the user</td></tr></tbody></table>

### `FLASH_LOAN` Command

Facilitates a flash loan transaction. It enables borrowing of a specified amount of an ERC20 token from a lender, with the requirement that it is returned within the same transaction, along with any agreed-upon fees.

<table><thead><tr><th width="190.33333333333331">Input Parameter</th><th width="190">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>lender</code></td><td>address</td><td>The address of the flash loan lender</td></tr><tr><td><code>token</code></td><td>address</td><td>The address of the token to borrow</td></tr><tr><td><code>amount</code></td><td>uint256</td><td>The amount of token to borrow</td></tr><tr><td><code>data</code></td><td>bytes</td><td>Additional data for the flash loan</td></tr></tbody></table>

### `ASSERT_MIN_BALANCE` Command

Checks if the specified token balance of an owner's address is at least the provided minimum value. If the balance is below the minimum, the command reverts the entire transaction.

<table><thead><tr><th width="190.33333333333331">Input Parameter</th><th width="190">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>token</code></td><td>address</td><td>The address of the token</td></tr><tr><td><code>owner</code></td><td>address</td><td>The address of the token owner to check the balance from</td></tr><tr><td><code>minValue</code></td><td>uin256</td><td>The minimum amount of token required</td></tr></tbody></table>

### `CURVE_SPLIT_IBT_LIQUIDITY` Command

&#x20;Split the input IBT amount into IBT for the pool and to deposit in the Principal Token. Add liquidity to the pool with the resulting PT and the split IBT amounts.

<table><thead><tr><th width="190.33333333333331">Input Parameter</th><th width="190">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>pool</code></td><td>address</td><td>The address of the Curve pool</td></tr><tr><td><code>ibts</code></td><td>uint256</td><td>The amount of IBT to deposit</td></tr><tr><td><code>recipient</code></td><td>address</td><td>The address of the LP token recipient</td></tr><tr><td><code>ytRecipient</code></td><td>address</td><td>The address of the YT recipient</td></tr><tr><td><code>minPTShares</code></td><td>uint256</td><td>The minimum amount of minted PT/YT shares from the portion of IBT deposited in the PT contract.</td></tr></tbody></table>

### `CURVE_ADD_LIQUIDITY` Command

Add liquidity to the Curve `pool` specifying each token amount in input and the minimum amount of LP token to mint (slippage protection).

<table><thead><tr><th width="207.33333333333331">Input Parameter</th><th width="190">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>pool</code></td><td>address</td><td>The address of the Curve pool</td></tr><tr><td><code>amounts</code></td><td>uint256[2]</td><td>The amount of IBT/PT to deposit</td></tr><tr><td><code>min_mint_amount</code></td><td>uint256</td><td>The minimum amount of LP token to mint</td></tr><tr><td><code>recipient</code></td><td>address</td><td>The address of the LP token recipient</td></tr></tbody></table>

### `CURVE_REMOVE_LIQUIDITY` Command

Remove liquidity from Curve `pool` specifying the amount `lps` of LP tokens to burn and the minum amount of liquidity to withdraw for each token (slippage protection).

<table><thead><tr><th width="190.33333333333331">Input Parameter</th><th width="190">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>pool</code></td><td>address</td><td>The address of the Curve pool</td></tr><tr><td><code>lps</code></td><td>uint256</td><td>The amount of LP tokens to burn</td></tr><tr><td><code>min_amounts</code></td><td>uint256[2]</td><td>The minimum amount of assets to receive</td></tr><tr><td><code>recipient</code></td><td>address</td><td>The address of the tokens recipient</td></tr></tbody></table>

### `CURVE_REMOVE_LIQUIDITY_ONE_COIN` Command

Remove liquidity from Curve `pool` by withdrawing a single coin. The user specify the amount `lps` of LP tokens to burn and the minimum amount of liquidity to withdraw for the chosen token (slippage protection).

<table><thead><tr><th width="190.33333333333331">Input Parameter</th><th width="190">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>pool</code></td><td>address</td><td>The address of the Curve pool</td></tr><tr><td><code>lps</code></td><td>uint256</td><td>The amount of LP tokens to burn</td></tr><tr><td><code>i</code></td><td>uint256</td><td>The index of the token to withdraw from the pool</td></tr><tr><td><code>min_amount</code></td><td>uint256</td><td>The minimum amount of assets to receive</td></tr><tr><td><code>recipient</code></td><td>address</td><td>The address of the token recipient</td></tr></tbody></table>
