In the LiquidationPool::distributeAssets function is used Chainlink latestRounData function to retrieve the EUR/USD and Token/USD prices. But the returned prices can be incorrect or stale. Therefore, it is important to check the returned values from Chainlink before their use. Also, the contract will be deployed on Arbitrum. When utilizing Chainlink in L2 chains like Arbitrum, it's important to ensure that the prices provided are not falsely perceived as fresh particularly in scenarios where the sequencer might be non-operational. Therefore, it is required to confirm the active status of the sequencer before trusting the data returned by the oracle.
The LiquidationPool::distributeAssets function relies on Chainlink latestRoundData function to retrieve the EUR/USD and Token/USD prices. But the function does not check if the returned price from Chainlink is not stale.
That can lead to issues if Chainlink starts a new round and struggles to establish consensus on the new value for the oracle. Without proper checks, the function LiquidationPool::distributeAssets may continue using outdated, stale, or incorrect price if oracles are unable to submit and start a new round. Possible reasons for this could include Chainlink nodes abandoning the oracle, chain congestion, or vulnerabilities/attacks on the Chainlink system.
Additionally, there is no check if the Arbitrum Sequencer is active. In the event of an Arbitrum Sequencer outage, the oracle data may become outdated, potentially leading to staleness. You can review Chainlink docs on L2 Sequencer Uptime Feeds for more details on this.
https://docs.chain.link/data-feeds/l2-sequencer-feeds
In the LiquidationPool::distributeAssets function, asset distribution is based on the current price of the EUROs and the assets being distributed. Stale prices could lead to incorrect distribution of assets, with users receiving either too much or too little compared to the actual market value. The function also calculates the cost in EUROs for the portion of assets distributed to each holder. Stale prices could lead to rewards being priced incorrectly, affecting the amount of EUROs burned and the rewards given to users.
Also, in the scenario where the Arbitrum Sequencer experiences an outage, the protocol will enable users to maintain their operations based on the previous (stale) rates.
Manual Review
To mitigate this issue, it is recommended to implement checks to ensure that the price returned by Chainlink is not stale. You can add the following code to validate the price obtained from Chainlink:
To check if the Arbitrum Sequencer is alive, you can add the following function and use it in require statement in the distributeAssets function:
Here is a code example on Chainlink docs: https://docs.chain.link/data-feeds/l2-sequencer-feeds#example-code
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.