FutureSwap Perpetual Exchange Collateral Accounting Exploit
On 2026-01-10 08:30:35 UTC (Arbitrum block 419,829,771), tx 0xe1e6aa5332deaf0fa0a3584113c17bedc906148730cbbc73efae16306121687b deployed an attacker contract that drained approximately 394,743 USDC.e from FutureSwap’s unverified perpetual exchange contract at 0xf7ca7384cc6619866749955065f17bedd3ed80bc (proxy, implementation 0x010659727ad7716c239e206acd3ebee0fdc9e207). The attacker exploited a flaw in the protocol’s changePosition(int256,int256,int256) (0xa442c8be) collateral accounting by using an Aave V3 flash loan to open a massive short position that corrupted internal balance tracking, then withdrawing far more collateral than deposited through a controlled helper address.
The attack vector is a logic flaw in position collateral accounting. When a large short position was opened, the protocol executed a Uniswap V3 swap that moved 68 WETH into the pool and received ~198,876 USDC.e, crediting the combined collateral deposit plus swap proceeds to the protocol’s internal stableBalance. A second account that had deposited only 1,000 USDC.e was then able to call changePosition(0, -894992852305, 0) to withdraw 894,993 USDC.e because the protocol’s per-account collateral available calculation drew from the inflated global stable balance rather than properly isolating per-position accounting.
The vulnerable contract is the FutureSwap perpetual exchange proxy at 0xf7ca7384cc6619866749955065f17bedd3ed80bc, delegating to implementation 0x010659727ad7716c239e206acd3ebee0fdc9e207. Neither contract is verified on Arbiscan. The proxy uses EIP-1967 storage with admin 0x35e55f3bb78f650804fdc7d365e9d018aaafe813. The protocol manages perpetual positions hedged through a Uniswap V3 WETH/USDC.e pool at 0xc31e54c7a869b9fcbecc14363cf510d1c41fa443 (0.05% fee tier) and prices via Chainlink ETH/USD at 0x639fe6ab55c921f74e7fac1ee960c0b6293ba612.
The vulnerable function is changePosition(int256,int256,int256) (0xa442c8be), which handles position size changes, collateral deposits, and collateral withdrawals. When called with (0, negativeCollateral, 0), it performs a collateral-only withdrawal. The flaw is that the amount available for withdrawal is computed from a global pool balance state that includes collateral deposited by other users and proceeds from Uniswap hedging swaps, rather than being strictly bounded by the caller’s own deposited collateral plus realized PnL. The protocol’s internal rebalancing function (0x9e934fdc) tracks WETH and USDC.e balances before and after Uniswap swaps, and the resulting stableBalance delta is attributed globally. When a large short position deposited 496,500 USDC.e and the protocol sold 68 WETH into Uniswap V3 for ~198,876 USDC.e, the protocol’s total tracked stable balance inflated to include both the collateral and the swap proceeds. The per-position accounting then allowed a different user with a tiny long position to claim a share of this inflated balance as withdrawable collateral.
The protocol’s position update event for Helper1’s withdrawal (log index 50, topic 0xc447a680) reports a position size of 324518553658423603970963131354509 (hex 0x0fffffffffffd4a98adb1e944d8d)—a nonsensical value ~3.24e32 WETH—indicating corrupted internal accounting. The corresponding trade completion event (log index 51, topic 0xb52f9573) confirms 894,992.852305 USDC.e was released as collateral withdrawal against what should have been at most a few hundred USDC in actual entitlement (1,000 USDC deposit minus ~309 USDC hedging swap cost = ~691 USDC remaining, minus unrealized loss from the price drop).
Call flow: attacker EOA 0xbf6ec059f519b668a309e1b6ecb9a8ea62832d95 deploys outer contract 0x21eda2e3ad975fde9c81769e15ed8e1532eb08a4, which creates inner vault 0x348df930e825da25552d8b3dc44e871c67846cb5 and three helper contracts (0xf1b426708d6ecf02274a789bbc10a94a1b5a6635, 0x8c6be2e20306dd1ec40a7e76f40310943953ba7f, 0xea09ea354009818776d41f8e2a9dcdfc9c4e7beb). The vault calls Aave V3 Pool (0x794a61358d6845594f94dc1db02a252b5b4814ad) flashLoanSimple (0x42b0b77c) borrowing 500,000 USDC.e. In the executeOperation (0x1b11d0ff) callback: (1) calls updateFunding (0x1ebf4eb5) and longPosition (0x83b3e153) on the protocol; (2) transfers 1,000 USDC.e to Helper1 which calls changePosition(+0.1e18, +1000e6, 0) opening a 0.1 WETH long, protocol buys 0.1 WETH from UniV3 for ~309 USDC.e; (3) transfers 2,000 USDC.e to Helper2 which calls changePosition(+0.3247e18, +2000e6, 0) opening a 0.3247 WETH long, protocol buys ~0.3247 WETH for ~1,003 USDC.e; (4) transfers 500 USDC.e to Helper3 which calls changePosition(+0.001e18, +500e6, 0) opening a 0.001 WETH long for ~3 USDC.e; (5) the vault calls changePosition(-68e18, +496500e6, 0) opening a massive 68 WETH short, protocol sells 68 WETH into UniV3 for ~198,876 USDC.e, crashing the pool price from ~3,089 to ~2,759 USDC/WETH; (6) Helper1 calls changePosition(0, -894992852305, 0) extracting 894,993 USDC.e from the protocol; (7) Helper1 transfers 894,993 USDC.e back to the vault; (8) vault repays 500,250 USDC.e to Aave (500,000 + 250 premium); (9) remaining 394,743 USDC.e flows through the outer contract to the attacker EOA.
Financial impact: 394,742.852305 USDC.e net profit to attacker 0xbf6ec059f519b668a309e1b6ecb9a8ea62832d95. The protocol also paid ~5 USDC.e in trading fees to 0x6749d795bb40ddf00a953f618cedda7440216707 and 250 USDC.e in Aave flash loan premium. The loss was borne by the FutureSwap protocol’s liquidity pool—specifically the USDC.e reserves held by the contract and any LP positions managed through the Uniswap V3 pool. Other users with open positions on the protocol may have been affected by the depleted reserves and the manipulated pool state.
Evidence: the Uniswap V3 Swap event at log index 43 (topic 0xc42079f9) on pool 0xc31e54c7a869b9fcbecc14363cf510d1c41fa443 shows amount0=+68e18 (68 WETH sold to pool), amount1=-198876475748 (~198,876 USDC.e received), with sqrtPriceX96 dropping from 4403802431845325338504495 to 4161502050704295058002620, confirming a 10.7% price impact. The final USDC.e Transfer at log index 60 (topic 0xddf252ad) shows 394742852305 (394,742.852305 USDC.e) from 0x21eda2e3ad975fde9c81769e15ed8e1532eb08a4 to 0xbf6ec059f519b668a309e1b6ecb9a8ea62832d95. The protocol’s position update event at log index 50 (topic 0xc447a680) for Helper1 shows corrupted position size field 0x0fffffffffffd4a98adb1e944d8d confirming the accounting failure. No swap was executed for Helper1’s withdrawal, proving the protocol released funds purely from its internal accounting without reversing the hedge.
Related URLs:
- https://arbiscan.io/tx/0xe1e6aa5332deaf0fa0a3584113c17bedc906148730cbbc73efae16306121687b
- https://www.bitget.com/news/detail/12560605140756
- https://www.cryptopolitan.com/arbitrum-futureswap-suspected-hack/
Validation
This report has been validated by the automated validation pipeline.
- Stage 1 (Logical Challenger): PASS_WITH_WARNINGS (confidence: 0.92)
- Stage 2 (On-Chain Verifier): PASS
- Stage 3 (Foundry PoC): PASS – see
poc/futureswap/test/Exploit.t.sol
Warnings (non-blocking)
- Source code for vulnerable contracts is unavailable (unverified on Arbiscan). Flaw description is behavioral, not source-verified.
- Report simplifies the Helper1 withdrawal call flow — vault orchestrates the drain via Helper1.9890220b() rather than Helper1 calling directly.