previewWithdraw() in AutoPxGlp and AutoPxGmx doesn't rounds up when calculating corresponding shares for assets, even so they are overrides previewWithdraw() in PirexERC4626 which rounds up and withdraw() in all 3 contract assumes and depends on previewWithdraw() to rounds up
Audit: 2022-11-redactedcartel-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2022-11-redactedcartel/blob/03b71a8d395c02324cb9fdaf92401357da5b19d1/src/vaults/AutoPxGlp.sol#L436-L444
https://github.com/code-423n4/2022-11-redactedcartel/blob/03b71a8d395c02324cb9fdaf92401357da5b19d1/src/vaults/AutoPxGlp.sol#L177-L195
https://github.com/code-423n4/2022-11-redactedcartel/blob/03b71a8d395c02324cb9fdaf92401357da5b19d1/src/vaults/AutoPxGmx.sol#L315-L337
https://github.com/code-423n4/2022-11-redactedcartel/blob/03b71a8d395c02324cb9fdaf92401357da5b19d1/src/vaults/AutoPxGmx.sol#L199-L217
https://github.com/code-423n4/2022-11-redactedcartel/blob/03b71a8d395c02324cb9fdaf92401357da5b19d1/src/vaults/PirexERC4626.sol#L156-L165
https://github.com/code-423n4/2022-11-redactedcartel/blob/03b71a8d395c02324cb9fdaf92401357da5b19d1/src/vaults/PirexERC4626.sol#L99-L122


# Vulnerability details

## Impact
Contracts `AutoPxGlp` and `AutoPxGmx` extends `PirexERC4626` and function `withdraw()` and `previewWithdraw()` has been overridden in those contracts. `withdraw()` uses function `previewWithdraw()` to calculate number of shares need to burn for corresponding amount of assets and it assumes and requires `previewWithdraw()` to perform rounds up when calculating amount of shares. but `previewWithdraw()` in `AutoPxGlp` and `AutoPxGmx` don't round up when calculating shares (in `PirexERC4626` function `previewWithdraw()` correctly rounds up, but when the function was overridden the behavior has been changed), this can cause inconsistency and also fund lose because of rounding error in the division. This is wrong implementation of `PirexERC4626` in the child contracts.

## Proof of Concept
This is `withdraw()` code in `PirexERC4626` and `AutoPxGlp` and `AutoPxGmx` contracts:
```
   // PirexERC4626
    function withdraw(
        uint256 assets,
        address receiver,
        address owner
    ) public virtual returns (uint256 shares) {
        shares = previewWithdraw(assets); // No need to check for rounding error, previewWithdraw rounds up.

        if (msg.sender != owner) {
            uint256 allowed = allowance[owner][msg.sender]; // Saves gas for limited approvals.

            if (allowed != type(uint256).max)
                allowance[owner][msg.sender] = allowed - shares;
        }

        beforeWithdraw(owner, assets, shares);

        _burn(owner, shares);

        emit Withdraw(msg.sender, receiver, owner, assets, shares);

        asset.safeTransfer(receiver, assets);

        afterWithdraw(owner, assets, shares);
    }

    /** AutoPxGlp
        @notice Override the withdrawal method to make sure compound is called before withdrawing
     */
    function withdraw(
        uint256 assets,
        address receiver,
        address owner
    ) public override returns (uint256 shares) {
        compound(1, 1, true);

        shares = PirexERC4626.withdraw(assets, receiver, owner);
    }

    // AutoPxGmx
    function withdraw(
        uint256 assets,
        address receiver,
        address