Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/transaction-pay-controller/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Bump `@metamask/assets-controller` from `^10.1.0` to `^10.2.0` ([#9450](https://github.com/MetaMask/core/pull/9450))
- Bump `@metamask/assets-controllers` from `^109.3.1` to `^109.4.0` ([#9450](https://github.com/MetaMask/core/pull/9450))

### Fixed

- Fix cross-chain Money Account deposits (e.g. Predict withdraw to a Money Account) reverting with `InvalidEOASignature()` (`0x3db6791c`) by only prepending the payment override onto the source Relay execute batch for same-chain flows ([#9449](https://github.com/MetaMask/core/pull/9449))

## [24.0.0]

### Added
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -966,6 +966,12 @@ describe('Relay Submit Utils', () => {
[ORIGINAL_TRANSACTION_ID_MOCK]: TRANSACTION_DATA_MOCK,
},
});

// The payment override is only prepended onto the source execute batch
// for same-chain flows, so align the quote's source and destination
// chains for these override-prepend assertions.
request.quotes[0].original.details.currencyOut.currency.chainId =
request.quotes[0].original.details.currencyIn.currency.chainId;
});

it('prepends override tx params to submit batch', async () => {
Expand Down Expand Up @@ -999,6 +1005,20 @@ describe('Relay Submit Utils', () => {
expect(getPaymentOverrideDataMock).not.toHaveBeenCalled();
});

it('does not prepend override for cross-chain flows', async () => {
request.quotes[0].request.paymentOverride =
PaymentOverride.MoneyAccount;
request.quotes[0].original.details.currencyIn.currency.chainId = 137;
request.quotes[0].original.details.currencyOut.currency.chainId = 143;
getPaymentOverrideDataMock.mockResolvedValue({
calls: [PAYMENT_OVERRIDE_TX_MOCK],
});

await submitRelayQuotes(request);

expect(getPaymentOverrideDataMock).not.toHaveBeenCalled();
});

it('does not prepend when callback returns empty array', async () => {
request.quotes[0].request.paymentOverride =
PaymentOverride.MoneyAccount;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -430,9 +430,20 @@ async function submitTransactions(
quote.request.from.toLowerCase() !==
(transaction.txParams.from as Hex).toLowerCase();

// Only prepend the payment override onto the source execute batch for
// same-chain flows. For cross-chain flows (e.g. Predict withdraw on Polygon
// depositing to a Money Account on Monad) the deposit is carried in the relay
// quote's destination txs[] and runs on the destination chain; its delegation
// is signed for the destination chainId, so redeeming it inside the
// source-chain batch recovers a wrong signer and reverts. In that case we
// fall through and prepend the original (e.g. Predict withdraw) tx instead.
const isSameChainOverride =
quote.original.details.currencyIn.currency.chainId ===
quote.original.details.currencyOut.currency.chainId;

let allParams = normalizedParams;

if (quote.request.paymentOverride) {
if (quote.request.paymentOverride && isSameChainOverride) {
const { transactionData } = messenger.call(
'TransactionPayController:getState',
);
Expand Down