Rugproof Security Audit — SpotOracleLending.sol

2026-05-13 · grade F · 3 Critical, 1 High, 0 Medium

Summary

A 60-line lending market that prices collateral and triggers liquidations from the spot reserves of a single Uniswap V2 pair. Three independent functions (borrow, liquidate, and the underlying _spotPrice) all rely on the same instantaneously-manipulable read. With a flash loan source, an attacker can:

  1. Borrow → swap to crash collateral price → liquidate every borrower at a discount → repay → walk away.
  2. Or: deposit → manipulate up → borrow above true LTV → repay manipulation → leave protocol with bad debt.
  3. Either path costs only the flash-loan fee. Critical-class risk to all funds in the pool.

    Findings

    IDSevTitle
    ORACLE-001CriticalSpot price read from AMM reserves
    ORACLE-002CriticalBorrow uses spot price for collateral valuation
    ORACLE-003CriticalLiquidation health check uses spot price
    FLASH-001HighAll three above are flash-loan-amplified in one block

    ORACLE-001 — Spot price read from AMM reserves (Critical)

    
    function _spotPrice() internal view returns (uint256) {
        (uint112 r0, uint112 r1,) = pair.getReserves();
        return uint256(r1) * 1e18 / uint256(r0);
    }
    

    Replace with a TWAP (≥30 min) and/or a Chainlink feed with freshness checks. Chainlink + Uniswap V3 TWAP cross-check is the canonical defense.

    ORACLE-002 — borrow uses spot price (Critical)

    Borrow capacity is computed from _spotPrice(). Attacker swaps to inflate the price, borrows beyond true LTV, swaps back, leaves the protocol with a bad debt position no one will liquidate (because the post-manipulation price says it's healthy).

    ORACLE-003 — liquidate uses spot price (Critical)

    Mirror image. Attacker swaps to deflate the price, liquidates every position, swaps back. Liquidation discount is pure profit.

    FLASH-001 — Single-block flash-loan amplification (High)

    The vulnerabilities above don't require holding capital. Aave / Balancer / Uniswap flash loans make the attack costless beyond the flash-loan fee (typically 0.05–0.09%). Any borrower-eligible collateral can be drained to the limit of pool liquidity.

    Recommendation

    Do not deploy. If the design must use AMM-derived prices:

    Skill detail: oracle-manipulation, flash-loan-attacks, lending-specialist.

    Generated by Rugproof — https://omermaksutii.github.io/RugProof