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:
- Borrow → swap to crash collateral price → liquidate every borrower at a discount → repay → walk away.
- Or: deposit → manipulate up → borrow above true LTV → repay manipulation → leave protocol with bad debt.
- Minimum: Uniswap V3
observe()TWAP with ≥30 minute window. Spot reads (slot0, V2getReserves) banned for any fund-flow logic. - Preferred: dual-source — Chainlink primary, V3 TWAP fallback, deviation gate of ≤1%.
- L2 deployments: add
SequencerUptimeFeedcheck.
Either path costs only the flash-loan fee. Critical-class risk to all funds in the pool.
Findings
| ID | Sev | Title |
|---|---|---|
| ORACLE-001 | Critical | Spot price read from AMM reserves |
| ORACLE-002 | Critical | Borrow uses spot price for collateral valuation |
| ORACLE-003 | Critical | Liquidation health check uses spot price |
| FLASH-001 | High | All 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