`UniV2LPOracle` will malfunction if token0 or token1's `decimals != 18`
When one of the LP token's underlying tokens `decimals` is not 18, the price of the LP token calculated by `UniV2LPOracle` will be wrong.\\n`UniV2LPOracle` is an implementation of Alpha Homora v2's Fair Uniswap's LP Token Pricing Formula:\\nThe Formula ... of combining fair asset prices and fair asset reserves:\\n$$ P = 2\\cdot \\frac{\\sqrt{r_0 \\cdot r_1} \\cdot \\sqrt{p_0\\cdot p_1}}{totalSupply}, $$\\nwhere $r_i$ is the asset ii's pool balance and $p_i$ is the asset $i$'s fair price.\\nHowever, the current implementation wrongful assumes $r_0$ and $r_1$ are always in 18 decimals.\\n```\\nfunction getPrice(address pair) external view returns (uint) {\\n    (uint r0, uint r1,) = IUniswapV2Pair(pair).getReserves();\\n\\n    // 2 * sqrt(r0 * r1 * p0 * p1) / totalSupply\\n    return FixedPointMathLib.sqrt(\\n        r0\\n        .mulWadDown(r1)\\n        .mulWadDown(oracle.getPrice(IUniswapV2Pair(pair).token0()))\\n        .mulWadDown(oracle.getPrice(IUniswapV2Pair(pair).token1()))\\n    )\\n    .mulDivDown(2e27, IUniswapV2Pair(pair).totalSupply());\\n}\\n```\\n\\n```\\nuint256 internal constant WAD = 1e18; // The scalar of ETH and most ERC20s.\\n\\nfunction mulWadDown(uint256 x, uint256 y) internal pure returns (uint256) {\\n    return mulDivDown(x, y, WAD); // Equivalent to (x * y) / WAD rounded down.\\n}\\n```\\n\\n```\\nfunction mulDivDown(\\n    uint256 x,\\n    uint256 y,\\n    uint256 denominator\\n) internal pure returns (uint256 z) {\\n    assembly {\\n        // Store x * y in z for now.\\n        z := mul(x, y)\\n\\n        // Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y))\\n        if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) {\\n            revert(0, 0)\\n        }\\n\\n        // Divide z by the denominator.\\n        z := div(z, denominator)\\n    }\\n}\\n```\\n
Issue `UniV2LPOracle` will malfunction if token0 or token1's `decimals != 18`\\nConsider normalizing r0 and r1 to 18 decimals before using them in the formula.\\nSentiment Team\\nFixed as recommended. PRs here and here.\\nLead Senior Watson\\nConfirmed fix.
When the decimals of one or both tokens in the pair is not 18, the price will be way off.
```\\nfunction getPrice(address pair) external view returns (uint) {\\n    (uint r0, uint r1,) = IUniswapV2Pair(pair).getReserves();\\n\\n    // 2 * sqrt(r0 * r1 * p0 * p1) / totalSupply\\n    return FixedPointMathLib.sqrt(\\n        r0\\n        .mulWadDown(r1)\\n        .mulWadDown(oracle.getPrice(IUniswapV2Pair(pair).token0()))\\n        .mulWadDown(oracle.getPrice(IUniswapV2Pair(pair).token1()))\\n    )\\n    .mulDivDown(2e27, IUniswapV2Pair(pair).totalSupply());\\n}\\n```\\n