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

Dapps security score #1709

Merged
merged 51 commits into from
Apr 1, 2024
Merged
Show file tree
Hide file tree
Changes from 49 commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
f4f434d
add new view with scores for marketplace
maxaleks Mar 8, 2024
95a8347
make solidityscan report component reusable
maxaleks Mar 8, 2024
37f6688
add security score component, integrate real data
maxaleks Mar 13, 2024
89b91fc
create contract list modal
maxaleks Mar 13, 2024
006e24a
fix contract list modal for mobiles
maxaleks Mar 14, 2024
4240c80
update link buttons, add tooltip, update modal title
maxaleks Mar 14, 2024
c4ba8c9
add beta label
maxaleks Mar 14, 2024
63448a8
fix search input margin on mobile
maxaleks Mar 14, 2024
50db854
move MoreInfo button to separate component
maxaleks Mar 14, 2024
8c974a4
move components
maxaleks Mar 14, 2024
b77d033
add reports to apps inside hook
maxaleks Mar 14, 2024
aaaedf9
rework AppSecurityReport
maxaleks Mar 14, 2024
b98ffd5
add security score to marketplace app modal
maxaleks Mar 14, 2024
17dced8
use ids instead of network names
maxaleks Mar 15, 2024
c02cd33
replace type
maxaleks Mar 15, 2024
3a8ab33
Update values.yaml.gotmpl
maxaleks Mar 15, 2024
93a8f4b
add new env to docs and validator
maxaleks Mar 15, 2024
21b4dc6
add marketplace config url for review deployment
maxaleks Mar 15, 2024
e2c79df
display apps without security score
maxaleks Mar 18, 2024
4d3ce52
add security score to dapp page
maxaleks Mar 18, 2024
00ed752
change format of security reports data
maxaleks Mar 18, 2024
5680028
add skeletons
maxaleks Mar 19, 2024
a304f4b
fix dapp page top bar for mobiles
maxaleks Mar 19, 2024
01b0db6
fix star icon size
maxaleks Mar 19, 2024
35f732f
wrap new components in A/B testing
maxaleks Mar 19, 2024
6ecb1e2
rework view switch to use url param and add skeleton
maxaleks Mar 19, 2024
1877b00
update no data component
maxaleks Mar 20, 2024
5899f90
fix wording for 1 item
maxaleks Mar 20, 2024
132c340
update empty search result
maxaleks Mar 20, 2024
8de2ada
turn off experiment by default
maxaleks Mar 20, 2024
f96072d
update search input placeholder
maxaleks Mar 20, 2024
d4ce12a
replace label with svg
maxaleks Mar 21, 2024
b89c3a1
rename url param
maxaleks Mar 21, 2024
3bff33f
add mixpanel events
maxaleks Mar 21, 2024
a43c517
Update .env.main
maxaleks Mar 21, 2024
f97c377
Merge branch 'main' into dapps-security-score
maxaleks Mar 21, 2024
b3cc05e
fix warnings
maxaleks Mar 21, 2024
4205089
update star icon
maxaleks Mar 21, 2024
dbd3ec5
fix star icon color
maxaleks Mar 21, 2024
e27f4e2
update screenshots
maxaleks Mar 21, 2024
6aee84d
hide new features
maxaleks Mar 21, 2024
2f05b15
Update MarketplaceApp.pw.tsx_default_mobile-base-view-1.png
maxaleks Mar 21, 2024
cb3408d
add security report type
maxaleks Mar 22, 2024
7c36394
update envs-validator schema
maxaleks Mar 22, 2024
15d2d94
fix types
maxaleks Mar 25, 2024
821182e
remove commented code
maxaleks Mar 25, 2024
0052c02
post-review changes
maxaleks Mar 25, 2024
6d17681
rework solidity report component
maxaleks Mar 25, 2024
e3e8dbb
add test for marketplace with security scores
maxaleks Mar 25, 2024
c20f58f
add back button
maxaleks Mar 27, 2024
946f77d
fix height of modal header
maxaleks Mar 27, 2024
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
10 changes: 9 additions & 1 deletion configs/app/features/marketplace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,19 @@ const submitFormUrl = getEnvValue('NEXT_PUBLIC_MARKETPLACE_SUBMIT_FORM');
const suggestIdeasFormUrl = getEnvValue('NEXT_PUBLIC_MARKETPLACE_SUGGEST_IDEAS_FORM');
const categoriesUrl = getExternalAssetFilePath('NEXT_PUBLIC_MARKETPLACE_CATEGORIES_URL');
const adminServiceApiHost = getEnvValue('NEXT_PUBLIC_ADMIN_SERVICE_API_HOST');
const securityReportsUrl = getExternalAssetFilePath('NEXT_PUBLIC_MARKETPLACE_SECURITY_REPORTS_URL');

const title = 'Marketplace';

const config: Feature<(
{ configUrl: string } |
{ api: { endpoint: string; basePath: string } }
) & { submitFormUrl: string; categoriesUrl: string | undefined; suggestIdeasFormUrl: string | undefined }
) & {
submitFormUrl: string;
categoriesUrl: string | undefined;
suggestIdeasFormUrl: string | undefined;
securityReportsUrl: string | undefined;
}
> = (() => {
if (enabled === 'true' && chain.rpcUrl && submitFormUrl) {
if (configUrl) {
Expand All @@ -27,6 +33,7 @@ const config: Feature<(
submitFormUrl,
categoriesUrl,
suggestIdeasFormUrl,
securityReportsUrl,
});
} else if (adminServiceApiHost) {
return Object.freeze({
Expand All @@ -35,6 +42,7 @@ const config: Feature<(
submitFormUrl,
categoriesUrl,
suggestIdeasFormUrl,
securityReportsUrl,
api: {
endpoint: adminServiceApiHost,
basePath: '',
Expand Down
1 change: 1 addition & 0 deletions configs/envs/.env.main
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ NEXT_PUBLIC_LOGOUT_URL=https://blockscoutcom.us.auth0.com/v2/logout
NEXT_PUBLIC_MARKETPLACE_ENABLED=true
NEXT_PUBLIC_MARKETPLACE_CONFIG_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/dev/configs/marketplace/eth-goerli.json
NEXT_PUBLIC_MARKETPLACE_CATEGORIES_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/dev/configs/marketplace-categories/default.json
NEXT_PUBLIC_MARKETPLACE_SECURITY_REPORTS_URL=https://gist.githubusercontent.com/maxaleks/ce5c7e3de53e8f5b240b88265daf5839/raw/328383c958a8f7ecccf6d50c953bcdf8ab3faa0a/security_reports_goerli_test.json
maxaleks marked this conversation as resolved.
Show resolved Hide resolved
NEXT_PUBLIC_MARKETPLACE_SUBMIT_FORM=https://airtable.com/shrqUAcjgGJ4jU88C
NEXT_PUBLIC_MARKETPLACE_SUGGEST_IDEAS_FORM=https://airtable.com/appiy5yijZpMMSKjT/pag3t82DUCyhGRZZO/form
NEXT_PUBLIC_STATS_API_HOST=https://stats-goerli.k8s-dev.blockscout.com
Expand Down
1 change: 1 addition & 0 deletions deploy/scripts/download_assets.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ ASSETS_DIR="$1"
ASSETS_ENVS=(
"NEXT_PUBLIC_MARKETPLACE_CONFIG_URL"
"NEXT_PUBLIC_MARKETPLACE_CATEGORIES_URL"
"NEXT_PUBLIC_MARKETPLACE_SECURITY_REPORTS_URL"
"NEXT_PUBLIC_FEATURED_NETWORKS"
"NEXT_PUBLIC_FOOTER_LINKS"
"NEXT_PUBLIC_NETWORK_LOGO"
Expand Down
1 change: 1 addition & 0 deletions deploy/tools/envs-validator/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ async function validateEnvs(appEnvs: Record<string, string>) {
'NEXT_PUBLIC_FEATURED_NETWORKS',
'NEXT_PUBLIC_MARKETPLACE_CONFIG_URL',
'NEXT_PUBLIC_MARKETPLACE_CATEGORIES_URL',
'NEXT_PUBLIC_MARKETPLACE_SECURITY_REPORTS_URL',
'NEXT_PUBLIC_FOOTER_LINKS',
];

Expand Down
71 changes: 70 additions & 1 deletion deploy/tools/envs-validator/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import type { AdTextProviders, AdBannerProviders } from '../../../types/client/a
import type { ContractCodeIde } from '../../../types/client/contract';
import { GAS_UNITS } from '../../../types/client/gasTracker';
import type { GasUnit } from '../../../types/client/gasTracker';
import type { MarketplaceAppOverview } from '../../../types/client/marketplace';
import type { MarketplaceAppOverview, MarketplaceAppSecurityReportRaw, MarketplaceAppSecurityReport } from '../../../types/client/marketplace';
import { NAVIGATION_LINK_IDS } from '../../../types/client/navigation-items';
import type { NavItemExternal, NavigationLinkId } from '../../../types/client/navigation-items';
import { ROLLUP_TYPES } from '../../../types/client/rollup';
Expand Down Expand Up @@ -85,6 +85,65 @@ const marketplaceAppSchema: yup.ObjectSchema<MarketplaceAppOverview> = yup
priority: yup.number(),
});

const issueSeverityDistributionSchema: yup.ObjectSchema<MarketplaceAppSecurityReport['overallInfo']['issueSeverityDistribution']> = yup
.object({
critical: yup.number().required(),
gas: yup.number().required(),
high: yup.number().required(),
informational: yup.number().required(),
low: yup.number().required(),
medium: yup.number().required(),
});

const solidityscanReportSchema: yup.ObjectSchema<MarketplaceAppSecurityReport['contractsData'][number]['solidityScanReport']> = yup
.object({
contractname: yup.string().required(),
scan_status: yup.string().required(),
scan_summary: yup
.object({
issue_severity_distribution: issueSeverityDistributionSchema.required(),
lines_analyzed_count: yup.number().required(),
scan_time_taken: yup.number().required(),
score: yup.string().required(),
score_v2: yup.string().required(),
threat_score: yup.string().required(),
})
.required(),
scanner_reference_url: yup.string().test(urlTest).required(),
});

const contractDataSchema: yup.ObjectSchema<MarketplaceAppSecurityReport['contractsData'][number]> = yup
.object({
address: yup.string().required(),
isVerified: yup.boolean().required(),
solidityScanReport: solidityscanReportSchema.nullable().notRequired(),
});

const chainsDataSchema = yup.lazy((objValue) => {
let schema = yup.object();
Object.keys(objValue).forEach((key) => {
schema = schema.shape({
[key]: yup.object({
overallInfo: yup.object({
verifiedNumber: yup.number().required(),
totalContractsNumber: yup.number().required(),
solidityScanContractsNumber: yup.number().required(),
securityScore: yup.number().required(),
issueSeverityDistribution: issueSeverityDistributionSchema.required(),
}).required(),
contractsData: yup.array().of(contractDataSchema).required(),
}),
});
});
return schema;
});

const securityReportSchema: yup.ObjectSchema<MarketplaceAppSecurityReportRaw> = yup
.object({
appName: yup.string().required(),
chainsData: chainsDataSchema,
});

const marketplaceSchema = yup
.object()
.shape({
Expand Down Expand Up @@ -125,6 +184,16 @@ const marketplaceSchema = yup
// eslint-disable-next-line max-len
otherwise: (schema) => schema.max(-1, 'NEXT_PUBLIC_MARKETPLACE_SUGGEST_IDEAS_FORM cannot not be used without NEXT_PUBLIC_MARKETPLACE_ENABLED'),
}),
NEXT_PUBLIC_MARKETPLACE_SECURITY_REPORTS_URL: yup
.array()
.json()
.of(securityReportSchema)
.when('NEXT_PUBLIC_MARKETPLACE_ENABLED', {
is: true,
then: (schema) => schema,
// eslint-disable-next-line max-len
otherwise: (schema) => schema.max(-1, 'NEXT_PUBLIC_MARKETPLACE_SECURITY_REPORTS_URL cannot not be used without NEXT_PUBLIC_MARKETPLACE_ENABLED'),
}),
});

const beaconChainSchema = yup
Expand Down
1 change: 1 addition & 0 deletions deploy/tools/envs-validator/test/.env.marketplace
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ NEXT_PUBLIC_MARKETPLACE_CONFIG_URL=https://example.com
NEXT_PUBLIC_MARKETPLACE_CATEGORIES_URL=https://example.com
NEXT_PUBLIC_MARKETPLACE_SUBMIT_FORM=https://example.com
NEXT_PUBLIC_MARKETPLACE_SUGGEST_IDEAS_FORM=https://example.com
NEXT_PUBLIC_MARKETPLACE_SECURITY_REPORTS_URL=https://example.com
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST=https://example.com
Loading
Loading