Skip to content

Commit 9840957

Browse files
runway-github[bot]metamaskbotCal-Lwachuneiabretonc7s
authored
chore(runway): cherry-pick fix(bridge): normalize Polygon native token addresses cp-7.75.0 (#29445)
- fix(bridge): normalize Polygon native token addresses cp-7.75.0 (#29440) <!-- 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** <!-- 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? --> Polygon native POL can enter the bridge/swaps flow from token details with Polygon's native token alias address (`0x0000000000000000000000000000000000001010`). Bridge state expects native EVM assets to use the swaps native zero address, so the alias can break downstream balance, gas, and quote matching behavior. This change normalizes source and destination bridge tokens as they are stored in the bridge Redux slice. That keeps bridge state canonical for all callers of `setSourceToken` and `setDestToken`, including the POL token details swap entry point. ## **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: Fixed a bug that prevented quotes when swapping from POL token details ## **Related issues** Issue: #29231 ## **Manual testing steps** ```gherkin Feature: POL swap quotes from token details Scenario: User starts a swap from the POL asset details screen Given the user has POL on Polygon Mainnet And the user opens POL from the wallet token list When the user taps Swap from the POL token details screen And the user enters a valid POL amount Then the swap flow fetches and displays available quotes ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** N/A ### **After** N/A ## **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. --> - [x] 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). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] 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) - [x] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [x] 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 - [x] 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. <!-- Generated with the help of the pr-description AI skill --> [b84864b](b84864b) --------- Co-authored-by: metamaskbot <metamaskbot@users.noreply.github.com> Co-authored-by: Cal Leung <cal.leung@consensys.net> Co-authored-by: MetaMask Bot <37885440+metamaskbot@users.noreply.github.com> Co-authored-by: Pedro Pablo Aste Kompen <wachunei@gmail.com> Co-authored-by: abretonc7s <107169956+abretonc7s@users.noreply.github.com> Co-authored-by: Matthew Grainger <46547583+Matt561@users.noreply.github.com> Co-authored-by: Satyajeet Kolhapure <77279246+satyajeetkolhapure@users.noreply.github.com> Co-authored-by: Jean-Baptiste Blanc <jb.blanc@consensys.net> Co-authored-by: Brian August Nguyen <brianacnguyen@gmail.com> Co-authored-by: George Weiler <georgejweiler@gmail.com> Co-authored-by: Caainã Jeronimo <caainaje@gmail.com> Co-authored-by: Luis Taniça <matallui@gmail.com> Co-authored-by: VGR <VanGulckRik@gmail.com> Co-authored-by: George Marshall <george.marshall@consensys.net> Co-authored-by: AxelGes <34173844+AxelGes@users.noreply.github.com> Co-authored-by: Patryk Łucka <patryk.lucka@gmail.com> Co-authored-by: Gustavo Antunes <17601467+gantunesr@users.noreply.github.com> Co-authored-by: Juanmi <95381763+juanmigdr@users.noreply.github.com> Co-authored-by: infiniteflower <139582705+infiniteflower@users.noreply.github.com> Co-authored-by: Davide Brocchetto <davide.brocchetto@consensys.net> Co-authored-by: Curtis David <Curtis.David7@gmail.com> Co-authored-by: Nick Gambino <35090461+gambinish@users.noreply.github.com> Co-authored-by: Monte Lai <monte.lai@consensys.net> Co-authored-by: Jyoti Puri <jyotipuri@gmail.com> Co-authored-by: Bruno Nascimento <brunonascimentodev@gmail.com> Co-authored-by: Maarten Zuidhoorn <maarten@zuidhoorn.com> Co-authored-by: cmd-ob <ola.bale@consensys.net> Co-authored-by: João <castrofjoao@gmail.com> Co-authored-by: sophieqgu <sophieqgu@gmail.com> Co-authored-by: Alejandro Garcia Anglada <aganglada@gmail.com> Co-authored-by: Mathieu Artu <mathieu.artu@consensys.net> Co-authored-by: sophieqgu <37032128+sophieqgu@users.noreply.github.com> Co-authored-by: Charly Chevalier <charlyy.chevalier@gmail.com> Co-authored-by: Bryan Fullam <bryan.fullam@consensys.net> Co-authored-by: Bryan Fullam <8902170+bfullam@users.noreply.github.com> Co-authored-by: SteP-n-s <stylianos.panagakos@consensys.net> Co-authored-by: António Regadas <antonio.regadas@consensys.net> Co-authored-by: Edouard Bougon <15703023+EdouardBougon@users.noreply.github.com> Co-authored-by: Alex Donesky <adonesky@gmail.com> Co-authored-by: Baptiste Marchand <75846779+baptiste-marchand@users.noreply.github.com> Co-authored-by: Fabio Bozzo <fabio.bozzo@gmail.com> Co-authored-by: Owen Craston <owen.craston@consensys.net> Co-authored-by: Pavel Dvorkin <pavel.dvorkin@consensys.net> Co-authored-by: Kevin Bluer <kevin@bluer.com> Co-authored-by: Vince Howard <vincenguyenhoward@gmail.com> Co-authored-by: Nicholas Gambino <nicholas.gambino@consensys.net> Co-authored-by: Nicholas Smith <nick.smith@consensys.net> Co-authored-by: sethkfman <10342624+sethkfman@users.noreply.github.com> Co-authored-by: Nodonisko <suchydan@gmail.com> Co-authored-by: Tamas <soostamas.hu@gmail.com> Co-authored-by: ffmcgee <51971598+ffmcgee725@users.noreply.github.com> Co-authored-by: Alexandre Chappaz <alex@achappaz.fr> Co-authored-by: Harika <153644847+hjetpoluru@users.noreply.github.com> Co-authored-by: Erik Nilsson <eriks@mail.se> Co-authored-by: runway-github[bot] <73448015+runway-github[bot]@users.noreply.github.com> Co-authored-by: Wei Sun <wei.sun@consensys.net> Co-authored-by: Patryk Łucka <5708018+PatrykLucka@users.noreply.github.com> Co-authored-by: Salim TOUBAL <salim.toubal@outlook.com> Co-authored-by: OGPoyraz <omergoktugpoyraz@gmail.com> Co-authored-by: Bernardo Garces Chapero <bernardo.chapero@consensys.net> Co-authored-by: Christian Montoya <christian.montoya@consensys.net> Co-authored-by: Vinicius Stevam <45455812+vinistevam@users.noreply.github.com> Co-authored-by: sethkfman <Seth.Kaufman@consensys.net> Co-authored-by: Gauthier Petetin <gauthierpetetin@hotmail.com> Co-authored-by: Ganesh Suresh Patra <ganesh.patra@consensys.net> Co-authored-by: João Loureiro <175489935+joaoloureirop@users.noreply.github.com> Co-authored-by: ieow <4881057+ieow@users.noreply.github.com> Co-authored-by: tommasini <46944231+tommasini@users.noreply.github.com> Co-authored-by: Xiaoming Wang <7315988+dawnseeker8@users.noreply.github.com> Co-authored-by: himanshuchawla009 <himanshuchawla2014@gmail.com> Co-authored-by: Gaurav Goel <grvgoel19@gmail.com> Co-authored-by: Elliot Winkler <elliot.winkler@gmail.com> Co-authored-by: Frederik Bolding <frederik.bolding@gmail.com> Co-authored-by: Matthew Walsh <matthew.walsh@consensys.net> Co-authored-by: Charly Chevalier <charly.chevalier@consensys.net> Co-authored-by: Micaela <100321200+micaelae@users.noreply.github.com> Co-authored-by: salimtb <salim.toubal@consensys.net> Co-authored-by: Micaela Estabillo <micaela.estabillo@consensys.net> Co-authored-by: jake-perkins <128608287+jake-perkins@users.noreply.github.com> Co-authored-by: Laurel <153323700+i18nlaurel@users.noreply.github.com> Co-authored-by: Kylan Hurt <6249205+smilingkylan@users.noreply.github.com> Co-authored-by: sethkfman <setk.kaufman@consensys.net> Co-authored-by: Prithpal Sooriya <prithpal.sooriya@consensys.net> Co-authored-by: Aslau Mario-Daniel <marioaslau@gmail.com> Co-authored-by: sahar-fehri <sahar.fehri@consensys.net> Co-authored-by: Alexey Kureev <a.g.kureev@gmail.com> Co-authored-by: Matt D. <85914066+geositta@users.noreply.github.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Co-authored-by: saustrie-consensys <shane.austrie@consensys.net> Co-authored-by: Matthew Grainger <matthew.grainger@consensys.net> Co-authored-by: Darius Costolas <dariuscostolas@yahoo.com> Co-authored-by: Darius Costolas <10818970+meltingice1337@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: wachunei <1024246+wachunei@users.noreply.github.com> Co-authored-by: Tyler Chong <tyler.chong@consensys.net> Co-authored-by: chloeYue <chloe.gao@consensys.net> Co-authored-by: geositta <matthew.denton@consensys.net> Co-authored-by: Michal Szorad <michal.szorad@consensys.net> Co-authored-by: Javier Garcia Vera <javier.vera@consensys.net> Co-authored-by: Samir Mehta <12882259+samir-acle@users.noreply.github.com> Co-authored-by: chloeYue <105063779+chloeYue@users.noreply.github.com> Co-authored-by: sleepytanya <104780023+sleepytanya@users.noreply.github.com> Co-authored-by: Remi ARQUEVAUX <r.arquevaux@gmail.com> Co-authored-by: metamaskbotv2[bot] <214045046+metamaskbotv2[bot]@users.noreply.github.com>
1 parent b1b48f0 commit 9840957

2 files changed

Lines changed: 46 additions & 3 deletions

File tree

app/core/redux/slices/bridge/index.test.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import reducer, {
88
setSlippage,
99
setBridgeViewMode,
1010
selectBridgeViewMode,
11+
setSourceToken,
1112
setDestToken,
1213
setIsDestTokenManuallySet,
1314
selectIsDestTokenManuallySet,
@@ -54,6 +55,15 @@ describe('bridge slice', () => {
5455
balanceFiat: '100',
5556
};
5657

58+
const polygonNativeToken: BridgeToken = {
59+
address: '0x0000000000000000000000000000000000001010',
60+
symbol: 'POL',
61+
decimals: 18,
62+
image: '',
63+
chainId: '0x89' as Hex,
64+
name: 'POL',
65+
};
66+
5767
describe('initial state', () => {
5868
it('has correct initial state', () => {
5969
expect(initialState).toEqual({
@@ -187,6 +197,14 @@ describe('bridge slice', () => {
187197
});
188198

189199
describe('setDestToken', () => {
200+
it('normalizes Polygon native token address', () => {
201+
const state = reducer(initialState, setDestToken(polygonNativeToken));
202+
203+
expect(state.destToken?.address).toBe(
204+
'0x0000000000000000000000000000000000000000',
205+
);
206+
});
207+
190208
it('sets the destination token and updates selectedDestChainId', () => {
191209
const action = setDestToken(mockDestToken);
192210
const state = reducer(initialState, action);
@@ -208,6 +226,16 @@ describe('bridge slice', () => {
208226
});
209227
});
210228

229+
describe('setSourceToken', () => {
230+
it('normalizes Polygon native token address', () => {
231+
const state = reducer(initialState, setSourceToken(polygonNativeToken));
232+
233+
expect(state.sourceToken?.address).toBe(
234+
'0x0000000000000000000000000000000000000000',
235+
);
236+
});
237+
});
238+
211239
describe('setIsDestTokenManuallySet', () => {
212240
it('sets the flag to true', () => {
213241
const action = setIsDestTokenManuallySet(true);

app/core/redux/slices/bridge/index.ts

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import { selectCanSignTransactions } from '../../../../selectors/accountsControl
4040
import { selectBasicFunctionalityEnabled } from '../../../../selectors/settings';
4141
import { hasMinimumRequiredVersion } from './utils/hasMinimumRequiredVersion';
4242
import { Bip44TokensForDefaultPairs } from '../../../../components/UI/Bridge/constants/default-swap-dest-tokens';
43+
import { normalizeTokenAddress } from '../../../../components/UI/Bridge/utils/tokenUtils';
4344

4445
export const selectBridgeControllerState = (state: RootState) =>
4546
state.engine.backgroundState?.BridgeController;
@@ -112,6 +113,19 @@ export const initialState: BridgeState = {
112113

113114
const name = 'bridge';
114115

116+
const normalizeBridgeToken = <T extends BridgeToken | undefined>(
117+
token: T,
118+
): T => {
119+
if (!token) {
120+
return token;
121+
}
122+
123+
const normalizedAddress = normalizeTokenAddress(token.address, token.chainId);
124+
return normalizedAddress === token.address
125+
? token
126+
: ({ ...token, address: normalizedAddress } as T);
127+
};
128+
115129
export const setSourceTokenExchangeRate = createAsyncThunk(
116130
'bridge/setSourceTokenExchangeRate',
117131
getTokenExchangeRate,
@@ -160,12 +174,13 @@ const slice = createSlice({
160174
...initialState,
161175
}),
162176
setSourceToken: (state, action: PayloadAction<BridgeToken | undefined>) => {
163-
state.sourceToken = action.payload;
177+
state.sourceToken = normalizeBridgeToken(action.payload);
164178
},
165179
setDestToken: (state, action: PayloadAction<BridgeToken>) => {
166-
state.destToken = action.payload;
180+
const destToken = normalizeBridgeToken(action.payload);
181+
state.destToken = destToken;
167182
// Update selectedDestChainId to match the destination token's chain ID
168-
state.selectedDestChainId = action.payload.chainId;
183+
state.selectedDestChainId = destToken.chainId;
169184
},
170185
/**
171186
* Sets whether the destination token was manually selected by the user.

0 commit comments

Comments
 (0)