Skip to content

feat/PancakeSwap CLMM LP Management & MasterChef Integration on BSC#606

Open
VeXHarbinger wants to merge 15 commits into
hummingbot:developmentfrom
VeXHarbinger:pancakeswap-clmm-lp-bsc
Open

feat/PancakeSwap CLMM LP Management & MasterChef Integration on BSC#606
VeXHarbinger wants to merge 15 commits into
hummingbot:developmentfrom
VeXHarbinger:pancakeswap-clmm-lp-bsc

Conversation

@VeXHarbinger
Copy link
Copy Markdown

@VeXHarbinger VeXHarbinger commented Feb 21, 2026

PR Summary: PancakeSwap CLMM LP Management & MasterChef Integration on BSC

@cardosofede ~ You said you'd take a look at this and I just saw that new post about bsc and don't know if it resolves these issues or not. I did move them up a level in the path like you asked

What's Included

This PR adds complete PancakeSwap CLMM (Concentrated Liquidity Market Maker) position management and MasterChef staking integration on BSC.

Key Features Added

1. MasterChef Staking System

  • POST /connectors/pancakeswap/masterchef-stake - Stake LP NFT positions in MasterChef

    • Validates NFT ownership and pool registration
    • Checks MasterChef approval before transfer
    • Returns detailed error messages with actionable steps
  • POST /connectors/pancakeswap/masterchef-unstake - Unstake LP NFT from MasterChef

    • Properly uses MasterChef withdraw() function
    • Returns collected rewards to wallet
  • POST /connectors/pancakeswap/masterchef-unstake-and-close ✨ NEW

    • Convenience endpoint: unstakes NFT and immediately closes position
    • Removes liquidity, collects fees, burns NFT in one call
  • POST /connectors/pancakeswap/masterchef-knows-pool ✨ NEW

    • Checks if a pool is registered in MasterChef
    • Returns pool ID for registered pools

2. Critical Fixes

  • BigInt Conversion Error - Fixed "Cannot convert X to BigInt" when executing swaps with decimal amounts
  • Amount Handling - Enhanced openPosition and quoteSwap to properly handle numeric values
  • Error Messages - Improved user-facing error messages with specific instructions

3. BSC Network Support

  • New /wallet/balances endpoint for getting wallet balances
  • Wallet management support for BSC (wallets stored alongside Ethereum)
  • Proper network routing for all operations

4. Enhanced Parameters

  • positionsOwned - Added activeOnly filter to show only positions with active liquidity
  • executeSwap - Added optional poolAddress parameter for manual pool selection
  • masterchef-stake/unstake - Added walletAddress parameter for transaction signing

Files Modified

Core Implementation (5 files)

  • src/connectors/pancakeswap/pancakeswap.ts - MasterChef integration methods
  • src/connectors/pancakeswap/clmm-routes/index.ts - Route registration
  • src/connectors/pancakeswap/masterchef-stake.ts ✨ NEW - Staking endpoint
  • src/connectors/pancakeswap/masterchef-unstake.ts ✨ NEW - Unstaking endpoint
  • src/connectors/pancakeswap/PancakeswapV3Masterchef.abi.json ✨ NEW - MasterChef ABI

New Endpoints

  • src/connectors/pancakeswap/masterchef-stake.ts ✨ NEW
  • src/connectors/pancakeswap/masterchef-unstake-and-close.ts ✨ NEW
  • src/connectors/pancakeswap/masterchef-knows-pool.ts ✨ NEW

Fixes & Enhancements (5 files)

  • src/connectors/pancakeswap/clmm-routes/quoteSwap.ts - BigInt fixes
  • src/connectors/pancakeswap/clmm-routes/openPosition.ts - Amount handling
  • src/connectors/pancakeswap/clmm-routes/positionsOwned.ts - activeOnly parameter
  • src/connectors/pancakeswap/clmm-routes/positionInfo.ts - Error handling
  • src/connectors/pancakeswap/schemas.ts - Schema updates

wallet Support (4 files)

  • src/wallet/schemas.ts - BSC chain support
  • src/wallet/utils.ts - BSC wallet handling
  • src/wallet/balances.ts ✨ NEW - wallet balance endpoint

Testing Checklist

Before merging, verify:

  • POST /connectors/pancakeswap/masterchef-stake succeeds (after NFT approval)
  • POST /connectors/pancakeswap/execute-swap handles decimal amounts correctly
  • POST /connectors/pancakeswap/open-position accepts string and number inputs
  • POST /connectors/pancakeswap/masterchef-unstake-and-close completes both operations
  • /wallet/balances returns correct wallet balances
  • Wallets can be added/retrieved with chain='bsc'

Value Conversions Corrected

All the following value conversion issues were fixed:

  1. BigInt Scientific Notation - Raw amounts now returned as full precision strings
  2. Decimal Input Handling - Amounts can be passed as decimals (0.032, 1.52938, etc.)
  3. String/Number Flexibility - Functions handle both string and numeric inputs

Breaking Changes

None. All changes are backward compatible with existing endpoints.

Fix 2: Execute-Swap BigInt Conversion Error

Problem

{
  "statusCode": 500,
  "error": "HttpError",
  "message": "Failed to execute swap: Cannot convert 200000000000000000 to a BigInt"
}

When calling with amount: 0.2, getting BigInt conversion error.
File: src/connectors/pancakeswap/clmm-routes/executeSwap.ts

Step-by-Step Testing Guide

Replace the following placeholders with your actual values:

  • <YOUR_WALLET_ADDRESS> - Your BSC wallet address (e.g., 0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb)
  • <YOUR_POOL_ADDRESS> - Pool contract address (e.g., 0x7f51c8aaa6b0599abd16674e2b17fec7a9f674a1)
  • <YOUR_NFT_ID> - NFT token ID from opened position (e.g., 12345)

Prerequisites

  1. Start Gateway (from ~/trash/hummingbot-core/)

    docker compose up -d
  2. Verify Gateway is Running

    curl http://localhost:15888/health
  3. Add Your Wallet to Gateway

    curl -X POST "http://localhost:15888/wallet/add" \
      -H "Content-Type: application/json" \
      -d '{
        "chain": "ethereum",
        "network": "bsc",
        "privateKey": "YOUR_PRIVATE_KEY_HERE"
      }'

Test 1: Get Pool Information

curl "http://localhost:15888/connectors/pancakeswap/clmm/pool-info?network=bsc&poolAddress=<YOUR_POOL_ADDRESS>"

Expected Response:

{
  "address": "0x7f51c8aaa6b0599abd16674e2b17fec7a9f674a1",
  "baseTokenAddress": "0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82",
  "quoteTokenAddress": "0x55d398326f99059fF775485246999027B3197955",
  "feePct": 0.25,
  "price": 3.75,
  "baseTokenAmount": 1250000,
  "quoteTokenAmount": 4687500,
  "activeBinId": 85176
}

Test 2: Quote a New Position

curl -X POST "http://localhost:15888/connectors/pancakeswap/clmm/quote-position" \
  -H "Content-Type: application/json" \
  -d '{
    "network": "bsc",
    "lowerPrice": 3.5,
    "upperPrice": 4.0,
    "poolAddress": "<YOUR_POOL_ADDRESS>",
    "baseTokenAmount": 100
  }'

Expected Response:

{
  "baseTokenAmount": 100,
  "quoteTokenAmount": 375.25,
  "lowerPrice": 3.5,
  "upperPrice": 4.0,
  "liquidity": "150000000000000000",
  "baseLimited": true
}

Test 3: Open a Position (Decimal Amount Handling)

Before running: Ensure you have approved both tokens for the Position Manager (0xEfF92A263d31888d860bD50809A8D171709b7b1c)

curl -X POST "http://localhost:15888/connectors/pancakeswap/clmm/open-position" \
  -H "Content-Type: application/json" \
  -d '{
    "network": "bsc",
    "walletAddress": "<YOUR_WALLET_ADDRESS>",
    "lowerPrice": 3.5,
    "upperPrice": 4.0,
    "poolAddress": "<YOUR_POOL_ADDRESS>",
    "baseTokenAmount": 0.5,
    "quoteTokenAmount": 1.875
  }'

Expected Response:

{
  "signature": "0x1234567890abcdef...",
  "status": 1,
  "data": {
    "fee": 0.00123,
    "positionAddress": "12345",
    "positionRent": 0,
    "baseTokenAmountAdded": 0.5,
    "quoteTokenAmountAdded": 1.875
  }
}

Save the positionAddress value as <YOUR_NFT_ID> for subsequent tests.

Test 4: Get Position Information

curl "http://localhost:15888/connectors/pancakeswap/clmm/position-info?network=bsc&positionAddress=<YOUR_NFT_ID>"

Expected Response:

{
  "address": "12345",
  "poolAddress": "0x7f51c8aaa6b0599abd16674e2b17fec7a9f674a1",
  "baseTokenAddress": "0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82",
  "quoteTokenAddress": "0x55d398326f99059fF775485246999027B3197955",
  "baseTokenAmount": 0.5,
  "quoteTokenAmount": 1.875,
  "baseFeeAmount": 0,
  "quoteFeeAmount": 0,
  "lowerBinId": 85150,
  "upperBinId": 85200,
  "lowerPrice": 3.5,
  "upperPrice": 4.0,
  "price": 3.75
}

Test 5: Execute Swap (BigInt Fix Test)

Before running: Ensure you have approved both tokens for the SwapRouter02 (0x1b81D678ffb9C0263b24A97847620C99d213eB14)

curl -X POST "http://localhost:15888/connectors/pancakeswap/clmm/execute-swap" \
  -H "Content-Type: application/json" \
  -d '{
    "network": "bsc",
    "walletAddress": "<YOUR_WALLET_ADDRESS>",
    "baseToken": "CAKE",
    "quoteToken": "USDT",
    "amount": 0.2,
    "side": "BUY",
    "slippagePct": 1.0
  }'

Expected Response:

{
  "signature": "0xabcdef1234567890...",
  "status": 1,
  "data": {
    "tokenIn": "0x55d398326f99059fF775485246999027B3197955",
    "tokenOut": "0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82",
    "amountIn": 0.75,
    "amountOut": 0.2,
    "fee": 0.00089,
    "baseTokenBalanceChange": 0.2,
    "quoteTokenBalanceChange": -0.75
  }
}

Test 6: Check if Pool is Registered in MasterChef

curl -X POST "http://localhost:15888/connectors/pancakeswap/masterchef-knows-pool" \
  -H "Content-Type: application/json" \
  -d '{
    "network": "bsc",
    "poolAddress": "<YOUR_POOL_ADDRESS>"
  }'

Expected Response (if registered):

{
  "isRegistered": true,
  "poolId": 42
}

Expected Response (if not registered):

{
  "isRegistered": false
}

Test 7: Stake NFT in MasterChef (Optional)

Before running: Ensure you have approved MasterChef for NFT transfers via the Position Manager's setApprovalForAll function.

curl -X POST "http://localhost:15888/connectors/pancakeswap/masterchef-stake" \
  -H "Content-Type: application/json" \
  -d '{
    "network": "bsc",
    "walletAddress": "<YOUR_WALLET_ADDRESS>",
    "nftId": "<YOUR_NFT_ID>"
  }'

Expected Response:

{
  "signature": "0x9876543210fedcba...",
  "status": 1,
  "message": "NFT staked successfully in MasterChef"
}

Test 8: Unstake NFT from MasterChef

curl -X POST "http://localhost:15888/connectors/pancakeswap/masterchef-unstake" \
  -H "Content-Type: application/json" \
  -d '{
    "network": "bsc",
    "walletAddress": "<YOUR_WALLET_ADDRESS>",
    "nftId": "<YOUR_NFT_ID>"
  }'

Expected Response:

{
  "signature": "0xfedcba0987654321...",
  "status": 1,
  "message": "NFT unstaked successfully from MasterChef",
  "rewardsCollected": 12.5
}

Test 9: Close Position

curl -X POST "http://localhost:15888/connectors/pancakeswap/clmm/close-position" \
  -H "Content-Type: application/json" \
  -d '{
    "network": "bsc",
    "walletAddress": "<YOUR_WALLET_ADDRESS>",
    "positionAddress": "<YOUR_NFT_ID>"
  }'

Expected Response:

{
  "signature": "0x1122334455667788...",
  "status": 1,
  "data": {
    "fee": 0.00095,
    "baseTokenAmountRemoved": 0.5,
    "quoteTokenAmountRemoved": 1.875,
    "baseFeeAmount": 0.002,
    "quoteFeeAmount": 0.0075
  }
}

Test 10: Get Wallet Balances

curl "http://localhost:15888/wallet/balances?chain=ethereum&network=bsc&address=<YOUR_WALLET_ADDRESS>"

Expected Response:

{
  "balances": {
    "BNB": "1.25",
    "CAKE": "150.5",
    "USDT": "500.25"
  }
}

Test 11: List All Positions Owned (with activeOnly filter)

curl "http://localhost:15888/connectors/pancakeswap/clmm/positions-owned?network=bsc&walletAddress=<YOUR_WALLET_ADDRESS>&activeOnly=true"

Expected Response:

[
  {
    "address": "12345",
    "poolAddress": "0x7f51c8aaa6b0599abd16674e2b17fec7a9f674a1",
    "baseTokenAmount": 0.5,
    "quoteTokenAmount": 1.875,
    "lowerPrice": 3.5,
    "upperPrice": 4.0,
    "price": 3.75
  }
]

Common Error Scenarios to Test

Error 1: Insufficient Allowance for Swap

# This should fail with clear error message if SwapRouter02 approval is missing
curl -X POST "http://localhost:15888/connectors/pancakeswap/clmm/execute-swap" \
  -H "Content-Type: application/json" \
  -d '{
    "network": "bsc",
    "walletAddress": "<YOUR_WALLET_ADDRESS>",
    "baseToken": "CAKE",
    "quoteToken": "USDT",
    "amount": 0.2,
    "side": "BUY"
  }'

Expected Error:

{
  "statusCode": 400,
  "error": "Bad Request",
  "message": "Insufficient allowance for USDT. Current: 0 USDT, Required: 0.75 USDT. To swap with PancakeSwap CLMM, you need to approve the spender \"pancakeswap/clmm/swap\" instead of \"pancakeswap/clmm\". This will approve the SwapRouter02 address (0x1b81D678ffb9C0263b24A97847620C99d213eB14)..."
}

Error 2: Pool Not Registered in MasterChef

curl -X POST "http://localhost:15888/connectors/pancakeswap/masterchef-stake" \
  -H "Content-Type: application/json" \
  -d '{
    "network": "bsc",
    "walletAddress": "<YOUR_WALLET_ADDRESS>",
    "nftId": "<NFT_FROM_UNREGISTERED_POOL>"
  }'

Expected Error:

{
  "statusCode": 400,
  "error": "Bad Request",
  "message": "Pool 0x... is not registered in MasterChef. Only pools registered in MasterChef can be staked."
}

Changes Made:

  1. Comprehensive Logging - Added logging at every step to trace where conversion happens:

    logger.info(`Input: amount=${amount}, type=${typeof amount}, side=${side}`);
    logger.info(`rawAmountIn: ${quote.rawAmountIn} (type: ${typeof quote.rawAmountIn})`);
  2. Raw Amount Formatting - Ensured all quote values are properly formatted strings:

    // In quoteSwap.ts
    const rawAmountInStr = BigNumber.from(trade.inputAmount.quotient.toString()).toString();
  3. Direct String Passing - Pass raw strings directly to contract functions:

    const exactInputParams = {
      tokenIn: quote.inputToken.address,
      tokenOut: quote.outputToken.address,
      fee: quote.feeTier,
      recipient: walletAddress,
      deadline: Math.floor(Date.now() / 1000) + 300,
      amountIn: quote.rawAmountIn,  // Direct string, no conversion
      amountOutMinimum: quote.rawMinAmountOut,
      sqrtPriceLimitX96: swapParams.sqrtPriceLimitX96,
    };
  4. Error Tracing - Enhanced error messages with stack traces:

    logger.error(`Swap execution error: ${error.message}`);
    logger.error(`Error stack: ${error.stack}`);

Expected Behavior Now

When you call the endpoint again with the same payload, you'll see detailed logs like:

=== executeClmmSwap START ===
Input: amount=0.2, type=number, side=BUY
Getting quote with amount=0.2...
Quote received:
  rawAmountIn: 200000000000000000 (type: string)
  rawAmountOut: 2500000000000000000 (type: string)
  ...
Calling exactInputSingle with params: {...}

This will show us EXACTLY where any conversion issue occurs, allowing us to pinpoint and fix it.

Follow-up Testing

After deploying these changes:

  1. Call /connectors/pancakeswap/clmm/execute-swap with your test payload
  2. Check gateway logs for the detailed trace
  3. If error persists, the logs will show the exact point of failure with types

Related Issues

  • Resolves MasterChef integration for LP position staking
  • Fixes BigInt conversion errors in token swap operations
  • Adds comprehensive BSC network support

@VeXHarbinger VeXHarbinger changed the title PancakeSwap CLMM LP Management & MasterChef Integration on BSC feat: PancakeSwap CLMM LP Management & MasterChef Integration on BSC Feb 21, 2026
@VeXHarbinger VeXHarbinger changed the title feat: PancakeSwap CLMM LP Management & MasterChef Integration on BSC feat/PancakeSwap CLMM LP Management & MasterChef Integration on BSC Feb 21, 2026
@VeXHarbinger
Copy link
Copy Markdown
Author

Wait there is a file that should have been removed

@VeXHarbinger VeXHarbinger reopened this Feb 21, 2026
@VeXHarbinger
Copy link
Copy Markdown
Author

When you said I created bsc as a chain (Chain/BSC) I misunderstood the comment and just saw what you were seeing. That was old and has been deleted, I thought you were referring to a config change.

@VeXHarbinger
Copy link
Copy Markdown
Author

I am getting worried that my PR could drift from dev but don't want to keep resolving conflicts until I know it's in queue

@fengtality
Copy link
Copy Markdown
Contributor

fengtality commented Mar 26, 2026

hey thanks for using the BSC Pancakeswap connector and applying these fixes. To get these reviewed and potentially merged, I recommend splitting this PR into separate ones for:

  • Pancakeswap fixes and routes changes: overall, I think these are fine and easy to review/merge
  • BSC as a new chain: I think this is better handled by BSC as a network supported by the Ethereum chain connector which is responsible for executing transactions on EVM networks. I plan on improving various aspects of the Ethereum connector, such as RPC integrations, transaction parsing, and integration with Hummingbot's AI tooling. If Metamask and Rabby treat BSC as an EVM network, then I think Hummingbot should as well.
  • Masterchef staking system: I support adding custom functionalities like this to Gateway, as long as it's well-structured. Here, I recommend introducing a new trading_type called nft_staking along with routes for it like /pancakeswap/nft-staking/route, rather than having it in the /clmm-routes folder.

@fengtality
Copy link
Copy Markdown
Contributor

Also, please base your PRs on the development branch and and check the Allow Edits by Maintainers box so we can help you manage it.

@VeXHarbinger
Copy link
Copy Markdown
Author

VeXHarbinger commented Mar 26, 2026

image

@fengtality It is, can you not? The problem was all the existing code was commented out in main but didn't exist at the time in dev. We had discussed it at the time. Which was why I made the mistake and forked main in the other repo PR but reverted that back to dev once I notced.

@fengtality fengtality changed the base branch from main to development March 31, 2026 17:32
@fengtality
Copy link
Copy Markdown
Contributor

@VeXHarbinger OK I figured out how to use Github and changed the base branch to development. Did you have a chance to address my comments earlier? IMO most important is treating BSC as an ETH network rather than separate chain

@VeXHarbinger
Copy link
Copy Markdown
Author

@VeXHarbinger OK I figured out how to use Github and changed the base branch to development. Did you have a chance to address my comments earlier? IMO most important is treating BSC as an ETH network rather than separate chain

resolved it on Feb 21st, I believe

@VeXHarbinger
Copy link
Copy Markdown
Author

VeXHarbinger commented Apr 1, 2026

@fengtality I remember fixing the branching for 2 of the 3 repos when you said it, this was the one with code in main that wasn't in dev, I asked you about it before I began to code. which was back in Jan . Sorry it became a problem for you. Was not my intent

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants