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,
|
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}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Loading…
Reference in New Issue