Summary
estimate_gas_units is a direct pass-through to eth_estimateGas with no multiplier applied to the result. The gas estimate is computed against the simulation block's state. Between simulation and on-chain inclusion (1-3 blocks on BSC), the following can change:
- A partial liquidation by another bot reduces collateral, altering storage-access patterns and adding cold SLOADs
- A price oracle update writes a new slot
- Flash-loan protocol re-entrancy guard flag uses additional storage
Industry standard for liquidation bots is to apply a 20-30% gas buffer:
let gas_limit = estimate * 120 / 100;
Without this buffer, the flash-loan callback can OOG mid-execution. In a flash-loan, an OOG revert causes the lender to reclaim the loan atomically, but all gas spent in the callback is consumed. The net effect: gas lost, opportunity missed.
The CLAUDE.md requirement that the simulation gate must not be bypassed implies the gas limit passed to simulation must match the gas limit used for broadcast. An underestimated limit that passes simulation but fails on-chain is a functional bypass of the gate.
File
crates/charon-executor/src/gas.rs — estimate_gas_units()
Fix
pub async fn estimate_gas_units(...) -> Result<u64, GasError> {
let estimate = provider.estimate_gas(&tx).await.map_err(GasError::Provider)?;
Ok(estimate.saturating_mul(12) / 10) // 20% buffer
}
Refs #43
Summary
estimate_gas_unitsis a direct pass-through toeth_estimateGaswith no multiplier applied to the result. The gas estimate is computed against the simulation block's state. Between simulation and on-chain inclusion (1-3 blocks on BSC), the following can change:Industry standard for liquidation bots is to apply a 20-30% gas buffer:
Without this buffer, the flash-loan callback can OOG mid-execution. In a flash-loan, an OOG revert causes the lender to reclaim the loan atomically, but all gas spent in the callback is consumed. The net effect: gas lost, opportunity missed.
The CLAUDE.md requirement that the simulation gate must not be bypassed implies the gas limit passed to simulation must match the gas limit used for broadcast. An underestimated limit that passes simulation but fails on-chain is a functional bypass of the gate.
File
crates/charon-executor/src/gas.rs—estimate_gas_units()Fix
Refs #43