Created
July 31, 2024 06:33
-
-
Save korrio/fa93de855aff6236dcaeb39697a913e0 to your computer and use it in GitHub Desktop.
bot.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const ethers = require('ethers'); | |
const { ChainId, Token, Fetcher, Route, Trade, TokenAmount, TradeType, Percent } = require('@uniswap/sdk'); | |
const { abi: IUniswapV2PairABI } = require('@uniswap/v2-core/build/IUniswapV2Pair.json'); | |
const { abi: IUniswapV2Router02ABI } = require('@uniswap/v2-periphery/build/IUniswapV2Router02.json'); | |
// Configuration | |
const ALCHEMY_URL = 'https://eth-mainnet.g.alchemy.com/v2/jssjArgnoSmS2Uv5RMVwQAySLhkBsOnJ'; | |
//const ALCHEMY_URL_TESTNET = 'https://eth-sepolia.g.alchemy.com/v2/jssjArgnoSmS2Uv5RMVwQAySLhkBsOnJ'; | |
const DAI_ADDRESS = '0x6B175474E89094C44Da98b954EedeAC495271d0F'; | |
const WETH_ADDRESS = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'; | |
const UNISWAP_ROUTER_ADDRESS = '0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D'; | |
const SUSHISWAP_ROUTER_ADDRESS = '0xd9e1cE17f2641f24aE83637ab66a2cca9C378B9F'; | |
const ARBITRAGE_THRESHOLD = 1; // 1% price difference | |
const AMOUNT_ETH = '1'; // Amount of ETH to check for arbitrage | |
// Create provider | |
let provider; | |
try { | |
provider = new ethers.providers.JsonRpcProvider(ALCHEMY_URL); | |
} catch (error) { | |
console.error('Failed to create provider:', error); | |
process.exit(1); | |
} | |
// สร้าง wallet จาก private key | |
const privateKey = '562b89ec5422eb55a52be67dd5d26e93a4c3c9a33cb55158c03d97e82dab40c3'; // อย่าใช้ private key ของ wallet หลัก! | |
const wallet = new ethers.Wallet(privateKey, provider); | |
console.log('Wallet address:', wallet.address); | |
// ตรวจสอบยอดคงเหลือ | |
async function checkBalance() { | |
const balance = await provider.getBalance(wallet.address); | |
console.log('Wallet balance:', ethers.utils.formatEther(balance), 'ETH'); | |
} | |
checkBalance(); | |
// Create token instances | |
const DAI = new Token(ChainId.MAINNET, DAI_ADDRESS, 18); | |
const WETH = new Token(ChainId.MAINNET, WETH_ADDRESS, 18); | |
// DEX configurations | |
// Create router instances | |
const uniswapRouter = new ethers.Contract(UNISWAP_ROUTER_ADDRESS, IUniswapV2Router02ABI, provider); | |
const sushiswapRouter = new ethers.Contract(SUSHISWAP_ROUTER_ADDRESS, IUniswapV2Router02ABI, provider); | |
async function getPriceOnDEX(router, tokenIn, tokenOut, amount) { | |
try { | |
const amounts = await router.getAmountsOut(amount,[tokenIn.address, tokenOut.address]); | |
return amounts[1]; | |
} catch (error) { | |
console.error(`Error getting price on DEX: ${error.message}`); | |
return null; | |
} | |
} | |
async function checkArbitragePossibility() { | |
try { | |
const amount = ethers.utils.parseEther(AMOUNT_ETH); | |
console.log('Fetching prices...'); | |
const uniswapPrice = await getPriceOnDEX(uniswapRouter, WETH, DAI, amount); | |
const sushiswapPrice = await getPriceOnDEX(sushiswapRouter, WETH, DAI, amount); | |
if (!uniswapPrice || !sushiswapPrice) { | |
console.log("Failed to fetch prices from one or both DEXes. Retrying in 5 seconds..."); | |
setTimeout(checkArbitragePossibility, 5000); | |
return; | |
} | |
console.log(`Uniswap price: 1 WETH = ${ethers.utils.formatUnits(uniswapPrice, 18)} DAI`); | |
console.log(`Sushiswap price: 1 WETH = ${ethers.utils.formatUnits(sushiswapPrice, 18)} DAI`); | |
const priceDifference = uniswapPrice.gt(sushiswapPrice) ? uniswapPrice.sub(sushiswapPrice) | |
: sushiswapPrice.sub(uniswapPrice); | |
const priceDifferencePercent = priceDifference.mul(10000).div(uniswapPrice); | |
console.log(`Price difference: ${priceDifferencePercent.toNumber() / 100}%`); | |
if (priceDifferencePercent.gte(ethers.BigNumber.from(ARBITRAGE_THRESHOLD * 100))) { | |
console.log('Arbitrage opportunity found!'); | |
if (uniswapPrice.gt(sushiswapPrice)) { | |
console.log("Buy on Sushiswap, sell on Uniswap"); | |
await simulateArbitrage(sushiswapRouter, uniswapRouter, amount); | |
} else { | |
console.log("Buy on Uniswap, sell on Sushiswap"); | |
await simulateArbitrage(uniswapRouter, sushiswapRouter, amount); | |
} | |
} else { | |
console.log("No significant arbitrage opportunity at the moment"); | |
} | |
// Schedule next check | |
console.log("Scheduling next check in 1 minute..."); | |
setTimeout(checkArbitragePossibility, 60000); | |
} catch (error) { | |
console.error("Error checking arbitrage possibility:", error); | |
console.log("Retrying in 5 seconds..."); | |
setTimeout(checkArbitragePossibility, 5000); | |
} | |
} | |
async function simulateArbitrage(buyRouter, sellRouter, amount) { | |
try { | |
console.log('Simulating arbitrage...'); | |
// Simulate buy | |
const buyAmount = await getPriceOnDEX(buyRouter, WETH, DAI, amount); | |
if (!buyAmount) { | |
console.log('Failed to simulate buy. Aborting arbitrage simulation.'); | |
return; | |
} | |
console.log(`Buying ${ethers.utils.formatUnits(buyAmount, 18)} DAI for ${AMOUNT_ETH} WETH`); | |
// Simulate sell | |
const sellAmount = await getPriceOnDEX(sellRouter, DAI, WETH, buyAmount); | |
if (!sellAmount) { | |
console.log('Failed to simulate sell. Aborting arbitrage simulation.'); | |
return; | |
} | |
console.log(`Selling DAI for ${ethers.utils.formatUnits(sellAmount, 18)} WETH`); | |
// Calculate profit | |
const profit = sellAmount.sub(amount); | |
console.log(`Estimated profit: ${ethers.utils.formatUnits(profit, 18)} WETH`); | |
if (profit.gt(0)) { | |
console.log('Profitable arbitrage opportunity!'); | |
// Here you would implement the actual trading logic | |
// This would involve calling the swap functions on the router contracts | |
// You'd also need to handle approvals, gas fees, and slippage tolerance | |
} else { | |
console.log('Arbitrage not profitable after considering potential fees.'); | |
} | |
} catch (error) { | |
console.error("Error simulating arbitrage:", error); | |
} | |
} | |
// Start the arbitrage checking process | |
console.log('Starting arbitrage bot...'); | |
checkArbitragePossibility(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment