diff --git a/src/api/uniswap/actions/buildSwapUniswap.ts b/src/api/uniswap/actions/buildSwapUniswap.ts index c8f3cf0..d7080c4 100644 --- a/src/api/uniswap/actions/buildSwapUniswap.ts +++ b/src/api/uniswap/actions/buildSwapUniswap.ts @@ -115,7 +115,7 @@ export async function buildSwapUniswap( if (debug) console.log('::API::UNISWAP::BALANCE', Number(tokenABalance)) const allowanceAgent = await tokenAContract?.allowance( - swap.address, + walletAddress, agentAddress ) @@ -153,37 +153,9 @@ export async function buildSwapUniswap( if (debug) console.log('::API::UNISWAP::FOUND_ALLOWANCE_SENDER_AGENT') } - // Transfer tokens from Sender to Agent - // ---------------------------------------------------------------------------- - // ---------------------------------------------------------------------------- - - const dataTransferFromSenderToAgent = - tokenAContract.interface.encodeFunctionData('transferFrom', [ - swap.address, - agentAddress, - adjAmount, - ]) - - const transferFromSenderToAgent = { - to: tokenAAddress, - value: 0, - data: dataTransferFromSenderToAgent, - } - - if (transferFromSenderToAgent) - if (debug) console.log('::API::UNISWAP::BUILD_TRANSFER_FROM_SENDER_AGENT') - - Calldatas.push(transferFromSenderToAgent) - // Encode Swap tx to Uni Router // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- - // const quote = await quotePair( - // tokenAAddress, - // tokenBAddress, - // Number(swap.chainId) - // ); - // const slippageTolerance = swap.slippage; const currency = { address: tokenBAddress, @@ -199,8 +171,6 @@ export async function buildSwapUniswap( name: await tokenAContract.name(), } - console.log(currency, currencyAmount) - const bestRoute = await route({ chainId: Number(137), recipient: agentAddress, @@ -211,8 +181,6 @@ export async function buildSwapUniswap( slippage: swaps[0].slippage, }) - console.log(bestRoute) - const swapMultiAgentToRouter = { to: bestRoute.methodParameters.to, value: bestRoute.methodParameters.value, @@ -221,7 +189,7 @@ export async function buildSwapUniswap( const allowanceAgentToUniversalRouter = await tokenAContract?.allowance( agentAddress, - bestRoute.methodParameters.to + uniRouter ) if (adjAmount.gt(allowanceAgentToUniversalRouter)) { @@ -230,7 +198,7 @@ export async function buildSwapUniswap( const calldataApproveAgentToRouter = tokenAContract.interface.encodeFunctionData('approve', [ - bestRoute.methodParameters.to, + uniRouter, ethers.constants.MaxUint256, ]) @@ -240,49 +208,47 @@ export async function buildSwapUniswap( data: calldataApproveAgentToRouter, } - ApprovalsAgent.push(approvalAgentToRouter) + Calldatas.push(approvalAgentToRouter) } else { if (debug) console.log('::API::UNISWAP::FOUND_ALLOWANCE_AGENT_UNIVERSAL_ROUTER') } - const allowanceAgentToUniversalRouter2 = await tokenAContract?.allowance( - uniRouter, - bestRoute.methodParameters.to - ) - - if (adjAmount.gt(allowanceAgentToUniversalRouter2)) { - if (debug) - console.log('::API::UNISWAP::MISSING_ALLOWANCE_AGENT_UNI_ROUTER') + for (let i = 0; i < bestRoute.route.length; i++) { + bestRoute.route[i].tokenPath.forEach(token => + tokensSet.add(token.address) + ) + } - const calldataApproveAgentToRouter2 = - tokenAContract.interface.encodeFunctionData('approve', [ - uniRouter, - ethers.constants.MaxUint256, - ]) + // Transfer tokens from Sender to Agent + // ---------------------------------------------------------------------------- + // ---------------------------------------------------------------------------- - const approvalAgentToRouter2 = { - to: tokenAAddress, - value: 0, - data: calldataApproveAgentToRouter2, - } + const dataTransferFromSenderToAgent = + tokenAContract.interface.encodeFunctionData('transferFrom', [ + walletAddress, + agentAddress, + adjAmount.add(BigNumber.from(100)), + ]) - ApprovalsAgent.push(approvalAgentToRouter2) - } else { - if (debug) console.log('::API::UNISWAP::FOUND_ALLOWANCE_AGENT_UNI_ROUTER') + const transferFromSenderToAgent = { + to: tokenAAddress, + value: 0, + data: dataTransferFromSenderToAgent, } - for (let i = 0; i < bestRoute.route.length; i++) { - bestRoute.route[i].tokenPath.forEach(token => - tokensSet.add(token.address) - ) + if (transferFromSenderToAgent) { + if (debug) console.log('::API::UNISWAP::BUILD_TRANSFER_FROM_SENDER_AGENT') + + Calldatas.push(transferFromSenderToAgent) } - if (swapMultiAgentToRouter) + if (swapMultiAgentToRouter) { if (debug) console.log('::API::UNISWAP::BUILD_AGENT_EXACT_INPUT_TO_UNIROUTER') - Calldatas.push(swapMultiAgentToRouter) + Calldatas.push(swapMultiAgentToRouter) + } } TokensReturn = Array.from(tokensSet) diff --git a/src/api/utils/uniswap/bestQuote.ts b/src/api/utils/uniswap/bestQuote.ts index 377ca72..2ef7504 100644 --- a/src/api/utils/uniswap/bestQuote.ts +++ b/src/api/utils/uniswap/bestQuote.ts @@ -97,7 +97,7 @@ async function isSwapPossible( async function getPoolData(poolContract, minRequiredLiquidity) { const slot0 = await poolContract.slot0() - const currentSqrtPriceX96 = slot0.sqrtPriceX96 + //const currentSqrtPriceX96 = slot0.sqrtPriceX96 const currentTick = slot0.tick const tickSpacing = await poolContract.tickSpacing() const desiredTickLower = currentTick - (currentTick % tickSpacing) @@ -264,7 +264,7 @@ export async function getBestQuote( const tokenAContract = new Contract(tokenAAddress, erc20Abi, wallet) const tokenADecimals = await tokenAContract.decimals() const tokenBAddress = reverse ? token0 : token1 - const adjAmount = getAdjAmount(amount, tokenADecimals) + const adjAmount = getAdjAmount(Number(amount).toPrecision(18), tokenADecimals) const bestQuote = await getBestQuoteForSwapPath( factoryContract, @@ -301,7 +301,7 @@ interface TradeRequest { export async function route(tradeRequest: TradeRequest) { console.log('::API::UNISWAP::ROUTE') - const router = new AlphaRouter({ + const alphaRouter = new AlphaRouter({ chainId: tradeRequest.chainId, provider: new ethers.providers.JsonRpcProvider( NETWORKS[tradeRequest.chainId] @@ -312,12 +312,12 @@ export async function route(tradeRequest: TradeRequest) { tradeRequest.currencyAmount, tradeRequest.chainId ) + const currency = parseToken(tradeRequest.currency, tradeRequest.chainId) - const formatedSlippage = tradeRequest.slippage / 100 // 5000/100 = 50 - const SLIPPAGE = new Percent(formatedSlippage, 10_000) // Correct 15% + const SLIPPAGE = new Percent(tradeRequest.slippage, 10_000) - const routing = router.route( + const routing = alphaRouter.route( CurrencyAmount.fromRawAmount(currencyAmount, Number(tradeRequest.amount)), currency, TradeType.EXACT_INPUT, @@ -329,8 +329,8 @@ export async function route(tradeRequest: TradeRequest) { //deadlineOrPreviousBlockhash: Math.floor(Date.now() / 1000) + 360, }, { - distributionPercent: 2, - maxSplits: 3, + distributionPercent: 5, + maxSplits: 2, protocols: [Protocol.V3, Protocol.V2, Protocol.MIXED], } ) diff --git a/src/core/strategies/loops/dca/price-based/config.json b/src/core/strategies/loops/dca/price-based/config.json index 4963218..55f4297 100644 --- a/src/core/strategies/loops/dca/price-based/config.json +++ b/src/core/strategies/loops/dca/price-based/config.json @@ -3,5 +3,5 @@ "SELECTED_CHAINID": 137, "FROMADDRESS": "0x0d500b1d8e8ef31e21c99d1db9a6444d3adf1270", "TOADDRESS": "0xb33eaad8d922b1083446dc23f610c2567fb5180f", - "SLIPPAGE": 1000 + "SLIPPAGE": 500 } diff --git a/src/core/strategies/loops/dca/price-based/main.ts b/src/core/strategies/loops/dca/price-based/main.ts index dd2a760..e56f136 100644 --- a/src/core/strategies/loops/dca/price-based/main.ts +++ b/src/core/strategies/loops/dca/price-based/main.ts @@ -20,7 +20,7 @@ let transactionHistory: { buyPrice: number; amount: BigNumber }[] = [] let startPrice: number | null = null let lastPriceStep: number | null = null const priceThresholdPercentage = 0.01 // Define the percentage threshold (e.g., 1%) -const forceInitialInvestment = true // Flag to force initial investment +let forceInitialInvestment = true // Flag to force initial investment // 🔍 Function to get the initial price const getInitialPrice = async () => { @@ -91,7 +91,6 @@ const initializeDCA = async () => { _tokenBalance, } } - const calculateInvestment = ( myBalance, CurrentETHPrice, @@ -100,44 +99,38 @@ const calculateInvestment = ( thirdStep, forceInitialInvestment ) => { - let amountIn: BigNumber + let amountIn: Number if (forceInitialInvestment) { - amountIn = myBalance.balance.div(20) // Or any initial investment logic you prefer - console.log( - `📊 Initial Step: Investing ${formatUnits(amountIn)} ${myBalance.symbol}` - ) + amountIn = Number(myBalance.formatted) / 20 + + console.log(`📊 Initial Step: Investing ${amountIn} `) + forceInitialInvestment = false } else if (CurrentETHPrice >= secondStep && CurrentETHPrice <= firstStep) { if (lastPriceStep !== firstStep) { - amountIn = myBalance.balance.div(20) + amountIn = Number(myBalance.formatted) / 20 lastPriceStep = firstStep - console.log( - `📊 First Step: Investing ${formatUnits(amountIn)} ${myBalance.symbol}` - ) + console.log(`📊 First Step: Investing ${amountIn} `) } else { - amountIn = BigNumber.from(0) + amountIn = 0 } } else if (CurrentETHPrice >= thirdStep && CurrentETHPrice <= secondStep) { if (lastPriceStep !== secondStep) { - amountIn = myBalance.balance.div(10) + amountIn = Number(myBalance.formatted) / 10 lastPriceStep = secondStep - console.log( - `📊 Second Step: Investing ${formatUnits(amountIn)} ${myBalance.symbol}` - ) + console.log(`📊 Second Step: Investing ${amountIn} `) } else { - amountIn = BigNumber.from(0) + amountIn = 0 } } else if (CurrentETHPrice < thirdStep) { if (lastPriceStep !== thirdStep) { - amountIn = myBalance.balance.div(5) + amountIn = Number(myBalance.formatted) / 5 lastPriceStep = thirdStep - console.log( - `📊 Third Step: Investing ${formatUnits(amountIn)} ${myBalance.symbol}` - ) + console.log(`📊 Third Step: Investing ${amountIn} `) } else { - amountIn = BigNumber.from(0) + amountIn = 0 } } else { - amountIn = BigNumber.from(0) + amountIn = 0 } return amountIn @@ -150,15 +143,15 @@ const executeSwapAndRecordTransaction = async ( toTokenMetadata, CurrentETHPrice ) => { - if (amountIn.eq(BigNumber.from(0))) { + await checkAndSellIfProfitable() + + if (amountIn === 0) { console.log('🚫 No action required, skipping...') return } console.log( - `💱 Executing swap: ${formatUnits(amountIn)} ${ - fromTokenMetadata.symbol - } to ${toTokenMetadata.symbol} at price ${CurrentETHPrice}` + `💱 Executing swap: ${amountIn} ${fromTokenMetadata.symbol} to ${toTokenMetadata.symbol} at price ${CurrentETHPrice}` ) await batchSwap([ @@ -169,23 +162,22 @@ const executeSwapAndRecordTransaction = async ( reverse: false, protocol: config.SELECTED_PROTOCOL, chainId: config.SELECTED_CHAINID, - amount: formatUnits(amountIn, toTokenMetadata.decimals), + amount: String(amountIn), // Ensure correct format slippage: config.SLIPPAGE, }, ]) transactionHistory.push({ buyPrice: CurrentETHPrice, - amount: amountIn, + amount: ethers.utils.parseUnits( + amountIn.toString(), + fromTokenMetadata.decimals + ), // Store as BigNumber }) console.log( - `📝 Transaction recorded: Bought at ${CurrentETHPrice}, Amount: ${formatUnits( - amountIn - )}` + `📝 Transaction recorded: Bought at ${CurrentETHPrice}, Amount: ${amountIn}` ) - - await checkAndSellIfProfitable() } const executeDCA = async (forceInitialInvestment = false) => { @@ -211,9 +203,9 @@ const executeDCA = async (forceInitialInvestment = false) => { const myBalance = _tokenBalance - const firstStep = startPrice * 0.998 - const secondStep = startPrice * 0.95 - const thirdStep = startPrice * 0.9 + const firstStep = startPrice! * 0.998 + const secondStep = startPrice! * 0.95 + const thirdStep = startPrice! * 0.9 console.log(`Current Price: ${CurrentETHPrice}, Start Price: ${startPrice}`) console.log( @@ -229,17 +221,6 @@ const executeDCA = async (forceInitialInvestment = false) => { forceInitialInvestment ) - console.log( - 'My Balance:', - formatUnits(String(myBalance.balance), fromTokenMetadata.decimals), - fromTokenMetadata.symbol - ) - console.log( - 'Investment Amount:', - formatUnits(amountIn, fromTokenMetadata.decimals), - fromTokenMetadata.symbol - ) - await executeSwapAndRecordTransaction( amountIn, dexWallet, @@ -257,7 +238,6 @@ const executeDCA = async (forceInitialInvestment = false) => { } } -// 🧮 Function to calculate profit const calculateProfit = async () => { const dexWallet = await initializeWallet( String(NETWORKS[config.SELECTED_CHAINID]) @@ -280,13 +260,16 @@ const calculateProfit = async () => { .catch(console.log) const currentPrice = parseFloat(ETHdata) + console.log(`Current ETH Price: ${currentPrice}`) let totalProfit = 0 transactionHistory.forEach(tx => { - const profit = - (currentPrice - tx.buyPrice) * - parseFloat(ethers.utils.formatEther(tx.amount)) + const amountInEther = ethers.utils.parseEther(String(tx.amount)) + const profit = (currentPrice - tx.buyPrice) * Number(amountInEther) totalProfit += profit + console.log( + `Transaction: Buy Price: ${tx.buyPrice}, Amount: ${amountInEther}, Current Price: ${currentPrice}, Profit: ${profit}` + ) }) console.log(`💹 Calculated total profit: ${totalProfit}`)