Rescue Assets From a Compromised Wallet

DeepDeep
4 min read

Flashbots can actually be a lifesaver sometimes.

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 this wallet was the owner of a contract we deployed. it still had the ownership, but it didn’t have any Ether left, so we can’t transfer the Ownership to another wallet as we don’t have any Ether left to pay the gas fees.

Well, just load the wallet with some Ether and transfer the tokens it’s so easy, well not really!

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

What’s the solution then?

It’s simple we need to transfer some Ether to the wallet and transfer the ownership of the contract before the bot set up by the hacker can perform any action, it has to be fast. means it has to be done in a single block

Can 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's 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 boats, 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.

Scenario

For this article, I’ve tried to replicate a similar scenario

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 provider.

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, so 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 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,

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

0
Subscribe to my newsletter

Read articles from Deep directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Deep
Deep

Blockchain and Fullstack developer, Web3, Solidity, React | Nextjs |Angular| Node | AWS | Serverless | Redux | Flutter, and all about web development