Incorrect reserves accounting leads to LP loss during minting or swapping
Protocol fees are not deducted from `contract_reserves` when collected, so the next LP minting or swapping after a fee collection event silently absorbs the difference as a loss.
Description
After swap, when the protocol updates the pool reserves and contract reserves, it subtracts the protocol fees from the pool reserves (which is fine, the protocol fees should be separated from the liquidity pool). However, the protocol does not subtract the protocol fees from contract_reserves (which is also fine, because contract_reserves should reflect the actual balance of the contract; it is used, for example, when LP is minted and the diff between actual balance and reserves is used to calculate how much is added).
In short:
- the pool reserves do not contain protocol fees.
- the contract reserves contain protocol fees.
When the privileged account collects fees (by calling the collect_protocol_fees(...) function), the protocol does not deduct them from contract reserves. This means that the accounting of contract reserves is lower than the actual amount. When a new LP comes in and sends a token in, that difference will be deducted from the amount they load in as LP, so they will be at a loss. This will also lead to loss during swapping as the token_in amount is calculated in the same way.
Impact
Impact is High, as it might amount to high losses for the fresh LP provider and swapper who engage with the contract directly after the fee collection event. The bigger the fee collection amount is, the bigger the loss of the next interacting user. Additionally if the LP or swapper tries to add a smaller amount than the balance - contract_reserves the function will revert with an underflow.
Recommendation
Subtract the amounts of collected fees from the contract_reserves within the collect_protocol_fees(...) function.
Resolution
Fixed in commit 3fe0690c72963b680df064e94ced9ad2daad728c.

