# Reserve factor changes do not affect treasury accrual until an unrelated rate-recalc path runs

K2's set_reserve_factor only stores config without checkpointing; treasury accrues stale old split until an unrelated rate-recalc runs, under-collecting reserves.

- Payout: Contest reward
- Severity: medium
- Program: K2
- Credited: ht111111
- Disclosed: 2026-08-20
- Write-up quality: 6/10
- Original: https://code4rena.com/reports/2026-04-k2#m-26
- Library page: https://bugbountylibrary.com/r/c4%3A2026-04-k2%3AM-26
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:solidity technique:source-review vuln:accounting-error vuln:business-logic

**Target:** Solidity lending pool reserve/treasury accounting (PoolConfigurator, KineticRouter)
**Root cause:** set_reserve_factor overwrites the packed configuration bitmap but never checkpoints the elapsed interval or recomputes current_liquidity_rate/current_variable_borrow_rate, so lazy update_state() keeps accruing the old supplier/protocol split.
**Steps:**
1. Create reserve utilization and set reserve_factor to 10%.
2. Governance calls PoolConfigurator.set_reserve_factor() raising factor to 90%; only storage bitmap updated.
3. Let a post-change interval elapse with no supply/withdraw/borrow/repay/liquidation/swap.
4. Call collect_protocol_reserves(): it invokes update_state() but not update_interest_rates_and_store(), accruing the whole window at the stale rate.
5. Compare against control: supply(1) then withdraw(1) in same timestamp forces update_interest_rates_and_store() to install new factor; treasury collects strictly more.
**How found:** Reading the reserve setter and tracing that it only stores config, then observing reserve state is lazy: update_state() accrues with stored rates and only update_interest_rates_and_store() installs fresh ones, while collect_protocol_reserves() skips the latter.
**Insight:** When a governance setter changes an economic parameter, check whether accrual is lazy and whether the setter checkpoints/recomputes rates; if collection paths call update_state() but not the rate-recalc function, parameter changes stay dormant until an unrelated user action.
