The function KeeperProxy._check()
(lines 188-198 in KeeperProxy.sol
) fails to properly handle return values from Chainlink's latestRoundData()
function. Specifically, it ignores key return values (answeredInRound
, roundID
), which can lead to oracle manipulation attacks or the use of stale price data. This creates a critical security risk, potentially enabling attackers to exploit outdated or manipulated price feeds.
Failure to Check answeredInRound
:
The function does not validate answeredInRound
, which is essential to confirm that the returned price is from a valid and latest round.
An attacker could force the contract to use an older price round, causing incorrect liquidations or price calculations.
Potential Use of Stale Data:
Although updatedAt
is checked, there is no verification that answeredInRound >= roundID
, allowing for potential oracle exploitation if the price feed is delayed or manipulated.
This could allow an attacker to replay an old, favorable price round.
Risk of Using an Invalid Price:
The function does not validate that chainLinkPrice
is a valid, non-zero price.
A manipulated oracle feed could return 0 or a negative value, breaking the contract's logic.
Manipulation of Price Feeds
Attackers could force the contract to use outdated price rounds, leading to potential incorrect liquidations or price arbitrage attacks.
Financial Loss to Users
If stale prices are used, liquidations may happen unfairly, causing loss of funds for users holding leveraged positions.
Contract May Rely on Invalid Data
Without checking answeredInRound
, the system may continue operating on incorrect or outdated oracle data, exposing it to market manipulation risks.
Vs code
1. Validate answeredInRound
to Ensure the Price Data is from a Valid Round
2. Check updatedAt
Against a Maximum Age Window
3. Ensure chainLinkPrice
is Not Zero or Negative
_check()
ImplementationPlease read the CodeHawks documentation to know which submissions are valid. If you disagree, provide a coded PoC and explain the real likelihood and the detailed impact on the mainnet without any supposition (if, it could, etc) to prove your point.
There is no real proof, concrete root cause, specific impact, or enough details in those submissions. Examples include: "It could happen" without specifying when, "If this impossible case happens," "Unexpected behavior," etc. Make a Proof of Concept (PoC) using external functions and realistic parameters. Do not test only the internal function where you think you found something.
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.