> ## Documentation Index
> Fetch the complete documentation index at: https://docs.saucerswap.finance/llms.txt
> Use this file to discover all available pages before exploring further.

# Adding liquidity (V1)

> Add liquidity to existing SaucerSwap V1 pools with the addLiquidityETH and addLiquidity functions, including allowance and LP token association setup.

Add liquidity to an existing HBAR/token liquidity pool.

Outlined below are two methods to add liquidity to an existing pool on SaucerSwap:

* [Adding HBAR-token liquidity](#adding-hbar-token-liquidity)

* [Adding token-token liquidity](#adding-token-token-liquidity)

<Info>
  Contract ID: [SaucerSwapV1RouterV3](https://hashscan.io/mainnet/contract/0.0.3045981)
</Info>

<Tip>
  To create a new liquidity pool, see [Creating a new liquidity pool](/developers/v1/liquidity/create-a-new-pool).
</Tip>

<Note>
  Ensure that the client has the LP token associated before adding liquidity.
</Note>

<Note>
  A spender allowance for the Router contract is required for HTS tokens.
</Note>

<Check>
  Both `addLiquidityETH` and `addLiquidity` support HTS tokens containing custom fees.
</Check>

***

## Adding HBAR-token liquidity

Add more liquidity to an existing HBAR/token liquidity pool.

Function name: `addLiquidityETH`

Recommended gas limit: 240,000

| Parameter Name            | Description                                   |
| ------------------------- | --------------------------------------------- |
| *address token*           | EVM address of the token to pool with HBAR    |
| *uint amountTokenDesired* | The maximum token amount in its smallest unit |
| *uint amountTokenMin*     | The minimum token amount in its smallest unit |
| *uint amountETHMin*       | The minimum HBAR amount in its smallest unit  |
| *address to*              | EVM address to receive the liquidity tokens   |
| *uint deadline*           | Deadline in Unix seconds                      |

<CodeGroup>
  ```solidity IUniswapV2Router01.sol theme={null}
  function addLiquidityETH(
    address token,
    uint amountTokenDesired,
    uint amountTokenMin,
    uint amountETHMin,
    address to,
    uint deadline
  ) external payable returns (uint amountToken, uint amountETH, uint liquidity);
  ```

  ```solidity UniswapV2Router02.sol theme={null}
  function addLiquidityETH(
    address token,
    uint amountTokenDesired,
    uint amountTokenMin,
    uint amountETHMin,
    address to,
    uint deadline
  ) external virtual override payable ensure(deadline) returns (uint amountToken, uint amountETH, uint liquidity) {
    (amountToken, amountETH) = _addLiquidity(
      token,
      whbar,
      amountTokenDesired,
      msg.value,
      amountTokenMin,
      amountETHMin
    );

    address pair = IUniswapV2Factory(factory).getPair(token, whbar);
    require(pair != address(0), "UniswapV2Router: PAIR DOES NOT EXIST");

    safeTransferToken(
      token, msg.sender, pair, amountToken
    );
    IWHBAR(WHBAR).deposit{value: amountETH}(msg.sender, pair);
    liquidity = IUniswapV2Pair(pair).mint(to);
    // refund dust eth, if any
    if (msg.value > amountETH) TransferHelper.safeTransferETH(msg.sender, msg.value - amountETH);
  }
  ```
</CodeGroup>

<Info>
  The `addLiquidityETH` function operates in HBAR but derives its name from Uniswap on Ethereum. This name was kept to simplify integration for developers versed in Uniswap tools.
</Info>

### Code overview

<Tabs>
  <Tab title="JavaScript SDK">
    Resources:

    * [SaucerSwap deployed contract IDs](/developers/contracts)
    * [Hedera JavaScript SDK](https://github.com/hashgraph/hedera-sdk-js)
    * [Token approve allowance](https://docs.hedera.com/hedera/sdks-and-apis/sdks/cryptocurrency/approve-an-allowance)
    * [Associate tokens to an account](https://docs.hedera.com/hedera/sdks-and-apis/sdks/token-service/associate-tokens-to-an-account)
    * [Calling a smart contract function](https://docs.hedera.com/hedera/sdks-and-apis/sdks/smart-contracts/call-a-smart-contract-function)

    ```typescript theme={null}
    import {
      ContractFunctionParameters,
      ContractExecuteTransaction,
      AccountAllowanceApproveTransaction,
      TokenAssociateTransaction
    } from '@hashgraph/sdk';

    //Client pre-checks:
    // - Output NFT token is associated
    // - Router contract has spender allowance for the input token

    const params = new ContractFunctionParameters();
    params.addAddress(tokenAddress); //address token
    params.addUint256(amountTokenDesired); //uint amountTokenDesired
    params.addUint256(amountTokenMin); //uint amountTokenMin
    params.addUint256(amountHBARMin); //uint amountETHMin
    params.addAddress(toAddress); //address to
    params.addUint256(deadline); //uint deadline

    const response = await new ContractExecuteTransaction()
     .setPayableAmount(inputHbar)
     .setContractId(routerContractId)
     .setGas(gasLim)
     .setFunction('addLiquidityETH', params)
     .execute(client);

    const record = await response.getRecord(client);
    const result = record.contractFunctionResult!;
    const values = result.getResult(['uint','uint','uint']);
    const amountToken = values[0]; //uint amountToken
    const amountHBAR = values[1]; //uint amountETH
    const liquidity = values[2]; //uint liquidity
    ```
  </Tab>
</Tabs>

## Adding token-token liquidity

Add more liquidity to an existing token/token liquidity pool.

Function name: `addLiquidity`

Recommended gas limit: 240,000

| Parameter Name        | Description                                                  |
| --------------------- | ------------------------------------------------------------ |
| *address tokenA*      | EVM address of the first HTS token                           |
| *address tokenB*      | EVM address of the second HTS token                          |
| *uint amountADesired* | The maximum amount for the first token in its smallest unit  |
| *uint amountBDesired* | The maximum amount for the second token in its smallest unit |
| *uint amountAMin*     | The minimum amount for the first token in its smallest unit  |
| *uint amountBMin*     | The minimum amount for the second token in its smallest unit |
| *address to*          | EVM address to receive the liquidity tokens                  |
| *uint deadline*       | Deadline in Unix seconds                                     |

<CodeGroup>
  ```solidity IUniswapV2Router01.sol theme={null}
  function addLiquidity(
    address tokenA,
    address tokenB,
    uint amountADesired,
    uint amountBDesired,
    uint amountAMin,
    uint amountBMin,
    address to,
    uint deadline
  ) external returns (uint amountA, uint amountB, uint liquidity);
  ```
</CodeGroup>

### Code overview

<Tabs>
  <Tab title="JavaScript SDK">
    Resources:

    * [SaucerSwap deployed contract IDs](/developers/contracts)
    * [Hedera JavaScript SDK](https://github.com/hashgraph/hedera-sdk-js)
    * [Token approve allowance](https://docs.hedera.com/hedera/sdks-and-apis/sdks/cryptocurrency/approve-an-allowance)
    * [Associate tokens to an account](https://docs.hedera.com/hedera/sdks-and-apis/sdks/token-service/associate-tokens-to-an-account)
    * [Calling a smart contract function](https://docs.hedera.com/hedera/sdks-and-apis/sdks/smart-contracts/call-a-smart-contract-function)

    ```typescript theme={null}
    import {
      ContractFunctionParameters,
      ContractExecuteTransaction,
      AccountAllowanceApproveTransaction,
      TokenAssociateTransaction
    } from '@hashgraph/sdk';

    //Client pre-checks:
    // - Output NFT token is associated
    // - Router contract has spender allowance for the input tokens

    const params = new ContractFunctionParameters();
    params.addAddress(tokenAAddress); //address tokenA
    params.addAddress(tokenBAddress); //address tokenB
    params.addUint256(amountADesired); //uint amountADesired
    params.addUint256(amountBDesired); //uint amountBDesired
    params.addUint256(amountAMin); //uint amountAMin
    params.addUint256(amountBMin); //uint amountBMin
    params.addAddress(toAddress); //address to
    params.addUint256(deadline); //uint deadline

    const response = await new ContractExecuteTransaction()
     .setContractId(routerContractId)
     .setGas(gasLim)
     .setFunction('addLiquidity', params)
     .execute(client);

    const record = await response.getRecord(client);
    const result = record.contractFunctionResult!;
    const values = result.getResult(['uint','uint','uint']);
    const amountA = values[0]; //uint amountA
    const amountB = values[1]; //uint amountB
    const liquidity = values[2]; //uint liquidity
    ```
  </Tab>
</Tabs>

## Next steps

<CardGroup cols={2}>
  <Card title="Removing liquidity (V1)" href="/developers/v1/liquidity/removing-liquidity">
    Withdraw your share of a V1 pool.
  </Card>

  <Card title="Create a new pool (V1)" href="/developers/v1/liquidity/create-a-new-pool">
    Create the pool first if it does not exist.
  </Card>

  <Card title="Get pool reserves (V1)" href="/developers/v1/liquidity/get-pool-reserves">
    Read current reserves before sizing amounts.
  </Card>
</CardGroup>
