Vulnerability: boundedSub() might fail to return the result that is bounded to prevent overflows
Severity: medium

Description:
The goal of `boundedSub()` is to bound the result regardless what the inputs are to prevent overflows/underflows. However, the goal is not achieved for some cases. As a result, `boundedSub()` still might underflow and still might revert. The goal of the function is not achieved.\\nAs a result, the protocol might not be fault-tolerant as it is supposed to be - when `boundedSub()` is designed to not revert in any case, it still might revert. For example, function `MarketUtils.getNextFundingAmountPerSize()` will be affected.\\n`boundedSub()` is designed to always bound its result between `type(int256).min` and `type(int256).max` so that it will never overflow/underflow:\\nIt achieves its goal in three cases:\\nCase 1: `if either a or b is zero or the signs are the same there should not be any overflow`.\\nCase 2: `a > 0`, and `b < 0`, and `a-b > type(int256).max`, then we need to return `type(int256).max`.\\nCase 3: `a < 0`, and `b > 0`, and a - b < `type(int256).min`, then we need to return `type(int256).min`\\nUnfortunately, the third case is implemented wrongly as follows:\\n```\\n // if subtracting `b` from `a` would result in a value less than the min int256 value\\n        // then return the min int256 value\\n        if (a < 0 && b <= type(int256).min - a) {\\n            return type(int256).min;\\n        }\\n```\\n\\nwhich essentially is checking a < 0 && b + a <= `type(int256).min`, a wrong condition to check. Because of using this wrong condition, underflow cases will not be detected and the function will revert instead of returning `type(int256).min` in this case.\\nTo verify, suppose a = `type(int256).min` and b = 1, `a-b` needs to be bounded to prevent underflow and the function should have returned `type(int256).min`. However, the function will fail the condition, as a result, it will not execute the if part, and the following final line will be executed instead:\\n```\\nreturn a - b;\\n```\\n\\nAs a result, instead of returning the minimum, the function will revert in the last line due to underflow. This violates the property of the function: it should have returned the bounded result `type(int256).min` and should not have reverted in any case.\\nThe following POC in Remix can show that the following function will revert:\\n```\\nfunction testBoundedSub() public pure returns (int256){\\n              return boundedSub(type(int256).min+3, 4);\\n}\\n```\\n

Impact:
`boundedSub()` does not guarantee underflow/overflow free as it is designed to be. As a result, the protocol might break at points when it is not supposed to break. For example, function `MarketUtils.getNextFundingAmountPerSize()` will be affected.

Recommended mitigation:
The correction is as follows:\\n```\\n function boundedSub(int256 a, int256 b) internal pure returns (int256) {\\n        // if either a or b is zero or the signs are the same there should not be any overflow\\n        if (a == 0 || b == 0 || (a > 0 && b > 0) || (a < 0 && b < 0)) {\\n            return a // Remove the line below\\n b;\\n        }\\n\\n        // if adding `// Remove the line below\\nb` to `a` would result in a value greater than the max int256 value\\n        // then return the max int256 value\\n        if (a > 0 && // Remove the line below\\nb >= type(int256).max // Remove the line below\\n a) {\\n            return type(int256).max;\\n        }\\n\\n        // if subtracting `b` from `a` would result in a value less than the min int256 value\\n        // then return the min int256 value\\n// Remove the line below\\n        if (a < 0 && b <= type(int256).min // Remove the line below\\n a) {\\n// Add the line below\\n        if (a < 0 && a <= type(int256).min // Add the line below\\n b) {\\n            return type(int256).min;\\n        }\\n\\n        return a // Remove the line below\\n b;\\n    }\\n```\\n