# Early user can call issue() and then melt() to increase basketsNeeded to supply ratio to its maximum value and then melt() won't work and contract features like issue() won't work

Early issuer calls issue(1e18) then melt(1e18-1), pushing basketsNeeded/supply ratio to max 1e27, bricking issue() and melt() for the RToken.

- Payout: Contest reward
- Severity: medium
- Program: Reserve
- Credited: unforgiven
- Disclosed: 2023-04-27
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2023-01-reserve-findings/issues/384
- Library page: https://bugbountylibrary.com/r/c4%3A2023-01-reserve%3AM-05
- Tags: domain:web3 impact:dos kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:source-review vuln:business-logic vuln:dos

**Target:** RToken contract (issue/melt, requireValidBUExchangeRate)
**Root cause:** melt() lets anyone burn their own RToken, and requireValidBUExchangeRate() only enforces an upper bound of 1e27 on basketsNeeded/supply; an early issuer can drive the ratio to that ceiling, after which any operation that would raise the ratio reverts.
**Steps:**
1. Be an early issuer; call `issue(1e18)` to mint 1e18 RToken, setting basketsNeeded=1e18, supply=1e18
2. Call `melt(1e18 - 1)` to burn all but 1 RToken; supply=1, basketsNeeded=1e18
3. Ratio = FIX_ONE*basketsNeeded/supply = 1e27, the max allowed by `requireValidBUExchangeRate()`
4. Subsequent `issue()` reverts because it calls furnace.melt() -> RToken.melt() -> requireValidBUExchangeRate() with ratio already at ceiling
5. Other paths (mint, setBasketsNeeded, handoutExcessAssets, redeem rounding) that would raise the ratio also revert
**How found:** Code reading of melt() and requireValidBUExchangeRate(): noticed melt() is permissionless and the rate check only bounds the ratio above at 1e27, so an early issuer burning nearly all supply hits the ceiling and blocks future ratio increases.
**Exploitation:** Attacker needs only small capital as an early issuer: issue then melt down to 1 RToken to pin the BU/RToken rate at 1e27, permanently reverting issue() and melt() and other ratio-increasing operations, bricking issuance for that RToken. No funds stolen; redeem still works.
**Insight:** When a contract enforces a bounded exchange-rate invariant, check whether a permissionless burn/redeem can push the ratio to the boundary cheaply at low supply, turning the invariant check into a griefing DoS on mint/issue paths.
