Skip to content

feat(types,mev): SERVO mempool source, EIP-7702 authorizations, SERVO bid sender - #219

Merged
datluongductuan merged 1 commit into
mainfrom
feat/servo-source
Aug 24, 2026
Merged

feat(types,mev): SERVO mempool source, EIP-7702 authorizations, SERVO bid sender#219
datluongductuan merged 1 commit into
mainfrom
feat/servo-source

Conversation

@datluongductuan

Copy link
Copy Markdown
Member

Adds everything the SERVO 2.0 order-flow auction needs at the library level, so
mempool-explorer, dexdex-arb, reserve-taker and poseidon can depend on one tag.

This must be tagged before the four downstream PRs are mergeable — they
currently carry a replace github.com/KyberNetwork/tradinglib => ../tradinglib
line with a TODO(servo) comment, to be swapped for a require bump.

types

  • MempoolSource gets Servo (10). Appended, never inserted: the values are
    persisted in pending-pool IDs, trade rows and bot configs.
  • Message.GetAllLogs lists Servo explicitly. Its default arm returns no
    logs
    , which downstream reads as "not a swap" — a missing arm silently drops
    every victim of the new source.
  • Message.AuthorizationList carries an EIP-7702 (type 0x4) victim's
    authorizations. They install code on the signing EOA before execution, so a
    re-simulation without them runs against a bare EOA and returns success with
    no logs
    rather than an error. SERVO is MetaMask flow, where smart-account
    delegation txs are expected, and its tx frames carry authorizationList.

mev

  • ServoSender implements IBackrunSender against SERVO's HTTP endpoint with
    X-Api-Key auth (SERVO signs nothing).
  • Its params object is its own type rather than SendBundleParams, which emits
    ReplacementUuid (capital R) and an unsolicited allowBuilderNetRefunds
    neither of which SERVO documents.
  • SERVO's blockNumber is a deadline, not a target: the bid is retried every
    block up to it, and omitting it means 5 blocks of retries on statically-priced
    calldata. The sender folds blockNumber/maxBlockNumber into that deadline
    and refuses to send a bid without one.
  • targetBuilders and coinbaseProfit are ignored — SERVO picks the builders.

Tests cover the exact wire shape (hash order, deadline, replacementUuid, the
API-key header) and every incomplete-bid rejection.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Bof9gJLKZ8oWxLB4uw354P

…e SERVO bid sender

SERVO 2.0 is Consensys/MetaMask's order-flow auction: it streams signed pending
txs and bundles over a websocket and takes backrun bids back as eth_sendBundle,
where the bid IS the backrun's priority fee (no coinbase transfer, no stake, and
settlement is conditional on the bundle landing).

types:
- MempoolSource gets Servo. Appended, never inserted: the values are persisted in
  pending-pool IDs, trade rows and bot configs.
- Message.GetAllLogs must list Servo explicitly — its default arm returns NO
  logs, which downstream reads as "not a swap" and silently drops the victim.
- Message.AuthorizationList carries an EIP-7702 (type 0x4) victim's
  authorizations. They install code on the signing EOA before execution, so a
  re-simulation without them runs against a bare EOA and returns success with no
  logs rather than an error. SERVO is MetaMask flow, where smart-account
  delegation txs are expected, and its tx frames carry authorizationList.
- CallFrame.AuthorizationList carries the same per FRAME, which is what a merged
  pending BUNDLE needs: it flattens its members into Calls, so a bundle-level
  list cannot say which member an authorization belongs to. Applying one member's
  delegation before an earlier member runs changes what that earlier call sees,
  and can flip the authorization's own nonce check.

mev:
- ServoSender implements IBackrunSender against SERVO's HTTP endpoint with
  X-Api-Key auth. Its params object is its own type rather than SendBundleParams,
  which emits `ReplacementUuid` (capital R) and an unsolicited
  allowBuilderNetRefunds — neither of which SERVO documents.
- SERVO's blockNumber is a DEADLINE, not a target: the bid is retried every block
  up to it, and omitting it means 5 blocks of retries on statically-priced
  calldata. The sender therefore folds blockNumber/maxBlockNumber into that
  deadline and refuses to send a bid without one.
- targetBuilders and coinbaseProfit are ignored: SERVO chooses the builders.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bof9gJLKZ8oWxLB4uw354P
@datluongductuan
datluongductuan merged commit 7576e78 into main Aug 24, 2026
3 checks passed
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.

2 participants