Using Flash Bots to Rescue Assets from a Compromised Wallet

Written by deeppatel | Published 2023/01/09
Tech Story Tags: ethereum | flashbots | wallet | mev | web3 | blockchain | crypto-wallet | blockchain-technology

TLDRFlashbot rescue is a way to transfer Ether from a hacked wallet to a new one. It uses a method called an array of Transactions to perform the transfer in a single block. The code is available on GitHub and you can clone the starter code from this repository. It can be used to transfer ERC20 tokens to a different wallet.via the TL;DR App

Flashbots can be real lifesavers sometimes.

Let’s look at a real-life event

One of our wallets had been hacked some time back, and all the Ether in that wallet was taken out. It was an issue but the bigger issue was that this wallet was the owner of a contract we deployed and it still had the ownership, but it didn’t have any Ether left, so we couldn’t transfer the Ownership to another wallet as we couldn’t pay for gas fees.

Well, just load the wallet with some Ether and transfer the tokens. It’s so easy, right?

Well not really!

There was a high probability that the person who hacked the wallet had set up a bot that would immediately take out all the assets transferred to the wallet. So, if we transfered any Ether to the wallet, there was a high probability that it would be taken out immediately.

What’s the solution then?

It’s simple. We needed to transfer some Ether to the wallet and transfer the ownership of the contract before the bot that was set up by the hacker could perform any action. It had to be fast and this meant it had to be done in a single block

Could we do it manually?

Noooo, that’s when the Flashbots come to rescue

Let’s understand some terms first

Maximal Extractable Value (MEV)

Maximal Extractable Value (MEV) represents excess value captured by miners (or validators) from users in a cryptocurrency network. This excess value often comes from reordering user'’ transactions to maximize fees or inserting new transactions that allow a miner to front-run users’ transactions.

More: Maximal extractable value (MEV) | ethereum.org

Flashbots

Flash boats refer to automated programs that use high-speed communication and data processing technologies to execute trades on decentralized exchanges (DEXs) or other types of blockchain-based trading platforms.

Like traditional flash bots, these programs use algorithms to analyze market data and identify trading opportunities in real-time. They can make trades based on a wide range of factors, such as changes in the prices of various cryptocurrencies or tokens, news events, and changes in market liquidity.

Back to the problem

For this article, I’ve tried to replicate a similar scenario to the one described earlier. We have a wallet that has been hacked, the hacker has taken out all the Eth from that wallet, but that wallet still has some ERC20 tokens left inside it, we want to take these tokens out and transfer them to another wallet.

Let’s see the code

You can clone the starter code from this Repo.
First of all, set the environment variables

TOKENS=Address of ERC20 token which we need to takeout of that wallet  
RESCUER=Private key of wallet in which we want to transfer those tokens
HACKED_WALLET=Private key of wallet that has been hacked

Let’s define some constants first

const provider = new providers.JsonRpcProvider('<https://rpc.ankr.com/eth_goerli>')
const authSigner = Wallet.createRandom()
const flashbotProvider = await FlashbotsBundleProvider.create(
        provider,
        authSigner,
        FLASHBOTS_URL
    )
const rescuer = new Wallet(RESCUER).connect(provider)
const hackedWallet = new Wallet(HACKED_WALLET).connect(provider)

We have created all the signers we need, and we are using Ankr as the RPC providers.

We will be using a method from flashbotProvider called sendBundle .

This method takes an array of Transactions that we want to perform in a single block, and as a second argument, it takes the number of blocks in which we want to include the transactions.

Cool? Alright. Let’s get the current block number first.

provider.on('block', async (blockNo) => {
	const targetBlock = blockNo + 1;
})

Out target block is the next block that is to be produced.

And now let’s use the sendBundle method

const resp = await flashbotProvider.sendBundle([
            {
                signer: rescuer,
                transaction: {
                    chainId: 5,
                    type: 2,
                    to: hackedWallet.address,
                    value: utils.parseEther('0.01'),
                    maxFeePerGas: utils.parseUnits('20', 'gwei'),
                    maxPriorityFeePerGas: utils.parseUnits('13', 'gwei')
                }
            },
            {
                signer: hackedWallet,
                transaction: {
                    chainId: 5,
                    type: 2,
                    to: TOKENS,
                    gasLimit: '70000',
                    data: iface.encodeFunctionData("transfer", [
                        rescuer.address,
                        utils.parseEther('200')
                    ]),
                    maxFeePerGas: utils.parseUnits('20', 'gwei'),
                    maxPriorityFeePerGas: utils.parseUnits('13', 'gwei')
                }
            }
        ], targetBlock)

Basically, we will be performing two transactions

  1. We need to transfer some Ether to the wallet that has been hacked to provide it with the gas fees that will be used to transfer the ERC20 tokens to the rescuer wallet.

  2. We now call the transfer function from the ERC20 contract using the signer of the hacked wallet and transfer all the tokens to the rescuer wallet.

These transactions can be anything
Like transfer, an NFT, Transfer Ownership of a contract, call any contract method.

And that’s it.


Also published here.

Want to connect? DM me on twitter @pateldeep_eth or Linkedin

Want to explore more examples?
https://github.com/flashbots/searcher-sponsored-tx

Also, Read


Written by deeppatel | Full stack & Blockchain developer
Published by HackerNoon on 2023/01/09