Incorrect price used when updating the global position data
Incorrect price used when updating the global position data leading to a loss of assets for LPs.\\nNear the end of the liquidation process, the `updateGlobalPositionData` function at Line 159 will be executed to update the global position data. However, when executing the `updateGlobalPositionData` function, the code sets the price at Line 160 below to the position's last price (position.lastPrice), which is incorrect. The price should be set to the current price instead, and not the position's last price.\\n```\\nFile: LiquidationModule.sol\\n    /// @notice Function to liquidate a position.\\n    /// @dev One could directly call this method instead of `liquidate(uint256, bytes[])` if they don't want to update the Pyth price.\\n    /// @param tokenId The token ID of the leverage position.\\n    function liquidate(uint256 tokenId) public nonReentrant whenNotPaused liquidationInvariantChecks(vault, tokenId) {\\n        FlatcoinStructs.Position memory position = vault.getPosition(tokenId);\\n\\n        (uint256 currentPrice, ) = IOracleModule(vault.moduleAddress(FlatcoinModuleKeys._ORACLE_MODULE_KEY)).getPrice();\\n\\n        // Settle funding fees accrued till now.\\n        vault.settleFundingFees();\\n\\n        // Check if the position can indeed be liquidated.\\n        if (!canLiquidate(tokenId)) revert FlatcoinErrors.CannotLiquidate(tokenId);\\n\\n        FlatcoinStructs.PositionSummary memory positionSummary = PerpMath._getPositionSummary(\\n            position,\\n            vault.cumulativeFundingRate(),\\n            currentPrice\\n        );\\n..SNIP..\\n        vault.updateGlobalPositionData({\\n            price: position.lastPrice,\\n            marginDelta: -(int256(position.marginDeposited) + positionSummary.accruedFunding),\\n            additionalSizeDelta: -int256(position.additionalSize) // Since position is being closed, additionalSizeDelta should be negative.\\n        });\\n```\\n\\nThe reason why the `updateGlobalPositionData` function expects a current price to be passed in is that within the `PerpMath._profitLossTotal` function, it will compute the price shift between the current price and the last price to obtain the PnL of all the open positions. Also, per the comment at Line 170 below, it expects the current price of the collateral to be passed in.\\nThus, it is incorrect to pass in the individual position's last/entry price, which is usually the price of the collateral when the position was first opened or adjusted some time ago.\\nThus, if the last/entry price of the liquidated position is higher than the current price of collateral, the PnL will be inflated, indicating more gain for the long traders. Since this is a zero-sum game, this also means that the LP loses more assets than expected due to the inflated gain of the long traders.\\n```\\nFile: FlatcoinVault.sol\\n    /// @notice Function to update the global position data.\\n    /// @dev This function is only callable by the authorized modules.\\n    /// @param _price The current price of the underlying asset.\\n    /// @param _marginDelta The change in the margin deposited total.\\n    /// @param _additionalSizeDelta The change in the size opened total.\\n    function updateGlobalPositionData(\\n        uint256 _price,\\n        int256 _marginDelta,\\n        int256 _additionalSizeDelta\\n    ) external onlyAuthorizedModule {\\n        // Get the total profit loss and update the margin deposited total.\\n        int256 profitLossTotal = PerpMath._profitLossTotal({globalPosition: _globalPositions, price: _price});\\n\\n        // Note that technically, even the funding fees should be accounted for when computing the margin deposited total.\\n        // However, since the funding fees are settled at the same time as the global position data is updated,\\n        // we can ignore the funding fees here.\\n        int256 newMarginDepositedTotal = int256(_globalPositions.marginDepositedTotal) + _marginDelta + profitLossTotal;\\n\\n        // Check that the sum of margin of all the leverage traders is not negative.\\n        // Rounding errors shouldn't result in a negative margin deposited total given that\\n        // we are rounding down the profit loss of the position.\\n        // If anything, after closing the last position in the system, the `marginDepositedTotal` should can be positive.\\n        // The margin may be negative if liquidations are not happening in a timely manner.\\n        if (newMarginDepositedTotal < 0) {\\n            revert FlatcoinErrors.InsufficientGlobalMargin();\\n        }\\n\\n        _globalPositions = FlatcoinStructs.GlobalPositions({\\n            marginDepositedTotal: uint256(newMarginDepositedTotal),\\n            sizeOpenedTotal: (int256(_globalPositions.sizeOpenedTotal) + _additionalSizeDelta).toUint256(),\\n            lastPrice: _price\\n        });\\n```\\n
Use the current price instead of liquidated position's last price when update the global position data\\n```\\n(uint256 currentPrice, ) = IOracleModule(vault.moduleAddress(FlatcoinModuleKeys._ORACLE_MODULE_KEY)).getPrice();\\n..SNIP..\\nvault.updateGlobalPositionData({\\n// Remove the line below\\n    price: position.lastPrice,\\n// Add the line below\\n    price: currentPrice,    \\n    marginDelta: // Remove the line below\\n(int256(position.marginDeposited) // Add the line below\\n positionSummary.accruedFunding),\\n    additionalSizeDelta: // Remove the line below\\nint256(position.additionalSize) // Since position is being closed, additionalSizeDelta should be negative.\\n});\\n```\\n
Loss of assets for the LP as mentioned in the above section.
```\\nFile: LiquidationModule.sol\\n    /// @notice Function to liquidate a position.\\n    /// @dev One could directly call this method instead of `liquidate(uint256, bytes[])` if they don't want to update the Pyth price.\\n    /// @param tokenId The token ID of the leverage position.\\n    function liquidate(uint256 tokenId) public nonReentrant whenNotPaused liquidationInvariantChecks(vault, tokenId) {\\n        FlatcoinStructs.Position memory position = vault.getPosition(tokenId);\\n\\n        (uint256 currentPrice, ) = IOracleModule(vault.moduleAddress(FlatcoinModuleKeys._ORACLE_MODULE_KEY)).getPrice();\\n\\n        // Settle funding fees accrued till now.\\n        vault.settleFundingFees();\\n\\n        // Check if the position can indeed be liquidated.\\n        if (!canLiquidate(tokenId)) revert FlatcoinErrors.CannotLiquidate(tokenId);\\n\\n        FlatcoinStructs.PositionSummary memory positionSummary = PerpMath._getPositionSummary(\\n            position,\\n            vault.cumulativeFundingRate(),\\n            currentPrice\\n        );\\n..SNIP..\\n        vault.updateGlobalPositionData({\\n            price: position.lastPrice,\\n            marginDelta: -(int256(position.marginDeposited) + positionSummary.accruedFunding),\\n            additionalSizeDelta: -int256(position.additionalSize) // Since position is being closed, additionalSizeDelta should be negative.\\n        });\\n```\\n