F-2025-0008·incorrect-accounting

Pool reserves accounting incorrectly includes composition protocol fees

TL;DR

When LPs mint to the active bin, `pool_reserves` is updated with a delta that still includes composition protocol fees. The exposed reserves read larger than the real pool balance.

Severity
LOW
Impact
LOW
Likelihood
HIGH
Method
MManual review
CAT.
Complexity
LOW
Exploitability
LOW
02Section · Description

Description

During LP minting a user can provide both Token X and Token Y only to the active bin. The active bin has a composition factor which describes the relation between both token reserves. If during LP minting the amounts of Token X and Token Y are provided in a way that alters the composition factor of the active bin, a composition fee is deducted from the user's reserves. This composition fee is composed of the LP fees (which join the pool reserves) and the protocol fees (which do not, because they are claimable by the fee collector).

The protocol fees portion of the composition fees is handled within the mint_utils::handle_composition_fees(...) function, i.e. it is deducted from amounts provided to the bin and added to the pool_protocol_fees storage variable.

After minting is handled, the pool reserves are updated in the mint_utils::update_reserves_after_mint(...) function, but is done based on the difference between amounts_received and amounts_to_refund:

code
let new_pool_reserves =
current_pool_reserves.add(amounts_received).sub(amounts_to_refund);
storage_keys
.pool_reserves
.insert(pool_id, new_pool_reserves);

This is incorrect, because the difference contains the protocol fees, which are not supposed to be part of the pool reserves.

03Section · Impact

Impact

The pool_reserves are not used for any calculation within the contract, yet they are exposed by the get_pool_reserves(...) method, hence the impact is low, as it does not affect the protocol internal accounting or operation, yet it could cause integration issues with other protocols, as the pool reserves reporting will be shown larger than in reality.

04Section · Recommendation

Recommendation

To fix this issue, increment the pool_reserves using the value of amounts_added_to_bins returned by the mint_utils::mint_bins(...) rather than the difference between amounts_received and amounts_to_refund.

05Section · Resolution

Resolution

Fixed in commit e3e597ada1ef043faf30cf18e75b176a5593891a.

Status
Fixed
Fix commit
e3e597ada1ef
F-2025-0008

oog
zealynx

Smart Contract Security Digest

Monthly exploit breakdowns, audit checklists, and DeFi security research — straight to your inbox

© 2026 Zealynx