Core Contracts

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

Critical Basis Points Implementation Error in FeeCollector

Summary

The FeeCollector contract contains a critical mismatch between its documented basis points standard and actual implementation in two fee types. This violates the contract's own validation checks and would prevent deployment.

Description

The FeeCollector contract explicitly states it uses basis points for percentage calculations where 10000 = 100%. This is enforced by a validation check that requires all fee shares to sum to BASIS_POINTS (10000). However, two fee types (Swap Tax and NFT Royalty) only sum to 2000 basis points (20%), violating this requirement.

Relevant Code

uint256 public constant BASIS_POINTS = 10000;
// Validation check in updateFeeType
if (newFee.veRAACShare + newFee.burnShare + newFee.repairShare + newFee.treasuryShare != BASIS_POINTS) {
revert InvalidDistributionParams();
}
// Problematic implementations
// Buy/Sell Swap Tax
feeTypes[6] = FeeType({
veRAACShare: 500, // 0.5%
burnShare: 500, // 0.5%
repairShare: 1000, // 1.0%
treasuryShare: 0 // 0%
}); // Sums to 2000 instead of 10000
// NFT Royalty Fees
feeTypes[7] = FeeType({
veRAACShare: 500, // 0.5%
burnShare: 0, // 0%
repairShare: 1000, // 1.0%
treasuryShare: 500 // 0.5%
}); // Sums to 2000 instead of 10000

Impact

  • Only 20% of collected fees would be distributed

  • 80% of fees would remain stuck in contract

  • Incorrect reward distribution to stakeholders

Proof of Concept

function testBasisPointsValidation() public {
// Testing Swap Tax (Type 6)
FeeType memory swapTax = feeCollector.getFeeType(6);
uint256 totalShare = swapTax.veRAACShare +
swapTax.burnShare +
swapTax.repairShare +
swapTax.treasuryShare;
assertEq(totalShare, 2000); // Sums to 2000 instead of required 10000
// Will fail validation
vm.expectRevert("InvalidDistributionParams");
feeCollector.updateFeeType(6, swapTax);
}
function testMultipleFeesValidation() public {
// Testing all fee types
for(uint8 i = 0; i < 8; i++) {
FeeType memory feeType = feeCollector.getFeeType(i);
uint256 totalShare = feeType.veRAACShare +
feeType.burnShare +
feeType.repairShare +
feeType.treasuryShare;
if(i < 6) {
assertEq(totalShare, 10000, "Early fee types sum correctly");
} else {
assertEq(totalShare, 2000, "Fee types 6 and 7 sum incorrectly");
}
}
}

Root Cause

The implementation appears to confuse:

  1. The fee rate charged to users (2% for swap tax and royalties)

  2. The internal distribution percentages of collected fees (should sum to 100%)

Fix Recommendation

  1. Correct the basis point calculations for Types 6 & 7:

// Buy/Sell Swap Tax (Type 6)
feeTypes[6] = FeeType({
veRAACShare: 2500, // 25%
burnShare: 2500, // 25%
repairShare: 5000, // 50%
treasuryShare: 0 // 0%
});
// NFT Royalty Fees (Type 7)
feeTypes[7] = FeeType({
veRAACShare: 2500, // 25%
repairShare: 5000, // 50%
treasuryShare: 2500 // 25%
});

Tools Used

  • Manual code review

  • Foundry testing framework

Updates

Lead Judging Commences

inallhonesty Lead Judge 4 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.