# Attacker can disable basket during un-registration, which can cause an unnecessary trade in some cases

Attacker supplies just enough gas so quantity() call in AssetRegistry unregistration reverts, disabling the basket and forcing an unnecessary rebalance trade.

- Payout: Contest reward
- Severity: medium
- Program: Reserve
- Credited: 0xA5DF
- Disclosed: 2023-11-13
- Write-up quality: 7/10
- Original: https://github.com/code-423n4/2023-06-reserve-findings/issues/7
- Library page: https://bugbountylibrary.com/r/c4%3A2023-06-reserve%3AM-11
- Tags: domain:web3 impact:dos impact:funds-loss kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:incomplete-fix vuln:business-logic vuln:dos

**Target:** AssetRegistry.unregister / _reserveGas gas reservation
**Root cause:** _reserveGas returns gasleft()-GAS_TO_RESERVE, so a caller can supply gas just above GAS_TO_RESERVE leaving ~1 gas for the quantity() call, which reverts and disables the basket.
**Steps:**
1. Call unregister with gas set so gasleft() is just above GAS_TO_RESERVE
2. _reserveGas returns ~1 gas for basketHandler.quantity()
3. quantity() reverts out-of-gas, disabling the basket
4. Basket requires refresh; after warmup, refresh may trigger a basket switch and trade
**How found:** Reading the mitigation that reserved gas for quantity(); noticed remaining gas could be made arbitrarily small, so the call reverts.
**Exploitation:** Attacker times execution: executes backup-token proposal first, then unregisters a non-basket asset with crafted gas to disable basket; refresh replaces DAI with USDT forcing a trade with slippage loss.
**Escalation:** Chains with pending governance proposals and asset default to force an unnecessary rebalance trade.
**Insight:** When a fix reserves gas by subtracting a constant from gasleft(), check whether the remainder passed to the inner call can be driven to near-zero by the caller's gas choice.
