On January 27, 2024, Citadel Finance on Arbitrum lost 43 ETH (approximately $93,000) to a flash loan attack exploiting price manipulation in its redemption contract. For developers and advanced users seeking to understand — and defend against — this class of vulnerability, this technical walkthrough dissects the exact attack vector and examines the code-level failures that enabled the exploit.
The Objective
This guide aims to provide a comprehensive understanding of how flash loan price manipulation attacks work in practice, using the Citadel Finance exploit as a real-world case study. By the end, you will be able to identify vulnerable code patterns in DeFi protocols, understand the economics of flash loan attacks, and implement defensive measures in your own smart contract development.
Prerequisites
This walkthrough assumes familiarity with Solidity smart contract development, an understanding of Automated Market Maker (AMM) mechanics, and basic knowledge of how flash loans operate on Ethereum and EVM-compatible chains. You should be comfortable reading Solidity code and understanding function calls, token approvals, and DEX routing mechanisms. Familiarity with Arbitrum and the Camelot DEX will be helpful but is not required.
Step-by-Step Walkthrough
Step 1: Understanding the vulnerable contract. The CITRedeem contract on Arbitrum handles token redemptions for Citadel Finance. The critical vulnerability lies in the variable-rate redemption path. When a user calls the redeem function with rate parameter set to 0 (variable rate), the contract uses the Camelot Router’s getAmountsOut function to determine the exchange rate. The routing path goes through three hops: CIT to WETH to USDC. This means the redemption value depends entirely on the current spot price in the Camelot liquidity pools — a price that can be manipulated.
Step 2: The flash loan acquisition. The attacker borrowed approximately 4,500 WETH through a flash loan from a lending protocol. Flash loans allow borrowing any amount of capital without collateral, provided the loan is repaid within the same transaction. This single-transaction constraint is what makes flash loans powerful for arbitrage and, unfortunately, for exploits. The attacker now had a massive capital advantage to distort market prices.
Step 3: Pool price manipulation. The attacker deposited the 4,500 WETH into the Camelot WETH/USDC liquidity pool. In an AMM, the price is determined by the ratio of tokens in the pool. By adding a massive amount of WETH relative to USDC, the attacker skewed the pool’s internal price ratio, making WETH appear artificially cheap relative to USDC. This is the core mechanism of any AMM-based price manipulation attack.
Step 4: Exploiting the distorted price. With the pool price manipulated, the attacker called redeem on the CITRedeem contract. The contract queried the now-distorted Camelot Router for the exchange rate, which returned an inflated redemption value. The attacker burned only 30.51 CIT tokens but received 21.326 WETH from the treasury — a vastly disproportionate exchange enabled by the manipulated oracle.
Step 5: Loan repayment and profit extraction. The attacker withdrew their 4,500 WETH from the Camelot pool, restoring the price to its natural level. They then repaid the flash loan from the same transaction. The net profit was the 21.326 WETH extracted from Citadel’s treasury, worth approximately $48,000 at the ETH price of roughly $2,267 at the time of the attack.
Troubleshooting
Identifying vulnerable patterns in your own code: Any contract that uses spot prices from AMM pools for financial calculations is vulnerable. Search your codebase for calls to getAmountsOut, getAmountIn, or direct reserve-based price calculations. Replace these with time-weighted average prices (TWAP) from Uniswap V2/V3 or use Chainlink price feeds.
Testing for flash loan vulnerability: Use Foundry or Hardhat to write tests that simulate flash loan attacks against your protocol. Create a test that borrows a large amount of capital within a single transaction, manipulates the pool price, and then interacts with your contract. If the attacker can extract more value than they should, your contract is vulnerable. Automated tools like Slither can also detect some price manipulation patterns.
Implementing circuit breakers: Add checks that compare the current spot price against a time-weighted average. If the deviation exceeds a reasonable threshold — typically 5-10% — the transaction should revert. This simple measure would have prevented the Citadel Finance exploit entirely, as the price manipulation from a 4,500 WETH deposit would have exceeded any reasonable deviation threshold.
Mastering the Skill
Flash loan attack vectors represent one of the most active areas of DeFi security research. To deepen your expertise, study historical exploits on Rekt News, which maintains a comprehensive database of DeFi hacks sorted by severity. Analyze the attack transactions on block explorers — the Citadel Finance attacker transaction on Arbiscan (0xf52a681…) provides a complete blueprint of the attack for educational purposes. Practice writing defensive Solidity code that implements TWAP oracles, rate limits, and emergency pause mechanisms. The most effective security measure is always a thorough audit by experienced smart contract security firms before deploying any DeFi protocol to mainnet.
Disclaimer: This article is for educational purposes only. The technical analysis is provided to help developers build more secure smart contracts. Always conduct professional security audits before deploying financial smart contracts.
citadel lost 43 eth on arbitrum from no freshness check on the oracle in redemption
flash_loan_fix 43 ETH lost because the redemption contract had no freshness check on the oracle. literally one require statement would have saved 93k
43 ETH for a flash loan attack feels almost small time these days, but the redemption contract vector is what makes this interesting. most devs still dont properly validate oracle inputs during the callback
price-dependent redemption logic without TWAP protection is basically leaving your front door open. this attack pattern has been documented since 2020
greta v. no twap plus no freshness check on a redemption contract. two layers of oracle failure for 93k
the redemption contract specifically lacked any freshness check on the price. not even a stale price threshold. literally the minimum you could do and they skipped it
Marco L. not even a stale threshold check is wild. chainlink docs have had literal code examples for this since 2021
Marco L. not even a stale threshold check. the dev literally just called the spot price once and used it. first year smart contract course material right there
Marco L. no freshness check AND no stale threshold. the dev basically copy pasted the chainlink docs example and removed the safety lines. 93K gone for laziness
twap_skeptic adding twap protection would have stopped that price manipulation easy
twap_must adding TWAP would have helped but the real fix is a sanity bounds check. spot price should never deviate more than 5% from the last known good value
The fact that Citadel was on Arbitrum makes the gas cost of the attack basically negligible. attacker probably spent more time writing the exploit than the actual execution cost
arbitrum gas being basically free means flash loan attacks cost pennies to execute. the ROI on a 43 eth exploit is insane
Devon C. the gas asymmetry is the real story. $2 in fees to extract $93k. L2s made flash loan attacks accessible to anyone who can copy solidity
Soren B. the gas asymmetry argument is why L2 deployments need mandatory oracle reviews before going live. 2 cents to extract 93K is absurd ROI for attackers
Devon C. the ROI math on L2 flash loans is insane. spend 2 cents on gas to extract 93k. mainnet would have eaten margins on an attack this size
^ exactly. and on L2s the flash loan fees are trivial compared to mainnet, which lowers the barrier for attackers significantly. any protocol with price-dependent logic needs time-weighted oracles at minimum
the writeup says attacker spent more time coding than on gas fees lol. $93k exploited for probably $2 in Arbitrum gas. asymmetric warfare
$93k extracted for basically free gas on arbitrum. the ROI on flash loan attacks on L2s is absurd which is why auditors need to treat price oracle validation as critical path
the article mentions the redemption contract accepted spot price directly. first year solidity students learn not to do this in week 2. how does this ship to mainnet on arbitrum in 2024
the fact that flash loan attacks on L2s have become profitable at scale shows how much security focus has shifted from contracts to infrastructure
^ exactly. the ROI on L2 attacks makes gas costs basically irrelevant. auditors are treating this seriously now
the flash loan was 43 ETH which is small compared to what it could have been. if the attacker had deeper liquidity on the target pair this would have been 7 figures easy
the redemption contract called spot price once with no freshness check. chainlink docs have had code examples for this since 2021. literally copy paste and youre safe
Marcus L. the wild part is the attacker probably spent more time writing the exploit script than the gas cost to execute it. 2 cents on arbitrum to extract 93K
43 ETH extracted for basically free gas. L2 deployments need mandatory oracle reviews before going live. this attack pattern has been documented for 4 years