Skip to content

Commit d4ee3dd

Browse files
chore(runway): cherry-pick fix:(cp-30138): skip blockaids validation for gas-included swaps cp-7.77.0 (#30150)
- fix(cp-30138): skip blockaids validation for gas-included swaps (#30140) <!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until this PR meets the canonical Definition of Ready For Review in `docs/readme/ready-for-review.md`. In short: the template must be materially complete (not just section titles present), all status checks must be currently passing, and the only expected follow-up commits must be reviewer-driven. --> ## **Description** Skip Blockaids validation for gas-included swaps <!-- Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions: 1. What is the reason for the change? 2. What is the improvement/solution? --> ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: null ## **Related issues** Fixes: #30138 ## **Manual testing steps** ```gherkin Feature: my feature name Scenario: user [verb for user action] Given [describe expected initial app state] When user [verb for user action] Then [describe expected outcome] ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** <!-- Every checklist item must be consciously assessed before marking this PR as "Ready for review". A checked box means you deliberately considered that responsibility, not that you literally performed every action listed. Unchecked boxes are ambiguous: they are not an implicit "N/A" and they are not a silent "skip". See `docs/readme/ready-for-review.md` for the full checklist semantics. --> - [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I've included tests if applicable - [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. #### Performance checks (if applicable) - [ ] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [ ] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [ ] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **Pre-merge reviewer checklist** <!-- Reviewer checklist items follow the same semantics as the author checklist: an unchecked box is ambiguous, a checked box means the reviewer consciously assessed that responsibility. See `docs/readme/ready-for-review.md`. --> - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes when Blockaid transaction validation runs for Solana bridge quotes, which could affect security checks if the `gasIncluded` signal is incorrect. Scope is small and covered by a targeted unit test. > > **Overview** > Updates `useBridgeQuoteData` to **skip Blockaid (`validateBridgeTx`) validation** for Solana/Solana→EVM quotes when the active quote is marked `gasIncluded`, clearing any prior `blockaidError` instead. > > Adds a unit test ensuring `validateBridgeTx` is not invoked for `gasIncluded` Solana quotes and that no Blockaid error is surfaced. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 8db17fe. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> [34d3395](34d3395) Co-authored-by: Remi ARQUEVAUX <r.arquevaux@gmail.com>
1 parent ca790dc commit d4ee3dd

2 files changed

Lines changed: 56 additions & 1 deletion

File tree

app/components/UI/Bridge/hooks/useBridgeQuoteData/index.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,12 @@ export const useBridgeQuoteData = ({
283283
);
284284

285285
const validateQuote = useCallback(async () => {
286-
if (!activeQuote || (!isSolanaSwap && !isSolanaToNonSolana)) {
286+
if (
287+
!activeQuote ||
288+
(!isSolanaSwap && !isSolanaToNonSolana) ||
289+
// Skip validation for gas-included quotes on Solana
290+
activeQuote?.quote?.gasIncluded === true
291+
) {
287292
lastValidatedQuoteRef.current = null;
288293
setBlockaidError(null);
289294
return;

app/components/UI/Bridge/hooks/useBridgeQuoteData/useBridgeQuoteData.test.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1100,6 +1100,56 @@ describe('useBridgeQuoteData', () => {
11001100
consoleErrorSpy.mockRestore();
11011101
});
11021102

1103+
it('skips validation for gas-included quotes on Solana', async () => {
1104+
const mockQuoteWithGasIncluded = {
1105+
...mockQuoteWithMetadata,
1106+
quote: {
1107+
...mockQuoteWithMetadata.quote,
1108+
gasIncluded: true,
1109+
},
1110+
};
1111+
1112+
(selectBridgeQuotes as unknown as jest.Mock).mockImplementation(() => ({
1113+
recommendedQuote: mockQuoteWithGasIncluded,
1114+
alternativeQuotes: [],
1115+
}));
1116+
1117+
const bridgeReducerOverrides = {
1118+
sourceToken: {
1119+
symbol: 'SOL',
1120+
chainId: SolScope.Mainnet,
1121+
address: '11111111111111111111111111111112',
1122+
decimals: 9,
1123+
},
1124+
destToken: {
1125+
symbol: 'USDC',
1126+
chainId: SolScope.Mainnet,
1127+
address:
1128+
'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp/token:EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
1129+
decimals: 6,
1130+
},
1131+
};
1132+
1133+
const testState = createBridgeTestState({
1134+
bridgeReducerOverrides,
1135+
});
1136+
1137+
const { result } = renderHookWithProvider(() => useBridgeQuoteData(), {
1138+
state: testState,
1139+
});
1140+
1141+
// Wait for the hook to stabilize
1142+
await waitFor(() => {
1143+
expect(result.current.activeQuote).toEqual(mockQuoteWithGasIncluded);
1144+
});
1145+
1146+
// Verify that validateBridgeTx was never called for gas-included quotes
1147+
expect(mockValidateBridgeTx).not.toHaveBeenCalled();
1148+
1149+
// Verify that no blockaid error is set
1150+
expect(result.current.blockaidError).toBe(null);
1151+
});
1152+
11031153
// Test validQuotes filtering
11041154
describe('validQuotes filtering', () => {
11051155
it('returns filtered validQuotes that match destination token', () => {

0 commit comments

Comments
 (0)