Outlined below are three methods to remove liquidity from an existing pool:
A spender allowance for the router is required for the LP token.
removeLiquidity supports HTS tokens with custom fees.
Removing HBAR/Token Liquidity
Remove liquidity from an existing HBAR/token liquidity pool.
Function name: removeLiquidityETH
⛽ Recommended gas: 2,800,000 gwei (~ $0.24 USD)
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
IUniswapV2Router01.sol
UniswapV2Router02.sol
function removeLiquidityETH (
address token ,
uint liquidity ,
uint amountTokenMin ,
uint amountETHMin ,
address to ,
uint deadline
) external returns ( uint amountToken , uint amountETH );
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.
Code Overview
Resources:
import {
ContractFunctionParameters ,
ContractExecuteTransaction ,
AccountAllowanceApproveTransaction ,
..
} from '@hashgraph/sdk' ;
//Client pre-checks:
// - Router contract has spender allowance 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
Resources:
import {
ContractFunctionParameters ,
ContractExecuteTransaction ,
AccountAllowanceApproveTransaction ,
..
} from '@hashgraph/sdk' ;
//Client pre-checks:
// - Router contract has spender allowance 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
Removing Token/Token Liquidity
Remove liquidity from an existing token/token liquidity pool.
Function name: removeLiquidity
⛽ Recommended gas: 1,600,000 gwei (~ $0.14 USD)
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
IUniswapV2Router01.sol
UniswapV2Router02.sol
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 );
Code Overview
Resources:
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 ( 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 ( 'addLiquidityNewPool' , 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
Resources:
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 ( 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 ( 'addLiquidityNewPool' , 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
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: 3,000,000 gwei (~ $0.26 USD)
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
IUniswapV2Router01.sol
UniswapV2Router02.sol
function removeLiquidityETHSupportingFeeOnTransferTokens (
address token ,
uint liquidity ,
uint amountTokenMin ,
uint amountETHMin ,
address to ,
uint deadline
) external returns ( uint amountETH );
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.
Code Overview
Resources:
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 [ 1 ]; //uint amountETH
Resources:
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 [ 1 ]; //uint amountETH