Savory Glossy Pike
High
The Bracket contract relies on an external oracle to fetch token exchange rates for order execution. However, there are no mechanisms to validate the freshness of the oracle data. If the oracle provides outdated or stale data, the checkInRange function will fail to identify valid orders or execute them at incorrect prices, leading to user losses and missed positions.
High Probability:
- Oracle delays or network congestion are common in blockchain environments, especially during periods of high activity.
No Validation Mechanism:
- Without data freshness checks, there is no safeguard against this issue occurring.
Reliance on Oracle Data:
- The function fetches the exchangeRate from the oracle using MASTER.getExchangeRate.
- There is no validation of whether the fetched rate is current.
Potential for Stale Data:
- If the oracle provides outdated data (e.g., due to network delays, lags, or disruptions) which is very common due to common occurrence of stale oracle data in blockchain systems., valid orders may not execute or execute at incorrect rates.
No response
No response
Scenario: Missed Stop-Loss Execution Due to Stale Data 1- Setup:
- A user sets a stop-loss order with a stop price of $950 for a token pair.
- The oracle updates exchange rates every 60 seconds.
2-Market Movement:
- The market price of the token pair rapidly drops from $1000 to $900 within 30 seconds.
3-Impact:
- The oracle still reports the exchange rate as $1000, as it hasn't been updated.
- The checkInRange function evaluates the stop-loss condition based on the stale rate of $1000, failing to trigger the stop-loss order.
- The user's position continues to lose value, and they miss the opportunity to limit their losses.
Scenario: Incorrect Take-Profit Execution 1-Setup:
- A user sets a take-profit order at $1050.
- The oracle is delayed due to network congestion.
2-Market Movement:
- The market price briefly spikes to $1100 before dropping back to $1000.
- The oracle updates the exchange rate to $1050 after the market price has already fallen back.
3-Impact:
- The checkInRange function triggers the take-profit order based on outdated data.
- The order executes at a less favorable rate than the user expected, leading to reduced profits.
1- Missed Opportunities:
- Orders that should have been triggered may remain unprocessed, resulting in missed opportunities for profit or risk mitigation.
2- Financial Losses:
- Executing orders based on outdated prices may cause users to sell or buy assets at unfavorable rates.
3- User Distrust:
- Users may lose confidence in the platform's reliability and accuracy, affecting its reputation.
Why High?
- The impact directly affects user funds and the platform's operational integrity.
- The likelihood is non-negligible due to the absence of validation and the common occurrence of stale oracle data in blockchain systems.
Introduce a freshness validation mechanism to ensure that the oracle data is up-to-date before executing orders.
Updated Code: Include Data Freshness Checks
function checkInRange(
Order memory order
) internal view returns (bool inRange, bool takeProfit, uint256 exchangeRate) {
(exchangeRate, uint256 lastUpdated) = MASTER.getExchangeRateWithTimestamp(order.tokenIn, order.tokenOut);
// Validate data freshness
require(block.timestamp - lastUpdated <= MAX_ORACLE_AGE, "Stale oracle data");
if (order.direction) {
if (exchangeRate <= order.takeProfit) {
return (true, true, exchangeRate);
}
if (exchangeRate >= order.stopPrice) {
return (true, false, exchangeRate);
}
} else {
if (exchangeRate >= order.takeProfit) {
return (true, true, exchangeRate);
}
if (exchangeRate <= order.stopPrice) {
return (true, false, exchangeRate);
}
}
}
Key Changes:
- Fetch both the exchange rate and its last update timestamp.
- Add a require statement to validate that the data is not older than a predefined threshold (MAX_ORACLE_AGE).
Definitions:
- MAX_ORACLE_AGE: Maximum allowable age for oracle data, e.g., 30 seconds.
- getExchangeRateWithTimestamp: Updated oracle function to return both the rate and the timestamp of its last update.