> ## 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.

# Removing liquidity (V1)

> Remove liquidity from SaucerSwap V1 pools with the removeLiquidityETH, removeLiquidity, and fee-on-transfer functions, including allowance requirements.

Outlined below are three methods to remove liquidity from an existing pool:

* [Removing HBAR-token liquidity](#removing-hbar-token-liquidity)
* [Removing token-token liquidity](#removing-token-token-liquidity)
* [Removing HBAR-token liquidity for tokens with custom fees](#removing-hbar-token-liquidity-supporting-tokens-with-custom-fees)

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

<Note>
  A spender allowance for the router is required for the LP token.
</Note>

<Check>
  removeLiquidity supports HTS tokens with custom fees.
</Check>

## Removing HBAR-token liquidity

Remove liquidity from an existing HBAR/token liquidity pool.

Function name: `removeLiquidityETH`

Recommended gas limit: 2,800,000

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

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

  ```solidity UniswapV2Router02.sol theme={null}
  function removeLiquidityETH(
    address token,
    uint liquidity,
    uint amountTokenMin,
    uint amountETHMin,
    address to,
    uint deadline
  ) public virtual override ensure(deadline) returns (uint amountToken, uint amountETH) {
    safeAssociateToken(address(this), token);
    (amountToken, amountETH) = removeLiquidity(
      token,
      whbar,
      liquidity,
      amountTokenMin,
      amountETHMin,
      address(this), // used to be msg.sender
      deadline
    );
    safeTransferToken(token, address(this), to, amountToken);
    safeApproveToken(whbar, WHBAR, amountETH);
    IWHBAR(WHBAR).withdraw(address(this), to, amountETH);
    safeDissociateToken(address(this), token);
  }
  ```
</CodeGroup>

<Info>
  The `removeLiquidityETH` 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)
    * [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
    } from '@hashgraph/sdk';

    //Client pre-checks:
    // - Router contract has spender allowance for the LP token

    const params = new ContractFunctionParameters();
    params.addAddress(tokenAddress); //address token
    params.addUint256(lpTokenAmountToRemove); //uint liquidity
    params.addUint256(amountTokenMin); //uint amountTokenMin
    params.addUint256(amountETHMin); //uint amountETHMin
    params.addAddress(toSoli); //address to
    params.addUint256(deadline); //uint deadline

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

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

***

## Removing token-token liquidity

Remove liquidity from an existing token/token liquidity pool.

Function name: `removeLiquidity`

Recommended gas limit: 1,600,000

| Parameter Name    | Description                                                  |
| ----------------- | ------------------------------------------------------------ |
| *address tokenA*  | EVM address of the first HTS token                           |
| *address tokenB*  | EVM address of the second HTS token                          |
| *uint liquidity*  | LP liquidity amount to remove 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 tokens                            |
| *uint deadline*   | Deadline in Unix seconds                                     |

<CodeGroup>
  ```solidity IUniswapV2Router01.sol theme={null}
  function removeLiquidity(
    address tokenA,
    address tokenB,
    uint liquidity,
    uint amountAMin,
    uint amountBMin,
    address to,
    uint deadline
  ) external returns (uint amountA, uint amountB);
  ```
</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)
    * [Hedera REST API](https://docs.hedera.com/hedera/sdks-and-apis/rest-api)
    * [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
    } from '@hashgraph/sdk';

    //Client pre-checks:
    // - Router contract has spender allowance for the LP token

    const params = new ContractFunctionParameters();
    params.addAddress(tokenAAddress); //address tokenA
    params.addAddress(tokenBAddress); //address tokenB
    params.addUint256(lpTokenAmountToRemove); //uint liquidity
    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('removeLiquidity', params)
     .execute(client);

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

***

## Removing HBAR-token liquidity supporting tokens with custom fees

Remove liquidity from an existing HBAR/token liquidity pool supporting HTS tokens with custom fees on transfer.

Function name: `removeLiquidityETHSupportingFeeOnTransferTokens`

Recommended gas limit: 3,000,000

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

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

  ```solidity UniswapV2Router02.sol theme={null}
  function removeLiquidityETHSupportingFeeOnTransferTokens(
    address token,
    uint liquidity,
    uint amountTokenMin,
    uint amountETHMin,
    address to,
    uint deadline
  ) public virtual override ensure(deadline) returns (uint amountETH) {
      safeAssociateToken(address(this), token);
      (, amountETH) = removeLiquidity(
        token,
        whbar,
        liquidity,
        amountTokenMin,
        amountETHMin,
        address(this),
        deadline
      );
      uint256 amountToSend = IERC20(token).balanceOf(address(this));
      require(amountToSend >= amountTokenMin, 'UniswapV2Router: INSUFFICIENT_A_AMOUNT_FOT'); // second slippage check
      safeTransferToken(token, address(this), to, amountToSend);
      safeApproveToken(whbar, WHBAR, amountETH);
      IWHBAR(WHBAR).withdraw(address(this), to, amountETH);
      safeDissociateToken(address(this), token);
  }
  ```
</CodeGroup>

<Info>
  The `removeLiquidityETHSupportingFeeOnTransferTokens` 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)
    * [Hedera REST API](https://docs.hedera.com/hedera/sdks-and-apis/rest-api)
    * [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
    } from '@hashgraph/sdk';

    //Client pre-checks:
    // - Router contract has spender allowance for the LP token

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

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

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

## Next steps

<CardGroup cols={2}>
  <Card title="Adding liquidity (V1)" href="/developers/v1/liquidity/adding-liquidity">
    Provide liquidity to an existing V1 pool.
  </Card>

  <Card title="Get pool reserves (V1)" href="/developers/v1/liquidity/get-pool-reserves">
    Read current reserves for a pool.
  </Card>

  <Card title="Contract deployments" href="/developers/contracts">
    Router, factory, and token IDs for mainnet and testnet.
  </Card>
</CardGroup>
