From 4e5dfa7408d5778425db9369941157fc5ebeec9a Mon Sep 17 00:00:00 2001 From: Matthew Walsh Date: Tue, 23 Jun 2026 16:53:25 +0100 Subject: [PATCH] fix: require 7702 support for sponsored gas --- .../hooks/delegation-7702-publish.test.ts | 28 +++++++++++++++++++ .../hooks/delegation-7702-publish.ts | 16 +++++++---- 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/app/util/transactions/hooks/delegation-7702-publish.test.ts b/app/util/transactions/hooks/delegation-7702-publish.test.ts index 197d4dec2ae4..36c5a52ce338 100644 --- a/app/util/transactions/hooks/delegation-7702-publish.test.ts +++ b/app/util/transactions/hooks/delegation-7702-publish.test.ts @@ -223,6 +223,34 @@ describe('Delegation 7702 Publish Hook', () => { }); }); + it('throws when atomic batch is not supported for a gas-sponsored transaction', async () => { + await expect( + hookClass.getHook()( + { + ...TRANSACTION_META_MOCK, + isGasFeeSponsored: true, + }, + SIGNED_TX_MOCK, + ), + ).rejects.toThrow( + 'Gas Station 7702: Chain must support EIP-7702 for sponsored or gas included transaction', + ); + }); + + it('throws when atomic batch is not supported for a gas-included transaction', async () => { + await expect( + hookClass.getHook()( + { + ...TRANSACTION_META_MOCK, + isGasFeeIncluded: true, + }, + SIGNED_TX_MOCK, + ), + ).rejects.toThrow( + 'Gas Station 7702: Chain must support EIP-7702 for sponsored or gas included transaction', + ); + }); + it('no selected gas fee token', async () => { isAtomicBatchSupportedMock.mockResolvedValueOnce([ { diff --git a/app/util/transactions/hooks/delegation-7702-publish.ts b/app/util/transactions/hooks/delegation-7702-publish.ts index b75e24532cc0..79ca21d04c8e 100644 --- a/app/util/transactions/hooks/delegation-7702-publish.ts +++ b/app/util/transactions/hooks/delegation-7702-publish.ts @@ -120,6 +120,8 @@ export class Delegation7702PublishHook { transactionMeta; const { from } = txParams; + const isGaslessBridge = Boolean(transactionMeta.isGasFeeIncluded); + const isSponsored = Boolean(transactionMeta.isGasFeeSponsored); const atomicBatchSupport = await this.#isAtomicBatchSupported({ address: from as Hex, @@ -137,16 +139,19 @@ export class Delegation7702PublishHook { if (!isChainSupported) { log('Skipping as EIP-7702 is not supported', { from, chainId }); + + if (isGaslessBridge || isSponsored) { + throw new Error( + 'Chain must support EIP-7702 for sponsored or gas included transaction', + ); + } + return EMPTY_RESULT; } const { delegationAddress, upgradeContractAddress } = atomicBatchChainSupport; - const isGaslessBridge = transactionMeta.isGasFeeIncluded; - - const isSponsored = Boolean(transactionMeta.isGasFeeSponsored); - if ( (!selectedGasFeeToken || !gasFeeTokens?.length) && !isGaslessBridge && @@ -173,8 +178,7 @@ export class Delegation7702PublishHook { parseInt(isE2ETest(chainId) ? SEPOLIA_CHAIN_ID : chainId, 16), ); const delegationManagerAddress = delegationEnvironment.DelegationManager; - const includeTransfer = - !isGaslessBridge && !transactionMeta.isGasFeeSponsored; + const includeTransfer = !isGaslessBridge && !isSponsored; if (includeTransfer && (!gasFeeToken || gasFeeToken === undefined)) { throw new Error('Gas fee token not found');