Skip to content

fix: preflight fee-sponsored Tempo transactions#657

Merged
brendanjryan merged 5 commits into
wevm:mainfrom
brendanjryan:brendanjryan/fee-payer-preflight
Jul 15, 2026
Merged

fix: preflight fee-sponsored Tempo transactions#657
brendanjryan merged 5 commits into
wevm:mainfrom
brendanjryan:brendanjryan/fee-payer-preflight

Conversation

@brendanjryan

Copy link
Copy Markdown
Collaborator

Motivation

Prevent wasted sponsorship work and broadcasts when a sender or final sponsored Tempo envelope would revert.

Summary

  • Centralized sponsored-transaction preflight orchestration.
  • Simulated sender and final sponsored envelopes before signing or broadcast.
  • Added coverage for preflight ordering and failure paths.

Key design considerations

  • Hosted fee-payer transports still preflight only the sender envelope because final completion is transport-owned.
  • The shared helper keeps all local sponsorship flows on the same simulation sequence.

@pkg-pr-new

pkg-pr-new Bot commented Jul 15, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/mppx@657

commit: 819449a

@brendanjryan brendanjryan marked this pull request as ready for review July 15, 2026 21:04
@cursor

cursor Bot commented Jul 15, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@tempoxyz-bot tempoxyz-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👁️ Cyclops Review

PR #657 centralizes sender-context and final sponsored-envelope simulations before fee-sponsored Tempo broadcasts. The new sponsored preflight flow is generally fail-closed across Charge, Subscription, and precompile paths, but two verified legacy session open regressions need changes before merge.

Reviewer Callouts
  • Hosted legacy fee-payer parity: If legacy hosted fee-payer URL opens reach broadcastOpenTransaction() without a concrete local feePayer, ensure the optimistic-mode fix sender-preflights those transactions too; preflightSponsorship() only covers local account sponsorship.
  • Legacy session regression tests: Add targeted tests for non-sponsored waitForConfirmation:false open simulation and local-sponsored crash/retry store repair so future refactors cannot move simulations outside caller-specific acceptance or recovery semantics.

return serializedTransaction
})()

if (!waitForConfirmation) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚨 [SECURITY] Non-sponsored optimistic legacy opens can credit calldata-derived deposits without simulation

preflightSponsorship() only runs in the local feePayer branch above. In the waitForConfirmation: false branch, no-local-fee-payer opens now call sendRawTransaction() and immediately return pendingOnChain decoded from calldata without the removed eth_call. The legacy server stores/credits that deposit, so reverting underfunded opens can receive service without escrow.

Recommended Fix:
Run a sender-context eth_call for every optimistic open that did not already complete local sponsored preflight before broadcasting/returning pendingOnChain (including hosted/no-local-fee-payer paths).

transaction: {
...transaction,
...(resolvedFeeToken ? { feeToken: resolvedFeeToken } : {}),
const completed = await FeePayer.preflightSponsorship({

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚨 [SECURITY] Sponsored legacy open retry preflight bypasses duplicate-open recovery

This new preflightSponsorship() call executes before the confirmed-mode try/catch below. A retry of an already-mined sponsored open can revert in preflight before getOnChainChannel() recovery runs, leaving the funded channel absent from the store after crash/response-loss retry.

Recommended Fix:
Move preflight/signing for confirmed legacy opens inside the recovery try/catch, or apply the same getOnChainChannel() fallback to preflight failures.

@brendanjryan brendanjryan merged commit 0679b0f into wevm:main Jul 15, 2026
14 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