# Commission fees can always be bypassed

Panoptic's settleBurn computes commission as min(notional, premium) fee, but _settleOptions passes zero amounts and zero premium skips fees entirely, letting users bypass commissions.

- Payout: Contest reward
- Severity: high
- Program: Panoptic
- Credited: prk0
- Disclosed: 2026-03-09
- Write-up quality: 7/10
- Original: https://code4rena.com/reports/2025-12-panoptic-next-core#h-03
- Library page: https://bugbountylibrary.com/r/c4%3A2025-12-panoptic-next-core%3AH-03
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:solidity technique:source-review vuln:business-logic vuln:fee-bypass

**Target:** CollateralTracker.sol settleBurn / PanopticPool.sol _settleOptions
**Root cause:** settleBurn takes the minimum of notional and premium commission fees, but _settleOptions calls it with longAmount/shortAmount/ammDeltaAmount all zero, making notional fee zero; additionally the whole fee block is skipped when realizedPremium == 0.
**Steps:**
1. Open a position so premium accrues.
2. Call PanopticPool::dispatchFrom -> _settlePremium -> _settleOptions, which invokes collateralToken0/1.settleBurn(owner,0,0,0,realizedPremia,...); notional fee is 0 so min() yields 0 commission.
3. Then call PanopticPool::dispatch -> _burnOptions -> settleBurn; if realizedPremium is 0 the fee block is skipped entirely (no CommissionPaid event).
4. Observe CommissionPaid event absent/zero in both interactions, confirming full commission bypass.
**How found:** Traced all call paths into settleBurn and noticed _settleOptions passes zero longAmount/shortAmount/ammDeltaAmount, so the min() of notional and premium fee collapses to zero; also spotted the realizedPremium != 0 guard skipping fee logic.
**Exploitation:** User settles premium first (commission computed as 0 due to zero notional amounts), then burns the position (commission skipped because realizedPremium==0), avoiding all commission fees on exit.
**Insight:** When a fee is min() of two components, audit every caller for arguments that zero out one component; also check early-return guards (realizedPremium != 0) that skip fee accounting on legitimate flows.
