Core Contracts

Regnum Aurum Acquisition Corp
HardhatReal World AssetsNFT
77,280 USDC
View results
Submission Details
Severity: low
Valid

Assumption in FeeCollector :: updateFeeType() is wrong

Summary

Vulnerability Details

updateFeeType()is use to Updates parameters for a specific fee type

The contract supports 8 different fee types (0-7):

  1. Protocol Fees (0): General operations

  2. Lending Fees (1): Lending/borrowing activities

  3. Performance Fees (2): Yield products

  4. Insurance Fees (3): NFT loan insurance

  5. Mint/Redeem Fees (4): Token operations

  6. Vault Fees (5): Vault management

  7. Swap Tax (6): Trading operations

  8. NFT Royalties (7): NFT transactions

Each fee type has configurable distribution parameters:

  • veRAACShare: Percentage for veRAAC holders

  • burnShare: Percentage for token burning

  • repairShare: Percentage for repair fund

  • treasuryShare: Percentage for treasury

if we look at _initializeFeeTypes()which Initializes default fee types according to protocol rules

function _initializeFeeTypes() internal {
// Protocol Fees: 80% to veRAAC holders, 20% to treasury
feeTypes[0] = FeeType({
veRAACShare: 8000, // 80%
burnShare: 0,
repairShare: 0,
treasuryShare: 2000 // 20%
});
// Lending Fees: Interest income distribution
feeTypes[1] = FeeType({
veRAACShare: 7000, // 70%
burnShare: 0,
repairShare: 0,
treasuryShare: 3000 // 30%
});
// Performance Fees: 20% from yield products
feeTypes[2] = FeeType({
veRAACShare: 6000, // 60%
burnShare: 0,
repairShare: 0,
treasuryShare: 4000 // 40%
});
// Insurance Fees: 3% from NFT loans
feeTypes[3] = FeeType({
veRAACShare: 5000, // 50%
burnShare: 0,
repairShare: 2000, // 20%
treasuryShare: 3000 // 30%
});
// Mint/Redeem Fees
feeTypes[4] = FeeType({
veRAACShare: 6000, // 60%
burnShare: 0,
repairShare: 2000, // 20%
treasuryShare: 2000 // 20%
});
// Vault Fees
feeTypes[5] = FeeType({
veRAACShare: 7000, // 70%
burnShare: 0,
repairShare: 0,
treasuryShare: 3000 // 30%
});
// Buy/Sell Swap Tax (2% total)
feeTypes[6] = FeeType({ // @audit ////////////////////////////////
veRAACShare: 500, // 0.5%
burnShare: 500, // 0.5%
repairShare: 1000, // 1.0%
treasuryShare: 0
});
// NFT Royalty Fees (2% total)
feeTypes[7] = FeeType({
veRAACShare: 500, // 0.5%
burnShare: 0,
repairShare: 1000, // 1.0% // @audit wrong comments //////////////////////////
treasuryShare: 500 // 0.5%
});
}

https://github.com/Cyfrin/2025-02-raac/blob/main/contracts/core/collectors/FeeCollector.sol#L330-L394

Place to look here is feeTypes[6] & feeTypes[7]where combining all 4 parameter it doesn't reach 100% (i.e 100_00 BIPs)

But when setting feeTypes with new fee via updateFeeType() it has strong check that all 4 configurable distribution parametersshould comined equal to 100% which will be not correct for feeTypes[6] & feeTypes[7]as shown above.

function updateFeeType(uint8 feeType, FeeType calldata newFee) external override { ///////////////////////////////////////////
if (!hasRole(FEE_MANAGER_ROLE, msg.sender)) revert UnauthorizedCaller();
if (feeType > 7) revert InvalidFeeType();
// Validate fee shares total to 100%
if (newFee.veRAACShare + newFee.burnShare + newFee.repairShare + newFee.treasuryShare != BASIS_POINTS) { // @audit-issue this could be wrong
revert InvalidDistributionParams();
}
feeTypes[feeType] = newFee;
emit FeeTypeUpdated(feeType, newFee);
}

https://github.com/Cyfrin/2025-02-raac/blob/main/contracts/core/collectors/FeeCollector.sol#L220-L231

Impact

Tools Used

manuall review

Recommendations

should reconsider this design.

Updates

Lead Judging Commences

inallhonesty Lead Judge about 2 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Fee shares for fee type 6 and 7 inside FeeCollector do not total up to the expected 10000 basis points, this leads to update problems, moreover they are 10x the specifications

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.