On May 17, 2026 at 2026-05-17T16:11:19Z, an attacker on Arbitrum used an Aave flashLoanSimple of 3,300 USDT to run 12 flash-loan-funded SEA settlement cycles through 0xa70f31c06f921019237fc00b1417217dae5c37c5. Each cycle deposited fixed USDT lots into the settlement adapter, redeemed a disproportionately large SEA amount through the adapter’s round logic, and sold the redeemed SEA back through the SEA/USDT pair. funds_flow.json shows the attacker EOA 0x352173fabf0e67e1cb1fcdf15474d0477d5d3674 ending the transaction with 13,904.941068 USDT, while the SEA/USDT pair 0xeeb9c6b73a9ba397fbea320d9e4cce7b8ac10513 lost 13,906.591068 USDT net and accumulated 129,202,760.357336 SEA.
Root Cause
Vulnerable Contract
SEA Settlement Adapter proxy 0xa70f31c06f921019237fc00b1417217dae5c37c5
- Proxy: yes
- Implementation used in this transaction:
0x13dde273b66323686bfb96cce5a2a7190b40b264 - Source type: recovered only,
confidence: low
The verified SEA token implementation is not the root cause. The verified source at SEATokenUpgradeable.sol is a fixed-supply ERC20 with one-time minting and pause or whitelist controls only. The pair implementation recovered at 0x00cf80e8... is a standard Uniswap V2 style pair. The trace places the exploit behavior inside the settlement adapter path: every profit-making cycle enters 0x987217bc, reads getUserRoundInfo, calls redeemPosition(), and then returns excess SEA to the attacker helper before that SEA is sold for USDT.
Vulnerable Functions
0x987217bc(uint256,uint256)on0xa70f31...[recovered signature unresolved]redeemPosition()(0xf046d966) on0xa70f31...
Why It’s Vulnerable
The root cause is best classified as logic_error, with flash_loan_abuse as the secondary technique.
Expected behavior: depositing 3,000 USDT into the settlement adapter and redeeming the resulting round position should return SEA consistent with the user’s actual round entitlement. The adapter should not let a caller repeatedly convert small fixed USDT lots into dramatically larger SEA amounts inside the same transaction.
Actual behavior proved by the trace:
- The attacker helper deposits a fixed USDT lot with selector
0x987217bcand round argument0. - The helper immediately reads
getUserRoundInfo(attackerHelper, 1)and then callsredeemPosition(). - Inside
redeemPosition(), the adapter makes multiple price-sensitive router and pair queries (0xd06ca61f,0x1f00ca74,0x8803dbee, plus repeatedgetReserves()calls through the router path), transfers SEA through the treasury-side address0x5210525f..., burns part of that SEA to0xdead, and returns a larger SEA amount to the attacker helper. - The attacker helper then sells the redeemed SEA back to USDT through the router and repeats the same sequence.
The verified SEA token source does not expose a mint-on-redeem surface. The pair is standard. The only contract in the call flow that can explain same-transaction creation of redeemable SEA value is the settlement adapter’s round accounting and redemption formula. The recovered implementation is low confidence, so the exact formula is approximate, but the trace directly proves the economic effect: 3,000 USDT deposits repeatedly unlock SEA redemptions large enough to leave the helper with increasing USDT after each sellback.
Logic Error Checklist
- Incorrect behavior occurs on the settlement adapter path rooted at
0x987217bcandredeemPosition(). - The transaction repeatedly mixes fixed USDT deposit lots (
3000, then split into intermediate1000and2000router-side actions) with much larger SEA redemption outputs, indicating a broken value-conversion or round-state formula. - No verified token-side mint path or privileged access path appears in the trace.
- The adapter’s recovered code shows round-state reads and writes around
slot_7_userRounds,slot_0b_runningValue, andslot_0c_runningValue[recovered — approximation], consistent with the observed round-based mis-accounting.
Attack Execution
High-Level Flow
- EOA
0x352173fabf0e67e1cb1fcdf15474d0477d5d3674calls attacker entry contract0x7b1de577da005a58565d6d1fbad286fdf2f269b7. - The entry contract creates helper
0x32db518e84955739912b6257cc65e3e8374b60e4and calls its owner-only flash-loan entrypoint0x8fedc408. - That call passes:
- round contract:
0xa70f31c06f921019237fc00b1417217dae5c37c5 - flash-loan amount:
0xc4b20100 = 3,300,000,000raw =3,300 USDT - per-loop swap amount:
0x11e1a300 = 300,000,000raw =300 USDT - per-loop settlement amount:
0xb2d05e00 = 3,000,000,000raw =3,000 USDT - iterations:
0x0c = 12
- round contract:
- The helper borrows
3,300 USDTfrom Aave and loops through swap -> deposit -> redeem -> swap-back logic. - After
12iterations, the helper approves Aave for3,301.65 USDT, repays the flash loan plus premium, transfers the remaining13,904.941068 USDTto the entry contract, and the entry contract sweeps that USDT to the attacker EOA.
Representative Settlement Cycle
One complete loop can be read directly from decoded_calls.json and funds_flow.json:
- The helper first sells
300 USDTinto the SEA/USDT pair and receives2,009,299.190519 SEA(funds_flowtransfers0to2). - It deposits
3,000 USDTinto the settlement adapter (funds_flowtransfer6). - The adapter immediately returns
1,000 USDTand then2,000 USDTto the pair in two router-facing actions (funds_flowtransfers7and13), while the pair transfers6,543,065.087247 SEAand then12,412,971.908597 SEAto the adapter (funds_flowtransfers8and14). - During the same redemption path, SEA is routed through
0x5210525f..., with portions burned to0xdeadand sent to0x7a8a47d5...(funds_flowtransfers9to18). - The adapter then sends
13,192,657.996172 SEAback to the pair (funds_flowtransfer21) and receives2,000 USDTfrom the pair (funds_flowtransfer22). - The adapter returns
17,101,229.888968 SEAto the helper (funds_flowtransfer29), and the helper sells17,915,897.432936 SEAback through the pair to receive2,506.180666 USDT(funds_flowtransfers31and32).
That representative cycle shows the core exploit mechanic: a fixed 3,000 USDT settlement deposit unlocks far more SEA than the helper should be able to redeem, and the helper immediately monetizes that SEA through the pair. The same pattern repeats across the remaining cycles, with decoded_calls.json showing:
24occurrences of selector0x987217bc24occurrences of selector0x49525c2324occurrences of selector0xf046d96648occurrences each of0xd06ca61f,0xfbec6d5e, and0x8d56dac5
The doubled counts reflect proxy + implementation entries for the adapter calls. The high-level economic pattern is stable across all 12 loops.
Detailed Call Trace
- Depth
0: attacker EOA0x352173...-> entry contract0x7b1de5..., selector0x93a66b22. - Depth
1: entry contract creates helper0x32db51.... - Depth
1: entry contract -> helper0x8fedc408(...). - Depth
2: helper -> Aave PoolflashLoanSimple(address,address,uint256,bytes,uint16). - Depth
5: Aave Pool -> helper callback0x1b11d0ff(...), then helper execution begins. - Per loop:
- helper -> router
0x5c11d795to swap300 USDT -> SEA - helper -> settlement adapter
0x987217bc(3000000000, 0) - helper -> settlement adapter
0x49525c23(attackerHelper, 1) - helper -> settlement adapter
redeemPosition() - settlement adapter -> router or pair helper functions
0xd06ca61f,0x1f00ca74,0x8803dbee - settlement adapter -> SEA token
transferFrom/transfer - settlement adapter -> pair via router path
- helper -> router
0x5c11d795to swap redeemed SEA back to USDT
- helper -> router
- After loop completion:
- helper approves Aave for
3,301.65 USDT - Aave pulls repayment with
transferFrom - helper transfers the remaining USDT to entry contract
- entry contract transfers that USDT to
tx.origin
- helper approves Aave for
Financial Impact
funds_flow.json is the primary evidence for realized impact in this transaction.
- Attacker realized gain:
13,904.941068 USDT - Pair net loss:
13,906.591068 USDT - Aave premium paid:
1.65 USDT
The 1.65 USDT difference between pair loss and attacker profit is fully explained by the flash-loan fee retained by Aave. trace_prestateTracer.json also shows the helper contract finishing with storage slot 0x0 = 0x33ccc900c, which matches the helper’s recovered profit() slot and corresponds to the accumulated profit [recovered — approximation].
Who lost funds:
- Primary direct victim: SEA/USDT pair
0xeeb9c6b73a9ba397fbea320d9e4cce7b8ac10513 - Secondary affected parties: SEA-side treasury and burn accounting paths, because the redemption flow pushes very large SEA amounts through treasury and burn addresses during each cycle
Evidence
- Transaction hash:
0x001cb16e17c4c5a5c4d02423c9e9b2f2b11ab6b2a1baf2ba53b8fcaf06167716 - Block:
463840994 - Timestamp:
2026-05-17T16:11:19Z - Status: success
- Attacker EOA:
0x352173fabf0e67e1cb1fcdf15474d0477d5d3674 - Flash-loan receiver / helper:
0x32db518e84955739912b6257cc65e3e8374b60e4 - Attacker entry contract:
0x7b1de577da005a58565d6d1fbad286fdf2f269b7 - Vulnerable contract:
0xa70f31c06f921019237fc00b1417217dae5c37c5 - Vulnerable implementation analyzed:
0x13dde273b66323686bfb96cce5a2a7190b40b264[recovered — approximation] - Pair:
0xeeb9c6b73a9ba397fbea320d9e4cce7b8ac10513 - Verified SEA token implementation: SEATokenUpgradeable.sol
- Recovered pair implementation: recovered.sol
- Recovered settlement adapter implementation: recovered.sol
- Recovered helper implementation: recovered.sol
Key trace-backed facts:
trace_callTracer.jsontop-level helper call input encodes flash-loan amount3300 USDT, per-loop swap amount300 USDT, per-loop settlement amount3000 USDT, and12iterations.decoded_calls.jsonshows24redeemPosition()entries because both the proxy and implementation calls are recorded for each of the12loops.funds_flow.jsonattacker_gainsrecords13,904.941068 USDT.funds_flow.jsonnet_changesrecords the pair at-13,906.591068 USDT.