Skip to content
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

test: add coverage for Security Alerts API fallback (PPOM local) #28565

Open
wants to merge 24 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
86929f3
add e2e to test security alerts api fallback
vinistevam Nov 20, 2024
a6fcd29
create e2e for security alerts api
vinistevam Nov 20, 2024
c370510
Merge branch 'develop' into test/add-coverage-fallback-tests-security…
vinistevam Nov 20, 2024
fdd0fe5
fix pipeline
vinistevam Nov 21, 2024
d70034a
Merge branch 'develop' into test/add-coverage-fallback-tests-security…
vinistevam Nov 21, 2024
06c5c9c
Merge branch 'develop' into test/add-coverage-fallback-tests-security…
vinistevam Nov 25, 2024
5d6baf0
enable blockaid network support test
vinistevam Nov 25, 2024
d148442
Merge branch 'develop' into test/add-coverage-fallback-tests-security…
vinistevam Nov 27, 2024
b1716b6
Merge branch 'develop' into test/add-coverage-fallback-tests-security…
vinistevam Nov 27, 2024
5c57a03
fix e2e test
vinistevam Nov 27, 2024
2698c02
Merge branch 'main' into test/add-coverage-fallback-tests-security-al…
vinistevam Dec 4, 2024
5f18b49
Merge branch 'main' into test/add-coverage-fallback-tests-security-al…
vinistevam Dec 6, 2024
4db2f73
Merge branch 'main' into test/add-coverage-fallback-tests-security-al…
vinistevam Dec 12, 2024
08bc0d3
Merge branch 'main' into test/add-coverage-fallback-tests-security-al…
vinistevam Dec 19, 2024
4aaaa8b
use page object to improve security alerts api e2e tests
vinistevam Jan 7, 2025
2d4bbc5
Merge branch 'main' into test/add-coverage-fallback-tests-security-al…
vinistevam Jan 7, 2025
368489a
revert change
vinistevam Jan 7, 2025
1fae67a
re use security alert mock across the tests
vinistevam Jan 13, 2025
49b8d41
Merge branch 'main' into test/add-coverage-fallback-tests-security-al…
vinistevam Jan 13, 2025
1a1f646
Merge branch 'main' into test/add-coverage-fallback-tests-security-al…
vinistevam Jan 13, 2025
e9b1657
Merge branch 'main' into test/add-coverage-fallback-tests-security-al…
vinistevam Jan 14, 2025
53ce817
Merge branch 'main' into test/add-coverage-fallback-tests-security-al…
vinistevam Jan 16, 2025
34674fc
Merge branch 'main' into test/add-coverage-fallback-tests-security-al…
vinistevam Jan 17, 2025
9c53f60
Merge branch 'main' into test/add-coverage-fallback-tests-security-al…
vinistevam Jan 17, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions test/e2e/page-objects/flows/transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,35 @@ export const createDappTransaction = async (
},
]);
};

/**
* This function creates the steps required to send a transaction from the homepage to final confirmation without confirm.
*
* @param params - An object containing the parameters.
* @param params.driver - The webdriver instance.
* @param params.recipientAddress - The recipient address.
* @param params.amount - The amount of the asset to be sent in the transaction.
*/
export const createTransactionToAddress = async ({
driver,
recipientAddress,
amount,
}: {
driver: Driver;
recipientAddress: string;
amount: string;
}): Promise<void> => {
console.log(
`Start flow to send amount ${amount} to recipient ${recipientAddress} on home screen`,
);
// click send button on homepage to start flow
const homePage = new HomePage(driver);
await homePage.startSendFlow();

// user should land on send token screen to fill recipient and amount
const sendToPage = new SendTokenPage(driver);
await sendToPage.check_pageIsLoaded();
await sendToPage.fillRecipient(recipientAddress);
await sendToPage.fillAmount(amount);
await sendToPage.goToNextScreen();
};
34 changes: 34 additions & 0 deletions test/e2e/page-objects/pages/confirmations/redesign/confirmation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ class Confirmation {

private navigationTitle: RawLocator;

private loadingSpinner: RawLocator;

private bannerAlert: RawLocator;

constructor(driver: Driver) {
this.driver = driver;

Expand All @@ -38,6 +42,8 @@ class Confirmation {
this.previousPageButton =
'[data-testid="confirm-nav__previous-confirmation"]';
this.navigationTitle = '[data-testid="confirm-page-nav-position"]';
this.loadingSpinner = '.loading-indicator';
this.bannerAlert = '[data-testid="confirm-banner-alert"]';
}

async clickScrollToBottomButton() {
Expand Down Expand Up @@ -91,6 +97,34 @@ class Confirmation {
throw e;
}
}

async checkLoadingSpinner(): Promise<void> {
await this.driver.assertElementNotPresent(this.loadingSpinner);
}

async checkBannerAlertIsNotPresent(): Promise<void> {
await this.driver.assertElementNotPresent(this.bannerAlert);
}

async validateBannerAlert({
expectedTitle,
expectedDescription,
}: {
expectedTitle: string;
expectedDescription: string;
}): Promise<void> {
await this.driver.findElement(this.bannerAlert);

await this.driver.waitForSelector({
css: '.mm-text--body-lg-medium',
text: expectedTitle,
});

await this.driver.waitForSelector({
css: '.mm-text--body-md',
text: expectedDescription,
});
}
}

export default Confirmation;
18 changes: 18 additions & 0 deletions test/e2e/page-objects/pages/test-dapp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,12 @@ class TestDapp {

private sign721PermitResultV = '#sign721PermitResultV';

private maliciousApprovalButton = '#maliciousApprovalButton';

private maliciousSetApprovalForAllButton = '#maliciousSetApprovalForAll';

private maliciousTradeOrder = '#maliciousTradeOrder';

private readonly eip747ContractAddressInput = '#eip747ContractAddress';

private readonly transactionRequestMessage = {
Expand Down Expand Up @@ -697,6 +703,18 @@ class TestDapp {
await this.driver.clickElement(this.sign721PermitButton);
}

async clickMaliciousApproval() {
await this.driver.clickElement(this.maliciousApprovalButton);
}

async clickMaliciousSetApprovalForAll() {
await this.driver.clickElement(this.maliciousSetApprovalForAllButton);
}

async clickMaliciousTradeOrder() {
await this.driver.clickElement(this.maliciousTradeOrder);
}

/**
* Sign a message with the personal sign method.
*/
Expand Down
22 changes: 22 additions & 0 deletions test/e2e/tests/confirmations/signatures/signature-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ export enum SignatureType {
SignTypedData = '#signTypedData',
SIWE = '#siwe',
SIWE_BadDomain = '#siweBadDomain',
MaliciousApproval = '#maliciousApproval',
MaliciousSetApprovalForAll = '#maliciousSetApprovalForAll',
MaliciousTradeOrder = '#maliciousTradeOrder',
}

type AssertSignatureMetricsOptions = {
Expand Down Expand Up @@ -383,6 +386,16 @@ export async function openDappAndTriggerDeploy(driver: Driver) {
await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
}

export async function openDappAndClickButton(
driver: Driver,
buttonSelector: string,
) {
await unlockWallet(driver);
await testDapp.openTestDappPage({ url: DAPP_URL });
await driver.clickElement(buttonSelector);
await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
}

export async function triggerSignature(type: string) {
switch (type) {
case SignatureType.PersonalSign:
Expand All @@ -409,6 +422,15 @@ export async function triggerSignature(type: string) {
case SignatureType.NFTPermit:
await testDapp.clickERC721Permit();
break;
case SignatureType.MaliciousApproval:
await testDapp.clickMaliciousApproval();
break;
case SignatureType.MaliciousSetApprovalForAll:
await testDapp.clickMaliciousSetApprovalForAll();
break;
case SignatureType.MaliciousTradeOrder:
await testDapp.clickMaliciousTradeOrder();
break;
default:
throw new Error('Invalid signature type');
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const {
unlockWallet,
withFixtures,
} = require('../../helpers');
const { mockSecurityAlertsAPIFailed } = require('./utils');
const { mockServerJsonRpc } = require('./mocks/mock-server-json-rpc');

const bannerAlertSelector = '[data-testid="security-provider-banner-alert"]';
Expand All @@ -23,6 +24,7 @@ const CONTRACT_ADDRESS = {
};

async function mockInfura(mockServer) {
await mockSecurityAlertsAPIFailed(mockServer);
await mockServerJsonRpc(mockServer, [
['eth_blockNumber'],
[
Expand Down
174 changes: 140 additions & 34 deletions test/e2e/tests/ppom/ppom-blockaid-alert-erc20-transfer.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,57 +6,163 @@ const {
unlockWallet,
withFixtures,
} = require('../../helpers');
const { SECURITY_ALERTS_PROD_API_BASE_URL } = require('./constants');
const { mockSecurityAlertsAPIFailed } = require('./utils');
const { mockServerJsonRpc } = require('./mocks/mock-server-json-rpc');

const SELECTED_ADDRESS = '0x5cfe73b6021e818b776b421b1c4db2474086a7e1';
const selectedAddress = '0x5cfe73b6021e818b776b421b1c4db2474086a7e1';
const selectedAddressWithoutPrefix = '5cfe73b6021e818b776b421b1c4db2474086a7e1';

const CONTRACT_ADDRESS_USDC = '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48';
const CONTRACT_ADDRESS = {
BalanceChecker: '0xb1f8e55c7f64d203c1400b9d8555d050f94adf39',
FiatTokenV2_1: '0xa2327a938febf5fec13bacfb16ae10ecbc4cbdcf',
OffChainOracle: '0x52cbe0f49ccdd4dc6e9c13bab024eabd2842045b',
USDC: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
};

async function mockInfura(mockServer) {
await mockSecurityAlertsAPIFailed(mockServer);

await mockServerJsonRpc(mockServer, [
['eth_blockNumber'],
['eth_call'],
[
'eth_call',
{
methodResultVariant: 'balanceChecker',
params: [{ to: CONTRACT_ADDRESS.BalanceChecker }],
},
{
result: '0x3635c9adc5dea00000',
},
],
[
'eth_call',
{
methodResultVariant: 'offchainOracle',
params: [{ to: CONTRACT_ADDRESS.OffChainOracle }],
},
],
[
'eth_call',
{
methodResultVariant: 'balance',
params: [
{
accessList: [],
data: `0x70a08231000000000000000000000000${selectedAddressWithoutPrefix}`,
to: CONTRACT_ADDRESS.USDC,
},
],
},
{
result: '0x3635c9adc5dea00000',
},
],
['eth_estimateGas'],
['eth_feeHistory'],
['eth_gasPrice'],
['eth_getBalance'],
['eth_getBlockByNumber'],
['eth_getCode'],
[
'eth_getCode',
{
methodResultVariant: 'USDC',
params: [CONTRACT_ADDRESS.USDC],
},
],
['eth_getTransactionCount'],
]);
}

const maliciousTransferAlert = {
block: 1,
result_type: 'Malicious',
reason: 'transfer_farming',
description:
'Transfer to 0x5fbdb2315678afecb367f032d93f642f64180aa3, classification: A known malicious address is involved in the transaction',
features: ['A known malicious address is involved in the transaction'],
};

async function mockRequest(server, response) {
await server
.forPost(`${SECURITY_ALERTS_PROD_API_BASE_URL}/validate/0x1`)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we already have these tests implemented for security alerts api also.

await mockServer
.forPost()
.withJsonBodyIncluding({
method: 'eth_sendTransaction',
params: [
{
from: SELECTED_ADDRESS,
data: '0xa9059cbb0000000000000000000000005fbdb2315678afecb367f032d93f642f64180aa30000000000000000000000000000000000000000000000000000000000000064',
to: CONTRACT_ADDRESS_USDC,
value: '0x0',
},
],
method: 'debug_traceCall',
params: [{ accessList: [], data: '0x00000000' }],
})
.thenJson(201, response);
}

async function mockInfuraWithMaliciousResponses(mockServer) {
await mockInfura(mockServer);
.thenCallback(async (req) => {
return {
statusCode: 200,
json: {
jsonrpc: '2.0',
id: (await req.body.getJson()).id,
result: {
calls: [
{
error: 'execution reverted',
from: CONTRACT_ADDRESS.USDC,
gas: '0x1d55c2c7',
gasUsed: '0xf0',
input: '0x00000000',
to: CONTRACT_ADDRESS.FiatTokenV2_1,
type: 'DELEGATECALL',
value: '0x1',
},
],
error: 'execution reverted',
from: '0x0000000000000000000000000000000000000000',
gas: '0x1dcd6500',
gasUsed: '0x6f79',
input: '0x00000000',
to: CONTRACT_ADDRESS.USDC,
type: 'CALL',
value: '0x1',
},
},
};
});

await mockRequest(mockServer, maliciousTransferAlert);
await mockServer
.forPost()
.withJsonBodyIncluding({
method: 'debug_traceCall',
params: [{ from: selectedAddress }],
})
.thenCallback(async (req) => {
const mockFakePhishingAddress =
'5fbdb2315678afecb367f032d93f642f64180aa3';

return {
statusCode: 200,
json: {
jsonrpc: '2.0',
id: (await req.body.getJson()).id,
result: {
calls: [
{
from: CONTRACT_ADDRESS.USDC,
gas: '0x2923d',
gasUsed: '0x4cac',
input: `0xa9059cbb000000000000000000000000${mockFakePhishingAddress}0000000000000000000000000000000000000000000000000000000000000064`,
logs: [
{
address: CONTRACT_ADDRESS.USDC,
data: '0x0000000000000000000000000000000000000000000000000000000000000064',
topics: [
'0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef',
`0x000000000000000000000000${selectedAddressWithoutPrefix}`,
`0x000000000000000000000000${mockFakePhishingAddress}`,
],
},
],
output:
'0x0000000000000000000000000000000000000000000000000000000000000001',
to: CONTRACT_ADDRESS.FiatTokenV2_1,
type: 'DELEGATECALL',
value: '0x1',
},
],
from: selectedAddress,
gas: '0x30d40',
gasUsed: '0xbd69',
input: `0xa9059cbb000000000000000000000000${mockFakePhishingAddress}0000000000000000000000000000000000000000000000000000000000000064`,
output:
'0x0000000000000000000000000000000000000000000000000000000000000001',
to: CONTRACT_ADDRESS.USDC,
type: 'CALL',
value: '0x1',
},
},
};
});
}

describe('PPOM Blockaid Alert - Malicious ERC20 Transfer @no-mmi', function () {
Expand All @@ -76,7 +182,7 @@ describe('PPOM Blockaid Alert - Malicious ERC20 Transfer @no-mmi', function () {
})
.build(),
defaultGanacheOptions,
testSpecificMock: mockInfuraWithMaliciousResponses,
testSpecificMock: mockInfura,
title: this.test.fullTitle(),
},

Expand Down
Loading
Loading