{
  "language": "Solidity",
  "sources": {
    "contracts/boringcrypto/BoringHelperV1.sol": {
      "content": "// SPDX-License-Identifier: MIT\n\n/**\n * This is a helper contract used by Sushiswap frontend to get all pool data.\n * Contract is available only via etherscan: https://etherscan.io/address/0x11ca5375adafd6205e41131a4409f182677996e6#code\n * It needs flattened due to cyclic dependencies.\n * BoringHelperV1 has been modified by:\n *  - Renaming Sushi -> Joe\n *  - Renaming ETH -> AVAX\n *  - Removed bentobox/kashi logic.\n *\n */\n\n// SPDX-License-Identifier: MIT\npragma solidity 0.6.12;\npragma experimental ABIEncoderV2;\n\n// Copyright (c) 2021 BoringCrypto\n// Twitter: @Boring_Crypto\n\n// Version 22-Mar-2021\n\ninterface IERC20 {\n    function totalSupply() external view returns (uint256);\n\n    function balanceOf(address account) external view returns (uint256);\n\n    function allowance(address owner, address spender)\n        external\n        view\n        returns (uint256);\n\n    function approve(address spender, uint256 amount) external returns (bool);\n\n    function owner() external view returns (address);\n\n    event Transfer(address indexed from, address indexed to, uint256 value);\n    event Approval(\n        address indexed owner,\n        address indexed spender,\n        uint256 value\n    );\n}\n\ninterface IMasterChef {\n    function BONUS_MULTIPLIER() external view returns (uint256);\n\n    function devaddr() external view returns (address);\n\n    function migrator() external view returns (address);\n\n    function owner() external view returns (address);\n\n    function startBlock() external view returns (uint256);\n\n    function joe() external view returns (address);\n\n    function joePerBlock() external view returns (uint256);\n\n    function totalAllocPoint() external view returns (uint256);\n\n    function poolLength() external view returns (uint256);\n\n    function poolInfo(uint256 nr)\n        external\n        view\n        returns (\n            address,\n            uint256,\n            uint256,\n            uint256\n        );\n\n    function userInfo(uint256 nr, address who)\n        external\n        view\n        returns (uint256, uint256);\n\n    function pendingTokens(uint256 pid, address who)\n        external\n        view\n        returns (\n            uint256,\n            address,\n            string memory,\n            uint256\n        );\n}\n\ninterface IPair is IERC20 {\n    function token0() external view returns (IERC20);\n\n    function token1() external view returns (IERC20);\n\n    function getReserves()\n        external\n        view\n        returns (\n            uint112,\n            uint112,\n            uint32\n        );\n}\n\ninterface IFactory {\n    function allPairsLength() external view returns (uint256);\n\n    function allPairs(uint256 i) external view returns (IPair);\n\n    function getPair(IERC20 token0, IERC20 token1)\n        external\n        view\n        returns (IPair);\n\n    function feeTo() external view returns (address);\n\n    function feeToSetter() external view returns (address);\n}\n\nlibrary BoringMath {\n    function add(uint256 a, uint256 b) internal pure returns (uint256 c) {\n        require((c = a + b) >= b, \"BoringMath: Add Overflow\");\n    }\n\n    function sub(uint256 a, uint256 b) internal pure returns (uint256 c) {\n        require((c = a - b) <= a, \"BoringMath: Underflow\");\n    }\n\n    function mul(uint256 a, uint256 b) internal pure returns (uint256 c) {\n        require(b == 0 || (c = a * b) / b == a, \"BoringMath: Mul Overflow\");\n    }\n}\n\ncontract Ownable {\n    address public immutable owner;\n\n    constructor() internal {\n        owner = msg.sender;\n    }\n\n    modifier onlyOwner() {\n        require(owner == msg.sender, \"Ownable: caller is not the owner\");\n        _;\n    }\n}\n\nlibrary BoringERC20 {\n    function returnDataToString(bytes memory data)\n        internal\n        pure\n        returns (string memory)\n    {\n        if (data.length >= 64) {\n            return abi.decode(data, (string));\n        } else if (data.length == 32) {\n            uint8 i = 0;\n            while (i < 32 && data[i] != 0) {\n                i++;\n            }\n            bytes memory bytesArray = new bytes(i);\n            for (i = 0; i < 32 && data[i] != 0; i++) {\n                bytesArray[i] = data[i];\n            }\n            return string(bytesArray);\n        } else {\n            return \"???\";\n        }\n    }\n\n    function symbol(IERC20 token) internal view returns (string memory) {\n        (bool success, bytes memory data) = address(token).staticcall(\n            abi.encodeWithSelector(0x95d89b41)\n        );\n        return success ? returnDataToString(data) : \"???\";\n    }\n\n    function name(IERC20 token) internal view returns (string memory) {\n        (bool success, bytes memory data) = address(token).staticcall(\n            abi.encodeWithSelector(0x06fdde03)\n        );\n        return success ? returnDataToString(data) : \"???\";\n    }\n\n    function decimals(IERC20 token) internal view returns (uint8) {\n        (bool success, bytes memory data) = address(token).staticcall(\n            abi.encodeWithSelector(0x313ce567)\n        );\n        return success && data.length == 32 ? abi.decode(data, (uint8)) : 18;\n    }\n\n    function DOMAIN_SEPARATOR(IERC20 token) internal view returns (bytes32) {\n        (bool success, bytes memory data) = address(token).staticcall{\n            gas: 10000\n        }(abi.encodeWithSelector(0x3644e515));\n        return\n            success && data.length == 32\n                ? abi.decode(data, (bytes32))\n                : bytes32(0);\n    }\n\n    function nonces(IERC20 token, address owner)\n        internal\n        view\n        returns (uint256)\n    {\n        (bool success, bytes memory data) = address(token).staticcall{\n            gas: 5000\n        }(abi.encodeWithSelector(0x7ecebe00, owner));\n        return\n            success && data.length == 32\n                ? abi.decode(data, (uint256))\n                : uint256(-1); // Use max uint256 to signal failure to retrieve nonce (probably not supported)\n    }\n}\n\nlibrary BoringPair {\n    function factory(IPair pair) internal view returns (IFactory) {\n        (bool success, bytes memory data) = address(pair).staticcall(\n            abi.encodeWithSelector(0xc45a0155)\n        );\n        return\n            success && data.length == 32\n                ? abi.decode(data, (IFactory))\n                : IFactory(0);\n    }\n}\n\ninterface IStrategy {\n    function skim(uint256 amount) external;\n\n    function harvest(uint256 balance, address sender)\n        external\n        returns (int256 amountAdded);\n\n    function withdraw(uint256 amount) external returns (uint256 actualAmount);\n\n    function exit(uint256 balance) external returns (int256 amountAdded);\n}\n\ninterface IBentoBox {\n    event LogDeploy(\n        address indexed masterContract,\n        bytes data,\n        address indexed cloneAddress\n    );\n    event LogDeposit(\n        address indexed token,\n        address indexed from,\n        address indexed to,\n        uint256 amount,\n        uint256 share\n    );\n    event LogFlashLoan(\n        address indexed borrower,\n        address indexed token,\n        uint256 amount,\n        uint256 feeAmount,\n        address indexed receiver\n    );\n    event LogRegisterProtocol(address indexed protocol);\n    event LogSetMasterContractApproval(\n        address indexed masterContract,\n        address indexed user,\n        bool approved\n    );\n    event LogStrategyDivest(address indexed token, uint256 amount);\n    event LogStrategyInvest(address indexed token, uint256 amount);\n    event LogStrategyLoss(address indexed token, uint256 amount);\n    event LogStrategyProfit(address indexed token, uint256 amount);\n    event LogStrategyQueued(address indexed token, address indexed strategy);\n    event LogStrategySet(address indexed token, address indexed strategy);\n    event LogStrategyTargetPercentage(\n        address indexed token,\n        uint256 targetPercentage\n    );\n    event LogTransfer(\n        address indexed token,\n        address indexed from,\n        address indexed to,\n        uint256 share\n    );\n    event LogWhiteListMasterContract(\n        address indexed masterContract,\n        bool approved\n    );\n    event LogWithdraw(\n        address indexed token,\n        address indexed from,\n        address indexed to,\n        uint256 amount,\n        uint256 share\n    );\n    event OwnershipTransferred(\n        address indexed previousOwner,\n        address indexed newOwner\n    );\n\n    function balanceOf(IERC20, address) external view returns (uint256);\n\n    function batch(bytes[] calldata calls, bool revertOnFail)\n        external\n        payable\n        returns (bool[] memory successes, bytes[] memory results);\n\n    function claimOwnership() external;\n\n    function deploy(\n        address masterContract,\n        bytes calldata data,\n        bool useCreate2\n    ) external payable;\n\n    function deposit(\n        IERC20 token_,\n        address from,\n        address to,\n        uint256 amount,\n        uint256 share\n    ) external payable returns (uint256 amountOut, uint256 shareOut);\n\n    function harvest(\n        IERC20 token,\n        bool balance,\n        uint256 maxChangeAmount\n    ) external;\n\n    function masterContractApproved(address, address)\n        external\n        view\n        returns (bool);\n\n    function masterContractOf(address) external view returns (address);\n\n    function nonces(address) external view returns (uint256);\n\n    function owner() external view returns (address);\n\n    function pendingOwner() external view returns (address);\n\n    function pendingStrategy(IERC20) external view returns (IStrategy);\n\n    function permitToken(\n        IERC20 token,\n        address from,\n        address to,\n        uint256 amount,\n        uint256 deadline,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) external;\n\n    function registerProtocol() external;\n\n    function setMasterContractApproval(\n        address user,\n        address masterContract,\n        bool approved,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) external;\n\n    function setStrategy(IERC20 token, IStrategy newStrategy) external;\n\n    function setStrategyTargetPercentage(IERC20 token, uint64 targetPercentage_)\n        external;\n\n    function strategy(IERC20) external view returns (IStrategy);\n\n    function strategyData(IERC20)\n        external\n        view\n        returns (\n            uint64 strategyStartDate,\n            uint64 targetPercentage,\n            uint128 balance\n        );\n\n    function toAmount(\n        IERC20 token,\n        uint256 share,\n        bool roundUp\n    ) external view returns (uint256 amount);\n\n    function toShare(\n        IERC20 token,\n        uint256 amount,\n        bool roundUp\n    ) external view returns (uint256 share);\n\n    function totals(IERC20)\n        external\n        view\n        returns (uint128 elastic, uint128 base);\n\n    function transfer(\n        IERC20 token,\n        address from,\n        address to,\n        uint256 share\n    ) external;\n\n    function transferMultiple(\n        IERC20 token,\n        address from,\n        address[] calldata tos,\n        uint256[] calldata shares\n    ) external;\n\n    function transferOwnership(\n        address newOwner,\n        bool direct,\n        bool renounce\n    ) external;\n\n    function whitelistMasterContract(address masterContract, bool approved)\n        external;\n\n    function whitelistedMasterContracts(address) external view returns (bool);\n\n    function withdraw(\n        IERC20 token_,\n        address from,\n        address to,\n        uint256 amount,\n        uint256 share\n    ) external returns (uint256 amountOut, uint256 shareOut);\n}\n\nstruct Rebase {\n    uint128 elastic;\n    uint128 base;\n}\n\nstruct AccrueInfo {\n    uint64 interestPerSecond;\n    uint64 lastAccrued;\n    uint128 feesEarnedFraction;\n}\n\ninterface IOracle {\n    function get(bytes calldata data)\n        external\n        returns (bool success, uint256 rate);\n\n    function peek(bytes calldata data)\n        external\n        view\n        returns (bool success, uint256 rate);\n\n    function peekSpot(bytes calldata data) external view returns (uint256 rate);\n\n    function symbol(bytes calldata data) external view returns (string memory);\n\n    function name(bytes calldata data) external view returns (string memory);\n}\n\ninterface IKashiPair {\n    function DOMAIN_SEPARATOR() external view returns (bytes32);\n\n    function accrue() external;\n\n    function accrueInfo() external view returns (AccrueInfo memory info);\n\n    function addAsset(\n        address to,\n        bool skim,\n        uint256 share\n    ) external returns (uint256 fraction);\n\n    function addCollateral(\n        address to,\n        bool skim,\n        uint256 share\n    ) external;\n\n    function allowance(address, address) external view returns (uint256);\n\n    function approve(address spender, uint256 amount) external returns (bool);\n\n    function asset() external view returns (IERC20);\n\n    function balanceOf(address) external view returns (uint256);\n\n    function bentoBox() external view returns (IBentoBox);\n\n    function borrow(address to, uint256 amount)\n        external\n        returns (uint256 part, uint256 share);\n\n    function claimOwnership() external;\n\n    function collateral() external view returns (IERC20);\n\n    function cook(\n        uint8[] calldata actions,\n        uint256[] calldata values,\n        bytes[] calldata datas\n    ) external payable returns (uint256 value1, uint256 value2);\n\n    function decimals() external view returns (uint8);\n\n    function exchangeRate() external view returns (uint256);\n\n    function feeTo() external view returns (address);\n\n    function getInitData(\n        IERC20 collateral_,\n        IERC20 asset_,\n        address oracle_,\n        bytes calldata oracleData_\n    ) external pure returns (bytes memory data);\n\n    function init(bytes calldata data) external payable;\n\n    function isSolvent(address user, bool open) external view returns (bool);\n\n    function liquidate(\n        address[] calldata users,\n        uint256[] calldata borrowParts,\n        address to,\n        address swapper,\n        bool open\n    ) external;\n\n    function masterContract() external view returns (address);\n\n    function name() external view returns (string memory);\n\n    function nonces(address) external view returns (uint256);\n\n    function oracle() external view returns (IOracle);\n\n    function oracleData() external view returns (bytes memory);\n\n    function owner() external view returns (address);\n\n    function pendingOwner() external view returns (address);\n\n    function permit(\n        address owner_,\n        address spender,\n        uint256 value,\n        uint256 deadline,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) external;\n\n    function removeAsset(address to, uint256 fraction)\n        external\n        returns (uint256 share);\n\n    function removeCollateral(address to, uint256 share) external;\n\n    function repay(\n        address to,\n        bool skim,\n        uint256 part\n    ) external returns (uint256 amount);\n\n    function setFeeTo(address newFeeTo) external;\n\n    function setSwapper(address swapper, bool enable) external;\n\n    function swappers(address) external view returns (bool);\n\n    function symbol() external view returns (string memory);\n\n    function totalAsset() external view returns (Rebase memory total);\n\n    function totalBorrow() external view returns (Rebase memory total);\n\n    function totalCollateralShare() external view returns (uint256);\n\n    function totalSupply() external view returns (uint256);\n\n    function transfer(address to, uint256 amount) external returns (bool);\n\n    function transferFrom(\n        address from,\n        address to,\n        uint256 amount\n    ) external returns (bool);\n\n    function transferOwnership(\n        address newOwner,\n        bool direct,\n        bool renounce\n    ) external;\n\n    function updateExchangeRate() external returns (bool updated, uint256 rate);\n\n    function userBorrowPart(address) external view returns (uint256);\n\n    function userCollateralShare(address) external view returns (uint256);\n\n    function withdrawFees() external;\n}\n\ncontract BoringHelperV1 is Ownable {\n    using BoringMath for uint256;\n    using BoringERC20 for IERC20;\n    using BoringERC20 for IPair;\n    using BoringPair for IPair;\n\n    IMasterChef public chef; // IMasterChef(0xc2EdaD668740f1aA35E4D8f227fB8E17dcA888Cd);\n    address public maker; // IJoeMaker(0xE11fc0B43ab98Eb91e9836129d1ee7c3Bc95df50);\n    IERC20 public joe; // IJoeToken(0x6B3595068778DD592e39A122f4f5a5cF09C90fE2);\n    IERC20 public WAVAX; // 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;\n    IFactory public joeFactory; // IFactory(0xC0AEe478e3658e2610c5F7A4A2E1777cE9e4f2Ac);\n    IFactory public pangolinFactory; // IFactory(0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f);\n    IERC20 public bar; // 0x8798249c2E607446EfB7Ad49eC89dD1865Ff4272;\n\n    constructor(\n        IMasterChef chef_,\n        address maker_,\n        IERC20 joe_,\n        IERC20 WAVAX_,\n        IFactory joeFactory_,\n        IFactory pangolinFactory_,\n        IERC20 bar_\n    ) public {\n        chef = chef_;\n        maker = maker_;\n        joe = joe_;\n        WAVAX = WAVAX;\n        joeFactory = joeFactory_;\n        pangolinFactory = pangolinFactory_;\n        bar = bar_;\n    }\n\n    function setContracts(\n        IMasterChef chef_,\n        address maker_,\n        IERC20 joe_,\n        IERC20 WAVAX_,\n        IFactory joeFactory_,\n        IFactory pangolinFactory_,\n        IERC20 bar_\n    ) public onlyOwner {\n        chef = chef_;\n        maker = maker_;\n        joe = joe_;\n        WAVAX = WAVAX_;\n        joeFactory = joeFactory_;\n        pangolinFactory = pangolinFactory_;\n        bar = bar_;\n    }\n\n    function getAVAXRate(IERC20 token) public view returns (uint256) {\n        if (token == WAVAX) {\n            return 1e18;\n        }\n        IPair pairPangolin;\n        IPair pairJoe;\n        if (pangolinFactory != IFactory(0)) {\n            pairPangolin = IPair(pangolinFactory.getPair(token, WAVAX));\n        }\n        if (joeFactory != IFactory(0)) {\n            pairJoe = IPair(joeFactory.getPair(token, WAVAX));\n        }\n        if (\n            address(pairPangolin) == address(0) &&\n            address(pairJoe) == address(0)\n        ) {\n            return 0;\n        }\n\n        uint112 reserve0;\n        uint112 reserve1;\n        IERC20 token0;\n        if (address(pairPangolin) != address(0)) {\n            (\n                uint112 reserve0Pangolin,\n                uint112 reserve1Pangolin,\n\n            ) = pairPangolin.getReserves();\n            reserve0 += reserve0Pangolin;\n            reserve1 += reserve1Pangolin;\n            token0 = pairPangolin.token0();\n        }\n\n        if (address(pairJoe) != address(0)) {\n            (uint112 reserve0Joe, uint112 reserve1Joe, ) = pairJoe\n            .getReserves();\n            reserve0 += reserve0Joe;\n            reserve1 += reserve1Joe;\n            if (token0 == IERC20(0)) {\n                token0 = pairJoe.token0();\n            }\n        }\n\n        if (token0 == WAVAX) {\n            return (uint256(reserve1) * 1e18) / reserve0;\n        } else {\n            return (uint256(reserve0) * 1e18) / reserve1;\n        }\n    }\n\n    struct Factory {\n        IFactory factory;\n        uint256 allPairsLength;\n    }\n\n    struct UIInfo {\n        uint256 avaxBalance;\n        uint256 joeBalance;\n        uint256 joeBarBalance;\n        uint256 xjoeBalance;\n        uint256 xjoeSupply;\n        uint256 joeBarAllowance;\n        Factory[] factories;\n        uint256 avaxRate;\n        uint256 joeRate;\n        uint256 btcRate;\n        uint256 pendingJoe;\n        uint256 blockTimeStamp;\n    }\n\n    function getUIInfo(\n        address who,\n        IFactory[] calldata factoryAddresses,\n        IERC20 currency,\n        address[] calldata masterContracts\n    ) public view returns (UIInfo memory) {\n        UIInfo memory info;\n        info.avaxBalance = who.balance;\n\n        info.factories = new Factory[](factoryAddresses.length);\n        for (uint256 i = 0; i < factoryAddresses.length; i++) {\n            IFactory factory = factoryAddresses[i];\n            info.factories[i].factory = factory;\n            info.factories[i].allPairsLength = factory.allPairsLength();\n        }\n\n        if (currency != IERC20(0)) {\n            info.avaxRate = getAVAXRate(currency);\n        }\n\n        if (joe != IERC20(0)) {\n            info.joeRate = getAVAXRate(joe);\n            info.joeBalance = joe.balanceOf(who);\n            info.joeBarBalance = joe.balanceOf(address(bar));\n            info.joeBarAllowance = joe.allowance(who, address(bar));\n        }\n\n        if (bar != IERC20(0)) {\n            info.xjoeBalance = bar.balanceOf(who);\n            info.xjoeSupply = bar.totalSupply();\n        }\n\n        if (chef != IMasterChef(0)) {\n            uint256 poolLength = chef.poolLength();\n            uint256 pendingJoe;\n            for (uint256 i = 0; i < poolLength; i++) {\n                (uint256 pendingJoeAmt, , , ) = chef.pendingTokens(i, who);\n                pendingJoe += pendingJoeAmt;\n            }\n            info.pendingJoe = pendingJoe;\n        }\n        info.blockTimeStamp = block.timestamp;\n\n        return info;\n    }\n\n    struct Balance {\n        IERC20 token;\n        uint256 balance;\n    }\n\n    struct BalanceFull {\n        IERC20 token;\n        uint256 totalSupply;\n        uint256 balance;\n        uint256 nonce;\n        uint256 rate;\n    }\n\n    struct TokenInfo {\n        IERC20 token;\n        uint256 decimals;\n        string name;\n        string symbol;\n        bytes32 DOMAIN_SEPARATOR;\n    }\n\n    function getTokenInfo(address[] calldata addresses)\n        public\n        view\n        returns (TokenInfo[] memory)\n    {\n        TokenInfo[] memory infos = new TokenInfo[](addresses.length);\n\n        for (uint256 i = 0; i < addresses.length; i++) {\n            IERC20 token = IERC20(addresses[i]);\n            infos[i].token = token;\n\n            infos[i].name = token.name();\n            infos[i].symbol = token.symbol();\n            infos[i].decimals = token.decimals();\n            infos[i].DOMAIN_SEPARATOR = token.DOMAIN_SEPARATOR();\n        }\n\n        return infos;\n    }\n\n    function findBalances(address who, address[] calldata addresses)\n        public\n        view\n        returns (Balance[] memory)\n    {\n        Balance[] memory balances = new Balance[](addresses.length);\n\n        uint256 len = addresses.length;\n        for (uint256 i = 0; i < len; i++) {\n            IERC20 token = IERC20(addresses[i]);\n            balances[i].token = token;\n            balances[i].balance = token.balanceOf(who);\n        }\n\n        return balances;\n    }\n\n    function getBalances(address who, IERC20[] calldata addresses)\n        public\n        view\n        returns (BalanceFull[] memory)\n    {\n        BalanceFull[] memory balances = new BalanceFull[](addresses.length);\n\n        for (uint256 i = 0; i < addresses.length; i++) {\n            IERC20 token = addresses[i];\n            balances[i].totalSupply = token.totalSupply();\n            balances[i].token = token;\n            balances[i].balance = token.balanceOf(who);\n            balances[i].nonce = token.nonces(who);\n            balances[i].rate = getAVAXRate(token);\n        }\n\n        return balances;\n    }\n\n    struct PairBase {\n        IPair token;\n        IERC20 token0;\n        IERC20 token1;\n        uint256 totalSupply;\n    }\n\n    function getPairs(\n        IFactory factory,\n        uint256 fromID,\n        uint256 toID\n    ) public view returns (PairBase[] memory) {\n        PairBase[] memory pairs = new PairBase[](toID - fromID);\n\n        for (uint256 id = fromID; id < toID; id++) {\n            IPair token = factory.allPairs(id);\n            uint256 i = id - fromID;\n            pairs[i].token = token;\n            pairs[i].token0 = token.token0();\n            pairs[i].token1 = token.token1();\n            pairs[i].totalSupply = token.totalSupply();\n        }\n        return pairs;\n    }\n\n    struct PairPoll {\n        IPair token;\n        uint256 reserve0;\n        uint256 reserve1;\n        uint256 totalSupply;\n        uint256 balance;\n    }\n\n    function pollPairs(address who, IPair[] calldata addresses)\n        public\n        view\n        returns (PairPoll[] memory)\n    {\n        PairPoll[] memory pairs = new PairPoll[](addresses.length);\n        for (uint256 i = 0; i < addresses.length; i++) {\n            IPair token = addresses[i];\n            pairs[i].token = token;\n            (uint256 reserve0, uint256 reserve1, ) = token.getReserves();\n            pairs[i].reserve0 = reserve0;\n            pairs[i].reserve1 = reserve1;\n            pairs[i].balance = token.balanceOf(who);\n            pairs[i].totalSupply = token.totalSupply();\n        }\n        return pairs;\n    }\n\n    struct PoolsInfo {\n        uint256 totalAllocPoint;\n        uint256 poolLength;\n    }\n\n    struct PoolInfo {\n        uint256 pid;\n        IPair lpToken;\n        uint256 allocPoint;\n        bool isPair;\n        IFactory factory;\n        IERC20 token0;\n        IERC20 token1;\n        string name;\n        string symbol;\n        uint8 decimals;\n    }\n\n    function getPools(uint256[] calldata pids)\n        public\n        view\n        returns (PoolsInfo memory, PoolInfo[] memory)\n    {\n        PoolsInfo memory info;\n        info.totalAllocPoint = chef.totalAllocPoint();\n        uint256 poolLength = chef.poolLength();\n        info.poolLength = poolLength;\n\n        PoolInfo[] memory pools = new PoolInfo[](pids.length);\n\n        for (uint256 i = 0; i < pids.length; i++) {\n            pools[i].pid = pids[i];\n            (address lpToken, uint256 allocPoint, , ) = chef.poolInfo(pids[i]);\n            IPair pair = IPair(lpToken);\n            pools[i].lpToken = pair;\n            pools[i].allocPoint = allocPoint;\n\n            pools[i].name = pair.name();\n            pools[i].symbol = pair.symbol();\n            pools[i].decimals = pair.decimals();\n\n            pools[i].factory = pair.factory();\n            if (pools[i].factory != IFactory(0)) {\n                pools[i].isPair = true;\n                pools[i].token0 = pair.token0();\n                pools[i].token1 = pair.token1();\n            }\n        }\n        return (info, pools);\n    }\n\n    struct PoolFound {\n        uint256 pid;\n        uint256 balance;\n    }\n\n    function findPools(address who, uint256[] calldata pids)\n        public\n        view\n        returns (PoolFound[] memory)\n    {\n        PoolFound[] memory pools = new PoolFound[](pids.length);\n\n        for (uint256 i = 0; i < pids.length; i++) {\n            pools[i].pid = pids[i];\n            (pools[i].balance, ) = chef.userInfo(pids[i], who);\n        }\n\n        return pools;\n    }\n\n    struct UserPoolInfo {\n        uint256 pid;\n        uint256 balance; // Balance of pool tokens\n        uint256 totalSupply; // Token staked lp tokens\n        uint256 lpBalance; // Balance of lp tokens not staked\n        uint256 lpTotalSupply; // TotalSupply of lp tokens\n        uint256 lpAllowance; // LP tokens approved for masterchef\n        uint256 reserve0;\n        uint256 reserve1;\n        uint256 rewardDebt;\n        uint256 pending; // Pending SUSHI\n    }\n\n    function pollPools(address who, uint256[] calldata pids)\n        public\n        view\n        returns (UserPoolInfo[] memory)\n    {\n        UserPoolInfo[] memory pools = new UserPoolInfo[](pids.length);\n\n        for (uint256 i = 0; i < pids.length; i++) {\n            (uint256 amount, ) = chef.userInfo(pids[i], who);\n            pools[i].balance = amount;\n            (uint256 pendingJoe, , , ) = chef.pendingTokens(pids[i], who);\n            pools[i].pending = pendingJoe;\n\n            (address lpToken, , , ) = chef.poolInfo(pids[i]);\n            pools[i].pid = pids[i];\n            IPair pair = IPair(lpToken);\n            IFactory factory = pair.factory();\n            if (factory != IFactory(0)) {\n                pools[i].totalSupply = pair.balanceOf(address(chef));\n                pools[i].lpAllowance = pair.allowance(who, address(chef));\n                pools[i].lpBalance = pair.balanceOf(who);\n                pools[i].lpTotalSupply = pair.totalSupply();\n\n                (uint112 reserve0, uint112 reserve1, ) = pair.getReserves();\n                pools[i].reserve0 = reserve0;\n                pools[i].reserve1 = reserve1;\n            }\n        }\n        return pools;\n    }\n}\n"
    }
  },
  "settings": {
    "optimizer": {
      "enabled": true,
      "runs": 200
    },
    "outputSelection": {
      "*": {
        "*": [
          "abi",
          "evm.bytecode",
          "evm.deployedBytecode",
          "evm.methodIdentifiers",
          "metadata",
          "devdoc",
          "userdoc",
          "storageLayout",
          "evm.gasEstimates"
        ],
        "": [
          "ast"
        ]
      }
    },
    "metadata": {
      "useLiteralContent": true
    },
    "libraries": {
      "": {
        "__CACHE_BREAKER__": "0x00000000d41867734bbee4c6863d9255b2b06ac1"
      }
    }
  }
}