The fee collection validation fails to properly track total fees when collecting multiple fee types. This breaks the core accounting of protocol revenue and could lead to incorrect distribution of fees to stakeholders.
The FeeCollector contract allows collecting different types of fees (protocol, lending, performance etc). When a fee collection occurs, the contract should properly track the total amount across all fee types. However, the sum of collected fees can become inconsistent with the individual fee type amounts.
When fees are collected, the total after collection equals the total before plus the new amount. Looking at the implementation in FeeCollector.sol, we can see the fee accounting happens in _updateCollectedFees() which updates individual fee type balances, but there's no validation that these updates maintain consistency with the total.
This are the variables involved:
collectedFees mapping tracking amounts per fee type
totalFees calculated by summing all fee types
amount parameter passed to collectFee()
In this sequence: collectFee() → _updateCollectedFees() → fee type balance update → total calculation
The FeeCollector contract manages a fee distribution system where different protocol activities generate distinct fee types from lending operations to NFT royalties. When examining how fees flow through the system, I discovered an accounting discrepancy that could significantly impact veRAACToken holder rewards. /FeeCollector.sol#collectFee()
Begins in the collectFee() function, where the protocol receives fees from various sources. The contract tracks eight different fee types, each with carefully calibrated distribution ratios between veRAACToken holders, the treasury, and the repair fund. For example, protocol fees allocate 80% to veRAACToken holders and 20% to the treasury, while swap taxes split 50-50 between burning and the repair fund.
The critical moment occurs during fee collection. When a new fee arrives, the contract updates individual fee type balances through _updateCollectedFees() but doesn't validate that these updates maintain consistency with the total. This creates a situation where the sum of individual fee types could diverge from _calculateTotalFees(), directly affecting reward calculations.
To make this concrete: Imagine the protocol collects 1000 RAAC in protocol fees and 500 RAAC in lending fees. The individual balances would show 1500 RAAC total, but without atomic validation, the calculated total used for distributions could differ. This means veRAACToken holders expecting 1200 RAAC (80% of protocol fees) plus 350 RAAC (70% of lending fees) might receive incorrect rewards.
The _updateCollectedFees() function updates individual fee types atomically, but there's no guarantee that these updates maintain consistency with the total calculation. could lead to:
Incorrect reward distributions to veRAACToken holders
Mismatched treasury allocations
Compromised protocol accounting accuracy
The FeeCollector's fee accounting system shows an interesting edge case in how it handles multi-type fee collection. Here's why this matters for RAAC protocol's core financial integrity. _initializeFeeTypes()
The protocol thoughtfully segments different fee types with precise allocation rules. This aligns with the whitepaper's section on fee distribution (particularly for RWA yield direction).
This is where things get interesting _calculateTotalFees()
The total calculation assumes perfect synchronization with individual updates. This is why this deserves attention.
This pattern resembles classic accounting systems where individual ledger entries must reconcile with the master balance.
We maintain all existing security features (nonReentrant, pausable) while adding crucial total validation. The key addition is the atomic check between pre and post-update totals, ensuring mathematical consistency across all fee operations directly addresses the core accounting vulnerability while preserving the protocol's fee management system.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.