Rounding error when closing quote
Rounding errors could occur if the provided `filledAmount` is too small, resulting in the locked balance of an account remains the same even though a certain amount of the position has been closed.\\n```\\nFile: LibQuote.sol\\n    function closeQuote(Quote storage quote, uint256 filledAmount, uint256 closedPrice) internal {\\n        QuoteStorage.Layout storage quoteLayout = QuoteStorage.layout();\\n        AccountStorage.Layout storage accountLayout = AccountStorage.layout();\\n\\n        quote.modifyTimestamp = block.timestamp;\\n\\n        LockedValues memory lockedValues = LockedValues(\\n            quote.lockedValues.cva -\\n                ((quote.lockedValues.cva * filledAmount) / (LibQuote.quoteOpenAmount(quote))),\\n            quote.lockedValues.mm -\\n                ((quote.lockedValues.mm * filledAmount) / (LibQuote.quoteOpenAmount(quote))),\\n            quote.lockedValues.lf -\\n                ((quote.lockedValues.lf * filledAmount) / (LibQuote.quoteOpenAmount(quote)))\\n        );\\n        accountLayout.lockedBalances[quote.partyA].subQuote(quote).add(lockedValues);\\n        accountLayout.partyBLockedBalances[quote.partyB][quote.partyA].subQuote(quote).add(\\n            lockedValues\\n        );\\n        quote.lockedValues = lockedValues;\\n\\n        (bool hasMadeProfit, uint256 pnl) = LibQuote.getValueOfQuoteForPartyA(\\n            closedPrice,\\n            filledAmount,\\n            quote\\n        );\\n        if (hasMadeProfit) {\\n            accountLayout.allocatedBalances[quote.partyA] += pnl;\\n            accountLayout.partyBAllocatedBalances[quote.partyB][quote.partyA] -= pnl;\\n        } else {\\n            accountLayout.allocatedBalances[quote.partyA] -= pnl;\\n            accountLayout.partyBAllocatedBalances[quote.partyB][quote.partyA] += pnl;\\n        }\\n```\\n\\nIn Lines 157, 159, and 161 above, a malicious user could make the numerator smaller than the denominator (LibQuote.quoteOpenAmount(quote)), and the result will be zero due to a rounding error in Solidity.\\nIn this case, the `quote.lockedValues` will not decrease and will remain the same. As a result, the locked balance of the account will remain the same even though a certain amount of the position has been closed. This could cause the account's locked balance to be higher than expected, and the errors will accumulate if it happens many times.
When the `((quote.lockedValues.cva * filledAmount) / (LibQuote.quoteOpenAmount(quote)))` rounds down to zero, this means that a rounding error has occurred as the numerator is smaller than the denominator. The CVA, `filledAmount` or both might be too small.\\nConsider performing input validation against the `filledAmount` within the `fillCloseRequest` function to ensure that the provided values are sufficiently large and will not result in a rounding error.
When an account's locked balances are higher than expected, their available balance will be lower than expected. The available balance affects the amount that users can withdraw from their accounts. The "silent" increase in their locked values means that the amount that users can withdraw becomes lesser over time, and these amounts are lost due to the errors.
```\\nFile: LibQuote.sol\\n    function closeQuote(Quote storage quote, uint256 filledAmount, uint256 closedPrice) internal {\\n        QuoteStorage.Layout storage quoteLayout = QuoteStorage.layout();\\n        AccountStorage.Layout storage accountLayout = AccountStorage.layout();\\n\\n        quote.modifyTimestamp = block.timestamp;\\n\\n        LockedValues memory lockedValues = LockedValues(\\n            quote.lockedValues.cva -\\n                ((quote.lockedValues.cva * filledAmount) / (LibQuote.quoteOpenAmount(quote))),\\n            quote.lockedValues.mm -\\n                ((quote.lockedValues.mm * filledAmount) / (LibQuote.quoteOpenAmount(quote))),\\n            quote.lockedValues.lf -\\n                ((quote.lockedValues.lf * filledAmount) / (LibQuote.quoteOpenAmount(quote)))\\n        );\\n        accountLayout.lockedBalances[quote.partyA].subQuote(quote).add(lockedValues);\\n        accountLayout.partyBLockedBalances[quote.partyB][quote.partyA].subQuote(quote).add(\\n            lockedValues\\n        );\\n        quote.lockedValues = lockedValues;\\n\\n        (bool hasMadeProfit, uint256 pnl) = LibQuote.getValueOfQuoteForPartyA(\\n            closedPrice,\\n            filledAmount,\\n            quote\\n        );\\n        if (hasMadeProfit) {\\n            accountLayout.allocatedBalances[quote.partyA] += pnl;\\n            accountLayout.partyBAllocatedBalances[quote.partyB][quote.partyA] -= pnl;\\n        } else {\\n            accountLayout.allocatedBalances[quote.partyA] -= pnl;\\n            accountLayout.partyBAllocatedBalances[quote.partyB][quote.partyA] += pnl;\\n        }\\n```\\n