# doesn't calculate the current borrowing amount for the provider, including the provider's borrowed shares and accumulated fees due to inconsistency in collateralRatio calculation

Lybra rigidRedemption computes provider collateralRatio from raw borrowed[] instead of getBorrowedOf(), omitting accrued fees and shares, letting undercollateralized providers redeem.

- Payout: Contest reward
- Severity: high
- Program: Lybra Finance
- Credited: turvy\_fuzz
- Disclosed: 2023-08-21
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2023-06-lybra-findings/issues/723
- Library page: https://bugbountylibrary.com/r/c4%3A2023-06-lybra%3AH-02
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:source-review vuln:accounting-error vuln:business-logic

**Target:** LybraPeUSDVaultBase.sol rigidRedemption collateral ratio calculation
**Root cause:** rigidRedemption divides depositedAsset by borrowed[provider] only, while liquidation uses getBorrowedOf() which adds feeStored and _newFee, so accrued fees/shares are excluded from the provider's ratio.
**Steps:**
1. Borrow PeUSD against collateral in LybraPeUSDVaultBase, accruing fees over time via feeStored/_newFee.
2. Observe rigidRedemption at L161 computes providerCollateralRatio = depositedAsset[provider]*assetPrice*100 / borrowed[provider], omitting fees.
3. Compare with liquidation at L127 using getBorrowedOf() = borrowed + feeStored + _newFee.
4. Provider whose true ratio (with fees) is below threshold still passes rigidRedemption's inflated ratio and redeems collateral.
**How found:** Code-reading comparison: noticed liquidation() uses getBorrowedOf() while rigidRedemption() uses raw borrowed[], spotting the inconsistency in collateralRatio computation.
**Exploitation:** A provider with accrued fees that push their real collateral ratio below the redemption threshold can still call rigidRedemption; the inflated ratio (fees excluded) passes the check, allowing them to redeem collateral they should not be able to, leaving bad debt.
**Insight:** When two functions compute the same risk metric (collateral ratio), diff their formulas; a raw storage read vs. an accrual-aware getter is a classic inconsistency that lets stale/understated debt pass health checks.
