Use Case & Applications

Monitors oracle price updates to detect and prevent price manipulation within a single transaction, protecting against flash loan attacks and malicious arbitrage. Critical for AMM-based DEXs using oracle prices, lending protocols relying on oracles for collateral valuation, synthetic asset platforms, derivatives protocols using oracles for settlement, and yield farming platforms calculating rewards based on asset prices. Intra-transaction price manipulations can lead to flash loan attacks, theft of funds through manipulated liquidations, or protocol insolvency due to incorrect asset valuations.

Explanation

Implements approach to verify oracle price updates using both pre/post state comparison and intra-transaction inspection:
  • forkPreState() / forkPostState(): Capture oracle price before and after transaction, compare for deviations
  • getCallInputs(): Monitor all price update function calls within transaction
  • registerCallTrigger(): Trigger when oracle price update is detected
  • Verify each update’s price parameter against initial price
  • Enforce no price update can deviate more than maximum allowed percentage
The assertion ensures oracle prices remain within acceptable deviation range throughout transaction, detecting and preventing flash loan attacks that attempt to manipulate prices. For more information about cheatcodes, see the Cheatcodes Documentation.

Code Example

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import {Assertion} from "credible-std/Assertion.sol";
import {PhEvm} from "credible-std/PhEvm.sol";

contract IntraTxOracleDeviationAssertion is Assertion {
    // Maximum allowed price deviation (10% by default)
    uint256 public constant MAX_DEVIATION_PERCENTAGE = 10;

    function triggers() external view override {
        // Register trigger for oracle price update calls
        registerCallTrigger(this.assertOracleDeviation.selector, IOracle.updatePrice.selector);
    }

    // Check that price updates don't deviate more than the allowed percentage
    // from the initial price at any point during the transaction
    function assertOracleDeviation() external {
        // Get the assertion adopter address
        IOracle adopter = IOracle(ph.getAssertionAdopter());

        // Start with a simple check comparing pre and post state
        ph.forkPreTx();
        uint256 prePrice = adopter.price();

        // Calculate allowed deviation thresholds (10% by default)
        uint256 maxAllowedPrice = (prePrice * (100 + MAX_DEVIATION_PERCENTAGE)) / 100;
        uint256 minAllowedPrice = (prePrice * (100 - MAX_DEVIATION_PERCENTAGE)) / 100;

        // First check post-state price
        ph.forkPostTx();
        uint256 postPrice = adopter.price();

        // Verify post-state price is within allowed deviation from initial price
        require(
            postPrice >= minAllowedPrice && postPrice <= maxAllowedPrice,
            "Oracle post-state price deviation exceeds threshold"
        );

        // Get all price update calls in this transaction
        // Since this assertion is triggered by updatePrice calls, we know there's at least one
        PhEvm.CallInputs[] memory priceUpdates = ph.getCallInputs(address(adopter), adopter.updatePrice.selector);

        // Check each price update to ensure none deviate more than allowed from initial price
        for (uint256 i = 0; i < priceUpdates.length; i++) {
            ph.forkPostCall(priceUpdates[i].id);

            // Call the price function at the given frame in the call stack
            uint256 updatedPrice = adopter.price();

            // Verify each update is within allowed deviation from initial pre-state price
            require(
                updatedPrice >= minAllowedPrice && updatedPrice <= maxAllowedPrice,
                "Oracle intra-tx price deviation exceeds threshold"
            );
        }
    }
}

interface IOracle {
    function updatePrice(uint256 price) external;
    function price() external view returns (uint256);
}
Note: Full examples with tests available in the Phylax Assertion Examples Repository.