The LendingPool contract retrieves NFT house prices without validating their staleness, potentially allowing borrowing and liquidation decisions based on outdated price data, which could lead to significant protocol risks.
The LendingPool contract uses NFT house prices for critical operations including borrowing, liquidations, and health factor calculations. The getNFTPrice()
function retrieves prices from the oracle but fails to validate whether these prices are fresh enough to be used, despite having access to the lastUpdateTimestamp:
This stale price issue becomes particularly dangerous because the getNFTPrice()
function is used in several critical functions:
Through getUserCollateralValue()
:
Which is then used in critical functions like:
borrow()
- for determining borrowing capacity
calculateHealthFactor()
- for liquidation decisions
withdrawNFT()
- for checking if withdrawal would leave user undercollateralized
The staleness vulnerability can be exploited in several scenarios:
When house prices (imagine a house has caught fire example California wild fires burn) drop sharply but oracle hasn't updated
During oracle downtime or technical issues or in cases of network congestion preventing timely updates
Oracle sets NFT price to 100,000 USDC
Market conditions cause actual value to drop to 60,000 USDC
Oracle fails to update due to technical issues
User borrows 80,000 USDC against the NFT (based on stale price)
Protocol is now undercollateralized as the actual value is only 60,000 USDC
Protocol could become undercollateralized due to loans based on stale prices
Liquidations might be delayed or prevented due to incorrect health factor calculations
Users could withdraw NFTs when they should be locked for collateral
Overall protocol solvency at risk
Manual Review
Add staleness check in getNFTPrice():
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.