Explorer: add alert notice to Project Serum deployments (#28913)

* explorer: add scam notice to serum deployments

* explorer: prettier fix

* explorer: generalize account-incident alerting

* explorer: format:fix

* explorer: remove github registry link

* explorer: remove unused fetch

* Change flagged accounts from context to flat record
This commit is contained in:
Noah Gundotra 2022-12-14 13:27:47 -05:00 committed by GitHub
parent fab0ce21a2
commit 5d6f94ef42
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 48 additions and 52 deletions

View File

@ -35,7 +35,7 @@ import {
useFetchAccountInfo, useFetchAccountInfo,
useMintAccountInfo, useMintAccountInfo,
} from "providers/accounts"; } from "providers/accounts";
import { useFlaggedAccounts } from "providers/accounts/flagged-accounts"; import FLAGGED_ACCOUNTS_WARNING from "providers/accounts/flagged-accounts";
import isMetaplexNFT from "providers/accounts/utils/isMetaplexNFT"; import isMetaplexNFT from "providers/accounts/utils/isMetaplexNFT";
import { useAnchorProgram } from "providers/anchor"; import { useAnchorProgram } from "providers/anchor";
import { CacheEntry, FetchStatus } from "providers/cache"; import { CacheEntry, FetchStatus } from "providers/cache";
@ -295,7 +295,6 @@ function DetailsSections({
const fetchAccount = useFetchAccountInfo(); const fetchAccount = useFetchAccountInfo();
const address = pubkey.toBase58(); const address = pubkey.toBase58();
const location = useLocation(); const location = useLocation();
const { flaggedAccounts } = useFlaggedAccounts();
if (!info || info.status === FetchStatus.Fetching) { if (!info || info.status === FetchStatus.Fetching) {
return <LoadingCard />; return <LoadingCard />;
@ -329,12 +328,7 @@ function DetailsSections({
return ( return (
<> <>
{flaggedAccounts.has(address) && ( {FLAGGED_ACCOUNTS_WARNING[address] ?? null}
<div className="alert alert-danger alert-scam" role="alert">
Warning! This account has been flagged by the community as a scam
account. Please be cautious sending SOL to this account.
</div>
)}
<InfoSection account={account} /> <InfoSection account={account} />
<MoreSection <MoreSection
account={account} account={account}

View File

@ -1,47 +1,52 @@
import React from "react"; import React from "react";
import { fetch } from "cross-fetch"; import { Link } from "react-router-dom";
const FLAGGED_REGISTRY = type FlaggedMap = Record<string, IncidentDescription>;
"https://solana-labs.github.io/solana-flagged-accounts/flagged.txt";
type FlaggedMap = Map<string, boolean>; type IncidentId = "ftx-hack-november-2022" | "known-scam";
type ProviderProps = { children: React.ReactNode }; type IncidentDescription = React.ReactElement;
const FlaggedContext = React.createContext<FlaggedMap>(new Map()); const FLAGGED_ACCOUNTS: Record<string, IncidentId> = {
GACpXND1SSfTSQMmqGuFvGwXB3jGEYBDRGNzmLfTYwSP: "known-scam",
"9tAViia54YAaL9gv92hBu8K4QGRBKbytCQ9TYsJ6F6or": "known-scam",
// Serum Swap
"22Y43yTVxuUkoRKdm9thyRhQ3SdgQS7c7kB6UNCiaczD": "ftx-hack-november-2022",
// Serum Dex V3
"9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin": "ftx-hack-november-2022",
// Serum Dex V2
EUqojwWA2rd19FZrzeBncJsm38Jm1hEhE3zsmX3bRc2o: "ftx-hack-november-2022",
// Serum Dex V1
BJ3jrUzddfuSrZHXSCxMUUQsjKEyLmuuyZebkcaFp2fg: "ftx-hack-november-2022",
};
export function FlaggedAccountsProvider({ children }: ProviderProps) { const INCIDENTS: Record<IncidentId, IncidentDescription> = {
const [flaggedAccounts, setFlaggedAccounts] = React.useState<FlaggedMap>( "known-scam": (
new Map() <>
); <div className="alert alert-danger alert-scam" role="alert">
Warning! This account has been flagged by the community as a scam
account. Please be cautious sending SOL to this account.
</div>
</>
),
"ftx-hack-november-2022": (
<>
<div className="alert alert-danger alert-scam" role="alert">
Warning! This program's upgrade key may have been compromised by the FTX
hack. Please migrate to the community fork:{" "}
<Link
className="text-white"
style={{ textDecoration: "underline" }}
to="https://github.com/openbook-dex/program"
>
https://github.com/openbook-dex/program
</Link>
</div>
</>
),
} as const;
React.useEffect(() => { const FLAGGED_ACCOUNTS_WARNING: FlaggedMap = {};
fetch(FLAGGED_REGISTRY) for (const [account, incidentId] of Object.entries(FLAGGED_ACCOUNTS)) {
.then((res) => { FLAGGED_ACCOUNTS_WARNING[account] = INCIDENTS[incidentId];
return res.text();
})
.then((body: string) => {
const flaggedAccounts = new Map<string, boolean>();
body
.split("\n")
.forEach((account) => flaggedAccounts.set(account, true));
setFlaggedAccounts(flaggedAccounts);
});
}, []);
return (
<FlaggedContext.Provider value={flaggedAccounts}>
{children}
</FlaggedContext.Provider>
);
}
export function useFlaggedAccounts() {
const flaggedAccounts = React.useContext(FlaggedContext);
if (!flaggedAccounts) {
throw new Error(
`useFlaggedAccounts must be used within a AccountsProvider`
);
}
return { flaggedAccounts };
} }
export default FLAGGED_ACCOUNTS_WARNING;

View File

@ -28,7 +28,6 @@ import { NonceAccount } from "validators/accounts/nonce";
import { SysvarAccount } from "validators/accounts/sysvar"; import { SysvarAccount } from "validators/accounts/sysvar";
import { ConfigAccount } from "validators/accounts/config"; import { ConfigAccount } from "validators/accounts/config";
import { ParsedAddressLookupTableAccount } from "validators/accounts/address-lookup-table"; import { ParsedAddressLookupTableAccount } from "validators/accounts/address-lookup-table";
import { FlaggedAccountsProvider } from "./flagged-accounts";
import { import {
ProgramDataAccount, ProgramDataAccount,
ProgramDataAccountInfo, ProgramDataAccountInfo,
@ -177,9 +176,7 @@ export function AccountsProvider({ children }: AccountsProviderProps) {
<FetchersContext.Provider value={fetchers}> <FetchersContext.Provider value={fetchers}>
<TokensProvider> <TokensProvider>
<HistoryProvider> <HistoryProvider>
<RewardsProvider> <RewardsProvider>{children}</RewardsProvider>
<FlaggedAccountsProvider>{children}</FlaggedAccountsProvider>
</RewardsProvider>
</HistoryProvider> </HistoryProvider>
</TokensProvider> </TokensProvider>
</FetchersContext.Provider> </FetchersContext.Provider>