# Due to the loss of precision, openPosition will make the user's leverage higher than expected

Rubicon's openPosition rounds down desired leverage, so a 1.000000000000000001x long borrows max collateral, yielding 1.7x leverage and liquidation risk.

- Payout: Contest reward
- Severity: high
- Program: Rubicon
- Credited: cccz
- Disclosed: 2025-02-17
- Write-up quality: 7/10
- Original: https://github.com/code-423n4/2023-04-rubicon-findings/issues/281
- Library page: https://bugbountylibrary.com/r/c4%3A2023-04-rubicon%3AH-16
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:solidity technique:source-review vuln:business-logic vuln:liquidation vuln:precision-loss

**Target:** Position.sol openPosition/_borrowLimit leverage calculation
**Root cause:** wmul rounds down _desiredAmount, so leverage just above 1x yields _desiredAmount == _assetAmount, making _borrowDelta 0 and _lastBorrow 0; openPosition then treats 0 as 100% borrow.
**Steps:**
1. Call `buyAllAmountWithLeverage(testCoin, testStableCoin, 0.4e18, 1e18+1)`.
2. In `_borrowLimit`, `_desiredAmount = wmul(4e8, 1e18+1) = 4e8`; loop exits with `_lastBorrow = 0`, `_limit = 1`.
3. In `openPosition`, `vars.lastBorrow == 0` so `vars.toBorrow = WAD` (100% borrow) instead of the intended tiny fraction.
4. Position borrows full collateral-factor amount, reaching 4e8 + 4e8*0.7 = 6.8e8, i.e. 1.7x leverage.
5. Observe borrowedAmount1 = 252000 vs 90000 for 1.25x and 121320 for 1.337x.
**How found:** Code review of `_borrowLimit` and `openPosition` noticed `wmul` rounds down and that `_lastBorrow == 0` is overloaded to mean 100% borrow; tested leverage values just above 1e18 with Hardhat.
**Exploitation:** User opens a long with leverage barely above 1x; contract borrows the maximum allowed by collateral factor, creating an unexpectedly high leveraged position that is more likely to be liquidated.
**Insight:** When a sentinel value (0) doubles as a legitimate computed fraction, check whether rounding can produce that sentinel from a valid input; fuzz leverage just above the minimum to expose it.
