UserOperation Gas Fees

The maxFeePerGas and maxPriorityFeePerGas fields on a UserOperation mimic the EIP-1559 model.

A User Operation can specify its own gas fees which, just like regular transactions, impacts how fast it gets included on-chain.

Using the EIP-1559 model

Gas fees in ERC-4337 is modelled to be almost identical to EIP-1559. A lot has been written on this topic and we highly recommend the following BlockNative article to get an in depth understanding. All the details can be directly applied to setting reliable gas prices on a User Operation.

Networks that don't support EIP-1559

There are some EVM networks that don't yet support EIP-1559. This usually means the BASEFEE opcode is not supported.

Fortunately ERC-4337 has a simple convention to still maintain support for these networks. By setting the maxFeePerGas and maxPriorityFeePerGas to the same value, the EntryPoint will assume a legacy fee model is being used and avoid calling the BASEFEE when determining the effective gas price.

// How the EntryPoint calculates the UserOperation gas price on-chain.

function getUserOpGasPrice(MemoryUserOp memory mUserOp) internal view returns (uint256) {
  unchecked {
    uint256 maxFeePerGas = mUserOp.maxFeePerGas;
    uint256 maxPriorityFeePerGas = mUserOp.maxPriorityFeePerGas;
    if (maxFeePerGas == maxPriorityFeePerGas) {
      //legacy mode (for networks that don't support basefee opcode)
      return maxFeePerGas;
    }
    return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);
  }
}

Who gets the gas fees?

In an EOA transaction, the gas fee is paid to the network (i.e. a validator or sequencer). The gas fees for a User Operation is also paid to the network, but in a more indirect way. It is first transferred to the EntryPoint and then used to compensate the Bundler for fronting the cost of the initial transaction. Remember that contracts cannot initiate transactions on their own (at least not yet).