DeFi Security

Price Manipulation in DeFi

by VirtualZero Research · 14 min read · Oracles · AMM · Flash Loans

Price manipulation is the most common attack vector in DeFi. Every protocol that uses on‑chain price data — whether for lending, liquidations, derivatives or swaps — must understand how manipulators distort prices and how to defend against it.

1. Flash Loan & Oracle Manipulation

A flash loan gives the attacker temporary control of a large capital. They use it to skew a spot price on a DEX, then exploit a protocol that reads that spot price without validation.

// ❌ VULNERABLE — uses spot price from a single AMM
contract WeakLender {
    IUniswapV2Pair public pool;

    function getCollateralValue(address token) public view returns (uint256) {
        (uint112 reserve0, uint112 reserve1, ) = pool.getReserves();
        return token == pool.token0() ? reserve0 : reserve1;
    }

    function liquidate(address user) external {
        uint256 coll = getCollateralValue(user);
        // ...
    }
}
Attack: Attacker flash‑borrows → swaps large amount on the pool → getReserves() returns a manipulated price → liquidates a healthy position → repays flash loan.

Mitigation: Use a TWAP oracle (e.g., Uniswap V2 built‑in) instead of a single block spot price. TWAP averages the price over a period, making manipulation exponentially more expensive.

// ✅ SAFER — TWAP-based oracle
import "@uniswap/v2-periphery/contracts/libraries/UniswapV2OracleLibrary.sol";

function getCurrentTWAP(address pool, uint256 period) external view returns (uint256) {
    uint256 priceCumulative = IUniswapV2Pair(pool).price0CumulativeLast();
    uint256 timestamp = IUniswapV2Pair(pool).blockTimestampLast();
    // use UniswapV2OracleLibrary to compute TWAP
    return UniswapV2OracleLibrary.currentPrice(pool, period);
}

2. TWAP Exploitation (Time‑Weighted Average Price)

TWAP oracles are not bulletproof. If the attack spans multiple blocks or the TWAP window is too short, an attacker can still manipulate the average.

// Attack scenario: manipulate TWAP over 2 blocks
// Block 1: attacker swaps 1000 ETH, moving price from 2000 to 1500
// Block 2: attacker swaps another 1000 ETH, moving price to 1100
// TWAP(2 blocks) = (2000 + 1500 + 1100) / 3 ≈ 1533  (still far from true market)

Mitigation: Use a longer TWAP window (≥30 minutes). Combine with a price deviation check — if the current price diverges from the TWAP by more than X%, revert.

3. Sandwich Attacks (MEV)

While not a protocol vulnerability, sandwich attacks harm users. A bot observes a pending transaction, places a buy order before it and a sell order after, capturing the slippage.

// User's tx: swap 10 ETH for USDC
// Bot's front-run: buy USDC before user → price ↑
// User's tx executes at worse rate
// Bot's back-run: sell USDC → profit

Mitigation: Use slippage protection (minAmountOut). Protocols can also use batch auctions or commit‑reveal schemes.

4. Price Manipulation via Liquidity Depletion

If a pool has very low liquidity, even a small trade can cause extreme price impact. Attackers target these pools to trigger liquidations or steal funds.

// ❌ VULNERABLE — uses pool with < 1 ETH liquidity
function getPrice(address token) view returns (uint256) {
    uint256 reserve = IUniswapV2Pair(pair).getReserves();
    // if reserve is tiny, division yields huge price
    return (reserve * 1e18) / otherReserve;
}

Mitigation: Always check minimum liquidity before trusting a price. Use a chainlink oracle as a fallback or a weighted median of multiple sources.

5. Defensive Patterns

← Back to Research