Skip to main content
Glama

remove_liquidity

Remove liquidity from trading pools by withdrawing liquidity tokens to reclaim underlying assets across supported EVM chains including Ethereum, Arbitrum, and Polygon.

Instructions

Remove liquidity from a trading pool using the Trader contract.

Args: chain_id: Chain ID (1, 10, 56, 100, 137, 8453, 42161) token0_address: Address of first token token1_address: Address of second token liquidity_amount: Amount of liquidity tokens to remove in wei Returns: JSON string with liquidity removal transaction details.

Input Schema

NameRequiredDescriptionDefault
chain_idYes
token0_addressYes
token1_addressYes
liquidity_amountYes

Input Schema (JSON Schema)

{ "properties": { "chain_id": { "title": "Chain Id", "type": "string" }, "liquidity_amount": { "title": "Liquidity Amount", "type": "string" }, "token0_address": { "title": "Token0 Address", "type": "string" }, "token1_address": { "title": "Token1 Address", "type": "string" } }, "required": [ "chain_id", "token0_address", "token1_address", "liquidity_amount" ], "type": "object" }

Implementation Reference

  • The handler function that implements the remove_liquidity MCP tool. It validates inputs, connects to the chain's Web3, calls the Trader contract's remove_liquidity function, signs and sends the transaction, waits for confirmation, and returns detailed transaction results in JSON.
    @mcp.tool() async def remove_liquidity(ctx: Context, chain_id: str, token0_address: str, token1_address: str, liquidity_amount: str) -> str: """Remove liquidity from a trading pool using the Trader contract. Args: chain_id: Chain ID (1, 10, 56, 100, 137, 8453, 42161) token0_address: Address of first token token1_address: Address of second token liquidity_amount: Amount of liquidity tokens to remove in wei Returns: JSON string with liquidity removal transaction details. """ try: paloma_ctx = ctx.request_context.lifespan_context if chain_id not in CHAIN_CONFIGS: return f"Error: Unsupported chain ID {chain_id}" config = CHAIN_CONFIGS[chain_id] if chain_id not in paloma_ctx.web3_clients: return f"Error: Web3 client not available for {config.name}" trader_address = TRADER_ADDRESSES.get(chain_id) if not trader_address: return f"Error: Trader contract not configured for {config.name}" # Validate addresses and amount if not Web3.is_address(token0_address): return f"Error: Invalid token0 address: {token0_address}" if not Web3.is_address(token1_address): return f"Error: Invalid token1 address: {token1_address}" try: amount_int = int(liquidity_amount) if amount_int <= 0: raise ValueError("Amount must be positive") except ValueError: return f"Error: Invalid liquidity amount: {liquidity_amount}" web3 = paloma_ctx.web3_clients[chain_id] trader_contract = web3.eth.contract(address=trader_address, abi=TRADER_ABI) # Get gas fee from contract try: gas_fee = trader_contract.functions.gas_fee().call() except Exception as e: logger.warning(f"Failed to get gas fee from contract: {e}, using 0") gas_fee = 0 # Build transaction remove_liquidity_tx_data = trader_contract.functions.remove_liquidity( token0_address, token1_address, amount_int ).build_transaction({ 'from': paloma_ctx.address, 'value': gas_fee, 'gasPrice': web3.to_wei(config.gas_price_gwei, 'gwei'), 'nonce': web3.eth.get_transaction_count(paloma_ctx.address) }) # Estimate gas with buffer try: estimated_gas = web3.eth.estimate_gas(remove_liquidity_tx_data) buffered_gas = estimated_gas + (estimated_gas // GAS_MULTIPLIER) remove_liquidity_tx_data['gas'] = buffered_gas except Exception as e: logger.warning(f"Gas estimation failed: {e}, using default") remove_liquidity_tx_data['gas'] = 400000 # Sign and send transaction signed_tx = paloma_ctx.account.sign_transaction(remove_liquidity_tx_data) tx_hash = web3.eth.send_raw_transaction(signed_tx.rawTransaction) # Wait for confirmation receipt = web3.eth.wait_for_transaction_receipt(tx_hash) # Get token symbols for display try: token0_contract = web3.eth.contract(address=token0_address, abi=ERC20_ABI) token1_contract = web3.eth.contract(address=token1_address, abi=ERC20_ABI) token0_symbol = token0_contract.functions.symbol().call() token1_symbol = token1_contract.functions.symbol().call() except: token0_symbol = "Unknown" token1_symbol = "Unknown" result = { "chain": config.name, "chain_id": config.chain_id, "trader_contract": trader_address, "token0": { "address": token0_address, "symbol": token0_symbol }, "token1": { "address": token1_address, "symbol": token1_symbol }, "liquidity_amount_wei": liquidity_amount, "transaction": { "hash": tx_hash.hex(), "status": "success" if receipt.status == 1 else "failed", "gas_used": receipt.gasUsed, "gas_fee_paid": str(gas_fee), "block_number": receipt.blockNumber }, "explorer_url": f"{config.explorer_url}/tx/{tx_hash.hex()}" } return json.dumps(result, indent=2) except Exception as e: logger.error(f"Error removing liquidity: {e}") return f"Error removing liquidity: {str(e)}"
  • The ABI schema definition for the remove_liquidity function in the Trader contract, which specifies the input parameters used by the tool handler.
    "name": "remove_liquidity", "type": "function", "inputs": [ {"name": "token0", "type": "address"}, {"name": "token1", "type": "address"}, {"name": "amount", "type": "uint256"} ], "outputs": [], "stateMutability": "payable" },
  • The full TRADER_ABI constant used by the remove_liquidity handler to interact with the Trader contract on various chains.
    TRADER_ABI = [ { "name": "purchase", "type": "function", "inputs": [ {"name": "from_token", "type": "address"}, {"name": "to_token", "type": "address"}, {"name": "amount", "type": "uint256"} ], "outputs": [], "stateMutability": "payable" }, { "name": "add_liquidity", "type": "function", "inputs": [ {"name": "token0", "type": "address"}, {"name": "token1", "type": "address"}, {"name": "amount0", "type": "uint256"}, {"name": "amount1", "type": "uint256"} ], "outputs": [], "stateMutability": "payable" }, { "name": "remove_liquidity", "type": "function", "inputs": [ {"name": "token0", "type": "address"}, {"name": "token1", "type": "address"}, {"name": "amount", "type": "uint256"} ], "outputs": [], "stateMutability": "payable" }, { "name": "gas_fee", "type": "function", "inputs": [], "outputs": [{"name": "", "type": "uint256"}], "stateMutability": "view" } ]
  • Mapping of chain IDs to Trader contract addresses, used to determine which contract to call for remove_liquidity operations.
    TRADER_ADDRESSES = { ChainID.ETHEREUM_MAIN: "0x7230EC05eD8c38D5be6f58Ae41e30D1ED6cfDAf1", ChainID.ARBITRUM_MAIN: "0x36B8763b3b71685F21512511bB433f4A0f50213E", ChainID.BASE_MAIN: "0xd58Dfd5b39fCe87dD9C434e95428DdB289934179", ChainID.BSC_MAIN: "0x8ee509a97279029071AB66Cb0391e8Dc67a137f9", ChainID.GNOSIS_MAIN: "0xd58Dfd5b39fCe87dD9C434e95428DdB289934179", ChainID.OPTIMISM_MAIN: "0xB6d4AAFfBbceB5e363352179E294326C91d6c127", ChainID.POLYGON_MAIN: "0xB6d4AAFfBbceB5e363352179E294326C91d6c127" }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/VolumeFi/mcpPADEX'

If you have feedback or need assistance with the MCP directory API, please join our Discord server