const HttpKit = require('../kit/http-kit.js') const Config = require('../config/config.js') const PrivateConfig = require('../PrivateConfig.js') const SimpleWeb3 = require("./web3/simple-web3"); const chainID = 56 class OneInch {} OneInch.price = async function(fromTokenAddress = '0xe9e7cea3dedca5984780bafc599bd69add087d56', fromTokenDecimals = 18, amount = Config.baseTokenAmount, toTokenAddress = '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c') { fromTokenAddress = fromTokenAddress.toLowerCase() toTokenAddress = toTokenAddress.toLowerCase() amount = amount * (10 ** fromTokenDecimals) const url = `https://api.1inch.exchange/v3.0/${chainID}/quote?fromTokenAddress=${fromTokenAddress}&amount=${amount}` + `&toTokenAddress=${toTokenAddress}` const { data: rst } = await HttpKit.get(url) if (!rst || !rst.toToken || !rst.toTokenAmount) { return rst } const toTokenAmount = parseFloat(rst.toTokenAmount) / (10 ** rst.toToken.decimals) const fromTokenAmount = amount / (10 ** fromTokenDecimals) const price = fromTokenAmount / toTokenAmount rst.price = price Config.estimatedGas = rst.estimatedGas if (toTokenAddress.toLowerCase() === '0xe9e7cea3dedca5984780bafc599bd69add087d56') { rst.price = 1 / rst.price } return rst.price } OneInch.buildSwapTx = async function(fromTokenAddress = '0xe9e7cea3dedca5984780bafc599bd69add087d56', toTokenAddress = '0x111111111117dc0aa78b770fa6a738034120c302', fromTokenDecimals = 18, amount = 100, gas = Config.estimatedGas, fromAddress = PrivateConfig.address, slippage = 1) { amount = amount * (10 ** fromTokenDecimals) const url = `https://api.1inch.exchange/v3.0/${chainID}/swap?fromTokenAddress=${fromTokenAddress}&toTokenAddress=${toTokenAddress}` + `&amount=${amount}&fromAddress=${fromAddress}&slippage=${slippage}` 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' }) if (rst && rst.toToken && rst.fromToken) { const fromTokenAmount = parseFloat(rst.fromTokenAmount) / (10 ** rst.fromToken.decimals) const toTokenAmount = parseFloat(rst.toTokenAmount) / (10 ** rst.toToken.decimals) rst.price = fromTokenAmount / toTokenAmount } return rst } OneInch.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.gasPrice = '0x165a0bc00' txObject.gas = SimpleWeb3.web3.utils.toHex(txObject.gas) txObject.value = SimpleWeb3.web3.utils.toHex(txObject.value) await SimpleWeb3.sendTransaction(txObject) } OneInch.Start = async function(toToken) { while (true) { toToken.alive = 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 OneInchPrice = await OneInch.price(baseToken.contract, baseToken.decimals, amount, toToken.contract) const binancePrice = await bs.price(binancePairSymbol) let distance = MyKit._N(100 * ((binancePrice / OneInchPrice) - 1.001), 4) let profit = MyKit._N(amount * distance / 100 - Config.charge, 4) let time = MyKit.getTimeByMillisecond(new Date().getTime()) // debug if (Config.debug && profit > 0) { console.log(`[${time}, ${binancePairSymbol}] D价格: ${OneInchPrice},C价格: ${binancePrice},利润:${profit}。`) } // 一次判断 if (profit > Config.profitLimit) { // 二次判断,并获取交易tx const swapRST = await OneInch.swap(baseToken.contract, toToken.contract, baseToken.decimals, amount) if (!swapRST) { continue } distance = MyKit._N(100 * ((binancePrice / swapRST.price) - 1.001), 4) profit = MyKit._N(amount * distance / 100 - Config.charge, 4) if (!baseToken.isSwap && profit > Config.profitLimit) { time = MyKit.getTimeByMillisecond(new Date().getTime()) // gas容错 swapRST.tx.gas = parseInt((parseInt(swapRST.tx.gas) * 1.5)) + '' // 如果利润大于5%,手续费*2抢单 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}\n\n`) await wallet.transferByTX1Inch(swapRST.tx) } } await MyKit.sleep(5000) } catch (e) { console.log(e) } } } module.exports = OneInch