Leverage Vault on sidechains that support Curve V2 pools is broken
No users will be able to deposit to the Leverage Vault on Arbitrum and Optimism that supports Curve V2 pools, leading to the core contract functionality of a vault being broken and a loss of revenue for the protocol.\\nFollowing are examples of some Curve V2 pools in Arbitum:\\nThe code from Line 64 to Line 71 is only executed if the contract resides on Ethereum. As a result, for Arbitrum and Optimism sidechains, the `IS_CURVE_V2` variable is always false.\\n```\\nFile: Curve2TokenPoolMixin.sol\\n    constructor(\\n        NotionalProxy notional_,\\n        DeploymentParams memory params\\n    ) SingleSidedLPVaultBase(notional_, params.tradingModule) {\\n        CURVE_POOL = params.pool;\\n\\n        bool isCurveV2 = false;\\n        if (Deployments.CHAIN_ID == Constants.CHAIN_ID_MAINNET) {\\n            address[10] memory handlers = \\n                Deployments.CURVE_META_REGISTRY.get_registry_handlers_from_pool(address(CURVE_POOL));\\n\\n            require(\\n                handlers[0] == Deployments.CURVE_V1_HANDLER ||\\n                handlers[0] == Deployments.CURVE_V2_HANDLER\\n            ); // @dev unknown Curve version\\n            isCurveV2 = (handlers[0] == Deployments.CURVE_V2_HANDLER);\\n        }\\n        IS_CURVE_V2 = isCurveV2;\\n```\\n\\nAs a result, code within the `_joinPoolAndStake` function will always call the Curve V1's `add_liquidity` function that does not define the `use_eth` parameter.\\n```\\nFile: Curve2TokenConvexVault.sol\\n    function _joinPoolAndStake(\\n..SNIP..\\n        // Slightly different method signatures in v1 and v2\\n        if (IS_CURVE_V2) {\\n            lpTokens = ICurve2TokenPoolV2(CURVE_POOL).add_liquidity{value: msgValue}(\\n                amounts, minPoolClaim, 0 < msgValue // use_eth = true if msgValue > 0\\n            );\\n        } else {\\n            lpTokens = ICurve2TokenPoolV1(CURVE_POOL).add_liquidity{value: msgValue}(\\n                amounts, minPoolClaim\\n            );\\n        }\\n```\\n\\nIf the `use_eth` parameter is not defined, it will default to `False`. As a result, the Curve pool expects the caller to transfer over the WETH to the pool and the pool will call `WETH.withdraw` to unwrap the WETH to Native ETH as shown in the code below.\\nHowever, Notional's leverage vault only works with Native ETH, and if one of the pool tokens is WETH, it will explicitly convert the address to either the `Deployments.ALT_ETH_ADDRESS` (0xEeeee) or `Deployments.ETH_ADDRESS` (address(0)) during deployment and initialization.\\nThe implementation of the above `_joinPoolAndStake` function will forward Native ETH to the Curve Pool, while the pool expects the vault to transfer in WETH. As a result, a revert will occur since the pool did not receive the WETH it required during the unwrap process.\\n```\\ndef add_liquidity(\\n    amounts: uint256[N_COINS],\\n    min_mint_amount: uint256,\\n    use_eth: bool = False,\\n    receiver: address = msg.sender\\n) -> uint256:\\n    """\\n    @notice Adds liquidity into the pool.\\n    @param amounts Amounts of each coin to add.\\n    @param min_mint_amount Minimum amount of LP to mint.\\n    @param use_eth True if native token is being added to the pool.\\n    @param receiver Address to send the LP tokens to. Default is msg.sender\\n    @return uint256 Amount of LP tokens received by the `receiver\\n    """\\n..SNIP..\\n    # --------------------- Get prices, balances -----------------------------\\n..SNIP..\\n    # -------------------------------------- Update balances and calculate xp.\\n..SNIP// rest of code\\n    # ---------------- transferFrom token into the pool ----------------------\\n\\n    for i in range(N_COINS):\\n\\n        if amounts[i] > 0:\\n\\n            if coins[i] == WETH20:\\n\\n                self._transfer_in(\\n                    coins[i],\\n                    amounts[i],\\n                    0,  # <-----------------------------------\\n                    msg.value,  #                             | No callbacks\\n                    empty(address),  # <----------------------| for\\n                    empty(bytes32),  # <----------------------| add_liquidity.\\n                    msg.sender,  #                            |\\n                    empty(address),  # <-----------------------\\n                    use_eth\\n                )\\n```\\n\\n```\\ndef _transfer_in(\\n..SNIP..\\n    use_eth: bool\\n):\\n..SNIP..\\n    @params use_eth True if the transfer is ETH, False otherwise.\\n    """\\n\\n    if use_eth and _coin == WETH20:\\n        assert mvalue == dx  # dev: incorrect eth amount\\n    else:\\n..SNIP..\\n        if _coin == WETH20:\\n            WETH(WETH20).withdraw(dx)  # <--------- if WETH was transferred in\\n            #           previous step and `not use_eth`, withdraw WETH to ETH.\\n```\\n
Ensure the `IS_CURVE_V2` variable is initialized on the Arbitrum and Optimism side chains according to the Curve Pool's version.\\nIf there is a limitation on the existing approach to determining a pool is V1 or V2 on Arbitrum and Optimsim, an alternative approach might be to use the presence of a `gamma()` function as an indicator of pool type
No users will be able to deposit to the Leverage Vault on Arbitrum and Optimism that supports Curve V2 pools. The deposit function is a core function of any vault. Thus, this issue breaks the core contract functionality of a vault.\\nIn addition, if the affected vaults cannot be used, it leads to a loss of revenue for the protocol.
```\\nFile: Curve2TokenPoolMixin.sol\\n    constructor(\\n        NotionalProxy notional_,\\n        DeploymentParams memory params\\n    ) SingleSidedLPVaultBase(notional_, params.tradingModule) {\\n        CURVE_POOL = params.pool;\\n\\n        bool isCurveV2 = false;\\n        if (Deployments.CHAIN_ID == Constants.CHAIN_ID_MAINNET) {\\n            address[10] memory handlers = \\n                Deployments.CURVE_META_REGISTRY.get_registry_handlers_from_pool(address(CURVE_POOL));\\n\\n            require(\\n                handlers[0] == Deployments.CURVE_V1_HANDLER ||\\n                handlers[0] == Deployments.CURVE_V2_HANDLER\\n            ); // @dev unknown Curve version\\n            isCurveV2 = (handlers[0] == Deployments.CURVE_V2_HANDLER);\\n        }\\n        IS_CURVE_V2 = isCurveV2;\\n```\\n