> For the complete documentation index, see [llms.txt](https://docs.aqua.network/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.aqua.network/developers/reference/router-and-pool-contracts.md).

# Router & pool contracts

The **router** is the single entry point for all AMM functionality: swaps, deposits, withdrawals, reward claims, and pool discovery. Router addresses for mainnet and testnet are listed in [Addresses & Networks](/developers/reference/addresses-and-networks.md).

### Read functions

Read-only functions don't change state — call them through transaction **simulation**; no signature or fees are required.

#### Get pools

The `get_pools` function returns all pools that exist for a set of tokens, as a map of pool hash → pool contract address:

```rust
fn get_pools(e: Env, tokens: Vec<Address>) -> Map<BytesN<32>, Address>;
```

| Parameter | Description           |
| --------- | --------------------- |
| `tokens`  | Ordered tokens vector |

See the [Get pools info example](/developers/code-examples/get-pools-info.md) for usage in Python and JavaScript.

#### Get info

The `get_info` function returns the parameters of a specific pool — pool type, fee, and type-specific values (for example, `a` for stable pools):

```rust
fn get_info(e: Env, tokens: Vec<Address>, pool_index: BytesN<32>) -> Map<Symbol, Val>;
```

| Parameter    | Description                 |
| ------------ | --------------------------- |
| `tokens`     | Ordered tokens vector       |
| `pool_index` | Pool hash (see `get_pools`) |

### Write functions

#### Deposit

The `deposit` function increases pool liquidity by exchanging tokens for pool share tokens:

```rust
fn deposit(
  e: Env,
  user: Address,
  tokens: Vec<Address>,
  pool_index: BytesN<32>,
  desired_amounts: Vec<u128>,
  min_shares: u128,
) -> (Vec<u128>, u128);
```

| Parameter         | Description                                    |
| ----------------- | ---------------------------------------------- |
| `user`            | The address of the user executing the deposit  |
| `tokens`          | Ordered tokens vector                          |
| `pool_index`      | Pool hash (see `get_pools`)                    |
| `desired_amounts` | Vector of desired amounts to deposit           |
| `min_shares`      | Minimum amount of shares to receive on deposit |

**Returns:** the actual amounts of deposited tokens and the minted shares amount.

#### Withdraw

The `withdraw` function removes liquidity from a pool by exchanging pool shares for pool tokens:

```rust
fn withdraw(
  e: Env,
  user: Address,
  tokens: Vec<Address>,
  pool_index: BytesN<32>,
  share_amount: u128,
  min_amounts: Vec<u128>,
) -> Vec<u128>;
```

| Parameter      | Description                                      |
| -------------- | ------------------------------------------------ |
| `user`         | The address of the user executing the withdrawal |
| `tokens`       | Ordered tokens vector                            |
| `pool_index`   | Pool hash (see `get_pools`)                      |
| `share_amount` | Amount of shares to withdraw                     |
| `min_amounts`  | Vector of minimum amounts to withdraw            |

**Returns:** the actual amounts of withdrawn tokens.

#### Swap chained

The `swap_chained` function executes a chain of token swaps to exchange an input token for an output token, with the **input amount fixed** (strict-send):

```rust
fn swap_chained(
    e: Env,
    user: Address,
    swaps_chain: Vec<(Vec<Address>, BytesN<32>, Address)>,
    token_in: Address,
    in_amount: u128,
    out_min: u128,
) -> u128
```

| Parameter     | Description                                                                                                                                                                                                             |
| ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `user`        | The address of the user executing the swaps                                                                                                                                                                             |
| `swaps_chain` | The series of swaps to execute. No need to build it manually — the find-path API returns it as an XDR-encoded `SCVal`. Each element is a tuple of the pool's token vector, the pool index hash, and the token to obtain |
| `token_in`    | The address of the input token to be swapped                                                                                                                                                                            |
| `in_amount`   | The amount of the input token to be swapped                                                                                                                                                                             |
| `out_min`     | The minimum amount of the output token to be received                                                                                                                                                                   |

**Returns:** the amount of the output token received after all swaps have been executed.

#### Swap chained strict receive

The `swap_chained_strict_receive` function is the strict-receive counterpart of `swap_chained`: the **output amount is fixed**, and the function spends no more of the input token than the specified maximum:

```rust
fn swap_chained_strict_receive(
    e: Env,
    user: Address,
    swaps_chain: Vec<(Vec<Address>, BytesN<32>, Address)>,
    token_in: Address,
    out_amount: u128,
    max_in: u128,
) -> u128
```

Parameters mirror `swap_chained`, except:

| Parameter    | Description                                                  |
| ------------ | ------------------------------------------------------------ |
| `out_amount` | The exact amount of the output token to receive              |
| `max_in`     | The maximum amount of the input token you authorize to spend |

**Returns:** the amount of the input token actually spent. See [Executing swaps through optimal path](/developers/code-examples/executing-swaps-through-optimal-path.md) for a complete example covering both modes.

{% hint style="warning" %}
**Chain length limits:** strict-send chains support up to **4 pools**, strict-receive chains up to **3** — the find-path API enforces these caps. Longer chains raise no contract validation error; the transaction fails simulation with a `BudgetExceed` error due to Soroban limitations.
{% endhint %}

#### Claim

The `claim` function collects accrued AQUA rewards for a liquidity provider:

```rust
fn claim(e: Env, user: Address, tokens: Vec<Address>, pool_index: BytesN<32>) -> u128;
```

**Returns:** the amount of AQUA claimed. See the [Claim LP rewards example](/developers/code-examples/claim-lp-rewards.md).

### Pool contract functions

Every liquidity pool is a separate contract that can also be called directly — useful for contract sub-invocations, as a direct call requires fewer resources than going through the router. `in_idx`/`out_idx` are the token indices in the pool's sorted token vector:

| Function                                                                                                | Description                                                      |
| ------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- |
| `estimate_swap(in_idx: u32, out_idx: u32, in_amount: u128) -> u128`                                     | Estimate the output of an exact-input swap (call via simulation) |
| `swap(user: Address, in_idx: u32, out_idx: u32, in_amount: u128, out_min: u128) -> u128`                | Execute an exact-input swap against this pool only               |
| `estimate_swap_strict_receive(in_idx: u32, out_idx: u32, out_amount: u128) -> u128`                     | Estimate the input required for an exact-output swap             |
| `swap_strict_receive(user: Address, in_idx: u32, out_idx: u32, out_amount: u128, in_max: u128) -> u128` | Execute an exact-output swap, spending at most `in_max`          |
| `claim(user: Address) -> u128`                                                                          | Claim accrued AQUA rewards from this pool                        |

See [Executing swaps through specific pool](/developers/code-examples/executing-swaps-through-specific-pool.md) for a complete example.
