Title: Why is the bot encountering an “Insufficient Balance” error when attempting to execute the arbitrage trade?

Summary:
The provided output shows an attempt to perform an arbitrage trade on the Binance Smart Chain (BSC) using a bot. The bot checks the prices of three token pairs: ETH/USDC, ETH/BUSD, and BUSD/USDC. It retrieves the token balances for the specified wallet address (0xf1BA27c6D14e137C9e1097B6a31F763DB45760de) and calculates the potential trade amounts based on the available USDC balance.

However, the bot encounters an issue when executing the arbitrage trade. It checks the balance of ETH (token address: 0x2170Ed0880ac9A755fd29B2688956BD959F933F8) for the wallet and finds that the balance is 0. This leads to an insufficient balance error because the available ETH balance (0) is less than the required amount (2384.130455617401 USDC) for the arbitrage trade.

As a result, the bot logs an error message, skips the arbitrage opportunity due to the insufficient balance, and reports that no profitable arbitrage opportunity was found.

The main problem here is the lack of sufficient ETH balance in the specified wallet to execute the arbitrage trade. To resolve this issue, the wallet should have enough ETH balance to cover the required amount for the trade execution. Additionally, the bot’s logic may need to be adjusted to handle cases where the available balances are insufficient for the intended trades.

“”
(base) mima0000@MacBook-Pro son % python web.py
2024-05-22 16:52:19,757 – INFO – Connected to BSC
2024-05-22 16:52:19,927 – INFO – Current block number: 38940500
2024-05-22 16:52:19,980 – INFO – Starting arbitrage check…
2024-05-22 16:52:23,211 – INFO – Pair 0x539e0EBfffd39e54A0f7E5F8FEc40ade7933A664 – Token0: 0x2170Ed0880ac9A755fd29B2688956BD959F933F8 (Decimals: 18), Token1: 0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d (Decimals: 18)
2024-05-22 16:52:23,212 – INFO – Raw price: 3769.2186500961557
2024-05-22 16:52:23,212 – INFO – Adjusted price: 3769.2186500961557
2024-05-22 16:52:25,187 – INFO – Pair 0x7213a321F1855CF1779f42c0CD85d3D95291D34C – Token0: 0x2170Ed0880ac9A755fd29B2688956BD959F933F8 (Decimals: 18), Token1: 0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56 (Decimals: 18)
2024-05-22 16:52:25,187 – INFO – Reserves: [2270217901281602855, 8547266914545769731589, 1716367256]
2024-05-22 16:52:25,187 – INFO – Raw price: 3764.9544168075645
2024-05-22 16:52:25,187 – INFO – Adjusted price: 3764.9544168075645
2024-05-22 16:52:26,639 – INFO – Pair 0x22536030B9cE783B6Ddfb9a39ac7F439f568E5e6 – Token0: 0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d (Decimals: 18), Token1: 0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56 (Decimals: 18)
2024-05-22 16:52:26,639 – INFO – Raw price: 0.9994434430298962
2024-05-22 16:52:26,639 – INFO – Adjusted price: 0.9994434430298962
2024-05-22 16:52:26,639 – INFO – ETH/USDC price: 3769.2186500961557
2024-05-22 16:52:26,639 – INFO – ETH/BUSD price: 3764.9544168075645
2024-05-22 16:52:26,639 – INFO – BUSD/USDC price: 0.9994434430298962
2024-05-22 16:52:27,334 – INFO – Token balance for 0x2170Ed0880ac9A755fd29B2688956BD959F933F8: 0 (Decimals: 18)
2024-05-22 16:52:28,032 – INFO – Token balance for 0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d: 2384130455617400710619 (Decimals: 18)
2024-05-22 16:52:28,769 – INFO – Token balance for 0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56: 0 (Decimals: 18)
2024-05-22 16:52:28,770 – INFO – ETH balance for 0xf1BA27c6D14e137C9e1097B6a31F763DB45760de: 0
2024-05-22 16:52:28,770 – INFO – USDC balance for 0xf1BA27c6D14e137C9e1097B6a31F763DB45760de: 2384.130455617400710619
2024-05-22 16:52:28,770 – INFO – BUSD balance for 0xf1BA27c6D14e137C9e1097B6a31F763DB45760de: 0
2024-05-22 16:52:30,216 – INFO – Token balance for 0x2170Ed0880ac9A755fd29B2688956BD959F933F8: 0 (Decimals: 18)
2024-05-22 16:52:30,925 – INFO – Token balance for 0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d: 2384130455617400710619 (Decimals: 18)
2024-05-22 16:52:32,122 – INFO – Token balance for 0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56: 0 (Decimals: 18)
2024-05-22 16:52:33,206 – INFO – ETH balance for 0xf1BA27c6D14e137C9e1097B6a31F763DB45760de: 0.0 ETH (raw: 0)
2024-05-22 16:52:33,206 – INFO – USDC balance for 0xf1BA27c6D14e137C9e1097B6a31F763DB45760de: 2384.130455617401 USDC (raw: 2384130455617400710619)
2024-05-22 16:52:33,206 – INFO – BUSD balance for 0xf1BA27c6D14e137C9e1097B6a31F763DB45760de: 0.0 BUSD (raw: 0)
2024-05-22 16:52:33,206 – INFO – Using USDC balance for arbitrage with initial amount: 2384.130455617401 USDC
2024-05-22 16:52:33,739 – INFO – Prices: 3764.9544168075645, 3769.2186500961557, 0.9994434430298962
2024-05-22 16:52:33,739 – INFO – Trade amounts: 8.976142489122164e+24, 3.3833043675919793e+28, 3.3814213659642135e+28
2024-05-22 16:52:34,829 – INFO – Balance of token 0x2170Ed0880ac9A755fd29B2688956BD959F933F8 for wallet: 0.0 (raw: 0)
2024-05-22 16:52:34,829 – ERROR – Insufficient balance: 0.0 < 2384.130455617401
2024-05-22 16:52:34,829 – INFO – Gas cost estimation failed. Skipping this opportunity.
2024-05-22 16:52:34,829 – INFO – No profitable arbitrage opportunity found.
“”

from web3 import Web3
import json
import time
import logging

# Setup logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger()

# Connect to BSC
bsc = 'https://bsc-dataseed.binance.org/'
web3 = Web3(Web3.HTTPProvider(bsc))

# Check connection
if web3.is_connected():
    logger.info("Connected to BSC")
else:
    logger.error("Failed to connect to BSC")
    exit()

# Check block number to ensure the node is synced
logger.info(f"Current block number: {web3.eth.block_number}")

# PancakeSwap Router and Factory contract addresses
router_address_v2 = web3.to_checksum_address('0x10ED43C718714eb63d5aA57B78B54704E256024E')
router_address_v3 = web3.to_checksum_address('0xEf1c6E67703c7BD7107eed8303Fbe6EC2554BF6B')

# Load ABIs from JSON files
def load_abi(file_path):
    with open(file_path, 'r') as file:
        return json.load(file)

router_abi_v2 = load_abi('router_abi_v2.json')
router_abi_v3 = load_abi('router_abi_v3.json')
v2_pair_abi = load_abi('pair_v2_abi.json')
v3_pair_abi = load_abi('pair_v3_abi.json')
erc20_abi = load_abi('erc20_abi.json')

# Initialize contracts
router_contract_v2 = web3.eth.contract(address=router_address_v2, abi=router_abi_v2)
router_contract_v3 = web3.eth.contract(address=router_address_v3, abi=router_abi_v3)

# Token addresses
eth_address = web3.to_checksum_address('0x2170Ed0880ac9A755fd29B2688956BD959F933F8')
usdc_address = web3.to_checksum_address('0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d')
busd_address = web3.to_checksum_address('0xe9e7cea3dedca5984780bafc599bd69add087d56')

# Pair addresses
eth_usdc_pair = web3.to_checksum_address('0x539e0ebfffd39e54a0f7e5f8fec40ade7933a664')
eth_busd_pair = web3.to_checksum_address('0x7213a321F1855CF1779f42c0CD85d3D95291D34C')
busd_usdc_pair = web3.to_checksum_address('0x22536030b9ce783b6ddfb9a39ac7f439f568e5e6')

def get_token_balance(token_address, wallet_address):
    token_contract = web3.eth.contract(address=token_address, abi=erc20_abi)
    balance = token_contract.functions.balanceOf(wallet_address).call()
    decimals = token_contract.functions.decimals().call()
    logger.info(f"Token balance for {token_address}: {balance} (Decimals: {decimals})")
    return balance

def get_token_decimals(token_address):
    token_contract = web3.eth.contract(address=token_address, abi=erc20_abi)
    decimals = token_contract.functions.decimals().call()
    return decimals

# Function to get token addresses for a pair
def get_pair_tokens(pair_address, abi):
    pair_contract = web3.eth.contract(address=pair_address, abi=abi)
    token0 = pair_contract.functions.token0().call()
    token1 = pair_contract.functions.token1().call()
    return token0, token1

# Function to get price from V2 pair contract
def get_price_v2(pair_address, token0_decimals, token1_decimals):
    try:
        pair_contract = web3.eth.contract(address=pair_address, abi=v2_pair_abi)
        reserves = pair_contract.functions.getReserves().call()
        reserve0, reserve1 = reserves[0], reserves[1]
        price = reserve1 / reserve0
        price_adjusted = price * (10 ** (token0_decimals - token1_decimals))
        token0, token1 = get_pair_tokens(pair_address, v2_pair_abi)
        logger.info(f"Pair {pair_address} - Token0: {token0} (Decimals: {token0_decimals}), Token1: {token1} (Decimals: {token1_decimals})")
        logger.info(f"Reserves: {reserves}")
        logger.info(f"Raw price: {price}")
        logger.info(f"Adjusted price: {price_adjusted}")
        return price_adjusted
    except Exception as e:
        logger.error(f"Error fetching price for pair {pair_address}: {e}")
        return None

# Function to get price from V3 pair contract
def get_price_v3(pair_address, token0_decimals, token1_decimals, invert=False):
    try:
        pair_contract = web3.eth.contract(address=pair_address, abi=v3_pair_abi)
        slot0 = pair_contract.functions.slot0().call()
        sqrt_price_x96 = slot0[0]
        if invert:
            price = (2 ** 192) / (sqrt_price_x96 ** 2)
        else:
            price = (sqrt_price_x96 ** 2) / (2 ** 192)
        price_adjusted = price * (10 ** (token0_decimals - token1_decimals))
        token0, token1 = get_pair_tokens(pair_address, v3_pair_abi)
        logger.info(f"Pair {pair_address} - Token0: {token0} (Decimals: {token0_decimals}), Token1: {token1} (Decimals: {token1_decimals})")
        logger.info(f"Raw price: {price}")
        logger.info(f"Adjusted price: {price_adjusted}")
        return price_adjusted
    except Exception as e:
        logger.error(f"Error fetching price for pair {pair_address}: {e}")
        return None

# Update router address dynamically in the arbitrage function
router_address = None

def estimate_gas_cost(wallet_address, token1, token2, amount_in, private_key, router_address):
    try:
        token_contract = web3.eth.contract(address=token1, abi=erc20_abi)
        balance = token_contract.functions.balanceOf(wallet_address).call()
        decimals = token_contract.functions.decimals().call()
        balance_adjusted = balance / (10 ** decimals)

        logger.info(f"Balance of token {token1} for wallet: {balance_adjusted} (raw: {balance})")

        amount_in_adjusted = amount_in / (10 ** decimals)
        if balance < amount_in:
            logger.error(f"Insufficient balance: {balance_adjusted} < {amount_in_adjusted}")
            return None

        allowance = token_contract.functions.allowance(wallet_address, router_address).call()
        logger.info(f"Allowance of token {token1} for router: {allowance}")

        approve_gas = 0
        if allowance < amount_in:
            nonce = web3.eth.get_transaction_count(wallet_address)
            reset_approve_tx = token_contract.functions.approve(router_address, 0).build_transaction({
                'from': wallet_address,
                'gasPrice': web3.eth.gas_price,
                'nonce': nonce,
            })
            signed_reset_approve_tx = web3.eth.account.sign_transaction(reset_approve_tx, private_key=private_key)
            web3.eth.send_raw_transaction(signed_reset_approve_tx.rawTransaction)
            web3.eth.wait_for_transaction_receipt(signed_reset_approve_tx.hash)

            approve_tx = token_contract.functions.approve(router_address, amount_in).build_transaction({
                'from': wallet_address,
                'gasPrice': web3.eth.gas_price,
                'nonce': nonce + 1,
            })
            signed_approve_tx = web3.eth.account.sign_transaction(approve_tx, private_key=private_key)
            web3.eth.send_raw_transaction(signed_approve_tx.rawTransaction)
            web3.eth.wait_for_transaction_receipt(signed_approve_tx.hash)
            logger.info("Updated token allowance for router")
            approve_gas = web3.eth.estimate_gas(approve_tx)
            logger.info(f"Estimated gas for approval: {approve_gas}")

        swap_tx = router_contract_v2.functions.swapExactTokensForTokens(
            amount_in, 0, [token1, token2], wallet_address, int(time.time()) + 60 * 10  # adding deadline
        ).build_transaction({
            'from': wallet_address,
            'gasPrice': web3.eth.gas_price,
            'nonce': web3.eth.get_transaction_count(wallet_address) + 2,
        })
        swap_gas = web3.eth.estimate_gas(swap_tx)
        logger.info(f"Estimated gas for swap: {swap_gas}")

        total_gas = approve_gas + swap_gas if allowance < amount_in else swap_gas
        gas_cost = total_gas * web3.eth.gas_price
        logger.info(f"Total estimated gas cost: {web3.from_wei(gas_cost, 'ether')} BNB")
        return gas_cost
    except Exception as e:
        logger.error(f"Error estimating gas cost: {e}")
        return None

# Function to monitor and log real-time prices
def monitor_prices():
    eth_decimals = get_token_decimals(eth_address)
    usdc_decimals = get_token_decimals(usdc_address)
    busd_decimals = get_token_decimals(busd_address)

    eth_usdc_price = get_price_v3(eth_usdc_pair, eth_decimals, usdc_decimals)
    eth_busd_price = get_price_v2(eth_busd_pair, eth_decimals, busd_decimals)
    busd_usdc_price = get_price_v3(busd_usdc_pair, busd_decimals, usdc_decimals)

    logger.info(f"ETH/USDC price: {eth_usdc_price}")
    logger.info(f"ETH/BUSD price: {eth_busd_price}")
    logger.info(f"BUSD/USDC price: {busd_usdc_price}")

    return eth_usdc_price, eth_busd_price, busd_usdc_price

def log_all_token_balances(wallet_address):
    eth_balance = get_token_balance(eth_address, wallet_address)
    usdc_balance = get_token_balance(usdc_address, wallet_address)
    busd_balance = get_token_balance(busd_address, wallet_address)

    logger.info(f"ETH balance for {wallet_address}: {web3.from_wei(eth_balance, 'ether')}")
    logger.info(f"USDC balance for {wallet_address}: {web3.from_wei(usdc_balance, 'ether')}")
    logger.info(f"BUSD balance for {wallet_address}: {web3.from_wei(busd_balance, 'ether')}")

# Function to calculate potential profit
def calculate_profit(price1, price2, price3, wallet_address, private_key, initial_amount, router_address):
    logger.info(f"Prices: {price1}, {price2}, {price3}")
    amount1 = initial_amount * price1
    amount2 = amount1 * price2
    amount3 = amount2 * price3
    logger.info(f"Trade amounts: {amount1}, {amount2}, {amount3}")
    potential_profit = amount3 - initial_amount

    gas_cost = estimate_gas_cost(wallet_address, eth_address, usdc_address, initial_amount, private_key, router_address)
    if gas_cost is None:
        logger.info("Gas cost estimation failed. Skipping this opportunity.")
        return None

    net_profit = potential_profit - gas_cost
    logger.info(f"Net profit: {net_profit}")

    slippage_tolerance = 0.01
    minimum_receive = net_profit * (1 - slippage_tolerance)
    logger.info(f"Minimum receive after slippage: {minimum_receive}")

    return minimum_receive

def execute_trade(token1_address, token2_address, token3_address, wallet_address, private_key, initial_amount):
    global router_address
    token1_contract = web3.eth.contract(address=token1_address, abi=erc20_abi)
    token2_contract = web3.eth.contract(address=token2_address, abi=erc20_abi)
    token3_contract = web3.eth.contract(address=token3_address, abi=erc20_abi)

    # Check balances of all tokens
    token1_balance = get_token_balance(token1_address, wallet_address)
    token2_balance = get_token_balance(token2_address, wallet_address)
    token3_balance = get_token_balance(token3_address, wallet_address)

    logger.info(f"Token1 balance: {token1_balance}")
    logger.info(f"Token2 balance: {token2_balance}")
    logger.info(f"Token3 balance: {token3_balance}")

    eth_balance = web3.eth.get_balance(wallet_address)
    if eth_balance < web3.toWei(0.01, 'ether'):  # Check if ETH balance is less than 0.01 ETH
        if token1_balance >= initial_amount:
            # Swap Token1 (USDC) to ETH
            swap_tx = router_contract_v2.functions.swapExactTokensForETH(
                initial_amount, 0, [token1_address, web3.toChecksumAddress('0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c')], wallet_address, int(time.time()) + 120
            ).build_transaction({
                'from': wallet_address,
                'gasPrice': web3.eth.gas_price,
                'nonce': web3.eth.get_transaction_count(wallet_address),
            })
            signed_swap_tx = web3.eth.account.sign_transaction(swap_tx, private_key=private_key)
            swap_tx_hash = web3.eth.send_raw_transaction(signed_swap_tx.rawTransaction)
            web3.eth.wait_for_transaction_receipt(swap_tx_hash)
            logger.info("Swapped Token1 (USDC) to ETH")
        elif token2_balance >= initial_amount:
            # Swap Token2 (BUSD) to ETH
            swap_tx = router_contract_v2.functions.swapExactTokensForETH(
                initial_amount, 0, [token2_address, web3.toChecksumAddress('0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c')], wallet_address, int(time.time()) + 120
            ).build_transaction({
                'from': wallet_address,
                'gasPrice': web3.eth.gas_price,
                'nonce': web3.eth.get_transaction_count(wallet_address),
            })
            signed_swap_tx = web3.eth.account.sign_transaction(swap_tx, private_key=private_key)
            swap_tx_hash = web3.eth.send_raw_transaction(signed_swap_tx.rawTransaction)
            web3.eth.wait_for_transaction_receipt(swap_tx_hash)
            logger.info("Swapped Token2 (BUSD) to ETH")
        else:
            logger.error("Insufficient balance in Token1 (USDC) or Token2 (BUSD) to swap to ETH")
            return 0

    # Approve router to spend token1
    approve_tx = token1_contract.functions.approve(router_address, initial_amount).build_transaction({
        'from': wallet_address,
        'gasPrice': web3.eth.gas_price,
        'nonce': web3.eth.get_transaction_count(wallet_address),
    })
    signed_approve_tx = web3.eth.account.sign_transaction(approve_tx, private_key=private_key)
    approve_tx_hash = web3.eth.send_raw_transaction(signed_approve_tx.rawTransaction)
    web3.eth.wait_for_transaction_receipt(approve_tx_hash)
    logger.info("Approved router to spend Token1")

    # Execute first trade: Token1 -> Token2
    trade1_tx = router_contract_v2.functions.swapExactTokensForTokens(
        initial_amount, 0, [token1_address, token2_address], wallet_address, int(time.time()) + 120
    ).build_transaction({
        'from': wallet_address,
        'gasPrice': web3.eth.gas_price,
        'nonce': web3.eth.get_transaction_count(wallet_address),
    })
    signed_trade1_tx = web3.eth.account.sign_transaction(trade1_tx, private_key=private_key)
    trade1_tx_hash = web3.eth.send_raw_transaction(signed_trade1_tx.rawTransaction)
    trade1_receipt = web3.eth.wait_for_transaction_receipt(trade1_tx_hash)
    logger.info("Executed first trade: Token1 -> Token2")

    # Get the balance of Token2 received
    token2_amount = get_token_balance(token2_address, wallet_address)
    logger.info(f"Token2 amount received: {token2_amount}")

    if token2_amount == 0:
        logger.error("Received 0 Token2. Aborting arbitrage.")
        return 0

    # Approve router to spend Token2
    approve_tx2 = token2_contract.functions.approve(router_address, token2_amount).build_transaction({
        'from': wallet_address,
        'gasPrice': web3.eth.gas_price,
        'nonce': web3.eth.get_transaction_count(wallet_address),
    })
    signed_approve_tx2 = web3.eth.account.sign_transaction(approve_tx2, private_key=private_key)
    approve_tx2_hash = web3.eth.send_raw_transaction(signed_approve_tx2.rawTransaction)
    web3.eth.wait_for_transaction_receipt(approve_tx2_hash)
    logger.info("Approved router to spend Token2")

    # Execute second trade: Token2 -> Token3
    trade2_tx = router_contract_v2.functions.swapExactTokensForTokens(
        token2_amount, 0, [token2_address, token3_address], wallet_address, int(time.time()) + 120
    ).build_transaction({
        'from': wallet_address,
        'gasPrice': web3.eth.gas_price,
        'nonce': web3.eth.get_transaction_count(wallet_address),
    })
    signed_trade2_tx = web3.eth.account.sign_transaction(trade2_tx, private_key=private_key)
    trade2_tx_hash = web3.eth.send_raw_transaction(signed_trade2_tx.rawTransaction)
    trade2_receipt = web3.eth.wait_for_transaction_receipt(trade2_tx_hash)
    logger.info("Executed second trade: Token2 -> Token3")

    # Get the balance of Token3 received
    token3_amount = get_token_balance(token3_address, wallet_address)
    logger.info(f"Token3 amount received: {token3_amount}")

    if token3_amount == 0:
        logger.error("Received 0 Token3. Aborting arbitrage.")
        return 0

    # Approve router to spend Token3
    approve_tx3 = token3_contract.functions.approve(router_address, token3_amount).build_transaction({
        'from': wallet_address,
        'gasPrice': web3.eth.gas_price,
        'nonce': web3.eth.get_transaction_count(wallet_address),
    })
    signed_approve_tx3 = web3.eth.account.sign_transaction(approve_tx3, private_key=private_key)
    approve_tx3_hash = web3.eth.send_raw_transaction(signed_approve_tx3.rawTransaction)
    web3.eth.wait_for_transaction_receipt(approve_tx3_hash)
    logger.info("Approved router to spend Token3")

    # Execute third trade: Token3 -> Token1
    trade3_tx = router_contract_v2.functions.swapExactTokensForTokens(
        token3_amount, 0, [token3_address, token1_address], wallet_address, int(time.time()) + 120
    ).build_transaction({
        'from': wallet_address,
        'gasPrice': web3.eth.gas_price,
        'nonce': web3.eth.get_transaction_count(wallet_address),
    })
    signed_trade3_tx = web3.eth.account.sign_transaction(trade3_tx, private_key=private_key)
    trade3_tx_hash = web3.eth.send_raw_transaction(signed_trade3_tx.rawTransaction)
    trade3_receipt = web3.eth.wait_for_transaction_receipt(trade3_tx_hash)
    logger.info("Executed third trade: Token3 -> Token1")

    # Get the final balance of Token1
    final_amount = get_token_balance(token1_address, wallet_address)
    logger.info(f"Final Token1 amount: {final_amount}")

    # Calculate profit
    profit = final_amount - initial_amount
    logger.info(f"Profit: {profit}")

    # Check if the final balance is in ETH and swap back to USDC or BUSD
    final_eth_balance = web3.eth.get_balance(wallet_address)
    if final_eth_balance > web3.toWei(0.01, 'ether'):  # Check if final ETH balance is greater than 0.01 ETH
        # Swap ETH back to Token1 (USDC)
        swap_tx = router_contract_v2.functions.swapExactETHForTokens(
            0, [web3.toChecksumAddress('0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c'), token1_address], wallet_address, int(time.time()) + 120
        ).build_transaction({
            'from': wallet_address,
            'value': final_eth_balance,
            'gasPrice': web3.eth.gas_price,
            'nonce': web3.eth.get_transaction_count(wallet_address),
        })
        signed_swap_tx = web3.eth.account.sign_transaction(swap_tx, private_key=private_key)
        swap_tx_hash = web3.eth.send_raw_transaction(signed_swap_tx.rawTransaction)
        web3.eth.wait_for_transaction_receipt(swap_tx_hash)
        logger.info("Swapped ETH back to Token1 (USDC)")

    return profit

def arbitrage(wallet_address, private_key, eth_usdc_pair, eth_busd_pair, busd_usdc_pair):
    global router_address
    eth_usdc_price, eth_busd_price, busd_usdc_price = monitor_prices()

    if not eth_usdc_price or not eth_busd_price or not busd_usdc_price:
        logger.error("One of the prices could not be fetched. Skipping this round.")
        return

    # Log all token balances before arbitrage
    log_all_token_balances(wallet_address)

    # Check balances for all tokens
    eth_balance_raw = get_token_balance(eth_address, wallet_address)
    usdc_balance_raw = get_token_balance(usdc_address, wallet_address)
    busd_balance_raw = get_token_balance(busd_address, wallet_address)

    # Convert raw balances based on token decimals
    eth_decimals = get_token_decimals(eth_address)
    usdc_decimals = get_token_decimals(usdc_address)
    busd_decimals = get_token_decimals(busd_address)

    eth_balance = eth_balance_raw / (10 ** eth_decimals)
    usdc_balance = usdc_balance_raw / (10 ** usdc_decimals)
    busd_balance = busd_balance_raw / (10 ** busd_decimals)

    logger.info(f"ETH balance for {wallet_address}: {eth_balance} ETH (raw: {eth_balance_raw})")
    logger.info(f"USDC balance for {wallet_address}: {usdc_balance} USDC (raw: {usdc_balance_raw})")
    logger.info(f"BUSD balance for {wallet_address}: {busd_balance} BUSD (raw: {busd_balance_raw})")

    # Determine which token to use for arbitrage based on available balance
    initial_amount_raw = 0
    initial_amount = 0
    trade_sequence = None

    if busd_balance > 0:
        initial_amount_raw = busd_balance_raw
        initial_amount = busd_balance
        logger.info(f"Using BUSD balance for arbitrage with initial amount: {initial_amount} BUSD")
        trade_sequence = ('BUSD', busd_address, eth_address, usdc_address)
    elif eth_balance > 0:
        initial_amount_raw = eth_balance_raw
        initial_amount = eth_balance
        logger.info(f"Using ETH balance for arbitrage with initial amount: {initial_amount} ETH")
        trade_sequence = ('ETH', eth_address, usdc_address, busd_address)
    elif usdc_balance > 0:
        initial_amount_raw = usdc_balance_raw
        initial_amount = usdc_balance
        logger.info(f"Using USDC balance for arbitrage with initial amount: {initial_amount} USDC")
        trade_sequence = ('USDC', usdc_address, eth_address, busd_address)
    else:
        logger.error("Insufficient balance for any token")
        return

    token_used = trade_sequence[1]
    token_out_1 = trade_sequence[2]
    token_out_2 = trade_sequence[3]

    # Refresh allowance if necessary
    router_address = router_address_v2  # Use V2 router
    token_contract = web3.eth.contract(address=token_used, abi=erc20_abi)
    allowance = token_contract.functions.allowance(wallet_address, router_address).call()
    nonce = web3.eth.get_transaction_count(wallet_address)

    if allowance < initial_amount_raw:
        reset_approve_tx = token_contract.functions.approve(router_address, 0).build_transaction({
            'from': wallet_address,
            'gasPrice': web3.eth.gas_price,
            'nonce': nonce,
        })
        signed_reset_approve_tx = web3.eth.account.sign_transaction(reset_approve_tx, private_key=private_key)
        web3.eth.send_raw_transaction(signed_reset_approve_tx.rawTransaction)
        web3.eth.wait_for_transaction_receipt(signed_reset_approve_tx.hash)
        logger.info("Reset token allowance to 0")

        nonce += 1
        approve_tx = token_contract.functions.approve(router_address, initial_amount_raw).build_transaction({
            'from': wallet_address,
            'gasPrice': web3.eth.gas_price,
            'nonce': nonce,
        })
        signed_approve_tx = web3.eth.account.sign_transaction(approve_tx, private_key=private_key)
        web3.eth.send_raw_transaction(signed_approve_tx.rawTransaction)
        web3.eth.wait_for_transaction_receipt(signed_approve_tx.hash)
        logger.info("Updated token allowance for router")

    # Compare prices for potential arbitrage opportunities
    if eth_usdc_price < eth_busd_price:
        profit = calculate_profit(eth_usdc_price, eth_busd_price, busd_usdc_price, wallet_address, private_key, initial_amount_raw, router_address)
        if profit and profit > 0:
            logger.info("Profitable arbitrage opportunity found: ETH/USDC -> ETH/BUSD -> BUSD/USDC")
            execute_trade(eth_address, usdc_address, busd_address, wallet_address, private_key, initial_amount_raw)
        else:
            logger.info("No profitable arbitrage opportunity found.")
    elif eth_busd_price < eth_usdc_price:
        profit = calculate_profit(eth_busd_price, eth_usdc_price, busd_usdc_price, wallet_address, private_key, initial_amount_raw, router_address)
        if profit and profit > 0:
            logger.info("Profitable arbitrage opportunity found: ETH/BUSD -> ETH/USDC -> BUSD/USDC")
            execute_trade(eth_address, busd_address, usdc_address, wallet_address, private_key, initial_amount_raw)
        else:
            logger.info("No profitable arbitrage opportunity found.")
    else:
        logger.info("No profitable arbitrage opportunity found.")

    # Log all token balances after arbitrage
    log_all_token_balances(wallet_address)


# Main loop
def main():
    wallet_address = '0xf1BA27c6D14e137C9e1097B6a31F763DB45760de'

    private_key = 'XXXXXXXXXXXXXXXXXXXXXXXXX'

    while True:
        try:
            logger.info("Starting arbitrage check...")
            arbitrage(wallet_address, private_key, eth_usdc_pair, eth_busd_pair, busd_usdc_pair)
        except Exception as e:
            logger.error(f"Error: {e}")
        time.sleep(1)

if __name__ == "__main__":
    main()

New contributor

user25183994 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật