The StrataxOracle "getPrice" function is expected to return a fresh, reliable price from Chainlink by calling latestRoundData() and validating the response before it is used in critical financial calculations such as determining borrow amounts during position opening and collateral withdrawal amounts during position unwinding.
However, the function discards the updatedAt, roundId, and answeredInRound fields from the Chainlink response and only checks that answer > 0. This means a price that hasn't been updated in hours or even days — due to Chainlink network congestion, feed deprecation, or multisig failures — will be silently accepted and used in _executeUnwindOperation and calculateOpenParams, potentially causing the contract to miscalculate collateral-to-debt ratios and resulting in users withdrawing too much or too little collateral when unwinding leveraged positions.
Likelihood:
Chainlink price feeds have documented instances of delayed updates during high network congestion, L2 sequencer downtime, or feed deprecation. When a feed's updatedAt timestamp falls significantly behind block.timestamp, every call to StrataxOracle::getPrice will return the outdated price without any revert, since the function only validates answer > 0 and discards all freshness metadata. This is not an edge case — Chainlink's own documentation explicitly recommends checking updatedAt and answeredInRound for this reason.
Impact:
During position unwinding in _executeUnwindOperation, a stale price causes the collateralToWithdraw calculation to be incorrect. If the stale price overvalues the collateral token relative to the debt token, the contract withdraws less collateral than needed to cover the flash loan repayment via swap, causing the require(returnAmount >= totalDebt) check to fail and locking the user out of unwinding their position. Conversely, if the stale price undervalues the collateral, the contract withdraws more collateral than necessary, leaving excess value in the swap return that gets re-supplied to Aave rather than returned to the user — a direct loss of user funds. During position opening via calculateOpenParams, a stale price produces an incorrect borrowAmount, which either causes the Aave borrow to revert (if too high) or results in a position with less leverage than intended (if too low).
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.
The contest is complete and the rewards are being distributed.