Read on for a long story full of adrenaline, black & white hats, bots, txs, and code snippets! ⤵️
Everything started with an email from the brother of a friend asking for help.
Amidst the excitement of an alpha leak, he had entered his seed phrase where he shouldn't had. He got almost all of his savings siphoned out of his account.
Yet not everything was lost! He still had $14K worth of RFuel tokens (no, I didn't know this project existed either) staked in a contract.
Unstaking them involved a 7-day waiting period, which the hacker had already kicked-off.
This set a concrete date and time when these tokens would become available: 1616110845, or in human-readable terms, Thursday, March 18 8:40:45 PM ART.
The date for the showdown was set. We were going to fight to get those tokens before the hacker did. ⚔️
With a week to prepare, I set out to research the latest from the flashbots team. @epheph had recently demoed a sample project for rescuing tokens from compromised accounts, which was almost what I needed.
Flashbots allow you to submit an all-or-nothing bundle of txs. The miner decides whether to accept them based on the overall funds sent to the coinbase account.
This allows you to send txs from accounts with zero ETH, as long as another tx in the bundle pays for it.
The idea was then to submit a bundle where we would unstake the tokens from the contract (the only change from the original script), transfer them to a secure account (all without ETH!), and then pay out to the miner from a separate, funded account.
But flashbots have a downside: their hashrate is not very high, so a bundle is mined only every 5-10 minutes.
Which is more than enough time for the hacker to fund the compromised account, unstake+transfer on their own, and run away with the last of the tokens.
While we could try frontrunning them, it was risky. So we added another bot to the mix: a burner.
This bot would constantly check the account's balance, and whenever it found ETH, would use it to send a tx to self at the highest possible gas price, burning it.
The plan was ready. I validated it with @onewayfunction to see if it had any holes. And @sniko_ kindly reached out to offer assistance, and went through the code to vet it.
All that was left was waiting until the date set.
Fast forward to Thursday. By 20.30hs I had an AWS server running the burner through @AlchemyPlatform, and a local instance running it via @infura_io.
I couldn't risk losing connectivity and giving the hacker a window to steal the funds.
The moment of truth approached. I kicked off the flashbot script and...
error: bundle interacted with more than 2 addresses 😱
I re-ran the script, changed parameters, tried a dry run. Same result. Did my best to contain the panic. I had tested this, hadn't I?
To make it worse, the hacker had sent a funding tx right on time to start the process.
Luckily, the burners caught it immediately and burned the funds. As long as they were running, I had time to fix this.
I asked for help in the flashbots discord. I got my response immediately: this was a new restriction added two days ago 💀
Luckily, @thegostep summoned @epheph, who reached out via DM right away and provided support.
I also got messaged by @fiiiu_, who revealed himself to be the author of this new limitation.
They had checked all bundles to make sure they didn't disrupt any bots. But my bot hadn't actually sent a bundle, only simulated them, so it went unnoticed.
I rushed to change the script. I had to break the bundle into two separate ones: one for unstake, one for transfer. As long as I kept the compromised account without ETH, it would be safe.
This is what my console looked like with everything running.
After five interminable minutes, the first bundle was mined. This was my first flashbot bundle ever, hooray!
But this also meant that the tokens were now on the account. The hacker started frantically sending funds to remove them.
Yet the burners held their ground.
The second bundle was awaiting its turn in the meantime. And 11 minutes after the first one, it was mined 🎉
The tokens were now safe, transferred to a secure location in a zero-gas-fee tx - with a nice bribe for the miner.
A few more inbound funding txs landed after that, but that was it. We were victorious.
This is what the battlefield looked like after everything went down.
To everyone not following the crypto scene, a new use case that is an actual game changer has come up recently.
I'm talking about flash loans (thread) 🧵
Decentralized Finance (DeFi, for short) has become one of the most popular use cases.
Financial instruments from the traditional world, such as loans and derivatives, have been encoded as smart contracts and run on the Ethereum decentralized network.
It's easy to see why DeFi took off. The first and most widespread blockchain (Bitcoin) was used for monetary transactions.
It makes sense that the next big step would be instruments operating on that value, which took so much effort to move on chain.