# CL gauge accepts unverified pools, allowing malicious pool to brick distribution

GaugeManager skips factory verification for CL gauges, so a fake pool that reverts in updateRewardsGrowthGlobal bricks distributeAll() once voted.

- Payout: Contest reward
- Severity: medium
- Program: Hybra Finance
- Credited: niffylord
- Disclosed: 2025-11-20
- Write-up quality: 6/10
- Original: https://code4rena.com/reports/2025-10-hybra-finance#m-09
- Library page: https://bugbountylibrary.com/r/c4%3A2025-10-hybra-finance%3AM-09
- Tags: domain:web3 impact:dos kind:contest platform:code4rena sev:medium tech:solidity technique:source-review vuln:access-control vuln:business-logic vuln:dos

**Target:** GaugeManager/GaugeCL gauge creation and reward distribution
**Root cause:** For _gaugeType==1, GaugeManager sets isPair=true without checking the pool came from the trusted CL factory (check removed for code size), so any contract exposing token0()/token1() is accepted and later called by GaugeCL.
**Steps:**
1. Deploy MaliciousCLPool exposing token0()/token1() and reverting updateRewardsGrowthGlobal()
2. Whitelist its tokens, call `gaugeManager.createGauge(address(maliciousPool), 1)`
3. Create veNFT lock and vote for the malicious pool during voting window
4. Advance epoch and call `gaugeManager.distributeAll()`
5. Observe revert 'Malicious pool blocks reward update', halting all distributions
**How found:** Code reading of GaugeManager._createGauge() spotted the commented-out factory check with note 'removed due to code size' and the isPair=true shortcut for CL gauges, contrasted against the verified standard-pair path.
**Exploitation:** Unprivileged attacker registers a fake CL pool gauge; any veNFT vote routes distribution through GaugeCL.notifyRewardAmount() into the malicious pool's reverting updateRewardsGrowthGlobal(), reverting distributeAll() for every pool until governance kills the gauge.
**Insight:** When a validation is commented out 'due to code size', trace every downstream call into the now-untrusted address; here GaugeCL's distribution loop makes the missing provenance check a global liveness bug rather than a local one.
