Description
The GaugeController::distributeRevenue
function calculates a 20% performance fee share but fails to store it in the performanceFees
mapping. This results in the protocol losing track of 20% of distributed revenue, making these funds permanently inaccessible.
Proof of Concept
Admin calls GaugeController::distributeRevenue
with 100 ETH
Function calculates 20 ETH as performance fee (amount * 20 / 100
)
Performance fee is neither stored in performanceFees
mapping nor distributed
20 ETH becomes permanently locked in contract with no tracking
function distributeRevenue(GaugeType gaugeType, uint256 amount) external {
uint256 performanceShare = amount * 20 / 100;
revenueShares[gaugeType] += veRAACShare;
}
Test case showing missing fee tracking:
it("fails to track performance fees", async () => {
const initialRevenue = await gaugeController.revenueShares(0);
const initialPerformanceFee = await gaugeController.performanceFees(
await rwaGauge.getAddress()
);
await gaugeController
.connect(emergencyAdmin)
.distributeRevenue(0, ethers.parseEther("100"));
expect(await gaugeController.revenueShares(0)).to.equal(
initialRevenue + ethers.parseEther("80")
);
expect(
await gaugeController.performanceFees(await rwaGauge.getAddress())
).to.equal(initialPerformanceFee);
});
Impact
High severity - Direct loss of protocol revenue. The unrecorded 20% performance fees become permanently inaccessible, violating core protocol economics and depriving fee recipients of their allocated share.
Recommendation
function distributeRevenue(GaugeType gaugeType, uint256 amount) external {
uint256 performanceShare = amount * 20 / 100;
+ performanceFees[gaugeType] += performanceShare;
revenueShares[gaugeType] += veRAACShare;
}
function distributeRevenue(GaugeType gaugeType, uint256 amount) external {
uint256 performanceShare = amount * 20 / 100;
revenueShares[gaugeType] += veRAACShare;
+ _distributeToGauges(gaugeType, performanceShare);
}
+ mapping(GaugeType => uint256) public typePerformanceFees;
function distributeRevenue(GaugeType gaugeType, uint256 amount) external {
uint256 performanceShare = amount * 20 / 100;
+ typePerformanceFees[gaugeType] += performanceShare;
revenueShares[gaugeType] += veRAACShare;
}