PerpDepository#_placePerpOrder miscalculates fees paid when shorting
PerpDepository#_placePerpOrder calculates the fee as a percentage of the quoteToken received. The issue is that this amount already has the fees taken so the fee percentage is being applied incorrectly.\\n```\\nfunction _placePerpOrder(\\n    uint256 amount,\\n    bool isShort,\\n    bool amountIsInput,\\n    uint160 sqrtPriceLimit\\n) private returns (uint256, uint256) {\\n    uint256 upperBound = 0; // 0 = no limit, limit set by sqrtPriceLimit\\n\\n    IClearingHouse.OpenPositionParams memory params = IClearingHouse\\n        .OpenPositionParams({\\n            baseToken: market,\\n            isBaseToQuote: isShort, // true for short\\n            isExactInput: amountIsInput, // we specify exact input amount\\n            amount: amount, // collateral amount - fees\\n            oppositeAmountBound: upperBound, // output upper bound\\n            // solhint-disable-next-line not-rely-on-time\\n            deadline: block.timestamp,\\n            sqrtPriceLimitX96: sqrtPriceLimit, // max slippage\\n            referralCode: 0x0\\n        });\\n\\n    (uint256 baseAmount, uint256 quoteAmount) = clearingHouse.openPosition(\\n        params\\n    );\\n\\n    uint256 feeAmount = _calculatePerpOrderFeeAmount(quoteAmount);\\n    totalFeesPaid += feeAmount;\\n\\n    emit PositionOpened(isShort, amount, amountIsInput, sqrtPriceLimit);\\n    return (baseAmount, quoteAmount);\\n}\\n\\nfunction _calculatePerpOrderFeeAmount(uint256 amount)\\n    internal\\n    view\\n    returns (uint256)\\n{\\n    return amount.mulWadUp(getExchangeFeeWad());\\n}\\n```\\n\\nWhen calculating fees, `PerpDepository#_placePerpOrder` use the quote amount retuned when opening the new position. It always uses exactIn which means that for shorts the amount of baseAsset being sold is specified. The result is that quote amount returned is already less the fees. If we look at how the fee is calculated we can see that it is incorrect.\\nExample: Imagine the market price of ETH is $1000 and there is a market fee of 1%. The 1 ETH is sold and the contract receives 990 USD. Using the math above it would calculated the fee as $99 (990 * 1%) but actually the fee is $100.\\nIt have submitted this as a medium because it is not clear from the given contracts what the fee totals are used for and I cannot fully assess the implications of the fee value being incorrect.
Rewrite _calculatePerpOrderFeeAmount to correctly calculate the fees paid:\\n```\\n-   function _calculatePerpOrderFeeAmount(uint256 amount)\\n+   function _calculatePerpOrderFeeAmount(uint256 amount, bool isShort)\\n        internal\\n        view\\n        returns (uint256)\\n    {\\n+       if (isShort) {\\n+           return amount.divWadDown(WAD - getExchangeFeeWad()) - amount;\\n+       } else {\\n            return amount.mulWadUp(getExchangeFeeWad());\\n+       }\\n    }\\n```\\n
totalFeesPaid will be inaccurate which could lead to disparities in other contracts depending on how it is used
```\\nfunction _placePerpOrder(\\n    uint256 amount,\\n    bool isShort,\\n    bool amountIsInput,\\n    uint160 sqrtPriceLimit\\n) private returns (uint256, uint256) {\\n    uint256 upperBound = 0; // 0 = no limit, limit set by sqrtPriceLimit\\n\\n    IClearingHouse.OpenPositionParams memory params = IClearingHouse\\n        .OpenPositionParams({\\n            baseToken: market,\\n            isBaseToQuote: isShort, // true for short\\n            isExactInput: amountIsInput, // we specify exact input amount\\n            amount: amount, // collateral amount - fees\\n            oppositeAmountBound: upperBound, // output upper bound\\n            // solhint-disable-next-line not-rely-on-time\\n            deadline: block.timestamp,\\n            sqrtPriceLimitX96: sqrtPriceLimit, // max slippage\\n            referralCode: 0x0\\n        });\\n\\n    (uint256 baseAmount, uint256 quoteAmount) = clearingHouse.openPosition(\\n        params\\n    );\\n\\n    uint256 feeAmount = _calculatePerpOrderFeeAmount(quoteAmount);\\n    totalFeesPaid += feeAmount;\\n\\n    emit PositionOpened(isShort, amount, amountIsInput, sqrtPriceLimit);\\n    return (baseAmount, quoteAmount);\\n}\\n\\nfunction _calculatePerpOrderFeeAmount(uint256 amount)\\n    internal\\n    view\\n    returns (uint256)\\n{\\n    return amount.mulWadUp(getExchangeFeeWad());\\n}\\n```\\n