-
Notifications
You must be signed in to change notification settings - Fork 428
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: restrict safe pass safe app access for ofac blocked addresses #4066
Changes from all commits
4dd18e4
05ac797
4a9818d
5480f2f
75a926c
da03cde
c3a6485
de491bf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
import { renderHook } from '@/tests/test-utils' | ||
import { useSanctionedAddress } from '../useSanctionedAddress' | ||
import useSafeAddress from '../useSafeAddress' | ||
import useWallet from '../wallets/useWallet' | ||
import { faker } from '@faker-js/faker' | ||
import { connectedWalletBuilder } from '@/tests/builders/wallet' | ||
import * as ofac from '@/store/ofac' | ||
import { skipToken } from '@reduxjs/toolkit/query' | ||
|
||
jest.mock('@/hooks/useSafeAddress') | ||
jest.mock('@/hooks/wallets/useWallet') | ||
|
||
describe('useSanctionedAddress', () => { | ||
const mockUseSafeAddress = useSafeAddress as jest.MockedFunction<typeof useSafeAddress> | ||
const mockUseWallet = useWallet as jest.MockedFunction<typeof useWallet> | ||
|
||
it('should return undefined without safeAddress and wallet', () => { | ||
const { result } = renderHook(() => useSanctionedAddress()) | ||
expect(result.current).toBeUndefined() | ||
}) | ||
|
||
it('should return undefined if neither safeAddress nor wallet are sanctioned', () => { | ||
mockUseSafeAddress.mockReturnValue(faker.finance.ethereumAddress()) | ||
mockUseWallet.mockReturnValue(connectedWalletBuilder().build()) | ||
|
||
jest.spyOn(ofac, 'useGetIsSanctionedQuery').mockReturnValue({ data: false, refetch: jest.fn() }) | ||
|
||
const { result } = renderHook(() => useSanctionedAddress()) | ||
expect(result.current).toBeUndefined() | ||
}) | ||
|
||
it('should return safeAddress if it is sanctioned', () => { | ||
const mockSafeAddress = faker.finance.ethereumAddress() | ||
const mockWalletAddress = faker.finance.ethereumAddress() | ||
mockUseSafeAddress.mockReturnValue(mockSafeAddress) | ||
mockUseWallet.mockReturnValue(connectedWalletBuilder().with({ address: mockWalletAddress }).build()) | ||
|
||
jest | ||
.spyOn(ofac, 'useGetIsSanctionedQuery') | ||
.mockImplementation((address) => ({ data: address === mockSafeAddress, refetch: jest.fn() })) | ||
|
||
const { result } = renderHook(() => useSanctionedAddress()) | ||
expect(result.current).toEqual(mockSafeAddress) | ||
}) | ||
|
||
it('should return walletAddress if it is sanctioned', () => { | ||
const mockSafeAddress = faker.finance.ethereumAddress() | ||
const mockWalletAddress = faker.finance.ethereumAddress() | ||
mockUseSafeAddress.mockReturnValue(mockSafeAddress) | ||
mockUseWallet.mockReturnValue(connectedWalletBuilder().with({ address: mockWalletAddress }).build()) | ||
|
||
jest | ||
.spyOn(ofac, 'useGetIsSanctionedQuery') | ||
.mockImplementation((address) => ({ data: address === mockWalletAddress, refetch: jest.fn() })) | ||
|
||
const { result } = renderHook(() => useSanctionedAddress()) | ||
expect(result.current).toEqual(mockWalletAddress) | ||
}) | ||
|
||
it('should return safeAddress if both are sanctioned', () => { | ||
const mockSafeAddress = faker.finance.ethereumAddress() | ||
const mockWalletAddress = faker.finance.ethereumAddress() | ||
mockUseSafeAddress.mockReturnValue(mockSafeAddress) | ||
mockUseWallet.mockReturnValue(connectedWalletBuilder().with({ address: mockWalletAddress }).build()) | ||
|
||
jest.spyOn(ofac, 'useGetIsSanctionedQuery').mockImplementation((arg) => { | ||
if (arg === skipToken) { | ||
return { data: undefined, refetch: jest.fn() } | ||
} | ||
return { data: true, refetch: jest.fn() } | ||
}) | ||
const { result } = renderHook(() => useSanctionedAddress()) | ||
expect(result.current).toEqual(mockSafeAddress) | ||
}) | ||
|
||
it('should skip sanction check if isRestricted is false', () => { | ||
const mockSafeAddress = faker.finance.ethereumAddress() | ||
const mockWalletAddress = faker.finance.ethereumAddress() | ||
mockUseSafeAddress.mockReturnValue(mockSafeAddress) | ||
mockUseWallet.mockReturnValue(connectedWalletBuilder().with({ address: mockWalletAddress }).build()) | ||
|
||
jest.spyOn(ofac, 'useGetIsSanctionedQuery').mockImplementation((arg) => { | ||
if (arg === skipToken) { | ||
return { data: undefined, refetch: jest.fn() } | ||
} | ||
return { data: true, refetch: jest.fn() } | ||
}) | ||
|
||
const { result } = renderHook(() => useSanctionedAddress(false)) | ||
expect(result.current).toBeUndefined() | ||
}) | ||
}) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import { useGetIsSanctionedQuery } from '@/store/ofac' | ||
import useSafeAddress from './useSafeAddress' | ||
import useWallet from './wallets/useWallet' | ||
import { skipToken } from '@reduxjs/toolkit/query/react' | ||
|
||
/** | ||
* Checks if the opened Safe or the connected wallet are sanctioned and returns the sanctioned address. | ||
* @param isRestricted the check is only performed if isRestricted is true. | ||
* @returns address of sanctioned wallet or Safe | ||
*/ | ||
export const useSanctionedAddress = (isRestricted = true) => { | ||
const wallet = useWallet() | ||
const safeAddress = useSafeAddress() | ||
|
||
const { data: isWalletSanctioned } = useGetIsSanctionedQuery(isRestricted && wallet ? wallet.address : skipToken) | ||
|
||
const { data: isSafeSanctioned } = useGetIsSanctionedQuery( | ||
isRestricted && safeAddress !== '' ? safeAddress : skipToken, | ||
) | ||
|
||
if (isSafeSanctioned) { | ||
return safeAddress | ||
} | ||
if (isWalletSanctioned) { | ||
return wallet?.address | ||
} | ||
Comment on lines
+21
to
+26
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that is not true. The error seems to be transformed and returned in the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is expected to either return a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we remove the data assignment on error then inside the
|
||
|
||
return undefined | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we if not avoid hardcode then at least make it a constant?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we use the constant
SAFE_PASS_URL
here?