# The Fluid DEX may become locked due to the division by zero error

Stale dexVariables2 copy in _calcRangeShifting restores the center-price-shift bit after _centerPriceShift was deleted, causing division-by-zero and locking all Fluid DEX operations.

- Payout: Contest reward
- Severity: medium
- Program: Instadapp
- Credited: etherSky
- Disclosed: 2025-01-07
- Write-up quality: 7/10
- Original: https://cdn.cantina.xyz/reports/cantina_competition_instadapp_september2024.pdf#3.1.2
- Library page: https://bugbountylibrary.com/r/cantina%3Ainstadapp_september2024%3A3.1.2
- Tags: domain:web3 impact:dos kind:contest platform:cantina sev:medium tech:evm tech:solidity technique:regression technique:source-review vuln:business-logic vuln:dos

**Target:** FluidDexT1 smart contract helpers (_getPricesAndExchangePrices)
**Root cause:** _calcRangeShifting receives the old dexVariables2_ and writes it back to storage at line 92, re-setting bit 248 that _calcCenterPrice had cleared, while _centerPriceShift is already 0.
**Steps:**
1. Set range percents shift (e.g. 11% over 600s) and center price shift (10% over 600s) via admin in same proposal
2. Advance time past shiftDuration so both shifts complete
3. Call any DEX operation (e.g. depositPerfect) triggering `_getPricesAndExchangePrices`
4. _calcCenterPrice clears bit 248 and deletes _centerPriceShift; then `_calcRangeShifting(upperRange_, lowerRange_, dexVariables2_)` runs with stale copy and line 92 writes back bit 248=1
5. Next call enters _calcCenterPrice with _centerPriceShift=0, dividing by time_=0 at line 159 -> panic 0x12, all ops revert
**How found:** Code reading of _getPricesAndExchangePrices: noticed _calcRangeShifting is passed the old dexVariables2_ rather than the updated one, and that its write-back at line 92 would resurrect the bit cleared by _calcCenterPrice.
**Exploitation:** Not attacker-triggered; requires governance to schedule center-price and range shifts with matching timing, after which the pool locks until admin updates config (~4 days).
**Insight:** When a function takes a packed config word by value and writes it back to storage, check whether an earlier call in the same transaction already mutated that word — stale copies can resurrect cleared flag bits and desync them from the state they gate.
