On-Chain Gas Optimization: Protecting Net Profit with EIP-1559
For an on-chain bot, gas wears two faces. It's a cost you have to pay, and it's a competitive weapon for getting executed ahead of everyone else. Ignore gas and every apparently profitable trade actually loses money; crank it up blindly and you hand your entire profit to validators. The key is to estimate it accurately and account for it in net profit.
Gas Cost = Gas Used × Gas Price
The cost of a single transaction is a product of two values: gas used — how heavy the computation is — and gas price — what you're willing to pay per unit. One swap consumes a roughly fixed amount; bundling multiple hops into one transaction, as with a triangular route, scales it up accordingly.
// The most accurate gas figure comes from simulating with EstimateGas
gasLimit, err := client.EstimateGas(ctx, ethereum.CallMsg{
From: botAddr,
To: &routerAddr,
Data: calldata,
})
if err != nil {
return fmt.Errorf("gas estimation failed (likely revert): %w", err)
}
// Add headroom to the estimate (state changes can push actual usage higher)
gasLimit = gasLimit * 12 / 10 // +20% buffer
When EstimateGas returns an error, that's a signal the transaction would very likely revert if executed now — the opportunity has closed, or the route is blocked. The right move is to skip rather than send, because a revert still costs gas.
EIP-1559 — maxFee and priorityFee
Most chains now use EIP-1559, which splits the gas price into two pieces: the base fee (set by the protocol and burned) and the priority fee, or tip (paid to the miner/validator). Your bot specifies two values.
- maxPriorityFeePerGas (tip) — the tip to the validator. Raising it improves the odds your transaction gets prioritized. This is the competitive lever.
- maxFeePerGas — the ceiling on total price per unit you're willing to bear. Even if base fee spikes, you never pay above this. In practice you only pay
base fee + tip, and the remainder is refunded.
// Pull the latest base fee and suggested tip, then build 1559 tx parameters
head, _ := client.HeaderByNumber(ctx, nil)
baseFee := head.BaseFee
tip, _ := client.SuggestGasTipCap(ctx) // the network's suggested tip
// maxFee = 2x base fee headroom + tip, so a base fee spike doesn't strand us
maxFee := new(big.Int).Add(
new(big.Int).Mul(baseFee, big.NewInt(2)),
tip,
)
tx := types.NewTx(&types.DynamicFeeTx{
GasTipCap: tip, // validator tip (priority)
GasFeeCap: maxFee, // ceiling on total price per unit
Gas: gasLimit,
To: &routerAddr,
Data: calldata,
})
The reason for 2x headroom on base fee is that base fee can climb over the few blocks it takes for your transaction to land. Set the ceiling too tightly and even a small rise leaves your transaction stuck.
Always Fold Gas into Net Profit
This is the part that matters most. Your bot's execution decision has to run on net profit after gas, not apparent profit. Convert estimated gas cost into the starting token's terms, subtract it, and check whether what's left still clears the threshold.
// Gas cost (wei) = gasLimit x (baseFee + tip)
gasCostWei := new(big.Int).Mul(
big.NewInt(int64(gasLimit)),
new(big.Int).Add(baseFee, tip),
)
// Execute only if the threshold is cleared after subtracting gas from gross profit
netProfit := new(big.Int).Sub(grossProfitWei, gasCostWei)
if netProfit.Cmp(minProfitWei) < 0 {
log.Printf("skip: insufficient net profit (gross=%s, gas=%s)", grossProfitWei, gasCostWei)
return
}
Practical Tips
- Make the tip dynamic. A quiet network only needs a low tip; heavy competition for the same opportunity calls for a higher one. But when the tip would exceed the profit, abandoning the trade is the correct answer.
- Prepare for base fee spikes. Big events send base fee up several multiples. Your maxFee ceiling and your net profit math both have to absorb that.
- Reverts are silent bleeding. Failed transactions still burn gas. Filter with
EstimateGasbefore sending to cut down on them. - Denominate gas and profit in the same unit. If profit is in USDT but gas is paid in the native coin, convert to a common basis before comparing net profit.
Gas quietly erodes a bot's P&L. But estimate it accurately, understand EIP-1559's two levers, and account for it in every net profit calculation, and gas stops being a cost and becomes a controllable variable.
This article is for educational and informational purposes and is not investment advice. On-chain automated trading carries the risk of principal loss and of failed-transaction costs, and the outcomes are your own responsibility.
댓글
댓글 쓰기