`withdraw` function does not comply with ERC5095
The `withdraw` function of Tranche/PT does not comply with ERC5095 as it does not return the exact amount of underlying assets requested by the users.\\nQ: Is the code/contract expected to comply with any EIPs? Are there specific assumptions around adhering to those EIPs that Watsons should be aware of? EIP20 and IERC5095\\nFollowing is the specification of the `withdraw` function of ERC5095. It stated that the user must receive exactly `underlyingAmount` of underlying tokens.\\nwithdraw Burns principalAmount from holder and sends exactly underlyingAmount of underlying tokens to receiver.\\nHowever, the `withdraw` function does not comply with this requirement.\\nOn a high-level, the reason is that Line 337 will compute the number of shares that need to be redeemed to receive `underlyingAmount` number of underlying tokens from the adaptor. The main problem here is that the division done here is rounded down. Thus, the `sharesRedeem` will be lower than expected. Consequently, when `sharesRedeem` number of shares are redeemed at Line 346 below, the users will not receive an exact number of `underlyingAmount` of underlying tokens.\\n```\\nFile: Tranche.sol\\n    function withdraw(\\n        uint256 underlyingAmount,\\n        address to,\\n        address from\\n    ) external override nonReentrant expired returns (uint256) {\\n        GlobalScales memory _gscales = gscales;\\n        uint256 cscale = _updateGlobalScalesCache(_gscales);\\n\\n        // Compute the shares to be redeemed\\n        uint256 sharesRedeem = underlyingAmount.divWadDown(cscale);\\n        uint256 principalAmount = _computePrincipalTokenRedeemed(_gscales, sharesRedeem);\\n\\n        // Update the global scales\\n        gscales = _gscales;\\n        // Burn PT tokens from `from`\\n        _burnFrom(from, principalAmount);\\n        // Withdraw underlying tokens from the adapter and transfer them to `to`\\n        _target.safeTransfer(address(adapter), sharesRedeem);\\n        (uint256 underlyingWithdrawn, ) = adapter.prefundedRedeem(to);\\n```\\n
Update the `withdraw` function to send exactly `underlyingAmount` number of underlying tokens to the caller so that the Tranche will be aligned with the ERC5095 specification.
The tranche/PT does not align with the ERC5095 specification.
```\\nFile: Tranche.sol\\n    function withdraw(\\n        uint256 underlyingAmount,\\n        address to,\\n        address from\\n    ) external override nonReentrant expired returns (uint256) {\\n        GlobalScales memory _gscales = gscales;\\n        uint256 cscale = _updateGlobalScalesCache(_gscales);\\n\\n        // Compute the shares to be redeemed\\n        uint256 sharesRedeem = underlyingAmount.divWadDown(cscale);\\n        uint256 principalAmount = _computePrincipalTokenRedeemed(_gscales, sharesRedeem);\\n\\n        // Update the global scales\\n        gscales = _gscales;\\n        // Burn PT tokens from `from`\\n        _burnFrom(from, principalAmount);\\n        // Withdraw underlying tokens from the adapter and transfer them to `to`\\n        _target.safeTransfer(address(adapter), sharesRedeem);\\n        (uint256 underlyingWithdrawn, ) = adapter.prefundedRedeem(to);\\n```\\n