Executor

Description:

Smart contract deployed on Ethereum.

Blockchain: Ethereum

Source Code: View Code On The Blockchain

Solidity Source Code:

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


interface IERC20 {
    function balanceOf(address account) external view returns (uint256);

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

    function decimals() external view returns (uint8);
}

interface IERC20Bytes32 {
    function symbol() external view returns (bytes32);

    function decimals() external view returns (uint8);
}

interface IFactory {
    function getExchange(address token) external view returns (address);

    function getPair(address token0, address token1) external view returns (address);
}

interface IV3Pool {
    function slot0()
    external
    view
    returns (
        uint160 sqrtPriceX96,
        int24 tick,
        uint16 observationIndex,
        uint16 observationCardinality,
        uint16 observationCardinalityNext,
        uint8 feeProtocol,
        bool unlocked
    );
}

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

interface IPair {
    function getReserves()
    external
    view
    returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
}


interface V4_IStateView {
    function getSlot0(bytes32 poolId) external view returns (
        uint160 sqrtPriceX96,
        int24 tick,
        uint24 protocolFee,
        uint24 lpFee
    );

    function getBalances(bytes32 poolId) external view returns (
        uint256 token0Balance,
        uint256 token1Balance
    );
}


contract Executor {
    address public owner;
    address public UNISWAP_Factory_V1;
    address public UNISWAP_Factory_V2;
    address public UNISWAP_Factory_V3;
    address public UNISWAP_StateView_V4;

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

    function setFactoryV1(address _v1) external onlyOwner {
        UNISWAP_Factory_V1 = _v1;
    }

    function setFactoryV2(address _v2) external onlyOwner {
        UNISWAP_Factory_V2 = _v2;
    }

    function setFactoryV3(address _v3) external onlyOwner {
        UNISWAP_Factory_V3 = _v3;
    }

    function setStateViewV4(address _v4) external onlyOwner {
        UNISWAP_StateView_V4 = _v4;
    }

    struct TokenInfo {
        string token0_symbol;
        uint8 token0_decimals;
        string token1_symbol;
        uint8 token1_decimals;
    }

    // uniswap V1 pool info (ETH balance + token balance)
    struct Uniswapv1Info {
        address token0_pair;
        uint256 token0_ethBalance;
        uint256 token0_tokenBalance;
        address token1_pair;
        uint256 token1_ethBalance;
        uint256 token1_tokenBalance;
    }


    struct Uniswapv2Info {
        address pair;
        uint112 reserve0;
        uint112 reserve1;
        uint32 blockTimestampLast;
    }

    struct PoolInfo {
        uint24 fee;
        address pool;
        uint256 token0Balance;
        uint256 token1Balance;
        uint160 sqrtPriceX96;  // from slot0
        int24 tick;            // from slot0
    }


    struct Uniswapv4Info {
        bytes32 poolId;
        uint24 fee;
        uint160 sqrtPriceX96;
        int24 tick;
        uint24 protocolFee;
        uint24 lpFee;
 
    }

    struct AllResults {
        TokenInfo tokenInfo;
        Uniswapv1Info Uniswap_v1_Info;
        Uniswapv2Info Uniswap_v2_Info;
        PoolInfo[] Uniswap_v3_Info;
        Uniswapv4Info[] Uniswap_v4_Info;
    }

    struct Slot0Data {
        uint160 sqrtPriceX96;
        int24 tick;
        uint24 protocolFee;
        uint24 lpFee;
    }

    constructor() {
        owner = msg.sender;
    }


    function getV3Pools(address token0, address token1) public view returns (PoolInfo[] memory pools){
        uint24[4] memory fees = [uint24(100), uint24(500), uint24(3000), uint24(10000)];
        pools = new PoolInfo[](fees.length);
        for (uint i = 0; i < fees.length; i++) {
            address poolAddr = IFactoryV3(UNISWAP_Factory_V3).getPool(token0, token1, fees[i]);

            if (poolAddr != address(0)) {


                (
                    uint160 sqrtPriceX96,
                    int24 tick,
                    ,
                    ,
                    ,
                    ,
                ) = IV3Pool(poolAddr).slot0();


                pools[i] = PoolInfo({
                    fee: fees[i],
                    pool: poolAddr,
                    token0Balance: poolAddr != address(0) ? IERC20(token0).balanceOf(poolAddr) : 0,
                    token1Balance: poolAddr != address(0) ? IERC20(token1).balanceOf(poolAddr) : 0,
                    sqrtPriceX96: sqrtPriceX96,
                    tick: tick
                });
            }

        }
    }


    function callGetExchangeAndBalances(address token0, address token1, uint24[] calldata fees, int24[] calldata tickSpacings) external view returns (

        AllResults memory results
//        TokenInfo memory tokenInfo,
//        Uniswapv1Info memory Get_Uniswap_v1_Info,
//        Uniswapv2Info memory Get_Uniswap_v2_Info,
//        PoolInfo[] memory Get_Uniswap_v3_Info,
//        Uniswapv4Info[] memory Get_Uniswap_v4_Info

    )
    {
        // token0
        results.tokenInfo.token0_symbol = _getSymbol(token0);
        results.tokenInfo.token0_decimals = _getDecimals(token0);

        // token1
        results.tokenInfo.token1_symbol = _getSymbol(token1);
        results.tokenInfo.token1_decimals = _getDecimals(token1);


        results.Uniswap_v1_Info = Uniswapv1Info({
            token0_pair: address(0),
            token0_ethBalance: 0,
            token0_tokenBalance: 0,
            token1_pair: address(0),
            token1_ethBalance: 0,
            token1_tokenBalance: 0
        });

        results.Uniswap_v2_Info = Uniswapv2Info({
            pair: address(0),
            reserve0: 0,
            reserve1: 0,
            blockTimestampLast: 0
        });


        results.Uniswap_v3_Info = new PoolInfo[](4);

        results.Uniswap_v4_Info = new Uniswapv4Info[](fees.length);


        if (UNISWAP_Factory_V1 != address(0)) {
            address pair0 = IFactory(UNISWAP_Factory_V1).getExchange(token0);
            address pair1 = IFactory(UNISWAP_Factory_V1).getExchange(token1);
            results.Uniswap_v1_Info = Uniswapv1Info({
                token0_pair: pair0,
                token0_ethBalance: pair0 != address(0) ? address(pair0).balance : 0,
                token0_tokenBalance: pair0 != address(0) ? IERC20(token0).balanceOf(pair0) : 0,
                token1_pair: pair1,
                token1_ethBalance: pair1 != address(0) ? address(pair1).balance : 0,
                token1_tokenBalance: pair1 != address(0) ? IERC20(token1).balanceOf(pair1) : 0
            });
        }


        if (UNISWAP_Factory_V2 != address(0)) {

            address token_pair = IFactory(UNISWAP_Factory_V2).getPair(token0, token1);

            if (token_pair != address(0)) {
                // Only query reserves if the pair exists
                (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast) = IPair(token_pair).getReserves();
                results.Uniswap_v2_Info = Uniswapv2Info({
                    pair: token_pair,
                    reserve0: reserve0,
                    reserve1: reserve1,
                    blockTimestampLast: blockTimestampLast
                });
            }
        }


        if (UNISWAP_Factory_V3 != address(0)) {
            results.Uniswap_v3_Info = getV3Pools(token0, token1);
        }


        if (UNISWAP_StateView_V4 != address(0) && fees.length > 0) {

            require(fees.length == tickSpacings.length, "Array length mismatch");
            require(fees.length > 0, "No fee tiers provided");

            V4_IStateView stateView = V4_IStateView(UNISWAP_StateView_V4);


            results.Uniswap_v4_Info = new Uniswapv4Info[](fees.length);


            for (uint i = 0; i < fees.length; i++) {


                (address _token0, address _token1) = token0 < token1
                    ? (token0, token1)
                    : (token1, token0);

                bytes32 poolId = keccak256(abi.encode(_token0, _token1, fees[i], tickSpacings[i], address(0)));

                Slot0Data memory s;
                (s.sqrtPriceX96, s.tick, s.protocolFee, s.lpFee) = stateView.getSlot0(poolId);


                results.Uniswap_v4_Info [i] = Uniswapv4Info({
                    poolId: poolId,
                    fee: fees[i],
                    sqrtPriceX96: s.sqrtPriceX96,
                    tick: s.tick,
                    protocolFee: s.protocolFee,
                    lpFee: s.lpFee
                });


            }


        }


    }


    function _getSymbol(address token) internal view returns (string memory) {
        try IERC20(token).symbol() returns (string memory sym) {
            return sym;
        } catch {
            try IERC20Bytes32(token).symbol() returns (bytes32 symBytes) {
                return string(abi.encodePacked(symBytes));
            } catch {
                return "";
            }
        }
    }

    function _getDecimals(address token) internal view returns (uint8) {
        try IERC20(token).decimals() returns (uint8 dec) {
            return dec;
        } catch {
            return 0;
        }
    }


}

Tags:
addr:0x608b00c2bc7a1e9a3c9f10e7285f2d3fb7be2fd1|verified:true|block:23405775|tx:0xe70d9d420a6a95d2c82202b6749731ec938ad5ff1bce45d4afa7b5e076e32b92|first_check:1758393062

Submitted on: 2025-09-20 20:31:04

Comments

Log in to comment.

No comments yet.