Skip to main content
Glama

add_liquidity

Add liquidity to trading pools on Paloma DEX across multiple EVM chains by specifying token amounts and addresses to receive transaction details.

Instructions

Add liquidity to 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
    token0_amount: Amount of first token in wei
    token1_amount: Amount of second token in wei

Returns:
    JSON string with liquidity addition transaction details.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
chain_idYes
token0_addressYes
token1_addressYes
token0_amountYes
token1_amountYes

Implementation Reference

  • The MCP tool handler for 'add_liquidity'. It validates inputs, builds and sends a transaction to the Trader contract's add_liquidity function on the specified EVM chain, and returns transaction details including explorer link.
    @mcp.tool()
    async def add_liquidity(ctx: Context, chain_id: str, token0_address: str, token1_address: str, token0_amount: str, token1_amount: str) -> str:
        """Add liquidity to 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
            token0_amount: Amount of first token in wei
            token1_amount: Amount of second token in wei
        
        Returns:
            JSON string with liquidity addition 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 amounts
            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:
                amount0_int = int(token0_amount)
                amount1_int = int(token1_amount)
                if amount0_int <= 0 or amount1_int <= 0:
                    raise ValueError("Amounts must be positive")
            except ValueError:
                return f"Error: Invalid amounts: {token0_amount}, {token1_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
            add_liquidity_tx_data = trader_contract.functions.add_liquidity(
                token0_address,
                token1_address,
                amount0_int,
                amount1_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(add_liquidity_tx_data)
                buffered_gas = estimated_gas + (estimated_gas // GAS_MULTIPLIER)
                add_liquidity_tx_data['gas'] = buffered_gas
            except Exception as e:
                logger.warning(f"Gas estimation failed: {e}, using default")
                add_liquidity_tx_data['gas'] = 400000
            
            # Sign and send transaction
            signed_tx = paloma_ctx.account.sign_transaction(add_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()
                token0_decimals = token0_contract.functions.decimals().call()
                token1_decimals = token1_contract.functions.decimals().call()
            except:
                token0_symbol = "Unknown"
                token1_symbol = "Unknown"
                token0_decimals = 18
                token1_decimals = 18
            
            amount0_display = float(amount0_int) / (10 ** token0_decimals)
            amount1_display = float(amount1_int) / (10 ** token1_decimals)
            
            result = {
                "chain": config.name,
                "chain_id": config.chain_id,
                "trader_contract": trader_address,
                "token0": {
                    "address": token0_address,
                    "symbol": token0_symbol,
                    "amount_wei": token0_amount,
                    "amount_display": str(amount0_display)
                },
                "token1": {
                    "address": token1_address,
                    "symbol": token1_symbol,
                    "amount_wei": token1_amount,
                    "amount_display": str(amount1_display)
                },
                "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 adding liquidity: {e}")
            return f"Error adding liquidity: {str(e)}"
  • ABI schema definition for the Trader contract's add_liquidity function, specifying the input parameters (token0, token1, amount0, amount1) that match the tool's parameters.
        "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"
    },
  • padex.py:1896-1896 (registration)
    FastMCP decorator that registers the add_liquidity function as an MCP tool.
    @mcp.tool()
  • TRADER_ABI defines the contract interface used by the add_liquidity handler, including the ABI for add_liquidity and supporting functions like gas_fee.
    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"
        }
    ]
  • Chain-specific Trader contract addresses used by the add_liquidity handler to locate the contract for liquidity addition.
    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