dexaggregator

Description:

Decentralized Finance (DeFi) protocol contract providing Mintable, Burnable, Swap, Liquidity, Factory functionality.

Blockchain: Ethereum

Source Code: View Code On The Blockchain

Solidity Source Code:

{{
  "language": "Solidity",
  "sources": {
    "contracts/swapv3agg.sol": {
      "content": "
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;
pragma abicoder v2;

library SafeCast {
    function toUint160(uint256 y) internal pure returns (uint160 z) {
        require((z = uint160(y)) == y);
    }

    function toInt128(int256 y) internal pure returns (int128 z) {
        require((z = int128(y)) == y);
    }

    function toInt256(uint256 y) internal pure returns (int256 z) {
        require(y < 2**255);
        z = int256(y);
    }
}

abstract contract ReentrancyGuard {
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and make it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;

        _;

        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
}


interface IPancakePair {
    event Approval(
        address indexed owner,
        address indexed spender,
        uint256 value
    );
    event Transfer(address indexed from, address indexed to, uint256 value);

    function name() external pure returns (string memory);

    function symbol() external pure returns (string memory);

    function decimals() external pure returns (uint8);

    function totalSupply() external view returns (uint256);

    function balanceOf(address owner) external view returns (uint256);

    function allowance(address owner, address spender)
        external
        view
        returns (uint256);

    function approve(address spender, uint256 value) external returns (bool);

    function transfer(address to, uint256 value) external returns (bool);

    function transferFrom(
        address from,
        address to,
        uint256 value
    ) external returns (bool);

    function DOMAIN_SEPARATOR() external view returns (bytes32);

    function PERMIT_TYPEHASH() external pure returns (bytes32);

    function nonces(address owner) external view returns (uint256);

    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    event Mint(address indexed sender, uint256 amount0, uint256 amount1);
    event Burn(
        address indexed sender,
        uint256 amount0,
        uint256 amount1,
        address indexed to
    );
    event Swap(
        address indexed sender,
        uint256 amount0In,
        uint256 amount1In,
        uint256 amount0Out,
        uint256 amount1Out,
        address indexed to
    );
    event Sync(uint112 reserve0, uint112 reserve1);

    function MINIMUM_LIQUIDITY() external pure returns (uint256);

    function factory() external view returns (address);

    function token0() external view returns (address);

    function token1() external view returns (address);

    function getReserves()
        external
        view
        returns (
            uint112 reserve0,
            uint112 reserve1,
            uint32 blockTimestampLast
        );

    function price0CumulativeLast() external view returns (uint256);

    function price1CumulativeLast() external view returns (uint256);

    function kLast() external view returns (uint256);

    function mint(address to) external returns (uint256 liquidity);

    function burn(address to)
        external
        returns (uint256 amount0, uint256 amount1);

    function swap(
        uint256 amount0Out,
        uint256 amount1Out,
        address to,
        bytes calldata data
    ) external;

    function skim(address to) external;

    function sync() external;

    function initialize(address, address) external;
}

interface IPancakeRouter02 {
    function factory() external pure returns (address);
    function WETH() external pure returns (address);

    function getAmountsOut(
        uint amountIn,
        address[] calldata path
    ) external view returns (uint[] memory amounts);

    function swapExactTokensForTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external returns (uint[] memory amounts);
}


library TransferHelper {
    function safeApprove(
        address token,
        address to,
        uint256 value
    ) internal {
        // bytes4(keccak256(bytes('approve(address,uint256)')));
        (bool success, bytes memory data) = token.call(
            abi.encodeWithSelector(0x095ea7b3, to, value)
        );
        require(
            success && (data.length == 0 || abi.decode(data, (bool))),
            "TransferHelper: APPROVE_FAILED"
        );
    }

    function safeTransfer(
        address token,
        address to,
        uint256 value
    ) internal {
        // bytes4(keccak256(bytes('transfer(address,uint256)')));
        (bool success, bytes memory data) = token.call(
            abi.encodeWithSelector(0xa9059cbb, to, value)
        );
        require(
            success && (data.length == 0 || abi.decode(data, (bool))),
            "TransferHelper: TRANSFER_FAILED"
        );
    }

    function safeTransferFrom(
        address token,
        address from,
        address to,
        uint256 value
    ) internal {
        // bytes4(keccak256(bytes('transferFrom(address,address,uint256)')));
        (bool success, bytes memory data) = token.call(
            abi.encodeWithSelector(0x23b872dd, from, to, value)
        );
        require(
            success && (data.length == 0 || abi.decode(data, (bool))),
            "TransferHelper: TRANSFER_FROM_FAILED"
        );
    }

    function safeTransferETH(address to, uint256 value) internal {
        (bool success, ) = to.call{value: value}(new bytes(0));
        require(success, "TransferHelper: ETH_TRANSFER_FAILED");
    }
}
    interface ISwapRouterQuick {
      struct ExactInputSingleParams {
        address tokenIn;
        address tokenOut;
        address recipient;
        uint256 deadline;
        uint256 amountIn;
        uint256 amountOutMinimum;
        uint160 limitSqrtPrice;
       }
         function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut);

    }

interface IERC20 {
    event Approval(
        address indexed owner,
        address indexed spender,
        uint256 value
    );
    event Transfer(address indexed from, address indexed to, uint256 value);

    function name() external view returns (string memory);

    function symbol() external view returns (string memory);

    function decimals() external view returns (uint8);

    function totalSupply() external view returns (uint256);

    function balanceOf(address owner) external view returns (uint256);

    function allowance(address owner, address spender)
        external
        view
        returns (uint256);

    function approve(address spender, uint256 value) external returns (bool);

    function transfer(address to, uint256 value) external returns (bool);

    function transferFrom(
        address from,
        address to,
        uint256 value
    ) external returns (bool);
}

library SafeMath {
    function add(uint256 x, uint256 y) internal pure returns (uint256 z) {
        require((z = x + y) >= x, "ds-math-add-overflow");
    }

    function sub(uint256 x, uint256 y) internal pure returns (uint256 z) {
        require((z = x - y) <= x, "ds-math-sub-underflow");
    }

    function mul(uint256 x, uint256 y) internal pure returns (uint256 z) {
        require(y == 0 || (z = x * y) / y == x, "ds-math-mul-overflow");
    }
}

interface IWETH {
    function deposit() external payable;

    function transfer(address to, uint256 value) external returns (bool);

    function withdraw(uint256) external;
}


interface IUniswapV3Pool {
    function token0() external returns (address);

    function token1() external returns (address);

    function swap(
        address recipient,
        bool zeroForOne,
        int256 amountSpecified,
        uint160 sqrtPriceLimitX96,
        bytes calldata data
    ) external returns (int256 amount0, int256 amount1);
}


interface ISwapUniRouter {
    struct ExactInputSingleParams {
        address tokenIn;
        address tokenOut;
        uint24 fee;
        address recipient;
        uint256 amountIn;
        uint256 amountOutMinimum;
        uint160 sqrtPriceLimitX96;
    }

    function exactInputSingle(ExactInputSingleParams calldata params)
        external
        payable
        returns (uint256 amountOut);

    struct ExactInputParams {
        bytes path;
        address recipient;
        uint256 amountIn;
        uint256 amountOutMinimum;
    }

    function exactInput(ExactInputParams calldata params)
        external
        payable
        returns (uint256 amountOut);

    function factory() external view returns (address);    

   }

interface ISwapRouter {
    struct ExactInputSingleParams {
        address tokenIn;
        address tokenOut;
        uint24 fee;
        address recipient;
        uint256 deadline;
        uint256 amountIn;
        uint256 amountOutMinimum;
        uint160 sqrtPriceLimitX96;
    }

    function exactInputSingle(ExactInputSingleParams calldata params)
        external
        payable
        returns (uint256 amountOut);

    struct ExactInputParams {
        bytes path;
        address recipient;
        uint256 deadline;
        uint256 amountIn;
        uint256 amountOutMinimum;
    }

    function exactInput(ExactInputParams calldata params)
        external
        payable
        returns (uint256 amountOut);

    function factory() external view returns (address);    

   }



interface IUniswapV3Factory {
    function getPool(
        address tokenA, 
        address tokenB, 
        uint24 fee
    ) external view returns (address);

    function createPool(
        address tokenA, 
        address tokenB, 
        uint24 fee
    ) external returns (address pool);

    function owner() external view returns (address);

    function feeAmountTickSpacing(uint24 fee) external view returns (int24);

    function setOwner(address _owner) external;

    function enableFeeAmount(uint24 fee, int24 tickSpacing) external;
}

contract dexaggregator is ReentrancyGuard {
    using SafeMath for uint256;
    using SafeCast for uint256;

    address public WETH;
    address public owneraddress;
    uint256 public Fee;
    address public operator;
    address Zero = 0x0000000000000000000000000000000000000000;
    uint256 hundred = 100000000000000000000;
    uint256 impact = 500000000000000000;
    address public constant coinAddressApi = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;

    struct ExactInputSingleParams {
        address tokenIn;
        address tokenOut;
        uint24 fee;
        address recipient;
        uint256 deadline;
        uint256 amountIn;
        uint256 amountOutMinimum;
        uint160 sqrtPriceLimitX96;
    }

    struct userdetails {
        address userAddress;
        address sellToken;
        address buyToken;
        uint256 amount;
        uint256 timeStamp;
        bool status;
    }

    struct _stableFee{
        uint256 fee;
    }
    
    struct ExactInputParams {
        bytes path;
        address recipient;
        uint256 deadline;
        uint256 amountIn;
        uint256 amountOutMinimum;
    }

    struct _Pair { 
        address[] pairAddress ;
        uint256 command;
        address token0;
        address token1;
        uint256 amountIn;
        uint256 amountOut;
        uint256 to;
        uint24[] fee;
        uint256 deadline;
        uint256 types;
        address router;
    }
    
    struct call_v2{
        uint256[]  amounts;
        address[]  path;
        address[]  pair;
        uint24[]  fee;
    } 
    
    struct _handleFinalTransfer{
        address user;
        address tk0;
        address finalToken;
        uint256 amount;
        bool coinStatus;
    }

    struct call_v3{
       address[]  pairAddress;
       address tokenIn;
       address tokenOut;
       uint24[]  poolFee;
       uint256 amountIn;
       uint256 amountOut;
       address router;
       uint256 types;
    }
    
    

    modifier onlyContractOwner() {
        require(msg.sender == owneraddress, "onlyOwner");
        _;
    }

    modifier controlOrder() {
        require(
            msg.sender == owneraddress || msg.sender == operator,
            "onlyOwner or operator"
        );
        _;
    }

 

    modifier ensure(uint256 deadline) {
        require(deadline >= block.timestamp, "AggregateRouter: EXPIRED");
        _;
    }

    receive() external payable {
        assert(msg.sender == WETH);
    }

    constructor(
        address _WETH,
        address _Owner,
        uint256 _fee,
        address _operator
    ) {
        WETH = _WETH;
        owneraddress = _Owner;
        Fee = _fee;
        operator = _operator;
    }
    
    mapping(address =>mapping(address =>_stableFee)) private  stableFee;
    mapping(address => mapping(uint256 => userdetails))  private _userdetails;


    userdetails[] internal _users;

    event  EstRecive(uint256 estimateRecive, uint256  estimateFee);

    function getAmountOut(
        uint256 amountIn,
        uint256 reserveIn,
        uint256 reserveOut,
        uint256 fee
    ) internal pure returns (uint256 amountOut) {
        require(amountIn > 0, "PancakeLibrary: INSUFFICIENT_INPUT_AMOUNT");
        require(
            reserveIn > 0 && reserveOut > 0,
            "PancakeLibrary: INSUFFICIENT_LIQUIDITY"
        );

        uint256 amountInWithFee = amountIn * (10000 - fee); 
        uint256 numerator = amountInWithFee * reserveOut;
        uint256 denominator = reserveIn * 10000 + amountInWithFee;
        amountOut = numerator / denominator;
    }

    function sortTokens(address tokenA, address tokenB)
        internal
        pure
        returns (address token0, address token1)
    {
        require(tokenA != tokenB, "PancakeLibrary: IDENTICAL_ADDRESSES");
        (token0, token1) = tokenA < tokenB
            ? (tokenA, tokenB)
            : (tokenB, tokenA);
        require(token0 != address(0), "PancakeLibrary: ZERO_ADDRESS");
    }

    function getStableFee(address[2] memory _address) public view returns (uint256){
         uint256 showFee = stableFee[_address[0]][_address[1]].fee > 0?stableFee[_address[0]][_address[1]].fee:
         stableFee[_address[1]][_address[0]].fee > 0?stableFee[_address[1]][_address[0]].fee:Fee;
         return showFee;
    }
     
    function changeStablefee(address[2] memory _address, uint256 setFee) public controlOrder{
        stableFee[_address[0]][_address[1]].fee = setFee;
    }

    function getAmountOut(
        uint256 amountIn,
        uint256 reserveIn,
        uint256 reserveOut
    ) internal pure returns (uint256 amountOut) {
        require(amountIn > 0, "PancakeLibrary: INSUFFICIENT_INPUT_AMOUNT");
        require(
            reserveIn > 0 && reserveOut > 0,
            "PancakeLibrary: INSUFFICIENT_LIQUIDITY"
        );
        uint256 amountInWithFee = amountIn.mul(9975);
        uint256 numerator = amountInWithFee.mul(reserveOut);
        uint256 denominator = reserveIn.mul(10000).add(amountInWithFee);
        amountOut = numerator / denominator;
    }

    function addLimitOrder(
        address buy,
        address sell,
        uint256 amount,
        uint256 _timeStamp
    ) external payable virtual ensure(_timeStamp) {
        require(amount > 0, "It's not valied");
            userdetails storage details = _userdetails[msg.sender][_timeStamp];
            require(details.userAddress == address(0), "Order already exists for this user");
            
        if (sell == WETH) {
            require(msg.value >= amount, "insufficient amount");
        } else {
            TransferHelper.safeTransferFrom(
                sell,
                msg.sender,
                address(this),
                amount
            );
        }
            details.userAddress = msg.sender;
            details.buyToken = buy;
            details.sellToken = sell;
            details.amount = amount;
            details.timeStamp = _timeStamp;
            details.status = true;
           _users.push(details);    
    }

   function _cancelledOrder(
        address buy,
        address sell,
        uint256 _timeStamp,
        address _userAddress
    ) external controlOrder {
        userdetails storage details = _userdetails[_userAddress][_timeStamp];
        require(
            details.buyToken == buy && details.sellToken == sell,
            "this not correct way"
        );
        // require(msg.sender == details.userAddress);
        if (sell == WETH) {
            TransferHelper.safeTransferETH(details.userAddress, details.amount);
        } else {
            TransferHelper.safeTransfer(
                details.sellToken,
                details.userAddress,
                details.amount
            );
        }
        details.status  = false;
        delete _userdetails[_userAddress][_timeStamp];
    }


    event _cancelOrder(address buy , address sell ,address userAddress ,uint256 _timeStamp );

    function LimitOrderCancelled(
        address buy,
        address sell,
        uint256 _timeStamp
    ) external {
        userdetails storage details = _userdetails[msg.sender][_timeStamp];
        require(
            details.buyToken == buy && details.sellToken == sell,
            "this not correct way"
        );
        require(msg.sender == details.userAddress);
        if (sell == WETH) {
            TransferHelper.safeTransferETH(details.userAddress, details.amount);
        } else {
            TransferHelper.safeTransfer(
                details.sellToken,
                details.userAddress,
                details.amount
            );
        }
        emit _cancelOrder(details.buyToken, details.sellToken, details.userAddress, _timeStamp);
        details.status  = false;
        delete _userdetails[msg.sender][_timeStamp];

    }

      function getUser(address userAddress) external view returns (userdetails[] memory) {
      uint256 count;
      for (uint256 i = 0; i < _users.length; i++) {
        if (
            _users[i].userAddress == userAddress && 
            _users[i].status == true 
        ) {
            userdetails storage details = _userdetails[_users[i].userAddress][_users[i].timeStamp];
            if (details.userAddress != address(0)) {
                count++;
            }
        }
    }
    userdetails[] memory userArr = new userdetails[](count);
    uint256 index = 0;

    for (uint256 i = 0; i < _users.length; i++) {
        if (
            _users[i].userAddress == userAddress && 
            _users[i].status == true 
        ) {
            userdetails storage details = _userdetails[_users[i].userAddress][_users[i].timeStamp];
            if (details.userAddress != address(0)) {
                userArr[index] = _users[i];
                index++;
            }
        }
    }

    return userArr;
    }

    function getFeeAndTransferUser(address userAddress,address tokenA,address tokenB,uint256 amountsOut,uint256 status)internal{
        uint256 exeFee = stableFee[tokenA][tokenB].fee > 0?stableFee[tokenA][tokenB].fee:
         stableFee[tokenB][tokenA].fee > 0?stableFee[tokenB][tokenA].fee:Fee;
        uint256 _fee = (exeFee * amountsOut) / hundred;
        uint256 amountToSendToUser = amountsOut > _fee? amountsOut - _fee: _fee - amountsOut;
        if(tokenB == WETH && status == 1){
        TransferHelper.safeTransferETH(
            userAddress,
            amountToSendToUser
        );
        if(_fee > 0){
         TransferHelper.safeTransferETH(
            owneraddress,
            _fee
         );
        }
        emit EstRecive(amountToSendToUser, _fee);
        }else{
            TransferHelper.safeTransfer(
                                tokenB,
                                userAddress,
                                amountToSendToUser
            );
        if(_fee > 0){
            TransferHelper.safeTransfer(
                                tokenB,
                                owneraddress,
                                _fee
            );
        }
       emit EstRecive(amountToSendToUser, _fee);
        }
    }


    function multiSwap(
        _Pair[] memory pairs,
        uint256 _amountIn,
        uint256 minOut,
        bool coinStatus
    ) external payable virtual ensure(pairs[0].deadline) {
        address tk0 = pairs[0].token0;

    if (tk0 == WETH || tk0 == address(uint160(coinAddressApi))) {
        if (msg.value > 0) {
            require(msg.value == _amountIn, "ETH amount mismatch");
            IWETH(WETH).deposit{value: msg.value}();
        } else {
            TransferHelper.safeTransferFrom(tk0, msg.sender, address(this), _amountIn);
        }
    } else {
        TransferHelper.safeTransferFrom(tk0, msg.sender, address(this), _amountIn);
    }
        for (uint256 i = 0; i < pairs.length; i++) {
            require(pairs[i].pairAddress[pairs[i].pairAddress.length -1] != address(0) || pairs[i].command == 1, "INVALID_PATH");
           
            uint256 inputAmount =  i == 0 ?  pairs[i].amountIn : 
            pairs[i].amountIn < IERC20(pairs[i].token0).balanceOf(address(this))? pairs[i].amountIn:IERC20(pairs[i].token0).balanceOf(address(this));

            if (pairs[i].command == 0) {
                // V2 Swap
             uint256[] memory amounts = new uint256[](2);
                address[] memory _tokens = new address[](2);
                _tokens[0] = pairs[i].token0;
                _tokens[1] = pairs[i].token1;
                amounts[0] = inputAmount;
                amounts[1] = pairs[i].amountOut;
                
                
                   call_v2 memory call_v2Params = call_v2({
                    amounts:amounts,
                    path: _tokens,
                    pair:pairs[i].pairAddress,
                    fee:pairs[i].fee});
                    swapv2(call_v2Params);


            } else {
                // V3 Swap
                require(pairs[i].amountIn > 0, "Invalid swap amount");
                

                swapv3(call_v3({
                  pairAddress: pairs[i].pairAddress,
                  tokenIn: pairs[i].token0,
                  tokenOut: pairs[i].token1,
                  poolFee: pairs[i].fee,
                  amountIn: inputAmount,
                  amountOut: pairs[i].amountOut,
                  router: pairs[i].router,
                  types : pairs[i].types
               }));

            }
                if (i == pairs.length - 1) {
                 _handleFinalTransfer memory transferData = _handleFinalTransfer({
                      user: msg.sender,
                      tk0: tk0,
                      finalToken:  pairs[i].token1,
                      amount: minOut,
                      coinStatus: coinStatus
                 });      
                    handleFinalTransfer(transferData);
                }
        }
    }

    function handleFinalTransfer(
         _handleFinalTransfer memory _datas
    ) internal {
        if (_datas.finalToken == WETH || _datas.finalToken == address(uint160(coinAddressApi))) {
            if (_datas.coinStatus) {
                uint256 wethBalance = IERC20(WETH).balanceOf(address(this));
                require(wethBalance >= _datas.amount, "Insufficient WETH balance");
                IWETH(WETH).withdraw(wethBalance);
                getFeeAndTransferUser(_datas.user, _datas.tk0, WETH, wethBalance, 1);
            } else {
                require(IERC20(_datas.finalToken).balanceOf(address(this)) >= _datas.amount, "Insufficient User receive balance");
                getFeeAndTransferUser(_datas.user, _datas.tk0, _datas.finalToken, IERC20(_datas.finalToken).balanceOf(address(this)), 0);
            }
        } else {
            require(IERC20(_datas.finalToken).balanceOf(address(this)) >= _datas.amount, "Insufficient User receive balance");
            getFeeAndTransferUser(_datas.user, _datas.tk0, _datas.finalToken, IERC20(_datas.finalToken).balanceOf(address(this)), 0);
        }
    }

    function swapv2(
       call_v2 memory datas
    ) internal {
      require(datas.amounts.length > 0 && datas.path.length > 0, "Invalid input arrays v2");
      require(datas.amounts[0] > 0, "Invalid input amount v2");
        if (datas.path[0] == WETH || datas.path[0] == address(uint160(coinAddressApi))) {
          require(IERC20(WETH).balanceOf(address(this)) >= datas.amounts[0], "Insufficient WETH balance v2");
          IWETH(WETH).transfer(datas.pair[0], datas.amounts[0]);
        } else {
          require(IERC20(datas.path[0]).balanceOf(address(this)) >= datas.amounts[0], "Insufficient token balance v2");
          TransferHelper.safeTransfer(datas.path[0], datas.pair[0], datas.amounts[0]);
        }
        address middleToken;
        uint256 amountOut;

        for (uint256 i; i < datas.pair.length; i++) 
        {

               address  _token0 = IPancakePair(datas.pair[i]).token0();
               address  _token1 = IPancakePair(datas.pair[i]).token1();

               (uint reserve0, uint reserve1, ) = IPancakePair(datas.pair[i]).getReserves();
            
               uint256 reserveIn = i == 0 ?datas.path[i] == _token0 ? reserve0 : reserve1:middleToken == _token0 ? reserve0 : reserve1;
               uint256 reserveOut = i == 0 ?datas.path[i] == _token0 ? reserve1 : reserve0:middleToken == _token0 ? reserve1 : reserve0;
               amountOut = getAmountOut(i == 0 ? datas.amounts[0] : amountOut, reserveIn, reserveOut,datas.fee[i]);
               address to = i < datas.pair.length - 1 ? datas.pair[i+1] : address(this);

               (uint amount0Out, uint amount1Out) = i == 0?  datas.path[i] == _token0 ? (uint(0), amountOut) 
                 : (amountOut, uint(0)): middleToken == _token0 ? (uint(0), amountOut) 
                 : (amountOut, uint(0));
                   middleToken = datas.path[i] == _token0 ? _token1: _token0;
                   IPancakePair(datas.pair[i]).swap(amount0Out, amount1Out, to, new bytes(0));
        }         
   }  
    
    //uinswapV3 swap code

    function swapv3(call_v3 memory swapData) internal {
     require(swapData.router != address(0), "Zero router address");
     require(swapData.tokenIn != address(0), "Zero tokenIn address");
     require(swapData.tokenOut != address(0), "Zero tokenOut address");
     require(swapData.amountIn > 0, "Zero amountIn");
     require(swapData.poolFee.length > 0, "No pool fee provided");

        if (swapData.pairAddress.length == 1) {
        if (swapData.types == 0) {
            _executeSwapV3(swapData);
        }else if(swapData.types == 2){
            _executeUniswapV3Swap(swapData);
        } else {
            _executeQuickSwapV3(swapData);
        }
      } else {
          if (swapData.types == 2) {
          _executeUniswapMultiHopSwap(swapData);
        }else if(swapData.types == 1){
         _executeMultiHopQuickSwap(swapData);
        }else{
          _executeMultiHopSwap(swapData);
        } 
      }
       if (swapData.tokenOut == address(uint160(coinAddressApi))) {
        require(address(this).balance >= swapData.amountOut, "Insufficient ETH for deposit");
        IWETH(WETH).deposit{value: swapData.amountOut}();
      }
   }
   
    function _executeMultiHopQuickSwap(call_v3 memory swapData) private {
        require(swapData.poolFee.length >= 2, "Insufficient pool fees MultiHop");
        ISwapRouter router = ISwapRouter(swapData.router);

          if (swapData.tokenIn != WETH && swapData.tokenIn != address(uint160(coinAddressApi))) {
            require(IERC20(swapData.tokenIn).balanceOf(address(this)) >= swapData.amountIn, "Insufficient tokenIn balance swapv3");
            IERC20(swapData.tokenIn).approve(address(router), swapData.amountIn);
         }
     
        address intermediateToken = swapData.tokenIn == IPancakePair(swapData.pairAddress[0]).token0() ? 
            IPancakePair(swapData.pairAddress[0]).token1() : 
            IPancakePair(swapData.pairAddress[0]).token0();
    
        bytes memory path = abi.encodePacked(
            swapData.tokenIn, 
            intermediateToken, 
            swapData.tokenOut
        );
    
        ISwapRouter.ExactInputParams memory params = ISwapRouter.ExactInputParams({
            path: path,
            recipient: address(this),
            deadline: block.timestamp + 300,
            amountIn: swapData.amountIn,
            amountOutMinimum: 0
        });
    
        if (swapData.tokenIn == WETH || swapData.tokenIn == address(uint160(coinAddressApi))) {
             require(IERC20(WETH).balanceOf(address(this)) >= swapData.amountIn, "Insufficient WETH balance v3");
          IWETH(WETH).withdraw(swapData.amountIn);
         require(address(this).balance >= swapData.amountIn, "Insufficient ETH balance v3");
            router.exactInput{value: swapData.amountIn}(params);
        } else {
            router.exactInput(params);
        }
    }

       function _executeMultiHopSwap(call_v3 memory swapData) private {
        require(swapData.poolFee.length >= 2, "Insufficient pool fees MultiHop");
    
        ISwapRouter router = ISwapRouter(swapData.router);

         if (swapData.tokenIn != WETH && swapData.tokenIn != address(uint160(coinAddressApi))) {
            require(IERC20(swapData.tokenIn).balanceOf(address(this)) >= swapData.amountIn, "Insufficient tokenIn balance swapv3");
            IERC20(swapData.tokenIn).approve(address(router), swapData.amountIn);
         }
    
        address intermediateToken = swapData.tokenIn == IPancakePair(swapData.pairAddress[0]).token0() ? 
            IPancakePair(swapData.pairAddress[0]).token1() : 
            IPancakePair(swapData.pairAddress[0]).token0();
    
        bytes memory path = abi.encodePacked(
            swapData.tokenIn, 
            swapData.poolFee[0], 
            intermediateToken, 
            swapData.poolFee[swapData.poolFee.length - 1], 
            swapData.tokenOut
        );
    
        ISwapRouter.ExactInputParams memory params = ISwapRouter.ExactInputParams({
            path: path,
            recipient: address(this),
            deadline: block.timestamp + 300,
            amountIn: swapData.amountIn,
            amountOutMinimum: 0
        });
    
        if (swapData.tokenIn == WETH || swapData.tokenIn == address(uint160(coinAddressApi))) {
             require(IERC20(WETH).balanceOf(address(this)) >= swapData.amountIn, "Insufficient WETH balance v3");
          IWETH(WETH).withdraw(swapData.amountIn);
         require(address(this).balance >= swapData.amountIn, "Insufficient ETH balance v3");
            router.exactInput{value: swapData.amountIn}(params);
        } else {
            router.exactInput(params);
        }
    }

     // Helper function for Uniswap V3 single swaps
     function _executeUniswapV3Swap(call_v3 memory swapData) private {
          ISwapUniRouter router = ISwapUniRouter(swapData.router);

        if (swapData.tokenIn != WETH && swapData.tokenIn != address(uint160(coinAddressApi))) {
            require(IERC20(swapData.tokenIn).balanceOf(address(this)) >= swapData.amountIn, "Insufficient tokenIn balance uni");
            IERC20(swapData.tokenIn).approve(address(router), swapData.amountIn);
         }
         
          ISwapUniRouter.ExactInputSingleParams memory params = ISwapUniRouter.ExactInputSingleParams({
                               tokenIn: swapData.tokenIn,
                               tokenOut: swapData.tokenOut,
                               fee: swapData.poolFee[0],
                               recipient: address(this),
                               amountIn: swapData.amountIn,
                               amountOutMinimum: 0,
                               sqrtPriceLimitX96: 0
                       });
      if (swapData.tokenIn != WETH && swapData.tokenIn != address(uint160(coinAddressApi))) {
          router.exactInputSingle(params);
      } else {
        require(IERC20(WETH).balanceOf(address(this)) >= swapData.amountIn, "Insufficient WETH balance uni");
        IWETH(WETH).withdraw(swapData.amountIn);
        require(address(this).balance >= swapData.amountIn, "Insufficient ETH balance uni");
        router.exactInputSingle{value: swapData.amountIn}(params);
    }
   }

    function _executeSwapV3(call_v3 memory swapData) private {
          ISwapRouter router = ISwapRouter(swapData.router);

        if (swapData.tokenIn != WETH && swapData.tokenIn != address(uint160(coinAddressApi))) {
            require(IERC20(swapData.tokenIn).balanceOf(address(this)) >= swapData.amountIn, "Insufficient tokenIn balance swapv3");
            IERC20(swapData.tokenIn).approve(address(router), swapData.amountIn);
         }
          ISwapRouter.ExactInputSingleParams memory params = ISwapRouter.ExactInputSingleParams({
                               tokenIn: swapData.tokenIn,
                               tokenOut: swapData.tokenOut,
                               fee: swapData.poolFee[0],
                               recipient: address(this),
                               deadline: block.timestamp +300,
                               amountIn: swapData.amountIn,
                               amountOutMinimum: 0,
                               sqrtPriceLimitX96: 0
                       });
      if (swapData.tokenIn != WETH && swapData.tokenIn != address(uint160(coinAddressApi))) {
          router.exactInputSingle(params);
      } else {
        require(IERC20(WETH).balanceOf(address(this)) >= swapData.amountIn, "Insufficient WETH balance swapv3");
        IWETH(WETH).withdraw(swapData.amountIn);
        require(address(this).balance >= swapData.amountIn, "Insufficient ETH balance swapv3");
        router.exactInputSingle{value: swapData.amountIn}(params);
    }
   }

     function _executeQuickSwapV3(call_v3 memory swapData) private {
        ISwapRouterQuick router = ISwapRouterQuick(swapData.router);
        
        if (swapData.tokenIn != WETH && swapData.tokenIn != address(uint160(coinAddressApi))) {
            uint256 balance = IERC20(swapData.tokenIn).balanceOf(address(this));
            require(balance >= swapData.amountIn, "Insufficient tokenIn balance quick");
            TransferHelper.safeApprove(swapData.tokenIn, address(router), swapData.amountIn);
        }
    
        ISwapRouterQuick.ExactInputSingleParams memory params = ISwapRouterQuick.ExactInputSingleParams({
            tokenIn: swapData.tokenIn,
            tokenOut: swapData.tokenOut,
            recipient: address(this),
            deadline: block.timestamp + 300,
            amountIn: swapData.amountIn,
            amountOutMinimum: 0,
            limitSqrtPrice: 0
        });
    
        if (swapData.tokenIn == WETH || swapData.tokenIn == address(uint160(coinAddressApi))) {
            require(IERC20(WETH).balanceOf(address(this)) >= swapData.amountIn, "Insufficient WETH balance quick");
            IWETH(WETH).withdraw(swapData.amountIn);
             require(address(this).balance >= swapData.amountIn, "Insufficient ETH balance quick");
            router.exactInputSingle{value: swapData.amountIn}(params);
        } else {
            router.exactInputSingle(params);
        }
    }
    
      function _executeUniswapMultiHopSwap(call_v3 memory swapData) private {
        require(swapData.poolFee.length >= 2, "Insufficient pool fees MultiHop");
        require(swapData.poolFee[0] > 0 && swapData.poolFee[swapData.poolFee.length - 1] > 0, "Invalid pool fees");
        ISwapUniRouter router = ISwapUniRouter(swapData.router);
        
        if (swapData.tokenIn != WETH && swapData.tokenIn != address(uint160(coinAddressApi))) {
            require(IERC20(swapData.tokenIn).balanceOf(address(this)) >= swapData.amountIn, "Insufficient tokenIn balance swapv3");
            IERC20(swapData.tokenIn).approve(address(router), swapData.amountIn);
         }
    
        address intermediateToken = swapData.tokenIn == IPancakePair(swapData.pairAddress[0]).token0() ? 
            IPancakePair(swapData.pairAddress[0]).token1() : 
            IPancakePair(swapData.pairAddress[0]).token0();
    
        bytes memory path = abi.encodePacked(
            swapData.tokenIn, 
            swapData.poolFee[0], 
            intermediateToken, 
            swapData.poolFee[swapData.poolFee.length - 1], 
            swapData.tokenOut
        );
    
        ISwapUniRouter.ExactInputParams memory params = ISwapUniRouter.ExactInputParams({
            path: path,
            recipient: address(this),
            amountIn: swapData.amountIn,
            amountOutMinimum: 0
        });
    
        if (swapData.tokenIn == WETH || swapData.tokenIn == address(uint160(coinAddressApi))) {
             require(IERC20(WETH).balanceOf(address(this)) >= swapData.amountIn, "Insufficient WETH balance MultiHop");
          IWETH(WETH).withdraw(swapData.amountIn);
         require(address(this).balance >= swapData.amountIn, "Insufficient ETH balance MultiHop");
            router.exactInput{value: swapData.amountIn}(params);
        } else {
            router.exactInput(params);
        }
    }

    function withdrawETH(address payable _to, uint256 _amount)
        public
        onlyContractOwner
        returns (uint256)
    {
        _to.transfer(_amount);
        return _amount;
    }

   function withdrawTokens(address _tokenAddress, uint256 _amount)
    public
    onlyContractOwner
   {
      require(IERC20(_tokenAddress).balanceOf(address(this)) >= _amount, "Insufficient balance");
      bool success = IERC20(_tokenAddress).transfer(msg.sender, _amount);
      require(success, "Token transfer failed");
    }

      
    function changeOperator(address _operator)public controlOrder{
        operator =_operator;
    }  

    function changeFee(uint256 _Fee)public controlOrder{
        Fee = _Fee;
    }

    function changeOwner(address _Owneraddress)public onlyContractOwner{
        owneraddress = _Owneraddress;
    }
}"
    }
  },
  "settings": {
    "optimizer": {
      "enabled": true,
      "runs": 200
    },
    "evmVersion": "paris",
    "outputSelection": {
      "*": {
        "*": [
          "evm.bytecode",
          "evm.deployedBytecode",
          "devdoc",
          "userdoc",
          "metadata",
          "abi"
        ]
      }
    }
  }
}}

Tags:
ERC20, DeFi, Mintable, Burnable, Swap, Liquidity, Factory|addr:0x0d1300ec4a25e742503b19a6b689470a0b36aac6|verified:true|block:23394800|tx:0xa03053550106223a58563da8d12cd8435c8e3c6037d251c688af5b41c0f9a416|first_check:1758277780

Submitted on: 2025-09-19 12:29:42

Comments

Log in to comment.

No comments yet.