Common Vulnerabilities: Oracles and Pricing - Smart Contracts
Introduction
One of the core advantages of Decentralised Finance is the composability of contracts, enabling different Dapps to source data from one another. This alone enables many novel use cases of onchain data such as token financial derivatives, betting platforms and insurance. With the ability to bring data onchain via Oracles, these uses are extended yet further to political bets, stock market derivatives and more.
In this article we will explore some of the common missteps made when attempting to make use of Oracles and pricing feeds in writing smart contracts, and steps that can be taken to mitigate them.
Spot Pricing
Due to the pseudo-anonymity and permissionless nature of blockchains, one must be more careful when attempting to read onchain prices. A common attack vector is utilising flash loans, instantaneous, arbitrarily sized, unbacked loans, to influence the price of a token on DeFi exchanges such as Uniswap or other venues. While most developers are now aware of this folly, they have been a repeated headache to those caught unaware. In 2020, Harvest Finance, a lending protocol, learned this the hard way when it integrated a Curve Finance pool token as collateral. A hacker used a flash loan to warp the collateral price and extract a loan larger than the deposit size. Despite Harvest Finance implementing 3% slippage checks, the attacker was able to yield a $24 million crop from repeated attack cycles.
Whilst most prolific on EVM based chains, spot pricing exploits have also occurred on other chains. Even a lack of flash loans is insufficient to protect against such attacks, as Mango Finance on Solana discovered when a trader found a "highly profitable trading strategy". Namely, using a large amount of funds to manipulate the spot price of MNGO while holding a large leveraged counter position on the Mango perpetual market. This resulted in a profit of about $110 million, which seemed to be the trade of a lifetime, until said trader was also charged and convicted in US courts.
Mitigation
- Avoid using raw spot pricing from onchain sources as a price feed. Alternatives, such as Time Weighted Average Pricing (TWAPs), are inbuilt to some decentralised exchanges such as Uniswap.
- Make use of time delays to prevent manipulations in the same, or a small number of blocks.
Homegrown Oracles
For many DeFi applications, the time to market can be of critical importance. With novel markets, it can be tempting to write your own price oracles to get the first mover advantage. However, when doing this, it can be easy to make mistakes due to a lack of standards to adopt. Synthetix, a synthetic asset trading platform, faced this issue in 2019 with their synthetic Maker Protocol token sMKR, which was intended to track the price of the DeFi token MKR.
An attacker discovered that, while Synthetix had made use of multiple price feeds, including offchain sources, the majority of these feeds were influenced heavily by the UniswapV1 MKR/ETH pool. Thus, they could influence the trading price of sMKR by trading against this pool. Coupling this with a position comprised of long or short sMKR/iMKR on Synthetix protocol, they could then synthesize a profit.
Mitigation
- Be cautious about the sources of price feed data and if these sources are manipulatable.
- Employ circuit breakers and backup mechanisms in the event when some price feeds are rejected or unavailable, so that the protocol does not become easier to attack.
- Use medians of various price feeds to make it more difficult and expensive to influence the overall price.
Time Delay/Frontrunning
Once an acceptable price feed is created, it can be tempting to consider the job done but, as is often the case in DeFi, it has just begun. While the sources of a price may be rigourous, these are not the only attributes a protocol needs to consider - timing too can be important. Due to the discrete nature of blocks and the decentralised nature of blockchains in general, onchain events occur quite slowly compared to their TradFi equivalents.
The pace of block propogation can make timing attacks viable. Most common with price feeds is frontrunning or backrunning where a transaction is placed just before or after a price update to benefit from the price delta. Synthetix again, as one of the trailblazers of DeFi, battled this issue for a long time. While there was no single attack, through protocol monitoring and careful analysis, Synthetix discovered patterns in trades suggesting some users were manipulating the delay in updating onchain price oracles, and so siphoning off value from the Synthetix stakers.
The initial fix for this issue was to integrate a settlement period where deviations in price in this time period would be settled on the traders account. While this helped fix the issue, it prevented related token transfers and produced a poor user experience. Synthetix later transitioned the majority of their trading to faster Layer 2 chains and adopted pull style price oracles, as these help eliminate price discrepancies by updating oracle values at higher frequencies.
Mitigation
- Make use of offchain monitoring to flag suspicious trades or patterns emerging.
- Make use of offchain MEV protection mechanisms such as Flashbots.
- If possible, deploy to blockchains with faster block times to reduce the window for attack, such as Layer 2 solutions. Typically, these also have far cheaper transactions which allow for more frequent price updates for the same price.
Gas congestion
Another form of pricing time delays that occur onchain arises due to the need to pay gas for transactions. In times of high transaction demand, users will bid higher gas price per transaction for fast inclusion. Price volatility often goes hand in hand with high network gas, owing to the fact that many contracts suddenly become profitable if accepted prices have changed elsewhere. This can be problematic if Dapps and their supporting software are not designed for this.
On 12th March 2020, Crypto’s Black Thursday happened. On this day, the price of Cryptocurrencies fell dramatically, with ETH experiencing a 40% decline (the stock market also faced significant losses).
This caused particular problems for Maker Protocol as their DAI stablecoin was only backed by ETH at that time. Typically, if a loan comes close to being underwater in the Maker system, it would trigger an auction of the collateral ETH, where bidders offer increasing amounts of DAI in return for being selected to receive the collateral at stake.
Owing to the very high gas prices at the time, peaking at around 200 gwei from averages of about 10 gwei daily beforehand, two events occured:
- Firstly, the ETH price oracles for Maker’s system lagged with updating prices, meaning that once updated, a sudden 20% price drop was realised leading to numerous vaults being liquidated at the same time.
- Then compounding this issue, as auctions for the collateral of the vaults started, the gas continued to be much higher than before. This lead to an auction where the initial 0 DAI bid for the $8.3 million of ETH succeeded.
This auction result occurred mainly because a majority of bidders were running reference bidding software designed by Maker, which was not equipped to handle such gas increases, meaning many bids were ignored by the network due to insufficient gas. The price volatility further compounded this issue as other usual bidders were hesitant to bid in fear of further flash crashes.
Mitigation
- Offchain software should be audited and treated as important as smart contracts.
- Multiple versions of critical offchain software should be encouraged through grants or inbuilt revenue streams.
- Ensure the protocol is designed with sufficient liquidation thresholds or configurations to handle flash crashes or price spikes.
Price Pegs
The Black Thursday crash also lead to other systemic issues for Maker as many surviving users were now close to being liquidated. In order to shore up their positions, debt holders were buying DAI on secondary markets to repay their loans. This sudden increase in demand caused the DAI token price to rise to $1.20. As an intended dollar stablecoin, this was hardly ideal. Lacking algorithmic mechanisms to adjust the pricing fast, Maker turned to allowing more alternative collaterals, specifically more USDC. Over time, this allowed the value of DAI to float back towards the peg and reduced its price volatility in general.
While not an exploit, this situation highlights an important point with oracles - even highly liquid and supposedly stable tokens, such as DAI or USDC, can experience price shocks and developers should refrain from hardcoding price assumptions, even if they are likely to be correct the majority of the time.
This event is commonly seen with USDC or tokens that are supposedly pegged to ETH. Yet, we frequently see these tokens depeg due to market forces. For example, the collapse of Silicon Valley Bank in March 2023 led to uncertainty about the backing of USDC's parent company Circle and saw its value drop to a low of $0.88 per USDC.
While not hardcoded, another token, USDR, suffered from an oracle that required manual adjustment via a multi-sig signed transaction. USDR was an algorithmic stablecoin, soft-pegged to the dollar, that was backed by real estate properties and other real world assets owned by Tangible's company.
The delayed value update acted as though it was hardcoded when serving a lower bound of their TNGBL governance token. This resulted in a user being able to double the market price of TNGBL from $5 to $10, then shortly afterwards used this inflated TNGBL to mint USDR.
Mitigation
- Do not use hardcoded price assumptions in smart contracts.
- Assess implicit assumptions, for example, if using a BTC/USD oracle, this is not a fair substitute as a price feed for BTC/USDC as the USDC token may also depeg. Likewise with staked ETH tokens, these should use their own price feeds, not that of ETH, as they can depeg due to market forces, hacks or malicious behaviour.
Slippage/Liquidity
Price feeds are commonly seen as a one-dimensional number, but it is important not to forget the other main characteristic of markets seen in liquidity and felt through slippage. This is particularly important for illiquid assets, such as NFTs, where the continuity of price may be fractured. That said, it is also important for fungible tokens, as users of Tangible's USDR found out in October 2023. Onchain redemption mostly occurred through a swap reserve with DAI. However, this pool only had about $12 million DAI, and with about $50 million of USDR in existence, it was clear the full intended value could not be realised if a bank run was to happen.
Some commenters predicted this issue and were proven right on October 12th 2023. Users panicked after large trades depleted the DAI reserves and attempted to draw out USDR from the remaining liquidity pools, dropping USDR to $0.50. While this did not cause any pricing issues in other smart contracts, many other users of USDR were caught unaware, having invested in the project based on high returns offered on many other platforms integrating it. It demonstrated that, while a token may notionally trade at a pegged value for small volume, the same cannot be said if larger trades are made.
Mitigation
- Risk assessments should be carried out regularly for any assets where the price is of importance. If they lack liquidity, then strict volume caps must be enforced.
- If swaps are to be made in smart contracts, they must check slippage on trades and make use of input parameters that limit this.
- Economic assumptions of protocols should be well thought out and stress tested against historic data as part of the development process.
Means, Medians and Maths
The way that a price is calculated can introduce issues. Out of an abundance of caution, it is wise to make use of means, medians or more complex pricing methods, such as time weighted average prices. When doing so, developers must be careful to ensure the maths formulas are correctly implemented and resistant to attacks.
Pegnet fell victim to an attack on their pricing oracle in April 2020. Pegnet was a synthetic currency and asset platform built on top of Factom network, where proof of work mining was used as part of the oracle system. The issue emerged when the attacker concentrated enough mining power to perform a 51% attack on Pegnet’s oracle system. Using this control, they used 1,265.79 pJPY in a wallet, worth roughly $11, and inflated it’s value to 6.7 million pUSD before swapping it to pUSD. This was achieved by taking control of 35 of the 50 oracle values and submitting an exchange rate of 5306 pUSD/pJPY, while the true rate was around 0.09 pUSD/pJPY.
Luckily for Pegnet, the exploiter later claimed this was a proof of concept and burned the resulting pUSD by sending to a burn address known as "FA2BURNBABYBURNooooooo", mitigating the impact of the attack.
Formulas can also come into play with other oracle solutions. Earlier we advised the use of TWAP oracles, while these can be useful it is wise to be aware of their limitations also. For example they can increase arbitrage opportunities for protocols as there is a time lag to their price value updating.
As TWAPs are formed from the mean of several different price readings it can still be possible to manipulate them if one reading is wildly different or only a few readings are used. A basic example of this is if we have four price readings [10, 9999, 12, 11] then a mean price TWAP would be 2508 despite 75% of the prices being far lower than this. This effect can be particularly pronounced if a liquidity pool is illiquid or the sole trading venue for a token as then other actors may not be able to arbitrage a sudden price difference back to the baseline.
Mitigation
- Write a detailed maths specification for pricing formulas and use this to verify the implementation is written correctly. Test vectors can be utilised to ensure the same outputs are received.
- Be aware of stakeholders and attack vectors the project is vulnerable to, use war games to outline possible attack paths prior to taking the project live.
- Make use of audits to detect deviations from the specification. Prefer pair programming to limit the risks that the implementation code has errors or deviates from the specification.
- Prefer the use of offchain oracles in critical operations.
- If making use of complicated oracle formulas such as TWAPs, be aware of the limitations of your pricing model.
- Make use of multiple price oracles if possible. By combining multiple price oracles then taking a median price it can become much harder to exploit the resulting price as multiple oracle systems would have to be compromised before the median is affected.
Parameter setting/Importance of testing
Once the right oracle has been chosen for your use, it is vital to read the documentation and setup instructions of platforms you are integrating with. Mistakes can be costly and quick, as one user of Morpho found out when creating a lending pool for PAXG, an onchain token that tracks the price of gold. While the code of the lending pool was safe, its setup was not, being deployed with an incorrect decimal conversion factor between the collateral PAXG and loan token USDC. This enabled an attacker to drain all the pooled USDC and walk off with a profit of $230,000.
Mitigation
- While DeFi apps aim to make their interfaces as accessible and easy to use as possible, it is important to remember the importance of writing offchain tests. One of our top recommendations to clients is the importance of comprehensive unit tests. At Sigma Prime, we complement our audits with custom test suites designed for clients, enabling error detection through fuzzing and edge case scenarios that may be challenging to identify manually.
- Use small amounts of tokens to test new contracts so that, should an error be discovered, the financial loss is minimal.
Non-financial oracles
While the usual first thought with oracles tends towards prices and numerical feeds, we have increasingly seen them used in other products, such as insurance resolution and betting markets centered around sports and politics.
Such uses can be finicky and lead to subjective outcomes, as users of Polymarket found out when betting on the result of the Venezuelan election. The election was disputed in the real world and the digital outcome was likewise as contentious. Initially, the market looked to favour one candidate, Maduro, who obtained 51.2% of the vote, but then, the dispute mechanism was engaged and using the underlying UMA oracle the vote was ruled in favour of González.
With an unclear real world result, cracks appeared in the resolution system set up by UMA. As a financial incentive, if UMA voters were in the majority decision, they would be rewarded, and if they voted for the minority decision, they would be punished. Adding to this was dissection of the wording of the bet made and what criteria would qualify for each result. While the political acceptance of the real election result varied based on the alignment of those answered, Maduro was sworn in as Venezuelan president on 10th Jan 2025. This conflicts with the final outcome of the Polymarket bet.
Clearly this was a contentious issue, but it illustrates some of the vagaries that need to be considered when working with non-financial oracles. Even less contentious issues, such as whether insurance payouts should be issued for smart contract hacks, can face similar challenges due to the fact that multiple parties may have different financial incentives.
Mitigation
- When implementing oracles dependent on multiple parties, it is important to factor in rational actions via methods such as game theory, to determine what incentives there are to misbehave.
- End users need to be aware of who decides oracle's results and what dispute processes exist.
Conclusion
As you can see, there are many factors to consider when implementing pricing functions and oracles into projects. Generally, it is best to review the existing practices of protocols similar to your own and discuss potential pitfalls as a team when designing a new application. When integrating specific projects like Uniswap or Curve, reading their documentation of swaps and oracles is a must, and if in doubt, be sure to reach out to the protocol you are integrating for advice.
Good luck with your development!