Calculated from recorded token losses using historical USD prices at the incident time.
0xff368294ccb3cd6e7e263526b5c820b22dea2b2fd8617119ba5c3ab8417403d80x75f805e2fb248462e7817f0230b36e9fae0280fcArbitrum0xc8f42db9eb6ab58bbfa6e2642107a6086cb4473bArbitrum0xe611e633c1e88d4f026fec5bc1e40e8a477f41adArbitrumOn Arbitrum transaction 0xff368294ccb3cd6e7e263526b5c820b22dea2b2fd8617119ba5c3ab8417403d8 in block 105524524, an unprivileged attacker used flash-loaned WETH to skew Balancer's wstETH-WETH stable pool, refreshed Themis's Balancer-gauge oracle while that skew was live, and then borrowed WETH against overstated gauge collateral. The same transaction repaid the flash liquidity and left the attacker with realized profits in ETH, USDC, and USDT.
The root cause is a lending-oracle design failure in Themis. Themis trusted a same-transaction LP price derived from live Balancer pool balances, so temporary attacker-controlled balance changes could immediately increase collateral value inside the borrow path.
Themis is an Aave-style lending market on Arbitrum with reserves such as tArbWETH, tArbDAI, tArbUSDC, tArbUSDT, tArbARB, and tArbWBTC. The affected collateral was Balancer gauge 0x8f0b53f3ba19ee31c0a73a6f6d84106340fadf5f, which represents LP exposure to Balancer pool 0x36bf227d6bac96e2ab1ebb5492ecec69c691943f (wstETH-WETH stable pool). Themis relied on Balancer LP oracle 0x17df2b52f5d756420846c78c69f4fe4ff10e57a4, and its price-oracle layer at 0xc8f42db9eb6ab58bbfa6e2642107a6086cb4473b consumed that LP price during borrow-limit checks in controller .
0x75f805e2fb248462e7817f0230b36e9fae0280fcThe relevant public protocol components identified in the analysis are:
0x75f805e2fb248462e7817f0230b36e9fae0280fc0xc8f42db9eb6ab58bbfa6e2642107a6086cb4473b0xe611e633c1e88d4f026fec5bc1e40e8a477f41ad0x17df2b52f5d756420846c78c69f4fe4ff10e57a40xde85d18adda9d2b9eafa7dbf0cec5a89119d90f0The ACT pre-state used in the analysis is Arbitrum immediately before block 105524524 tx index 3, including Themis reserve balances, Balancer pool balances and total supply, Balancer gauge balances, and the public Chainlink feeds for WETH and wstETH. The auditor marked each of the key protocol contracts above as is_verified=false; the exploit analysis therefore relies on the collected trace and runtime behavior rather than verified explorer source for those addresses. The attack still qualifies as ACT because every critical call path used public on-chain entrypoints: Aave V3 flash loans, Uniswap V3 flash liquidity, Balancer joins and swaps, and Themis supply and borrow flows.
This incident is an ATTACK-category oracle-manipulation exploit. Themis priced Balancer gauge collateral from spot Balancer balances that were observable at the exact moment of the borrow, rather than from a manipulation-resistant source such as a TWAP or delayed oracle update. That allowed the attacker to use flash liquidity to push WETH into the wstETH-WETH stable pool, drastically change the pool composition, and immediately force 0x17df...::latestAnswer() to return an inflated LP price. Themis then consumed that inflated LP price through 0xc8f42...::getAssetPrice() during 0x75f805...::borrow(), so the borrow-limit calculation treated the attacker subaccount as if it had much more collateral than it actually did. Once the WETH borrow succeeded, the attacker unwound the Balancer distortion and repaid the flash liquidity, proving that the price increase was transient and fully attacker-controlled. The broken invariant is straightforward: collateral valuation used in health-factor and borrow-limit checks must not be increaseable within the same transaction by temporary pool balance changes under attacker control.
The vulnerable components were:
0x75f805e2fb248462e7817f0230b36e9fae0280fc0xc8f42db9eb6ab58bbfa6e2642107a6086cb4473b0x17df2b52f5d756420846c78c69f4fe4ff10e57a40x8f0b53f3ba19ee31c0a73a6f6d84106340fadf5fThe exploit required only three public conditions:
The violated security principles are the same ones called out in the root cause artifact:
The collector trace shows the attacker first assembling temporary WETH liquidity from Aave V3 and Uniswap V3. It then set up a fresh Themis subaccount, joined the Balancer pool with 55 WETH, deposited the received BPT into the Balancer gauge, and supplied 54.665092912647660455 gauge shares into Themis as collateral.
The key oracle breakpoint is visible before and after the Balancer skew. Before manipulation, the LP oracle returned a normal baseline value:
0x17df2B52f5D756420846c78c69F4fE4fF10e57A4::latestAnswer()
MetaStablePool::totalSupply() -> 5445998568169458716380
BalancerVault::getPoolTokens(...) -> [wstETH=2423240452850875484052, WETH=2740951628276599438098]
...
<- [Return] 191099705466
After the attacker swapped 39724.937330688241115794 WETH into the Balancer pool, the pool balances and oracle output changed immediately:
BalancerVault::swap(... amountIn = 2423002389146086585543 wstETH ...)
MetaStablePool::onSwap(...) -> 39724937330688241115794
...
0x17df2B52f5D756420846c78c69F4fE4fF10e57A4::latestAnswer()
MetaStablePool::totalSupply() -> 5500663661082106376835
BalancerVault::getPoolTokens(...) -> [wstETH=61447309529146061, WETH=42252095142331057715112]
...
<- [Return] 1468795169887
That inflated LP price was then consumed directly in Themis's borrow path:
0x75F805e2fB248462e7817F0230B36E9Fae0280Fc::borrow(WETH, 317620373410593518825, 2, 0, 0x2132...)
0xC8f42dB9eB6aB58bBFA6E2642107A6086CB4473B::getAssetPrice(0x8F0B53..., 0x2132...)
0x17df2B52f5D756420846c78c69F4fE4fF10e57A4::latestAnswer()
<- [Return] 1468795169887
...
0xe611e633C1E88d4f026fec5Bc1E40E8A477f41aD::transferUnderlyingTo(0x2132..., 317620373410593518825)
This is the concrete code-level breakpoint described in the root cause artifact: latestAnswer() read live Balancer balances, getAssetPrice() consumed the manipulated value, and borrow() trusted it for collateral accounting. Once the WETH borrow completed, the attacker routed the borrowed WETH back out of the subaccount, reversed the Balancer skew, repaid Aave and Uniswap, and kept the residual assets.
The realized-profit predicate is fully supported by the seed balance diff. The sender EOA started with 0.4984956909 ETH, finished with 94.820454696766716128 ETH, and also ended the transaction with 130471.920034 USDC and 58824.329320 USDT. Using the same-transaction Chainlink WETH price 1900.07440273 USD, the collector-backed valuation is:
947.178902150296196157 USD369462.16817854604140905305822944 USD368514.9892763957 USDThe root cause therefore is not the presence of flash loans themselves. Flash liquidity only made the attack large enough to matter; the actual failure was Themis allowing a same-transaction spot LP oracle to determine collateral value.
The attacker cluster identified in the artifact is:
0xdb73eb484e7dea3785520d750eabef50a9b9ab33: sender EOA and final profit recipient0x05a1b877330c168451f081bfaf32d690ea964fca: exploit orchestration contract targeted by the seed tx0x33f3fb58ea0f91f4bd8612d9f477420b01023f25: helper contract deployed mid-transaction0x2132d49157d6148dee8753f059fad1c1b09c477c: freshly created Themis subaccount used for collateral and borrowingThe on-chain execution flow is:
22000 WETH from Aave V3 and another 18000 WETH from two Uniswap V3 pools.0x33f3..., creates subaccount 0x2132... through the public Themis subaccount proxy 0xdE85..., joins Balancer with 55 WETH, deposits the resulting BPT into the gauge, and supplies 54.665092912647660455 gauge shares to Themis.39725 WETH into the Balancer wstETH-WETH stable pool, pushing the LP oracle from 191099705466 to 1468795169887.317.620373410593518825 WETH from tArbWETH.This is a fully permissionless ACT sequence. No admin action, no off-chain privileged data, and no private attacker artifact was required to make the victim protocol consume the manipulated price.
The conservative realized losses captured in the artifact are:
ETH: 94321959005866716128 wei (94.321959005866716128 ETH)USDC: 130471920034 (130471.920034 USDC)USDT: 58824329320 (58824.329320 USDT)The exploit-specific protocol loss was the under-collateralized 317.620373410593518825 WETH borrow from Themis WETH reserve 0xe611e633c1e88d4f026fec5bc1e40e8a477f41ad. The broader attacker PnL after unwind is visible in the balance diff:
{
"native_balance_delta_wei": "94321959005866716128",
"usdc_delta": "130471920034",
"usdt_delta": "58824329320"
}
Those values match the root cause artifact's realized-profit section and show that the attacker walked away with material value after every flash-liquidity obligation had been repaid.
[1] Seed transaction metadata: /workspace/session/artifacts/collector/seed/42161/0xff368294ccb3cd6e7e263526b5c820b22dea2b2fd8617119ba5c3ab8417403d8/metadata.json[2] Seed transaction trace: /workspace/session/artifacts/collector/seed/42161/0xff368294ccb3cd6e7e263526b5c820b22dea2b2fd8617119ba5c3ab8417403d8/trace.cast.log[3] Seed transaction balance diff: /workspace/session/artifacts/collector/seed/42161/0xff368294ccb3cd6e7e263526b5c820b22dea2b2fd8617119ba5c3ab8417403d8/balance_diff.json[4] Collector seed index: /workspace/session/artifacts/collector/seed/index.json[5] Public secondary PoC reference cited by the auditor: https://raw.githubusercontent.com/SunWeb3Sec/DeFiHackLabs/main/src/test/2023-06/Themis_exp.solThe only exploit transaction required to reproduce the ACT opportunity is:
42161: 0xff368294ccb3cd6e7e263526b5c820b22dea2b2fd8617119ba5c3ab8417403d8