# sqrtDiscriminant can be calculated wrong

Math.sqrt roundUp flag returns inconsistent results for small values, causing wrong sqrtDiscriminant and mispriced leverage/deleverage amounts in Timeswap pools.

- Payout: Contest reward
- Severity: medium
- Program: Timeswap
- Credited: sorrynotsorry
- Disclosed: 2023-03-10
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2023-01-timeswap-findings/issues/227
- Library page: https://bugbountylibrary.com/r/c4%3A2023-01-timeswap%3AM-04
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:solidity technique:source-review vuln:accounting-error vuln:precision-loss

**Target:** TimeswapV2Pool leverage/deleverage via ConstantProduct.updateGivenSumLong
**Root cause:** Math.sqrt with roundUp=true uses a Babylonian loop whose rounding is inconsistent for small values (e.g. sqrt(6)=2, sqrt(15)=3), so sqrtDiscriminant is computed wrong when value1==0 in sqrt512.
**Steps:**
1. Call Math.sqrt(value, true) for small values: sqrt(6)->2, sqrt(8)->2, sqrt(12)->3, sqrt(15)->3, sqrt(20)->4, sqrt(24)->4, sqrt(30)->5.
2. Trace leverage/deleverage with transaction=GivenSum -> ConstantProduct.updateGivenSumLong -> getShortOrLongFromGivenSum -> calculateSqrtDiscriminant -> FullMath.sqrt512(b0,b1,true).
3. When value1==0, sqrt512 falls to value0.sqrt(roundUp) with roundUp=true, yielding the inconsistent result.
4. amount = (negativeB - sqrtDiscriminant)>>1 is then wrong, mispricing long/short amounts and fees.
5. Pools with low token decimals (e.g. GUSD 2 decimals) and small amounts are most affected.
**How found:** Code review of Math.sqrt rounding behavior; tested small values in Remix/Excel and noticed non-monotonic results, then traced roundUp=true usage into sqrt512 and the leverage/deleverage math.
**Exploitation:** User calls leverage or deleverage with GivenSum transaction; wrong sqrtDiscriminant yields incorrect long/short amounts, causing user financial loss and protocol fee loss.
**Insight:** When auditing integer sqrt implementations, test small inputs and check monotonicity/rounding consistency; a roundUp flag applied to a Babylonian loop can under-round, and any downstream discriminant math inherits the error.
