# Potential infinite loop in _borrowLimit function

Rubicon Position._borrowLimit while-loop shrinks _loopBorrowed geometrically; with collateralFactor below ~66% it needs billions of iterations, bricking openPosition.

- Payout: Contest reward
- Severity: medium
- Program: Rubicon
- Credited: bytes032
- Disclosed: 2025-02-17
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2023-04-rubicon-findings/issues/557
- Library page: https://bugbountylibrary.com/r/c4%3A2023-04-rubicon%3AM-22
- Tags: domain:web3 impact:dos kind:contest platform:code4rena sev:medium tech:solidity technique:source-review vuln:dos

**Target:** Position.sol leverage wrapper (_borrowLimit / openPosition)
**Root cause:** The while loop recomputes _loopBorrowed = wmul(_loopBorrowed, _collateralFactor) each iteration, so it decays geometrically toward 0 instead of converging; when collateralFactor is low the remaining gap to _desiredAmount is filled by ever-smaller increments, requiring an unbounded number of iterations.
**Steps:**
1. Set collateralFactor to 0.5e18 via comptroller._setCollateralFactor.
2. Call _borrowLimit(bathToken, asset, 25e18, 23.32e18) so _desiredAmount = wmul(25e18, 23.32e18) = 58.3e18.
3. Iteration 1: _loopBorrowed = wmul(25e18, 0.5e18) = 12.5e18, _assetAmount = 37.5e18.
4. Iteration 2+: _loopBorrowed = wmul(prev, 0.5e18) halves each time (6.25e18, 3.125e18, ...).
5. After ~60 iterations _loopBorrowed reaches 1 wei; _assetAmount ~5e19, still below 58.3e18, so ~8.3e18 more iterations are needed.
6. Run `yarn hardhat test ./test/leverage-wrapper.ts --grep "should open long position"` to observe the loop stalling.
**How found:** Reading the loop and noticing _loopBorrowed is multiplied by _collateralFactor against itself rather than the original amount, then testing with a reduced collateral factor (0.5) to see the geometric decay never closes the gap to _desiredAmount.
**Exploitation:** Not weaponized; the loop runs out of gas / never terminates, making openPosition revert and the leverage feature unusable for affected collateral factors.
**Insight:** When a loop's increment is derived from the previous increment (geometric decay) rather than a fixed base, check convergence for the worst-case parameter range; a factor below ~0.66 makes the series sum finite but the loop count unbounded.
