Skip to content

fix: gate Money Account payment override prepend to same-chain flows#9449

Open
OGPoyraz wants to merge 2 commits into
mainfrom
ogp/fix-money-account-cross-chain-invalid-eoa-signature
Open

fix: gate Money Account payment override prepend to same-chain flows#9449
OGPoyraz wants to merge 2 commits into
mainfrom
ogp/fix-money-account-cross-chain-invalid-eoa-signature

Conversation

@OGPoyraz

@OGPoyraz OGPoyraz commented Jul 9, 2026

Copy link
Copy Markdown
Member

Explanation

Cross-chain Money Account deposits — e.g. a Predict (Polymarket) withdrawal on Polygon that deposits into a Money Account on Monad — failed on the Relay /execute step with the custom error InvalidEOASignature() (selector 0x3db6791c).

Current state: submitTransactions unconditionally prepends the Money Account payment override onto the source-chain execute batch whenever quote.request.paymentOverride is set. For a cross-chain deposit, the payment override is a Money Account deposit delegation that belongs on the destination chain — it is already carried in the Relay quote's destination txs[], and its delegation is EIP-712 signed for the destination chainId. Prepending it onto the source-chain batch caused that destination-signed delegation to be redeemed on the source chain, so redeemDelegationsexecuteFromExecutor validated the signature with the source chain's domain, recovered a different signer, and the EIP7702StatelessDeleGator reverted with InvalidEOASignature().

Solution: Only prepend the payment override onto the source execute batch for same-chain flows (currencyIn.chainId === currencyOut.chainId). For cross-chain flows we fall through to the existing post-quote path, which prepends the original transaction (e.g. the Predict withdrawal); the Money Account deposit continues to run on the destination side via the quote's txs[].

The change is a one-line guard (&& isSameChainOverride) plus a comment explaining the invariant.

Proof

Before the fix, the Relay /execute simulation returned (decoded revert trace):

Multicall3.aggregate3Value
└─ redeemDelegations                @ 0xdb9b1e94… (DelegationManager, source chain 137)
   └─ executeFromExecutor           @ 0x6d404afe… (7702 account)
      └─ redeemDelegations          @ 0xdb9b1e94…
         └─ revert 0x3db6791c = InvalidEOASignature()

The delegation being redeemed was signed for the destination chain (Monad, chainId 143) but executed on the source chain (Polygon, chainId 137) — confirmed via signDelegation logs showing domain.chainId: 143 for the Money Account delegation while the execute body used data.chainId: 137.

After the fix, the cross-chain source batch no longer contains the destination-signed override, so the InvalidEOASignature() revert no longer occurs.

References

Checklist

  • I've updated the test suite for new or updated code as appropriate
  • I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate
  • I've communicated my changes to consumers by updating changelogs for packages I've changed
  • I've introduced breaking changes in this PR and have prepared draft pull requests for clients and consumer packages to resolve them

Note

Medium Risk
Targets Relay submit batch assembly for payment overrides and cross-chain Money Account deposits; scope is narrow but touches delegation/signature-critical execute paths.

Overview
Fixes cross-chain Money Account deposits (e.g. Predict withdraw on Polygon → Money Account on Monad) failing Relay /execute with InvalidEOASignature() (0x3db6791c).

submitTransactions in relay-submit.ts no longer always prepends the Money Account payment override on the source-chain batch when paymentOverride is set. It only does so when currencyIn.chainId === currencyOut.chainId (isSameChainOverride). On cross-chain quotes, the override delegation belongs on the destination (already in the quote’s destination txs[]) and is EIP-712 signed for the destination chainId; prepending it on the source batch caused wrong-domain signature recovery. Cross-chain flows fall through to the existing post-quote path (prepend the original tx, e.g. Predict withdraw).

Tests align quote chains for same-chain override cases and assert cross-chain flows do not call getPaymentOverrideData. Changelog updated.

Reviewed by Cursor Bugbot for commit cb53dab. Bugbot is set up for automated code reviews on this repo. Configure here.

@OGPoyraz OGPoyraz requested review from a team as code owners July 9, 2026 13:53
@OGPoyraz OGPoyraz temporarily deployed to default-branch July 9, 2026 13:53 — with GitHub Actions Inactive
OGPoyraz added a commit that referenced this pull request Jul 9, 2026
OGPoyraz added a commit that referenced this pull request Jul 9, 2026
@matthewwalsh0 matthewwalsh0 requested a review from jpuri July 9, 2026 14:08
jpuri
jpuri previously approved these changes Jul 9, 2026
OGPoyraz added 2 commits July 10, 2026 13:14
Cross-chain flows (e.g. Predict withdraw on Polygon depositing to a Money
Account on Monad) carry the deposit in the Relay quote's destination txs[]
with a delegation signed for the destination chain. Prepending it onto the
source-chain execute batch made that delegation get redeemed on the source
chain, so the on-chain signature check recovered a wrong signer and reverted
with InvalidEOASignature() (0x3db6791c). Only prepend the override for
same-chain flows; cross-chain flows fall through to prepend the original tx.
@OGPoyraz OGPoyraz force-pushed the ogp/fix-money-account-cross-chain-invalid-eoa-signature branch from 0c9db1b to cb53dab Compare July 10, 2026 10:15
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