From bc18265a2b95609e98e5007a2f3e5e913bbbb907 Mon Sep 17 00:00:00 2001 From: Anton Sauchyk Date: Tue, 17 Feb 2026 10:17:23 +0100 Subject: [PATCH 1/3] fix(core): disable account_data_size limit and add meta.err checking MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 12.5MB setLoadedAccountsDataSizeLimit was causing all buy transactions to fail with MaxLoadedAccountsDataSizeExceeded since pump.fun migrated to Token-2022. Transactions landed on-chain (fees paid) but inner instructions were rejected — the bot paid gas for nothing. Changes: - Disable account_data_size in all bot configs (Token-2022 needs >12.5MB) - Add meta.err check in get_buy_transaction_details() for clear error reporting when transactions fail on-chain - Include tx signature in platform_aware.py error messages for debugging Tested: full buy→sell→cleanup cycle works on pump_fun with geyser listener. Co-Authored-By: Claude Opus 4.6 --- bots/bot-sniper-1-geyser.yaml | 2 +- bots/bot-sniper-2-logs.yaml | 2 +- bots/bot-sniper-3-blocks.yaml | 2 +- bots/bot-sniper-4-pp.yaml | 2 +- src/core/client.py | 9 +++++++++ src/trading/platform_aware.py | 3 ++- 6 files changed, 15 insertions(+), 5 deletions(-) diff --git a/bots/bot-sniper-1-geyser.yaml b/bots/bot-sniper-1-geyser.yaml index 0772916..cceb543 100644 --- a/bots/bot-sniper-1-geyser.yaml +++ b/bots/bot-sniper-1-geyser.yaml @@ -63,7 +63,7 @@ compute_units: # Note: Savings don't show in "consumed CU" but improve tx priority/cost. # Note (Nov 23, 2025): with data size set to 512KB, transactions fail - increasing to 12.5MB resolves the issue. # Reference: https://www.anza.xyz/blog/cu-optimization-with-setloadedaccountsdatasizelimit - account_data_size: 12_500_000 + # account_data_size: 12_500_000 # Disabled: causes MaxLoadedAccountsDataSizeExceeded with Token-2022 # Filters for token selection filters: diff --git a/bots/bot-sniper-2-logs.yaml b/bots/bot-sniper-2-logs.yaml index 7f4c0b6..e7113cc 100644 --- a/bots/bot-sniper-2-logs.yaml +++ b/bots/bot-sniper-2-logs.yaml @@ -63,7 +63,7 @@ compute_units: # Note: Savings don't show in "consumed CU" but improve tx priority/cost. # Note (Nov 23, 2025): with data size set to 512KB, transactions fail - increasing to 12.5MB resolves the issue. # Reference: https://www.anza.xyz/blog/cu-optimization-with-setloadedaccountsdatasizelimit - account_data_size: 12_500_000 + # account_data_size: 12_500_000 # Disabled: causes MaxLoadedAccountsDataSizeExceeded with Token-2022 # Filters for token selection filters: diff --git a/bots/bot-sniper-3-blocks.yaml b/bots/bot-sniper-3-blocks.yaml index 96e4525..ba35a07 100644 --- a/bots/bot-sniper-3-blocks.yaml +++ b/bots/bot-sniper-3-blocks.yaml @@ -63,7 +63,7 @@ compute_units: # Note: Savings don't show in "consumed CU" but improve tx priority/cost. # Note (Nov 23, 2025): with data size set to 512KB, transactions fail - increasing to 12.5MB resolves the issue. # Reference: https://www.anza.xyz/blog/cu-optimization-with-setloadedaccountsdatasizelimit - account_data_size: 12_500_000 + # account_data_size: 12_500_000 # Disabled: causes MaxLoadedAccountsDataSizeExceeded with Token-2022 # Filters for token selection filters: diff --git a/bots/bot-sniper-4-pp.yaml b/bots/bot-sniper-4-pp.yaml index cc1f6d8..8c0498d 100644 --- a/bots/bot-sniper-4-pp.yaml +++ b/bots/bot-sniper-4-pp.yaml @@ -61,7 +61,7 @@ compute_units: # Note: Savings don't show in "consumed CU" but improve tx priority/cost. # Note (Nov 23, 2025): with data size set to 512KB, transactions fail - increasing to 12.5MB resolves the issue. # Reference: https://www.anza.xyz/blog/cu-optimization-with-setloadedaccountsdatasizelimit - account_data_size: 12_500_000 + # account_data_size: 12_500_000 # Disabled: causes MaxLoadedAccountsDataSizeExceeded with Token-2022 # Filters for token selection filters: diff --git a/src/core/client.py b/src/core/client.py index 526f735..e21f5d5 100644 --- a/src/core/client.py +++ b/src/core/client.py @@ -354,6 +354,15 @@ async def get_buy_transaction_details( return None, None meta = result.get("meta", {}) + + # Check for transaction execution errors (e.g., MaxLoadedAccountsDataSizeExceeded) + tx_err = meta.get("err") + if tx_err: + logger.error( + f"Transaction {signature[:16]}... failed with error: {tx_err}" + ) + return None, None + mint_str = str(mint) # Get tokens received from pre/post token balance diff diff --git a/src/trading/platform_aware.py b/src/trading/platform_aware.py index 8f616ad..58350c8 100644 --- a/src/trading/platform_aware.py +++ b/src/trading/platform_aware.py @@ -156,7 +156,8 @@ async def execute(self, token_info: TokenInfo) -> TradeResult: else: raise ValueError( f"Failed to parse transaction details: tokens={tokens_raw}, " - f"sol_spent={sol_spent}" + f"sol_spent={sol_spent} (tx: {tx_signature}). " + f"The transaction may have failed on-chain — check explorer." ) return TradeResult( From dda2b30ec865fb52aa780bb176ee763960612884 Mon Sep 17 00:00:00 2001 From: Anton Sauchyk Date: Tue, 17 Feb 2026 10:28:15 +0100 Subject: [PATCH 2/3] fix(core): check meta.err in confirm_transaction to detect failed txs Solana transactions can be "confirmed" (included in a block) but still fail execution if inner program instructions are rejected. Previously, confirm_transaction only checked that the tx landed on-chain, causing silent failures in buy, sell, and cleanup operations. Now fetches the transaction result after confirmation and checks meta.err, returning False when the transaction failed. This fixes the ATA cleanup issue where sells were silently failing with Custom: 6003 errors, leaving non-zero token balances. Co-Authored-By: Claude Opus 4.6 --- src/core/client.py | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/core/client.py b/src/core/client.py index e21f5d5..ad21923 100644 --- a/src/core/client.py +++ b/src/core/client.py @@ -280,14 +280,18 @@ async def build_and_send_transaction( async def confirm_transaction( self, signature: str, commitment: str = "confirmed" ) -> bool: - """Wait for transaction confirmation. + """Wait for transaction confirmation and verify execution success. + + Confirms the transaction landed on-chain, then checks meta.err to + ensure the inner program instructions actually succeeded. A transaction + can be "confirmed" (included in a block) but still fail execution. Args: signature: Transaction signature commitment: Confirmation commitment level Returns: - Whether transaction was confirmed + Whether transaction was confirmed AND executed successfully """ await self._rate_limiter.acquire() client = await self.get_client() @@ -295,11 +299,22 @@ async def confirm_transaction( await client.confirm_transaction( signature, commitment=commitment, sleep_seconds=1 ) - return True except Exception: logger.exception(f"Failed to confirm transaction {signature}") return False + # Verify the transaction actually succeeded (no program errors) + result = await self._get_transaction_result(str(signature)) + if result: + tx_err = result.get("meta", {}).get("err") + if tx_err: + logger.error( + f"Transaction {str(signature)[:16]}... confirmed but failed: {tx_err}" + ) + return False + + return True + async def get_transaction_token_balance( self, signature: str, user_pubkey: Pubkey, mint: Pubkey ) -> int | None: From 410f0ef95c50dbe1f605da26dfaeb62477c836e5 Mon Sep 17 00:00:00 2001 From: Anton Sauchyk Date: Tue, 17 Feb 2026 10:34:49 +0100 Subject: [PATCH 3/3] fix(core): treat failed tx fetch as unconfirmed in confirm_transaction MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When _get_transaction_result returns None (RPC failure, timeout, etc.), the function was falling through to return True — silently treating an unknown state as success. Now returns False with a warning log. Co-Authored-By: Claude Opus 4.6 --- src/core/client.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/core/client.py b/src/core/client.py index ad21923..ab8e9d4 100644 --- a/src/core/client.py +++ b/src/core/client.py @@ -305,13 +305,19 @@ async def confirm_transaction( # Verify the transaction actually succeeded (no program errors) result = await self._get_transaction_result(str(signature)) - if result: - tx_err = result.get("meta", {}).get("err") - if tx_err: - logger.error( - f"Transaction {str(signature)[:16]}... confirmed but failed: {tx_err}" - ) - return False + if not result: + logger.warning( + f"Could not fetch transaction {str(signature)[:16]}... " + f"to verify execution — treating as unconfirmed" + ) + return False + + tx_err = result.get("meta", {}).get("err") + if tx_err: + logger.error( + f"Transaction {str(signature)[:16]}... confirmed but failed: {tx_err}" + ) + return False return True