In the UpdateWeightRunner contract, there's a function performUpdate function which calls _getData private view (staticCall) function to update weights. The _getData function has oracle data staleness threshold checks implementations to ensure that oracle data is fresh and ready to use. However, those checks has an oversight which makes protocol inefficient and buggy. The issue is a tiny mis-comparison of staleness threshold, Comparison missed one second of oracle staleness threshold which causes potential issues.
If the weight update fails due to a one-second shortage in the oracle stale threshold, it could lead to several potential issues, particularly in a protocol like QuantAMM that depends on timely and accurate weight updates:
UpdateWeightRunner::_getData:
As we can see clearly that, if check has a flaw of in comparison, the comparison operator > used instead of >= due to which there's comes a shortage of one-second.
Let's see a scenario...
let's say, the oracleStalenessThreshold is 1 hours
oracle data last updated at 10 AM
The current timestamp is of 11 AM
According to the if check condition: oracleResult.timestamp > block.timestamp - oracleStalenessThreshold
10 AM > 11 AM - 1 hours
10 AM > 10 AM = False
revert: No fresh oracle values available
Missed Opportunity for Optimal Rebalancing
Effect: Delays in updating weights may prevent the pool from adjusting to market conditions effectively. If the weights don't reflect recent price movements, the pool could:
Underperform compared to an optimally rebalanced pool.
Expose LPs to increased impermanent loss.
Example: If the price of an asset spikes, failing to update weights in time means the pool doesn't capitalize on the opportunity to rebalance and mitigate risk.
Economic Arbitrage Risks
Effect: Stale weights could misprice assets within the pool, allowing arbitrageurs to exploit the difference between pool prices and the market price because the update was recently failed.
Example: If an oracle is stale for even a second, arbitrageurs might profit by buying underpriced assets or selling overpriced ones, leading to a loss of value for LPs.
Weight Drift
Effect: The pool's weights might drift significantly from the intended trajectory, resulting in misaligned portfolio composition.
Impact: This can reduce the pool's effectiveness in achieving diversification and expose LPs to unintended risk concentrations.
Potential Protocol Downtime
Effect: If weight updates consistently fail due to oracle data issues, the pool might enter a semi-stalled state where weights remain static. This reduces trust in the protocol and limits its functionality.
Example: Users might be unable to make informed decisions about depositing, withdrawing, or trading due to uncertainty in the pool's performance.
Compounded Delays
Effect: A small initial delay might cascade into larger timing issues. Weight updates are typically scheduled periodically, and missing one window might mean waiting for the next.
Impact: This could compound losses or inefficiencies over time
Manual Review
Phind AI Buddy (Asked its severity)
The Mitigation is so simple. Update the if checks and replace > operator with >= operator as we did below:
UpdateWeightRunner::_getData:
Please read the CodeHawks documentation to know which submissions are valid. If you disagree, provide a coded PoC and explain the real likelyhood and the detailed impact on the mainnet without any supposition (if, it could, etc) to prove your point.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.