The FeeCollector contract manages the collection and distribution of protocol fees across various categories, including Protocol Fees, Lending Fees, Performance Fees, Insurance Fees, Mint/Redeem Fees, Vault Fees, Swap Tax, and NFT Royalties. While fee types 0–5 are correctly configured, fee types 6 and 7—intended to represent Swap Tax and NFT Royalties (each expected to total 2% of fees)—are misinitialized, resulting in values that imply a 20% share instead of 2%. This error leads to grossly inflated fee calculations for these categories, causing misallocation of rewards and undermining the protocol’s economic integrity.
Additionally, although the contract provides an updateFeeType function to modify fee type parameters post-initialization, it includes a flawed validation check. The function enforces that the sum of fee shares equals exactly BASIS_POINTS (i.e., 100%), using an equality comparison (==) negation. However, this strict equality negation check prevents fee managers from setting valid fee shares for Swap Tax and NFT Royalties when slight adjustments are necessary, effectively blocking correct configuration. This combination of misinitialization and faulty validation elevates the issue to a high severity due to its potential to disrupt fee distribution and erode stakeholder trust.
The _initializeFeeTypes function sets default fee configurations:
Due to a unit or scaling error, fee types 6 and 7 are set with values that are 10 times higher than intended. This misconfiguration leads to an overestimation of fees in these categories during distribution, resulting in misallocated rewards and economic imbalance.
The contract also provides a function to update fee type parameters:
Issue:
The function enforces that the total of fee shares must equal exactly BASIS_POINTS (typically 10,000), using an equality check. In practice, when adjusting fee types 6 and 7 (Swap Tax and NFT Royalties), the correct fee configuration might require slight deviations or a different interpretation of basis points. For instance, if the intended total is 200 basis points (2%) rather than 2000 (20%), the current check will always fail, preventing fee managers from applying the correct configuration. The validation logic should allow for proper configuration (e.g., using a greater-than operator or an acceptable range) rather than demanding an exact match.
Miscalculated Fee Distribution:
The misinitialization of fee types 6 and 7 leads to fees being recorded at roughly 10 times the intended percentage. When these fees are used in the distribution process, the shares calculated for veRAAC holders, burn, repair fund, and treasury become grossly inflated or misdirected.
Inability to Correct Fee Configuration:
The faulty updateFeeType function prevents fee managers from updating the misconfigured fee types because the strict equality check for fee shares does not allow valid adjustments, especially for fee types 6 and 7. This locks the system into a state with incorrect fee distributions.
Economic and Governance Instability:
Over time, these issues can lead to significant economic imbalances, misaligned incentives, and erosion of trust among protocol participants, undermining both reward distribution and governance processes.
Before Fee Collection:
The FeeCollector’s fee types are initialized using _initializeFeeTypes. Fee types 6 and 7 are misconfigured, recording excessively high values.
Fee Collection:
When fees are collected via collectFee, the FeeCollector records the full (inflated) amounts for fee types 6 and 7.
Fee Distribution:
During distribution, the function _calculateDistribution computes distribution shares based on the inflated fee type values, leading to an overall allocation that deviates significantly from the protocol's intended design.
Attempted Correction via updateFeeType:
A fee manager tries to update fee types 6 and 7 using the updateFeeType function with the correct (scaled-down) values (e.g., veRAACShare: 50, burnShare: 50, repairShare: 100, treasuryShare: 0 for Swap Tax). However, the validation check fails because the sum of these values (50+50+100+0 = 200) does not exactly equal BASIS_POINTS (10,000), thereby preventing the update.
The following test suite demonstrates the impact:
Before Collection:
All fee types are initialized to 0.
After Collection:
Fee types 6 and 7 record values that are significantly inflated (e.g., ~965000000000000000000000 each), leading to a total fee figure that exceeds the actual token balance of the FeeCollector.
Update Attempt:
The test attempts to update fee types 6 and 7 with corrected values (scaled down by a factor of 10). However, due to the strict equality check in updateFeeType (which requires the sum of fee shares to equal exactly BASIS_POINTS), these update attempts revert, demonstrating that fee managers cannot fix the misconfiguration.
After Distribution:
The final distribution logs show misallocated funds among the fee collector, repair fund, and treasury, confirming that the misconfiguration negatively impacts fee distribution.
Severe Economic Imbalance:
The misconfiguration of fee types 6 and 7 leads to an overestimation of fees (approximately 20% instead of 2%), resulting in disproportionate fee allocation that distorts reward distribution.
Governance and Stakeholder Trust Erosion:
Incorrect fee distributions undermine the protocol's fairness, potentially leading to disputes among stakeholders and a loss of confidence in the system's economic model.
Inability to Correct Fee Parameters:
The flawed validation in updateFeeType prevents fee managers from updating fee type parameters to their intended values, locking the system into a state of misallocation.
Long-Term Protocol Instability:
Persistent misallocation of fees can destabilize the protocol's tokenomics, affecting governance, participation incentives, and overall economic sustainability.
Manual Review
Foundry
To mitigate this high-severity issue, the following corrective actions are recommended:
Adjust the fee type initialization in _initializeFeeTypes to correctly represent a total of 2% (200 basis points) instead of 20% (2000 basis points):
Modify the updateFeeType function to allow fee managers to update fee types without requiring the fee shares to equal exactly BASIS_POINTS (i.e., 10,000 basis points). Instead, use a comparison that ensures the sum does not exceed BASIS_POINTS or is within an acceptable range. For instance:
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.