Skip to content

Commit

Permalink
Merge pull request #551 from hats-finance/feature/submissions-in-audits
Browse files Browse the repository at this point in the history
[Feature] New submissions section on VaultDetailsPage
  • Loading branch information
fonstack authored Sep 26, 2023
2 parents 2e212e7 + 0395c13 commit 2ecd573
Show file tree
Hide file tree
Showing 19 changed files with 351 additions and 28 deletions.
32 changes: 31 additions & 1 deletion packages/web/src/constants/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,4 +122,34 @@ export const HAT_TOKEN_ADDRESS_V1 = "0x436cA314A2e6FfDE52ba789b257b51DaCE778F1a"
export const HAT_TOKEN_DECIMALS_V1 = "18";
export const HAT_TOKEN_SYMBOL_V1 = "HAT";

export const disallowedElementsMarkdown = ["script", "iframe", "img", "audio", "video", "object", "embed"];
export const allowedElementsMarkdown = [
"h1",
"h2",
"h3",
"h4",
"h5",
"h6",
"p",
"a",
"ul",
"ol",
"li",
"strong",
"em",
"s",
"code",
"blockquote",
"pre",
"img",
"hr",
"br",
"table",
"thead",
"tbody",
"tr",
"th",
"td",
"caption",
"div",
"span",
];
5 changes: 5 additions & 0 deletions packages/web/src/languages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,11 @@
"projectNotAvailable": "Project not available",
"projectNotAvailableExplanation": "The project on which you are attempting to submit a vulnerability is no longer available. \n\n If you think this is an error, please contact Hats support.",
"understand": "Understand",
"thereIsNoPublicSubmission": "There are no public submission for this vault yet.",
"gettingSubmissions": "Getting submissions",
"seeSubmissionsOnGithub": "See submissions on GitHub",
"openGithub": "Open GitHub",
"doYouWantToSeeSubmissionsOnGithub": "Do you want to see the submissions on GitHub?",
"submissionChanged": "Submission changed",
"submissionChangedExplanationAuditWizard": "The submission you are trying to edit has changed. \n\n If you want to edit the submission, please go back to Audit Wizard.",
"submissionNotValid": "Submission not valid",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import LinkIcon from "@mui/icons-material/InsertLinkOutlined";
import MDEditor from "@uiw/react-md-editor";
import { Alert, Button, HatSpinner, WalletButton } from "components";
import { useKeystore } from "components/Keystore";
import { IPFS_PREFIX, disallowedElementsMarkdown } from "constants/constants";
import { IPFS_PREFIX, allowedElementsMarkdown } from "constants/constants";
import { RoutePaths } from "navigation";
import { useEffect } from "react";
import { useTranslation } from "react-i18next";
Expand Down Expand Up @@ -84,7 +84,7 @@ export const SubmissionDetailsPage = () => {
<SubmissionCard submission={submission} noActions />

<MDEditor.Markdown
disallowedElements={disallowedElementsMarkdown}
allowedElements={allowedElementsMarkdown}
className="submission-content"
source={submission?.submissionDataStructure?.content}
/>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { IVault } from "@hats-finance/shared";
import MDEditor from "@uiw/react-md-editor";
import { Pill } from "components";
import { disallowedElementsMarkdown } from "constants/constants";
import { allowedElementsMarkdown } from "constants/constants";
import { useTranslation } from "react-i18next";

type EnvSetupSectionProps = {
Expand All @@ -20,7 +20,7 @@ export const EnvSetupSection = ({ vault }: EnvSetupSectionProps) => {
</div>

<MDEditor.Markdown
disallowedElements={disallowedElementsMarkdown}
allowedElements={allowedElementsMarkdown}
source={vault.description?.scope?.protocolSetupInstructions.instructions}
style={{ whiteSpace: "normal", fontSize: "var(--xsmall)", background: "transparent", color: "var(--white)" }}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import TerminalIcon from "@mui/icons-material/Terminal";
import ContractsIcon from "@mui/icons-material/ViewInAr";
import ContractsTwoIcon from "@mui/icons-material/ViewWeekOutlined";
import MDEditor from "@uiw/react-md-editor";
import { Alert, Button, CopyToClipboard, Pill, WithTooltip } from "components";
import { disallowedElementsMarkdown } from "constants/constants";
import { Alert, Button, CopyToClipboard, Loading, Pill, WithTooltip } from "components";
import { allowedElementsMarkdown } from "constants/constants";
import { defaultAnchorProps } from "constants/defaultAnchorProps";
import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
Expand Down Expand Up @@ -50,7 +50,7 @@ export const InScopeSection = ({ vault }: InScopeSectionProps) => {
getRepoContractsList();
}, [vault.description?.scope?.reposInformation]);

if (!vault.description) return null;
if (!vault.description) return <Loading fixed extraText={`${t("loading")}...`} />;

const contractsCovered = severitiesToContractsCoveredForm(vault.description?.severities);
const docsLink = vault.description.scope?.docsLink;
Expand Down Expand Up @@ -161,7 +161,7 @@ export const InScopeSection = ({ vault }: InScopeSectionProps) => {

<div className="section-content">
<MDEditor.Markdown
disallowedElements={disallowedElementsMarkdown}
allowedElements={allowedElementsMarkdown}
source={vault.description?.scope?.description}
style={{ whiteSpace: "normal", fontSize: "var(--xsmall)", background: "transparent", color: "var(--white)" }}
/>
Expand Down Expand Up @@ -219,7 +219,9 @@ export const InScopeSection = ({ vault }: InScopeSectionProps) => {
</>
)
) : (
<Alert type="info">{t("loadingContractsOnRepo")}</Alert>
<Alert type="info" className="mb-4">
{t("loadingContractsOnRepo")}
</Alert>
)}

{/* Contracts covered */}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { IVault } from "@hats-finance/shared";
import MDEditor from "@uiw/react-md-editor";
import { disallowedElementsMarkdown } from "constants/constants";
import { allowedElementsMarkdown } from "constants/constants";

type OutOfScopeSectionProps = {
vault: IVault;
Expand All @@ -12,7 +12,7 @@ export const OutOfScopeSection = ({ vault }: OutOfScopeSectionProps) => {
return (
<div className="subsection-container">
<MDEditor.Markdown
disallowedElements={disallowedElementsMarkdown}
allowedElements={allowedElementsMarkdown}
source={vault.description.scope.outOfScope}
style={{ whiteSpace: "normal", fontSize: "var(--xsmall)", background: "transparent", color: "var(--white)" }}
/>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { IVault, IVulnerabilitySeverity } from "@hats-finance/shared";
import MDEditor from "@uiw/react-md-editor";
import { Pill } from "components";
import { disallowedElementsMarkdown } from "constants/constants";
import { allowedElementsMarkdown } from "constants/constants";
import { getSeveritiesColorsArray } from "hooks/severities/useSeverityRewardInfo";
import { StyledSeverityLevelsSection } from "./styles";

Expand All @@ -20,7 +20,7 @@ export const SeverityLevelsSection = ({ vault }: SeverityLevelsSectionProps) =>
<div className="severity" key={idx}>
<Pill isSeverity transparent text={severity.name} textColor={severityColors[idx]} />
<MDEditor.Markdown
disallowedElements={disallowedElementsMarkdown}
allowedElements={allowedElementsMarkdown}
className="mt-4 pl-2"
source={severity.description}
style={{ whiteSpace: "normal", fontSize: "var(--xsmall)", background: "transparent", color: "var(--white)" }}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { IVault, IVulnerabilitySeverity } from "@hats-finance/shared";
import MDEditor from "@uiw/react-md-editor";
import { Pill } from "components";
import { allowedElementsMarkdown } from "constants/constants";
import { getSeveritiesColorsArray } from "hooks/severities/useSeverityRewardInfo";
import moment from "moment";
import { IGithubIssue } from "pages/Honeypots/VaultDetailsPage/types";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { StyledPublicSubmissionCard } from "./styles";

type PublicSubmissionCardProps = {
vault: IVault;
submission: IGithubIssue;
};

function PublicSubmissionCard({ vault, submission }: PublicSubmissionCardProps) {
const { t } = useTranslation();

const [isOpen, setIsOpen] = useState(false);

const severityColors = getSeveritiesColorsArray(vault);
const severityIndex =
submission.severity &&
vault?.description?.severities.findIndex((sev: IVulnerabilitySeverity) =>
sev.name.toLowerCase().includes(submission.severity ?? "")
);

return (
<StyledPublicSubmissionCard isOpen={isOpen}>
<div className="card-header" onClick={() => setIsOpen((prev) => !prev)}>
<div className="severity">
<Pill textColor={severityColors[severityIndex ?? 0]} isSeverity text={submission.severity ?? t("noSeverity")} />
</div>
<p className="date">{moment(submission.createdAt).format("Do MMM YYYY - hh:mma")}</p>
<p className="submission-title">{submission.issueData.issueTitle}</p>
</div>

<div className="card-content">
<MDEditor.Markdown
allowedElements={allowedElementsMarkdown}
className="submission-content"
source={submission.issueData.issueDescription
.replace("\n**Submission hash", "\\\n**Submission hash")
.replace("\n**Severity:**", "\\\n**Severity:**")}
/>
</div>
</StyledPublicSubmissionCard>
);
}

export default PublicSubmissionCard;
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import styled, { css } from "styled-components";
import { getSpacing } from "styles";

export const StyledPublicSubmissionCard = styled.div<{ isOpen: boolean }>(
({ isOpen }) => css`
position: relative;
.card-header {
position: relative;
display: flex;
flex-direction: column;
gap: ${getSpacing(1.5)};
border: 1px solid var(--primary-light);
padding: ${getSpacing(3)} ${getSpacing(4)};
background: var(--background-2);
cursor: pointer;
transition: 0.2s;
&:hover {
border-color: var(--primary);
}
.date {
position: absolute;
top: ${getSpacing(3)};
right: ${getSpacing(4)};
}
.submission-title {
font-size: var(--small);
padding-left: ${getSpacing(1)};
font-weight: 700;
}
}
.card-content {
overflow: hidden;
height: 0;
${isOpen &&
css`
height: auto;
`}
.submission-content {
white-space: normal;
font-size: var(--xsmall);
background: var(--background-3);
padding: ${getSpacing(3)} ${getSpacing(4)};
color: var(--white);
border: 1px solid var(--primary-light);
border-top: none;
}
}
`
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { IVault } from "@hats-finance/shared";
import OpenIcon from "@mui/icons-material/OpenInNewOutlined";
import { Alert, Button, HatSpinner } from "components";
import useConfirm from "hooks/useConfirm";
import { useTranslation } from "react-i18next";
import { useSavedSubmissions, useVaultRepoName } from "../../hooks";
import PublicSubmissionCard from "./PublicSubmissionCard/PublicSubmissionCard";
import { StyledSubmissionsSection } from "./styles";

type VaultSubmissionsSectionProps = {
vault: IVault;
noDeployed?: boolean;
};

export const VaultSubmissionsSection = ({ vault }: VaultSubmissionsSectionProps) => {
const { t } = useTranslation();
const confirm = useConfirm();

const { data: savedSubmissions, isLoading } = useSavedSubmissions(vault);
const { data: repoName } = useVaultRepoName(vault);

const goToGithubIssues = async () => {
if (!repoName) return;

const githubLink = `https://github.com/hats-finance/${repoName}/issues`;

const wantToGo = await confirm({
title: t("openGithub"),
titleIcon: <OpenIcon className="mr-2" fontSize="large" />,
description: t("doYouWantToSeeSubmissionsOnGithub"),
cancelText: t("no"),
confirmText: t("yesGo"),
});

if (!wantToGo) return;
window.open(githubLink, "_blank");
};

return (
<StyledSubmissionsSection>
<h2>
{t("submissions")}

{repoName && (
<Button className="ml-3" styleType="text" textColor="secondary" onClick={goToGithubIssues}>
{t("seeSubmissionsOnGithub")}
</Button>
)}
</h2>

{savedSubmissions?.length === 0 && (
<Alert className="mt-5 mb-5" type="info">
{t("thereIsNoPublicSubmission")}
</Alert>
)}

{isLoading && <HatSpinner text={`${t("gettingSubmissions")}...`} />}

{savedSubmissions && savedSubmissions?.length > 0 && (
<div className="public-submissions">
{savedSubmissions.map((submission) => (
<PublicSubmissionCard key={submission._id} vault={vault} submission={submission} />
))}
</div>
)}
</StyledSubmissionsSection>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import styled from "styled-components";
import { getSpacing } from "styles";

export const StyledSubmissionsSection = styled.div`
padding-bottom: ${getSpacing(10)};
.public-submissions {
margin-top: ${getSpacing(3)};
display: flex;
flex-direction: column;
gap: ${getSpacing(3)};
}
`;
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { VaultRewardsSection } from "./VaultRewardsSection/VaultRewardsSection";
export { VaultScopeSection } from "./VaultScopeSection/VaultScopeSection";
export { VaultDepositsSection } from "./VaultDepositsSection/VaultDepositsSection";
export { VaultSubmissionsSection } from "./VaultSubmissionsSection/VaultSubmissionsSection";
Loading

0 comments on commit 2ecd573

Please sign in to comment.