The getLatestPrice()
does not check if the retrieved price is stale. This allows the protocol to rely on outdated price data, which can be exploited to manipulate borrowing and liquidation in dependent contract - LendingPool
.
Attack scenario:
Assume an NFT was last priced at 100 ETH.
The oracle stops updating or is manipulated, and the real estate was disappeared.
A malicious user calls borrow()
in LendingPool
, which calls getLatestPrice()
to fetch the outdated 100 ETH price.
The attacker borrows far more than allowed, leading to bad debt for the protocol.
As seen above, this is only on example and so many vulnerabilities there. Real estate price is safer than others but does not mean maintain forever and even only their price is changed slower than others. But this means it doesn't ignore their stalenesss.
Severe risk of protocol bad debt: Borrowers over-borrow against outdated prices, leading to insolvency.
Unfair liquidations: Attackers trigger liquidations based on outdated low prices.
If the protocol loses funds due to incorrect price validation, users will not trust the lending system.
manual
To prevent outdated price exploitation, add a staleness check before returning the price.
At least, after a few seconds of lastUpdated, the price can be believable
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.