Skip to main content
PulseScanner.io

Address

0x1e9ac35b7d8ddffd2a4ebaf1628a8d8b2f2dbebe
Current Holdings
$0.00
TXs sent
not counted
First Active
2026-04-15
block 26,292,036
Last Active
154 days ago
block 26,292,036
Funded By
not identified

Net worth historyi

No net-worth snapshots recorded yet
exact matchPoolDetailsGettersolc 0.8.31+commit.fd3a2265runtime exact · creation exact
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {IV3PoolLike, IPool} from "./interfaces.sol";
import "@balancer-labs/v2-interfaces/contracts/vault/IVault.sol";
import "@uniswap/v2-core/contracts/interfaces/IUniswapV2ERC20.sol";
import "@uniswap/v2-core/contracts/interfaces/IUniswapV2Pair.sol";

interface IBalancerPoolWithId {
    function getPoolId() external view returns (bytes32);
}

contract PoolDetailsGetter {
    struct PoolData {
        address pairAddress;
        uint256[] balance;
        uint8[] decimals;
        address[] tokens;
        address factory;
        string poolType;
    }

    function getReserveData(
        address poolAddress,
        string memory poolType,
        address[] memory tokens
    )
        external
        view
        returns (uint8[] memory decimals, uint256[] memory reserves)
    {
        decimals = new uint8[](tokens.length);
        reserves = new uint256[](tokens.length);

        if (keccak256(bytes(poolType)) == keccak256(bytes("balancer-v2"))) {
            IVault vault = IPool(poolAddress).getVault();
            bytes32 poolId = IBalancerPoolWithId(poolAddress).getPoolId();

            for (uint256 i = 0; i < tokens.length; i++) {
                decimals[i] = IUniswapV2ERC20(tokens[i]).decimals();

                try vault.getPoolTokenInfo(poolId, IERC20(tokens[i])) returns (
                    uint256 cash,
                    uint256,
                    uint256,
                    address
                ) {
                    reserves[i] = cash;
                } catch {
                    revert("Failed to get balancer v2 balance");
                }
            }

            return (decimals, reserves);
        }

        for (uint256 i = 0; i < tokens.length; i++) {
            uint256 balance = IERC20(tokens[i]).balanceOf(poolAddress);
            uint8 decimal = IUniswapV2ERC20(tokens[i]).decimals();

            reserves[i] = balance;
            decimals[i] = decimal;
        }

        return (decimals, reserves);
    }

    function getPoolsBalance(
        address[] memory pools
    ) external view returns (PoolData[] memory results) {
        results = new PoolData[](pools.length);

        uint256 count;

        for (uint256 i = 0; i < pools.length; i++) {
            try this._getPoolType(pools[i]) returns (string memory poolType) {
                results[count].poolType = poolType;
            } catch {
                continue;
            }

            address[] memory poolTokens;
            try this.getPoolTokens(pools[i], results[count].poolType) returns (
                address[] memory tokens
            ) {
                poolTokens = tokens;
                results[count].tokens = tokens;
            } catch {
                continue;
            }

            // Safe balanceOf calls: if a token call reverts, skip this pool
            try
                this.getReserveData(
                    pools[i],
                    results[count].poolType,
                    poolTokens
                )
            returns (uint8[] memory decimals, uint256[] memory reserves) {
                results[count].balance = reserves;
                results[count].decimals = decimals;
            } catch {
                continue;
            }

            // set pair address
            results[count].pairAddress = pools[i];
            (address factoryAddr, bool factoryOk) = _getFactory(pools[i]);
            if (!factoryOk) {
                if (
                    keccak256(bytes(results[count].poolType)) ==
                    keccak256(bytes("balancer-v2"))
                ) {
                    try IPool(pools[i]).getVault() returns (IVault vault) {
                        factoryAddr = address(vault);
                    } catch {
                        continue;
                    }
                }
            }
            results[count].factory = factoryAddr;

            count++;
        }

        // 3) shrink the array’s length slot to `count`
        assembly {
            mstore(results, count)
        }

        return results;
    }

    function getPoolTokens(
        address poolAddress,
        string memory poolType
    ) external view returns (address[] memory tokens) {
        bytes32 poolTypeHash = keccak256(bytes(poolType));

        if (poolTypeHash == keccak256(bytes("balancer-v2"))) {
            IVault vault = IPool(poolAddress).getVault();
            bytes32 poolId = IBalancerPoolWithId(poolAddress).getPoolId();
            (IERC20[] memory poolTokens, , ) = vault.getPoolTokens(poolId);

            tokens = new address[](poolTokens.length);

            for (uint256 i = 0; i < poolTokens.length; i++) {
                tokens[i] = address(poolTokens[i]);
            }

            return tokens;
        }

        if (
            poolTypeHash == keccak256(bytes("uniswap-v2")) ||
            poolTypeHash == keccak256(bytes("uniswap-v3"))
        ) {
            tokens = new address[](2);
            tokens[0] = IUniswapV2Pair(poolAddress).token0();
            tokens[1] = IUniswapV2Pair(poolAddress).token1();
            return tokens;
        }

        revert("Unknown pool");
    }

    function _getPoolType(
        address pool
    ) external view returns (string memory result) {
        try IUniswapV2Pair(pool).getReserves() returns (
            uint112,
            uint112,
            uint32
        ) {
            result = "uniswap-v2";
        } catch {
            try IV3PoolLike(pool).tickSpacing() returns (int24) {
                result = "uniswap-v3";
            } catch {
                // Check if it is a balancer v2 pool
                try IPool(pool).getVault() returns (IVault) {
                    result = "balancer-v2";
                } catch {
                    revert("Unknown pool");
                }
            }
        }

        return result;
    }

    function _getFactory(
        address pool
    ) internal view returns (address factoryAddr, bool ok) {
        (bool success, bytes memory data) = pool.staticcall(
            abi.encodeWithSignature("factory()")
        );
        if (success && data.length >= 32) {
            factoryAddr = abi.decode(data, (address));
            ok = factoryAddr != address(0);
        }
    }
}