# Providing Liquidity To Classic Pools

## Pool creation

In some cases, your contract may be instantiating a new pool for a token pair. This can be done by calling the router's createPool function.

### Example[​](https://docs.kyberswap.com/Classic/contract/providing-liquidity#example) <a href="#example" id="example"></a>

Create a new DAI-USDC pool with amplification factor of 50. Refer to [this section](https://docs.kyberswap.com/~/changes/1kQEhDNzHMDf7SwOE6Yu/liquidity-solutions/kyberswap-classic/concepts/dynamic-pricing-curves) to understand more about the amplification factor.

```solidity
poolAddress = dmmFactory.createPool(dai, usdc, 50000);
```

Kindly note the following:

* The token addresses are interchangeable, ie. `dmm.createPool(usdc, dai, 50000)` yields the same result.
* There can be at most 1 unamplified pool for a token pair, ie. only 1 pool can exist with `ampBps = BPS (10000)`. Should there already be an existing unamplified pool, attempts to create another one will fail.

## Adding liquidity

To safely add liquidity to a pool, we recommend using the router. There are different functions for adding liquidity to existing pools or creating a new pool, and if the token pair is ERC20-ERC20, or ETH-ERC20.

These methods both require committment to a *belief about the current price*, which is encoded in the `amount*Desired` parameters. While it is fairly safe to assume that the current fair market price is around what the current reserve ratio is for a pair due to arbitrage, it is dangerous to obtain this ratio within the same transaction as it can be easily manipulated.

In addition, the `amount*Min` and `vReserveRatioBounds` parameters should be utilised as a sanity buffer as the market price may shift drastically before the transaction is confirmed.

### Determining the appropriate pool[​](https://docs.kyberswap.com/Classic/contract/providing-liquidity#determining-the-appropriate-pool) <a href="#determining-the-appropriate-pool" id="determining-the-appropriate-pool"></a>

See [this section](https://docs.kyberswap.com/~/changes/1kQEhDNzHMDf7SwOE6Yu/liquidity-solutions/kyberswap-classic/developer-guides/get-classic-pool-addresses) on pool selection.

### Examples[​](https://docs.kyberswap.com/Classic/contract/providing-liquidity#examples) <a href="#examples" id="examples"></a>

1. Create a new ERC20-ERC20 pool with amplification factor 100
2. Add liquidity to an existing ERC20-ERC20 with FoT pool

Creation and liquidity provision to ERC20-ETH pools are similar, with the only difference being the functions to be called.

### New ERC20-ERC20 pool via addLiquidityNewPool[​](https://docs.kyberswap.com/Classic/contract/providing-liquidity#new-erc20-erc20-pool-via-addliquiditynewpool) <a href="#new-erc20-erc20-pool-via-addliquiditynewpool" id="new-erc20-erc20-pool-via-addliquiditynewpool"></a>

For new ERC20-ETH pool creations, the equivalent function is addLiquidityNewPoolETH.

**Example: Create a new pool with 100 USDC and 100 USDT**[**​**](https://docs.kyberswap.com/Classic/contract/providing-liquidity#example-create-a-new-pool-with-100-usdc-and-100-usdt)

```solidity
// Note: assume that usdc and usdt token approvals have been given to router
// and that transferFrom has been called to transfer tokens to contract from user
dmmRouter.addLiquidityNewPool(
    usdc,
    usdt,
    1000000, // amplification factor of 100
    100 * 1e6, // 100 usdc
    100 * 1e6, // 100 usdt
    100 * 1e6, // no slippage tolerance because it is a new pool
    100 * 1e6 // no slippage tolerance because it is a new pool
);
```

### Add to existing ERC20-ERC20 (FoT) pool via addLiquidity[​](https://docs.kyberswap.com/Classic/contract/providing-liquidity#add-to-existing-erc20-erc20-fot-pool-via-addliquidity) <a href="#add-to-existing-erc20-erc20-fot-pool-via-addliquidity" id="add-to-existing-erc20-erc20-fot-pool-via-addliquidity"></a>

Although CORE is a Fee-on-Transfer (FoT) token, it utilises the same function as adding liquidity to an existing ERC20-ERC20 pool. However, it is likely that the slippage tolerance will have to be adjusted to account for the token fee.

For adding liquidity to existing ERC20-ETH pools, the the equivalent function is addLiquidityETH.

**Example: Add 1 CORE and 1000 USDT**[**​**](https://docs.kyberswap.com/Classic/contract/providing-liquidity#example-add-1-core-and-1000-usdt)

```solidity
// Note: assume that core and usdt token approvals have been given to router
// and that transferFrom has been called to transfer tokens to contract from user

// the vReserveRatioBounds below is set to the absolute minimum and maximum values as an example
// it is recommended to read the virtual reserve ratio and set the appropriate values from that
vReserveRatioBounds = new uint256[2];
(vReserveRatioBounds[0], vReserveRatioBounds[1]) = (0, -1);
dmmRouter.addLiquidity(
    core,
    usdt,
    core-usdt-pool, // core-usdt pool address
    1 * 1e18, // 1 core
    1000 * 1e6, // 1000 usdt
    97 * 1e16, // 3% slippage tolerance (0.97 core / 1000 usdt)
    970 * 1e6, // 3% slippage tolerance (1 core / 970 usdt)
    vReserveRatioBounds
);
```

## Removing liquidity

As is the case with Uniswap LP tokens, DMM-LP tokens implement meta-approvals to vastly help improve UX and save on gas costs. Hence, we recommend the usage of the `removeLiquidity*withPermit*` functions.

### Removing LP tokens from ERC20-ERC20 pool[​](https://docs.kyberswap.com/Classic/contract/providing-liquidity#removing-lp-tokens-from-erc20-erc20-pool) <a href="#removing-lp-tokens-from-erc20-erc20-pool" id="removing-lp-tokens-from-erc20-erc20-pool"></a>

#### Removing 100 wbtc-usdt LP tokens via removeLiquidityWithPermit[​](https://docs.kyberswap.com/Classic/contract/providing-liquidity#removing-100-wbtc-usdt-lp-tokens-via-removeliquiditywithpermit) <a href="#removing-100-wbtc-usdt-lp-tokens-via-removeliquiditywithpermit" id="removing-100-wbtc-usdt-lp-tokens-via-removeliquiditywithpermit"></a>

Note: For FoT tokens like CORE, the same function can be used, but the minimum receivable of core tokens should be adjusted.

```solidity
dmmRouter.removeLiquidityWithPermit(
    wbtc,
    usdt,
    wbtc-usdt-pool, // wbtc-usdt pool address
    100 * 1e8, // 100 wbtc-usdt LP tokens
    1 * 1e8, // Min receivable of 1 wbtc
    100 * 1e6, // Min receivable of 100 usdt
    msg.sender, // send assets to msg.sender
    block.timestamp, // deadline
    approveMax, // boolean flag if max token allowance approval
    v, // approve permit signature field
    r, // approve permit signature field
    s // approve permit signature field
);
```

### Removing LP tokens from ERC20-ETH pool[​](https://docs.kyberswap.com/Classic/contract/providing-liquidity#removing-lp-tokens-from-erc20-eth-pool) <a href="#removing-lp-tokens-from-erc20-eth-pool" id="removing-lp-tokens-from-erc20-eth-pool"></a>

#### Removing 100 core-eth LP tokens via removeLiquidityETHWithPermitSupportingFeeOnTransferTokens[​](https://docs.kyberswap.com/Classic/contract/providing-liquidity#removing-100-core-eth-lp-tokens-via-removeliquidityethwithpermitsupportingfeeontransfertokens) <a href="#removing-100-core-eth-lp-tokens-via-removeliquidityethwithpermitsupportingfeeontransfertokens" id="removing-100-core-eth-lp-tokens-via-removeliquidityethwithpermitsupportingfeeontransfertokens"></a>

```solidity
dmmRouter.removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(
    core,
    core-eth-pool, // core-eth pool address
    100 * 1e8, // 100 core-eth LP tokens
    1 * 1e18, // Min receivable of 1 core
    10 * 1e17, // Min receivable of 0.1 ether
    msg.sender, // send assets to msg.sender
    block.timestamp, // deadline
    approveMax, // boolean flag if max token allowance approval
    v, // approve permit signature field
    r, // approve permit signature field
    s // approve permit signature field
);
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.kyberswap.com/~/changes/1kQEhDNzHMDf7SwOE6Yu/liquidity-solutions/kyberswap-classic/developer-guides/providing-liquidity-to-classic-pools.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
