Attackers can call UToken.redeem() and drain the funds in assetManager
Attackers can call `UToken.redeem()` and drain the funds in assetManager, taking advantage of the following vulnerability: due to round error, it is possible that uTokenAmount = 0; the redeem()function does not check whether `uTokenAmount = 0` and will redeem the amount of `underlyingAmount` even when zero uTokens are burned.\\nConsider the following attack scenario:\\nSuppose `exchangeRate = 1000 WAD`, that is each utoken exchanges for 1000 underlying tokens.\\nAttacker B calls `redeem(0, 999)`, then the else-part of the following code will get executed:\\n```\\n if (amountIn > 0) {\\n            // We calculate the exchange rate and the amount of underlying to be redeemed:\\n            // uTokenAmount = amountIn\\n            // underlyingAmount = amountIn x exchangeRateCurrent\\n            uTokenAmount = amountIn;\\n            underlyingAmount = (amountIn * exchangeRate) / WAD;\\n        } else {\\n            // We get the current exchange rate and calculate the amount to be redeemed:\\n            // uTokenAmount = amountOut / exchangeRate\\n            // underlyingAmount = amountOut\\n            uTokenAmount = (amountOut * WAD) / exchangeRate;\\n            underlyingAmount = amountOut;\\n        }\\n```\\n\\nwe have `uTokenAmount = 999*WAD/1000WAD = 0`, and `underlyingAmount = 999`.\\nSince `redeeem()` does not check whether `uTokenAmount = 0` and the function will proceed. When finished, the attacker will get 999 underlying tokens, but burned no utokens. He stole 999 underlying tokens.\\nThe attacker can accomplish draining the `assetManger` by writing a malicious contract/function using a loop to run `redeem(0, exchangeRate/WAD-1)` multiple times (as long as not running of gas) and will be able to steal more funds in one SINGLE transaction. Running this transaction a few times will drain `assetManager` easily. This attack will be successful when `exchangeRate/WAD-1 > 0`. Here we need to consider that `exchangeRate` might change due to the decreasing of `totalReeemable`. So in each iteration, when we call `redeem(0, exchangeRate/WAD-1)`, the second argument is recalculated.
Issue Attackers can call UToken.redeem() and drain the funds in assetManager\\nRevise `redeem()` so that it will revert when `uTokenAmount = 0`.
An attacker can keep calling redeem() and drain the funds in `assetManager`.
```\\n if (amountIn > 0) {\\n            // We calculate the exchange rate and the amount of underlying to be redeemed:\\n            // uTokenAmount = amountIn\\n            // underlyingAmount = amountIn x exchangeRateCurrent\\n            uTokenAmount = amountIn;\\n            underlyingAmount = (amountIn * exchangeRate) / WAD;\\n        } else {\\n            // We get the current exchange rate and calculate the amount to be redeemed:\\n            // uTokenAmount = amountOut / exchangeRate\\n            // underlyingAmount = amountOut\\n            uTokenAmount = (amountOut * WAD) / exchangeRate;\\n            underlyingAmount = amountOut;\\n        }\\n```\\n