add_liquidity
Add liquidity to trading pools on Paloma DEX across multiple EVM chains by providing token addresses and amounts to enable trading and earn fees.
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
| Name | Required | Description | Default |
|---|---|---|---|
| chain_id | Yes | ||
| token0_address | Yes | ||
| token1_address | Yes | ||
| token0_amount | Yes | ||
| token1_amount | Yes |
Input Schema (JSON Schema)
{
"properties": {
"chain_id": {
"title": "Chain Id",
"type": "string"
},
"token0_address": {
"title": "Token0 Address",
"type": "string"
},
"token0_amount": {
"title": "Token0 Amount",
"type": "string"
},
"token1_address": {
"title": "Token1 Address",
"type": "string"
},
"token1_amount": {
"title": "Token1 Amount",
"type": "string"
}
},
"required": [
"chain_id",
"token0_address",
"token1_address",
"token0_amount",
"token1_amount"
],
"type": "object"
}
Implementation Reference
- padex.py:1897-2026 (handler)The main handler function for the 'add_liquidity' MCP tool. It validates inputs, builds and sends a transaction to the Trader contract's add_liquidity method on the specified chain, and returns transaction details.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)}"
- padex.py:256-266 (schema)ABI schema definition for the add_liquidity contract function called by the tool handler."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:1897-1897 (registration)MCP tool registration decorator that registers the add_liquidity function as an available tool.async def add_liquidity(ctx: Context, chain_id: str, token0_address: str, token1_address: str, token0_amount: str, token1_amount: str) -> str:
- padex.py:288-296 (helper)Mapping of chain IDs to Trader contract addresses used by the add_liquidity handler.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" }
- padex.py:243-285 (helper)Full ABI for the Trader contract, including add_liquidity function interface.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" } ]