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:
parent
fab0ce21a2
commit
5d6f94ef42
|
@ -35,7 +35,7 @@ import {
|
|||
useFetchAccountInfo,
|
||||
useMintAccountInfo,
|
||||
} 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 { useAnchorProgram } from "providers/anchor";
|
||||
import { CacheEntry, FetchStatus } from "providers/cache";
|
||||
|
@ -295,7 +295,6 @@ function DetailsSections({
|
|||
const fetchAccount = useFetchAccountInfo();
|
||||
const address = pubkey.toBase58();
|
||||
const location = useLocation();
|
||||
const { flaggedAccounts } = useFlaggedAccounts();
|
||||
|
||||
if (!info || info.status === FetchStatus.Fetching) {
|
||||
return <LoadingCard />;
|
||||
|
@ -329,12 +328,7 @@ function DetailsSections({
|
|||
|
||||
return (
|
||||
<>
|
||||
{flaggedAccounts.has(address) && (
|
||||
<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>
|
||||
)}
|
||||
{FLAGGED_ACCOUNTS_WARNING[address] ?? null}
|
||||
<InfoSection account={account} />
|
||||
<MoreSection
|
||||
account={account}
|
||||
|
|
|
@ -1,47 +1,52 @@
|
|||
import React from "react";
|
||||
import { fetch } from "cross-fetch";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
const FLAGGED_REGISTRY =
|
||||
"https://solana-labs.github.io/solana-flagged-accounts/flagged.txt";
|
||||
type FlaggedMap = Record<string, IncidentDescription>;
|
||||
|
||||
type FlaggedMap = Map<string, boolean>;
|
||||
type ProviderProps = { children: React.ReactNode };
|
||||
type IncidentId = "ftx-hack-november-2022" | "known-scam";
|
||||
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 [flaggedAccounts, setFlaggedAccounts] = React.useState<FlaggedMap>(
|
||||
new Map()
|
||||
);
|
||||
const INCIDENTS: Record<IncidentId, IncidentDescription> = {
|
||||
"known-scam": (
|
||||
<>
|
||||
<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(() => {
|
||||
fetch(FLAGGED_REGISTRY)
|
||||
.then((res) => {
|
||||
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 };
|
||||
const FLAGGED_ACCOUNTS_WARNING: FlaggedMap = {};
|
||||
for (const [account, incidentId] of Object.entries(FLAGGED_ACCOUNTS)) {
|
||||
FLAGGED_ACCOUNTS_WARNING[account] = INCIDENTS[incidentId];
|
||||
}
|
||||
export default FLAGGED_ACCOUNTS_WARNING;
|
||||
|
|
|
@ -28,7 +28,6 @@ import { NonceAccount } from "validators/accounts/nonce";
|
|||
import { SysvarAccount } from "validators/accounts/sysvar";
|
||||
import { ConfigAccount } from "validators/accounts/config";
|
||||
import { ParsedAddressLookupTableAccount } from "validators/accounts/address-lookup-table";
|
||||
import { FlaggedAccountsProvider } from "./flagged-accounts";
|
||||
import {
|
||||
ProgramDataAccount,
|
||||
ProgramDataAccountInfo,
|
||||
|
@ -177,9 +176,7 @@ export function AccountsProvider({ children }: AccountsProviderProps) {
|
|||
<FetchersContext.Provider value={fetchers}>
|
||||
<TokensProvider>
|
||||
<HistoryProvider>
|
||||
<RewardsProvider>
|
||||
<FlaggedAccountsProvider>{children}</FlaggedAccountsProvider>
|
||||
</RewardsProvider>
|
||||
<RewardsProvider>{children}</RewardsProvider>
|
||||
</HistoryProvider>
|
||||
</TokensProvider>
|
||||
</FetchersContext.Provider>
|
||||
|
|
Loading…
Reference in New Issue