1

I am trying to perform multiple transactions where I call executeMultitrading and it uses ETH to buy TokenX, then sell TokenX for ETh, then use ETH to buy Token X, then Sell TokenX for ETH.

when i deploy and fund my fund my contract with Eth, I run run the executeMultitrading function with the parameters address tokenAddress, uint256 tradeAmount where tokenAddress is the address of TokenX. But when i do this i get an error Returned error: {"jsonrpc":"2.0","error":"execution reverted",

Can anyone see if i'm doing anything wrong?

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "./contracts/token/ERC20/IERC20.sol";
import "./contracts/interfaces/IUniswapV2Router02.sol";

contract MultiTrading {

    address private constant UNISWAP_ROUTER_ADDRESS =
        0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;

    uint256 private constant TRADE_COUNT = 2; // Number of trades to execute

    IUniswapV2Router02 private uniswapRouter;
    IERC20 private token;
    address private owner;
    event ETHReceived(address sender, uint256 amount);

    modifier onlyOwner() {
        require(
            msg.sender == owner,
            "Only the contract owner can call this function"
        );
        _;
    }

    constructor() {
        uniswapRouter = IUniswapV2Router02(UNISWAP_ROUTER_ADDRESS);
        owner = msg.sender;
    }

    function executeMultitrading(address tokenAddress, uint256 tradeAmount) external onlyOwner {
        token = IERC20(tokenAddress);
        // Approve token for buy and sell trades
        _approveTokenForBuyTrade(tokenAddress, tradeAmount);
        // Check if the token approval was successful
        require(_checkTokenApproval(tokenAddress, address(uniswapRouter), tradeAmount), "Token approval failed");

        // Perform buy and sell trades on Uniswap
        for (uint256 i = 0; i < TRADE_COUNT; i++) {
            // Perform buy trade on Uniswap
            bool buyTradeSuccess = _performBuyTrade(tokenAddress, tradeAmount);
            require(buyTradeSuccess, "Buy trade failed");

            // Perform sell trade on Uniswap
            bool sellTradeSuccess = _performSellTrade(tokenAddress, tradeAmount);
            require(sellTradeSuccess, "Sell trade failed");
        }
    }


    function _approveTokenForBuyTrade(address tokenAddress, uint256 tradeAmount) private {
        IERC20(tokenAddress).approve(address(uniswapRouter), tradeAmount);
    }

    function _approveTokenForSellTrade(address tokenAddress, uint256 tradeAmount) private {
        IERC20(tokenAddress).approve(address(uniswapRouter), tradeAmount);
    }


    function _performBuyTrade(address tokenAddress, uint256 tradeAmount) private returns (bool) {
        // Calculate the amount of ETH required for the trade
        uint256[] memory amounts = uniswapRouter.getAmountsIn(
            tradeAmount,
            getPathForETHToToken(tokenAddress)
        );
        uint256 ethAmount = amounts[0];

        // Swap ETH for the token on Uniswap
        address[] memory path = getPathForETHToToken(tokenAddress);
        _swap(ethAmount, path);

        // Assuming the swap was successful, you can return true
        return true;
    }

    function _performSellTrade(address tokenAddress, uint256 tradeAmount) private returns (bool) {
        // Calculate the amount of token required for the trade
        uint256[] memory amounts = uniswapRouter.getAmountsOut(
            tradeAmount,
            getPathForTokenToETH(tokenAddress)
        );
        uint256 tokenAmount = amounts[1];

        // Swap the token for ETH on Uniswap
        address[] memory path = getPathForTokenToETH(tokenAddress);
        _swap(tokenAmount, path);
        return true;
    }


    function _swap(uint256 amountIn, address[] memory path) private {

        // Approve the spending of tokens on Uniswap
        IERC20(path[0]).approve(address(uniswapRouter), amountIn);

        uniswapRouter.swapExactTokensForTokensSupportingFeeOnTransferTokens(
            amountIn,
            0,
            path,
            address(this),
            block.timestamp
        );
    }

    function getPathForETHToToken(address tokenAddress) private view returns (address[] memory) {
        address[] memory path = new address[](2);
        path[0] = uniswapRouter.WETH();
        path[1] = tokenAddress;
        return path;
    }

    function getPathForTokenToETH(address tokenAddress) private view returns (address[] memory) {
        address[] memory path = new address[](2);
        path[0] = tokenAddress;
        path[1] = uniswapRouter.WETH();
        return path;
    }

    function withdrawETH() external onlyOwner {
        uint256 balance = address(this).balance;
        payable(owner).transfer(balance);
    }

    receive() external payable {
        emit ETHReceived(msg.sender, msg.value);
    }

    function view_balance() external view returns (uint256) {
        return address(this).balance;
    }

   function _checkTokenApproval(address tokenAddress, address spender, uint256 tradeAmount) private view returns (bool) {
       IERC20 token = IERC20(tokenAddress);
       uint256 allowance = token.allowance(msg.sender, spender);
       return allowance >= tradeAmount;
    }

}
Mikko Ohtamaa
  • 82,057
  • 50
  • 264
  • 435
RedRum
  • 902
  • 1
  • 13
  • 26

1 Answers1

0

I am trying to perform multiple transactions where I call executeMultitrading and it uses ETH to buy TokenX, then sell TokenX for ETh, then use ETH to buy Token X, then Sell TokenX for ETH.

These are not multiple transactions, but multiple smart contract calls. By definition, all Solidity code must run in a single transaction. Ethereum transaction is a record in a blockchain block with transaction hash.

But when i do this i get an error Returned error {"jsonrpc":"2.0","error":"execution reverted",

Because the question does not contain a repeatable code example with enough context, it is not possible to tell what you are doing wrong.

You can debug transctions using commercial freemium transaction debuggers like Tenderly.co to inspect the stack trace of your Ethereum transaction and figure out yourself what you are doing wrong. You need to have your transaction hash on a public network as an input, and also have your smart contract source code verified on Etherscan.

Mikko Ohtamaa
  • 82,057
  • 50
  • 264
  • 435