PR: #41 (feat/executor: transaction builder + eth_call simulator)
File: crates/charon-executor/src/builder.rs — build_tx()
Refs #41
Problem
build_tx fetches the nonce with:
let nonce = provider
.get_transaction_count(from)
.await
.context("tx builder: failed to fetch nonce")?;
alloy's get_transaction_count defaults to BlockId::latest() — the count of confirmed transactions, not pending. If two build_tx calls execute before either broadcast (two opportunities dequeued from OpportunityQueue in the same block), both receive the same nonce. The second broadcast is rejected with nonce too low and the opportunity silently drops.
Impact
Loss of liquidation revenue in any burst scenario (multiple liquidatable positions in one block). The race window is inherent in the flash-loan-per-block model.
Fix
Use the pending nonce:
use alloy::rpc::types::BlockNumberOrTag;
let nonce = provider
.get_transaction_count(from)
.block_id(BlockId::Number(BlockNumberOrTag::Pending))
.await
.context("tx builder: failed to fetch pending nonce")?;
Note: PR #43 (feat/18-gas-and-nonce) introduces a nonce manager that supersedes this. Until PR #43 merges, pending is the correct interim fix. Add a TODO referencing #43.
PR: #41 (feat/executor: transaction builder + eth_call simulator)
File: crates/charon-executor/src/builder.rs — build_tx()
Refs #41
Problem
build_tx fetches the nonce with:
alloy's get_transaction_count defaults to BlockId::latest() — the count of confirmed transactions, not pending. If two build_tx calls execute before either broadcast (two opportunities dequeued from OpportunityQueue in the same block), both receive the same nonce. The second broadcast is rejected with nonce too low and the opportunity silently drops.
Impact
Loss of liquidation revenue in any burst scenario (multiple liquidatable positions in one block). The race window is inherent in the flash-loan-per-block model.
Fix
Use the pending nonce:
Note: PR #43 (feat/18-gas-and-nonce) introduces a nonce manager that supersedes this. Until PR #43 merges, pending is the correct interim fix. Add a TODO referencing #43.