Let’s Understand Price Oracle Manipulation

Securr
5 min readMay 20, 2024

--

Introduction

In the context of blockchain and decentralized finance (DeFi), price oracles are services that provide smart contracts with real-world data. They are crucial for various DeFi applications, such as lending platforms, synthetic assets, and decentralized exchanges, which rely on accurate and timely price feeds to function correctly.

Oracles bridge the gap between the off-chain world and on-chain smart contracts, enabling them to react to real-world events. Without reliable oracles, smart contracts cannot securely access external data, making oracles a critical component in the DeFi ecosystem.

How it works

Price oracle manipulation occurs when an attacker influences the price feed provided by the oracle, thereby affecting the smart contracts that depend on this data. This can lead to substantial financial losses, as smart contracts might execute trades, liquidations, or collateral adjustments based on the manipulated prices.

Let’s see the Techniques of Oracle Manipulation

A. Low Liquidity Attacks
Attackers target oracles that pull data from low liquidity markets. By executing large trades in these markets, they can significantly move the price, which is then reflected by the oracle.

- Example: Suppose an oracle pulls the price of an asset from a decentralized exchange (DEX) with low trading volume. An attacker could buy a large amount of the asset to artificially inflate the price, then trigger a smart contract function that benefits from the higher price, and finally sell the asset back, causing a profit at the expense of the smart contract or its users.

B. Flash Loan Attacks
Flash loans allow borrowing large amounts of cryptocurrency without collateral, provided the loan is repaid within the same transaction. Attackers use flash loans to manipulate prices temporarily.

-Example: An attacker takes a flash loan to buy a large amount of an asset, inflating its price on the exchange. The inflated price is captured by the oracle, allowing the attacker to exploit this high price in a DeFi protocol (e.g., taking out an over-collateralized loan). The attacker then sells the asset, repays the flash loan, and pockets the difference.

C. Data Source Exploitation
Oracles that rely on a single data source or a small set of sources are vulnerable to manipulation if the attacker can influence these sources.

- Example: An oracle using data from a single exchange can be manipulated by an attacker who influences the exchange’s price by executing a series of trades designed to shift the price in a specific direction.

Let’s see some Real-World Examples

A. bZx Attack (2020)
The bZx protocol was exploited twice in February 2020 through oracle manipulation. The attacker used flash loans to manipulate the price of wrapped Bitcoin (WBTC) on the Kyber Network, which was used by bZx’s oracle, resulting in substantial losses.

B. Harvest Finance (2020)
In October 2020, Harvest Finance suffered a $24 million exploit. The attacker manipulated the price of stablecoins on Curve Finance (a DEX) using flash loans, which Harvest Finance used for pricing its assets.

The Mitigation Strategies

If You are a web3 company looking for amazing protection from such hacks, look no more contact us — https://calendly.com/securrtech/securr

Know more about the amazing service like Web3 Bug Bounty and Smart Contract Auditing which securr provides — https://securr.tech

A. Use of Multiple Oracles
Relying on multiple oracles from different providers reduces the risk of manipulation, as it becomes harder to influence all data sources simultaneously.

B. Time-Weighted Average Prices (TWAP)
TWAPs smooth out price fluctuations by averaging prices over a set period, mitigating the impact of short-term manipulation.

C. Decentralized Oracle Networks
Decentralized oracle networks distribute the trust among many nodes, reducing the reliance on any single data source.

- Example: Tellor and Band Protocol use decentralized networks of data providers to secure their oracles.

D. Collateralization and Limits
Setting collateralization limits and requiring over-collateralization in DeFi protocols can reduce the impact of manipulated prices.

Let’s try to understand more clearly with some technical examples

1. Using Multiple Oracles

Using multiple oracles helps aggregate data from different sources to prevent manipulation. Here’s an example in Solidity:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface IOracle {
function getPrice() external view returns (uint256);
}

contract MultiOracle {
IOracle[] public oracles;

constructor(IOracle[] memory _oracles) {
oracles = _oracles;
}

function getMedianPrice() public view returns (uint256) {
uint256[] memory prices = new uint256[](oracles.length);
for (uint256 i = 0; i < oracles.length; i++) {
prices[i] = oracles[i].getPrice();
}
return median(prices);
}

function median(uint256[] memory array) internal pure returns (uint256) {
sort(array);
return array[array.length / 2];
}

function sort(uint256[] memory array) internal pure {
// Simple insertion sort
for (uint256 i = 1; i < array.length; i++) {
uint256 key = array[i];
uint256 j = i — 1;
while (j >= 0 && array[j] > key) {
array[j + 1] = array[j];
j — ;
}
array[j + 1] = key;
}
}
}

2. Using Time-Weighted Average Price (TWAP)

TWAP helps to smooth out price fluctuations by averaging prices over time. Here’s an example in Solidity using Uniswap’s TWAP:

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import “@uniswap/v2-core/contracts/interfaces/IUniswapV2Pair.sol”;

contract TWAPOracle {
IUniswapV2Pair public pair;
uint256 public priceCumulativeLast;
uint32 public blockTimestampLast;
uint256 public priceAverage;

constructor(IUniswapV2Pair _pair) {
pair = _pair;
priceCumulativeLast = pair.price0CumulativeLast();
(, , blockTimestampLast) = pair.getReserves();
}

function update() external {
(uint256 price0Cumulative, , uint32 blockTimestamp) = UniswapV2OracleLibrary.currentCumulativePrices(address(pair));
uint32 timeElapsed = blockTimestamp — blockTimestampLast;

require(timeElapsed > 0, “TWAPOracle: no time elapsed”);

priceAverage = (price0Cumulative — priceCumulativeLast) / timeElapsed;
priceCumulativeLast = price0Cumulative;
blockTimestampLast = blockTimestamp;
}

function getPrice() external view returns (uint256) {
return priceAverage;
}
}
```

3. Using Decentralized Oracle Networks

Decentralized oracle networks like Chainlink provide reliable price feeds. Here’s an example using Chainlink’s price feed:

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import “@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol”;

contract ChainlinkOracle {
AggregatorV3Interface internal priceFeed;

constructor(address _priceFeed) {
priceFeed = AggregatorV3Interface(_priceFeed);
}

function getLatestPrice() public view returns (int256) {
(, int256 price, , ,) = priceFeed.latestRoundData();
return price;
}
}
```

4. Implementing Collateralization and Limits

Ensuring proper collateralization can mitigate the impact of manipulated prices. Here’s an example of a lending platform with over-collateralization:

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import “@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol”;

contract LendingPlatform {
AggregatorV3Interface internal priceFeed;
mapping(address => uint256) public collateral;
mapping(address => uint256) public debt;

constructor(address _priceFeed) {
priceFeed = AggregatorV3Interface(_priceFeed);
}

function depositCollateral() external payable {
collateral[msg.sender] += msg.value;
}

function borrow(uint256 amount) external {
uint256 collateralValue = getCollateralValue(msg.sender);
require(collateralValue >= amount * 150 / 100, “Not enough collateral”);
debt[msg.sender] += amount;
payable(msg.sender).transfer(amount);
}

function getCollateralValue(address user) public view returns (uint256) {
(, int256 price, , ,) = priceFeed.latestRoundData();
return collateral[user] * uint256(price) / 1e8;
}

function repayDebt() external payable {
require(msg.value <= debt[msg.sender], “Overpaying debt”);
debt[msg.sender] -= msg.value;
}
}
```

Conclusion
Price oracle manipulation is a critical threat to the DeFi ecosystem, requiring robust solutions and constant vigilance. Employing a combination of multiple oracles, decentralized networks, time-weighted prices, and stringent collateralization requirements can significantly mitigate the risks. As DeFi continues to grow, the security of price oracles will remain a pivotal factor in ensuring the stability and trustworthiness of the ecosystem.

Understanding and addressing the vulnerabilities in price oracles is crucial for the long-term success and security of DeFi platforms. As the technology and strategies evolve, staying informed and implementing best practices will help safeguard against the sophisticated tactics employed by attackers.

Securr’s Twitter Handle-https://x.com/Securrtech
Securr’s Website- https://securr.tech
Securr’s Calendly- https://calendly.com/securrtech/securr

--

--

Securr

Pioneering Web3 Bug Bounty Platform - Your Gateway to Solid Security