Unsafe downcasting arithmetic operation in UserManager related contract and in UToken.sol
The value is unsafely downcasted and truncated from uint256 to uint96 or uint128 in UserManager related contract and in UToken.sol.\\nvalue can unsafely downcasted. let us look at it cast by cast.\\nIn UserManagerDAI.sol\\n```\\n  function stakeWithPermit(\\n      uint256 amount,\\n      uint256 nonce,\\n      uint256 expiry,\\n      uint8 v,\\n      bytes32 r,\\n      bytes32 s\\n  ) external whenNotPaused {\\n      IDai erc20Token = IDai(stakingToken);\\n      erc20Token.permit(msg.sender, address(this), nonce, expiry, true, v, r, s);\\n\\n      stake(uint96(amount));\\n  }\\n```\\n\\nas we can see, the user's staking amount is downcasted from uint256 to uint96.\\nthe same issue exists in UserManagerERC20.sol\\nIn the context of UToken.sol, a bigger issue comes.\\nUser invokes the borrow function in UToken.sol\\n```\\n   function borrow(address to, uint256 amount) external override onlyMember(msg.sender) whenNotPaused nonReentrant {\\n```\\n\\nand\\n```\\n  // Withdraw the borrowed amount of tokens from the assetManager and send them to the borrower\\n  if (!assetManagerContract.withdraw(underlying, to, amount)) revert WithdrawFailed();\\n\\n  // Call update locked on the userManager to lock this borrowers stakers. This function\\n  // will revert if the account does not have enough vouchers to cover the borrow amount. ie\\n  // the borrower is trying to borrow more than is able to be underwritten\\n  IUserManager(userManager).updateLocked(msg.sender, uint96(amount + fee), true);\\n```\\n\\nnote when we withdraw fund from asset Manager, we use a uint256 amount, but we downcast it to uint96(amount + fee) when updating the locked. The accounting would be so broken if the amount + fee is a larger than uint96 number.\\nSame issue in the function UToken.sol# _repayBorrowFresh\\n```\\n    function _repayBorrowFresh(\\n        address payer,\\n        address borrower,\\n        uint256 amount\\n    ) internal {\\n```\\n\\nand\\n```\\n  // Update the account borrows to reflect the repayment\\n  accountBorrows[borrower].principal = borrowedAmount - repayAmount;\\n  accountBorrows[borrower].interest = 0;\\n```\\n\\nand\\n```\\n IUserManager(userManager).updateLocked(borrower, uint96(repayAmount - interest), false);\\n```\\n\\nwe use a uint256 number for borrowedAmount - repayAmount, but downcast it to uint96(repayAmount - interest) when updating the lock!\\nNote there are index-related downcasting, the damage is small , comparing the accounting related downcasting.because it is difference to have uint128 amount of vouch, but I still want to mention it: the index is unsafely downcasted from uint256 to uint128\\n```\\n  // Get the new index that this vouch is going to be inserted at\\n  // Then update the voucher indexes for this borrower as well as\\n  // Adding the Vouch the the vouchers array for this staker\\n  uint256 voucherIndex = vouchers[borrower].length;\\n  voucherIndexes[borrower][staker] = Index(true, uint128(voucherIndex));\\n  vouchers[borrower].push(Vouch(staker, trustAmount, 0, 0));\\n\\n  // Add the voucherIndex of this new vouch to the vouchees array for this\\n  // staker then update the voucheeIndexes with the voucheeIndex\\n  uint256 voucheeIndex = voucheesLength;\\n  vouchees[staker].push(Vouchee(borrower, uint96(voucherIndex)));\\n  voucheeIndexes[borrower][staker] = Index(true, uint128(voucheeIndex));\\n```\\n\\nThere are block.number related downcasting, which is a smaller issue.\\n```\\nvouch.lastUpdated = uint64(block.number);\\n```\\n
Just use uint256, or use openzepplin safeCasting.
The damage level from the number truncation is rated by:\\nUToken borrow and repaying downcasting > staking amount downcating truncation > the vouch index related downcasting. > block.number casting.
```\\n  function stakeWithPermit(\\n      uint256 amount,\\n      uint256 nonce,\\n      uint256 expiry,\\n      uint8 v,\\n      bytes32 r,\\n      bytes32 s\\n  ) external whenNotPaused {\\n      IDai erc20Token = IDai(stakingToken);\\n      erc20Token.permit(msg.sender, address(this), nonce, expiry, true, v, r, s);\\n\\n      stake(uint96(amount));\\n  }\\n```\\n