Incorrect pricing for CurveV2 LP Token
Using the Curve rETH/frxETH pool (0xe7c6e0a739021cdba7aac21b4b728779eef974d9) to illustrate the issue:\\nThe price of the LP token of Curve rETH/frxETH pool can be obtained via the following `lp_price` function:\\n```\\ndef lp_price() -> uint256:\\n    """\\n    Approximate LP token price\\n    """\\n    return 2 * self.virtual_price * self.sqrt_int(self.internal_price_oracle()) / 10**18\\n```\\n\\nThus, the formula to obtain the price of the LP token is as follows:\\n$$ price_{LP} = 2 \\times virtualPrice \\times \\sqrt{internalPriceOracle} $$\\n```\\ndef price_oracle() -> uint256:\\n    return self.internal_price_oracle()\\n```\\n\\nThe $internalPriceOracle$ is the price of coins[1](frxETH) with coins[0](rETH) as the quote currency, which means how many rETH (quote) are needed to purchase one frxETH (base).\\n$$ base/quote \\ frxETH/rETH $$\\nDuring pool registration, the `poolInfo.tokenToPrice` is always set to the second coin (coins[1]) as per Line 131 below. In this example, `poolInfo.tokenToPrice` will be set to frxETH token address (coins[1]).\\n```\\nFile: CurveV2CryptoEthOracle.sol\\n    function registerPool(address curvePool, address curveLpToken, bool checkReentrancy) external onlyOwner {\\n..SNIP..\\n        /**\\n         * Curve V2 pools always price second token in `coins` array in first token in `coins` array.  This means that\\n         *    if `coins[0]` is Weth, and `coins[1]` is rEth, the price will be rEth as base and weth as quote.  Hence\\n         *    to get lp price we will always want to use the second token in the array, priced in eth.\\n         */\\n        lpTokenToPool[lpToken] =\\n            PoolData({ pool: curvePool, checkReentrancy: checkReentrancy ? 1 : 0, tokenToPrice: tokens[1] });\\n```\\n\\nNote that `assetPrice` variable below is equivalent to $internalPriceOracle$ in the above formula.\\nWhen fetching the price of the LP token, Line 166 computes the price of frxETH with ETH as the quote currency ($frxETH/ETH$) via the `getPriceInEth` function, and assigns to the `assetPrice` variable.\\nHowever, the $internalPriceOracle$ or `assetPrice` should be $frxETH/rETH$ instead of $frxETH/ETH$. Thus, the price of the LP token computed will be incorrect.\\n```\\nFile: CurveV2CryptoEthOracle.sol\\n    function getPriceInEth(address token) external returns (uint256 price) {\\n        Errors.verifyNotZero(token, "token");\\n\\n        PoolData memory poolInfo = lpTokenToPool[token];\\n        if (poolInfo.pool == address(0)) revert NotRegistered(token);\\n\\n        ICryptoSwapPool cryptoPool = ICryptoSwapPool(poolInfo.pool);\\n\\n        // Checking for read only reentrancy scenario.\\n        if (poolInfo.checkReentrancy == 1) {\\n            // This will fail in a reentrancy situation.\\n            cryptoPool.claim_admin_fees();\\n        }\\n\\n        uint256 virtualPrice = cryptoPool.get_virtual_price();\\n        uint256 assetPrice = systemRegistry.rootPriceOracle().getPriceInEth(poolInfo.tokenToPrice);\\n\\n        return (2 * virtualPrice * sqrt(assetPrice)) / 10 ** 18;\\n    }\\n```\\n
Issue Incorrect pricing for CurveV2 LP Token\\nUpdate the `getPriceInEth` function to ensure that the $internalPriceOracle$ or `assetPrice` return the price of `coins[1]` with `coins[0]` as the quote currency.
The protocol relies on the oracle to provide accurate pricing for many critical operations, such as determining the debt values of DV, calculators/stats used during the rebalancing process, NAV/shares of the LMPVault, and determining how much assets the users should receive during withdrawal.\\nIncorrect pricing of LP tokens would result in many implications that lead to a loss of assets, such as users withdrawing more or fewer assets than expected due to over/undervalued vaults or strategy allowing an unprofitable rebalance to be executed.
```\\ndef lp_price() -> uint256:\\n    """\\n    Approximate LP token price\\n    """\\n    return 2 * self.virtual_price * self.sqrt_int(self.internal_price_oracle()) / 10**18\\n```\\n