Summary: The StrataxOracle contract accepts stale price data from Chainlink feeds without validation. This allows the protocol to execute critical calculations using outdated market rates, which can lock the single-owner out of unwinding positions during volatility.
Severity: High
Affected Component:
File: src/StrataxOracle.sol
Function: getPrice
Source Confirmation: The function calls latestRoundData() but ignores the updatedAt return value:
Root Cause: Methodical oversight in the Oracle integration. The developer assumed latestRoundData always returns fresh data, neglecting to check the updatedAt timestamp against a heartbeat threshold.
Impact and Transaction Trace:
Context: Stratax is a single-owner protocol where only the deployer can manage positions.
Scenario:
The Owner holds a leveraged position: Collateral = ETH, Debt = USDC.
State: Market crashes. ETH price drops from $2000 to $1000.
Oracle: The Chainlink ETH feed stops updating (latency or DoS), freezing at $2000 (Stale Price).
Action: The Owner attempts to call unwindPosition to close the trade and stop losses.
Execution Trace:
Stratax.unwindPosition calls _executeUnwindOperation.
Contract calls calculateCollateralToWithdraw.
StrataxOracle.getPrice returns the stale $2000 for ETH.
Calculation: collateralToWithdraw = Debt / $2000.
Result: The contract withdraws only 0.5x the amount of ETH actually needed to cover the debt (because real price is $1000).
The contract swaps this insufficient ETH for USDC.
The swap returns roughly 50% of the required USDC.
The check require(returnAmount >= totalDebt) fails and reverts.
Source Confirmation:
// src/Stratax.sol:588require(returnAmount >= totalDebt, "Insufficient funds to repay flash loan");
Outcome: The Owner is locked out of closing their position because the contract math relies on the wrong price. As the real price continues to drop, the position gets liquidated by Aave, causing total loss of collateral, purely because the Stratax contract refused to calculate the correct withdrawal amount.
PoC (End-to-End Verified):
This PoC simulates the exact ETH/USD scenario described in the impact trace. It uses the WETH_PRICE_FEED constant and simulates a 2-hour old price update (exceeding the standard 1-hour heartbeat).
Verification Evidence:
The following is the actual terminal output from the test execution. Note that this test runs in a mocked environment (as indicated by the gas usage and lack of fork initialization logs), which is sufficient to prove the logic flaw in the StrataxOracle contract itself.
Recommended Fix:
Add a configurable heartbeat mapping. To ensure backward compatibility, setPriceFeed sets a default heartbeat (24h) if none exists.
⚠️ Warning: The default 24h heartbeat is unsafe for volatile assets like ETH (which requires 1h). Owners MUST call
setHeartbeatmanually for volatile tokens after setting the feed, or the vulnerability will persist for those assets (allowing up to 23h of staleness).
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.