Lyra vault underestimates the collateral value
Lyra vault subtracts the withdrawal fee while calculating the collateral value in USD, and it does not match the actual Lyra Pool implementation.\\nThe user's collateral value is estimated using the function `priceCollateralToUSD()` at `Vault_Lyra.sol#L77` as follows.\\n```\\nfunction priceCollateralToUSD(bytes32 _currencyKey, uint256 _amount) public view override returns(uint256){\\n        //The LiquidityPool associated with the LP Token is used for pricing\\n    ILiquidityPoolAvalon LiquidityPool = ILiquidityPoolAvalon(collateralBook.liquidityPoolOf(_currencyKey));\\n    //we have already checked for stale greeks so here we call the basic price function.\\n    uint256 tokenPrice = LiquidityPool.getTokenPrice();\\n    uint256 withdrawalFee = _getWithdrawalFee(LiquidityPool);\\n    uint256 USDValue  = (_amount * tokenPrice) / LOAN_SCALE;\\n    //we remove the Liquidity Pool withdrawalFee\\n    //as there's no way to remove the LP position without paying this.\\n    uint256 USDValueAfterFee = USDValue * (LOAN_SCALE- withdrawalFee)/LOAN_SCALE;\\n    return(USDValueAfterFee);\\n}\\n```\\n\\nSo it is understood that the withdrawal fee is removed to get the reasonable value of the collateral. But according to the Lyra Pool implementation, the token price used for withdrawal is calculated using the function `_getTotalBurnableTokens`. And the function `_getTotalBurnableTokens` is as belows.\\n```\\nfunction _getTotalBurnableTokens()\\n    internal\\n    returns (\\n      uint tokensBurnable,\\n      uint tokenPriceWithFee,\\n      bool stale\\n    )\\n  {\\n    uint burnableLiquidity;\\n    uint tokenPrice;\\n    (tokenPrice, stale, burnableLiquidity) = _getTokenPriceAndStale();\\n\\n    if (optionMarket.getNumLiveBoards() != 0) {\\n      tokenPriceWithFee = tokenPrice.multiplyDecimal(DecimalMath.UNIT - lpParams.withdrawalFee);\\n    } else {\\n      tokenPriceWithFee = tokenPrice;//@audit withdrawalFee is not applied if there are no live borads\\n    }\\n\\n    return (burnableLiquidity.divideDecimal(tokenPriceWithFee), tokenPriceWithFee, stale);\\n  }\\n```\\n\\nFrom the code, it is clear that the withdrawal fee is subtracted only when the related option market has live boards. Because `Vault_Lyra.sol` applies a withdrawal fee all the time to price the collateral, it means the user's collateral is under-valued.
Make sure to apply withdrawal fee consistent to how Lyra pool does.
User's collaterals are under-valued than reasonable and might get to a liquidatable status sooner than expected. A liquidator can abuse this to get an unfair profit by liquidating the user's collateral with the under-estimated value and withdrawing it from the Lyra pool without paying a withdrawal fee.
```\\nfunction priceCollateralToUSD(bytes32 _currencyKey, uint256 _amount) public view override returns(uint256){\\n        //The LiquidityPool associated with the LP Token is used for pricing\\n    ILiquidityPoolAvalon LiquidityPool = ILiquidityPoolAvalon(collateralBook.liquidityPoolOf(_currencyKey));\\n    //we have already checked for stale greeks so here we call the basic price function.\\n    uint256 tokenPrice = LiquidityPool.getTokenPrice();\\n    uint256 withdrawalFee = _getWithdrawalFee(LiquidityPool);\\n    uint256 USDValue  = (_amount * tokenPrice) / LOAN_SCALE;\\n    //we remove the Liquidity Pool withdrawalFee\\n    //as there's no way to remove the LP position without paying this.\\n    uint256 USDValueAfterFee = USDValue * (LOAN_SCALE- withdrawalFee)/LOAN_SCALE;\\n    return(USDValueAfterFee);\\n}\\n```\\n