Summary
The FeeCollector::updateFeeType()
function fails to update feeTypes
as expected due to an incorrect validation of fee share allocations.
Vulnerability Details
In the _initializeFeeTypes()
function, the sum of share
values is not always equal to BASIS_POINTS
, which represents 100% allocation.
function _initializeFeeTypes() internal {
feeTypes[6] = FeeType({
@> veRAACShare: 500,
@> burnShare: 500,
@> repairShare: 1000,
treasuryShare: 0
});
feeTypes[7] = FeeType({
@> veRAACShare: 500,
burnShare: 0,
@> repairShare: 1000,
@> treasuryShare: 500
});
}
However, the current implementation of the updateFeeType()
function enforces a strict validation that the sum of all fee shares must equal BASIS_POINTS
, leading to unexpected failures when attempting to update feeTypes
.
function updateFeeType(uint8 feeType, FeeType calldata newFee) external override {
if (!hasRole(FEE_MANAGER_ROLE, msg.sender)) revert UnauthorizedCaller();
if (feeType > 7) revert InvalidFeeType();
@> if (newFee.veRAACShare + newFee.burnShare + newFee.repairShare + newFee.treasuryShare != BASIS_POINTS) {
revert InvalidDistributionParams();
}
feeTypes[feeType] = newFee;
emit FeeTypeUpdated(feeType, newFee);
}
Impact
The updateFeeType()
function does not allow updates to feeTypes
if the new share distribution does not strictly sum to BASIS_POINTS
, even though _initializeFeeTypes()
does not enforce this requirement. This discrepancy prevents the intended modifications to fee structures.
Tools Used
Manual Review
Recommendations
Modify the updateFeeType()
function to introduce a totalShares
parameter, allowing flexibility in defining the expected sum of fee shares instead of enforcing an absolute BASIS_POINTS
check.
For example:
- function updateFeeType(uint8 feeType, FeeType calldata newFee) external override {
+ function updateFeeType(uint8 feeType, FeeType calldata newFee, uint256 totalShares) external override {
if (!hasRole(FEE_MANAGER_ROLE, msg.sender)) revert UnauthorizedCaller();
if (feeType > 7) revert InvalidFeeType();
+ if (totalShares > BASIS_POINTS) revert InvalidDistributionParams();
- // Validate fee shares total to 100%
- if (newFee.veRAACShare + newFee.burnShare + newFee.repairShare + newFee.treasuryShare != BASIS_POINTS) {
- revert InvalidDistributionParams();
- }
+ // Validate fee shares total to totalShares
+ if (newFee.veRAACShare + newFee.burnShare + newFee.repairShare + newFee.treasuryShare != totalShares) {
+ revert InvalidDistributionParams();
+ }
feeTypes[feeType] = newFee;
emit FeeTypeUpdated(feeType, newFee);
}