Liquidation of PartyA will fail due to underflow errors
Liquidation of PartyA will fail due to underflow errors. As a result, assets will be stuck, and there will be a loss of assets for the counterparty (the creditor) since they cannot receive the liquidated assets.\\n```\\nFile: LiquidationFacetImpl.sol\\n    function liquidatePositionsPartyA(\\n        address partyA,\\n        uint256[] memory quoteIds\\n    ) internal returns (bool) {\\n..SNIP..\\n            (bool hasMadeProfit, uint256 amount) = LibQuote.getValueOfQuoteForPartyA(\\n                accountLayout.symbolsPrices[partyA][quote.symbolId].price,\\n                LibQuote.quoteOpenAmount(quote),\\n                quote\\n            );\\n..SNIP..\\n            if (\\n                accountLayout.liquidationDetails[partyA].liquidationType == LiquidationType.NORMAL\\n            ) {\\n                accountLayout.partyBAllocatedBalances[quote.partyB][partyA] += quote\\n                    .lockedValues\\n                    .cva;\\n                if (hasMadeProfit) {\\n                    accountLayout.partyBAllocatedBalances[quote.partyB][partyA] -= amount;\\n                } else {\\n                    accountLayout.partyBAllocatedBalances[quote.partyB][partyA] += amount;\\n                }\\n            } else if (\\n                accountLayout.liquidationDetails[partyA].liquidationType == LiquidationType.LATE\\n            ) {\\n                accountLayout.partyBAllocatedBalances[quote.partyB][partyA] +=\\n                    quote.lockedValues.cva -\\n                    ((quote.lockedValues.cva * accountLayout.liquidationDetails[partyA].deficit) /\\n                        accountLayout.lockedBalances[partyA].cva);\\n                if (hasMadeProfit) {\\n                    accountLayout.partyBAllocatedBalances[quote.partyB][partyA] -= amount;\\n                } else {\\n                    accountLayout.partyBAllocatedBalances[quote.partyB][partyA] += amount;\\n                }\\n            } else if (\\n                accountLayout.liquidationDetails[partyA].liquidationType == LiquidationType.OVERDUE\\n            ) {\\n                if (hasMadeProfit) {\\n                    accountLayout.partyBAllocatedBalances[quote.partyB][partyA] -= amount;\\n                } else {\\n                    accountLayout.partyBAllocatedBalances[quote.partyB][partyA] +=\\n                        amount -\\n                        ((amount * accountLayout.liquidationDetails[partyA].deficit) /\\n                            uint256(-accountLayout.liquidationDetails[partyA].totalUnrealizedLoss));\\n                }\\n            }\\n```\\n\\nAssume that at this point, the allocated balance of PartyB (accountLayout.partyBAllocatedBalances[quote.partyB][partyA]) only has 1000 USD.\\nIn Line 152 above, the `getValueOfQuoteForPartyA` function is called to compute the PnL of a position. Assume the position has a huge profit of 3000 USD due to a sudden spike in price. For this particular position, PartyA will profit 3000 USD while PartyB will lose 3000 USD.\\nIn this case, 3000 USD needs to be deducted from PartyB's account. However, when the `accountLayout.partyBAllocatedBalances[quote.partyB][partyA] -= amount;` code at Line 170, 182, or 190 gets executed, an underflow error will occur, and the transaction will revert. This is because `partyBAllocatedBalances` is an unsigned integer, and PartyB only has 1000 USD of allocated balance, but the code attempts to deduct 3000 USD.
Consider implementing the following fixes to ensure that the amount to be deducted will never exceed the allocated balance of PartyB to prevent underflow errors from occurring.\\n```\\nif (hasMadeProfit) {\\n// Add the line below\\n amountToDeduct = amount > accountLayout.partyBAllocatedBalances[quote.partyB][partyA] ? accountLayout.partyBAllocatedBalances[quote.partyB][partyA] : amount\\n// Add the line below\\n  accountLayout.partyBAllocatedBalances[quote.partyB][partyA] // Remove the line below\\n= amountToDeduct\\n// Remove the line below\\n    accountLayout.partyBAllocatedBalances[quote.partyB][partyA] // Remove the line below\\n= amount;\\n} else {\\n    accountLayout.partyBAllocatedBalances[quote.partyB][partyA] // Add the line below\\n= amount;\\n}\\n```\\n
Liquidation of PartyA will fail. Since liquidation cannot be completed, the assets that are liable to be liquidated cannot be transferred from PartyA (the debtor) to the counterparty (the creditor). Assets will be stuck, and there will be a loss of assets for the counterparty (the creditor) since they cannot receive the liquidated assets.
```\\nFile: LiquidationFacetImpl.sol\\n    function liquidatePositionsPartyA(\\n        address partyA,\\n        uint256[] memory quoteIds\\n    ) internal returns (bool) {\\n..SNIP..\\n            (bool hasMadeProfit, uint256 amount) = LibQuote.getValueOfQuoteForPartyA(\\n                accountLayout.symbolsPrices[partyA][quote.symbolId].price,\\n                LibQuote.quoteOpenAmount(quote),\\n                quote\\n            );\\n..SNIP..\\n            if (\\n                accountLayout.liquidationDetails[partyA].liquidationType == LiquidationType.NORMAL\\n            ) {\\n                accountLayout.partyBAllocatedBalances[quote.partyB][partyA] += quote\\n                    .lockedValues\\n                    .cva;\\n                if (hasMadeProfit) {\\n                    accountLayout.partyBAllocatedBalances[quote.partyB][partyA] -= amount;\\n                } else {\\n                    accountLayout.partyBAllocatedBalances[quote.partyB][partyA] += amount;\\n                }\\n            } else if (\\n                accountLayout.liquidationDetails[partyA].liquidationType == LiquidationType.LATE\\n            ) {\\n                accountLayout.partyBAllocatedBalances[quote.partyB][partyA] +=\\n                    quote.lockedValues.cva -\\n                    ((quote.lockedValues.cva * accountLayout.liquidationDetails[partyA].deficit) /\\n                        accountLayout.lockedBalances[partyA].cva);\\n                if (hasMadeProfit) {\\n                    accountLayout.partyBAllocatedBalances[quote.partyB][partyA] -= amount;\\n                } else {\\n                    accountLayout.partyBAllocatedBalances[quote.partyB][partyA] += amount;\\n                }\\n            } else if (\\n                accountLayout.liquidationDetails[partyA].liquidationType == LiquidationType.OVERDUE\\n            ) {\\n                if (hasMadeProfit) {\\n                    accountLayout.partyBAllocatedBalances[quote.partyB][partyA] -= amount;\\n                } else {\\n                    accountLayout.partyBAllocatedBalances[quote.partyB][partyA] +=\\n                        amount -\\n                        ((amount * accountLayout.liquidationDetails[partyA].deficit) /\\n                            uint256(-accountLayout.liquidationDetails[partyA].totalUnrealizedLoss));\\n                }\\n            }\\n```\\n