5
min read

Oracle Manipulation

Published on
June 30, 2024

It is one of the most common attack vectors in DeFi, so both auditors and protocols need to learn what it is and how to deal with it, so get your notepads out and dive into our thread.

Oracle Manipulation: Theory

Firstly, let’s figure out how and why we get the price. For simplicity, let’s have an example of the lending protocol Shieldify. Before letting to borrow funds, we want to get the current price. The safest way is to call Chainlink’s Price Feed and get an aggregate off-chain price, but it’s often the case when the protocol wants to use on-chain oracles (e.g. Uniswap). If we use Uniswap, we call <code-word>slot0<code-word> function to get the current price of an asset (e.g. WETH). The problem is that at that very moment, the price can be manipulated to be extremely high or low depending on the attacker’s needs.

For example, the current WETH price is $4000 and the user has deposited exactly 1 WETH. They want to borrow USDC, but LTV is 80%, which means they can get up to $3200. To calculate it in the protocol and not allow to take out more than $3200, we have to get the price of the token, so we call <code-word>slot0<code-word> on Uniswap’s Oracle contract.

But, before depositing, the attacker decides to make a big swap on Uniswap (involving flash-loans) leading to WETH's price increasing from $4000 to $6000. Now, the max amount of USDC they can get is $4800 instead of $3200. They borrow $4800, swap on Uniswap back to $4000 WETH price, return the flash loan and profit $800 ($4800 - $4000).

Oracle Manipulation: Code

For a deep dive into code, let’s take a simple Lending & Borrowing protocol. But, in this example, we will have a collateralization ratio of 120%. It’s similar to the LTV that we used above, e.g. from $4000 worth of WETH, we’ll get 3333 USDC.

Above, you can see our borrow function and let’s walk through it step by step. We get the position struct for the <code-word>msg.sender<code-word> who’s going to borrow. Then we increase their borrowed amount by the value they input and collateral by the <code-word>msg.value<code-word> they’ve sent. After that, we check if the position is healthy, i.e. holds the 120% collateralization ratio.

In the position health check, we get the collateral price and then calculate the current collateralization ratio of the position:

If the result is that the collateralization ratio is ≥ 120%, then it’s healthy and unhealthy if it’s less. But the main problem here is in the <code-word>getCollateralPrice()<code-word> function.

As you see, we get the price of USDC from Uniswap’s <code-word>slot0<code-word>. So let’s construct an attack path to manipulate the price and steal funds from this lending protocol.

The same as previously, the ETH price is $4000 and we want to borrow exactly 1 ETH of collateral. With a 120% collateralization ratio, we’re able to borrow only 3,333 USDC. So here’s what we have to do:

1. Make a large swap on Uniswap, increasing the price to $6000.

2. Call `borrow` method with 4800 USDC to borrow and 1 ETH as collateral.

3. Make a swap back, returning the price to $4000, and repay the flash loan.

4. Results:
   - Sent as collateral 1 ETH = $4000.
   - Profit is 5000 USDC = $5000 (120% collateralization ratio).

Mitigation

There are two of the most safe mitigations in this case:

  • TWAP — you can check about TWAP in one of our recent threads.
  • Off-chain oracles — one of the best examples can be Chainlink or Pyth.
  • Combination of both — you can verify the data both oracles give you in case one of them is compromised or goes offline.

Conclusion

In conclusion, oracle manipulation is a critical risk in DeFi, allowing attackers to exploit price discrepancies for profit. To mitigate this, protocols should use safeguards like Time-Weighted Average Price (TWAP) and reliable off-chain oracles such as Chainlink or Pyth. Combining these methods enhances security by cross-verifying data and ensuring resilience against failures. These measures are essential for protecting the integrity and stability of the DeFi ecosystem.