Skip to content

Add Uniswap TWAP fee oracle for batch_policy.log_gas_price - #30

Open
stephenctw wants to merge 19 commits into
mainfrom
feature/l1-fee-oracle
Open

Add Uniswap TWAP fee oracle for batch_policy.log_gas_price#30
stephenctw wants to merge 19 commits into
mainfrom
feature/l1-fee-oracle

Conversation

@stephenctw

Copy link
Copy Markdown
Collaborator

Summary

  • Add an L1 fee oracle that converts paid gas (base_fee + priority) into fee-token smallest units via a pinned Uniswap V3 WETH/X 30‑minute TWAP, applies 10× slack, and updates batch_policy.log_gas_price.
  • Share Alloy’s EIP-1559 estimator between the batch poster and the oracle so submission and charging stay on one policy; Anvil/devnet uses an explicit fixed exponent (mainnet/Sepolia default to pinned USDC pool presets).
  • Supervise the oracle as a sixth runtime worker with a mandatory refresh before the inclusion lane starts; frame fees remain immutable until the next frame opens.

Test plan

  • cargo test -p sequencer --lib fee_oracle
  • cargo test -p sequencer --lib eip1559
  • cargo test -p sequencer --lib config::
  • cargo run -p rollups-e2e --bin rollups-e2e -- fixed_fee_oracle_sets_frame_fee_test --exact
  • Confirm Anvil boots with fixed log_gas_price = 0 when fee-oracle env is unset
  • Confirm mainnet/Sepolia resolve to the pinned USDC pool presets without overrides

Drop the redundant current_frame_fee argument so dequeue/execute always
use the lane's committed WriteHead fee.
Extract Alloy's MetaMask-style medium estimator behind a small helper so
batch submission and fee charging stay on one policy.
Convert base+priority gas into fee-token units via a pinned V3 TWAP,
apply 10× slack, and persist log_gas_price through a dedicated writer.
Resolve fixed vs Uniswap sources from config, require an initial refresh
before the inclusion lane starts, and join the oracle on shutdown.
Record fee-token TWAP charging, writer ownership, env knobs, and Uniswap
pool trust in the operator-facing and threat-model docs.
Add live-source worker/math/TWAP unit tests and assert a configured
fixed log_gas_price is sampled into the first frame fee on devnet.
@stephenctw
stephenctw requested a review from GCdePaula August 3, 2026 08:06
@stephenctw stephenctw self-assigned this Aug 3, 2026
Exercise worker shutdown/transient retention, canonical Uniswap sqrt
vectors, encode bump behavior, and full Uniswap config overrides.
Move the tenfold price slack into batch_policy.log_slack and encode
oracle quotes with fee_from_linear_ceil so the linear path stays exact.
Store the reviewed fee source in deployment_identity, refuse unknown-chain
free pricing, refresh before opening the Tip, and skip the worker for Fixed.
Misconfig exits terminal; transient quote failures stay unclassified.
Pin Fixed fee at setup in the harness and read the first frame fee
directly so the Tip-before-refresh ordering bug cannot regress quietly.
Record that fee-oracle mode and addresses are setup identity, free
pricing is refused on unknown chains, and recommended fee includes
log_slack (default 1356).
The post-recovery gold-batch pump (~150 self-transfers) needs ~6M in
fees at log_recommended_fee 1356; the old 2M deposit ran out mid-loop.
Schema and batch sizing docs still described 10× slack inside the oracle
and omitted log_slack from the recommended-fee formula.
Values above fee_to_linear(MAX_EXPONENT) can no longer saturate silently;
fee_from_linear_ceil and encode_log_gas_price return an error instead.
Only Uniswap OLD reverts map to insufficient observations / misconfig;
other observe failures stay provider errors and exit transient at connect.
Match bootstrap: arithmetic that cannot encode without undercharging
pages the operator (EXIT_TERMINAL) instead of an unclassified restart.
Decode the revert payload and require an exact "OLD" reason so gateway
messages like THRESHOLD cannot become EXIT_TERMINAL misconfig.
refresh_once already opens the writer before spawn; open_read_only could
not catch the failure mode it was shaped for.
Record setup's Fixed write of log_gas_price, fix l1/ list indentation,
and document that observe-only failures do not trip the L1 stale-view
detector while Uniswap run boot deliberately requires live L1.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant