Untitled

 avatar
unknown
plain_text
18 days ago
3.9 kB
3
Indexable
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

interface IUniswapV2Pair {
    function factory() external view returns (address);
    function token0() external view returns (address);
    function token1() external view returns (address);
    function swap(
        uint amount0Out,
        uint amount1Out,
        address to,
        bytes calldata data
    ) external;
}

interface IUniswapV2Factory {
    function getPair(address tokenA, address tokenB) external view returns (address);
}

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

    function WETH() external view returns (address);
}

interface IERC20 {
    function approve(address spender, uint amount) external returns (bool);
    function transfer(address to, uint amount) external returns (bool);
    function transferFrom(address from, address to, uint amount) external returns (bool);
    function balanceOf(address account) external view returns (uint);
}

contract FlashSwapArbitrage {
    address public owner;

    IUniswapV2Factory public uniswapFactory;
    IUniswapV2Router public secondaryRouter; // e.g. SushiSwap

    address public WETH;

    modifier onlyOwner() {
        require(msg.sender == owner, "Not owner");
        _;
    }

    constructor(address _factory, address _router) {
        owner = msg.sender;
        uniswapFactory = IUniswapV2Factory(_factory);
        secondaryRouter = IUniswapV2Router(_router);
        WETH = secondaryRouter.WETH();
    }

    // This is the entry point for flash arbitrage
    function startArbitrage(
        address token0,
        address token1,
        uint amount0,
        uint amount1
    ) external onlyOwner {
        address pairAddress = uniswapFactory.getPair(token0, token1);
        require(pairAddress != address(0), "No pair found");

        IUniswapV2Pair(pairAddress).swap(
            amount0,
            amount1,
            address(this),
            abi.encode(token0, token1)
        );
    }

    // Callback function for Uniswap V2 flash swap
    function uniswapV2Call(
        address sender,
        uint amount0,
        uint amount1,
        bytes calldata data
    ) external {
        require(sender == address(this), "Unauthorized");

        (address tokenBorrow, address tokenPayback) = abi.decode(data, (address, address));
        address ;
        path[0] = tokenBorrow;
        path[1] = tokenPayback;

        uint amountReceived = amount0 > 0 ? amount0 : amount1;

        IERC20(tokenBorrow).approve(address(secondaryRouter), amountReceived);

        // Swap borrowed token on another DEX
        uint[] memory result = secondaryRouter.swapExactTokensForTokens(
            amountReceived,
            1, // No slippage control for simplicity
            path,
            address(this),
            block.timestamp
        );

        uint amountOut = result[result.length - 1];

        // Calculate amount to repay (with 0.3% fee)
        uint fee = ((amountReceived * 3) / 997) + 1;
        uint amountToRepay = amountReceived + fee;

        require(amountOut > amountToRepay, "No profit");

        // Repay Uniswap pair
        IERC20(tokenPayback).transfer(msg.sender, amountToRepay);

        // Send profit to owner
        uint profit = amountOut - amountToRepay;
        IERC20(tokenPayback).transfer(owner, profit);
    }

    function withdrawToken(address token) external onlyOwner {
        uint bal = IERC20(token).balanceOf(address(this));
        require(bal > 0, "Zero balance");
        IERC20(token).transfer(owner, bal);
    }
}
Editor is loading...
Leave a Comment