Skip to content

Commit

Permalink
fix(multichain): Filter out non-Celo tokens in legacy token selectors (
Browse files Browse the repository at this point in the history
…#4236)

### Description

Fixes an issue where non-Celo tokens can possibly be returned by legacy
selectors, leaking multi-chain features in unintended places. [Slack
thread with
context.](https://valora-app.slack.com/archives/C02KBT0DAHJ/p1695763773794809)

### Test plan

Unit tested

### Related issues

N/A

### Backwards compatibility

Yes.
  • Loading branch information
jophish authored Sep 28, 2023
1 parent 9bae467 commit d888060
Show file tree
Hide file tree
Showing 24 changed files with 616 additions and 93 deletions.
40 changes: 34 additions & 6 deletions src/analytics/ValoraAnalytics.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,16 @@ import { Statsig } from 'statsig-react-native'
import { getMockStoreData } from 'test/utils'
import {
mockCeloAddress,
mockCeloTokenId,
mockCeurAddress,
mockCeurTokenId,
mockCusdAddress,
mockCusdTokenId,
mockPositions,
mockTestTokenAddress,
mockTestTokenTokenId,
} from 'test/values'
import { NetworkId } from 'src/transactions/types'

jest.mock('@segment/analytics-react-native')
jest.mock('@segment/analytics-react-native-plugin-adjust')
Expand All @@ -27,6 +32,17 @@ jest.mock('src/config', () => ({
}))
jest.mock('statsig-react-native')
jest.mock('src/statsig')
jest.mock('src/web3/networkConfig', () => {
const originalModule = jest.requireActual('src/web3/networkConfig')
return {
...originalModule,
__esModule: true,
default: {
...originalModule.default,
defaultNetworkId: 'celo-alfajores',
},
}
})

const mockDeviceId = 'abc-def-123' // mocked in __mocks__/react-native-device-info.ts (but importing from that file causes weird errors)
const expectedSessionId = '205ac8350460ad427e35658006b409bbb0ee86c22c57648fe69f359c2da648'
Expand All @@ -38,45 +54,57 @@ const mockStore = jest.mocked(store)
const state = getMockStoreData({
tokens: {
tokenBalances: {
[mockCusdAddress]: {
[mockCusdTokenId]: {
address: mockCusdAddress,
tokenId: mockCusdTokenId,
networkId: NetworkId['celo-alfajores'],
symbol: 'cUSD',
priceUsd: '1',
balance: '10',
priceFetchedAt: Date.now(),
isCoreToken: true,
},
[mockCeurAddress]: {
[mockCeurTokenId]: {
address: mockCeurAddress,
tokenId: mockCeurTokenId,
networkId: NetworkId['celo-alfajores'],
symbol: 'cEUR',
priceUsd: '1.2',
balance: '20',
priceFetchedAt: Date.now(),
isCoreToken: true,
},
[mockCeloAddress]: {
[mockCeloTokenId]: {
address: mockCeloAddress,
tokenId: mockCeloTokenId,
networkId: NetworkId['celo-alfajores'],
symbol: 'CELO',
priceUsd: '5',
balance: '0',
priceFetchedAt: Date.now(),
isCoreToken: true,
},
[mockTestTokenAddress]: {
[mockTestTokenTokenId]: {
address: mockTestTokenAddress,
tokenId: mockTestTokenTokenId,
networkId: NetworkId['celo-alfajores'],
symbol: 'TT',
balance: '10',
priceFetchedAt: Date.now(),
},
'0xMOO': {
'celo-alfajores:0xMOO': {
address: '0xMOO',
tokenId: 'celo-alfajores:0xMOO',
networkId: NetworkId['celo-alfajores'],
symbol: 'MOO',
priceUsd: '4',
balance: '0',
priceFetchedAt: Date.now(),
},
'0xUBE': {
'celo-alfajores:0xUBE': {
address: '0xUBE',
tokenId: 'celo-alfajores:0xUBE',
networkId: NetworkId['celo-alfajores'],
symbol: 'UBE',
priceUsd: '2',
balance: '1',
Expand Down
69 changes: 56 additions & 13 deletions src/components/TokenBalance.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,26 @@ import { getFeatureGate } from 'src/statsig'
import { ONE_DAY_IN_MILLIS } from 'src/utils/time'
import { createMockStore, getElementText } from 'test/utils'
import { mockPositions, mockTokenBalances } from 'test/values'
import { NetworkId } from 'src/transactions/types'

jest.mock('src/statsig')

jest.mock('src/web3/networkConfig', () => {
const originalModule = jest.requireActual('src/web3/networkConfig')
return {
__esModule: true,
...originalModule,
default: {
...originalModule.default,
networkToNetworkId: {
celo: 'celo-alfajores',
ethereum: 'ethereuim-sepolia',
},
defaultNetworkId: 'celo-alfajores',
},
}
})

const defaultStore = {
tokens: {
tokenBalances: mockTokenBalances,
Expand All @@ -40,22 +57,28 @@ describe('FiatExchangeTokenBalance and HomeTokenBalance', () => {
...defaultStore,
tokens: {
tokenBalances: {
'0x00400FcbF0816bebB94654259de7273f4A05c762': {
'celo-alfajores:0x00400FcbF0816bebB94654259de7273f4A05c762': {
priceUsd: '0.1',
address: '0x00400FcbF0816bebB94654259de7273f4A05c762',
tokenId: 'celo-alfajores:0x00400FcbF0816bebB94654259de7273f4A05c762',
networkId: NetworkId['celo-alfajores'],
symbol: 'POOF',
balance: '5',
priceFetchedAt: Date.now(),
},
'0x10c892A6EC43a53E45D0B916B4b7D383B1b78C0F': {
'celo-alfajores:0x10c892A6EC43a53E45D0B916B4b7D383B1b78C0F': {
priceUsd: '1.16',
address: '0x10c892A6EC43a53E45D0B916B4b7D383B1b78C0F',
tokenId: 'celo-alfajores:0x10c892A6EC43a53E45D0B916B4b7D383B1b78C0F',
networkId: NetworkId['celo-alfajores'],
symbol: 'cEUR',
balance: '7',
priceFetchedAt: Date.now(),
},
'0x048F47d358EC521a6cf384461d674750a3cB58C8': {
'celo-alfajores:0x048F47d358EC521a6cf384461d674750a3cB58C8': {
address: '0x048F47d358EC521a6cf384461d674750a3cB58C8',
tokenId: 'celo-alfajores:0x048F47d358EC521a6cf384461d674750a3cB58C8',
networkId: NetworkId['celo-alfajores'],
symbol: 'TT',
balance: '10',
priceFetchedAt: Date.now(),
Expand Down Expand Up @@ -83,16 +106,20 @@ describe('FiatExchangeTokenBalance and HomeTokenBalance', () => {
tokens: {
// FiatExchangeTokenBalance requires 2 balances to display the View Balances button
tokenBalances: {
'0x00400FcbF0816bebB94654259de7273f4A05c762': {
'celo-alfajores:0x00400FcbF0816bebB94654259de7273f4A05c762': {
priceUsd: '0.1',
address: '0x00400FcbF0816bebB94654259de7273f4A05c762',
tokenId: 'celo-alfajores:0x00400FcbF0816bebB94654259de7273f4A05c762',
networkId: NetworkId['celo-alfajores'],
symbol: 'POOF',
balance: '5',
priceFetchedAt: Date.now(),
},
'0x10c892A6EC43a53E45D0B916B4b7D383B1b78C0F': {
'celo-alfajores:0x10c892A6EC43a53E45D0B916B4b7D383B1b78C0F': {
priceUsd: '1.16',
address: '0x10c892A6EC43a53E45D0B916B4b7D383B1b78C0F',
tokenId: 'celo-alfajores:0x10c892A6EC43a53E45D0B916B4b7D383B1b78C0F',
networkId: NetworkId['celo-alfajores'],
symbol: 'cEUR',
balance: '7',
priceFetchedAt: Date.now(),
Expand Down Expand Up @@ -199,15 +226,19 @@ describe('FiatExchangeTokenBalance and HomeTokenBalance', () => {
...defaultStore,
tokens: {
tokenBalances: {
'0x10c892A6EC43a53E45D0B916B4b7D383B1b78C0F': {
'celo-alfajores:0x10c892A6EC43a53E45D0B916B4b7D383B1b78C0F': {
priceUsd: '1.16',
address: '0x10c892A6EC43a53E45D0B916B4b7D383B1b78C0F',
tokenId: 'celo-alfajores:0x10c892A6EC43a53E45D0B916B4b7D383B1b78C0F',
networkId: NetworkId['celo-alfajores'],
symbol: 'cEUR',
balance: '7',
priceFetchedAt: Date.now(),
},
'0x048F47d358EC521a6cf384461d674750a3cB58C8': {
'celo-alfajores:0x048F47d358EC521a6cf384461d674750a3cB58C8': {
address: '0x048F47d358EC521a6cf384461d674750a3cB58C8',
tokenId: 'celo-alfajores:0x048F47d358EC521a6cf384461d674750a3cB58C8',
networkId: NetworkId['celo-alfajores'],
symbol: 'TT',
balance: '10',
},
Expand Down Expand Up @@ -236,15 +267,19 @@ describe('FiatExchangeTokenBalance and HomeTokenBalance', () => {
...defaultStore,
tokens: {
tokenBalances: {
'0x10c892A6EC43a53E45D0B916B4b7D383B1b78C0F': {
'celo-alfajores:0x10c892A6EC43a53E45D0B916B4b7D383B1b78C0F': {
priceUsd: '1.16',
address: '0x10c892A6EC43a53E45D0B916B4b7D383B1b78C0F',
tokenId: 'celo-alfajores:0x10c892A6EC43a53E45D0B916B4b7D383B1b78C0F',
networkId: NetworkId['celo-alfajores'],
symbol: 'cEUR',
balance: '7',
priceFetchedAt: Date.now(),
},
'0x048F47d358EC521a6cf384461d674750a3cB58C8': {
'celo-alfajores:0x048F47d358EC521a6cf384461d674750a3cB58C8': {
address: '0x048F47d358EC521a6cf384461d674750a3cB58C8',
tokenId: 'celo-alfajores:0x048F47d358EC521a6cf384461d674750a3cB58C8',
networkId: NetworkId['celo-alfajores'],
symbol: 'TT',
balance: '10',
},
Expand Down Expand Up @@ -312,17 +347,21 @@ describe('FiatExchangeTokenBalance and HomeTokenBalance', () => {
const store = createMockStore({
tokens: {
tokenBalances: {
'0xcelo': {
'celo-alfajores:0xcelo': {
name: 'Celo',
address: '0xcelo',
tokenId: 'celo-alfajores:0xcelo',
networkId: NetworkId['celo-alfajores'],
symbol: 'CELO',
balance: '1',
priceUsd: '0.90',
priceFetchedAt: Date.now() - ONE_DAY_IN_MILLIS,
isCoreToken: true,
},
'0x048F47d358EC521a6cf384461d674750a3cB58C8': {
'celo-alfajores:0x048F47d358EC521a6cf384461d674750a3cB58C8': {
address: '0x048F47d358EC521a6cf384461d674750a3cB58C8',
tokenId: 'celo-alfajores:0x048F47d358EC521a6cf384461d674750a3cB58C8',
networkId: NetworkId['celo-alfajores'],
symbol: 'TT',
balance: '10',
},
Expand Down Expand Up @@ -350,17 +389,21 @@ describe('FiatExchangeTokenBalance and HomeTokenBalance', () => {
const store = createMockStore({
tokens: {
tokenBalances: {
'0xcelo': {
'celo-alfajores:0xcelo': {
name: 'Celo',
address: '0xcelo',
tokenId: 'celo-alfajores:0xcelo',
networkId: NetworkId['celo-alfajores'],
symbol: 'CELO',
balance: '1',
priceUsd: '0.90',
priceFetchedAt: Date.now() - ONE_DAY_IN_MILLIS,
isCoreToken: true,
},
'0x048F47d358EC521a6cf384461d674750a3cB58C8': {
'celo-alfajores:0x048F47d358EC521a6cf384461d674750a3cB58C8': {
address: '0x048F47d358EC521a6cf384461d674750a3cB58C8',
tokenId: 'celo-alfajores:0x048F47d358EC521a6cf384461d674750a3cB58C8',
networkId: NetworkId['celo-alfajores'],
symbol: 'TT',
balance: '10',
},
Expand Down
24 changes: 21 additions & 3 deletions src/components/TokenDisplay.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,22 @@ import { RootState } from 'src/redux/reducers'
import { getFeatureGate } from 'src/statsig'
import { Currency } from 'src/utils/currencies'
import { createMockStore, getElementText, RecursivePartial } from 'test/utils'
import { NetworkId } from 'src/transactions/types'

jest.mock('src/statsig', () => ({
getFeatureGate: jest.fn(() => false),
}))
jest.mock('src/web3/networkConfig', () => {
const originalModule = jest.requireActual('src/web3/networkConfig')
return {
...originalModule,
__esModule: true,
default: {
...originalModule.default,
defaultNetworkId: 'celo-alfajores',
},
}
})

describe('TokenDisplay', () => {
function store(storeOverrides?: RecursivePartial<RootState>) {
Expand All @@ -24,22 +36,28 @@ describe('TokenDisplay', () => {
},
tokens: {
tokenBalances: {
['0xusd']: {
['celo-alfajores:0xusd']: {
address: '0xusd',
tokenId: 'celo-alfajores:0xusd',
networkId: NetworkId['celo-alfajores'],
symbol: 'cUSD',
balance: '50',
priceUsd: '1',
priceFetchedAt: Date.now(),
},
['0xeur']: {
['celo-alfajores:0xeur']: {
address: '0xeur',
tokenId: 'celo-alfajores:0xeur',
networkId: NetworkId['celo-alfajores'],
symbol: 'cEUR',
balance: '50',
priceUsd: '1.2',
priceFetchedAt: Date.now(),
},
['0xcelo']: {
['celo-alfajores:0xcelo']: {
address: '0xcelo',
tokenId: 'celo-alfajores:0xcelo',
networkId: NetworkId['celo-alfajores'],
symbol: 'CELO',
balance: '10',
priceUsd: '5',
Expand Down
28 changes: 24 additions & 4 deletions src/dapps/DappShortcutsRewards.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,28 @@ import { navigate } from 'src/navigator/NavigationService'
import { Screens } from 'src/navigator/Screens'
import { Position } from 'src/positions/types'
import { createMockStore } from 'test/utils'
import { mockCusdAddress, mockPositions, mockShortcuts } from 'test/values'
import { mockCusdAddress, mockCusdTokenId, mockPositions, mockShortcuts } from 'test/values'
import { NetworkId } from 'src/transactions/types'

jest.mock('src/statsig', () => ({
getFeatureGate: jest.fn(() => true),
}))
jest.mock('src/web3/networkConfig', () => {
const originalModule = jest.requireActual('src/web3/networkConfig')
return {
...originalModule,
__esModule: true,
default: {
...originalModule.default,
defaultNetworkId: 'celo-alfajores',
},
}
})

const mockCeloAddress = '0x471ece3750da237f93b8e339c536989b8978a438'
const mockUbeAddress = '0x00be915b9dcf56a3cbe739d9b9c202ca692409ec'
const mockCeloTokenId = `celo-alfajores:${mockCeloAddress}`
const mockUbeTokenId = `celo-alfajores:${mockUbeAddress}`

const getPositionWithClaimableBalance = (balance?: string): Position => ({
type: 'contract-position',
Expand Down Expand Up @@ -89,23 +103,29 @@ const defaultState = {
},
tokens: {
tokenBalances: {
[mockCeloAddress]: {
[mockCeloTokenId]: {
address: mockCeloAddress,
tokenId: mockCeloTokenId,
networkId: NetworkId['celo-alfajores'],
symbol: 'CELO',
priceUsd: '0.6959536890241361', // matches data in mockPositions
balance: '10',
priceFetchedAt: Date.now(),
isCoreToken: true,
},
[mockUbeAddress]: {
[mockUbeTokenId]: {
address: mockUbeAddress,
tokenId: mockUbeTokenId,
networkId: NetworkId['celo-alfajores'],
symbol: 'UBE',
priceUsd: '0.00904673476946796903', // matches data in mockPositions
balance: '10',
priceFetchedAt: Date.now(),
},
[mockCusdAddress]: {
[mockCusdTokenId]: {
address: mockCusdAddress,
tokenId: mockCusdTokenId,
networkId: NetworkId['celo-alfajores'],
symbol: 'cUSD',
priceUsd: '1',
balance: '10',
Expand Down
Loading

0 comments on commit d888060

Please sign in to comment.