# Stable2::calcLpTokenSupply() function cannot convert under certain circumstances, DoSing calcReserveAtRatioLiquidity

Stable2 calcLpTokenSupply Newton iteration oscillates ±2 and reverts on non-convergence, DoSing calcReserveAtRatioLiquidity for certain reserve/ratio combos.

- Payout: Audit contest
- Severity: medium
- Program: Basin
- Found by: Egis_Security
- Disclosed: 2024-09-11
- Write-up quality: 6/10
- Original: https://code4rena.com/reports/2024-08-basin#m-01
- Library page: https://bugbountylibrary.com/r/c4%3A2024-08-basin%3AM-01
- Tags: domain:web3 impact:dos kind:contest platform:code4rena sev:medium tech:solidity technique:fuzzing technique:source-review vuln:dos

**Target:** Stable2 well calcReserveAtRatioLiquidity / calcLpTokenSupply
**Root cause:** Newton iteration in calcLpTokenSupply oscillates between two values differing by 2, exceeding the fixed convergence threshold of 1, so the added revert fires.
**Steps:**
1. Call `calcReserveAtRatioLiquidity(reserves=[1987e18,12345e8], j=0, ratios=[1e18,1e18], data)`
2. Increment ratios[0] by 0.003e18 in a loop up to 10000 iterations
3. At ratios[0]=7.195e18 the price falls in LUT bucket PriceData(0.27702e6,0,9.646293093274934449e18,0.001083e6,0,2000e18,1e18)
4. calcLpTokenSupply oscillates 237151473819804594336 <-> ...338 and reverts 'Non convergence: calcLpTokenSupply'
**How found:** Looping fuzz over ratio values in Foundry revealed a revert; traced into calcLpTokenSupply and observed the iteration values alternating by 2, tied to a specific LUT bucket where price is closer to lowPrice.
**Insight:** Fixed absolute convergence thresholds (<=1 wei) in iterative solvers can be defeated by 2-cycle oscillation; check whether the iteration can alternate between two adjacent values rather than monotonically approach, especially near LUT bucket boundaries.
