{
    "Function": "slitherConstructorConstantVariables",
    "File": "contracts/adapters/liquidity/CurveLPAdapter.sol",
    "Parent Contracts": [
        "contracts/adapters/BaseAdapter.sol",
        "contracts/interfaces/IBaseAdapter.sol"
    ],
    "High-Level Calls": [],
    "Internal Calls": [],
    "Library Calls": [],
    "Low-Level Calls": [],
    "Code": "contract CurveLPAdapter is BaseAdapter {\n    using SafeERC20 for IERC20;\n\n    ICurveAddressProvider public immutable addressProvider;\n    ICurveDepositZapRegistry public immutable zapRegistry;\n    address public constant TRICRYPTO2 = 0xc4AD29ba4B3c580e6D59105FFf484999997675Ff;\n    address public constant TRICRYPTO2_POOL = 0xD51a44d3FaE010294C616388b506AcdA1bfAAE46;\n    address private constant WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;\n    address private constant WBTC = 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599;\n    address private constant USDT = 0xdAC17F958D2ee523a2206206994597C13D831ec7;\n\n    constructor(\n        address addressProvider_,\n        address zapRegistry_,\n        address weth_\n    ) public BaseAdapter(weth_) {\n        addressProvider = ICurveAddressProvider(addressProvider_);\n        zapRegistry = ICurveDepositZapRegistry(zapRegistry_);\n    }\n\n    function swap(\n        uint256 amount,\n        uint256 expected,\n        address tokenIn,\n        address tokenOut,\n        address from,\n        address to\n    ) public override {\n        require(tokenIn != tokenOut, \"Tokens cannot match\");\n        if (from != address(this))\n            IERC20(tokenIn).safeTransferFrom(from, address(this), amount);\n\n        ICurveRegistry curveRegistry = ICurveRegistry(addressProvider.get_registry());\n        address poolIn = curveRegistry.get_pool_from_lp_token(tokenIn);\n        address poolOut = curveRegistry.get_pool_from_lp_token(tokenOut);\n        if (poolIn == address(0) && poolOut != address(0)) {\n            _deposit(amount, tokenIn, poolOut, curveRegistry.get_coins(poolOut));\n        } else if (poolIn != address(0) && poolOut == address(0)) {\n            _withdraw(amount, tokenIn, tokenOut, poolIn, curveRegistry.get_coins(poolIn));\n        } else if (poolIn != address(0) && poolOut != address(0)) { //Metapool\n            bool isDeposit;\n            address[8] memory depositCoins = curveRegistry.get_coins(poolOut);\n            for (uint256 i = 0; i < 8; i++) {\n                if (depositCoins[i] == address(0)) break;\n                if (depositCoins[i] == tokenIn) {\n                    isDeposit = true;\n                    break;\n                }\n            }\n            if (isDeposit) {\n                _deposit(amount, tokenIn, poolOut, depositCoins);\n            } else {\n                bool isWithdraw;\n                address[8] memory withdrawCoins = curveRegistry.get_coins(poolIn);\n                for (uint256 i = 0; i < 8; i++) {\n                    if (withdrawCoins[i] == address(0)) break;\n                    if (withdrawCoins[i] == tokenOut) {\n                        isWithdraw = true;\n                        break;\n                    }\n                }\n                if (isWithdraw) _withdraw(amount, tokenIn, tokenOut, poolIn, withdrawCoins);\n            }\n        } else if (tokenIn == TRICRYPTO2 || tokenOut == TRICRYPTO2) {\n            // tricrypto not in registry\n            address[8] memory coins;\n            coins[0] = USDT;\n            coins[1] = WBTC;\n            coins[2] = WETH;\n            if (tokenIn == TRICRYPTO2) _withdraw(amount, tokenIn, tokenOut, TRICRYPTO2_POOL, coins);\n            if (tokenOut == TRICRYPTO2) _deposit(amount, tokenIn, TRICRYPTO2_POOL, coins);\n        } else {\n            revert();\n        }\n        uint256 received = IERC20(tokenOut).balanceOf(address(this));\n        require(received >= expected, \"Insufficient tokenOut amount\");\n        if (to != address(this))\n            IERC20(tokenOut).safeTransfer(to, received);\n    }\n\n    function _deposit(\n        uint256 amount,\n        address tokenIn,\n        address pool,\n        address[8] memory coins\n    ) internal {\n        IERC20(tokenIn).safeApprove(pool, amount);\n        uint256 coinsInPool;\n        uint256 tokenIndex = 8; //Outside of possible index range. If index not found function will fail\n        for (uint256 i = 0; i < 8; i++) {\n          if (coins[i] == address(0)) {\n              coinsInPool = i;\n              break;\n          }\n          if (coins[i] == tokenIn) tokenIndex = i;\n        }\n        require(tokenIndex < 8, \"Token not found\");\n        if (coinsInPool == 4) {\n            uint256[4] memory depositAmounts;\n            depositAmounts[tokenIndex] = amount;\n            ICurveStableSwap(pool).add_liquidity(depositAmounts, 0);\n        } else if (coinsInPool == 3) {\n            uint256[3] memory depositAmounts;\n            depositAmounts[tokenIndex] = amount;\n            ICurveStableSwap(pool).add_liquidity(depositAmounts, 0);\n        } else if (coinsInPool == 2) {\n            uint256[2] memory depositAmounts;\n            depositAmounts[tokenIndex] = amount;\n            ICurveStableSwap(pool).add_liquidity(depositAmounts, 0);\n        }\n    }\n\n    function _withdraw(\n        uint256 amount,\n        address tokenIn,\n        address tokenOut,\n        address pool,\n        address[8] memory coins\n    ) internal {\n        address zap = zapRegistry.getZap(tokenIn);\n        if (zap == address(0)) zap = pool;\n\n        int128 tokenIndex;\n        for (uint256 i = 0; i < 8; i++) {\n            require(coins[i] != address(0), \"Token not found in pool\");\n            if (coins[i] == tokenOut) {\n                tokenIndex = int128(i);\n                break;\n            }\n        }\n\n        if (zap != pool)\n            IERC20(tokenIn).safeApprove(zap, amount);\n\n        uint256 indexType = zapRegistry.getIndexType(zap);\n        if (indexType == 0) { //int128\n            ICurveDeposit(zap).remove_liquidity_one_coin(amount, tokenIndex, 1);\n        } else if (indexType == 1) { //uint256\n            ICurveDeposit(zap).remove_liquidity_one_coin(amount, uint256(tokenIndex), 1);\n        } else {\n            return revert(\"Unknown index type\");\n        }\n    }\n}"
}