ERC20: transfer amount exceeds balance. Order of tx in bundle

I was wondering if there was a case to use more than send gas → sponsored transaction. For example I want to send gas → unstake staked token → transfer this token to some recipient

I have modified sponsored-tx github repo and added a new engine that supports said logic, but I get an error that I have insufficient amount of tokens to transfer (in a last step), which is true, because initially wallet has zero of this tokens and only after unstake has enough to perform a transfer operation

So, question is, how I can add two dependent transactions in one bundle, if next tx cannot execute before the previous one does?

I have seen on-chain examples of such operations, for example:

transfer gas

unstake

transfer unstaken erc20

all three in one block

My snippet, referring to seacher-sponsored-tx repo from flashbots ream

  async getSponsoredTransactions(): Promise<Array<TransactionRequest>> {
    const claimTx = await this._stakeTokenContract.populateTransaction.unstake(
      BigNumber.from(this._amount),
      []
    );

    const transferTx =
      await this._erc20TokenContract.populateTransaction.transfer(
        this._recipient,
        BigNumber.from(this._amount)
      );

    return [
      {
        ...claimTx,
      },
      {
        ...transferTx,
      },
    ];
  }

I get

"code":3,"message":"execution reverted: ERC20: transfer amount exceeds balance"

Hi, @kaladin

This error means that the ERC20 token contract does not have enough balance to transfer the requested amount.

Please try these steps.

  1. Add a balance check before transfer and revert if insufficient balance:
if(_erc20TokenContract.balanceOf(stakingContract) < _amount) {
  revert("Insufficient balance");
}
  1. Transfer a reduced amount if balance is less than requested amount.

  2. Handle unstake and transfer asynchronously:

async function getSponsoredTransactions() {

  await stakingContract.unstake(_amount); 

  const balance = await _erc20TokenContract.balanceOf(stakingContract);

  if(balance < _amount) {
    _amount = balance;
  }

  return [
    transferTx  
  ]

}

Please try these steps.

I said in my initial post that I know what the problem is, I am trying to sumbit two dependent tx in one bundle, steps that you have listed unfortunately don’t help much in this matter