Solodit Checklist Explained (7): Price Manipulation Attacks
Attacker's Mindset / Price Manipulation Attack
This article was originally published on the Cyfrin Blog.
Welcome back to the "Solodit Checklist Explained" series.
Today, we are diving into Price Manipulation Attacks.
These attacks are a prevalent threat in decentralized finance (DeFi), exploiting vulnerabilities in protocols to artificially skew asset prices for illicit profits. In 2024 alone, these attacks have accounted for over $52 million in losses across 37 incidents, making them the second most damaging attack vector. Attackers often leverage flash loans or exploit weak oracles to create price discrepancies, impacting critical components like lending platforms, decentralized exchanges (DEXs), and stablecoins.
This article covers two critical items from the Solodit checklist, focusing on vulnerable pricing mechanisms that can be exploited and how to build manipulation-resistant systems.
For the best experience, open a tab with the Solodit checklist to refer to it as you read.
Note: We have previously covered topics including denial-of-service (part 1, part 2), donation attacks, front-running attacks, griefing attacks, and miner attacks. Make sure to check them out!
SOL-AM-PMA-1: Is the price calculated by the ratio of token balances?
Description: Price can be manipulated via flash loans or donations if it is derived from the ratio of token balances.
Remediation: Use Chainlink oracles for the asset prices.
Calculating prices from token balances within a single contract seems straightforward: the ratio of Token A to Token B in a pool dictates the price. However, attackers can temporarily alter these balances using flash loans or direct donations, causing wild price swings. We previously discussed how attackers can manipulate protocol state via donation attacks, which often rely on distorting internal balances to affect values like 'share price'. Flash loans exploit similar principles, allowing attackers to temporarily manipulate the underlying token balances used for pricing within a single transaction.
Let's examine how an attacker exploits a simple DEX where the price is derived directly from token balances.
In this scenario, the Pool contract's getPrice function calculates the exchange rate based on the current balances of tokenA and tokenB held by the pool. This dependency on internal, easily altered state is the core vulnerability.
How the attack works
Setup: The attacker funds the
Exploitcontract with a small amount oftokenA(swapAmount) that they will use for the exploitative swap.Flashloan: The attacker calls
attackon theExploitcontract, initiating a large flash loan oftokenAfrom thePoolcontract itself. This loan executes before thereceiveFlashLoanfunction returns.Price manipulation (inside
receiveFlashLoan): While the flash loan is active, thePool'stokenAbalance is artificially low. When theExploitcontract callspool.swap(tokenA, swapAmount), thePool'sgetPricefunction calculates a price based on these temporarily distorted lowtokenAreserves. This leads to a manipulated price wheretokenAlooks much more valuable than it is under normal conditions.Exploitative swap (inside
receiveFlashLoan): TheExploitcontract swaps a small amount of its own pre-fundedtokenAfortokenBusing thepool.swapfunction. Due to the manipulated price, this swap yields a disproportionately large amount oftokenB.Repay loan (inside
receiveFlashLoan): TheExploitcontract repays the largetokenAflash loan to thePoolcontract. ThereceiveFlashLoancall must complete successfully, meaning the loan is repaid.Profit (after
receiveFlashLoanreturns): TheExploitcontract now holds the originalswapAmountoftokenA(or slightly less due to fees, though fees are omitted in this simplified example) plus the excess amount oftokenBreceived from the manipulated swap. The remaining tokens are sent back to the attacker's address, realizing the profit intokenB.
Remediation: using reliable price sources (oracles)
The robust solution is to stop relying on on-chain balance ratios for price calculation and integrate external price oracles, such as Chainlink. Oracles offer reliable, tamper-resistant off-chain price data, significantly hardening contracts against manipulation based on internal state.
By fetching prices from a Chainlink feed, the contract decouples its price logic from its internal, manipulable state and external, volatile spot markets, significantly reducing the attack surface.
Note that there must be additional checks on the data received from the oracle to ensure its validity and freshness. Neglecting these checks can create a different kind of oracle vulnerability. As mentioned in the code comments, we will cover these essential checks in later parts of the checklist series.
Examples are available on my GitHub here.
SOL-AM-PMA-2: Is the price calculated from DEX liquidity pool spot prices?
Description: Spot price readings derived directly from DEX liquidity pools are vulnerable to manipulation through flash loans that can temporarily drain the pools.
Remediation: Use TWAP (time-weighted average price) with appropriate time windows based on asset volatility and liquidity, or use reliable oracle solutions.
In the previous section, we established that relying solely on a contract's internal token balance ratios for pricing is unsafe. However, what about getting prices from external sources like large DEX liquidity pools (e.g., Uniswap, SushiSwap)? Despite the risks, DEX spot prices still tempt developers with perceived benefits: their decentralized nature, cost efficiency (avoiding oracle fees), transparency, and instant pricing, especially for new tokens. Unlike dedicated oracle networks, they use only on-chain data, seemingly avoiding external dependencies.
But their mathematical simplicity, tied directly to volatile pool reserves (x * y = k), makes them manipulation targets via strategic trades, similar to the smaller pool example we discussed. Attackers can exploit this by executing large trades (often funded by flash loans) to temporarily skew the pool's balances, causing the spot price reported by the pool to spike or plummet, depending on the direction of the trade. This risk is especially pronounced for low-liquidity pools, where even moderately sized trades can cause significant price shifts.
Remediation: Time-weighted average price (TWAP)
To mitigate price manipulation using sudden spot price changes, one can use a TWAP. Instead of taking an instant snapshot (spot price), a TWAP averages prices over a defined period, typically ranging from minutes to hours.
This significantly blunts the impact of short-term manipulations. A TWAP works by recording cumulative prices at specific intervals and computing the average price between two timestamps.
To significantly skew a TWAP over its window, an attacker must sustain a distorted price for the duration of that window. This is a considerably more costly feat than a fleeting flash loan manipulation. Especially in high-liquidity pools, the trades necessary to hold a skewed price would incur substantial slippage or require immense capital.
Protocols like Uniswap offer native TWAP oracles built directly into their contracts, and the concept is explained very well in their article.
The TWAP approach is particularly effective for applications that can tolerate some price latency, such as settlement layers, treasury operations, or slow-moving markets. However, the time window is a crucial design parameter: a longer window increases manipulation resistance but introduces more latency in price updates; a shorter window is quicker but easier to manipulate. The optimal window must be carefully chosen based on the asset's volatility, pool liquidity, and the specific requirements of the protocol using the price feed.
Conclusion
We've explored critical vulnerabilities related to price manipulation in DeFi protocols. By understanding how attackers can distort on-chain price calculations, whether from direct contract token balances or volatile DEX spot prices, developers can build stronger defenses. The increasing sophistication of DeFi requires robust security measures integrated from the ground up. For further resources, check out the Cyfrin audit checklist.
Key takeaways:
Token balance ratios are unsafe: Never derive critical asset prices solely from a contract's internal token balances.
DEX spot prices are volatile: Avoid relying on raw, instantaneous spot prices from liquidity pools for significant financial operations.
Oracles provide resilience: Reliable oracle networks like Chainlink offer more trustworthy, manipulation-resistant price data sourced externally.
TWAP is a powerful tool (for DEX sources): If using DEX data, implement TWAPs over sufficient time windows to smooth price variations and deter flash loan attacks.
Integrating these principles into your development significantly reduces the risk of price manipulation attacks, contributing to a safer and more reliable DeFi ecosystem.
Next time, we'll continue dissecting the Solodit checklist, exploring more facets of smart contract security from an attacker's perspective. Stay vigilant, code thoughtfully, and always think like an attacker.




