const HttpKit = require('../../kit/http-kit.js') const Config = require('../../config/config.js') const PrivateConfig = require('../../PrivateConfig.js') const SimpleWeb3 = require("./simple-web3"); const chainID = 56 const rpc = 'https://bsc-dataseed1.binance.org' class DoDo {} DoDo.price = async function(sellToken = '0xe9e7cea3dedca5984780bafc599bd69add087d56', sellTokenDecimals = 18, sellAmount = 100, buyToken = '0xba2ae424d960c26247dd6c32edc70b295c744c43', slippagePercentage = 0.03, affiliateAddress = '0x221d5c4993297Fd95fA17743b9297E2e49FCe9D2') { sellAmount = sellAmount * (10 ** sellTokenDecimals) const url = `https://bsc.api.0x.org/swap/v1/quote?sellToken=${sellToken}&sellAmount=${sellAmount}&buyToken=${buyToken}` + `&slippagePercentage=${slippagePercentage}&affiliateAddress=${affiliateAddress}` const { data: rst } = await HttpKit.get(url) if (!rst || !rst.price) { return rst } if (sellToken === '0xe9e7cea3dedca5984780bafc599bd69add087d56') { return 1 / parseFloat(rst.price) } else { parseFloat(rst.price) } } DoDo.buildSwapTx = async function(fromTokenAddress = '0xe9e7cea3dedca5984780bafc599bd69add087d56', fromTokenDecimals = 18, toTokenAddress = '0x111111111117dc0aa78b770fa6a738034120c302', toTokenDecimals = 18, amount = 100, userAddr = PrivateConfig.address, slippage = 1) { amount = amount * (10 ** fromTokenDecimals) const url = `https://dodo-route.dodoex.io/dodoapi/getdodoroute?fromTokenAddress=${fromTokenAddress}&fromTokenDecimals=${fromTokenDecimals}` + `&toTokenAddress=${toTokenAddress}&toTokenDecimals=${toTokenDecimals}&fromAmount=${amount}&userAddr=${userAddr}` + `&slippage=${slippage}&chainId=${chainID}&rpc=${rpc}` const { data: rst } = await HttpKit.get(url, { 'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4464.0 Safari/537.36 Edg/91.0.852.0' }) return rst } DoDo.swap = async function(txObject) { const txCount = await SimpleWeb3.web3.eth.getTransactionCount(PrivateConfig.address) txObject.nonce = SimpleWeb3.web3.utils.toHex(txCount) txObject.gasPrice = SimpleWeb3.web3.utils.toHex(txObject.gasPrice) txObject.gas = SimpleWeb3.web3.utils.toHex(txObject.gas) txObject.gasLimit = SimpleWeb3.web3.utils.toHex(txObject.gasLimit) await SimpleWeb3.sendTransaction(txObject) } DoDo.Start = async function(toToken) { while (true) { // 如果BNB连续变化maxRefreshBNBTimes次,则1INCH或其他交易所可能已经出bug。 if (Config.refreshBNBTimes >= Config.maxRefreshBNBTimes) { console.log(`机器人判定交易所可能出了bug,失败次数:${Config.refreshBNBTimes},为保护BNB,已停止交易。`) break } try { const tokenSymbol = toToken.symbol const baseToken = Config.baseToken if (!baseToken.balance) { await MyKit.sleep(1000) continue } const binancePairSymbol = tokenSymbol + baseToken.symbol const amount = Config.baseTokenAmount < baseToken.balance ? Config.baseTokenAmount : baseToken.balance const profitLimit = toToken.profitLimit ? toToken.profitLimit : Config.profitLimit const binancePrice = await bs.price(binancePairSymbol) // 一次判断 let time = MyKit.getTimeByMillisecond(new Date().getTime()) // 直接判断并抢单 const DoDoSwapRst = await DoDo.swap(baseToken.contract, baseToken.decimals, toToken.contract, toToken.decimals, amount) // 对询价结果容错 if (!DoDoSwapRst || !DoDoSwapRst.data) { continue } // 构建交易包 const swapRST = DoDoSwapRst.data swapRST.price = MyKit._N(swapRST.resPricePerToToken, 6) swapRST.tx = { gasPrice: 7 * (10 ** 9), gas: '500000', from: PrivateConfig.address, to: swapRST.to, data: swapRST.data } // 间距百分比与预估利润 distance = MyKit._N(100 * ((binancePrice / swapRST.price - 1.001)), 4) profit = MyKit._N(amount * distance / 100 - Config.charge, 4) // debug if (Config.debug) { console.log(`[${time}, ${binancePairSymbol}] D价格: ${swapRST.price},C价格: ${binancePrice},利润:${profit},源:${swapRST.useSource}。`) } // 屏蔽询价源 if (Config.limitSources.indexOf(swapRST.useSource) !== -1 || !swapRST.useSource) { continue } if (swapRST.price && !baseToken.isSwap && profit > Config.profitLimit) { if (distance > 20) { console.log('[利润大于20%]手续费*1.5执行抢单逻辑.') swapRST.tx.gasPrice = parseInt((parseInt(swapRST.tx.gasPrice) * 1.5)) + '' } console.log(`[${time}, ${tokenSymbol}]判定通过, 利润率:${distance}%, 预估利润:${profit}${baseToken.symbol}, 目标利润:${Config.profitLimit}${baseToken.symbol}.\n`) console.log(`DEFI价格: ${swapRST.price}, CEFI价格: ${binancePrice}, 报价源: ${swapRST.useSource}\n\n`) await wallet.transferByTXDoDo(swapRST.tx) } // else if (profit > 0) { // console.log(`[${time}, ${tokenSymbol}]二次判定不通过, 利润率:${distance}%, 预估利润:${profit}${baseToken.symbol}, 目标利润:${profitLimit}${baseToken.symbol}.\n`) // console.log(`DEFI价格: ${swapRST.price}, CEFI价格: ${binancePrice}, 报价源: ${swapRST.useSource}\n\n`) // } } catch (e) { console.log(e) } await MyKit.sleep(Config.delay) } } module.exports = DoDo