Sandwich attacks on Elysium
Elysium opened as a private mainnet with early-access trading and went public on Nov 9 at 13:00. Since the private launch, bots have sandwiched more than 13,000 trades. 99% of them came before the public launch; since then, sandwiching has almost stopped.
- Data
- Every Elysium mainnet block up to block 4,076,763 (Nov 10 at 14:40)
- Times
- UTC
- Dollars
- HYPE converted at each day's median price in Elysium's HYPE/USDC pools. K is thousand, M is million
- Sandwich
- A bot buys just before a victim's buy and sells right after it, so the victim pays a higher price
- Operator
- One attacker: the wallets that send its transactions and the bot contracts they call. The five that caused the most loss are labeled Operator A to E
- Victims lost
- What the victim's trade would have returned without the bot's buy, minus what it returned. For 2.4% of sandwiches it can't be measured, and they count as zero (why)
- Bots kept
- The operator's net gain in HYPE, WHYPE and USDC over its two transactions, after gas
- Same block
- The bot's buy, the victim's trade and the bot's sell are in one block. Otherwise the bot sold 1–2 blocks later
median 3.3% of a trade
56% of the loss
by 4,315 wallets
since Nov 9 at 13:00
Three operators caused 86% of the losses. Users of one trading-bot router, 0x9b60…3333, took 65%. The timeline follows Operator A: it alone caused 51% of the losses, more than the next three operators together.
- Nov 421:43First sandwich. Until Nov 8, bots mostly sell 1–2 blocks after the victim.
- Nov 705:53Operator A starts and soon becomes the largest attacker.
- Nov 820:00Losses peak: $8.5K in one hour.
- Nov 823:04Operator A starts putting its buy, the victim and its sell in one block.
- Nov 903:00Losses fall under $900 an hour and stay there.
- Nov 913:00Public launch. Operator A stops at 15:09.
What does a sandwich look like?
In both, the bot saw the victim's buy before it reached a block.
Private mainnet, Nov 8: the victim lost 9.1% of the trade
Block 2,784,446 on Nov 8 at 23:29, ISLAND / HYPE on Uniswap V4, run by Operator A.
1. Bot buys with 9.3 HYPE. Its tip is 1 wei above the victim's, so it goes first.
0xd193…62922. Victim buys with 2.9 HYPE at the raised price and gets 9.1% fewer tokens, a loss of 0.268 HYPE.
0x0853…7edc3. Bot sells everything with a zero tip, so it goes right after the victim. It keeps 0.083 HYPE; pool and launchpad fees take the rest of the victim's loss.
0xbaaa…84af
Public mainnet, Nov 10: the victim lost 3.9% of the trade
Block 3,931,121 on Nov 10 at 10:11, BUTTERFLY / HYPE on Uniswap V4, run by 0x2593…2b5a.
1. Bot buys with 3.5 HYPE. Its tip is 1 wei above the victim's, so it goes first.
0x5c0a…19482. Victim buys with 18.8 HYPE at the raised price and gets 3.9% fewer tokens, a loss of 0.735 HYPE.
0x9d98…966f3. Bot sells everything 2 blocks later. It keeps 0.739 HYPE.
0xc6dc…5e2c
When did it happen?
Operators took turns, then Operator A caused most losses from Nov 8
Victims' losses per day, by operator. On the worst day, Nov 8, sandwiched trades were 8.4% of all HYPE traded on Elysium.
Losses peaked on Nov 8 and fell 10 hours before the public launch
Victims' losses per hour. At the peak, $8.5K at 20:00, Operator A was still selling 1–2 blocks after the victim.
Day by day
| Day | HYPE price ($) | Sandwiches | Traded ($) | Victims lost ($) | Bots kept ($) |
|---|---|---|---|---|---|
| Nov 4 | 77.55 | 27 | 13,524 | 868 | 518 |
| Nov 5 | 71.57 | 137 | 81,071 | 4,453 | 3,103 |
| Nov 6 | 67.31 | 2,057 | 488,816 | 22,934 | 12,621 |
| Nov 7 | 74.06 | 4,388 | 1,277,978 | 46,457 | 25,447 |
| Nov 8 | 74.19 | 5,224 | 1,843,802 | 66,973 | 37,475 |
| Nov 9 | 74.97 | 1,128 | 287,111 | 11,594 | 6,741 |
| Nov 10 | 74.24 | 100 | 16,927 | 166 | 135 |
Who did it?
Operator A caused 51% of all losses
All 12 operators, by victims' loss. Same block is the share of an operator's sandwiches with its buy, the victim's trade and its sell in one block; in the rest it sold 1–2 blocks later. Bots kept 56% of what victims lost, because each sandwich pays pool and launchpad fees on two trades.
| Operator | Sandwiches | Same block | Victims lost ($) | Kept ($) | First | Last | |
|---|---|---|---|---|---|---|---|
| Operator A | 6,822 | 15% | 77,671 | 44,067 | Nov 705:53 | Nov 915:09 | |
| Operator B | 1,997 | 2% | 29,334 | 15,574 | Nov 713:17 | Nov 902:47 | |
| Operator C | 2,248 | <1% | 25,355 | 13,706 | Nov 607:02 | Nov 706:27 | |
| Operator D | 1,448 | 1% | 12,317 | 7,067 | Nov 705:37 | Nov 906:29 | |
| Operator E | 182 | 0% | 6,160 | 4,167 | Nov 421:43 | Nov 623:15 | |
| 0x5d82…c2a9 | 77 | 0% | 699 | 338 | Nov 714:21 | Nov 919:58 | |
| 0xf31c…6074 | 55 | 0% | 613 | 298 | Nov 616:27 | Nov 709:20 | |
| 0x0b8d…8471 | 29 | 3% | 558 | 363 | Nov 917:53 | Nov 1010:58 | |
| 0x2593…2b5a | 94 | 0% | 546 | 365 | Nov 605:26 | Nov 1014:13 | |
| 0x800c…589e | 25 | 0% | 174 | 90 | Nov 510:27 | Nov 514:55 | |
| 0x3cca…5a3e | 82 | 0% | 18 | 6 | Nov 1002:06 | Nov 1014:30 | |
| 0x32d1…0bfd | 2 | 100% | 0 | 1 | Nov 913:29 | Nov 913:31 | |
| Total | 13,061 | 153,445 | 86,041 |
Addresses of the five largest operators
Wallets are the accounts that sign and send an operator's transactions; one operator can run several, for example to send many transactions at once. Bot contracts are the contracts those transactions call to trade. Operator B has none: its wallet trades through an app contract that also holds the funds. Largest sandwich links the bot's buy, the victim's trade and the bot's sell.
| Wallets | Bot contracts | Other addresses | Largest sandwich | |
|---|---|---|---|---|
| A | 0x20e8…f3a9 0xc64a…1ca0 | 0x39fd…4bf9 0x6761…94e9 | buy · victim · sell | |
| B | 0x6666…6666 | none | funds held in app contract 0xaa6f…48ad | buy · victim · sell |
| C | 0x8fc2…8275 | 0xb85f…b8f2 | buy · victim · sell | |
| D | 0x084b…d45c 0x2a83…f042 0x5e0b…7881 0x8aa4…ea61 +7 more | 0x55e2…caea | buy · victim · sell | |
| E | 0x9999…9999 | 0x120d…ea05 | buy · victim · sell |
Who got hurt, and how badly?
The median victim lost 3.3% of the trade
Sandwiched trades, by the share of the trade's value the victim lost. 1,961 trades lost 10% or more.
Users of one trading-bot router took 65% of the losses
Victims' losses by the contract their transaction called. Users of Uniswap's router and other unrelated apps were hit too, so the leak was on a path these apps share, not inside one app.
| Contract | Name | Trades | Wallets | Lost ($) | |
|---|---|---|---|---|---|
| 0x9b60…3333 | Unnamed trading-bot router | 8,105 | 2,004 | 100,029 | |
| 0xc6e9…a157 | 2,112 | 1,163 | 12,105 | ||
| 0x1b34…3c1a | Uniswap Universal Router 2.2.0 | 859 | 557 | 9,299 | |
| 0x751c…b430 | 76 | 30 | 4,630 | ||
| 0xaf8d…a295 | 489 | 181 | 4,627 | ||
| 0xa13f…4b45 | Uniswap Universal Router 2.1.2 | 252 | 119 | 4,433 | |
| 0xca11…ca11 | Multicall3 | 168 | 103 | 3,401 | |
| 0x6506…acf9 | 146 | 62 | 2,959 | ||
| 99 other contracts | 979 | 355 | 11,962 |
Ten largest victims
| Wallet | Trades | Traded ($) | Lost ($) |
|---|---|---|---|
| 0x2435…cbab | 47 | 114,451 | 2,835 |
| 0x9356…9262 | 33 | 63,680 | 2,112 |
| 0xef5b…500a | 56 | 6,775 | 1,500 |
| 0x1b78…685b | 77 | 14,269 | 1,388 |
| 0xdfc2…2ed6 | 32 | 12,008 | 1,274 |
| 0xe83b…a2a6 | 40 | 13,502 | 1,096 |
| 0x7b3d…8d61 | 19 | 18,411 | 1,061 |
| 0xf979…923d | 25 | 3,447 | 953 |
| 0xfc3f…9637 | 28 | 7,730 | 890 |
| 0xc183…d8c3 | 4 | 27,743 | 847 |
Where did it happen?
Most targets were new tokens paired with HYPE on Uniswap V4
The ten pools with the largest losses. 1,610 pools were hit; these ten took 22% of all losses. Operator A was the main attacker in all ten.
| Pool | Sandwiches | Traded ($) | Lost ($) | Example | |
|---|---|---|---|---|---|
| BLOB / HYPE | 135 | 265,494 | 7,562 | buy · victim · sell | |
| e/acc / WHYPE | 133 | 347,109 | 4,547 | buy · victim · sell | |
| EACCAT / HYPE | 123 | 298,349 | 4,298 | buy · victim · sell | |
| CHAMELEON / HYPE | 150 | 194,293 | 2,905 | buy · victim · sell | |
| AGORA / HYPE | 161 | 158,772 | 2,790 | buy · victim · sell | |
| LIQUITTY / HYPE | 114 | 34,452 | 2,449 | buy · victim · sell | |
| YIELDEX / HYPE | 127 | 79,618 | 2,439 | buy · victim · sell | |
| AETHER / WHYPE | 32 | 34,096 | 2,368 | buy · victim · sell | |
| VOID / HYPE | 90 | 86,580 | 2,142 | buy · victim · sell | |
| NMEOWS / WHYPE | 115 | 97,217 | 1,974 | buy · victim · sell |
How do we know?
Venues
All swap events of the common AMM formats, from block 1.
| Venue | Swap events | Sandwiches | Note |
|---|---|---|---|
| Uniswap V4 pools, including launchpad hooks | 1,842,763 | 12,827 | |
| Uniswap V2 and V3 pools and forks | 303,820 | 234 | |
| Bin AMM pools (USDC/WHYPE, from Nov 9) | 95,652 | 0 | swaps rebuilt from token transfers |
| Liquidity Book pools (USDC/WHYPE, from Nov 9) | 69,082 | 0 | swaps rebuilt from token transfers |
| Aggregator Exchange events | 48,543 | trades land in the pools above | |
| Bonding-curve Buy and Sell events | 121 | too few to matter | |
| Algebra, PancakeSwap V3, Curve, Balancer | 0 |
Finding sandwiches
- In one pool: a buy, then other wallets buying in the same direction, then a sell by the first buyer of about what it bought (within 5%), all within 2 blocks.
- The buy and the sell come from the same wallet, each victim from a different one.
- Same block: 1,101 sandwiches, all counted. Sold 1–2 blocks later: 12,002 candidates; 11,960 counted, from operators that profit from this pattern overall.
Evidence that bots saw pending transactions
Elysium has no public mempool. Yet in 576 of 594 sandwiches with the three transactions next to each other, the bot's buy pays a higher tip than the victim and its sell no more than the victim; usually the buy pays the victim's tip plus 1 wei. In all 1,101 same-block sandwiches, the bot signed its sell together with its buy (consecutive nonces). Operator A's contract refuses to sell unless it gets back more than it paid, which only works if it knows a buy will land in between.
Losses and profits
- Victims lost: the victim's transaction is re-run with
eth_simulateV1on the state just before the bot's buy and compared with what it really received. - Not measured: 309 sandwiches (2.4%). 270 are in pools of two tokens with neither HYPE nor USDC, so their loss has no price; for the other 39 the re-run failed or its result could not be valued. They count as zero, so the totals are a floor.
- Bots kept: both bot transactions are traced with
debug_traceTransaction, summing every HYPE, WHYPE and USDC movement in and out of the operator's addresses, minus gas. Swap events alone overstate it, because launchpad hooks take fees outside the event.
Grouping wallets into operators
A wallet joins the bot contract it calls for its trades. Bot contracts with the same code, once hard-coded addresses are blanked, are joined. An address that repeatedly receives most of an operator's sell proceeds joins as its profit address. A contract that 5 or more other wallets use for their own trades is a public app, not a bot.
Out of scope
- Sandwiches with more than 2 blocks between the bot's buy and sell; launch sniping, arbitrage and back-running.
- Profit moved to an address that the transactions don't link to the operator, or kept in tokens other than HYPE, WHYPE and USDC.