From 63749e586fade49b5c236ce479f6d89178d9a562 Mon Sep 17 00:00:00 2001 From: TsarBuig <70858574+tsarbuig@users.noreply.github.com> Date: Sun, 27 Feb 2022 23:18:10 +0100 Subject: [PATCH] Added new "private_node" option Removed Pinksale Simplified LP Pair usage V2 --- settings.json | 2 +- sniper.py | 982 +++++++++++++++++++++++--------------------------- tokens.json | 19 +- 3 files changed, 458 insertions(+), 545 deletions(-) diff --git a/settings.json b/settings.json index 0b37fbd..46231de 100755 --- a/settings.json +++ b/settings.json @@ -13,7 +13,7 @@ "WALLETADDRESS5": "null", "PRIVATEKEY5": "null", -"MEMPOOL_METHOD": "normal", // write 'normal' for a normal token, and 'pinksale' to snipe token launched on Pinksale +"MEMPOOL_METHOD": "private_node", // write 'public_node' if you're using a Public Node, and 'private_node' if you're using a private node... "USECUSTOMNODE": "false", "CUSTOMNODE": "false", // put your own node here if you want and set USECUSTOMNODE = true diff --git a/sniper.py b/sniper.py index 069a35d..c1ca11e 100644 --- a/sniper.py +++ b/sniper.py @@ -11,7 +11,6 @@ import web3 from web3.exceptions import ABIFunctionNotFound, TransactionNotFound, BadFunctionCallOutput import logging -import pause from datetime import datetime from functools import lru_cache from cachetools import cached, LRUCache, TTLCache @@ -395,8 +394,6 @@ def load_settings_file(settings_path, load_message=True): 'USECUSTOMNODE', 'PASSWORD_ON_CHANGE', 'SLOW_MODE', - 'START_BUY_AFTER_TIMESTAMP', - 'START_SELL_AFTER_TIMESTAMP', 'ENABLE_APPRISE_NOTIFICATIONS' ] @@ -589,7 +586,6 @@ def load_tokens_file(tokens_path, load_message=True): 'GASPRIORITY_FOR_ETH_ONLY': 1.5, 'STOPLOSSPRICEINBASE': 0, 'BUYCOUNT': 0, - 'PINKSALE_PRESALE_ADDRESS': "", '_STABLE_BASES': {} } @@ -832,7 +828,6 @@ def reload_tokens_file(tokens_path, load_message=True): 'GASPRIORITY_FOR_ETH_ONLY': 1.5, 'STOPLOSSPRICEINBASE': 0, 'BUYCOUNT': 0, - 'PINKSALE_PRESALE_ADDRESS': "", '_STABLE_BASES': {} } @@ -960,22 +955,22 @@ def reload_tokens_file(tokens_path, load_message=True): '_CONTRACT_DECIMALS': _TOKENS_saved[token['SYMBOL']]['_CONTRACT_DECIMALS'], '_BASE_DECIMALS': _TOKENS_saved[token['SYMBOL']]['_BASE_DECIMALS'], '_WETH_DECIMALS': _TOKENS_saved[token['SYMBOL']]['_WETH_DECIMALS'], + '_LIQUIDITY_DECIMALS': _TOKENS_saved[token['SYMBOL']]['_WETH_DECIMALS'], '_LAST_PRICE_MESSAGE': _TOKENS_saved[token['SYMBOL']]['_LAST_PRICE_MESSAGE'], '_LAST_MESSAGE': _TOKENS_saved[token['SYMBOL']]['_LAST_MESSAGE'], '_FIRST_SELL_QUOTE': _TOKENS_saved[token['SYMBOL']]['_FIRST_SELL_QUOTE'], '_BUILT_BY_BOT': _TOKENS_saved[token['SYMBOL']]['_BUILT_BY_BOT'], + '_EXCHANGE_BASE_SYMBOL': _TOKENS_saved[token['SYMBOL']]['_EXCHANGE_BASE_SYMBOL'], + '_PAIR_SYMBOL': _TOKENS_saved[token['SYMBOL']]['_PAIR_SYMBOL'], '_BUY_IS_MADE': _TOKENS_saved[token['SYMBOL']]['_BUY_IS_MADE'], '_IN_TOKEN': _TOKENS_saved[token['SYMBOL']]['_IN_TOKEN'], - '_OUT_TOKEN': _TOKENS_saved[token['SYMBOL']]['_OUT_TOKEN'], - '_EXCHANGE_BASE_SYMBOL': _TOKENS_saved[token['SYMBOL']]['_EXCHANGE_BASE_SYMBOL'], - '_PAIR_SYMBOL': _TOKENS_saved[token['SYMBOL']]['_PAIR_SYMBOL'] + '_OUT_TOKEN': _TOKENS_saved[token['SYMBOL']]['_OUT_TOKEN'] }) # Add any tokens generated by "WATCH_STABLES_PAIRS" to the tokens list. for token_dict in set_of_new_tokens: tokens.append(token_dict) - printt_debug("tokens after reload:", tokens) printt_debug("EXIT reload_tokens_file") return tokens @@ -1122,7 +1117,7 @@ def check_release(): # Check for version # -version = '1.1.3' +version = '2.0.0' printt("YOUR BOT IS CURRENTLY RUNNING VERSION ", version, write_to_log=True) check_release() @@ -1135,7 +1130,7 @@ def check_release(): my_provider = settings['CUSTOMNODE'] print(timestamp(), 'Using custom node.') else: - my_provider = "https://bsc-dataseed1.defibit.io" + my_provider = "https://bsc-dataseed4.defibit.io" if not my_provider: printt_err('Custom node empty. Exiting') @@ -1179,7 +1174,7 @@ def check_release(): my_provider = settings['CUSTOMNODE'] print(timestamp(), 'Using custom node.') else: - my_provider = "https://data-seed-prebsc-2-s2.binance.org:8545/" + my_provider = "https://data-seed-prebsc-2-s2.binance.org:8545" if not my_provider: print(timestamp(), 'Custom node empty. Exiting') @@ -2343,7 +2338,7 @@ def auth(): try: decode = decode_key() except Exception: - printt_err("There is a problem with your private key: please check if it's correct. Don't enter your seed phrase!") + printt_err("There is a problem with your private key: please check if it's correct. Don't enter your seed phrase !") wallet_address = Web3.toChecksumAddress(decode) balance = balanceContract.functions.balanceOf(wallet_address).call() @@ -2597,62 +2592,16 @@ def check_rugdoc_api(token): token['_QUOTE'] = 0 -def scan_mempool(token, methodid): - printt_debug("ENTER scan_mempool") +def scan_mempool_public_node(token): + printt_debug("ENTER scan_mempool_public_node", write_to_log=True) printt("") printt("--------------------------------------------------------") - printt("SCANNING MEMPOOL - normal way") + printt("SCANNING MEMPOOL -", token['SYMBOL'], "token") printt("") printt("Bot will scan mempool to detect AddLiquidity functions") printt("") - printt_warn("DO NOT CLOSE THE BOT - if nothing appears it's normal!") - printt("") - printt("--------------------------------------------------------") - - liquidity_detected = False - - # If we look for Pinksale sales, we look into the Presale Address's transactions for 0x4bb278f3 methodID - if settings['MEMPOOL_METHOD'] == 'pinksale': - tx_filter = client.eth.filter({"filter_params": "pending", "address": Web3.toChecksumAddress(token['PINKSALE_PRESALE_ADDRESS'])}) - else: - tx_filter = client.eth.filter({"filter_params": "pending", "address": token['ADDRESS']}) - - while liquidity_detected == False: - - try: - for tx_event in tx_filter.get_new_entries(): - - txHash = tx_event['transactionHash'] - txHashDetails = client.eth.get_transaction(txHash) - printt_debug(txHashDetails) - txFunction = txHashDetails.input[:10] - input_decoded = routerContract.decode_function_input(txHashDetails.input) - printt_err(input_decoded) - - if txFunction.lower() in methodid: - liquidity_detected = True - token['_GAS_IS_CALCULATED'] = True - token['_GAS_TO_USE'] = int(txHashDetails.gasPrice) / 1000000000 - printt_ok("LIQUIDITY ADDING FUNCTION DETECTED --> Trading is enabled --> Bot will buy", write_to_log=True) - printt_ok("MethodID: ", txFunction, " Block: ", tx_event['blockNumber'], " Found Signal", "in txHash:", txHash.hex(), write_to_log=True) - printt_ok("GAS will be the same as liquidity adding event. GAS=", token['_GAS_TO_USE']) - break - else: - printt("Found something in mempool - MethodID: ", txFunction, " Block: ", tx_event['blockNumber']) - except Exception as e: - printt_err("scan_mempool Error. It can happen with Public node : private node is recommended. Still, let's continue.") - continue - - -def scan_mempool_classic(token): - printt_debug("ENTER scan_mempool_classic") - - printt("") - printt("--------------------------------------------------------") - printt("SCANNING MEMPOOL") - printt("") - printt("Bot will scan mempool to detect AddLiquidity functions") + printt_warn("Do not make any transaction with this wallet before bot buys, because Nonce is pre-calculated") printt("") printt("--------------------------------------------------------") @@ -2691,6 +2640,8 @@ def scan_mempool_classic(token): try: if filter_contract['token'] == Web3.toChecksumAddress(token['ADDRESS']): printt_debug("token_check true 1") + token['LIQUIDITYINNATIVETOKEN'] = 'true' + token['USECUSTOMBASEPAIR'] = 'false' token_check = True else: printt_debug("token_check false 1") @@ -2698,8 +2649,19 @@ def scan_mempool_classic(token): # Some liquidity functions use tokenA and tokenB instead except Exception as e: - if filter_contract['tokenA'] == Web3.toChecksumAddress(token['ADDRESS']) or filter_contract['tokenB'] == Web3.toChecksumAddress(token['ADDRESS']): - printt_debug("token_check true 2") + if filter_contract['tokenA'] == Web3.toChecksumAddress(token['ADDRESS']): + token['LIQUIDITYINNATIVETOKEN'] = 'false' + token['USECUSTOMBASEPAIR'] = 'true' + token['_OUT_TOKEN'] = filter_contract['tokenB'] + token['BASEADDRESS'] = filter_contract['tokenB'] + token['BASESYMBOL'] = base_symbol + token_check = True + elif filter_contract['tokenB'] == Web3.toChecksumAddress(token['ADDRESS']): + token['LIQUIDITYINNATIVETOKEN'] = 'false' + token['USECUSTOMBASEPAIR'] = 'true' + token['_OUT_TOKEN'] = filter_contract['tokenA'] + token['BASEADDRESS'] = filter_contract['tokenA'] + token['BASESYMBOL'] = base_symbol token_check = True else: @@ -2734,6 +2696,7 @@ def scan_mempool_classic(token): if token['LIQUIDITYINNATIVETOKEN'] == 'true': printt_debug("pending['value']", pending['value']) liquidity_amount = pending['value'] / token['_LIQUIDITY_DECIMALS'] + elif token['LIQUIDITYINNATIVETOKEN'] == 'false' and token['USECUSTOMBASEPAIR'] == 'true': printt_debug("token['ADDRESS'].lower()", token['BASEADDRESS'].lower()) printt_debug("decoded['tokenA']", filter_contract['tokenA'].lower()) @@ -2778,128 +2741,141 @@ def scan_mempool_classic(token): def scan_mempool_private_node(token, methodid): - printt_debug("ENTER scan_mempool_private_node") + printt_debug("ENTER scan_mempool_private_node", write_to_log=True) printt("") printt("--------------------------------------------------------") - printt("SCANNING MEMPOOL - for Private node") + printt("SCANNING MEMPOOL -", token['SYMBOL'], "token") printt("") printt("Bot will scan mempool to detect AddLiquidity functions") printt("") + printt_err("This function has to be used on a private node with proper setup, otherwise AddLiquidity Tx won't be detected!") + printt("") + printt_warn("Do not make any transaction with this wallet before bot buys, because Nonce is pre-calculated") + printt("") + printt_warn("Don't worry if nothing appears : it's normal! Do not close the bot") + printt("") printt("--------------------------------------------------------") - - printt_debug("methodid:", methodid) - openTrade = False + + buyToken = False tokenAddress = Web3.toChecksumAddress(token['ADDRESS']) - while openTrade == False: + while buyToken == False: try: tx_pool = client.geth.txpool.content()['pending'].items() + for k,v in tx_pool: for k1, v1 in v.items(): - input_decoded = routerContract.decode_function_input(v1['input']) - printt(input_decoded) - if input_decoded[1]['token'] == tokenAddress and v1['input'][:10] in methodid: - printt_ok("") - printt_ok("--------------------------------------------------------") - printt_ok("WE FOUND SOMETHING IN MEMPOOL") - printt_ok("") - printt_ok("Bot detected a AddLiquidity Event:") - printt("Block number:", client.eth.block_number) - printt("- MethodID:", v1['input'][:10]) - printt("- to:", v1['to']) - printt("- from:", v1['from']) - printt("- TxHash:", v1['hash']) - printt_debug(v1) - printt_ok("") - printt_ok("--------------------------------------------------------") + # If we detect the MethodID we've listed in 'input' + if v1['input'][:10] in methodid: + input_decoded = routerContract.decode_function_input(v1['input']) + + # If liquidity is in native token (BNB/ETH...), it uses 'token' key + try: + if input_decoded[1]['token'].lower() == tokenAddress.lower(): + # it's the token you've put in your tokens.json --> token detected, let's snipe ! + token['LIQUIDITYINNATIVETOKEN'] = 'true' + token['USECUSTOMBASEPAIR'] = 'false' + tokenDetected = True + else: + tokenDetected = False + + # If liquidity is in another token, it uses tokenA and tokenB instead + # --> so we set it as IN_TOKEN, to buy through BNB > inToken > token route + except Exception as e: + if input_decoded[1]['tokenA'].lower() == tokenAddress.lower(): + token['LIQUIDITYINNATIVETOKEN'] = 'false' + token['USECUSTOMBASEPAIR'] = 'true' + token['_OUT_TOKEN'] = Web3.toChecksumAddress(input_decoded[1]['tokenB']) + token['BASEADDRESS'] = Web3.toChecksumAddress(input_decoded[1]['tokenB']) + token['BASESYMBOL'] = base_symbol + tokenDetected = True + elif input_decoded[1]['tokenB'].lower() == tokenAddress.lower(): + token['LIQUIDITYINNATIVETOKEN'] = 'false' + token['USECUSTOMBASEPAIR'] = 'true' + token['_OUT_TOKEN'] = Web3.toChecksumAddress(input_decoded[1]['tokenA']) + token['BASEADDRESS'] = Web3.toChecksumAddress(input_decoded[1]['tokenA']) + token['BASESYMBOL'] = base_symbol + tokenDetected = True + else: + tokenDetected = False + + # Let's snipe! + if tokenDetected: + + printt_debug("v1:", v1) + printt_debug("input_decoded:", input_decoded) + + token['_GAS_IS_CALCULATED'] = True + token['_GAS_TO_USE'] = int(v1['gasPrice'], 16) / 1000000000 + + printt_ok("") + printt_ok("--------------------------------------------------------") + printt_ok("WE FOUND SOMETHING IN MEMPOOL") + printt_ok("") + printt_ok("Bot detected a AddLiquidity Event:") + printt("") + printt("Block number:", client.eth.block_number) + printt("- MethodID:", v1['input'][:10]) + printt("- from:", v1['from']) + printt("- TxHash:", v1['hash']) + printt("- GAS:", token['_GAS_TO_USE']) + printt_ok("--------------------------------------------------------") + + # LIQUIDITY CHECK + # Let's calculate Liquidity amount added. 2 cases : + # 1/ If liquidity is in native token (BNB...) the amount is situated in v1['value'] + # 2/ If liquidity is NOT in native token (BUSD...) the amount is situated in v1['amountADesired'] or v1['amountBDesired'] + if token["MINIMUM_LIQUIDITY_IN_DOLLARS"] != 0: + if token['LIQUIDITYINNATIVETOKEN'] == 'true': + printt_debug("pending['value']", int(v1['value'], 16)) + liquidity_amount = int(v1['value'], 16) / token['_LIQUIDITY_DECIMALS'] + + elif token['LIQUIDITYINNATIVETOKEN'] == 'false' and token['USECUSTOMBASEPAIR'] == 'true': + printt_debug("token['ADDRESS'].lower()", token['BASEADDRESS'].lower()) + printt_debug("input_decoded[1]['tokenA']", input_decoded[1]['tokenA'].lower()) + printt_debug("input_decoded[1]['tokenB']", input_decoded[1]['tokenB'].lower()) + if token['BASEADDRESS'].lower() == input_decoded[1]['tokenA'].lower(): + printt_debug("the token we're trying to snipe is tokenA --> let's find amount in amountADesired") + printt_debug("input_decoded[1]['amountADesired']", input_decoded[1]['amountADesired']) + liquidity_amount = input_decoded[1]['amountADesired'] / token['_LIQUIDITY_DECIMALS'] + else: + printt_debug("the token we're trying to snipe is tokenB --> let's find amount in amountBDesired") + printt_debug("input_decoded[1]['amountBDesired']", input_decoded[1]['amountBDesired']) + liquidity_amount = input_decoded[1]['amountBDesired'] / token['_LIQUIDITY_DECIMALS'] + + liquidity_result = check_liquidity_amount_mempool(token, liquidity_amount) + if liquidity_result != 0: + buyToken = True + else: + response = "" + while response != "y" and response != "n": + printt("What do you want to do?") + response = input(" Would you like to restart the bot and scan mempool again? (y/n): ") + + if response == "y": + scan_mempool_private_node(token, methodid) + else: + sys.exit() + + else: + # If we don't want to check liquidity... That's suicide but let's go! + buyToken = True - printt_debug("input_decoded:", input_decoded) - openTrade = True else: - if command_line_args.verbose == False: - printt("Block number:", client.eth.block_number, "- MethodID:", v1['input'][:10], "- to:", v1['to']) + pass except Exception as e: print(e) continue -def handle_event(event, methodid, filter_id, id_pending, id_latest): - f_id = 0 - if filter_id == id_pending: f_id = 'pending' - if filter_id == id_latest: f_id = 'latest' - - try: - txHash = event['transactionHash'] - txHashDetails = client.eth.get_transaction(txHash) - txFunction = txHashDetails.input[:10] - - if txFunction.lower() in methodid: - printt_ok("--------------------------------------------") - printt_ok("BOT FOUND AddLiquidity-like EVENT IN MEMPOOL") - printt_ok("") - printt_ok("Block:", txHashDetails['blockNumber'], - "- Function:", txFunction, - "- TxHash:", Web3.toHex(txHashDetails['hash'])) - printt_ok("--------------------------------------------") - return True - else: - printt("Detected something, but it's not AddLiquidity", - "- Block:", txHashDetails['blockNumber'], - "- Function:", txFunction, - "- TxHash:", Web3.toHex(txHashDetails['hash'])) - printt_ok("--------------------------------------------") - return False - except Exception as e: - print(e) - - -async def log_loop(fut, event_filter, methodid, poll_interval, id_pend, id_last): - while True: - for event in event_filter.get_new_entries(): - result = handle_event(event, methodid, event_filter.filter_id, id_pend, id_last) - if result == True: fut.set_result('True') - #await asyncio.sleep(poll_interval) - - -def scan_mempool_public_node(token, methodid): - printt_debug("ENTER scan_mempool_private_node") - - printt("") - printt("-----------------------------------------------------------") - printt("SCANNING MEMPOOL - for Public node") - printt("") - printt("Bot will scan mempool to detect AddLiquidity functions") - printt("") - printt_warn("DO NOT CLOSE THE BOT - if nothing appears it's normal!") - printt("") - printt("-----------------------------------------------------------") - - tokenAddress = Web3.toChecksumAddress(token['ADDRESS']) - block_filter = client.eth.filter({"filter_params": "latest", "address": tokenAddress}) - id_last = block_filter.filter_id - tx_filter = client.eth.filter({"filter_params": "pending", "address": tokenAddress}) - id_pend = tx_filter.filter_id - loop = asyncio.get_event_loop() - fut = loop.create_future() - - try: - loop.run_until_complete( - asyncio.gather( - log_loop(fut, block_filter, methodid, 0.0001, id_pend, id_last), - log_loop(fut, tx_filter, methodid, 0.0001, id_pend, id_last))) - finally: - loop.close() - return - - def wait_for_open_trade(token, inToken, outToken, parameter): printt_debug("ENTER wait_for_open_trade") printt(" ", write_to_log=False) - - if parameter != 'pinksale' and (token['WAIT_FOR_OPEN_TRADE'] == 'true' or token['WAIT_FOR_OPEN_TRADE'] == 'true_after_buy_tx_failed'): + + if token['WAIT_FOR_OPEN_TRADE'] == 'true' or token['WAIT_FOR_OPEN_TRADE'] == 'true_after_buy_tx_failed': printt("-----------------------------------------------------------------------------------------------------------------------------", write_to_log=True) printt("WAIT_FOR_OPEN_TRADE is enabled", write_to_log=True) printt("", write_to_log=True) @@ -2921,58 +2897,41 @@ def wait_for_open_trade(token, inToken, outToken, parameter): printt("When you will have read all this message and understood how it works, enter the value 'true_no_message' or 'true_after_buy_tx_failed_no_message' in your WAIT_FOR_OPEN_TRADE setting", write_to_log=False) printt(" ", write_to_log=False) printt("------------------------------------------------------------------------------------------------------------------------------", write_to_log=True) - + if token['WAIT_FOR_OPEN_TRADE'] == 'mempool' or token['WAIT_FOR_OPEN_TRADE'] == 'mempool_after_buy_tx_failed': printt("-----------------------------------------------------------------------------------------------------------------------------", write_to_log=True) printt("WAIT_FOR_OPEN_TRADE is enabled", write_to_log=True) printt("", write_to_log=True) printt("It will scan mempool to detect Enable Trading functions", write_to_log=True) printt("------------------------------------------------------------------------------------------------------------------------------", write_to_log=True) - - if parameter == 'pinksale': - printt("------------------------------------------------------", write_to_log=True) - printt("Let's scan mempool to detect Pinksale launch!", write_to_log=True) - printt("") - printt_warn("Don't worry if nothing appears : it's normal! Do not close the bot", write_to_log=True) - printt("") - printt("------------------------------------------------------", write_to_log=True) - + openTrade = False # We store the initial token price by running check_price() once - if parameter != 'pinksale': - token['_PREVIOUS_QUOTE'] = check_price(inToken, outToken, token['USECUSTOMBASEPAIR'], token['LIQUIDITYINNATIVETOKEN'], int(token['_CONTRACT_DECIMALS']), int(token['_BASE_DECIMALS'])) - - # If we look for Pinksale sales, we look into the Presale Address's transactions for 0x4bb278f3 methodID - if parameter == 'pinksale': - tx_filter = client.eth.filter({"filter_params": "pending", "address": Web3.toChecksumAddress(token['PINKSALE_PRESALE_ADDRESS'])}) - else: - tx_filter = client.eth.filter({"filter_params": "pending", "address": inToken}) + token['_PREVIOUS_QUOTE'] = check_price(inToken, outToken, token['USECUSTOMBASEPAIR'], token['LIQUIDITYINNATIVETOKEN'], int(token['_CONTRACT_DECIMALS']), int(token['_BASE_DECIMALS'])) - if parameter == 'pinksale': - # Function: finalize() - check examples below - list_of_methodId = ["0x4bb278f3"] - else: - # the methodIDs below are openTrading() - like methods. Check below for examples - list_of_methodId = ["0x8a8c523c", "0x0d295980", "0xbccce037", "0x4efac329", "0x7b9e987a", "0x6533e038", "0x8f70ccf7", "0xa6334231", "0x48dfea0a", "0xc818c280", "0xade87098", "0x0099d386", "0xfb201b1d", "0x293230b8", "0x68c5111a", "0xc49b9a80", "0xc00f04d1", "0xcd2a11be", "0xa0ac5e19", "0x1d97b7cd", "0xf275f64b", "0x5e83ae76", "0x82aa7c68"] - - while openTrade == False: + tx_filter = client.eth.filter({"filter_params": "pending", "address": inToken}) + + # the methodIDs below are openTrading() - like methods. Check below for examples + list_of_methodId = ["0x8a8c523c", "0x0d295980", "0xbccce037", "0x4efac329", "0x7b9e987a", "0x6533e038", "0x8f70ccf7", "0xa6334231", "0x48dfea0a", "0xc818c280", "0xade87098", "0x0099d386", "0xfb201b1d", "0x293230b8", "0x68c5111a", "0xc49b9a80", "0xc00f04d1", "0xcd2a11be", "0xa0ac5e19", "0x1d97b7cd", "0xf275f64b", "0x5e83ae76", "0x82aa7c68"] + while openTrade == False: + # If "true" value is selected, it scans the price in // to detect for price movement - if parameter != 'pinksale' and (token['WAIT_FOR_OPEN_TRADE'] == 'true' or token['WAIT_FOR_OPEN_TRADE'] == 'true_no_message' or token['WAIT_FOR_OPEN_TRADE'] == 'true_after_buy_tx_failed' or token['WAIT_FOR_OPEN_TRADE'] == 'true_after_buy_tx_failed_no_message'): + if token['WAIT_FOR_OPEN_TRADE'] == 'true' or token['WAIT_FOR_OPEN_TRADE'] == 'true_no_message' or token['WAIT_FOR_OPEN_TRADE'] == 'true_after_buy_tx_failed' or token['WAIT_FOR_OPEN_TRADE'] == 'true_after_buy_tx_failed_no_message': pprice = check_price(inToken, outToken, token['USECUSTOMBASEPAIR'], token['LIQUIDITYINNATIVETOKEN'], int(token['_CONTRACT_DECIMALS']), int(token['_BASE_DECIMALS'])) - + if pprice != float(token['_PREVIOUS_QUOTE']): token['_TRADING_IS_ON'] = True printt_ok("Token price:", pprice, "--> IT HAS MOVED :)", write_to_log=True) printt_ok("PRICE HAS MOVED --> trading is enabled --> Bot will buy", write_to_log=True) break - + printt("Token price:", pprice) try: for tx_event in tx_filter.get_new_entries(): - + txHash = tx_event['transactionHash'] txHashDetails = client.eth.get_transaction(txHash) # printt_debug(txHashDetails) @@ -2981,10 +2940,7 @@ def wait_for_open_trade(token, inToken, outToken, parameter): openTrade = True token['_GAS_IS_CALCULATED'] = True token['_GAS_TO_USE'] = int(txHashDetails.gasPrice) / 1000000000 - if parameter == 'pinksale': - printt_ok("Pinksale finalize() function detected --> let's buy!", write_to_log=True) - else: - printt_ok("OPEN TRADE FUNCTION DETECTED --> Trading is enabled --> let's buy!", write_to_log=True) + printt_ok("OPEN TRADE FUNCTION DETECTED --> Trading is enabled --> let's buy!", write_to_log=True) printt_ok("MethodID: ", txFunction, " Block: ", tx_event['blockNumber'], " Found Signal", "in txHash:", txHash.hex(), write_to_log=True) printt_ok("GAS will be the same as detected Tx --> GAS=", token['_GAS_TO_USE']) break @@ -2993,18 +2949,8 @@ def wait_for_open_trade(token, inToken, outToken, parameter): except Exception as e: printt_err("Error detected. It can happen with Public node : private node is recommended. Still, let's continue.") continue - - - # Examples of tokens used on pinkSale launch - # - # https://bscscan.com/tx/0x5f0e7fb04ed0c0fe76c959b8f16a9af1f77adfc494a13b11ea3f40d3cfd299d5 - # https://bscscan.com/tx/0xc770f1ca17f7e606e62a910017e5f9eb902af2f650d69743649431e152741b8d - # https://bscscan.com/tx/0x7bfbecc5d58b19e64ea52c7ce68b6482295b93f9ac885a2c699891e5c9c27216 - # https://snowtrace.io/tx/0xbef367a437c758a82640b3e63de9556ecf2d3153e56868130f9cd0901cd24e1d - # Function: finalize() *** - # MethodID: 0x4bb278f3 - - + + # Examples of tokens and functions used for openTrading # # https://bscscan.com/tx/0x468008dd3439b1802784f11a29dd82f195a2a239e381fa83c29dcc39b85024fb @@ -3016,7 +2962,7 @@ def wait_for_open_trade(token, inToken, outToken, parameter): # https://etherscan.io/tx/0x65d66d1e7d3ff3d8fc67308d105aac6722b00da23f116c89a5420544db5b875d # Function: openTrading() # MethodID: 0xc9567bf9 - + # https://etherscan.io/tx/0x303143b2015a398050a50e4dc2ef16668b974c06db2fd4c4e4abbe64f0c2d592 # https://etherscan.io/tx/0x9fbec460367b783afee66446eacf45a1159c9bdfaccb414eca7fb5716bee230b # https://etherscan.io/tx/0xa2b0a8ae04254befd4c463f4abacc50ebe0e3c99b829e95f6e2a9353aab959cf @@ -3026,41 +2972,41 @@ def wait_for_open_trade(token, inToken, outToken, parameter): # https://ftmscan.com/tx/0x4bc8d55aff81c5d202914508b1e7703012d7be998f24cdd476f945fe60451207 # Function: enableTrading() # MethodID: 0x8a8c523c - + # https://bscscan.com/tx/0x19cac49bf8319689a7620935bf9466e469317992b994ec9692697a9ef71e3ace # https://bscscan.com/tx/0xa98ae84de5aee32d216d734b790131a845548c7e5013085688dccd58c9b5b277 # https://bscscan.com/tx/0x5b834a448d4d6309b86fa1aa0fb83d621acfa0450eeb070fd841432f60e10b58 # https://bscscan.com/tx/0x034df83b677bd410d60d864da175efedd3662d3c74bdeda49917581149aae450 # Function: tradingStatus # methodId = "0x0d295980" - + # WitcherVerse - 0xD2f71875d66188F96BaDBF98a5F020894209E34b # https://bscscan.com/tx/0xb42089396c1b1f887cb79e0cf48ae785aa92fa66f0645c759244f70b2a2834f9 # Function: preSaleAfter() # methodId = "0xbccce037" - + # https://bscscan.com/tx/0x5b8d8d70b6d1e591d0620a50247deef38bb924de0c38307cc9c5b77839f68bcc # Function: snipeListing() ** * # MethodID: 0x4efac329 - + # https://bscscan.com/tx/0x0c528819b84a7336c3ff1cc72290ba8ca48555b932383fcbe6722a703a6b72a4 # https://bscscan.com/tx/0x7f526b56a20bf34a7af29137747c9e153c4563f5af4d084d8682893b20e56bd8 # https://bscscan.com/tx/0x6bd42e4c2da59d67809d33912786782e67d8dcff89ce51eb1f95e5b778ca2497 # Function: SetupEnableTrading # MethodID: 0x7b9e987a - + # https://bscscan.com/tx/0x5b2c05e60789350c578ab2d01d3963266dba47aed8e9750c7d2dc78660438091 # Function: enabledTradingOnly # MethodID: 0x6533e038 - + # https://etherscan.io/tx/0xb78202678abf65936f9a4a2be8ee267dbefe28d5df49d1390c4dc55a09c206b0 # Function: setTrading(bool _tradingOpen) # MethodID: 0x8f70ccf7 - + # https://etherscan.io/tx/0xd4a9333c99f3f2b5f09afe80f9b63061e1bc0e4feb9a563a833fe94c7ee096c0 # Function: allowtrading() # MethodID: 0xa6334231 - + # https://etherscan.io/tx/0x7c5c49ec152783dcb6e2c7602154c2cd80542d27ff11587db46df18ec3c6994c # Function: openTrading(address[] lockSells, uint256 duration) # MethodID: 0x48dfea0a @@ -3077,7 +3023,7 @@ def wait_for_open_trade(token, inToken, outToken, parameter): # https://bscscan.com/tx/0x65f672dacff98d68706d49d673ba4d9d2aa252963cfe77fa0dadac21965aea4f # Function: startTrading() # MethodID: 0x293230b8 - + # https://bscscan.com/tx/0x30e8b947fd4a1165c7ae846c72588e43a26562c2c6b5be0589fcccf253d092e8 # Function: setLFG() # MethodID: 0x68c5111a @@ -3088,24 +3034,6 @@ def wait_for_open_trade(token, inToken, outToken, parameter): # MethodID: 0xc49b9a80 # many examples here : https://www.4byte.directory/signatures/?sort=text_signature&page=10003 - -def get_tokens_purchased(tx_hash): - # Function: get_tokens_purchased - # ---------------------------- - # provides the number of tokens purchased in a transaction - # - # tx_hash = the transaction hash - # - # returns: number of tokens purchased - - # Get transaction object - tx = client.eth.get_transaction(tx_hash) - contract = client.eth.contract(address=tx["to"], abi=lpAbi) - - # decode input data using contract object's decode_function_input() method - func_obj, func_params = contract.decode_function_input(tx["input"]) - print(func_params) - exit(0) def build_sell_conditions(token_dict, condition, show_message): @@ -3781,7 +3709,8 @@ def calculate_gas(token): printt_info("") printt_info("Current Gas Price =", gas_price) token['_GAS_TO_USE'] = (gas_price * ((int(token['BOOSTPERCENT'])) / 100)) + gas_price - printt_info("Transaction for", token['SYMBOL'], "will be created with gas =", token['_GAS_TO_USE']) + printt_info("BUY transaction will be created with same GAS as liquidity adding Tx detected") + printt_info("SELL transaction will be created with gas =", token['_GAS_TO_USE']) printt_info("") else: token['_GAS_TO_USE'] = int(token['GAS']) @@ -3847,7 +3776,7 @@ def rug_check(address): return mint -def make_the_buy(inToken, outToken, buynumber, pwd, amount, gas, gaslimit, gaspriority, routing, custom, slippage, DECIMALS): +def make_the_buy(inToken, outToken, buynumber, pwd, amount, gas, gaslimit, gaspriority, routing, custom, slippage, DECIMALS, nonce): # Function: make_the_buy # -------------------- # creates BUY order with the good condition @@ -3857,28 +3786,24 @@ def make_the_buy(inToken, outToken, buynumber, pwd, amount, gas, gaslimit, gaspr printt_debug("ENTER make_the_buy") printt_ok("") - printt_ok("--------------------------------------------------------------------------------") - printt_ok("KIND_OF_SWAP = base --> bot will use BUYAMOUNTINBASE") - printt_ok(" ") - printt_ok("Did you know? You can now swap exact amount of tokens with KIND_OF_SWAP = tokens ") - printt_ok("--------------------------------------------------------------------------------") - + # Choose proper wallet. if buynumber == 0: - walletused = settings['WALLETADDRESS'] + walletused = Web3.toChecksumAddress(settings['WALLETADDRESS']) if buynumber == 1: - walletused = settings['WALLETADDRESS2'] + walletused = Web3.toChecksumAddress(settings['WALLETADDRESS2']) if buynumber == 2: - walletused = settings['WALLETADDRESS3'] + walletused = Web3.toChecksumAddress(settings['WALLETADDRESS3']) if buynumber == 3: - walletused = settings['WALLETADDRESS4'] + walletused = Web3.toChecksumAddress(settings['WALLETADDRESS4']) if buynumber == 4: - walletused = settings['WALLETADDRESS5'] + walletused = Web3.toChecksumAddress(settings['WALLETADDRESS5']) if custom.lower() == 'false': - # if USECUSTOMBASEPAIR = false - + # USECUSTOMBASEPAIR = false + # LIQUIDITYINNATIVETOKEN not defined yet + if routing.lower() == 'false': # LIQUIDITYINNATIVETOKEN = false # USECUSTOMBASEPAIR = false @@ -3889,17 +3814,14 @@ def make_the_buy(inToken, outToken, buynumber, pwd, amount, gas, gaslimit, gaspr else: # LIQUIDITYINNATIVETOKEN = true # USECUSTOMBASEPAIR = false - amount_out = routerContract.functions.getAmountsOut(amount, [weth, outToken]).call()[-1] - - if settings['UNLIMITEDSLIPPAGE'].lower() == 'true': - amountOutMin = 0 - else: - amountOutMin = int(amount_out * (1 - (slippage / 100))) + # amount_out = routerContract.functions.getAmountsOut(amount, [weth, outToken]).call()[-1] + amountOutMin = 0 deadline = int(time() + + 60) # THIS SECTION IS FOR MODIFIED CONTRACTS : EACH EXCHANGE NEEDS TO BE SPECIFIED + # LIQUIDITYINNATIVETOKEN = true # USECUSTOMBASEPAIR = false if modified == True: @@ -3908,14 +3830,14 @@ def make_the_buy(inToken, outToken, buynumber, pwd, amount, gas, gaslimit, gaspr transaction = routerContract.functions.swapExactKCSForTokens( amountOutMin, [weth, outToken], - Web3.toChecksumAddress(walletused), + walletused, deadline ).buildTransaction({ 'gasPrice': Web3.toWei(gas, 'gwei'), 'gas': gaslimit, 'value': amount, - 'from': Web3.toChecksumAddress(walletused), - 'nonce': client.eth.getTransactionCount(walletused) + 'from': walletused, + 'nonce': nonce }) elif settings["EXCHANGE"].lower() == 'pangolin' or settings["EXCHANGE"].lower() == 'traderjoe': @@ -3923,14 +3845,14 @@ def make_the_buy(inToken, outToken, buynumber, pwd, amount, gas, gaslimit, gaspr transaction = routerContract.functions.swapExactAVAXForTokens( amountOutMin, [weth, outToken], - Web3.toChecksumAddress(walletused), + walletused, deadline ).buildTransaction({ 'gasPrice': Web3.toWei(gas, 'gwei'), 'gas': gaslimit, 'value': amount, - 'from': Web3.toChecksumAddress(walletused), - 'nonce': client.eth.getTransactionCount(walletused) + 'from': walletused, + 'nonce': nonce }) elif settings["EXCHANGE"].lower() == 'bakeryswap': @@ -3938,18 +3860,19 @@ def make_the_buy(inToken, outToken, buynumber, pwd, amount, gas, gaslimit, gaspr transaction = routerContract.functions.swapExactBNBForTokens( amountOutMin, [weth, outToken], - Web3.toChecksumAddress(walletused), + walletused, deadline ).buildTransaction({ 'gasPrice': Web3.toWei(gas, 'gwei'), 'gas': gaslimit, 'value': amount, - 'from': Web3.toChecksumAddress(walletused), - 'nonce': client.eth.getTransactionCount(walletused) + 'from': walletused, + 'nonce': nonce }) else: + # LIQUIDITYINNATIVETOKEN = true # USECUSTOMBASEPAIR = false # This section is for exchange with Modified = false --> uniswap / pancakeswap / apeswap, etc. @@ -3962,19 +3885,20 @@ def make_the_buy(inToken, outToken, buynumber, pwd, amount, gas, gaslimit, gaspr transaction = routerContract.functions.swapExactETHForTokens( amountOutMin, [weth, outToken], - Web3.toChecksumAddress(walletused), + walletused, deadline ).buildTransaction({ 'maxFeePerGas': Web3.toWei(gas, 'gwei'), 'maxPriorityFeePerGas': Web3.toWei(gaspriority, 'gwei'), 'gas': gaslimit, 'value': amount, - 'from': Web3.toChecksumAddress(walletused), - 'nonce': client.eth.getTransactionCount(walletused), + 'from': walletused, + 'nonce': nonce, 'type': "0x02" }) else: + # LIQUIDITYINNATIVETOKEN = true # USECUSTOMBASEPAIR = false # for all the rest of exchanges with Modified = false @@ -3982,27 +3906,25 @@ def make_the_buy(inToken, outToken, buynumber, pwd, amount, gas, gaslimit, gaspr transaction = routerContract.functions.swapExactETHForTokens( amountOutMin, [weth, outToken], - Web3.toChecksumAddress(walletused), + walletused, deadline ).buildTransaction({ 'gasPrice': Web3.toWei(gas, 'gwei'), 'gas': gaslimit, 'value': amount, - 'from': Web3.toChecksumAddress(walletused), - 'nonce': client.eth.getTransactionCount(walletused) + 'from': walletused, + 'nonce': nonce }) else: # USECUSTOMBASEPAIR = true + # LIQUIDITYINNATIVETOKEN not defined yet if inToken == weth: # USECUSTOMBASEPAIR = true # but user chose to put WETH or WBNB contract as CUSTOMBASEPAIR address amount_out = routerContract.functions.getAmountsOut(amount, [weth, outToken]).call()[-1] - if settings['UNLIMITEDSLIPPAGE'].lower() == 'true': - amountOutMin = 0 - else: - amountOutMin = int(amount_out * (1 - (slippage / 100))) + amountOutMin = 0 deadline = int(time() + + 60) @@ -4013,14 +3935,14 @@ def make_the_buy(inToken, outToken, buynumber, pwd, amount, gas, gaslimit, gaspr amount, amountOutMin, [weth, outToken], - Web3.toChecksumAddress(walletused), + walletused, deadline ).buildTransaction({ 'maxFeePerGas': Web3.toWei(gas, 'gwei'), 'maxPriorityFeePerGas': Web3.toWei(gaspriority, 'gwei'), 'gas': gaslimit, - 'from': Web3.toChecksumAddress(walletused), - 'nonce': client.eth.getTransactionCount(walletused), + 'from': walletused, + 'nonce': nonce, 'type': "0x02" }) @@ -4029,14 +3951,14 @@ def make_the_buy(inToken, outToken, buynumber, pwd, amount, gas, gaslimit, gaspr transaction = routerContract.functions.swapExactTokensForTokens( amount, amountOutMin, - [weth, outToken], - Web3.toChecksumAddress(walletused), + [weth, inToken, outToken], + walletused, deadline ).buildTransaction({ 'gasPrice': Web3.toWei(gas, 'gwei'), 'gas': gaslimit, - 'from': Web3.toChecksumAddress(walletused), - 'nonce': client.eth.getTransactionCount(walletused) + 'from': walletused, + 'nonce': nonce }) else: @@ -4053,13 +3975,8 @@ def make_the_buy(inToken, outToken, buynumber, pwd, amount, gas, gaslimit, gaspr printt_info("YOU ARE TRADING WITH VERY BIG AMOUNT, BE VERY CAREFUL YOU COULD LOSE MONEY!!! TEAM RECOMMEND NOT TO DO THAT") if routing.lower() == 'true': - amount_out = routerContract.functions.getAmountsOut(amount, [inToken, weth, outToken]).call()[-1] + amountOutMin = 0 - if settings['UNLIMITEDSLIPPAGE'].lower() == 'true': - amountOutMin = 100 - else: - amountOutMin = int(amount_out * (1 - (slippage / 100))) - deadline = int(time() + + 60) if settings["EXCHANGE"].lower() == 'uniswap' or settings["EXCHANGE"].lower() == 'uniswaptestnet': @@ -4073,15 +3990,15 @@ def make_the_buy(inToken, outToken, buynumber, pwd, amount, gas, gaslimit, gaspr amount, amountOutMin, [inToken, weth, outToken], - Web3.toChecksumAddress(walletused), + walletused, deadline ).buildTransaction({ 'maxFeePerGas': Web3.toWei(gas, 'gwei'), 'maxPriorityFeePerGas': Web3.toWei(gaspriority, 'gwei'), 'gas': gaslimit, 'value': amount, - 'from': Web3.toChecksumAddress(walletused), - 'nonce': client.eth.getTransactionCount(walletused), + 'from': walletused, + 'nonce': nonce, 'type': "0x02" }) @@ -4095,13 +4012,13 @@ def make_the_buy(inToken, outToken, buynumber, pwd, amount, gas, gaslimit, gaspr amount, amountOutMin, [inToken, weth, outToken], - Web3.toChecksumAddress(walletused), + walletused, deadline ).buildTransaction({ 'gasPrice': Web3.toWei(gas, 'gwei'), 'gas': gaslimit, - 'from': Web3.toChecksumAddress(walletused), - 'nonce': client.eth.getTransactionCount(walletused) + 'from': walletused, + 'nonce': nonce }) else: @@ -4117,14 +4034,9 @@ def make_the_buy(inToken, outToken, buynumber, pwd, amount, gas, gaslimit, gaspr or str(inToken).lower() == '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48') \ and (int(amount) / DECIMALS) > 2999: printt_info("YOU ARE TRADING WITH VERY BIG AMOUNT, BE VERY CAREFUL YOU COULD LOSE MONEY!!! TEAM RECOMMEND NOT TO DO THAT") - - amount_out = routerContract.functions.getAmountsOut(amount, [inToken, outToken]).call()[-1] - - if settings['UNLIMITEDSLIPPAGE'].lower() == 'true': - amountOutMin = 100 - else: - amountOutMin = int(amount_out * (1 - (slippage / 100))) + amountOutMin = 0 + deadline = int(time() + + 60) if settings["EXCHANGE"].lower() == 'uniswap' or settings["EXCHANGE"].lower() == 'uniswaptestnet': @@ -4137,18 +4049,67 @@ def make_the_buy(inToken, outToken, buynumber, pwd, amount, gas, gaslimit, gaspr amount, amountOutMin, [inToken, outToken], - Web3.toChecksumAddress(walletused), + walletused, deadline ).buildTransaction({ 'maxFeePerGas': Web3.toWei(gas, 'gwei'), 'maxPriorityFeePerGas': Web3.toWei(gaspriority, 'gwei'), 'gas': gaslimit, 'value': amount, - 'from': Web3.toChecksumAddress(walletused), - 'nonce': client.eth.getTransactionCount(walletused), + 'from': walletused, + 'nonce': nonce, 'type': "0x02" }) - + + if modified == True: + if settings["EXCHANGE"].lower() == 'koffeeswap': + printt_debug("make_the_buy condition 13", write_to_log=True) + + transaction = routerContract.functions.swapExactKCSForTokens( + amountOutMin, + [weth, inToken, outToken], + walletused, + deadline + ).buildTransaction({ + 'gasPrice': Web3.toWei(gas, 'gwei'), + 'gas': gaslimit, + 'value': amount, + 'from': walletused, + 'nonce': nonce + }) + + elif settings["EXCHANGE"].lower() == 'pangolin' or settings["EXCHANGE"].lower() == 'traderjoe': + printt_debug("make_the_buy condition 14", write_to_log=True) + + transaction = routerContract.functions.swapExactAVAXForTokens( + amountOutMin, + [weth, inToken, outToken], + walletused, + deadline + ).buildTransaction({ + 'gasPrice': Web3.toWei(gas, 'gwei'), + 'gas': gaslimit, + 'value': amount, + 'from': walletused, + 'nonce': nonce + }) + + elif settings["EXCHANGE"].lower() == 'bakeryswap': + printt_debug("make_the_buy condition 15", write_to_log=True) + + transaction = routerContract.functions.swapExactBNBForTokens( + amountOutMin, + [weth, inToken, outToken], + walletused, + deadline + ).buildTransaction({ + 'gasPrice': Web3.toWei(gas, 'gwei'), + 'gas': gaslimit, + 'value': amount, + 'from': walletused, + 'nonce': nonce + }) + else: # LIQUIDITYINNATIVETOKEN = false # USECUSTOMBASEPAIR = true @@ -4156,20 +4117,20 @@ def make_the_buy(inToken, outToken, buynumber, pwd, amount, gas, gaslimit, gaspr # Exchange different from Uniswap printt_debug("make_the_buy condition 10", write_to_log=True) - transaction = routerContract.functions.swapExactTokensForTokens( - amount, + transaction = routerContract.functions.swapExactETHForTokens( amountOutMin, - [inToken, outToken], - Web3.toChecksumAddress(walletused), + [weth, inToken, outToken], + walletused, deadline ).buildTransaction({ 'gasPrice': Web3.toWei(gas, 'gwei'), 'gas': gaslimit, - 'from': Web3.toChecksumAddress(walletused), - 'nonce': client.eth.getTransactionCount(walletused) + 'value': amount, + 'from': walletused, + 'nonce': nonce }) - - sync(inToken, outToken) + + # sync(inToken, outToken) if buynumber == 0: # No need to decrypt PRIVATEKEY because it was already decrypted in parse_wallet_settings() @@ -4204,7 +4165,7 @@ def make_the_buy(inToken, outToken, buynumber, pwd, amount, gas, gaslimit, gaspr return tx_hash -def make_the_buy_exact_tokens(token_dict, inToken, outToken, buynumber, pwd, gaslimit, routing, custom, slippage, DECIMALS_FOR_AMOUNT, basebalance): +def make_the_buy_exact_tokens(token_dict, inToken, outToken, buynumber, pwd, gaslimit, routing, custom, slippage, DECIMALS_FOR_AMOUNT, basebalance, nonce): # Function: make_the_buy_exact_tokens # -------------------- # creates BUY order with the good condition @@ -4223,12 +4184,6 @@ def make_the_buy_exact_tokens(token_dict, inToken, outToken, buynumber, pwd, gas gaspriority = token_dict['GASPRIORITY_FOR_ETH_ONLY'] token_symbol = token_dict['SYMBOL'] - - # implementing an ugly fix for those shitty tokens with decimals = 9 to solve https://github.com/CryptoGnome/LimitSwap/issues/401 - # if DECIMALS == 1000000000: - # DECIMALS = 1000000000 * DECIMALS - # printt_debug("DECIMALS after fix applied for those shitty tokens with decimals = 9:", DECIMALS) - DECIMALS = 1000000000000000000 # Choose proper wallet. @@ -4390,7 +4345,11 @@ def make_the_buy_exact_tokens(token_dict, inToken, outToken, buynumber, pwd, gas else: # USECUSTOMBASEPAIR = true - printt_err("Sorry, swap for exact tokens is only available for USECUSTOMBASEPAIR = false. Exiting.") + printt("") + printt_err("Sorry, KIND_OF_SWAP = tokens is only available when liquidity is added in native token (BNB/ETH...).") + printt_err("If you want the Sniper to buy when liquidity is not added in native token, please use KIND_OF_SWAP = base.") + printt_err("Exiting") + sleep(10) sys.exit() @@ -4503,7 +4462,7 @@ def preapprove_base(token): printt_debug("EXIT - preapprove_base()") -def buy(token_dict, inToken, outToken, pwd): +def buy(token_dict, inToken, outToken, pwd, nonce): # Function: buy # ---------------------------- # purchases the amount of tokens specified for the contract specified @@ -4524,11 +4483,8 @@ def buy(token_dict, inToken, outToken, pwd): amount = 0 slippage = token_dict['SLIPPAGE'] - gaslimit = token_dict['GASLIMIT'] - boost = token_dict['BOOSTPERCENT'] - fees = token_dict["HASFEES"] + gaslimit = int(token_dict['GASLIMIT']) custom = token_dict['USECUSTOMBASEPAIR'] - symbol = token_dict['SYMBOL'] routing = token_dict['LIQUIDITYINNATIVETOKEN'] gaspriority = token_dict['GASPRIORITY_FOR_ETH_ONLY'] multiplebuys = token_dict['MULTIPLEBUYS'] @@ -4545,7 +4501,7 @@ def buy(token_dict, inToken, outToken, pwd): token_dict['ENABLED'] = 'false' return False - # Check for amount of success transactions before buy (MAX_FAILED_TRANSACTIONS_IN_A_ROW parameter) + # Check for amount of success transactions before buy (MAX_SUCCESS_TRANSACTIONS_IN_A_ROW parameter) printt_debug("debug _SUCCESS_TRANSACTIONS:", token_dict['_SUCCESS_TRANSACTIONS']) if token_dict['_SUCCESS_TRANSACTIONS'] >= int(token_dict['MAX_SUCCESS_TRANSACTIONS_IN_A_ROW']): printt_ok("---------------------------------------------------------------", write_to_log=True) @@ -4560,43 +4516,18 @@ def buy(token_dict, inToken, outToken, pwd): printt_info("Bot will wait", token_dict['BUYAFTER_XXX_SECONDS'], " seconds before buy, as you entered in BUYAFTER_XXX_SECONDS parameter") sleep(token_dict['BUYAFTER_XXX_SECONDS']) - if int(gaslimit) < 250000: - printt_info("Your GASLIMIT parameter is too low : LimitSwap has forced it to 300000 otherwise your transaction would fail for sure. We advise you to raise it to 1000000.") - gaslimit = 300000 - # Define balance before BUY # - if custom.lower() == 'false': - balance = token_dict['_BASE_BALANCE'] - else: - balance = token_dict['_CUSTOM_BASE_BALANCE'] - - printt_debug("Check balance:", balance) + balance = token_dict['_BASE_BALANCE'] - if balance > Decimal(amount) or token_dict['KIND_OF_SWAP'] == 'tokens': - - if (base_symbol == "ETH" or base_symbol == "MATIC") and token_dict['_GAS_IS_CALCULATED'] != True: - # We calculate the GAS only for ETH and MATIC, because it changes at every block. - # On other blockchains, it's almost constant so ne need for it - # - # If WAIT_FOR_OPEN_TRADE was used and detected openTrading transaction in mempool : - # 1/ _GAS_TO_USE was calculated by wait_for_open_trade to be the same as openTrading transaction - # 2/ _GAS_IS_CALCULATED was set to true, to understand that we don't need to re-calculate it again - # - # If WAIT_FOR_OPEN_TRADE was not used, let's calculate now how much gas we should use for this token for ETH only - printt_debug("Need to re-calculate GAS price") - calculate_gas(token_dict) + if balance > Decimal(amount): # Stops transaction if GAS > MAXGAS - printt_debug("_GAS_TO_USE is set to: ", token_dict['_GAS_TO_USE']) - printt_debug("MAX_GAS is set to : ", token_dict['MAX_GAS']) - if token_dict['_GAS_TO_USE'] > token_dict['MAX_GAS']: printt_err("GAS = ", token_dict['_GAS_TO_USE'], "is superior to your MAX_GAS parameter (=", token_dict['MAX_GAS'], ") --> bot do not buy", ) token_dict['ENABLED'] = 'false' return False - gaslimit = int(gaslimit) slippage = int(slippage) amount = int(float(amount) * token_dict['_BASE_DECIMALS']) buynumber = 0 @@ -4609,18 +4540,18 @@ def buy(token_dict, inToken, outToken, pwd): if buynumber < amount_of_buys: printt("Placing New Buy Order for wallet number:", buynumber) if token_dict['KIND_OF_SWAP'] == 'tokens': - make_the_buy_exact_tokens(token_dict, inToken, outToken, buynumber, pwd, gaslimit, routing, custom, slippage, CONTRACT_DECIMALS, balance) + make_the_buy_exact_tokens(token_dict, inToken, outToken, buynumber, pwd, gaslimit, routing, custom, slippage, CONTRACT_DECIMALS, balance, nonce) else: - make_the_buy(inToken, outToken, buynumber, pwd, amount, token_dict['_GAS_TO_USE'], gaslimit, gaspriority, routing, custom, slippage, CONTRACT_DECIMALS) + make_the_buy(inToken, outToken, buynumber, pwd, amount, int(token_dict['_GAS_TO_USE']), gaslimit, gaspriority, routing, custom, slippage, CONTRACT_DECIMALS, nonce) buynumber += 1 else: printt_ok("All BUYS orders have been sent - Stopping Bot") sys.exit(0) else: if token_dict['KIND_OF_SWAP'] == 'tokens': - tx_hash = make_the_buy_exact_tokens(token_dict, inToken, outToken, buynumber, pwd, gaslimit, routing, custom, slippage, CONTRACT_DECIMALS, balance) + tx_hash = make_the_buy_exact_tokens(token_dict, inToken, outToken, buynumber, pwd, gaslimit, routing, custom, slippage, CONTRACT_DECIMALS, balance, nonce) else: - tx_hash = make_the_buy(inToken, outToken, buynumber, pwd, amount, token_dict['_GAS_TO_USE'], gaslimit, gaspriority, routing, custom, slippage, CONTRACT_DECIMALS) + tx_hash = make_the_buy(inToken, outToken, buynumber, pwd, amount, int(token_dict['_GAS_TO_USE']), gaslimit, gaspriority, routing, custom, slippage, CONTRACT_DECIMALS, nonce) return tx_hash @@ -5388,17 +5319,15 @@ def run(): if token['KIND_OF_SWAP'].lower() == 'tokens' and token['MAX_BASE_AMOUNT_PER_EXACT_TOKENS_TRANSACTION'] == 0: printt_err("You have selected KIND_OF_SWAP = tokens, so you must enter a value in MAX_BASE_AMOUNT_PER_EXACT_TOKENS_TRANSACTION") sys.exit() - + + if token['BUYAMOUNTINBASE'] == 0: + printt_err("You need to enter a BUY amount") + sys.exit() + # Set the checksum addressed for the addresses we're working with # _IN_TOKEN is the token you want to BUY (example : CAKE) token['_IN_TOKEN'] = Web3.toChecksumAddress(token['ADDRESS']) - - # _OUT_TOKEN is the token you want to TRADE WITH (example : ETH or USDT) - if token['USECUSTOMBASEPAIR'] == 'true': - token['_OUT_TOKEN'] = Web3.toChecksumAddress(token['BASEADDRESS']) - else: - token['_OUT_TOKEN'] = weth - + # Calculate contract / custom base pair / weth decimals printt_debug("Pre-calculations for token:", token['ADDRESS'], ": Gas / Decimals / Balance / RugDoc check") @@ -5441,7 +5370,14 @@ def run(): token['_PAIR_TO_DISPLAY'] = token['SYMBOL'] + "/" + token['BASESYMBOL'] else: token['_PAIR_TO_DISPLAY'] = token['SYMBOL'] + "/" + base_symbol - + + # let's define _OUT_TOKEN (the token you want to TRADE WITH (example : ETH or USDT)) + # it depends of which liquidity was detected + if token['USECUSTOMBASEPAIR'] == 'true': + token['_OUT_TOKEN'] = Web3.toChecksumAddress(token['BASEADDRESS']) + else: + token['_OUT_TOKEN'] = weth + # Check to see if we have any tokens in our wallet already token['_TOKEN_BALANCE'] = check_balance(token['ADDRESS'], token['SYMBOL'], display_quantity=False) / token['_CONTRACT_DECIMALS'] token['_PREVIOUS_TOKEN_BALANCE'] = token['_TOKEN_BALANCE'] @@ -5461,6 +5397,9 @@ def run(): # Calculate how much gas we should use for this token calculate_gas(token) + # Determine nonce + nonce = client.eth.getTransactionCount(Web3.toChecksumAddress(settings['WALLETADDRESS'])) + # Call of RugDoc API if parameter is set to True if token['RUGDOC_CHECK'] == 'true': check_rugdoc_api(token) @@ -5469,13 +5408,6 @@ def run(): tokens_file_modified_time = os.path.getmtime(command_line_args.tokens) first_liquidity_check = True - # if START_BUY_AFTER_TIMESTAMP setting is a number, then wait until it's reached - if re.search(r'^[0-9]+$', str(settings['START_BUY_AFTER_TIMESTAMP'])): - printt_info("") - printt_info("Bot will wait until timestamp=", settings['START_BUY_AFTER_TIMESTAMP'], "before buying. Use https://www.unixtimestamp.com/ to define value") - printt_info("") - pause.until(int(settings['START_BUY_AFTER_TIMESTAMP'])) - while True: # Check to see if the tokens file has changed every 10 iterations @@ -5497,9 +5429,8 @@ def run(): # Before changing tokens, we store them in a dict, to be able to re-use the internal values like "COST_PER_TOKEN" # The key to re-use them will be token['SYMBOL'] # - printt_debug("tokens before reload:", tokens) - + _TOKENS_saved = {} for token in tokens: _TOKENS_saved[token['SYMBOL']] = token @@ -5518,179 +5449,168 @@ def run(): if token['ENABLED'] == 'true': # - # BALANCE CHECK - # We won't try to buy this token if balance > MAXTOKENS + # MEMPOOL SCAN + # + # if we haven't reached MAXTOKENS + # and no BUY has been made yet + # --> let's scan mempool ! # - if token['_TOKEN_BALANCE'] < token['MAXTOKENS']: + if token['_TOKEN_BALANCE'] < float(token['MAXTOKENS']) and token['_BUY_IS_MADE'] == False: # # METHODS ID definition # Let's define which methods id we'll search in mempool # - if settings['MEMPOOL_METHOD'] == 'pinksale': - # Function: finalize() - check examples below - methods_id = ["0x4bb278f3"] - else: - # We scan for AddLiquidity-kind of methods - # many examples here : https://www.4byte.directory/signatures/?sort=text_signature&page=633 - methods_id = ["0xf305d719", "0xf91b3f72", "0xe8e33700", "0xeaaed442", "0xa987e39d", "0xa62f0f32", "0x395d3384", "0xe8078d94", "0xed39257a", "0x3b2b65a0", "0xbe0ca465", "0xf5917c99", "0x44192a01", "0x2a3395b0", "0xe3412e3d", "0x6f24391a", "0x380ecef2", "0x00b071e1", "0xfde3b265", "0x011ad359", "0x6ac8ac29", "0x863f15cd", "0xde48a49b", "0xfbf45135", "0xd71a1bc5"] - - # Examples of tokens and functions used for AddLiquidity - # (I don't display the usual "addLiquidityETH" / etc. ones - # - # https://etherscan.io/tx/0x5241874905739ac52a65c048af6b69532a247febb18be080885f282d02978759 - # Function: execTransaction (on ShibaSwap --> needs to be implemented) - # MethodID: 0x6a761202 - # - # https://bscscan.com/tx/0xeb86daec5cd7a646e28ed9cfc392f6d0b11e259bce15b7b905bef017ddd9b1af - # Function: addLiquidity() *** (on UniCrypt --> needs to be implemented) - # MethodID: 0xe8078d94 + # We scan for AddLiquidity-kind of methods + # many examples here : https://www.4byte.directory/signatures/?sort=text_signature&page=633 + methods_id = ["0xf305d719", "0xe8e33700", "0xf91b3f72", "0xd71a1bc5"] + # Examples of tokens and functions used for AddLiquidity + # (I don't display the usual "addLiquidityETH" / etc. ones # - # MEMPOOL SCAN - # Let's scan mempool + # https://etherscan.io/tx/0x5241874905739ac52a65c048af6b69532a247febb18be080885f282d02978759 + # Function: execTransaction (on ShibaSwap --> needs to be implemented) + # MethodID: 0x6a761202 # - if token['_BUY_IS_MADE'] == False: - if settings['MEMPOOL_METHOD'] == 'pinksale': - wait_for_open_trade(token, token['_IN_TOKEN'], token['_OUT_TOKEN'], 'pinksale') - else: - scan_mempool_classic(token) + # https://bscscan.com/tx/0xeb86daec5cd7a646e28ed9cfc392f6d0b11e259bce15b7b905bef017ddd9b1af + # Function: addLiquidity() *** (on UniCrypt --> needs to be implemented) + # MethodID: 0xe8078d94 + + + # let's scans mempool + # + if settings['MEMPOOL_METHOD'] == 'public_node': + scan_mempool_public_node(token) + elif settings['MEMPOOL_METHOD'] == 'private_node': + scan_mempool_private_node(token, methods_id) + else: + printt_err("Wrong value in MEMPOOL_METHOD setting.") + sleep(10) + sys.exit() # # OPEN TRADE CHECK # If the option is selected, bot wait for trading_is_on == True to create a BUY order # + + if token['WAIT_FOR_OPEN_TRADE'].lower() == 'true' or token['WAIT_FOR_OPEN_TRADE'].lower() == 'true_no_message' or token['WAIT_FOR_OPEN_TRADE'] == 'mempool': + wait_for_open_trade(token, token['_IN_TOKEN'], token['_OUT_TOKEN'], 'normal') - if token['WAIT_FOR_OPEN_TRADE'].lower() == 'true' or token['WAIT_FOR_OPEN_TRADE'].lower() == 'true_no_message' or token['WAIT_FOR_OPEN_TRADE'].lower() == 'mempool': - wait_for_open_trade(token, token['_IN_TOKEN'], token['_OUT_TOKEN'], 'normal') - - printt_debug(token) - - # - # BUY - # Let's buy! - # - - if command_line_args.sim_buy: - tx = command_line_args.sim_buy - else: - tx = buy(token, token['_OUT_TOKEN'], token['_IN_TOKEN'], userpassword) - - if tx != False: - txbuyresult = wait_for_tx(token, tx, token['ADDRESS']) - printt_debug("wait_for_tx result is : ", txbuyresult) - if txbuyresult != 1: - # transaction is a FAILURE - printt_err("-------------------------------", write_to_log=True) - printt_err(" BUY TRANSACTION FAILURE !") - printt_err("-------------------------------") - printt_err("Type of failures and possible causes:") - printt_err("- TRANSFER_FROM_FAILED --> GASLIMIT too low. Raise it to GASLIMIT = 1000000 at least") - printt_err("- TRANSFER_FROM_FAILED --> Your BASE token is not approved for trade") - printt_err("- INSUFFICIENT_OUTPUT_AMOUNT --> SLIPPAGE too low") - printt_err("- TRANSFER_FAILED --> Trading is not enabled. Use WAIT_FOR_OPEN_TRADE parameter after reading wiki") - printt_err("- TRANSFER_FAILED --> There is a whitelist") - printt_err("- Sorry, We are unable to locate this TxnHash --> You don't have enough funds on your wallet to cover fees") - printt_err("- ... or your node is not working well") - printt_err("-------------------------------") - - # Apprise notification - try: - if settings['ENABLE_APPRISE_NOTIFICATIONS'] == 'true': - apprise_notification(token, 'buy_failure') - except Exception as e: - printt_err("An error occured when using Apprise notification --> check your settings.") - logging.exception(e) - logger1.exception(e) - - # increment _FAILED_TRANSACTIONS amount - token['_FAILED_TRANSACTIONS'] += 1 - printt_debug("3813 _FAILED_TRANSACTIONS:", token['_FAILED_TRANSACTIONS']) - - # Check if Base pair is approved, in case of TRANSFER_FROM_FAILED - preapprove_base(token) - - # If user selected WAIT_FOR_OPEN_TRADE = 'XXX_after_buy_tx_failed" bot enters WAIT_FOR_OPEN_TRADE mode - if token['WAIT_FOR_OPEN_TRADE'].lower() == 'true_after_buy_tx_failed' or token['WAIT_FOR_OPEN_TRADE'].lower() == 'true_after_buy_tx_failed_no_message' or token['WAIT_FOR_OPEN_TRADE'] == 'mempool_after_buy_tx_failed': - wait_for_open_trade(token, token['_IN_TOKEN'], token['_OUT_TOKEN'], 'normal') - - else: - # transaction is a SUCCESS - printt_ok("----------------------------------", write_to_log=True) - printt_ok("SUCCESS : your buy Tx is confirmed", write_to_log=True) - printt_ok("") - - # Save previous token balance before recalculating - token['_PREVIOUS_TOKEN_BALANCE'] = token['_TOKEN_BALANCE'] - - # Re-calculate balances after buy() - calculate_base_balance(token) - - # Check the balance of our wallet - DECIMALS = token['_CONTRACT_DECIMALS'] - token['_TOKEN_BALANCE'] = check_balance(token['_IN_TOKEN'], token['SYMBOL'],display_quantity=True) / DECIMALS - printt_ok("", write_to_log=True) - printt_ok("You bought", token['_TOKEN_BALANCE'] - token['_PREVIOUS_TOKEN_BALANCE'], token['SYMBOL'], "tokens", write_to_log=True) - printt_ok("----------------------------------", write_to_log=True) - - # Apprise notification - try: - if settings['ENABLE_APPRISE_NOTIFICATIONS'] == 'true': - apprise_notification(token, 'buy_success') - except Exception as e: - printt_err("An error occured when using Apprise notification --> check your settings.") - logging.exception(e) - logger1.exception(e) - - # if user has chose the option "instantafterbuy", token is approved right after buy order is confirmed. - if (settings['PREAPPROVE'] == 'instantafterbuy' or settings['PREAPPROVE'] == 'true'): - check_approval(token, token['ADDRESS'], token['_TOKEN_BALANCE'] * DECIMALS, 'preapprove') - - # Optional cooldown after SUCCESS buy, if you use XXX_SECONDS_COOLDOWN_AFTER_BUY_SUCCESS_TX parameter - if token['XXX_SECONDS_COOLDOWN_AFTER_BUY_SUCCESS_TX'] != 0: - printt_info("Bot will wait", token['XXX_SECONDS_COOLDOWN_AFTER_BUY_SUCCESS_TX'], "seconds after BUY, due to XXX_SECONDS_COOLDOWN_AFTER_BUY_SUCCESS_TX parameter", write_to_log=True) - sleep(token['XXX_SECONDS_COOLDOWN_AFTER_BUY_SUCCESS_TX']) - - # if START_SELL_AFTER_TIMESTAMP setting is a number, then wait until it's reached - if re.search(r'^[0-9]+$', str(settings['START_SELL_AFTER_TIMESTAMP'])): - printt_info("") - printt_info("Bot will wait until timestamp=", settings['START_SELL_AFTER_TIMESTAMP'], "before selling. Use https://www.unixtimestamp.com/ to define value") - printt_info("") - - pause.until(int(settings['START_SELL_AFTER_TIMESTAMP'])) - - # increment _SUCCESS_TRANSACTIONS amount - token['_SUCCESS_TRANSACTIONS'] += 1 - printt_debug("3840 _SUCCESS_TRANSACTIONS:", token['_SUCCESS_TRANSACTIONS']) - - # Check if MAX_SUCCESS_TRANSACTIONS_IN_A_ROW is reached or not - if token['_SUCCESS_TRANSACTIONS'] >= token['MAX_SUCCESS_TRANSACTIONS_IN_A_ROW']: - token['_REACHED_MAX_SUCCESS_TX'] = True - printt_warn("You have reached MAX_SUCCESS_TRANSACTIONS_IN_A_ROW for", token['SYMBOL'], "token --> disabling trade", write_to_log=True) - - printt_info("") - printt_info("--------------------------------------------") - printt_info(" Buy is now made --> Entering SELL MODE") - printt_info("--------------------------------------------") - printt_info("") - - # Set _BUY_IS_MADE to true to avoid entering Mempool mode again - token['_BUY_IS_MADE'] = True - - # Build sell conditions for the token - build_sell_conditions(token, 'after_buy', 'show_message') - - printt_debug(tokens) - + if command_line_args.sim_buy: + tx = command_line_args.sim_buy + else: + tx = buy(token, token['_OUT_TOKEN'], token['_IN_TOKEN'], userpassword, nonce) + + if tx != False: + txbuyresult = wait_for_tx(token, tx, token['ADDRESS']) + printt_debug("wait_for_tx result is : ", txbuyresult) + if txbuyresult != 1: + # transaction is a FAILURE + printt_err("-------------------------------", write_to_log=True) + printt_err(" BUY TRANSACTION FAILURE !") + printt_err("-------------------------------") + printt_err("Type of failures and possible causes:") + printt_err("- TRANSFER_FROM_FAILED --> GASLIMIT too low. Raise it to GASLIMIT = 1000000 at least") + printt_err("- TRANSFER_FROM_FAILED --> Your BASE token is not approved for trade") + printt_err("- INSUFFICIENT_OUTPUT_AMOUNT --> SLIPPAGE too low") + printt_err("- TRANSFER_FAILED --> Trading is not enabled. Use WAIT_FOR_OPEN_TRADE parameter after reading wiki") + printt_err("- TRANSFER_FAILED --> There is a whitelist") + printt_err("- Sorry, We are unable to locate this TxnHash --> You don't have enough funds on your wallet to cover fees") + printt_err("- ... or your node is not working well") + printt_err("-------------------------------") + + # Apprise notification + try: + if settings['ENABLE_APPRISE_NOTIFICATIONS'] == 'true': + apprise_notification(token, 'buy_failure') + except Exception as e: + printt_err("An error occured when using Apprise notification --> check your settings.") + logging.exception(e) + logger1.exception(e) + + # increment _FAILED_TRANSACTIONS amount + token['_FAILED_TRANSACTIONS'] += 1 + printt_debug("3813 _FAILED_TRANSACTIONS:", token['_FAILED_TRANSACTIONS']) + + # Check if Base pair is approved, in case of TRANSFER_FROM_FAILED + preapprove_base(token) + + # If user selected WAIT_FOR_OPEN_TRADE = 'XXX_after_buy_tx_failed" bot enters WAIT_FOR_OPEN_TRADE mode + if token['WAIT_FOR_OPEN_TRADE'].lower() == 'true_after_buy_tx_failed' or token['WAIT_FOR_OPEN_TRADE'].lower() == 'true_after_buy_tx_failed_no_message' or token['WAIT_FOR_OPEN_TRADE'] == 'mempool_after_buy_tx_failed': + wait_for_open_trade(token, token['_IN_TOKEN'], token['_OUT_TOKEN'], 'normal') + else: - continue + # transaction is a SUCCESS + printt_ok("----------------------------------", write_to_log=True) + printt_ok("SUCCESS : your buy Tx is confirmed", write_to_log=True) + printt_ok("") + + # Save previous token balance before recalculating + token['_PREVIOUS_TOKEN_BALANCE'] = token['_TOKEN_BALANCE'] + + # Wait 3s before recalculating, because sometimes it's not updated yet + printt("Let's wait 3s before we check your new balance, to be sure we get correct amount") + sleep(3) + printt("") + + # Re-calculate balances after buy() + calculate_base_balance(token) + + # Check the balance of our wallet + DECIMALS = token['_CONTRACT_DECIMALS'] + token['_TOKEN_BALANCE'] = check_balance(token['_IN_TOKEN'], token['SYMBOL'],display_quantity=True) / DECIMALS + printt_ok("", write_to_log=True) + printt_ok("You bought", token['_TOKEN_BALANCE'] - token['_PREVIOUS_TOKEN_BALANCE'], token['SYMBOL'], "tokens", write_to_log=True) + printt_ok("----------------------------------", write_to_log=True) + + # Apprise notification + try: + if settings['ENABLE_APPRISE_NOTIFICATIONS'] == 'true': + apprise_notification(token, 'buy_success') + except Exception as e: + printt_err("An error occured when using Apprise notification --> check your settings.") + logging.exception(e) + logger1.exception(e) + + # if user has chose the option "instantafterbuy", token is approved right after buy order is confirmed. + if (settings['PREAPPROVE'] == 'instantafterbuy' or settings['PREAPPROVE'] == 'true'): + check_approval(token, token['ADDRESS'], token['_TOKEN_BALANCE'] * DECIMALS, 'preapprove') + + # Optional cooldown after SUCCESS buy, if you use XXX_SECONDS_COOLDOWN_AFTER_BUY_SUCCESS_TX parameter + if token['XXX_SECONDS_COOLDOWN_AFTER_BUY_SUCCESS_TX'] != 0: + printt_info("Bot will wait", token['XXX_SECONDS_COOLDOWN_AFTER_BUY_SUCCESS_TX'], "seconds after BUY, due to XXX_SECONDS_COOLDOWN_AFTER_BUY_SUCCESS_TX parameter", write_to_log=True) + sleep(token['XXX_SECONDS_COOLDOWN_AFTER_BUY_SUCCESS_TX']) + + # increment _SUCCESS_TRANSACTIONS amount + token['_SUCCESS_TRANSACTIONS'] += 1 + printt_debug("3840 _SUCCESS_TRANSACTIONS:", token['_SUCCESS_TRANSACTIONS']) + + # Check if MAX_SUCCESS_TRANSACTIONS_IN_A_ROW is reached or not + if token['_SUCCESS_TRANSACTIONS'] >= token['MAX_SUCCESS_TRANSACTIONS_IN_A_ROW']: + token['_REACHED_MAX_SUCCESS_TX'] = True + printt_warn("You have reached MAX_SUCCESS_TRANSACTIONS_IN_A_ROW for", token['SYMBOL'], "token --> disabling trade", write_to_log=True) + + printt_info("") + printt_info("--------------------------------------------") + printt_info(" Buy is now made --> Entering SELL MODE") + printt_info("--------------------------------------------") + printt_info("") + + # Set _BUY_IS_MADE to true to avoid entering Mempool mode again + token['_BUY_IS_MADE'] = True + + # Build sell conditions for the token + build_sell_conditions(token, 'after_buy', 'show_message') + + printt_debug(tokens) + + else: + continue # - # PRICE CHECK - # Check the latest price on this token and record information on the price that we may - # need to use later + # SELL MODE + # Buy has been made --> let's SELL this token :) # - token['_PREVIOUS_QUOTE'] = token['_QUOTE'] if token['LIQUIDITYINNATIVETOKEN'] == 'true': diff --git a/tokens.json b/tokens.json index e5a85e1..501702e 100644 --- a/tokens.json +++ b/tokens.json @@ -5,19 +5,19 @@ "SYMBOL": "CAKE", "ADDRESS": "0x0e09fabb73bd3ade0a17ecc321fd13a19e81ce82", - "PINKSALE_PRESALE_ADDRESS": "0x0000000000000000000000000000000000000", // use this if you're trying to snipe Pinksale tokens - "KIND_OF_SWAP": "base", // enter "base" to use BUYAMOUNTINBASE , and "tokens" to use BUYAMOUNTINTOKENS "BUYAMOUNTINBASE": "0.005", "BUYAMOUNTINTOKEN": "5", "MAX_BASE_AMOUNT_PER_EXACT_TOKENS_TRANSACTION": "0.5", // used with KIND_OF_SWAP = tokens + "SELLAMOUNTINTOKENS": "ALL", + "SELLPRICEINBASE": "300%", // You can now put amount in % in this field "STOPLOSSPRICEINBASE": "40%", // You can now put amount in % in this field "SLIPPAGE": "49", "MOONBAG": "0", // Bot will keep this amount in your wallet after SELL order - "MAXTOKENS": "10", // Bot will stop if your balance > MAXTOKENS + "MAXTOKENS": "0.00001", // Bot will stop if your balance > MAXTOKENS "MAX_SUCCESS_TRANSACTIONS_IN_A_ROW": "2", "MAX_FAILED_TRANSACTIONS_IN_A_ROW": "2", @@ -28,17 +28,10 @@ "BUYCOUNT": "2", "ALWAYS_CHECK_BALANCE": "false", // use this if you want bot to check your token balance between each price check - "MINIMUM_LIQUIDITY_IN_DOLLARS": "1000", - - "LIQUIDITYINNATIVETOKEN": "true", - "USECUSTOMBASEPAIR": "false", - "BASESYMBOL": "BUSD", - "BASEADDRESS": "0xe9e7cea3dedca5984780bafc599bd69add087d56", - - "SELLAMOUNTINTOKENS": "0.00001", + "MINIMUM_LIQUIDITY_IN_DOLLARS": "1000", // minimum value of liquidity added to make the bot buy. Team recommend to put 1000 minimum - "HASFEES": "false", - "GAS": "BOOST", // Team recommend you to use BOOST here + "HASFEES": "false", // can be necessary if token has huge additional fees (like taxes...) for SELL + "GAS": "BOOST", // Value used for SELL transaction. Team recommend you to use BOOST here "MAX_GAS": "99999", // Put here the maximum of GAS you want to pay if you use BOOST. If GAS > MAX_GAS Tx won't be made "BOOSTPERCENT": "30", "GASLIMIT": "1000000", // Team recommend you to use 1000000 here