The protocol uses cached Chainlink spot prices to optimize gas usage. The documentation states that any actions related to shorts will attempt to check the latest Oracle price and will occasionally use a cached oracle price to save on gas by saving the last oracleTime and oraclePrice.
The vulnerability comes from the inconsistency in price fetching methods across different functions, particularly those that set or reset flags on shorts. The main function that sets a flag, ‘flag’, uses the ‘getSavedOrSpotOraclePrice’ function to fetch the oracle price, which could either use the saved price or the latest price, depending on whether the latest update has surpassed 15 minutes.
However, other functions like ‘increaseCollateral’ and ‘maybeResetFlag’ use the ‘getCollateralRatio’ function, which relies on the ‘getPrice’ function, fetching only the latest saved price in the system.
This difference in price fetching methods between functions that influence the same flag can lead to discrepancies, potentially allowing the flag to be incorrectly reset.
Consider the following scenario:
Time: 0 hours
Oracle Spot Price: $1000 (Saved in the system)
Time: 16 minutes
A user calls the flag
function due to a perceived drop in price.
Actual Oracle Spot Price: $800 (The system updates the saved price as it's past 15 minutes from the last update.)
The short is correctly flagged, considering the new price drop.
Time: 17 minutes
The short holder calls increaseCollateral
with a minimal amount of ETH.
The system uses the outdated higher price from 17 minutes ago to check the collateral ratio in maybeResetFlag
.
The flag on the short gets incorrectly reset as it perceives the collateral ratio to be healthy with the outdated price.
The short holder calls increaseCollateral with a minimal amount of ETH.
The system uses the outdated higher price from 17 minutes ago to check the collateral ratio in maybeResetFlag.
The flag on the short gets incorrectly reset as it perceives the collateral ratio to be healthy with the outdated price.
The inconsistency in price fetching can be exploited by knowledgeable short holders. They can manipulate the system by intentionally calling functions like ‘increaseCollateral’ or one of the exit short positions that use ‘maybeResetFlag’ to reset the flag.
This incorrect reset could cause the original flagger to lose their right to potentially liquidate the short and earn fees, even though the short was correctly flagged due to the latest price.
Manual Analysis
Standardize the method of fetching prices across all functions that deal with setting or resetting flags. This eliminates the chances of discrepancies in prices between different functions.
Specifically, it would be better to modify functions like ‘increaseCollateral’ and ‘maybeResetFlag’ to use the ‘getSavedOrSpotOraclePrice’ function, as this method provides a more up-to-date price compared to using only the latest saved price.
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.