DEV Community

liguang he
liguang he

Posted on

Aave CAPO Oracle $27.78M Liquidation — Dev.to

When the Guard Dog Bites: The Aave CAPO Oracle Incident That Liquidated $27.78M
A deep dive into how Aave's automated anti-manipulation oracle became the source of a $27.78M liquidation cascade, and what Web3 developers should learn from it.
The Incident in Brief
On March 10, 2026, Aave's CAPO Oracle — an automated system designed to prevent oracle manipulation — pushed a faulty snapshotRatio update for wstETH. The oracle priced wstETH at ~1.19 ETH instead of the market rate of ~1.228849 ETH. A 2.85% discrepancy.
That was enough. 34 E-Mode positions were liquidated. 10,938 wstETH wiped out. Total value: approximately $27.78M.
No hacker. No exploit. The safety system itself fired on friendly forces.
Understanding CAPO Oracle
┌──────────────────────────────┐
│ Chaos Labs Edge Risk Engine │ ← Off-chain computation
└────────────┬─────────────────┘
│ Submit update

┌──────────────────────────────┐
│ AgentHub (BGD Labs) │ ← On-chain execution layer
└────────────┬─────────────────┘
│ Execute (1 block)

┌──────────────────────────────┐
│ Aave CAPO Oracle │ ← Price feed for protocol
└──────────────────────────────┘

Design philosophy: Speed over deliberation. No time-lock. No multisig review. If the system makes an error, it executes in the same one-block window designed for emergency response.
The Root Cause
The official post-mortem states: "a configuration mismatch between two parameters that should have moved in sync."
contract CAPOOracle {
uint256 public snapshotRatio;
uint256 public referenceRate;

function getAssetPrice(address asset) external view returns (uint256) {
    if (asset == WSTETH) {
        uint256 basePrice = chainlinkFeed.latestAnswer();
        uint256 effectiveRatio = (snapshotRatio * referenceRate) / 1e18;
        return (basePrice * effectiveRatio) / 1e18;
    }
}

function updateParameters(
    uint256 newSnapshotRatio,
    uint256 newReferenceRate
) external onlyRole(AGENTHUB_ROLE) {
    // ⚠️ No consistency validation
    snapshotRatio = newSnapshotRatio;
    referenceRate = newReferenceRate;
}
Enter fullscreen mode Exit fullscreen mode

}

The Liquidation Cascade
2.85% oracle error → 34 accounts liquidated → 10,938 wstETH → $27.78M gone.
The Two Narratives
Omer Goldberg (Chaos Labs CEO): "A misconfiguration on Aave's CAPO oracle resulted in wstETH E-Mode liquidations, causing 345 ETH in losses. All affected users will be fully compensated."
Stani Kulechov (Aave founder): "Technical misconfiguration caused the liquidation of positions that were already close to liquidation threshold."
Lessons for Web3 Developers

  1. Automated Systems Need Automated Safeguards
    modifier withinSafetyBounds(uint256 newValue, uint256 oldValue) {
    if (oldValue > 0) {
    uint256 deviation = newValue > oldValue
    ? (newValue - oldValue) * 10000 / oldValue
    : (oldValue - newValue) * 10000 / newValue;
    if (deviation > MAX_DEVIATION_BPS) {
    emit SafetyBoundExceeded(oldValue, newValue, deviation);
    _scheduleTimelockedUpdate(newValue);
    return;
    }
    }
    _;
    }

  2. Multi-Parameter Systems Need Consistency Checks
    function updateParameters(uint256 newRatio, uint256 newCache) external onlyOperator {
    uint256 oldOutput = (snapshotRatio * exchangeCache) / 1e18;
    uint256 newOutput = (newRatio * newCache) / 1e18;
    uint256 outputDelta = newOutput > oldOutput ? newOutput - oldOutput : oldOutput - newOutput;
    require(outputDelta * 10000 / oldOutput <= MAX_OUTPUT_CHANGE_BPS, "Output deviation too large");
    snapshotRatio = newRatio;
    exchangeCache = newCache;
    }

  3. Time-Locks Are Not the Enemy of Speed
    enum UpdateType { Routine, Emergency }

function scheduleUpdate(uint256 newPrice, UpdateType updateType) external onlyOperator {
uint256 delay = updateType == UpdateType.Emergency ? 0 : 30 minutes;
if (updateType == UpdateType.Emergency) {
require(hasValidMultisigSignature(), "Emergency requires multisig");
}
_scheduleUpdate(newPrice, delay);
}

  1. Independent Monitoring Should Be a First-Class Concern LTV Protocol, a third-party monitor, was the first to publicly flag the anomaly — before Aave's official post-mortem.
  2. Track Records Create Complacency CAPO had pushed 1,200+ payloads with zero failures. Then one failure caused $27.78M in liquidations. Conclusion The speed that makes CAPO effective against manipulation also makes it dangerous when it misfires. Automate safely. Validate consistency. Embrace monitoring. Design for failure. References:
  3. Parameter Update TX
  4. Execution TX
  5. Aave Post-Mortem
  6. LTV Protocol Alert

Top comments (0)