Skip to content

Commit

Permalink
chore(runway): cherry-pick feat: Update Polygon from MATIC to POL (
Browse files Browse the repository at this point in the history
…#10959)

- feat: Update Polygon from `MATIC` to `POL` (#10831)

## **Description**

Adds POL token and ticker to networks configs. See

[blog](https://polygon.technology/blog/save-the-date-matic-pol-migration-coming-september-4th-everything-you-need-to-know)
for more details

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/MMASSETS-362

## **Manual testing steps**

1. When adding Polygon Network from a network from, ticker should be POL
2. When switching to Polygon Mainnet, ticker should be POL (not MATIC)
3. Can import Polygon Network Token on Ethereum Mainnet
4. Can import Matic Network Token on Ethereum Mainnet (backward
compatibility)
Note, that both MATIC and POL erc20 tokens can already be imported on
Ethereum Mainnet, so this behavior should remain unchanged.

Additionally, when a user upgrades to this build, migration should run
and overwrite ticker from `MATIC` to `POL`

Install a previous build (checkout main and `yarn && yarn setup && yarn
watch` should be fine here) -> Polygon Network should show MATIC as
ticker. You may need to remove and re-add Polygon Network, as migrations
are incremental.
checkout to this branch, `yarn && yarn setup && yarn watch`, migration
051 should run -> Polygon Network should show POL as ticker, even when
default selected Network was MATIC in previous build.

## **Screenshots/Recordings**

<img width="453" alt="Screenshot 2024-08-27 at 11 11 31 PM"

src="https://github.com/user-attachments/assets/0486dc2b-5fcd-48c0-97db-508dc866c8b9">

## **Pre-merge author checklist**

- [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.

## **Pre-merge reviewer checklist**

- [ ] 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.
[58413e8](58413e8)

Co-authored-by: Nick Gambino <35090461+gambinish@users.noreply.github.com>
Co-authored-by: sethkfman <10342624+sethkfman@users.noreply.github.com>
  • Loading branch information
3 people authored Sep 4, 2024
1 parent 0982b16 commit ef6667a
Show file tree
Hide file tree
Showing 10 changed files with 402 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ describe('NetworkSwitcher View', () => {
).toMatchInlineSnapshot(`
[
[
"MATIC",
"POL",
],
]
`);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,13 @@ export class NetworkSettings extends PureComponent {
(network) => network.chainId === parseInt(chainId),
);

// This is a temporary hack to not include POL as a potential scam token while chainlist updates
// TODO: This can be safely removed once safeChainsList updates from MATIC to POL
if (parseInt(chainId) === 137) {
chainToMatch.nativeCurrency.symbol = 'POL';
chainToMatch.nativeCurrency.name = 'POL';
}

this.updateNetworkList(chainToMatch);
this.validateName(chainToMatch);
this.validateSymbol(chainToMatch);
Expand Down
3 changes: 2 additions & 1 deletion app/constants/network.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export const CHAINLIST_CURRENCY_SYMBOLS_MAP = {
OPTIMISM: 'ETH',
BNB: 'BNB',
MATIC: 'MATIC',
POL: 'POL',
FANTOM_OPERA: 'FTM',
BASE: 'ETH',
ARBITRUM: 'ETH',
Expand All @@ -73,7 +74,7 @@ export const CURRENCY_SYMBOL_BY_CHAIN_ID = {
[NETWORKS_CHAIN_ID.MAINNET]: CHAINLIST_CURRENCY_SYMBOLS_MAP.MAINNET,
[NETWORKS_CHAIN_ID.OPTIMISM]: CHAINLIST_CURRENCY_SYMBOLS_MAP.OPTIMISM,
[NETWORKS_CHAIN_ID.BSC]: CHAINLIST_CURRENCY_SYMBOLS_MAP.BNB,
[NETWORKS_CHAIN_ID.POLYGON]: CHAINLIST_CURRENCY_SYMBOLS_MAP.MATIC,
[NETWORKS_CHAIN_ID.POLYGON]: CHAINLIST_CURRENCY_SYMBOLS_MAP.POL,
[NETWORKS_CHAIN_ID.FANTOM]: CHAINLIST_CURRENCY_SYMBOLS_MAP.FANTOM_OPERA,
[NETWORKS_CHAIN_ID.BASE]: CHAINLIST_CURRENCY_SYMBOLS_MAP.BASE,
[NETWORKS_CHAIN_ID.ARBITRUM]: CHAINLIST_CURRENCY_SYMBOLS_MAP.ARBITRUM,
Expand Down
2 changes: 2 additions & 0 deletions app/images/image-icons.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import MATIC from './matic.png';
import POL from './pol.png';
import PALM from './palm.png';
import AETH from './arbitrum.png';
import OPTIMISM from './optimism.png';
Expand All @@ -14,6 +15,7 @@ import LINEA_MAINNET from './linea-mainnet-logo.png';
export default {
PALM,
MATIC,
POL,
OPTIMISM,
ONE,
FTM,
Expand Down
Binary file added app/images/pol.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
310 changes: 310 additions & 0 deletions app/store/migrations/051.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,310 @@
import migrate from './051';
import { merge } from 'lodash';
import initialRootState from '../../util/test/initial-root-state';
import { captureException } from '@sentry/react-native';
import { isObject } from '@metamask/utils';

jest.mock('@sentry/react-native', () => ({
captureException: jest.fn(),
}));
const mockedCaptureException = jest.mocked(captureException);

describe('Migration #51', () => {
beforeEach(() => {
jest.restoreAllMocks();
jest.resetAllMocks();
});

const oldState = {
engine: {
backgroundState: {
NetworkController: {
networkConfigurations: {
'network-1-uuid': {
chainId: '0x89',
ticker: 'MATIC',
},
'network-2-uuid': {
chainId: '0x1',
ticker: 'ETH',
},
},
providerConfig: {
chainId: '0x1',
ticker: 'ETH',
},
},
},
},
};

const expectedNewState = {
engine: {
backgroundState: {
NetworkController: {
networkConfigurations: {
'network-1-uuid': {
chainId: '0x89',
ticker: 'POL',
},
'network-2-uuid': {
chainId: '0x1',
ticker: 'ETH',
},
},
providerConfig: {
chainId: '0x1',
ticker: 'ETH',
},
},
},
},
};

const invalidStates = [
{
state: merge({}, initialRootState, {
engine: null,
}),
errorMessage:
"FATAL ERROR: Migration 51: Invalid engine state error: 'object'",
scenario: 'engine state is invalid',
},
{
state: merge({}, initialRootState, {
engine: {
backgroundState: null,
},
}),
errorMessage:
"FATAL ERROR: Migration 51: Invalid engine backgroundState error: 'object'",
scenario: 'backgroundState is invalid',
},
{
state: merge({}, initialRootState, {
engine: {
backgroundState: {
NetworkController: null,
},
},
}),
errorMessage:
"FATAL ERROR: Migration 51: Invalid NetworkController state error: 'object'",
scenario: 'NetworkController state is invalid',
},
{
state: merge({}, initialRootState, {
engine: {
backgroundState: {
NetworkController: {
networkConfigurations: null,
},
},
},
}),
errorMessage:
"FATAL ERROR: Migration 51: NetworkController networkConfigurations not found: 'null'",
scenario: 'networkConfigurations is null',
},
{
state: merge({}, initialRootState, {
engine: {
backgroundState: {
NetworkController: {
providerConfig: null,
},
},
},
}),
errorMessage:
"FATAL ERROR: Migration 51: providerConfig not found: 'null'",
scenario: 'providerConfig is null',
},
];

for (const { errorMessage, scenario, state } of invalidStates) {
it(`should capture exception if ${scenario}`, async () => {
const newState = await migrate(state);

expect(newState).toStrictEqual(state);
expect(mockedCaptureException).toHaveBeenCalledWith(expect.any(Error));
expect(mockedCaptureException.mock.calls[0][0].message).toBe(
errorMessage,
);
});
}

it('changes MATIC to POL for network with chainId 0x89', async () => {
const newState = await migrate(oldState);

expect(newState).toStrictEqual(expectedNewState);
});

it('does not change other networks', async () => {
const modifiedOldState = merge({}, oldState, {
engine: {
backgroundState: {
NetworkController: {
networkConfigurations: {
'network-3-uuid': {
chainId: '0x2a',
ticker: 'KOVAN',
},
},
},
},
},
});

const newState = (await migrate(
modifiedOldState,
)) as typeof modifiedOldState;

const kovanNetwork = Object.values(
newState.engine.backgroundState.NetworkController.networkConfigurations,
).find((network) => isObject(network) && network.ticker === 'KOVAN');

expect(kovanNetwork).toStrictEqual({
chainId: '0x2a',
ticker: 'KOVAN',
});
});

it("does not change ticker if network's chainId is 0x89 but ticker is not MATIC", async () => {
const modifiedOldState = merge({}, oldState, {
engine: {
backgroundState: {
NetworkController: {
networkConfigurations: {
'network-1-uuid': {
chainId: '0x89',
ticker: 'NOT_MATIC',
},
},
},
},
},
});

const newState = (await migrate(
modifiedOldState,
)) as typeof modifiedOldState;

const customNotMaticPolygon = Object.values(
newState.engine.backgroundState.NetworkController.networkConfigurations,
).find((network) => isObject(network) && network.ticker === 'NOT_MATIC');

expect(customNotMaticPolygon).toStrictEqual({
chainId: '0x89',
ticker: 'NOT_MATIC',
});
});

it("does not change ticker if network's chainId is 0x1 but ticker is MATIC", async () => {
const modifiedOldState = merge({}, oldState, {
engine: {
backgroundState: {
NetworkController: {
networkConfigurations: {
'network-1-uuid': {
chainId: '0x1',
ticker: 'MATIC',
},
},
},
},
},
});

const newState = (await migrate(
modifiedOldState,
)) as typeof modifiedOldState;

const customNotMaticPolygon = Object.values(
newState.engine.backgroundState.NetworkController.networkConfigurations,
).find((network) => isObject(network) && network.ticker === 'MATIC');

expect(customNotMaticPolygon).toStrictEqual({
chainId: '0x1',
ticker: 'MATIC',
});
});

it('changes providerConfig ticker to POL if chainId is 0x89 and ticker is MATIC', async () => {
const modifiedOldState = merge({}, oldState, {
engine: {
backgroundState: {
NetworkController: {
providerConfig: {
chainId: '0x89',
ticker: 'MATIC',
},
},
},
},
});

const expectedState = merge({}, expectedNewState, {
engine: {
backgroundState: {
NetworkController: {
providerConfig: {
chainId: '0x89',
ticker: 'POL',
},
},
},
},
});

const newState = await migrate(modifiedOldState);

expect(newState).toStrictEqual(expectedState);
});

it('does not change providerConfig ticker if chainId is 0x89 but ticker is not MATIC', async () => {
const modifiedOldState = merge({}, oldState, {
engine: {
backgroundState: {
NetworkController: {
providerConfig: {
chainId: '0x89',
ticker: 'NOT_MATIC',
},
},
},
},
});

const newState = (await migrate(
modifiedOldState,
)) as typeof modifiedOldState;

expect(
newState.engine.backgroundState.NetworkController.providerConfig.ticker,
).toBe('NOT_MATIC');
});

it('does not change providerConfig ticker if chainId is 0x1 but ticker is MATIC', async () => {
const modifiedOldState = merge({}, oldState, {
engine: {
backgroundState: {
NetworkController: {
providerConfig: {
chainId: '0x1',
ticker: 'MATIC',
},
},
},
},
});

const newState = (await migrate(
modifiedOldState,
)) as typeof modifiedOldState;

expect(
newState.engine.backgroundState.NetworkController.providerConfig.ticker,
).toBe('MATIC');
});
});
Loading

0 comments on commit ef6667a

Please sign in to comment.