{
    "Function": "slitherConstructorConstantVariables",
    "File": "contracts/oracles/estimators/CurveLPEstimator.sol",
    "Parent Contracts": [
        "contracts/interfaces/IEstimator.sol"
    ],
    "High-Level Calls": [],
    "Internal Calls": [],
    "Library Calls": [],
    "Low-Level Calls": [],
    "Code": "contract CurveLPEstimator is IEstimator {\n    using SafeMath for uint256;\n    using SignedSafeMath for int256;\n\n    IAddressProvider public constant ADDRESS_PROVIDER = IAddressProvider(0x0000000022D53366457F9d5E68Ec105046FC4383);\n    address public constant SBTC = 0xfE18be6b3Bd88A2D2A7f928d00292E7a9963CfC6;\n    address public constant SUSD = 0x57Ab1ec28D129707052df4dF418D58a2D46d5f51;\n    address public constant USDT = 0xdAC17F958D2ee523a2206206994597C13D831ec7;\n    address public constant TRICRYPTO2 = 0xc4AD29ba4B3c580e6D59105FFf484999997675Ff;\n    address public constant TRICRYPTO2_ORACLE = 0xE8b2989276E2Ca8FDEA2268E3551b2b4B2418950;\n    uint256 private constant TRICRYPTO2_PRECISION = 10**30; // lpPrice_precision + (lp_precision - usdt_precision) = 18 + (18 - 6) = 30\n\n    function estimateItem(uint256 balance, address token) public view override returns (int256) {\n        return _estimateItem(balance, token);\n    }\n\n    function estimateItem(address user, address token) public view override returns (int256) {\n        uint256 balance = IERC20(token).balanceOf(address(user));\n        return _estimateItem(balance, token);\n    }\n\n    function _estimateItem(uint256 balance, address token) private view returns (int256) {\n        if (balance == 0) return 0;\n        if (token == TRICRYPTO2) { //Hack because tricrypto2 is not registered\n            uint256 lpPrice = ICurveCrypto(TRICRYPTO2_ORACLE).lp_price();\n            return IOracle(msg.sender).estimateItem(lpPrice.mul(balance).div(TRICRYPTO2_PRECISION), USDT);\n        } else {\n            ICurveRegistry registry = ICurveRegistry(ADDRESS_PROVIDER.get_registry());\n            address pool = registry.get_pool_from_lp_token(token);\n            uint256 assetType = registry.get_pool_asset_type(pool);\n            if (assetType < 4) {\n                uint256 virtualPrice = registry.get_virtual_price_from_lp_token(token);\n                uint256 virtualBalance =\n                    balance.mul(\n                        virtualPrice\n                    ).div(10**18);\n                if (assetType == 0) {\n                    // USD\n                    return IOracle(msg.sender).estimateItem(virtualBalance, SUSD);\n                } else if (assetType == 1) {\n                    // ETH\n                    return int256(virtualBalance);\n                } else if (assetType == 2) {\n                    // BTC\n                    return IOracle(msg.sender).estimateItem(virtualBalance, SBTC);\n                } else {\n                    // Other (Link or Euro)\n                    (uint256 coinsInPool, ) = registry.get_n_coins(pool);\n                    address[8] memory coins = registry.get_coins(pool);\n                    for (uint256 i = 0; i < coinsInPool; i++) {\n                        address underlyingToken = coins[i];\n                        uint256 decimals = uint256(IERC20NonStandard(underlyingToken).decimals());\n                        uint256 convertedBalance = virtualBalance;\n                        if (decimals < 18) {\n                          convertedBalance = convertedBalance.div(10**(18-decimals));\n                        } else if (decimals > 18) {\n                          convertedBalance = convertedBalance.mul(10**(decimals-18));\n                        }\n                        try IOracle(msg.sender).estimateItem(convertedBalance, underlyingToken) returns (int256 value) {\n                            if (value > 0) {\n                              return value;\n                            }\n                        } catch (bytes memory) {\n                            continue;\n                        }\n                    }\n                    revert(\"Asset not found\");\n                }\n            } else {\n                // Other crypto pools\n                revert(\"Not supported\");\n            }\n        }\n    }\n\n}"
}