Wrong order in delta calculation in the `tickCumulatives` could result in wrong `twapTick` thus putting the protocol in a broken and undesirable state (insolvent state)
Audit: 2024-04-panoptic-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2024-04-panoptic/blob/main/contracts/libraries/PanopticMath.sol#L257-L259


# Vulnerability details

## Impact

The `PanopticMath.twapFilter` function is used to compute the `twap` of a Uniswap V3 pool using data from its oracle. The `twap` value in this case computed by taking the the `average price` over a `series of time intervals` and then taking the `median` of those averages.

The computation of the `average price` over a `series of time intervals` is performed as shown below:

```solidity
            for (uint256 i = 0; i < 19; ++i) {
                twapMeasurement[i] = int24(
                    (tickCumulatives[i] - tickCumulatives[i + 1]) / int56(uint56(twapWindow / 20))
                );
            }
```

The `tickCumulatives` value above represents the `cumulative sum` of the `active tick` at the `time of the observation`. This tick accumulator value increases monotonically and grows by the value of the current tick - per second (As per the Uniswap Docs).

Hence it is clear there is an error in the above depicted code snippet since the delta of the two observations (tickCumulatives) is taken in the reverse order `tickCumulatives[i] - tickCumulatives[i + 1]` where as this should be taken as `tickCumulatives[i + 1] - tickCumulatives[i]` since the `tickCumulatives` values increase monotonically.

Since the order of `tickCumulatives` used to compute the `twap` is erroneous this will result in wrong value for `twap`. (Eg: if correct `twap` value is positive the `twapFilter` function will return the negative value of it and vice versa).

The `PanopticMath.twapFilter` function is called by the `PanopticPool.getUniV3TWAP` function. The `PanopticPool.liquidate` and `PanopticPool.forceExercise` functions call the `getUniV3TWAP` function in their transaction execution flows.

In the case of `PanopticPool.liquidate` function execution the following issues may occur due to above explained vulnerability.

The `liquidate` function performs the following check to ensure the maximum allowed delta between the `currentTick` and the `Uniswap TWAP tick` during a liquidation is not exceeded (if it exceeds then the transaction will revert).

```solidity
            if (Math.abs(currentTick - twapTick) > MAX_TWAP_DELTA_LIQUIDATION) 
                revert Errors.StaleTWAP();
```

Issue here is since the returned `twapTick` is of opposit sign value the above condition will result in `true` and transaction will revert even if it should have resulted in `false`. Because if the correct `twapTick` is positive the `currentTick - twapTick` value will be less. But since the returned `twapTick` by the `PanopticMath.twapFilter` is negative this will result in `currentTick - (-twapTick) => currentTick + twapTick` thus increasing on the total which could be `> MAX_TWAP_DELTA_LIQUIDATION` thus reverting the transaction. Hence this will revert a valid `liquidation` thus putting the protocol into broken state and a state of