# Pool (v2)

## Off-chain get methods

### `get_pool_data`

Returns the current state of the `Pool`

```
_ get_pool_data() method_id;
```

#### **Arguments**

`None`

#### **Result (common)**

Returns `PoolData` structure containing current state of the pool. Typed pools may return additional arguments if present

**`PoolData` structure**

| Key                             | Type      | Index | Description                                                                  |
| ------------------------------- | --------- | ----- | ---------------------------------------------------------------------------- |
| `is_locked`                     | `bool`    | 0     | true if `transfer_notification` operations are locked (`swap`, `provide_lp`) |
| `router_address`                | `address` | 1     | Address of the `Router`                                                      |
| `total_supply`                  | `coins`   | 2     | Total supply of lp tokens                                                    |
| `reserve0`                      | `coins`   | 3     | Amount of the first token (in basic token units)                             |
| `reserve1`                      | `coins`   | 4     | Amount of the second token (in basic token units)                            |
| `token0_wallet_address`         | `address` | 5     | Address of the first Jetton token                                            |
| `token1_wallet_address`         | `address` | 6     | Address of the second Jetton token                                           |
| `lp_fee`                        | `uint16`  | 7     | Liquidity pool fee value                                                     |
| `protocol_fee`                  | `uint16`  | 8     | Protocol fee                                                                 |
| `protocol_fee_address`          | `address` | 9     | Address for receiving protocol fees                                          |
| `collected_token0_protocol_fee` | `coins`   | 10    | Amount of collected protocol fees of the first token (in basic token units)  |
| `collected_token1_protocol_fee` | `coins`   | 11    | Amount of collected protocol fees of the second token (in basic token units) |

Notes:

* fee ratio is the value of fee divided by `params::fee_divider` (10000); so a fee of 1% has a value of 100

#### **Result (`stableswap`)**

Additional data in `PoolData` structure specific to stableswap pools

**`PoolData` structure additional params**

| Key   | Type     | Index | Description                        |
| ----- | -------- | ----- | ---------------------------------- |
| `amp` | `uint32` | 12    | Stableswap amplification parameter |

#### **Result (`weighted_stableswap`)**

Additional data in `PoolData` structure specific to weighted stableswap pools

**`PoolData` structure additional params**

| Key           | Type      | Index | Description                                 |
| ------------- | --------- | ----- | ------------------------------------------- |
| `amp`         | `uint128` | 12    | Weighted stableswap amplification parameter |
| `rate`        | `uint128` | 13    | Stable token ratio parameter                |
| `w0`          | `uint128` | 14    | Token 0 weight parameter                    |
| `rate_setter` | `address` | 15    | Address with rights to change `rate`        |

#### **Result (`weighted_const_product`)**

Additional data in `PoolData` structure specific to weighted constant product pools

**`PoolData` structure additional params**

| Key  | Type      | Index | Description              |
| ---- | --------- | ----- | ------------------------ |
| `w0` | `uint128` | 12    | Token 0 weight parameter |

### `get_lp_account_address`

Get the lp account address of a user

```
slice get_lp_account_address(slice owner_address) method_id;
```

#### **Arguments**

| Key             | Type      | Description       |
| --------------- | --------- | ----------------- |
| `owner_address` | `address` | Address of a user |

#### **Result**

Returns the lp account address of a user

### `get_jetton_data`

Standard jetton 'get' methods from TonWeb JettonMinter.

```
(int, int, slice, cell, cell) get_jetton_data() method_id;
```

#### **Arguments**

None

#### **Result**

Returns a structure with Jetton data

**`JettonData` structure**

| Key                  | Type      | Index | Description                                            |
| -------------------- | --------- | ----- | ------------------------------------------------------ |
| `total_supply`       | `coins`   | 0     | Total token supply of lp tokens (in basic token units) |
| `mintable`           | `bool`    | 1     | always `true`                                          |
| `admin_address`      | `address` | 2     | `Router` address                                       |
| `jetton_content_uri` | `string`  | 3     | Offchain uri with Jetton data                          |
| `jetton_wallet_code` | `cell`    | 4     | Code of the lp Jetton wallet                           |

### `get_wallet_address`

Get lp wallet address of a user.

```
slice get_wallet_address(slice owner_address) method_id;
```

#### **Arguments**

| Name            | Type      | Description       |
| --------------- | --------- | ----------------- |
| `owner_address` | `address` | Address of a user |

#### **Result**

Returns a calculated lp wallet address of a user

### `get_pool_type`

Get `Pool` type, equals to `dex_type` param in `get_router_data`

```
_ get_pool_type() method_id;
```

#### **Arguments**

None

#### **Result**

Return pool type of this pool as string:

* `constant_product`
* `stableswap`
* `weighted_stableswap`
* `weighted_const_product`

## On-chain queries

On-chain counterparts of getter methods.

#### **Operations table**

| Name                        | Value      | Description                                           |
| --------------------------- | ---------- | ----------------------------------------------------- |
| `getter_pool_data`          | 0x26df39fc | Sends a message with the current state of the pool    |
| `getter_lp_account_address` | 0x15fbca95 | Sends a message with the lp account address of a user |
| `provide_wallet_address`    | 0x2c76b973 | Sends a message with the lp wallet address of a user  |

### `getter_pool_data` (0x26df39fc)

Sends a message with the current state of the pool. On-chain equivalent of `get_pool_data`.

#### **TL-B**

```
getter_pool_data#26df39fc query_id:uint64 = InternalMsgBody;
```

#### **Message body**

None

#### **Outgoing messages**

Sends a message with current pool data to the `sender_address`

#### **Response message body**

| Name              | Type      | Description                                       |
| ----------------- | --------- | ------------------------------------------------- |
| `op`              | `uint32`  | Operation code is equal to `getter_pool_data`     |
| `query_id`        | `uint64`  | Query id                                          |
| `is_locked`       | `uint1`   | If this `Pool` is locked                          |
| `reserve0`        | `coins`   | Amount of the first token (in basic token units)  |
| `reserve1`        | `coins`   | Amount of the second token (in basic token units) |
| `token0_address`  | `address` | Address of the first Jetton token                 |
| `token1_address`  | `address` | Address of the second Jetton token                |
| `additional_data` | `cell`    | Cell with additional data                         |

#### **`additional_data` body**

| Name                            | Type      | Description                                                                  |
| ------------------------------- | --------- | ---------------------------------------------------------------------------- |
| `lp_fee`                        | `uint16`  | Liquidity pool fee value                                                     |
| `protocol_fee`                  | `uint16`  | Protocol fee                                                                 |
| `router_address`                | `address` | Address of the `Router`                                                      |
| `protocol_fee_address`          | `address` | Address for receiving protocol fees                                          |
| `total_supply`                  | `coins`   | Total amount of minted lp tokens                                             |
| `collected_token0_protocol_fee` | `coins`   | Amount of collected protocol fees of the first token (in basic token units)  |
| `collected_token1_protocol_fee` | `coins`   | Amount of collected protocol fees of the second token (in basic token units) |

### `getter_lp_account_address` (0x15fbca95)

Sends a message with the lp account address of a user. On-chain equivalent of `get_lp_account_address`.

#### **TL-B**

```
getter_lp_account_address#15fbca95 query_id:uint64 user_address:MsgAddress = InternalMsgBody;
```

#### **Message body**

| Name           | Type      | Description       |
| -------------- | --------- | ----------------- |
| `user_address` | `address` | Address of a user |

#### **Outgoing messages**

Sends a message with the lp account address of a user to `sender_address`

#### **Response message body**

| Name                 | Type      | Description                                          |
| -------------------- | --------- | ---------------------------------------------------- |
| `op`                 | `uint32`  | Operation code is equal to `getter_expected_outputs` |
| `query_id`           | `uint64`  | Query id                                             |
| `lp_account_address` | `address` | lp account address of a user                         |

### `provide_wallet_address` (0x2c76b973)

Sends a message with the lp wallet address of a user. On-chain equivalent of `get_wallet_address`.

#### **TL-B**

```
provide_wallet_address#2c76b973 query_id:uint64 owner_address:MsgAddress include_address?:Bool = InternalMsgBody;
```

#### **Message body**

| Name               | Type      | Description                                  |
| ------------------ | --------- | -------------------------------------------- |
| `owner_address`    | `address` | Address of a user                            |
| `include_address?` | `uint1`   | Include user address in the response message |

#### **Outgoing messages**

Sends a message back to sender with the calculated lp wallet address of a user

#### **Response message body**

| Name                | Type        | Description                                                   |
| ------------------- | ----------- | ------------------------------------------------------------- |
| `op`                | `uint32`    | Operation code is equal to `take_wallet_address` (0xd1735400) |
| `query_id`          | `uint64`    | Query id                                                      |
| `lp_wallet_address` | `address`   | Calculated lp wallet address                                  |
| `additional_data`   | `maybe_ref` | Cell with data if `include_address?` evaluates to `true`      |

#### **`additional_data` body**

| Name               | Type      | Description       |
| ------------------ | --------- | ----------------- |
| `included_address` | `address` | Address of a user |

## Jetton handlers

Handles operations sent from a Jetton wallet.

#### **Operations table**

| Name                    | Value      | Description                                                     |
| ----------------------- | ---------- | --------------------------------------------------------------- |
| `burn_notification_ext` | 0x297437cf | Sent by LP wallet after burning LP jettons to release liquidity |

### `burn_notification_ext` (0x297437cf)

Sent by `LpWallet` after burning LP jettons to release liquidity.

#### **TL-B**

```
burn_notification_ext#297437cf query_id:uint64 jetton_amount:Coins from_address:MsgAddress response_address:MsgAddress maybe_custom_payload:(Maybe ^Cell) = InternalMsgBody;
```

#### **Message body**

| Name               | Type        | Description                                               |
| ------------------ | ----------- | --------------------------------------------------------- |
| `jetton_amount`    | `coins`     | Amount of liquidity tokens to burn (in basic token units) |
| `from_address`     | `address`   | User address                                              |
| `response_address` | `address`   | Address for a response message                            |
| `custom_payloads`  | `maybe_ref` | Payloads for token0 and token1                            |

#### **custom\_payloads**

| Name        | Type        | Description                                     |
| ----------- | ----------- | ----------------------------------------------- |
| `payload_1` | `maybe_ref` | Payload used for `amount0`; can be `cross_swap` |
| `payload_2` | `maybe_ref` | Payload used for `amount1`; can be `cross_swap` |

#### **Outgoing messages**

Sends a message with op `excesses` (0xd53276db) to `response_address`

Sends a message with a released amount of both tokens to be received by a user as a result of the burn operation to the router, which initiates `pay_to` operation to `from_address`

## Router internal message handlers

Handles messages from the router.

#### **Operations table**

| Name         | Value      | Description            |
| ------------ | ---------- | ---------------------- |
| `swap`       | 0x6664de2a | Swap tokens            |
| `provide_lp` | 0x37c096df | Provide liquidity      |
| `reset_gas`  | 0x29d22935 | Reset gas              |
| `set_fees`   | 0x58274069 | Set new fee parameters |

### `swap` (0x6664de2a)

Swap tokens. This message is received from the router when the user initiates a token swap.

#### **TL-B**

```
swap#6664de2a query_id:uint64 from_user:MsgAddress left_amount:Coins right_amount:Coins dex_payload:^[transferred_op:uint32 token_wallet1:MsgAddress refund_address:MsgAddress excesses_address:MsgAddress tx_deadline:uint64 swap_body:^[min_out:Coins receiver:MsgAddress fwd_gas:Coins custom_payload:(Maybe ^Cell) refund_fwd_gas:Coins refund_payload:(Maybe ^Cell) ref_fee:uint16 ref_address:MsgAddress]] = InternalMsgBody;
```

#### **Message body**

| Name        | Type      | Description                     |
| ----------- | --------- | ------------------------------- |
| `from_user` | `address` | User address                    |
| `amount0`   | `coins`   | Amount of incoming first token  |
| `amount1`   | `coins`   | Amount of incoming second token |
| `payload`   | `cell`    | Cell with dex payload           |

#### **`payload` body**

| Name                 | Type      | Description                                     |
| -------------------- | --------- | ----------------------------------------------- |
| `op`                 | `uint32`  | Swap op                                         |
| `other_token_wallet` | `address` | Address of the other `Router`token wallet       |
| `refund_address`     | `address` | Address where refund will be sent if swap fails |
| `excesses_address`   | `address` | Address where TON excesses will be sent         |
| `additional_data`    | `cell`    | Cell with additional data                       |

#### **`additional_data` body**

| Name               | Type        | Description                                                                                           |
| ------------------ | ----------- | ----------------------------------------------------------------------------------------------------- |
| `min_out`          | `coins`     | Minimum required amount of tokens to receive                                                          |
| `receiver_address` | `address`   | Address where tokens will be sent after swap                                                          |
| `fwd_gas`          | `coins`     | Gas used to forward a message in `transfer_notification` after swap if `custom_payload` is present    |
| `custom_payload`   | `maybe_ref` | Payload sent in `transfer_notification` after swap                                                    |
| `refund_fwd_gas`   | `coins`     | Gas used to forward a message in `transfer_notification` if swap fails if `refund_payload` is present |
| `refund_payload`   | `maybe_ref` | Payload sent in `transfer_notification` if swap fails                                                 |
| `ref_fee`          | `uint16`    | Referral fee                                                                                          |
| `referral_address` | `address`   | Referral address                                                                                      |

Notes:

* swap will fail if a user should receive less than `min_out` of tokens as a result
* max allowed value of `ref_fee` is 100 (1%)

#### **Outgoing messages**

Sends a message with an amount of the other tokens to be received by a user as a result of the swap to the router, which initiates `pay_to` operation

Additionally may send a message with referrer fees to the router, which initiates `pay_vault` operation to `Vault` of `referral_address`

### `provide_lp` (0x37c096df)

Provide liquidity for the pool. A user must submit an amount of both tokens to receive lp tokens and add new liquidity to a pool. This message is routed to liquidity pool account with `add_liquidity` operation code.

#### **TL-B**

```
provide_lp#37c096df query_id:uint64 from_user:MsgAddress left_amount:Coins right_amount:Coins dex_payload:^[transferred_op:uint32 token_wallet1:MsgAddress refund_address:MsgAddress excesses_address:MsgAddress tx_deadline:uint64 provide_lp_body:^[min_lp_out:Coins to_address:MsgAddress both_positive:uint1 fwd_amount:Coins custom_payload:(Maybe ^Cell)]] = InternalMsgBody;
```

#### **Message body**

| Name        | Type      | Description                     |
| ----------- | --------- | ------------------------------- |
| `from_user` | `address` | User address                    |
| `amount0`   | `coins`   | Amount of incoming first token  |
| `amount1`   | `coins`   | Amount of incoming second token |
| `payload`   | `cell`    | Cell with dex payload           |

#### **`payload` body**

| Name                 | Type      | Description                                     |
| -------------------- | --------- | ----------------------------------------------- |
| `op`                 | `uint32`  | Provide lp op                                   |
| `other_token_wallet` | `address` | Address of the other `Router` token wallet      |
| `refund_address`     | `address` | Address where refund will be sent if swap fails |
| `excesses_address`   | `address` | Address where TON excesses will be sent         |
| `additional_data`    | `cell`    | Cell with additional data                       |

#### **`additional_data` body**

| Name               | Type        | Description                                                                                        |
| ------------------ | ----------- | -------------------------------------------------------------------------------------------------- |
| `min_lp_out`       | `coins`     | Minimum required amount of lp tokens to receive                                                    |
| `receiver_address` | `address`   | Address where lp tokens will be sent                                                               |
| `both_positive`    | `uint1`     | Trigger liquidity deposit only if both token amounts are non-zero                                  |
| `fwd_gas`          | `coins`     | Gas used to forward a message in `transfer_notification` after mint if `custom_payload` is present |
| `custom_payload`   | `maybe_ref` | Payload sent in `transfer_notification` after lp mint                                              |

#### **Outgoing messages**

Sends a message to liquidity pool account with `add_liquidity` operation code.

### `reset_gas` (0x29d22935)

Updates the amount of TON (in nanoTons) on the pool to `storage_fee::pool` (10000000) of the pool. The remaining amount of TON will be sent to `excesses_address`.

#### **TL-B**

```
reset_gas#29d22935 query_id:uint64 = InternalMsgBody;
```

#### **Message body**

| Name               | Type      | Description                           |
| ------------------ | --------- | ------------------------------------- |
| `excesses_address` | `address` | Address where excess ton will be sent |

#### **Outgoing messages**

Sends a message to `excesses_address` with the remaining TON

### `internal_set_fees` (0x75930d63)

Set new fee values including liquidity pool fees, protocol fees and referral fees as well as an address for receiving collected protocol fees.

#### **TL-B**

```
internal_set_fees#75930d63 query_id:uint64 new_lp_fee:uint16 new_protocol_fee:uint16 new_protocol_fee_address:MsgAddress excesses_address:MsgAddress = InternalMsgBody;
```

#### **Message body**

| Name                       | Type      | Description                                                        |
| -------------------------- | --------- | ------------------------------------------------------------------ |
| `new_lp_fee`               | `uint16`  | New liquidity pool fee ratio (multiplied by `params::fee_divider`) |
| `new_protocol_fee`         | `uint16`  | New protocol fee ratio (multiplied by `params::fee_divider`)       |
| `new_protocol_fee_address` | `address` | Address for receiving protocol fees                                |
| `excesses_address`         | `address` | Address where TON excesses will be sent                            |

Notes:

* fee ratio is the value of fee divided by `params::fee_divider` (10000); so to set a fee to 1% the value must be 100
* fees must be between `params::min_fee` (0) and `params::max_fee` (100)

#### **Outgoing messages**

Sends a message to `excesses_address` with the remaining TON

***

## Protocol address internal message handlers

Handles messages from the `protocol_fee_address`.

#### **Operations table**

| Name           | Value      | Description  |
| -------------- | ---------- | ------------ |
| `collect_fees` | 0x1ee4911e | Collect fees |

### `collect_fees` (0x1ee4911e)

Collect protocol fees. The amount of fees in both tokens will be sent to `protocol_fee_address` address.

#### **TL-B**

```
collect_fees#1ee4911e query_id:uint64 maybe_payload0:(Maybe ^Cell) maybe_payload1:(Maybe ^Cell) = InternalMsgBody;
```

#### **Message body**

| Name        | Type        | Description                                     |
| ----------- | ----------- | ----------------------------------------------- |
| `payload_0` | `maybe_ref` | Payload used for `amount0`; can be `cross_swap` |
| `payload_1` | `maybe_ref` | Payload used for `amount1`; can be `cross_swap` |

#### **Outgoing messages**

Sends a message with collected fees in both tokens to the router, which initiates `pay_to` operation to `protocol_fee_address`.

## LP Account internal message handlers

Handles messages from an lp account.

#### **Operations table**

| Name               | Value      | Description                                       |
| ------------------ | ---------- | ------------------------------------------------- |
| `cb_add_liquidity` | 0x06ecd527 | Sent by user's lp\_account after adding liquidity |
| `cb_refund_me`     | 0x0f98e2b8 | Sent by user's lp\_account after adding liquidity |

### `cb_add_liquidity` (0x06ecd527)

Add new liquidity to the pool. Sent by user's lp account after both or one amounts tokens is sent by a user. The resulting added liquidity must be greater than `min_lp_out` for the operation to be successful.

#### **TL-B**

```
cb_add_liquidity#6ecd527 query_id:uint64 tot_am0:Coins tot_am1:Coins user_address:MsgAddress min_lp_out:Coins fwd_amount:Coins custom_payload_cs:(Maybe ^Cell) additional_fields:^[to_user_address:MsgAddress refund_address:MsgAddress excess_address:MsgAddress] = InternalMsgBody;
```

#### **Message body**

| Name              | Type        | Description                                                                          |
| ----------------- | ----------- | ------------------------------------------------------------------------------------ |
| `amount0`         | `coins`     | Amount of the first Jetton tokens added (in basic token units)                       |
| `amount1`         | `coins`     | Amount of the second Jetton tokens added (in basic token units)                      |
| `user_address`    | `address`   | Owner's address                                                                      |
| `min_lp_out`      | `coins`     | Minimum amount of received liquidity tokens (in basic token units)                   |
| `fwd_amount`      | `coins`     | Forward amount used to send `custom_payload` (if present) in `transfer_notification` |
| `custom_payload`  | `maybe_ref` | Payload sent in `transfer_notification` upon receiving tokens                        |
| `additional_data` | `ref`       | See table below                                                                      |

#### **additional\_data**

| Name             | Type      | Description                                                                                           |
| ---------------- | --------- | ----------------------------------------------------------------------------------------------------- |
| `to_address`     | `address` | Owner of new liquidity tokens                                                                         |
| `refund_address` | `address` | Address of the owner of `LpAccount` where tokens will be refunded if liquidity mint wasn't successful |
| `excess_address` | `address` | Address where all TON excesses will be sent                                                           |

Notes:

* addition of liquidity will fail if a user should receive less than `min_lp_out` of lp tokens as a result
* cannot add liquidity if a supply of either tokens becomes greater than `MAX_COINS` (2^120 - 1)

#### **Outgoing messages**

Sends a message with `internal_transfer` (0x178d4519) op code to the lp wallet of `to_address` with minted liquidity tokens

### `cb_refund_me` (0x0f98e2b8)

Sent by user's lp account after a user initiates `refund_me` operation to cancel addition of new liquidity. The amount of previously stored tokens will be sent back to the user.

#### **TL-B**

```
cb_refund_me#f98e2b8 query_id:uint64 tot_am0:Coins tot_am1:Coins user_address:MsgAddress left_maybe_payload:(Maybe ^Cell) right_maybe_payload:(Maybe ^Cell) = InternalMsgBody;
```

#### **Message body**

| Name           | Type        | Description                                               |
| -------------- | ----------- | --------------------------------------------------------- |
| `amount0`      | `coins`     | Amount of the first Jetton tokens (in basic token units)  |
| `amount1`      | `coins`     | Amount of the second Jetton tokens (in basic token units) |
| `user_address` | `address`   | Owner's address                                           |
| `payload_0`    | `maybe_ref` | Payload used for `amount0`; can be `cross_swap`           |
| `payload_1`    | `maybe_ref` | Payload used for `amount1`; can be `cross_swap`           |

#### **Outgoing messages**

Sends a message with `amount0` of the first token and `amount1` of the second token to the router, which initiates `pay_to` operation

***

## Constants

| Name                                | Value     | Description                                                         |
| ----------------------------------- | --------- | ------------------------------------------------------------------- |
| `storage_fee::pool`                 | 10000000  | Amount of TON (in nanoTons) to be left on the pool contract as gas  |
| `params::required_min_liquidity`    | 1001      | Minimum amount of liquidity required                                |
| `MAX_COINS`                         | 2^120 - 1 | Maximum amount of tokens (in basic token units) stored as liquidity |
| `gas::pool::provide_wallet_address` | 20000000  | Additional gas (in nanoTons) for providing a wallet                 |
| `params::fee_divider`               | 10000     | Fee values are divided by this value                                |
| `params::min_fee`                   | 0         | Minimum fee allowed (0%)                                            |
| `params::max_fee`                   | 100       | Maximum fee allowed (1%)                                            |
