Skip to content

Commit

Permalink
[coin] Add ability to override coin supplies for verified coins (#931)
Browse files Browse the repository at this point in the history
If a coin is verified to not have mint and burn, but they forgot
to set the supply, we can manually set the supply here.
  • Loading branch information
gregnazario authored Nov 23, 2024
1 parent 2a30a82 commit a56dd4f
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 18 deletions.
33 changes: 30 additions & 3 deletions src/api/hooks/useGetCoinSupplyLimit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,48 @@ import {useGlobalState} from "../../global-config/GlobalConfig";
import {useEffect, useState} from "react";
import {useViewFunction} from "./useViewFunction";

export function useGetCoinSupplyLimit(coinType: string): bigint | null {
// Override table for coins that have burnt their mint and burn, but did not properly track on-chain supply
// This will not override an existing supply, but will set a supply if it is not already set
const supplyLimitOverrides: Record<string, bigint> = {
"0x268d4a7a2ad93274edf6116f9f20ad8455223a7ab5fc73154f687e7dbc3e3ec6::LOON::LOON":
1000000000000000n,
};

export enum SupplyType {
ON_CHAIN = "On-Chain",
VERIFIED_OFF_CHAIN = "Verified Off-Chain",
NO_SUPPLY_TRACKED = "No supply tracked",
}

export function useGetCoinSupplyLimit(
coinType: string,
): [bigint | null, SupplyType | null] {
const [state] = useGlobalState();
const [totalSupply, setTotalSupply] = useState<bigint | null>(null);
const [supplyType, setSupplyType] = useState<SupplyType | null>(null);

const {data} = useViewFunction("0x1::coin::supply", [coinType], []);
const override = supplyLimitOverrides[coinType];

useEffect(() => {
if (data !== undefined) {
// Parse supply
const mappedData = data as [{vec: [string]}];
const val = mappedData[0]?.vec[0];

if (val !== undefined && val !== null) {
setTotalSupply(BigInt(val));
setSupplyType(SupplyType.ON_CHAIN);
} else if (override) {
// If supply is not set, but there is an override, set the supply
setTotalSupply(override);
setSupplyType(SupplyType.VERIFIED_OFF_CHAIN);
} else {
setTotalSupply(null);
setSupplyType(SupplyType.NO_SUPPLY_TRACKED);
}
}
}, [data, state]);
}, [data, state, override]);

return totalSupply;
return [totalSupply, supplyType];
}
2 changes: 1 addition & 1 deletion src/pages/Analytics/NetworkInfo/TotalSupply.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import MetricCard from "./MetricCard";
import {APTOS_COIN} from "@aptos-labs/ts-sdk";

export default function TotalSupply() {
const totalSupply = useGetCoinSupplyLimit(APTOS_COIN);
const [totalSupply] = useGetCoinSupplyLimit(APTOS_COIN);

return (
<MetricCard
Expand Down
7 changes: 4 additions & 3 deletions src/pages/Coin/Index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ export default function CoinPage() {
error: infoError,
isLoading,
} = useGetAccountResource(address, `0x1::coin::CoinInfo<${struct}>`);
const supply = useGetCoinSupplyLimit(struct);

const supplyInfo = useGetCoinSupplyLimit(struct);
const pairedFa = useGetCoinPairedFa(struct);

if (error === null) {
Expand Down Expand Up @@ -72,7 +73,7 @@ export default function CoinPage() {
struct={struct}
data={data as CoinData | undefined}
tabValues={tabValues}
supply={supply}
supplyInfo={supplyInfo}
pairedFa={pairedFa}
coinData={coinData}
/>
Expand All @@ -83,7 +84,7 @@ export default function CoinPage() {
struct={struct}
data={data as CoinData | undefined}
tabValues={tabValues}
supply={supply}
supplyInfo={supplyInfo}
pairedFa={pairedFa}
coinData={coinData}
/>
Expand Down
13 changes: 7 additions & 6 deletions src/pages/Coin/Tabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {useNavigate} from "../../routing";
import {CoinData} from "./Components/CoinData";
import {CoinDescription} from "../../api/hooks/useGetCoinList";
import HoldersTab from "./Tabs/HoldersTab";
import {SupplyType} from "../../api/hooks/useGetCoinSupplyLimit";

const TAB_VALUES: TabValue[] = ["info", "holders", "transactions"];

Expand Down Expand Up @@ -53,7 +54,7 @@ type TabPanelProps = {
value: TabValue;
struct: string;
data: CoinData | undefined;
supply: bigint | null;
supplyInfo: [bigint | null, SupplyType | null];
pairedFa: string | null;
coinData: CoinDescription | undefined;
};
Expand All @@ -62,7 +63,7 @@ function TabPanel({
value,
struct,
data,
supply,
supplyInfo,
pairedFa,
coinData,
}: TabPanelProps): JSX.Element {
Expand All @@ -71,7 +72,7 @@ function TabPanel({
<TabComponent
struct={struct}
data={data}
supply={supply}
supplyInfo={supplyInfo}
pairedFa={pairedFa}
coinData={coinData}
/>
Expand All @@ -82,7 +83,7 @@ type CoinTabsProps = {
struct: string;
data: CoinData | undefined;
tabValues?: TabValue[];
supply: bigint | null;
supplyInfo: [bigint | null, SupplyType | null];
pairedFa: string | null;
coinData: CoinDescription | undefined;
};
Expand All @@ -92,7 +93,7 @@ export default function CoinTabs({
struct,
data,
tabValues = TAB_VALUES,
supply,
supplyInfo,
pairedFa,
coinData,
}: CoinTabsProps): JSX.Element {
Expand Down Expand Up @@ -134,7 +135,7 @@ export default function CoinTabs({
value={effectiveTab}
struct={struct}
data={data}
supply={supply}
supplyInfo={supplyInfo}
pairedFa={pairedFa}
coinData={coinData}
/>
Expand Down
57 changes: 53 additions & 4 deletions src/pages/Coin/Tabs/InfoTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,64 @@ import HashButton, {HashType} from "../../../components/HashButton";
import {CoinData} from "../Components/CoinData";
import {getFormattedBalanceStr} from "../../../components/IndividualPageContent/ContentValue/CurrencyValue";
import {CoinDescription} from "../../../api/hooks/useGetCoinList";
import {getAssetSymbol} from "../../../utils";
import {assertNever, getAssetSymbol} from "../../../utils";
import {SupplyType} from "../../../api/hooks/useGetCoinSupplyLimit";
import Tooltip from "@mui/material/Tooltip";
import VerifiedOutlined from "@mui/icons-material/VerifiedOutlined";
import {VerifiedTwoTone} from "@mui/icons-material";
import QuestionMarkOutlined from "@mui/icons-material/QuestionMarkOutlined";

type InfoTabProps = {
struct: string;
data: CoinData | undefined;
supply: bigint | null;
supplyInfo: [bigint | null, SupplyType | null];
pairedFa: string | null;
coinData: CoinDescription | undefined;
};

export default function InfoTab({
struct,
data,
supply,
supplyInfo,
pairedFa,
coinData,
}: InfoTabProps) {
if (!data || Array.isArray(data)) {
return <EmptyTabContent />;
}

const [supply, supplyType] = supplyInfo;
let supplyIcon = null;
switch (supplyType) {
case SupplyType.ON_CHAIN:
supplyIcon = (
<Tooltip title={"Supply tracked on-chain, may change over time"}>
<VerifiedOutlined />
</Tooltip>
);
break;
case SupplyType.VERIFIED_OFF_CHAIN:
supplyIcon = (
<Tooltip title={"Supply verified off-chain to have a fixed supply"}>
<VerifiedTwoTone />
</Tooltip>
);
break;
case SupplyType.NO_SUPPLY_TRACKED:
supplyIcon = (
<Tooltip
title={"No supply is tracked for this coin on-chain or off-chain"}
>
<QuestionMarkOutlined />
</Tooltip>
);
break;
case null:
break;
default:
assertNever(supplyType);
}

let formattedSupply: string | null = null;
if (supply !== undefined && supply !== null) {
formattedSupply =
Expand All @@ -53,7 +90,19 @@ export default function InfoTab({
title={"Decimals:"}
value={data?.data?.decimals?.toString()}
/>
<ContentRow title={"Total supply:"} value={formattedSupply} />
{formattedSupply !== null ? (
<ContentRow
title={"Total supply:"}
value={
<>
{`${formattedSupply} `}
{supplyIcon}
</>
}
/>
) : (
<ContentRow title={"Total supply:"} value={supplyIcon} />
)}
<ContentRow
title={"Icon:"}
value={
Expand Down
16 changes: 15 additions & 1 deletion src/pages/FungibleAsset/Tabs/InfoTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import {getFormattedBalanceStr} from "../../../components/IndividualPageContent/
import {getAssetSymbol} from "../../../utils";
import HashButton, {HashType} from "../../../components/HashButton";
import {FACombinedData} from "../Index";
import Tooltip from "@mui/material/Tooltip";
import VerifiedOutlined from "@mui/icons-material/VerifiedOutlined";

type InfoTabProps = {
address: string;
Expand Down Expand Up @@ -52,6 +54,11 @@ export default function InfoTab({address, data}: InfoTabProps) {
}

const icon_uri = data?.coinData?.logoUrl ?? data?.metadata?.icon_uri;
const supplyIcon = (
<Tooltip title={"Supply tracked on-chain, may change over time"}>
<VerifiedOutlined />
</Tooltip>
);

return (
<Box marginBottom={3}>
Expand All @@ -70,7 +77,14 @@ export default function InfoTab({address, data}: InfoTabProps) {
title={"Decimals:"}
value={data?.metadata?.decimals?.toString()}
/>
<ContentRow title={"Total supply:"} value={formattedSupply} />
<ContentRow
title={"Total supply:"}
value={
<>
{`${formattedSupply} `} {supplyIcon}
</>
}
/>
<ContentRow
title={"Icon:"}
value={
Expand Down

0 comments on commit a56dd4f

Please sign in to comment.