Proposed UI fix: UI should keep track of current feed price by querying /oracle from Coinbase, and tell user to update prices if current actions will cause liquidation, or if prices are stale.
Issue tl;dr: Liquidator can choose any combination of valid Coinbase-signed reports since last update to submit (e.g. 4 hrs ago for COMP and latest for ETH), to liquidate users even if the UI doesn’t indicate a liquidation possibility.
That means what you think its a 95% borrow limit while you are unwinding your positions, is a tasty snack for liquidators.
Current status: Reported, Known issue
Current fix: Prior to skating too close to your borrow limits, update price yourself through this link https://app.compound.finance/prices
I was unwinding a position in Compound and took out my supply to pay off the borrowing, I targetted 97% borrow limit, but was hit by a liquidation bot in the same block as the withdrawal.
As it turns out, the MEV transaction invoked a pair of oracle update that set the ETH price to a 6 minute old price, and the COMP price to a 4 hour old price.
The transaction I’m referencing is 0x1afd5cf2f5a0989e9f9e1733ed4afa0511fccc97ce1de5d22e3c616063554f21, in block 12425678 (Thu May 11:09:09 2021 GMT+0)
Using an archive node, we can reconstruct the numbers:
ETH | Thu May 13 02:54:00 2021 | 3632.155000
COMP | Thu May 13 02:54:00 2021 | 779.720000
Block 12425678 (MEV tx block):
ETH | Thu May 13 11:03:00 2021 | 3610.690000
COMP | Thu May 13 07:15:00 2021 | 810.420000
As can be seen, the COMP value was 4 hours old, and based on the Coinbase charts it would have between $761 and $765 in the minute candle.
This would have resulted in a 1.5% correct difference in value instead of the actual 4.5% shift in value.
How you might be affected
The liquidator would have to keep polling the coinbase oracle and not post the data.
As long as the oracle smart contract is not kept updated by an honest reporter, the liquidator can post any combination of price and time to maximise the liquidation. In this case, the attacker had a window of 8 hours to choose any combination of prices within.
Suggested SC Fixes
- I’m told that the price feed is in the middle of a massive overhaul: Oracle Infrastructure: Chainlink Proposal - #61 by jared
- LiquidateBorrower should require both Oracle reports to be signed at the same time.
- If for some reason the data isn’t available at the same time, there should be a sanity check against the uniswap oracle to see if it’s within limits.
Suggested UI Fixes before oracle overhaul
- UI should keep track of current feed price by querying /oracle from Coinbase, and tell user to update prices if current actions will cause liquidation, or if prices are stale.