GaugeController is meant to manage funds, but it has 0 ERC20 approve() functions or any kind of transfer.
You can see that this is never done as there is none ERC20 approve() function neither any kind of transfer in the contract. Just use a code editor parser like the default one in VisualStudioCode to realize.
Whenever GaugeController::distributeRevenue() needs to be called. The % destined to the performance fee will remain in the contract forever.
The percentage destined for this is 20%, see here. The other 80% are allegedly distributed to veToken holders via Gauge::notifyRewardAmount() to the gauges, see % in above the previously linked line of code. See the notifyRewardAmount() call inside _distributeToGauges(), called here, its logic here.
As there are no transfers nor approvals, even if there is a transferFrom() on the gauge, the funds will never be moved. Thus that other 80% is also stuck on the contract.
Another function that should move funds and doesn't is GaugeController::distributeRewards(). It is even mentioned in the docs here.
Add ways of transfering tokens out of the contract. Either via approvals or transfers.
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.