# FurnaceP1.setRatio will work incorrectly after call when frozen 

FurnaceP1.setRatio updates ratio but skips lastPayout when melt reverts under freeze, causing excess token burn after unfreeze.

- Payout: Contest reward
- Severity: medium
- Program: Reserve
- Credited: rvierdiiev
- Disclosed: 2023-11-13
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2023-06-reserve-findings/issues/29
- Library page: https://bugbountylibrary.com/r/c4%3A2023-06-reserve%3AM-04
- Tags: domain:web3 impact:integrity kind:contest platform:code4rena sev:medium tech:solidity technique:incomplete-fix technique:source-review vuln:accounting-error vuln:business-logic

**Target:** FurnaceP1 staking/melting contract (Solidity)
**Root cause:** setRatio calls melt inside try/catch; when melt reverts due to notFrozen, ratio is updated but lastPayout/lastPayoutBal are not, leaving stale payout accounting.
**Steps:**
1. Freeze the Furnace component so notFrozen modifier reverts.
2. Call `setRatio(newRatio)`; internal `melt()` reverts, catch swallows it, `ratio` is written but `lastPayout`/`lastPayoutBal` unchanged.
3. Unfreeze Furnace.
4. Call `melt()`; elapsed time is measured from stale `lastPayout`, so more tokens are burnt than intended.
**How found:** Code reading of setRatio's try/catch around melt: noticed the catch path updates ratio without updating payout accounting variables.
**Exploitation:** Requires the Furnace to be frozen (governance/emergency action) while setRatio is invoked; after unfreeze, melt over-burns RToken from lastPayoutBal, harming melters.
**Insight:** When a setter wraps a state-mutating call in try/catch, audit every variable the skipped call would have updated—partial updates on the catch path create stale-accounting bugs that surface only after the blocking condition (freeze) clears.
