Skip to content

Commit

Permalink
Merge pull request #1383 from blockscout/fe-1371
Browse files Browse the repository at this point in the history
soliditycheck report
  • Loading branch information
isstuev authored Dec 2, 2023
2 parents 3d3b251 + b0ddaca commit e2dbfa4
Show file tree
Hide file tree
Showing 24 changed files with 363 additions and 6 deletions.
1 change: 1 addition & 0 deletions configs/app/ui/views/address.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const hiddenViews = (() => {
const config = Object.freeze({
identiconType,
hiddenViews,
solidityscanEnabled: getEnvValue('NEXT_PUBLIC_VIEWS_CONTRACT_SOLIDITYSCAN_ENABLED') === 'true',
});

export default config;
1 change: 1 addition & 0 deletions configs/envs/.env.eth_goerli
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ NEXT_PUBLIC_VISUALIZE_API_HOST=https://visualizer.services.blockscout.com
NEXT_PUBLIC_CONTRACT_INFO_API_HOST=https://contracts-info.services.blockscout.com
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST=https://admin-rs.services.blockscout.com
NEXT_PUBLIC_WEB3_WALLETS=['token_pocket','metamask']
NEXT_PUBLIC_VIEWS_CONTRACT_SOLIDITYSCAN_ENABLED='true'

#meta
NEXT_PUBLIC_OG_IMAGE_URL=https://github.com/blockscout/frontend-configs/blob/main/configs/og-images/eth-goerli.png?raw=true
1 change: 1 addition & 0 deletions deploy/tools/envs-validator/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,7 @@ const schema = yup
.transform(replaceQuotes)
.json()
.of(yup.string<AddressViewId>().oneOf(ADDRESS_VIEWS_IDS)),
NEXT_PUBLIC_VIEWS_CONTRACT_SOLIDITYSCAN_ENABLED: yup.boolean(),
NEXT_PUBLIC_VIEWS_TX_HIDDEN_FIELDS: yup
.array()
.transform(replaceQuotes)
Expand Down
5 changes: 3 additions & 2 deletions deploy/values/review/values.yaml.gotmpl
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ frontend:
NEXT_PUBLIC_FEATURED_NETWORKS: https://raw.githubusercontent.com/blockscout/frontend-configs/dev/configs/featured-networks/eth-goerli.json
NEXT_PUBLIC_NETWORK_LOGO: https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-logos/goerli.svg
NEXT_PUBLIC_NETWORK_ICON: https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-icons/goerli.svg
NEXT_PUBLIC_API_HOST: etc.blockscout.com
NEXT_PUBLIC_STATS_API_HOST: https://stats-etc.k8s.blockscout.com/
NEXT_PUBLIC_API_HOST: eth-goerli.blockscout.com
NEXT_PUBLIC_STATS_API_HOST: https://stats-goerli.k8s-dev.blockscout.com/
NEXT_PUBLIC_VISUALIZE_API_HOST: http://visualizer-svc.visualizer-testing.svc.cluster.local/
NEXT_PUBLIC_CONTRACT_INFO_API_HOST: https://contracts-info-test.k8s-dev.blockscout.com
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST: https://admin-rs-test.k8s-dev.blockscout.com
Expand All @@ -67,6 +67,7 @@ frontend:
NEXT_PUBLIC_WEB3_WALLETS: "['token_pocket','coinbase','metamask']"
NEXT_PUBLIC_VIEWS_ADDRESS_IDENTICON_TYPE: gradient_avatar
NEXT_PUBLIC_VIEWS_ADDRESS_HIDDEN_VIEWS: "['top_accounts']"
NEXT_PUBLIC_VIEWS_CONTRACT_SOLIDITYSCAN_ENABLED: true
NEXT_PUBLIC_VIEWS_TX_HIDDEN_FIELDS: "['value','fee_currency','gas_price','gas_fees','burnt_fees']"
NEXT_PUBLIC_VIEWS_TX_ADDITIONAL_FIELDS: "['fee_per_gas']"
NEXT_PUBLIC_USE_NEXT_JS_PROXY: true
Expand Down
1 change: 1 addition & 0 deletions docs/ENVS.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ Settings for meta tags and OG tags
| --- | --- | --- | --- | --- | --- |
| NEXT_PUBLIC_VIEWS_ADDRESS_IDENTICON_TYPE | `"github" \| "jazzicon" \| "gradient_avatar" \| "blockie"` | Style of address identicon appearance. Choose between [GitHub](https://github.blog/2013-08-14-identicons/), [Metamask Jazzicon](https://metamask.github.io/jazzicon/), [Gradient Avatar](https://github.com/varld/gradient-avatar) and [Ethereum Blocky](https://mycryptohq.github.io/ethereum-blockies-base64/) | - | `jazzicon` | `gradient_avatar` |
| NEXT_PUBLIC_VIEWS_ADDRESS_HIDDEN_VIEWS | `Array<AddressViewId>` | Address views that should not be displayed. See below the list of the possible id values. | - | - | `'["top_accounts"]'` |
| NEXT_PUBLIC_VIEWS_CONTRACT_SOLIDITYSCAN_ENABLED | `boolean` | Set to `true` if SolidityScan reports are supperted | - | - | `true` |

##### Address views list
| Id | Description |
Expand Down
4 changes: 4 additions & 0 deletions icons/score/score-not-ok.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions icons/score/score-ok.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 6 additions & 1 deletion lib/api/resources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import type { AddressesResponse } from 'types/api/addresses';
import type { BlocksResponse, BlockTransactionsResponse, Block, BlockFilters, BlockWithdrawalsResponse } from 'types/api/block';
import type { ChartMarketResponse, ChartTransactionResponse } from 'types/api/charts';
import type { BackendVersionConfig } from 'types/api/configs';
import type { SmartContract, SmartContractReadMethod, SmartContractWriteMethod, SmartContractVerificationConfig } from 'types/api/contract';
import type { SmartContract, SmartContractReadMethod, SmartContractWriteMethod, SmartContractVerificationConfig, SolidityscanReport } from 'types/api/contract';
import type { VerifiedContractsResponse, VerifiedContractsFilters, VerifiedContractsCounters } from 'types/api/contracts';
import type { IndexingStatus } from 'types/api/indexingStatus';
import type { InternalTransactionsResponse } from 'types/api/internalTransaction';
Expand Down Expand Up @@ -343,6 +343,10 @@ export const RESOURCES = {
path: '/api/v2/smart-contracts/:hash/verification/via/:method',
pathParams: [ 'hash' as const, 'method' as const ],
},
contract_solidityscan_report: {
path: '/api/v2/smart-contracts/:hash/solidityscan-report',
pathParams: [ 'hash' as const ],
},

verified_contracts: {
path: '/api/v2/smart-contracts',
Expand Down Expand Up @@ -659,6 +663,7 @@ Q extends 'contract_methods_read' ? Array<SmartContractReadMethod> :
Q extends 'contract_methods_read_proxy' ? Array<SmartContractReadMethod> :
Q extends 'contract_methods_write' ? Array<SmartContractWriteMethod> :
Q extends 'contract_methods_write_proxy' ? Array<SmartContractWriteMethod> :
Q extends 'contract_solidityscan_report' ? SolidityscanReport :
Q extends 'verified_contracts' ? VerifiedContractsResponse :
Q extends 'verified_contracts_counters' ? VerifiedContractsCounters :
Q extends 'visualize_sol2uml' ? VisualizedContract :
Expand Down
65 changes: 65 additions & 0 deletions mocks/contract/solidityscanReport.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
export const solidityscanReportAverage = {
scan_report: {
scan_status: 'scan_done',
scan_summary: {
issue_severity_distribution: {
critical: 0,
gas: 1,
high: 0,
informational: 0,
low: 2,
medium: 0,
},
lines_analyzed_count: 18,
scan_time_taken: 1,
score: '3.61',
score_v2: '72.22',
threat_score: '94.74',
},
scanner_reference_url: 'https://solidityscan.com/quickscan/0xc1EF7811FF2ebFB74F80ed7423f2AdAA37454be2/blockscout/eth-goerli?ref=blockscout',
},
};

export const solidityscanReportGreat = {
scan_report: {
scan_status: 'scan_done',
scan_summary: {
issue_severity_distribution: {
critical: 0,
gas: 0,
high: 0,
informational: 0,
low: 0,
medium: 0,
},
lines_analyzed_count: 18,
scan_time_taken: 1,
score: '3.61',
score_v2: '100',
threat_score: '94.74',
},
scanner_reference_url: 'https://solidityscan.com/quickscan/0xc1EF7811FF2ebFB74F80ed7423f2AdAA37454be2/blockscout/eth-goerli?ref=blockscout',
},
};

export const solidityscanReportLow = {
scan_report: {
scan_status: 'scan_done',
scan_summary: {
issue_severity_distribution: {
critical: 2,
gas: 1,
high: 3,
informational: 0,
low: 2,
medium: 10,
},
lines_analyzed_count: 18,
scan_time_taken: 1,
score: '3.61',
score_v2: '22.22',
threat_score: '94.74',
},
scanner_reference_url: 'https://solidityscan.com/quickscan/0xc1EF7811FF2ebFB74F80ed7423f2AdAA37454be2/blockscout/eth-goerli?ref=blockscout',
},
};
24 changes: 23 additions & 1 deletion stubs/contract.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { SmartContract } from 'types/api/contract';
import type { SmartContract, SolidityscanReport } from 'types/api/contract';
import type { VerifiedContract } from 'types/api/contracts';

import { ADDRESS_PARAMS } from './addressParams';
Expand Down Expand Up @@ -53,3 +53,25 @@ export const VERIFIED_CONTRACT_INFO: VerifiedContract = {
tx_count: 565058,
verified_at: '2023-04-10T13:16:33.884921Z',
};

export const SOLIDITYSCAN_REPORT: SolidityscanReport = {
scan_report: {
scan_status: 'scan_done',
scan_summary: {
issue_severity_distribution: {
critical: 0,
gas: 1,
high: 0,
informational: 0,
low: 2,
medium: 0,
},
lines_analyzed_count: 18,
scan_time_taken: 1,
score: '3.61',
score_v2: '72.22',
threat_score: '94.74',
},
scanner_reference_url: 'https://solidityscan.com/quickscan/0xc1EF7811FF2ebFB74F80ed7423f2AdAA37454be2/blockscout/eth-goerli?ref=blockscout',
},
};
22 changes: 22 additions & 0 deletions types/api/contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,3 +156,25 @@ export interface SmartContractVerificationError {
constructor_arguments?: Array<string>;
name?: Array<string>;
}

export type SolidityscanReport = {
scan_report: {
scan_status: string;
scan_summary: {
issue_severity_distribution: {
critical: number;
gas: number;
high: number;
informational: number;
low: number;
medium: number;
};
lines_analyzed_count: number;
scan_time_taken: number;
score: string;
score_v2: string;
threat_score: string;
};
scanner_reference_url: string;
};
}
68 changes: 68 additions & 0 deletions ui/address/SolidityscanReport.pw.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { test, expect } from '@playwright/experimental-ct-react';
import React from 'react';

import * as solidityscanReportMock from 'mocks/contract/solidityscanReport';
import TestApp from 'playwright/TestApp';
import buildApiUrl from 'playwright/utils/buildApiUrl';

import SolidityscanReport from './SolidityscanReport';

const addressHash = 'hash';
const REPORT_API_URL = buildApiUrl('contract_solidityscan_report', { hash: addressHash });

test('average report +@dark-mode +@mobile', async({ mount, page }) => {
await page.route(REPORT_API_URL, (route) => route.fulfill({
status: 200,
body: JSON.stringify(solidityscanReportMock.solidityscanReportAverage),
}));

const component = await mount(
<TestApp>
<SolidityscanReport hash={ addressHash }/>
</TestApp>,
);

await expect(page).toHaveScreenshot({ clip: { x: 0, y: 0, width: 100, height: 50 } });

await component.getByLabel('SolidityScan score').click();

await expect(page).toHaveScreenshot({ clip: { x: 0, y: 0, width: 400, height: 500 } });
});

test('great report', async({ mount, page }) => {
await page.route(REPORT_API_URL, (route) => route.fulfill({
status: 200,
body: JSON.stringify(solidityscanReportMock.solidityscanReportGreat),
}));

const component = await mount(
<TestApp>
<SolidityscanReport hash={ addressHash }/>
</TestApp>,
);

await expect(page).toHaveScreenshot({ clip: { x: 0, y: 0, width: 100, height: 50 } });

await component.getByLabel('SolidityScan score').click();

await expect(page).toHaveScreenshot({ clip: { x: 0, y: 0, width: 400, height: 500 } });
});

test('low report', async({ mount, page }) => {
await page.route(REPORT_API_URL, (route) => route.fulfill({
status: 200,
body: JSON.stringify(solidityscanReportMock.solidityscanReportLow),
}));

const component = await mount(
<TestApp>
<SolidityscanReport hash={ addressHash }/>
</TestApp>,
);

await expect(page).toHaveScreenshot({ clip: { x: 0, y: 0, width: 100, height: 50 } });

await component.getByLabel('SolidityScan score').click();

await expect(page).toHaveScreenshot({ clip: { x: 0, y: 0, width: 400, height: 500 } });
});
Loading

0 comments on commit e2dbfa4

Please sign in to comment.