LiquidationPool::distributeAssets()
makes use of Chainlink's price feeds but does not perform the recommended staleness checks.
The Chainlink price feeds can return stale data for a variety of reasons. Currently, calls to the oracles inside LiquidationPool::distributeAssets()
do not perform the recommended checks to protect against this.
L207:
L218:
This is also present in the PriceCalculator
contract and will lead to similar issues wherever its functions are used. While that one is out of scope for this contest, I believe it is still worth mentioning.
For a detailed explanation of why this might occur, refer to the following resource: https://ethereum.stackexchange.com/questions/133242/how-future-resilient-is-a-chainlink-price-feed/133843#133843
Wrongly updated EUROs positions of all stakers
Wrong amount of EUROs being burned from the contract
Wrong reward distribution
Manual Analysis
Read the updatedAt
parameter returned from latestRoundData()
and verify that it isn't older than a set threshold amount:
The staleness threshold should correspond to the heartbeat duration of the feed. These can be checked in the official Chainlink docs (make sure to check "Show more details"):
https://docs.chain.link/data-feeds/price-feeds/addresses/?network=arbitrum&page=1.
It's also important to note that different feeds have different heartbeats, so it's advisable to store these values somewhere and incorporate them into the staleness check logic on a feed to feed basis.
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.