The use of spot data when discounting is subjected to manipulation
The use of spot data when discounting is subjected to manipulation. As a result, malicious users could receive more cash than expected during redemption by performing manipulation. Since this is a zero-sum, the attacker's gain is the protocol loss.\\nWhen redeeming wfCash before maturity, the `_sellfCash` function will be executed.\\nAssume that there is insufficient fCash left on the wrapper to be sold back to the Notional AMM. In this case, the `getPrincipalFromfCashBorrow` view function will be used to calculate the number of prime cash to be withdrawn for a given fCash amount and sent to the users.\\nNote that the `getPrincipalFromfCashBorrow` view function uses the spot data (spot interest rate, spot utilization, spot totalSupply/totalDebt, etc.) internally when computing the prime cash to be withdrawn for a given fCash. Thus, it is subjected to manipulation.\\n```\\nFile: wfCashLogic.sol\\n    /// @dev Sells an fCash share back on the Notional AMM\\n    function _sellfCash(\\n        address receiver,\\n        uint256 fCashToSell,\\n        uint32 maxImpliedRate\\n    ) private returns (uint256 tokensTransferred) {\\n        (IERC20 token, bool isETH) = getToken(true); \\n        uint256 balanceBefore = isETH ? WETH.balanceOf(address(this)) : token.balanceOf(address(this)); \\n        uint16 currencyId = getCurrencyId(); \\n\\n        (uint256 initialCashBalance, uint256 fCashBalance) = getBalances(); \\n        bool hasInsufficientfCash = fCashBalance < fCashToSell; \\n\\n        uint256 primeCashToWithdraw; \\n        if (hasInsufficientfCash) {\\n            // If there is insufficient fCash, calculate how much prime cash would be purchased if the\\n            // given fCash amount would be sold and that will be how much the wrapper will withdraw and\\n            // send to the receiver. Since fCash always sells at a discount to underlying prior to maturity,\\n            // the wrapper is guaranteed to have sufficient cash to send to the account.\\n            (/* */, primeCashToWithdraw, /* */, /* */) = NotionalV2.getPrincipalFromfCashBorrow( \\n                currencyId,\\n                fCashToSell, \\n                getMaturity(),\\n                0, \\n                block.timestamp\\n            ); \\n            // If this is zero then it signifies that the trade will fail.\\n            require(primeCashToWithdraw > 0, "Redeem Failed"); \\n\\n            // Re-write the fCash to sell to the entire fCash balance.\\n            fCashToSell = fCashBalance;\\n        }\\n```\\n\\nWithin the `CalculationViews.getPrincipalFromfCashBorrow` view function, it will rely on the `InterestRateCurve.calculatefCashTrade` function to compute the cash to be returned based on the current interest rate model.\\nAssume that the current utilization rate is slightly above Kink 1. When Bob redeems his wfCash, the interest rate used falls within the gentle slope between Kink 1 and Kink 2. Let the interest rate based on current utilization be 4%. The amount of fCash will be discounted back with 4% interest rate to find out the cash value (present value) and the returned value is $x$.\\nObserved that before Kink 1, the interest rate changed sharply. If one could nudge the utilization toward the left (toward zero) and cause the utilization to fall between Kink 0 and Kink 1, the interest rate would fall sharply. Since the utilization is computed as on `utilization = totalfCash/totalCashUnderlying`, one could deposit prime cash to the market to increase the denominator (totalCashUnderlying) to bring down the utilization rate.\\nBob deposits a specific amount of prime cash (either by its own funds or flash-loan) to reduce the utilization rate, which results in a reduction in interest rate. Assume that the interest rate reduces to 1.5%. The amount of fCash will be discounted with a lower interest rate of 1.5%, which will result in higher cash value, and the returned value/received cash is $y$.\\n$y > x$. So Bob received $y - x$ more cash compared to if he had not performed the manipulation. Since this is a zero-sum, Bob's gain is the protocol loss.\\n
Avoid using spot data when computing the amount of assets that the user is entitled to during redemption. Consider using a TWAP/Time-lagged oracle to guard against potential manipulation.
Malicious users could receive more cash than expected during redemption by performing manipulation. Since this is a zero-sum, the attacker's gain is the protocol loss.
```\\nFile: wfCashLogic.sol\\n    /// @dev Sells an fCash share back on the Notional AMM\\n    function _sellfCash(\\n        address receiver,\\n        uint256 fCashToSell,\\n        uint32 maxImpliedRate\\n    ) private returns (uint256 tokensTransferred) {\\n        (IERC20 token, bool isETH) = getToken(true); \\n        uint256 balanceBefore = isETH ? WETH.balanceOf(address(this)) : token.balanceOf(address(this)); \\n        uint16 currencyId = getCurrencyId(); \\n\\n        (uint256 initialCashBalance, uint256 fCashBalance) = getBalances(); \\n        bool hasInsufficientfCash = fCashBalance < fCashToSell; \\n\\n        uint256 primeCashToWithdraw; \\n        if (hasInsufficientfCash) {\\n            // If there is insufficient fCash, calculate how much prime cash would be purchased if the\\n            // given fCash amount would be sold and that will be how much the wrapper will withdraw and\\n            // send to the receiver. Since fCash always sells at a discount to underlying prior to maturity,\\n            // the wrapper is guaranteed to have sufficient cash to send to the account.\\n            (/* */, primeCashToWithdraw, /* */, /* */) = NotionalV2.getPrincipalFromfCashBorrow( \\n                currencyId,\\n                fCashToSell, \\n                getMaturity(),\\n                0, \\n                block.timestamp\\n            ); \\n            // If this is zero then it signifies that the trade will fail.\\n            require(primeCashToWithdraw > 0, "Redeem Failed"); \\n\\n            // Re-write the fCash to sell to the entire fCash balance.\\n            fCashToSell = fCashBalance;\\n        }\\n```\\n