Vulnerability: `ExternalLending`
Severity: medium

Description:
When the Treasury rebalances and has to redeem aTokens from AaveV3, it checks that the actual amount withdrawn is greater than or equal to the set `withdrawAmount`. This check will always fail for fee-on-transfer tokens since the `withdrawAmount` does not account for the transfer fee.\\n```\\n        address[] memory targets = new address[](UNDERLYING_IS_ETH ? 2 : 1);\\n        bytes[] memory callData = new bytes[](UNDERLYING_IS_ETH ? 2 : 1);\\n        targets[0] = LENDING_POOL;\\n        callData[0] = abi.encodeWithSelector(\\n            ILendingPool.withdraw.selector, underlyingToken, withdrawAmount, address(NOTIONAL)\\n        );\\n\\n        if (UNDERLYING_IS_ETH) {\\n            // Aave V3 returns WETH instead of native ETH so we have to unwrap it here\\n            targets[1] = address(Deployments.WETH);\\n            callData[1] = abi.encodeWithSelector(WETH9.withdraw.selector, withdrawAmount);\\n        }\\n\\n        data = new RedeemData[](1);\\n        // Tokens with less than or equal to 8 decimals sometimes have off by 1 issues when depositing\\n        // into Aave V3. Aave returns one unit less than has been deposited. This adjustment is applied\\n        // to ensure that this unit of token is credited back to prime cash holders appropriately.\\n        uint8 rebasingTokenBalanceAdjustment = UNDERLYING_DECIMALS <= 8 ? 1 : 0;\\n        data[0] = RedeemData(\\n            targets, callData, withdrawAmount, ASSET_TOKEN, rebasingTokenBalanceAdjustment\\n        );\\n```\\n\\nNote that the third field in the `RedeemData` struct is the `expectedUnderlying` field which is set to the `withdrawAmount` and that `withdrawAmount` is a value greater than zero.\\n```\\n            for (uint256 j; j < data.targets.length; j++) {\\n                GenericToken.executeLowLevelCall(data.targets[j], 0, data.callData[j]);\\n            }\\n\\n            // Ensure that we get sufficient underlying on every redemption\\n            uint256 newUnderlyingBalance = TokenHandler.balanceOf(underlyingToken, address(this));\\n            uint256 underlyingBalanceChange = newUnderlyingBalance.sub(oldUnderlyingBalance);\\n            // If the call is not the final redemption, then expectedUnderlying should\\n            // be set to zero.\\n            require(data.expectedUnderlying <= underlyingBalanceChange);\\n```\\n\\n```\\nredeemAmounts[0] = currentAmount - targetAmount;\\n```\\n\\nIt does not account for transfer fees. In effect, that check will always revert when the underlying being withdrawn is a fee-on-transfer token.

Impact:
```\\n    uint256 withdrawAmount = uint256(netTransferExternal.neg());\\n    ExternalLending.redeemMoneyMarketIfRequired(currencyId, underlying, withdrawAmount);\\n```\\n\\nThis means that these tokens can only be deposited into AaveV3 but can never redeemed. This can lead to insolvency of the protocol.

Recommended mitigation:
When computing for the `withdrawAmount / data.expectedUnderlying`, it should account for the transfer fees. The pseudocode for the computation may look like so:\\n```\\nwithdrawAmount = currentAmount - targetAmount\\nif (underlyingToken.hasTransferFee) {\\n  withdrawAmount = withdrawAmount / (100% - underlyingToken.transferFeePercent)\\n}\\n```\\n