Expand description
driftbrake: chain-agnostic pre-flight simulation traits, plus a
drift-based halt guard that stops your strategy the moment realized
profit diverges from the simulated prediction — before drift compounds
into real capital loss.
This is a facade crate: it re-exports driftbrake_core,
driftbrake_reconcile, driftbrake_receipt_poller, and
driftbrake_journal under one dependency, so cargo add driftbrake gets
you the chain-agnostic traits, the default dual-guard halt policy, receipt
polling, and persistent WAL state in one shot.
The REVM simulation backend is intentionally not bundled here.
driftbrake-revm-backend is a separate crate (cargo add driftbrake-revm-backend) — see docs/ARCHITECTURE.md’s “swappable
simulation backend” design goal: a team with an existing simulation
stack implements SimEngine against their own tooling and should
never be forced to compile REVM just to depend on this crate for the
reconciliation and halt logic. If you do want the REVM backend
(most users will), add it alongside this crate — see the Quickstart
below.
For the full mechanism specification and correctness argument, see
docs/whitepaper.md. For exact trait contracts, see docs/API.md.
§Quickstart
This example type-checks against the real API (see this crate’s doc
tests) but is marked no_run, since it needs a live RPC endpoint to
actually execute — see examples/toy-arbitrage for a runnable
end-to-end version.
use driftbrake::{
DecodeError, HaltDecision, HaltPolicy, Log, PredictedProfit, ProfitDecoder,
RawSimOutput, RealizedProfit, RealizedProfitDecoder, ReconcileHistory,
ReconcilePolicy, SimEngine, TxReceipt, TxStatus,
};
// The REVM backend is a separate crate — `cargo add driftbrake-revm-backend`.
use driftbrake_revm_backend::{BlockContext, CandidateTx, DbFactory, RevmBackend};
// 1. `SimEngine` needs a `DbFactory` — something that forks chain state.
// Bring your own (a live RPC-backed one, or a test fixture); this
// minimal stub is just enough to make the example self-contained.
#[derive(Clone)]
struct MyDbFactory;
impl DbFactory for MyDbFactory {
type Db = CacheDB<EmptyDB>;
type Error = std::convert::Infallible;
fn fresh_db(&self) -> Result<Self::Db, Self::Error> {
Ok(CacheDB::new(EmptyDB::new()))
}
}
// 2. Implement `ProfitDecoder` / `RealizedProfitDecoder` for your
// executor contract's specific ABI shape (see docs/API.md).
struct MyProfitDecoder;
impl ProfitDecoder for MyProfitDecoder {
fn decode_predicted(&self, raw: &RawSimOutput) -> Result<PredictedProfit, DecodeError> {
if raw.revert_reason.is_some() {
return Err(DecodeError::Reverted);
}
Ok(PredictedProfit(0)) // decode your executor's real return value here
}
}
struct MyRealizedDecoder;
impl RealizedProfitDecoder for MyRealizedDecoder {
fn decode_realized(&self, receipt: &TxReceipt, _logs: &[Log]) -> Result<RealizedProfit, DecodeError> {
if receipt.status != TxStatus::Confirmed {
return Err(DecodeError::Other("not confirmed".into()));
}
Ok(RealizedProfit(0)) // decode your Profit event and net gas cost here
}
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let block = BlockContext { number: 0, timestamp: 0, gas_limit: 30_000_000, basefee: 0, coinbase: [0; 20] };
let sim = RevmBackend::new(MyDbFactory, block, /* block_time_ms */ 12_000, /* timeout_fraction */ 0.5, /* concurrency */ 4);
let predicted_decoder = MyProfitDecoder;
let realized_decoder = MyRealizedDecoder;
let mut guard = ReconcilePolicy::default_dual_guard();
let mut history = ReconcileHistory::new();
let candidate_tx = CandidateTx { caller: [0; 20], to: [0; 20], value: 0, data: vec![], gas_limit: 100_000 };
let raw = sim.simulate(&candidate_tx).await?;
let predicted = match predicted_decoder.decode_predicted(&raw) {
Ok(p) if p.0 > 0 => p,
_ => return Ok(()), // not profitable in simulation (or reverted), skip submission
};
let receipt = submit_and_wait(&candidate_tx).await?;
let realized = realized_decoder.decode_realized(&receipt, &[])?;
history.append(predicted, realized);
match guard.evaluate(&history) {
HaltDecision::Continue => {}
HaltDecision::Halt(reason) => {
eprintln!("phantom-guard halted strategy: {reason:?}");
std::process::exit(1);
}
}
Ok(())
}Structs§
- Drawdown
Config - Absolute net capital drawdown configuration: halts if cumulative prediction deficit
(sum(predicted - realized)) across the last
windowpairs exceedsmax_drawdown_limit. - Fast
Guard Config - Fast-guard configuration: halts on
windowconsecutive ratios all belowthreshold. - Journaled
History - A disk-backed Write-Ahead Log wrapping
ReconcileHistory. - Log
- A single decoded event log from a confirmed transaction receipt.
- Poller
Config - Polling cadence and timeout, both expressed as a function of block
time rather than a fixed millisecond constant — the same reasoning as
driftbrake-revm-backend’sSimEnginetimeout: a value tuned for one chain’s block time doesn’t transfer to a chain with a meaningfully different one. - Predicted
Profit - Profit predicted by simulation, in the smallest denominated unit of the relevant token (e.g. wei for ETH-denominated strategies).
- RawSim
Output - Opaque wrapper around whatever a
crate::SimEngineimplementation returns for a single candidate-transaction simulation. - Realized
Profit - Profit actually realized on-chain, net of gas cost, in the same unit
and same token as the corresponding
PredictedProfit. - Receipt
Poller - Polls a
ReceiptSourcefor a transaction’s receipt and books its realized profit via aRealizedProfitDecoder, once both the confirmed-status and decodable-profit-event conditions are met. - Reconcile
History - Append-only, confirmation-time-ordered history of
(predicted, realized)pairs and on-chain revert events. - Reconcile
Policy - The default
HaltPolicy: the phantom-guard dual guard, optionally extended with revert and capital-weighted risk guards. - Revert
Burst Config - Revert-burst configuration: halts if
limitconsecutive transactions revert on-chain. - Revert
Event - A confirmed-but-reverted transaction, tracked separately from
ReconcileHistory::pairsrather than folded in as a zero-profit realization (whitepaper Section 4.5). - Revert
GasConfig - Revert gas-budget configuration: halts if cumulative gas fees burned on reverts
within the last
windowtimeline entries exceedsbudget_limit. - Slow
Guard Config - Slow-guard configuration: halts when the mean of the last
windowratios drops belowthreshold. - TxReceipt
- Standard confirmed-transaction receipt.
- Volume
Weighted Config - Volume-weighted average ratio configuration: halts if VWAR of the last
windowconfirmed pairs drops belowthreshold.
Enums§
- Decode
Error - Shared error vocabulary for
crate::ProfitDecoderandcrate::RealizedProfitDecoder. - Halt
Decision - Decision returned by
crate::HaltPolicy::evaluate. - Halt
Reason - Structured reason a
HaltDecision::Haltwas returned. - History
Entry - A chronological event in the execution timeline.
- Journal
Error - Poll
Error - Error from the receipt source itself (RPC failure, connection drop,
etc.) — distinct from
PollOutcome::DecodeFailed, which is a successful poll that then failed to decode. - Poll
Outcome - Outcome of polling a single transaction to settlement (or giving up).
- SimError
- Error type returned by a
crate::SimEngineimplementation. - TxStatus
- Confirmation status of a transaction, as reported by the chain.
Traits§
- Halt
Policy - Given the full
(sim, realized)history so far, decides whether to halt. - Profit
Decoder - Decodes a raw simulation result into a predicted profit.
- Realized
Profit Decoder - Decodes a confirmed receipt + its logs into a realized profit, net of gas cost.
- Receipt
Source - Where
receipt-pollergets receipts and logs from. - SimEngine
- Forks chain state and runs a candidate transaction through a
simulation backend, returning a
RawSimOutputwithin a hard latency budget.