PoolBalancerV3StateReader

Description:

Multi-signature wallet contract requiring multiple confirmations for transaction execution.

Blockchain: Ethereum

Source Code: View Code On The Blockchain

Solidity Source Code:

{{
  "language": "Solidity",
  "sources": {
    "contracts/v14/PoolBalancerV3StateReader.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.28;
pragma abicoder v2;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/interfaces/IERC20Metadata.sol";
import "../interfaces/IOffchainOracle.sol";
//import "hardhat/console.sol";

interface IRateProvider {
    function getRate() external view returns (uint256);
}
// Supported protocols: balancerv3
contract PoolBalancerV3StateReader {
    struct BalancerToken {
        address token;
        uint256 reserve;
    }
    struct TokenInfo {
        TokenType tokenType;
        IRateProvider rateProvider;
        bool paysYieldFees;
    }
    enum TokenType {
        STANDARD,
        WITH_RATE
    }

    function getPool(address poolAddress)
    external
    view
    returns (
        string memory protocol,
        BalancerToken[] memory tokens
    )
    {
        uint256 count = 0;
        bool success;
        bytes memory data;
        protocol = "balancerv3";
        BalancerToken[] memory returnTokens;

        (success, data) = poolAddress.staticcall(abi.encodeWithSignature("getTokenInfo()"));
        if (success) {
            (address[] memory tokens, TokenInfo[] memory tokenInfos, uint256[] memory balancesRaw, uint256[] memory lastBalancesLiveScaled18) = abi.decode(data, (address[], TokenInfo[], uint256[], uint256[]));
            returnTokens = new BalancerToken[](tokens.length);
            for (uint256 i = 0; i < tokens.length; i++) {
                returnTokens[i] = BalancerToken({ token: tokens[i], reserve: balancesRaw[i] });
                count++;
            }
        }

        require(count >= 2, "Balancer tokens parse error");
        return (protocol, returnTokens);
    }

    function multicall(bytes[] calldata data) external payable returns (bytes[] memory results) {
        results = new bytes[](data.length);
        for (uint256 i = 0; i < data.length; i++) {
            (bool success, bytes memory result) = address(this).delegatecall(data[i]); // msg.sender remains the same because of delegatecall

            if (!success) {
                // Next 5 lines from https://ethereum.stackexchange.com/a/83577
                if (result.length < 68) revert();
                assembly {
                    result := add(result, 0x04)
                }
                revert(abi.decode(result, (string))); // it decodes only strings, but not objects
            }

            results[i] = result;
        }
    }

    function balanceOf(address wallet, address token) external view returns (uint256) {
        return IERC20(token).balanceOf(wallet);
    }
}"
    },
    "contracts/interfaces/IOffchainOracle.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSED
// !! THIS FILE WAS AUTOGENERATED BY abi-to-sol v0.8.0. SEE SOURCE BELOW. !!
pragma solidity ^0.8.18;

interface IOffchainOracle {
    error ArraysLengthMismatch();
    error ConnectorAlreadyAdded();
    error InvalidOracleTokenKind();
    error OracleAlreadyAdded();
    error SameTokens();
    error TooBigThreshold();
    error UnknownConnector();
    error UnknownOracle();
    event ConnectorAdded(address connector);
    event ConnectorRemoved(address connector);
    event MultiWrapperUpdated(address multiWrapper);
    event OracleAdded(address oracle, uint8 oracleType);
    event OracleRemoved(address oracle, uint8 oracleType);
    event OwnershipTransferred(
        address indexed previousOwner,
        address indexed newOwner
    );

    function addConnector(address connector) external;

    function addOracle(address oracle, uint8 oracleKind) external;

    function connectors()
        external
        view
        returns (address[] memory allConnectors);

    function getRate(
        address srcToken,
        address dstToken,
        bool useWrappers
    ) external view returns (uint256 weightedRate);

    function getRateToEth(address srcToken, bool useSrcWrappers)
        external
        view
        returns (uint256 weightedRate);

    function getRateToEthWithCustomConnectors(
        address srcToken,
        bool useSrcWrappers,
        address[] memory customConnectors,
        uint256 thresholdFilter
    ) external view returns (uint256 weightedRate);

    function getRateToEthWithThreshold(
        address srcToken,
        bool useSrcWrappers,
        uint256 thresholdFilter
    ) external view returns (uint256 weightedRate);

    function getRateWithCustomConnectors(
        address srcToken,
        address dstToken,
        bool useWrappers,
        address[] memory customConnectors,
        uint256 thresholdFilter
    ) external view returns (uint256 weightedRate);

    function getRateWithThreshold(
        address srcToken,
        address dstToken,
        bool useWrappers,
        uint256 thresholdFilter
    ) external view returns (uint256 weightedRate);

    function multiWrapper() external view returns (address);

    function oracles()
        external
        view
        returns (address[] memory allOracles, uint8[] memory oracleTypes);

    function owner() external view returns (address);

    function removeConnector(address connector) external;

    function removeOracle(address oracle, uint8 oracleKind) external;

    function renounceOwnership() external;

    function setMultiWrapper(address _multiWrapper) external;

    function transferOwnership(address newOwner) external;
}

// THIS FILE WAS AUTOGENERATED FROM THE FOLLOWING ABI JSON:
/*
[{"inputs":[{"internalType":"contract MultiWrapper","name":"_multiWrapper","type":"address"},{"internalType":"contract IOracle[]","name":"existingOracles","type":"address[]"},{"internalType":"enum OffchainOracle.OracleType[]","name":"oracleTypes","type":"uint8[]"},{"internalType":"contract IERC20[]","name":"existingConnectors","type":"address[]"},{"internalType":"contract IERC20","name":"wBase","type":"address"},{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ArraysLengthMismatch","type":"error"},{"inputs":[],"name":"ConnectorAlreadyAdded","type":"error"},{"inputs":[],"name":"InvalidOracleTokenKind","type":"error"},{"inputs":[],"name":"OracleAlreadyAdded","type":"error"},{"inputs":[],"name":"SameTokens","type":"error"},{"inputs":[],"name":"TooBigThreshold","type":"error"},{"inputs":[],"name":"UnknownConnector","type":"error"},{"inputs":[],"name":"UnknownOracle","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract IERC20","name":"connector","type":"address"}],"name":"ConnectorAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract IERC20","name":"connector","type":"address"}],"name":"ConnectorRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract MultiWrapper","name":"multiWrapper","type":"address"}],"name":"MultiWrapperUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract IOracle","name":"oracle","type":"address"},{"indexed":false,"internalType":"enum OffchainOracle.OracleType","name":"oracleType","type":"uint8"}],"name":"OracleAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract IOracle","name":"oracle","type":"address"},{"indexed":false,"internalType":"enum OffchainOracle.OracleType","name":"oracleType","type":"uint8"}],"name":"OracleRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[{"internalType":"contract IERC20","name":"connector","type":"address"}],"name":"addConnector","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IOracle","name":"oracle","type":"address"},{"internalType":"enum OffchainOracle.OracleType","name":"oracleKind","type":"uint8"}],"name":"addOracle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"connectors","outputs":[{"internalType":"contract IERC20[]","name":"allConnectors","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"srcToken","type":"address"},{"internalType":"contract IERC20","name":"dstToken","type":"address"},{"internalType":"bool","name":"useWrappers","type":"bool"}],"name":"getRate","outputs":[{"internalType":"uint256","name":"weightedRate","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"srcToken","type":"address"},{"internalType":"bool","name":"useSrcWrappers","type":"bool"}],"name":"getRateToEth","outputs":[{"internalType":"uint256","name":"weightedRate","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"srcToken","type":"address"},{"internalType":"bool","name":"useSrcWrappers","type":"bool"},{"internalType":"contract IERC20[]","name":"customConnectors","type":"address[]"},{"internalType":"uint256","name":"thresholdFilter","type":"uint256"}],"name":"getRateToEthWithCustomConnectors","outputs":[{"internalType":"uint256","name":"weightedRate","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"srcToken","type":"address"},{"internalType":"bool","name":"useSrcWrappers","type":"bool"},{"internalType":"uint256","name":"thresholdFilter","type":"uint256"}],"name":"getRateToEthWithThreshold","outputs":[{"internalType":"uint256","name":"weightedRate","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"srcToken","type":"address"},{"internalType":"contract IERC20","name":"dstToken","type":"address"},{"internalType":"bool","name":"useWrappers","type":"bool"},{"internalType":"contract IERC20[]","name":"customConnectors","type":"address[]"},{"internalType":"uint256","name":"thresholdFilter","type":"uint256"}],"name":"getRateWithCustomConnectors","outputs":[{"internalType":"uint256","name":"weightedRate","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"srcToken","type":"address"},{"internalType":"contract IERC20","name":"dstToken","type":"address"},{"internalType":"bool","name":"useWrappers","type":"bool"},{"internalType":"uint256","name":"thresholdFilter","type":"uint256"}],"name":"getRateWithThreshold","outputs":[{"internalType":"uint256","name":"weightedRate","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"multiWrapper","outputs":[{"internalType":"contract MultiWrapper","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oracles","outputs":[{"internalType":"contract IOracle[]","name":"allOracles","type":"address[]"},{"internalType":"enum OffchainOracle.OracleType[]","name":"oracleTypes","type":"uint8[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"connector","type":"address"}],"name":"removeConnector","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IOracle","name":"oracle","type":"address"},{"internalType":"enum OffchainOracle.OracleType","name":"oracleKind","type":"uint8"}],"name":"removeOracle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract MultiWrapper","name":"_multiWrapper","type":"address"}],"name":"setMultiWrapper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]
*/"
    },
    "@openzeppelin/contracts/interfaces/IERC20Metadata.sol": {
      "content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/IERC20Metadata.sol)

pragma solidity >=0.6.2;

import {IERC20Metadata} from "../token/ERC20/extensions/IERC20Metadata.sol";
"
    },
    "@openzeppelin/contracts/token/ERC20/IERC20.sol": {
      "content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/IERC20.sol)

pragma solidity >=0.4.16;

/**
 * @dev Interface of the ERC-20 standard as defined in the ERC.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /**
     * @dev Returns the value of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the value of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves a `value` amount of tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 value) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the
     * caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 value) external returns (bool);

    /**
     * @dev Moves a `value` amount of tokens from `from` to `to` using the
     * allowance mechanism. `value` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address from, address to, uint256 value) external returns (bool);
}
"
    },
    "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": {
      "content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity >=0.6.2;

import {IERC20} from "../IERC20.sol";

/**
 * @dev Interface for the optional metadata functions from the ERC-20 standard.
 */
interface IERC20Metadata is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the symbol of the token.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the decimals places of the token.
     */
    function decimals() external view returns (uint8);
}
"
    }
  },
  "settings": {
    "optimizer": {
      "enabled": false,
      "runs": 200
    },
    "outputSelection": {
      "*": {
        "*": [
          "evm.bytecode",
          "evm.deployedBytecode",
          "devdoc",
          "userdoc",
          "metadata",
          "abi"
        ]
      }
    },
    "remappings": []
  }
}}

Tags:
ERC20, Multisig, Upgradeable, Multi-Signature, Factory, Oracle|addr:0x9656ee3c80f2ad4b9df209540c759f46d8ba42c2|verified:true|block:23705846|tx:0x8ede7906fcf7381cbe0adf0075de24d1836c7f9d098974c474489d3a2b6270c1|first_check:1762016516

Submitted on: 2025-11-01 18:01:56

Comments

Log in to comment.

No comments yet.