replace hardcoded token symbols with on-chain data hook
Signed-off-by: Uncle Fatso <uncle.fatso@ghostchain.io>
This commit is contained in:
parent
856bf01ffe
commit
5dffd62c5a
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "ghost-dao-interface",
|
||||
"private": true,
|
||||
"version": "0.1.2",
|
||||
"version": "0.1.3",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
@ -47,6 +47,7 @@ import BondDiscount from "../../containers/Bond/components/BondDiscount";
|
||||
import DashboardIcon from '@mui/icons-material/Dashboard';
|
||||
import ShowerIcon from '@mui/icons-material/Shower';
|
||||
|
||||
import { useTokenSymbol } from "../../hooks/tokens";
|
||||
import { useFtsoPrice, useGhstPrice } from "../../hooks/prices";
|
||||
import { useLiveBonds } from "../../hooks/bonds/index";
|
||||
|
||||
@ -67,6 +68,9 @@ const NavContent = ({ chainId, addressChainId }) => {
|
||||
const ftsoPrice = useFtsoPrice(chainId);
|
||||
const ghstPrice = useGhstPrice(chainId);
|
||||
|
||||
const { symbol: ftsoSymbol } = useTokenSymbol(chainId, "FTSO");
|
||||
const { symbol: ghstSymbol } = useTokenSymbol(chainId, "GHST");
|
||||
|
||||
return (
|
||||
<Paper className="dapp-sidebar">
|
||||
<Box className="dapp-sidebar-inner" display="flex" justifyContent="space-between" flexDirection="column">
|
||||
@ -82,10 +86,10 @@ const NavContent = ({ chainId, addressChainId }) => {
|
||||
</Link>
|
||||
<Box display="flex" flexDirection="column" mt="10px">
|
||||
<Box fontSize="12px" fontWeight="500" lineHeight={"15px"}>
|
||||
FTSO Price: {formatCurrency(ftsoPrice, 2)}
|
||||
{ftsoSymbol} Price: {formatCurrency(ftsoPrice, 2)}
|
||||
</Box>
|
||||
<Box fontSize="12px" fontWeight="500" lineHeight="15px">
|
||||
GHST Price: {formatCurrency(ghstPrice, 2)}
|
||||
{ghstSymbol} Price: {formatCurrency(ghstPrice, 2)}
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { SvgIcon } from "@mui/material";
|
||||
import { styled } from "@mui/material/styles";
|
||||
|
||||
import FtsoIcon from "../../assets/tokens/eGHST.svg?react";
|
||||
import StnkIcon from "../../assets/tokens/sGHST.svg?react";
|
||||
import FtsoIcon from "../../assets/tokens/FTSO.svg?react";
|
||||
import StnkIcon from "../../assets/tokens/STNK.svg?react";
|
||||
import GhstIcon from "../../assets/tokens/GHST.svg?react";
|
||||
import DaiIcon from "../../assets/tokens/DAI.svg?react";
|
||||
import WethIcon from "../../assets/tokens/wETH.svg?react";
|
||||
@ -26,6 +26,7 @@ const StyledSvgIcon = styled(SvgIcon)(() => ({
|
||||
const Token = ({ name, viewBox = "0 0 260 260", fontSize = "large", ...props }) => {
|
||||
const parseKnownToken = (name) => {
|
||||
let icon;
|
||||
// TBD: should be extended on new tokens
|
||||
switch (name?.toUpperCase()) {
|
||||
case "FTSO":
|
||||
icon = FtsoIcon;
|
||||
|
@ -18,7 +18,7 @@ import GhostStyledIcon from "../../Icon/GhostIcon";
|
||||
import TokenStack from "../../TokenStack/TokenStack";
|
||||
import { PrimaryButton, SecondaryButton } from "../../Button";
|
||||
|
||||
import { useBalance } from "../../../hooks/tokens";
|
||||
import { useBalance, useTokenSymbol } from "../../../hooks/tokens";
|
||||
import { useDaiPrice, useFtsoPrice, useStnkPrice, useGhstPrice } from "../../../hooks/prices";
|
||||
import { useLpValuation } from "../../../hooks/treasury";
|
||||
import { useAccount } from "wagmi";
|
||||
@ -76,7 +76,7 @@ export const Token = (props) => {
|
||||
const navigate = useNavigate();
|
||||
|
||||
const useLink = (symbol, fromAddress, toAddress, isPool) => {
|
||||
if (symbol === "GDAI") {
|
||||
if (symbol.toUpperCase() === "GDAI") {
|
||||
navigate({ pathname: "/faucet" })
|
||||
} else {
|
||||
navigate({
|
||||
@ -133,7 +133,7 @@ export const Token = (props) => {
|
||||
onClick={() => useLink(symbol, daiAddress, address, isPool)}
|
||||
fullWidth
|
||||
>
|
||||
<Typography>Get on {symbol === "GDAI" ? "Faucet" : "Uniswap"}</Typography>
|
||||
<Typography>Get on {symbol.toUpperCase() === "GDAI" ? "Faucet" : "Uniswap"}</Typography>
|
||||
</SecondaryButton>
|
||||
</Box>
|
||||
</Box>
|
||||
@ -178,9 +178,15 @@ export const useWallet = (chainId, userAddress) => {
|
||||
const ghstPrice = useGhstPrice(chainId);
|
||||
const lpDaiFtsoPrice = useLpValuation(chainId, "GDAI_FTSO", 1000000000000000000n);
|
||||
|
||||
const { symbol: daiSymbol } = useTokenSymbol(chainId, "GDAI");
|
||||
const { symbol: ftsoSymbol } = useTokenSymbol(chainId, "FTSO");
|
||||
const { symbol: stnkSymbol } = useTokenSymbol(chainId, "STNK");
|
||||
const { symbol: ghstSymbol } = useTokenSymbol(chainId, "GHST");
|
||||
const { symbol: lpDaiFtsoSymbol } = useTokenSymbol(chainId, "GDAI_FTSO");
|
||||
|
||||
const tokens = {
|
||||
dai: {
|
||||
symbol: "GDAI",
|
||||
symbol: daiSymbol,
|
||||
address: daiAddress,
|
||||
balance: daiBalance,
|
||||
price: daiPrice,
|
||||
@ -188,7 +194,7 @@ export const useWallet = (chainId, userAddress) => {
|
||||
externalUrl: "https://ghostchain.io/wp-content/uploads/2025/03/gDAI.svg",
|
||||
},
|
||||
ftso: {
|
||||
symbol: "FTSO",
|
||||
symbol: ftsoSymbol,
|
||||
address: ftsoAddress,
|
||||
balance: ftsoBalance,
|
||||
price: ftsoPrice,
|
||||
@ -196,7 +202,7 @@ export const useWallet = (chainId, userAddress) => {
|
||||
externalUrl: "https://ghostchain.io/wp-content/uploads/2025/03/eGHST.svg",
|
||||
},
|
||||
stnk: {
|
||||
symbol: "STNK",
|
||||
symbol: stnkSymbol,
|
||||
address: stnkAddress,
|
||||
balance: stnkBalance,
|
||||
price: stnkPrice,
|
||||
@ -204,7 +210,7 @@ export const useWallet = (chainId, userAddress) => {
|
||||
externalUrl: "https://ghostchain.io/wp-content/uploads/2025/03/sGHST.svg",
|
||||
},
|
||||
ghst: {
|
||||
symbol: "GHST",
|
||||
symbol: ghstSymbol,
|
||||
address: ghstAddress,
|
||||
balance: ghstBalance,
|
||||
price: ghstPrice,
|
||||
@ -213,7 +219,7 @@ export const useWallet = (chainId, userAddress) => {
|
||||
},
|
||||
daiFtso: {
|
||||
isPool: true,
|
||||
symbol: "UNI-V2",
|
||||
symbol: lpDaiFtsoSymbol,
|
||||
address: lpDaiFtsoBalanceAddress,
|
||||
balance: lpDaiFtsoBalance,
|
||||
price: lpDaiFtsoPrice,
|
||||
@ -248,8 +254,8 @@ export const Tokens = ({ address, tokens, onClose }) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
{alwaysShowTokens.map(token => (
|
||||
<Token key={token.symbol} {...tokenProps(token)} />
|
||||
{alwaysShowTokens.map((token, i) => (
|
||||
<Token key={i} {...tokenProps(token)} />
|
||||
))}
|
||||
</>
|
||||
);
|
||||
|
@ -17,6 +17,7 @@ import { ClaimBonds } from "./components/ClaimBonds";
|
||||
import { useLiveBonds } from "../../hooks/bonds";
|
||||
import { useTotalReserves } from "../../hooks/treasury";
|
||||
import { useFtsoPrice } from "../../hooks/prices";
|
||||
import { useTokenSymbol } from "../../hooks/tokens";
|
||||
|
||||
const Bonds = ({ chainId, address, connect }) => {
|
||||
const [isZoomed] = useState(false);
|
||||
@ -34,6 +35,8 @@ const Bonds = ({ chainId, address, connect }) => {
|
||||
const totalReserves = useTotalReserves(chainId);
|
||||
const ftsoPrice = useFtsoPrice(chainId);
|
||||
|
||||
const { symbol: ftsoSymbol } = useTokenSymbol(chainId, "FTSO");
|
||||
|
||||
useEffect(() => {
|
||||
const interval = setInterval(() => {
|
||||
const date = Math.round(Date.now() / 1000);
|
||||
@ -44,7 +47,7 @@ const Bonds = ({ chainId, address, connect }) => {
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<PageTitle name={"Protocol Bonding"} subtitle="Buy FTSO from the protocol at a discount" />
|
||||
<PageTitle name={"Protocol Bonding"} subtitle={`Buy ${ftsoSymbol} from the protocol at a discount`} />
|
||||
<Container
|
||||
style={{
|
||||
paddingLeft: isSmallScreen || isVerySmallScreen ? "0" : "3.3rem",
|
||||
@ -64,7 +67,7 @@ const Bonds = ({ chainId, address, connect }) => {
|
||||
isLoading={false}
|
||||
/>
|
||||
<Metric
|
||||
label={`FTSO price`}
|
||||
label={`${ftsoSymbol} price`}
|
||||
metric={formatCurrency(ftsoPrice, 2)}
|
||||
isLoading={false}
|
||||
/>
|
||||
|
@ -9,7 +9,7 @@ const BondInfoText = () => {
|
||||
fontSize="0.875em"
|
||||
lineHeight="15px"
|
||||
>
|
||||
Important: Bonding is the act of selling “naked” assets such as gDAI (reserve bonds) or liquidity tokens such as gDAI-FTSO SLP (liquidity bonds) for FTSO at a discount.
|
||||
Important: Bonding is the act of selling “naked” assets or liquidity tokens for ghostDAO native token at a discount.
|
||||
<Link
|
||||
color={theme.colors.primary[300]}
|
||||
href="https://ghostchain.io/ghostdao_litepaper"
|
||||
|
@ -37,6 +37,9 @@ const BondInputArea = ({
|
||||
const { currentIndex } = useCurrentIndex(chainId);
|
||||
const { balance } = useBalance(chainId, bond.quoteToken.quoteTokenAddress, address);
|
||||
|
||||
const { symbol: ftsoSymbol } = useTokenSymbol(chainId, "FTSO");
|
||||
const { symbol: ghstSymbol } = useTokenSymbol(chainId, "GHST");
|
||||
|
||||
const [amount, setAmount] = useState("");
|
||||
const [checked, setChecked] = useState(false);
|
||||
const [confirmOpen, setConfirmOpen] = useState(false);
|
||||
@ -164,11 +167,11 @@ const BondInputArea = ({
|
||||
title={"You Will Get"}
|
||||
balance={
|
||||
<span>
|
||||
{formatCurrency(amountInBaseToken, formatDecimals, "FTSO")}
|
||||
{formatCurrency(amountInBaseToken, formatDecimals, ftsoSymbol)}
|
||||
{" "}
|
||||
{!!currentIndex && (
|
||||
<span>
|
||||
(≈{formatCurrency(amountInBaseToken.div(currentIndex), formatDecimals, "GHST")})
|
||||
(≈{formatCurrency(amountInBaseToken.div(currentIndex), formatDecimals, ghstSymbol)})
|
||||
</span>
|
||||
)}
|
||||
</span>
|
||||
@ -182,8 +185,8 @@ const BondInputArea = ({
|
||||
balance={
|
||||
<span>
|
||||
{bond.baseToken.tokenAddress.toUpperCase() === bond.quoteToken.quoteTokenAddress.toUpperCase()
|
||||
? `${formatCurrency(baseTokenString, formatDecimals, "FTSO")}`
|
||||
: `${formatCurrency(baseTokenString, formatDecimals, "FTSO")} (≈${formatCurrency(baseTokenString.div(currentIndex), formatDecimals, "GHST")})`}
|
||||
? `${formatCurrency(baseTokenString, formatDecimals, ftsoSymbol)}`
|
||||
: `${formatCurrency(baseTokenString, formatDecimals, ftsoSymbol)} (≈${formatCurrency(baseTokenString.div(currentIndex), formatDecimals, ghstSymbol)})`}
|
||||
</span>
|
||||
}
|
||||
/>
|
||||
@ -191,7 +194,7 @@ const BondInputArea = ({
|
||||
<DataRow
|
||||
title="Discount"
|
||||
balance={<BondDiscount discount={bond.discount} textOnly />}
|
||||
tooltip="The bond discount is the percentage difference between FTSO market value and the bond's price"
|
||||
tooltip={`The bond discount is the percentage difference between ${ftsoSymbol} market value and the bond's price`}
|
||||
/>
|
||||
|
||||
<DataRow
|
||||
|
@ -170,7 +170,7 @@ const payoutTokenCapacity = (bond) => {
|
||||
const payoutTokenCapacity = bond.maxPayout.inBaseToken.lt(bond.capacity.inBaseToken)
|
||||
? bond.maxPayout.inBaseToken
|
||||
: bond.capacity.inBaseToken;
|
||||
return `${formatNumber(payoutTokenCapacity, 4)} FTSO`;
|
||||
return `${formatNumber(payoutTokenCapacity, 4)} ${bond.baseToken.name}`;
|
||||
};
|
||||
|
||||
const BondRow = ({ bond, secondsTo }) => {
|
||||
|
@ -19,6 +19,7 @@ import { formatCurrency } from "../../../helpers";
|
||||
|
||||
import { useCurrentIndex, useEpoch, useWarmupLength, useWarmupInfo } from "../../../hooks/staking";
|
||||
import { useNotes, redeem } from "../../../hooks/bonds";
|
||||
import { useTokenSymbol } from "../../../hooks/tokens";
|
||||
|
||||
export const ClaimBonds = ({ chainId, address, secondsTo }) => {
|
||||
const isSmallScreen = useScreenSize("md");
|
||||
@ -37,6 +38,10 @@ export const ClaimBonds = ({ chainId, address, secondsTo }) => {
|
||||
const { currentIndex, refetch: currentIndexRefetch } = useCurrentIndex(chainId);
|
||||
const { notes, refetch: notesRefetch } = useNotes(chainId, address);
|
||||
|
||||
const { symbol: ftsoSymbol } = useTokenSymbol(chainId, "FTSO");
|
||||
const { symbol: stnkSymbol } = useTokenSymbol(chainId, "STNK");
|
||||
const { symbol: ghstSymbol } = useTokenSymbol(chainId, "GHST");
|
||||
|
||||
if (!notes || notes.length === 0) return null;
|
||||
|
||||
const totalClaimableBalance = new DecimalBigNumber(
|
||||
@ -91,8 +96,8 @@ export const ClaimBonds = ({ chainId, address, secondsTo }) => {
|
||||
onChange={(_, view) => setIsPayoutGhstInner(view === 1)}
|
||||
TabIndicatorProps={{ style: { display: "none" } }}
|
||||
>
|
||||
<Tab aria-label="payout-stnk-button" label="STNK" style={{ fontSize: "1rem" }} />
|
||||
<Tab aria-label="payout-ghst-button" label="GHST" style={{ fontSize: "1rem" }} />
|
||||
<Tab aria-label="payout-stnk-button" label={stnkSymbol} style={{ fontSize: "1rem" }} />
|
||||
<Tab aria-label="payout-ghst-button" label={ghstSymbol} style={{ fontSize: "1rem" }} />
|
||||
</Tabs>
|
||||
</Box>
|
||||
|
||||
@ -105,8 +110,8 @@ export const ClaimBonds = ({ chainId, address, secondsTo }) => {
|
||||
<Box mt="4px" mb="8px">
|
||||
<Typography variant="h4" align="center">
|
||||
{isPayoutGhst
|
||||
? formatCurrency(totalClaimableBalance, 5, "GHST")
|
||||
: formatCurrency(currentIndex.mul(totalClaimableBalance), 5, "STNK")
|
||||
? formatCurrency(totalClaimableBalance, 5, ghstSymbol)
|
||||
: formatCurrency(currentIndex.mul(totalClaimableBalance), 5, stnkSymbol)
|
||||
}
|
||||
</Typography>
|
||||
</Box>
|
||||
@ -152,8 +157,8 @@ export const ClaimBonds = ({ chainId, address, secondsTo }) => {
|
||||
<Typography>Payout</Typography>
|
||||
<Typography>
|
||||
{isPayoutGhst
|
||||
? formatCurrency(note.payout, 5, "GHST")
|
||||
: formatCurrency(currentIndex.mul(note.payout), 5, "STNK")
|
||||
? formatCurrency(note.payout, 5, ghstSymbol)
|
||||
: formatCurrency(currentIndex.mul(note.payout), 5, stnkSymbol)
|
||||
}
|
||||
</Typography>
|
||||
</Box>
|
||||
@ -208,8 +213,8 @@ export const ClaimBonds = ({ chainId, address, secondsTo }) => {
|
||||
<TableCell style={{ padding: "8px 0" }}>
|
||||
<Typography>
|
||||
{isPayoutGhst
|
||||
? formatCurrency(note.payout, 5, "GHST")
|
||||
: formatCurrency(currentIndex.mul(note.payout), 5, "STNK")
|
||||
? formatCurrency(note.payout, 5, ghstSymbol)
|
||||
: formatCurrency(currentIndex.mul(note.payout), 5, stnkSymbol)
|
||||
}
|
||||
</Typography>
|
||||
</TableCell>
|
||||
|
@ -42,6 +42,11 @@ const TokenModal = ({ chainId, account, listOpen, setListOpen, setTokenAddress }
|
||||
const { balance: stnkBalance } = useBalance(chainId, "STNK", account);
|
||||
const { balance: ghstBalance } = useBalance(chainId, "GHST", account);
|
||||
|
||||
const { symbol: daiSymbol } = useTokenSymbol(chainId, "GDAI");
|
||||
const { symbol: ftsoSymbol } = useTokenSymbol(chainId, "FTSO");
|
||||
const { symbol: stnkSymbol } = useTokenSymbol(chainId, "STNK");
|
||||
const { symbol: ghstSymbol } = useTokenSymbol(chainId, "GHST");
|
||||
|
||||
const searchToken = useMemo(() => {
|
||||
return [{
|
||||
name: searchSymbol,
|
||||
@ -54,31 +59,31 @@ const TokenModal = ({ chainId, account, listOpen, setListOpen, setTokenAddress }
|
||||
const knownTokens = useMemo(() => {
|
||||
return [
|
||||
{
|
||||
name: "gDAI",
|
||||
name: daiSymbol,
|
||||
icons: ["GDAI"],
|
||||
balance: daiBalance,
|
||||
address: DAI_ADDRESSES[chainId]
|
||||
},
|
||||
{
|
||||
name: "FTSO",
|
||||
name: ftsoSymbol,
|
||||
icons: ["FTSO"],
|
||||
balance: ftsoBalance,
|
||||
address: FTSO_ADDRESSES[chainId]
|
||||
},
|
||||
{
|
||||
name: "STNK",
|
||||
name: stnkSymbol,
|
||||
icons: ["STNK"],
|
||||
balance: stnkBalance,
|
||||
address: STNK_ADDRESSES[chainId]
|
||||
},
|
||||
{
|
||||
name: "GHST",
|
||||
name: ghstSymbol,
|
||||
icons: ["GHST"],
|
||||
balance: ghstBalance,
|
||||
address: GHST_ADDRESSES[chainId]
|
||||
}
|
||||
]
|
||||
}, [daiBalance, ghstBalance, stnkBalance, ghstBalance]);
|
||||
}, [daiSymbol, ftsoSymbol, stnkSymbol, ghstSymbol, daiBalance, ftsoBalance, stnkBalance, ghstBalance]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isAddress(userInput)) {
|
||||
|
@ -14,7 +14,7 @@ import { DAI_ADDRESSES } from "../../constants/addresses";
|
||||
import { DecimalBigNumber } from "../../helpers/DecimalBigNumber";
|
||||
import { formatCurrency, formatNumber } from "../../helpers";
|
||||
|
||||
import { useBalance as useTokenBalance, useConversionRate, mintDai } from "../../hooks/tokens";
|
||||
import { useBalance as useTokenBalance, useTokenSymbol, useConversionRate, mintDai } from "../../hooks/tokens";
|
||||
|
||||
const Faucet = ({ chainId, address, config, connect }) => {
|
||||
const isSmallScreen = useMediaQuery("(max-width: 650px)");
|
||||
@ -24,14 +24,11 @@ const Faucet = ({ chainId, address, config, connect }) => {
|
||||
const daiConversionRate = useConversionRate(chainId, "GDAI");
|
||||
const { balance: daiBalance, refetch: daiBalanceRefetch } = useTokenBalance(chainId, "GDAI", address);
|
||||
const { data: nativeBalance, refetch: balanceRefetch } = useBalance({ address });
|
||||
const { symbol: faucetSymbol } = useTokenSymbol(chainId, "GDAI");
|
||||
|
||||
const [isPending, setIsPending] = useState(false);
|
||||
const [balance, setBalance] = useState(new DecimalBigNumber(0, 0));
|
||||
const [amount, setAmount] = useState("");
|
||||
const [faucetToken, setFaucetToken] = useState({
|
||||
name: "",
|
||||
address: "",
|
||||
});
|
||||
const [scanInfo, setScanInfo] = useState({
|
||||
name: "",
|
||||
url: "",
|
||||
@ -51,18 +48,10 @@ const Faucet = ({ chainId, address, config, connect }) => {
|
||||
let scanName = "";
|
||||
let scanUrl = "";
|
||||
|
||||
const tokenName = "gDAI";
|
||||
const tokenAddress = DAI_ADDRESSES[chainId];
|
||||
|
||||
const client = config?.getClient();
|
||||
scanName = client?.chain?.blockExplorers?.default?.name;
|
||||
scanUrl = client?.chain?.blockExplorers?.default?.url;
|
||||
|
||||
setFaucetToken({
|
||||
name: tokenName,
|
||||
address: tokenAddress,
|
||||
});
|
||||
|
||||
setScanInfo({
|
||||
name: scanName,
|
||||
url: scanUrl,
|
||||
@ -131,10 +120,10 @@ const Faucet = ({ chainId, address, config, connect }) => {
|
||||
<Paper
|
||||
headerContent={
|
||||
<Box alignItems="center" justifyContent="space-between" display="flex" width="100%">
|
||||
<Typography variant="h4">Get {faucetToken.name}</Typography>
|
||||
<Typography variant="h4">Get {faucetSymbol}</Typography>
|
||||
{!isSemiSmallScreen && <PrimaryButton
|
||||
variant="text"
|
||||
href={`${scanInfo.url}/token/${faucetToken.address}`}
|
||||
href={`${scanInfo.url}/token/${DAI_ADDRESSES[chainId]}`}
|
||||
>
|
||||
Check on {scanInfo.name}
|
||||
</PrimaryButton>}
|
||||
@ -167,11 +156,11 @@ const Faucet = ({ chainId, address, config, connect }) => {
|
||||
</Box>
|
||||
<Box maxWidth="416px" display="flex" justifyContent={isVerySmallScreen ? "end" : "space-between"}>
|
||||
{!isVerySmallScreen && <Typography fontSize="12px" lineHeight="15px">You will get:</Typography>}
|
||||
<Typography fontSize="12px" lineHeight="15px">{formatCurrency(estimatedAmount, 5, faucetToken.name)}</Typography>
|
||||
<Typography fontSize="12px" lineHeight="15px">{formatCurrency(estimatedAmount, 5, faucetSymbol)}</Typography>
|
||||
</Box>
|
||||
<Box display="flex" justifyContent={isVerySmallScreen ? "end" : "space-between"}>
|
||||
{!isVerySmallScreen && <Typography fontSize="12px" lineHeight="15px">Your {faucetToken.name} balance:</Typography>}
|
||||
<Typography fontSize="12px" lineHeight="15px">{formatCurrency(daiBalance, 5, faucetToken.name)}</Typography>
|
||||
{!isVerySmallScreen && <Typography fontSize="12px" lineHeight="15px">Your {faucetSymbol} balance:</Typography>}
|
||||
<Typography fontSize="12px" lineHeight="15px">{formatCurrency(daiBalance, 5, faucetSymbol)}</Typography>
|
||||
</Box>
|
||||
</Box>
|
||||
<PrimaryButton
|
||||
|
@ -16,6 +16,7 @@ import { ClaimsArea } from "./components/ClaimsArea";
|
||||
import { Apy, CurrentIndex, TotalDeposit } from "./components/Metric";
|
||||
|
||||
import { useEpoch } from "../../hooks/staking";
|
||||
import { useTokenSymbol } from "../../hooks/tokens";
|
||||
|
||||
export const StakeContainer = ({ chainId, address, connect }) => {
|
||||
const [isModalOpened, handleModal] = useState(false);
|
||||
@ -24,6 +25,9 @@ export const StakeContainer = ({ chainId, address, connect }) => {
|
||||
const isSmallScreen = useMediaQuery("(max-width: 650px)");
|
||||
const isVerySmallScreen = useMediaQuery("(max-width: 379px)");
|
||||
|
||||
const { symbol: ftsoSymbol } = useTokenSymbol(chainId, "FTSO");
|
||||
const { symbol: stnkSymbol } = useTokenSymbol(chainId, "STNK");
|
||||
|
||||
const { epoch, refetch: refetchEpoch } = useEpoch(chainId);
|
||||
|
||||
useEffect(() => {
|
||||
@ -44,7 +48,7 @@ export const StakeContainer = ({ chainId, address, connect }) => {
|
||||
|
||||
return (
|
||||
<Box >
|
||||
<PageTitle name="Protocol Staking" subtitle="Stake your FTSO to earn rebase yields" />
|
||||
<PageTitle name="Protocol Staking" subtitle={`Stake your ${ftsoSymbol} to earn rebase yields`} />
|
||||
<Container
|
||||
style={{
|
||||
paddingLeft: isSmallScreen || isVerySmallScreen ? "0" : "3.3rem",
|
||||
@ -71,13 +75,13 @@ export const StakeContainer = ({ chainId, address, connect }) => {
|
||||
>
|
||||
<Grid container spacing={1}>
|
||||
<Grid item xs={isSmallScreen ? 12 : 4}>
|
||||
<Apy distribute={epoch.distribute} chainId={chainId} />
|
||||
<Apy stnkSymbol={stnkSymbol} distribute={epoch.distribute} chainId={chainId} />
|
||||
</Grid>
|
||||
<Grid item xs={isSmallScreen ? 12 : 4}>
|
||||
<TotalDeposit chainId={chainId} />
|
||||
<TotalDeposit stnkSymbol={stnkSymbol} chainId={chainId} />
|
||||
</Grid>
|
||||
<Grid item xs={isSmallScreen ? 12 : 4}>
|
||||
<CurrentIndex chainId={chainId} />
|
||||
<CurrentIndex ftsoSymbol={ftsoSymbol} chainId={chainId} />
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
|
@ -55,7 +55,7 @@ const ClaimConfirmationModal = (props) => {
|
||||
/>
|
||||
<Box display="flex" flexDirection="row" justifyContent="center">
|
||||
<Typography>
|
||||
{props.outputToken}
|
||||
{props.outputTokenName}
|
||||
</Typography>
|
||||
</Box>
|
||||
</Box>
|
||||
|
@ -28,7 +28,7 @@ import { prettifySecondsInDays } from "../../../helpers/timeUtil";
|
||||
import { formatNumber } from "../../../helpers";
|
||||
import { STAKING_ADDRESSES } from "../../../constants/addresses";
|
||||
import { useCurrentIndex, useWarmupInfo } from "../../../hooks/staking";
|
||||
import { useBalanceForShares } from "../../../hooks/tokens";
|
||||
import { useBalanceForShares, useTokenSymbol } from "../../../hooks/tokens";
|
||||
|
||||
import ClaimConfirmationModal from "./ClaimConfirmationModal";
|
||||
|
||||
@ -61,6 +61,10 @@ export const ClaimsArea = ({ chainId, address, epoch }) => {
|
||||
const { currentIndex, refetch: currentIndexRefetch } = useCurrentIndex(chainId);
|
||||
const { balanceForShares } = useBalanceForShares(chainId, "STNK", claim.shares);
|
||||
|
||||
const { symbol: ftsoSymbol } = useTokenSymbol(chainId, "FTSO");
|
||||
const { symbol: stnkSymbol } = useTokenSymbol(chainId, "STNK");
|
||||
const { symbol: ghstSymbol } = useTokenSymbol(chainId, "GHST");
|
||||
|
||||
const closeConfirmationModal = () => {
|
||||
setConfirmationModalOpen(false);
|
||||
claimRefetch();
|
||||
@ -85,6 +89,7 @@ export const ClaimsArea = ({ chainId, address, epoch }) => {
|
||||
receiver={address}
|
||||
receiveAmount={claim.expiry > epoch.number ? claim.deposit : isPayoutGhst ? balanceForShares.div(currentIndex) : balanceForShares}
|
||||
outputToken={claim.expiry > epoch.number ? "FTSO" : isPayoutGhst ? "GHST" : "STNK"}
|
||||
outputTokenName={claim.expiry > epoch.number ? ftsoSymbol : isPayoutGhst ? ghstSymbol : stnkSymbol}
|
||||
action={claim.expiry > epoch.number ? "forfeit" : "claim"}
|
||||
chainId={chainId}
|
||||
/>
|
||||
@ -98,7 +103,7 @@ export const ClaimsArea = ({ chainId, address, epoch }) => {
|
||||
justifyContent="space-between"
|
||||
flexDirection={isSmallScreen ? "column" : "row"}
|
||||
>
|
||||
<Typography variant="h6">Your active {isPayoutGhst ? "GHST" : "STNK"} claim</Typography>
|
||||
<Typography variant="h6">Your active {isPayoutGhst ? ghstSymbol : stnkSymbol} claim</Typography>
|
||||
<Tabs
|
||||
centered
|
||||
textColor="primary"
|
||||
@ -108,8 +113,8 @@ export const ClaimsArea = ({ chainId, address, epoch }) => {
|
||||
onChange={(_, view) => setIsPayoutGhstInner(view === 1)}
|
||||
TabIndicatorProps={{ style: { display: "none" } }}
|
||||
>
|
||||
<Tab aria-label="payout-stnk-button" label="STNK" style={{ fontSize: "1rem" }} />
|
||||
<Tab aria-label="payout-ghst-button" label="GHST" style={{ fontSize: "1rem" }} />
|
||||
<Tab aria-label="payout-stnk-button" label={stnkSymbol} style={{ fontSize: "1rem" }} />
|
||||
<Tab aria-label="payout-ghst-button" label={ghstSymbol} style={{ fontSize: "1rem" }} />
|
||||
</Tabs>
|
||||
</Box>
|
||||
}
|
||||
@ -124,6 +129,8 @@ export const ClaimsArea = ({ chainId, address, epoch }) => {
|
||||
claim={claim}
|
||||
epoch={epoch}
|
||||
isClaimable={claim.expiry > epoch.number}
|
||||
stnkSymbol={stnkSymbol}
|
||||
ghstSymbol={ghstSymbol}
|
||||
/>
|
||||
) : (
|
||||
<Table>
|
||||
@ -142,6 +149,8 @@ export const ClaimsArea = ({ chainId, address, epoch }) => {
|
||||
claim={claim}
|
||||
epoch={epoch}
|
||||
isClaimable={claim.expiry > epoch.number}
|
||||
stnkSymbol={stnkSymbol}
|
||||
ghstSymbol={ghstSymbol}
|
||||
/>
|
||||
</Table>
|
||||
|
||||
@ -151,21 +160,21 @@ export const ClaimsArea = ({ chainId, address, epoch }) => {
|
||||
);
|
||||
};
|
||||
|
||||
const ClaimInfo = ({ setConfirmationModalOpen, prepareBalance, claim, epoch, isClaimable, isPayoutGhst }) => {
|
||||
const ClaimInfo = ({ setConfirmationModalOpen, prepareBalance, claim, epoch, isClaimable, isPayoutGhst, stnkSymbol, ghstSymbol }) => {
|
||||
return (
|
||||
<TableBody>
|
||||
<TableRow>
|
||||
<TableCell style={{ padding: "8px 8px 8px 0" }}>
|
||||
<Box display="flex" flexDirection="row" alignItems="center" style={{ whiteSpace: "nowrap" }}>
|
||||
<Token key={isPayoutGhst ? "GHST" : "STNK"} name={isPayoutGhst ? "GHST" : "STNK"} />
|
||||
<Token key={isPayoutGhst ? ghstSymbol : stnkSymbol} name={isPayoutGhst ? ghstSymbol : stnkSymbol} />
|
||||
<Box marginLeft="14px" marginRight="10px">
|
||||
<Typography>{isPayoutGhst ? "GHST" : "STNK"}</Typography>
|
||||
<Typography>{isPayoutGhst ? ghstSymbol : stnkSymbol}</Typography>
|
||||
</Box>
|
||||
</Box>
|
||||
</TableCell>
|
||||
<TableCell style={{ padding: "8px 8px 8px 0" }}>
|
||||
<Typography gutterBottom={false} style={{ lineHeight: 1.4 }}>
|
||||
{`${formatNumber(prepareBalance, 5)} ${isPayoutGhst ? "GHST" : "STNK"}`}
|
||||
{`${formatNumber(prepareBalance, 5)} ${isPayoutGhst ? ghstSymbol : stnkSymbol}`}
|
||||
</Typography>
|
||||
</TableCell>
|
||||
<TableCell style={{ padding: "8px 8px 8px 0" }}>
|
||||
@ -182,13 +191,13 @@ const ClaimInfo = ({ setConfirmationModalOpen, prepareBalance, claim, epoch, isC
|
||||
);
|
||||
};
|
||||
|
||||
const MobileClaimInfo = ({ setConfirmationModalOpen, prepareBalance, epoch, claim, isPayoutGhst, isClaimable }) => {
|
||||
const MobileClaimInfo = ({ setConfirmationModalOpen, prepareBalance, epoch, claim, isPayoutGhst, isClaimable, ghstSymbol, stnkSymbol }) => {
|
||||
return (
|
||||
<Box mt="10px">
|
||||
<Box display="flex" flexDirection="row" alignItems="center" style={{ whiteSpace: "nowrap" }}>
|
||||
<Token key={isPayoutGhst ? "GHST" : "STNK"} name={isPayoutGhst ? "GHST" : "STNK"} />
|
||||
<Token key={isPayoutGhst ? ghstSymbol : stnkSymbol} name={isPayoutGhst ? ghstSymbol : stnkSymbol} />
|
||||
<Box marginLeft="14px" marginRight="10px">
|
||||
<Typography>{isPayoutGhst ? "GHST" : "STNK"}</Typography>
|
||||
<Typography>{isPayoutGhst ? ghstSymbol : stnkSymbol}</Typography>
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
|
@ -18,7 +18,7 @@ import { DecimalBigNumber } from "../../../helpers/DecimalBigNumber";
|
||||
import { formatCurrency } from "../../../helpers";
|
||||
|
||||
import { useLpValuation } from "../../../hooks/treasury";
|
||||
import { useTotalSupply } from "../../../hooks/tokens";
|
||||
import { useTotalSupply, useTokenSymbol } from "../../../hooks/tokens";
|
||||
|
||||
import {
|
||||
DAI_ADDRESSES,
|
||||
@ -31,10 +31,13 @@ const FarmPools = ({ chainId }) => {
|
||||
const { totalSupply: daiFtsoUniTotalSupply } = useTotalSupply(chainId, "GDAI_FTSO");
|
||||
const daiFtsoUniValuation = useLpValuation(chainId, "GDAI_FTSO", daiFtsoUniTotalSupply._value);
|
||||
|
||||
const { symbol: daiSymbol } = useTokenSymbol(chainId, "GDAI");
|
||||
const { symbol: ftsoSymbol } = useTokenSymbol(chainId, "FTSO");
|
||||
|
||||
const pools = [
|
||||
{
|
||||
icons: ["FTSO", "GDAI"],
|
||||
name: "FTSO-gDAI",
|
||||
name: `${ftsoSymbol}-${daiSymbol}`,
|
||||
dex: "Uniswap V2",
|
||||
url: "/dex/uniswap",
|
||||
tvl: daiFtsoUniValuation,
|
||||
@ -61,7 +64,7 @@ const FarmPools = ({ chainId }) => {
|
||||
return (
|
||||
<Paper headerText="Farm Pools" fullWidth enableBackground>
|
||||
<TableContainer>
|
||||
<Table aria-label="Available bonds" style={{ tableLayout: "fixed" }}>
|
||||
<Table aria-label="Farm pools" style={{ tableLayout: "fixed" }}>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell style={{ padding: "8px 0", width: "30%" }}>Asset</TableCell>
|
||||
|
@ -13,7 +13,7 @@ export const CurrentIndex = props => {
|
||||
const _props = {
|
||||
...props,
|
||||
label: `Current Index`,
|
||||
tooltip: `The current index indicates the amount of FTSO a holder would possess if they had staked and maintained 1 FTSO since its launch.`,
|
||||
tooltip: `The current index indicates the amount of ${props.ftsoSymbol} a holder would possess if they had staked and maintained 1 ${props.ftsoSymbol} since its launch.`,
|
||||
};
|
||||
|
||||
if (currentIndex) _props.metric = `${formatNumber(currentIndex, 2)}`;
|
||||
@ -35,7 +35,7 @@ export const Apy = props => {
|
||||
const _props = {
|
||||
...props,
|
||||
label: "APY",
|
||||
tooltip: "The annualized rate of return, accounting for compounding from STNK’s exponential rebasing.",
|
||||
tooltip: `The annualized rate of return, accounting for compounding from ${props.stnkSymbol}’s exponential rebasing.`,
|
||||
};
|
||||
|
||||
if (apy) _props.metric = `${formatNumber(apy, 2)}${apy === Infinity ? "" : "%"}`;
|
||||
@ -52,7 +52,7 @@ export const TotalDeposit = props => {
|
||||
const _props = {
|
||||
...props,
|
||||
label: "Total Deposit",
|
||||
tooltip: "The total stablecoin reserves in the ghostDAO treasury backing the entire circulating supply of STNK.",
|
||||
tooltip: `The total stablecoin reserves in the ghostDAO treasury backing the entire circulating supply of ${props.stnkSymbol}.`,
|
||||
};
|
||||
|
||||
if (deposit) _props.metric = `${formatCurrency(deposit, 2)}`;
|
||||
|
@ -39,7 +39,7 @@ const StakeConfirmationModal = (props) => {
|
||||
checkedIcon={<CheckBoxOutlined viewBox="0 0 24 24" />}
|
||||
/>
|
||||
}
|
||||
label={`I understand the FTSO (eGHST) I’m staking will only be available to claim ${warmupLength.toString()} epochs after my transaction is confirmed`}
|
||||
label={`I understand the ${props.ftsoSymbol} I’m staking will only be available to claim ${warmupLength.toString()} epochs after my transaction is confirmed`}
|
||||
/>
|
||||
</Box>
|
||||
</>
|
||||
@ -115,7 +115,7 @@ const StakeConfirmationModal = (props) => {
|
||||
/>
|
||||
<Box display="flex" flexDirection="row" justifyContent="center">
|
||||
<Typography>
|
||||
{props.upperToken}
|
||||
{props.upperToken === "FTSO" ? props.ftsoSymbol : props.upperToken === "STNK" ? props.stnkSymbol : props.ghstSymbol}
|
||||
</Typography>
|
||||
</Box>
|
||||
</Box>
|
||||
@ -127,7 +127,7 @@ const StakeConfirmationModal = (props) => {
|
||||
/>
|
||||
<Box display="flex" flexDirection="row" justifyContent="center">
|
||||
<Typography>
|
||||
{props.bottomToken}
|
||||
{props.bottomToken === "FTSO" ? props.ftsoSymbol : props.bottomToken === "STNK" ? props.stnkSymbol : props.ghstSymbol}
|
||||
</Typography>
|
||||
</Box>
|
||||
</Box>
|
||||
@ -141,7 +141,7 @@ const StakeConfirmationModal = (props) => {
|
||||
owner={props.address}
|
||||
spender={STAKING_ADDRESSES[props.chainId]}
|
||||
decimals={props.spendDecimals}
|
||||
approvalText={"Approve " + props.upperToken}
|
||||
approvalText={"Approve " + props.upperToken === "FTSO" ? props.ftsoSymbol : props.upperToken === "STNK" ? props.stnkSymbol : props.ghstSymbol}
|
||||
approvalPendingText={"Approving..."}
|
||||
connect={props.connect}
|
||||
isVertical
|
||||
|
@ -23,7 +23,7 @@ import {
|
||||
STAKING_ADDRESSES,
|
||||
} from "../../../constants/addresses";
|
||||
import { useCurrentIndex } from "../../../hooks/staking";
|
||||
import { useBalance } from "../../../hooks/tokens";
|
||||
import { useBalance, useTokenSymbol } from "../../../hooks/tokens";
|
||||
import { formatNumber } from "../../../helpers";
|
||||
|
||||
const PREFIX = "StakeInputArea";
|
||||
@ -106,6 +106,10 @@ export const StakeInputArea = ({
|
||||
const { balance: stnkBalance, refetch: stnkRefetch } = useBalance(chainId, "STNK", address);
|
||||
const { balance: ghstBalance, refetch: ghstRefetch } = useBalance(chainId, "GHST", address);
|
||||
|
||||
const { symbol: ftsoSymbol } = useTokenSymbol(chainId, "FTSO");
|
||||
const { symbol: stnkSymbol } = useTokenSymbol(chainId, "STNK");
|
||||
const { symbol: ghstSymbol } = useTokenSymbol(chainId, "GHST");
|
||||
|
||||
const setIsClaimInner = (value) => {
|
||||
setIsClaim(value);
|
||||
localStorage.setItem("stake-isClaim", value);
|
||||
@ -185,11 +189,24 @@ export const StakeInputArea = ({
|
||||
stnkBalance : tokenName === "FTSO" ?
|
||||
ftsoBalance : ghstBalance;
|
||||
|
||||
let realTokenName = "";
|
||||
switch (tokenName.toUpperCase()) {
|
||||
case "FTSO":
|
||||
realTokenName = ftsoSymbol;
|
||||
break;
|
||||
case "STNK":
|
||||
realTokenName = stnkSymbol;
|
||||
break;
|
||||
case "GHST":
|
||||
realTokenName = ghstSymbol;
|
||||
break;
|
||||
}
|
||||
|
||||
return (
|
||||
<SwapCard
|
||||
id={`${tokenName.toLowerCase()}-input`}
|
||||
token={tokenName}
|
||||
tokenName={tokenName}
|
||||
tokenName={realTokenName}
|
||||
tokenOnClick={() => handleModal(true)}
|
||||
inputProps={{ "data-testid": `${tokenName.toLowerCase()}-input`, min: "0" }}
|
||||
value={tokenAmount}
|
||||
@ -228,24 +245,30 @@ export const StakeInputArea = ({
|
||||
{upperTokenModalOpen && (
|
||||
<TokenModal
|
||||
open={upperTokenModalOpen}
|
||||
handleSelect={data => handleTokenModalInput(data.name, data.isUpper)}
|
||||
handleSelect={data => handleTokenModalInput(data.token, data.isUpper)}
|
||||
handleClose={() => setUpperTokenModalOpen(false)}
|
||||
ftsoBalance={formatNumber(ftsoBalance, formatDecimals)}
|
||||
stnkBalance={formatNumber(stnkBalance, formatDecimals)}
|
||||
ghstBalance={formatNumber(ghstBalance, formatDecimals)}
|
||||
isUpper={true}
|
||||
ftsoSymbol={ftsoSymbol}
|
||||
stnkSymbol={stnkSymbol}
|
||||
ghstSymbol={ghstSymbol}
|
||||
/>
|
||||
)}
|
||||
{bottomTokenModalOpen && (
|
||||
<TokenModal
|
||||
open={bottomTokenModalOpen}
|
||||
handleSelect={data => handleTokenModalInput(data.name, data.isUpper)}
|
||||
handleSelect={data => handleTokenModalInput(data.token, data.isUpper)}
|
||||
handleClose={() => setBottomTokenModalOpen(false)}
|
||||
ftsoBalance={formatNumber(ftsoBalance, formatDecimals)}
|
||||
stnkBalance={formatNumber(stnkBalance, formatDecimals)}
|
||||
ghstBalance={formatNumber(ghstBalance, formatDecimals)}
|
||||
tokenToExclude={upperToken}
|
||||
isUpper={false}
|
||||
ftsoSymbol={ftsoSymbol}
|
||||
stnkSymbol={stnkSymbol}
|
||||
ghstSymbol={ghstSymbol}
|
||||
/>
|
||||
)}
|
||||
|
||||
@ -292,6 +315,9 @@ export const StakeInputArea = ({
|
||||
receiveDecimals={bottomToken === "GHST" ? 18 : 9}
|
||||
isClaim={isClaim}
|
||||
isTrigger={isTrigger}
|
||||
ftsoSymbol={ftsoSymbol}
|
||||
stnkSymbol={stnkSymbol}
|
||||
ghstSymbol={ghstSymbol}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
@ -13,20 +13,23 @@ const TokenModal = ({
|
||||
ghstBalance = "0.00",
|
||||
tokenToExclude,
|
||||
isUpper,
|
||||
ftsoSymbol,
|
||||
stnkSymbol,
|
||||
ghstSymbol
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
|
||||
const TokenItem = ({ name, exclude, isUpper, balance = "0", icon, address = "", price, decimals, ...props }) => {
|
||||
const TokenItem = ({ token, name, exclude, isUpper, balance = "0", icon, address = "", price, decimals, ...props }) => {
|
||||
if (name === exclude) {
|
||||
return <></>;
|
||||
}
|
||||
|
||||
return (
|
||||
<ListItem
|
||||
key={name}
|
||||
button
|
||||
key={token}
|
||||
button="true"
|
||||
onClick={() => {
|
||||
handleSelect({name, isUpper});
|
||||
handleSelect({token, isUpper});
|
||||
handleClose();
|
||||
}}
|
||||
sx={{ borderBottom: `1px solid ${theme.colors.gray[500]}` }}
|
||||
@ -35,7 +38,7 @@ const TokenModal = ({
|
||||
{icon ? (
|
||||
<Avatar src={icon} sx={{ width: "15px", height: "15px" }} />
|
||||
) : (
|
||||
<Token name={name} sx={{ fontSize: "15px" }} />
|
||||
<Token name={token} sx={{ fontSize: "15px" }} />
|
||||
)}
|
||||
|
||||
<ListItemText
|
||||
@ -66,9 +69,9 @@ const TokenModal = ({
|
||||
</Link>
|
||||
</Box>
|
||||
<List>
|
||||
{<TokenItem isUpper={isUpper} exclude={tokenToExclude} name="FTSO" balance={ftsoBalance} />}
|
||||
{<TokenItem isUpper={isUpper} exclude={tokenToExclude} name="STNK" balance={stnkBalance} />}
|
||||
{<TokenItem isUpper={isUpper} exclude={tokenToExclude} name="GHST" balance={ghstBalance} />}
|
||||
{<TokenItem isUpper={isUpper} exclude={tokenToExclude} token="FTSO" name={ftsoSymbol} balance={ftsoBalance} />}
|
||||
{<TokenItem isUpper={isUpper} exclude={tokenToExclude} token="STNK" name={stnkSymbol} balance={stnkBalance} />}
|
||||
{<TokenItem isUpper={isUpper} exclude={tokenToExclude} token="GHST" name={ghstSymbol} balance={ghstBalance} />}
|
||||
</List>
|
||||
</Box>
|
||||
</Dialog>
|
||||
|
@ -17,11 +17,17 @@ import Paper from "../../components/Paper/Paper";
|
||||
import PageTitle from "../../components/PageTitle/PageTitle";
|
||||
import SafariFooter from "../../components/SafariFooter/SafariFooter";
|
||||
|
||||
import { useTokenSymbol } from "../../hooks/tokens";
|
||||
|
||||
const MetricsDashboard = ({ chainId }) => {
|
||||
const theme = useTheme();
|
||||
const isMobileScreen = useMediaQuery("(max-width: 885px)");
|
||||
const isVeryMobileScreen = useMediaQuery("(max-width: 560px)");
|
||||
|
||||
const { symbol: ftsoSymbol } = useTokenSymbol(chainId, "FTSO");
|
||||
const { symbol: stnkSymbol } = useTokenSymbol(chainId, "STNK");
|
||||
const { symbol: ghstSymbol } = useTokenSymbol(chainId, "GHST");
|
||||
|
||||
const xsCalculator = useMemo(() => {
|
||||
return isMobileScreen ? isVeryMobileScreen ? 12 : 6 : 4;
|
||||
}, [isMobileScreen, isVeryMobileScreen])
|
||||
@ -33,22 +39,22 @@ const MetricsDashboard = ({ chainId }) => {
|
||||
<Paper fullWidth enableBackground>
|
||||
<Grid container spacing={2}>
|
||||
<Grid item xs={xsCalculator}>
|
||||
<TreasuryMarketCap chainId={chainId} />
|
||||
<TreasuryMarketCap ftsoSymbol={ftsoSymbol} chainId={chainId} />
|
||||
</Grid>
|
||||
<Grid item xs={xsCalculator}>
|
||||
<FatsoPrice chainId={chainId} />
|
||||
<FatsoPrice ftsoSymbol={ftsoSymbol} chainId={chainId} />
|
||||
</Grid>
|
||||
<Grid item xs={xsCalculator}>
|
||||
<GhostPrice chainId={chainId} />
|
||||
<GhostPrice ghstSymbol={ghstSymbol} ftsoSymbol={ftsoSymbol} chainId={chainId} />
|
||||
</Grid>
|
||||
<Grid item xs={xsCalculator}>
|
||||
<CirculatingSupply chainId={chainId} />
|
||||
<CirculatingSupply stnkSymbol={stnkSymbol} chainId={chainId} />
|
||||
</Grid>
|
||||
<Grid item xs={xsCalculator}>
|
||||
<FatsoBacking chainId={chainId} />
|
||||
<FatsoBacking ftsoSymbol={ftsoSymbol} chainId={chainId} />
|
||||
</Grid>
|
||||
<Grid item xs={xsCalculator}>
|
||||
<CurrentIndex chainId={chainId} />
|
||||
<CurrentIndex ftsoSymbol={ftsoSymbol} chainId={chainId} />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Paper>
|
||||
|
@ -15,10 +15,10 @@ export const CurrentIndex = props => {
|
||||
const _props = {
|
||||
...props,
|
||||
label: `Current Index`,
|
||||
tooltip: `The current index indicates the amount of FTSO a holder would possess if they had staked and maintained 1 FTSO since its launch.`,
|
||||
tooltip: `The current index indicates the amount of ${props.ftsoSymbol} a holder would possess if they had staked and maintained 1 ${props.ftsoSymbol} since its launch.`,
|
||||
};
|
||||
|
||||
if (currentIndex) _props.metric = `${formatNumber(currentIndex, 2)} FTSO`;
|
||||
if (currentIndex) _props.metric = `${formatNumber(currentIndex, 2)} ${props.ftsoSymbol}`;
|
||||
else _props.isLoading = true;
|
||||
|
||||
return <Metric {..._props} />;
|
||||
@ -31,8 +31,8 @@ export const GhostPrice = props => {
|
||||
|
||||
const _props = {
|
||||
...props,
|
||||
label: "GHST " + `Price`,
|
||||
tooltip: "1 GHST = 1 FTSO x Current Index",
|
||||
label: `${props.ghstSymbol} Price`,
|
||||
tooltip: `1 ${props.ghstSymbol} = 1 ${props.ftsoSymbol} x Current Index`,
|
||||
};
|
||||
|
||||
if (ghstPrice) _props.metric = formatCurrency(ghstPrice, 2);
|
||||
@ -46,8 +46,8 @@ export const FatsoPrice = props => {
|
||||
|
||||
const _props = {
|
||||
...props,
|
||||
label: "FTSO " + `Price`,
|
||||
tooltip: `Weighted FTSO Price Across V2 DEXs on the chosen EVM Chain`,
|
||||
label: `${props.ftsoSymbol} Price`,
|
||||
tooltip: `Weighted ${props.ftsoSymbol} Price Across V2 DEXs on the chosen EVM Chain`,
|
||||
};
|
||||
|
||||
if (ftsoPrice) _props.metric = formatCurrency(ftsoPrice, 2);
|
||||
@ -63,7 +63,7 @@ export const CirculatingSupply = props => {
|
||||
const _props = {
|
||||
...props,
|
||||
label: `Circulating / Total`,
|
||||
tooltip: `Circulating supply refers to the amount of STNK in circulation, excluding those held by the protocol in its treasury. However, STNK allocated to Protocol-Owned Liquidity is considered part of the circulating supply.`,
|
||||
tooltip: `Circulating supply refers to the amount of ${props.stnkSymbol} in circulation, excluding those held by the protocol in its treasury. However, ${props.stnkSymbol} allocated to Protocol-Owned Liquidity is considered part of the circulating supply.`,
|
||||
};
|
||||
|
||||
if (circulatingSupply && totalSupply) _props.metric = `${formatNumber(circulatingSupply, 0)}/${formatNumber(totalSupply, 0)}`;
|
||||
@ -83,8 +83,8 @@ export const FatsoBacking = props => {
|
||||
|
||||
const _props = {
|
||||
...props,
|
||||
label: `Backing per FTSO`,
|
||||
tooltip: `The total amount of stablecoins held by the ghostDAO treasury to support the value of each FTSO in circulation.`
|
||||
label: `Backing per ${props.ftsoSymbol}`,
|
||||
tooltip: `The total amount of stablecoins held by the ghostDAO treasury to support the value of each ${props.ftsoSymbol} in circulation.`
|
||||
};
|
||||
|
||||
if (backing) _props.metric = formatCurrency(backing, 2);
|
||||
@ -101,7 +101,7 @@ export const TreasuryMarketCap = props => {
|
||||
const _props = {
|
||||
...props,
|
||||
label: `Market Cap`,
|
||||
tooltip: `Market Cap = FTSO Price × FTSO Total Supply`
|
||||
tooltip: `Market Cap = ${props.ftsoSymbol} Price × ${props.ftsoSymbol} Total Supply`
|
||||
};
|
||||
|
||||
if (marketCap) _props.metric = formatCurrency(marketCap, 2);
|
||||
|
@ -7,7 +7,7 @@ import { SecondaryButton } from "../../../components/Button";
|
||||
import { formatNumber, formatCurrency } from "../../../helpers";
|
||||
import { DecimalBigNumber } from "../../../helpers/DecimalBigNumber";
|
||||
|
||||
import { useBalance } from "../../../hooks/tokens";
|
||||
import { useBalance, useTokenSymbol } from "../../../hooks/tokens";
|
||||
import {
|
||||
useFtsoPrice,
|
||||
useStnkPrice,
|
||||
@ -79,6 +79,11 @@ const TokenInfo = ({ chainId, isMobileScreen }) => {
|
||||
const ghstPrice = useGhstPrice(chainId);
|
||||
const daiPrice = useDaiPrice(chainId);
|
||||
|
||||
const { symbol: daiSymbol } = useTokenSymbol(chainId, "GDAI");
|
||||
const { symbol: ftsoSymbol } = useTokenSymbol(chainId, "FTSO");
|
||||
const { symbol: stnkSymbol } = useTokenSymbol(chainId, "STNK");
|
||||
const { symbol: ghstSymbol } = useTokenSymbol(chainId, "GHST");
|
||||
|
||||
const { balance: ftsoBalance, contractAddress: ftsoAddress } = useBalance(chainId, "FTSO", address);
|
||||
const { balance: stnkBalance, contractAddress: stnkAddress } = useBalance(chainId, "STNK", address);
|
||||
const { balance: ghstBalance, contractAddress: ghstAddress } = useBalance(chainId, "GHST", address);
|
||||
@ -95,10 +100,10 @@ const TokenInfo = ({ chainId, isMobileScreen }) => {
|
||||
to: `${ftsoAddress}`,
|
||||
})}
|
||||
theme={theme}
|
||||
tokenName="FTSO"
|
||||
tokenName={ftsoSymbol}
|
||||
balance={ftsoBalance}
|
||||
price={ftsoPrice}
|
||||
description="FTSO is the native token of the ghostDAO protocol, fully backed by stablecoin reserves held in the ghostDAO treasury."
|
||||
description={`${ftsoSymbol} is the native token of the ghostDAO protocol, fully backed by stablecoin reserves held in the ghostDAO treasury.`}
|
||||
/>
|
||||
<TokenTab
|
||||
isMobileScreen={isMobileScreen}
|
||||
@ -108,10 +113,10 @@ const TokenInfo = ({ chainId, isMobileScreen }) => {
|
||||
to: `${stnkAddress}`,
|
||||
})}
|
||||
theme={theme}
|
||||
tokenName="STNK"
|
||||
tokenName={stnkSymbol}
|
||||
balance={stnkBalance}
|
||||
price={stnkPrice}
|
||||
description="STNK is a receipt for staked FTSO, growing with staking rewards. When unstaked, it’s burned for FTSO at a 1:1 ratio."
|
||||
description={`${stnkSymbol} is a receipt for staked ${ftsoSymbol}, growing with staking rewards. When unstaked, it’s burned for ${ftsoSymbol} at a 1:1 ratio.`}
|
||||
/>
|
||||
<TokenTab
|
||||
isMobileScreen={isMobileScreen}
|
||||
@ -121,20 +126,20 @@ const TokenInfo = ({ chainId, isMobileScreen }) => {
|
||||
to: `${ghstAddress}`,
|
||||
})}
|
||||
theme={theme}
|
||||
tokenName="GHST"
|
||||
tokenName={ghstSymbol}
|
||||
balance={ghstBalance}
|
||||
price={ghstPrice}
|
||||
description="GHST enables ghostDAO to have on-chain governance and to be truly cross-chain. GHST Price = FTSO Price x Current Index."
|
||||
description={`${ghstSymbol} enables ghostDAO to have on-chain governance and to be truly cross-chain. ${ghstSymbol} Price = ${ftsoSymbol} Price x Current Index.`}
|
||||
/>
|
||||
<TokenTab
|
||||
isMobileScreen={isMobileScreen}
|
||||
tokenUrl="/faucet"
|
||||
tokenUrlParams=""
|
||||
theme={theme}
|
||||
tokenName="gDAI"
|
||||
tokenName={daiSymbol}
|
||||
balance={daiBalance}
|
||||
price={daiPrice}
|
||||
description="FTSO is backed by a treasury reserve of crypto assets, with gDAI being the primary and most liquid asset."
|
||||
description={`${ftsoSymbol} is backed by a treasury reserve of crypto assets, with ${daiSymbol} being the primary and most liquid asset.`}
|
||||
/>
|
||||
</Box>
|
||||
</Grid>
|
||||
|
@ -14,7 +14,8 @@ import { abi as TreasuryAbi } from "../../abi/GhostTreasury.json";
|
||||
import { abi as BondingCalculatorAbi } from "../../abi/GhostBondingCalculator.json";
|
||||
|
||||
import { useFtsoPrice } from "../prices";
|
||||
import { getTokenAddress, getTokenIcons, getTokenName, getBondNameDisplayName, getTokenPurchaseLink } from "../helpers";
|
||||
import { useTokenSymbol, useTokenSymbols } from "../tokens";
|
||||
import { getTokenAddress, getTokenIcons, getBondNameDisplayName, getTokenPurchaseLink } from "../helpers";
|
||||
import { DecimalBigNumber } from "../../helpers/DecimalBigNumber";
|
||||
import { shorten } from "../../helpers";
|
||||
|
||||
@ -104,6 +105,9 @@ export const useLiveBonds = (chainId) => {
|
||||
})
|
||||
});
|
||||
|
||||
const { symbols: quoteTokenSymbols } = useTokenSymbols(chainId, markets?.map(m => m.result?.at(1)));
|
||||
const { symbol: baseTokenSymbol } = useTokenSymbol(chainId, "FTSO");
|
||||
|
||||
const liveBonds = liveIndexesRaw ? liveIndexesRaw.map((bondIndex, index) => {
|
||||
const id = Number(bondIndex);
|
||||
|
||||
@ -119,6 +123,7 @@ export const useLiveBonds = (chainId) => {
|
||||
const markdown = markdowns?.at(index).result
|
||||
? new DecimalBigNumber(markdowns.at(index).result, quoteTokenDecimals)
|
||||
: new DecimalBigNumber(1n, 0);
|
||||
const quoteTokenSymbol = quoteTokenSymbols?.at(index).result ? quoteTokenSymbols.at(index).result : "";
|
||||
|
||||
const quoteTokenPerBaseToken = new DecimalBigNumber(marketPrice, 9);
|
||||
const priceInUsd = quoteTokenPerUsd.mul(quoteTokenPerBaseToken).mul(markdown);
|
||||
@ -140,19 +145,20 @@ export const useLiveBonds = (chainId) => {
|
||||
);
|
||||
|
||||
const zero = new DecimalBigNumber(0n, 0);
|
||||
const bondName = `${baseTokenSymbol}/${quoteTokenSymbol}`;
|
||||
|
||||
return {
|
||||
id,
|
||||
discount,
|
||||
displayName: getBondNameDisplayName(chainId, markets?.at(index).result?.at(1)),
|
||||
displayName: getBondNameDisplayName(chainId, bondName, quoteTokenAddress),
|
||||
baseToken: {
|
||||
name: "FTSO",
|
||||
name: quoteTokenSymbol,
|
||||
purchaseUrl: getTokenPurchaseLink(chainId, ""),
|
||||
icons: ["FTSO"],
|
||||
tokenAddress: getTokenAddress(chainId, "FTSO")
|
||||
},
|
||||
quoteToken: {
|
||||
name: getTokenName(chainId, quoteTokenAddress),
|
||||
name: quoteTokenName,
|
||||
purchaseUrl: getTokenPurchaseLink(chainId, quoteTokenAddress),
|
||||
icons: getTokenIcons(chainId, quoteTokenAddress),
|
||||
decimals: quoteTokenDecimals,
|
||||
@ -229,14 +235,17 @@ export const useNotes = (chainId, address) => {
|
||||
}),
|
||||
});
|
||||
|
||||
const { symbols: quoteTokenSymbols } = useTokenSymbols(chainId, markets?.map(m => m.result?.at(1)));
|
||||
|
||||
const notes = indexesFor ? indexesFor.map((noteIndex, index) => {
|
||||
const id = Number(noteIndex);
|
||||
const quoteTokenAddress = markets?.at(index).result?.at(1) ? markets.at(index).result.at(1) : "";
|
||||
const quoteTokenSymbol = quoteTokenSymbols?.at(index).result ? quoteTokenSymbols.at(index).result : "";
|
||||
|
||||
return {
|
||||
id,
|
||||
quoteToken: {
|
||||
name: getTokenName(chainId, quoteTokenAddress),
|
||||
name: quoteTokenSymbol,
|
||||
icons: getTokenIcons(chainId, quoteTokenAddress),
|
||||
},
|
||||
vesting: terms?.at(index).result?.at(2) ? terms.at(index).result.at(2) : 0,
|
||||
|
@ -12,9 +12,13 @@ import { abi as StinkyAbi } from "../abi/Stinky.json";
|
||||
import { abi as GhostAbi } from "../abi/Ghost.json";
|
||||
import { abi as Erc20Abi } from "../abi/ERC20.json";
|
||||
|
||||
// TBD: should be extended on new tokens
|
||||
export const getTokenAbi = (name) => {
|
||||
let abi = Erc20Abi;
|
||||
switch (name?.toUpperCase()) {
|
||||
case "DAI":
|
||||
abi = DaiAbi;
|
||||
break;
|
||||
case "GDAI":
|
||||
abi = DaiAbi;
|
||||
break;
|
||||
@ -31,9 +35,13 @@ export const getTokenAbi = (name) => {
|
||||
return abi;
|
||||
}
|
||||
|
||||
// TBD: should be extended on new tokens
|
||||
export const getTokenDecimals = (name) => {
|
||||
let decimals = 18;
|
||||
switch (name?.toUpperCase()) {
|
||||
case "DAI":
|
||||
decimals = 18;
|
||||
break;
|
||||
case "GDAI":
|
||||
decimals = 18;
|
||||
break;
|
||||
@ -50,9 +58,13 @@ export const getTokenDecimals = (name) => {
|
||||
return decimals;
|
||||
}
|
||||
|
||||
// TBD: should be extended on new tokens
|
||||
export const getTokenAddress = (chainId, name) => {
|
||||
let address = name;
|
||||
switch (name?.toUpperCase()) {
|
||||
case "DAI":
|
||||
address = DAI_ADDRESSES[chainId];
|
||||
break;
|
||||
case "GDAI":
|
||||
address = DAI_ADDRESSES[chainId];
|
||||
break;
|
||||
@ -72,6 +84,7 @@ export const getTokenAddress = (chainId, name) => {
|
||||
return address;
|
||||
}
|
||||
|
||||
// TBD: should be extended on new tokens
|
||||
export const getTokenIcons = (chainId, address) => {
|
||||
let icons = [""];
|
||||
switch (address) {
|
||||
@ -94,39 +107,11 @@ export const getTokenIcons = (chainId, address) => {
|
||||
return icons;
|
||||
}
|
||||
|
||||
export const getTokenName = (chainId, address) => {
|
||||
let name = "";
|
||||
switch (address) {
|
||||
case DAI_ADDRESSES[chainId]:
|
||||
name = "gDAI";
|
||||
break;
|
||||
case FTSO_ADDRESSES[chainId]:
|
||||
name = "FTSO";
|
||||
break;
|
||||
case STNK_ADDRESSES[chainId]:
|
||||
name = "STNK";
|
||||
break;
|
||||
case GHST_ADDRESSES[chainId]:
|
||||
name = "GHST";
|
||||
break;
|
||||
case FTSO_DAI_LP_ADDRESSES[chainId]:
|
||||
name = "UNI-V2";
|
||||
break;
|
||||
export const getBondNameDisplayName = (chainId, stringValue, tokenAddress) => {
|
||||
if (tokenAddress.toUpperCase() === FTSO_DAI_LP_ADDRESSES[chainId].toUpperCase()) {
|
||||
stringValue = `LP ${stringValue}`;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
export const getBondNameDisplayName = (chainId, tokenAddress) => {
|
||||
let bondName = "";
|
||||
switch (tokenAddress) {
|
||||
case DAI_ADDRESSES[chainId]:
|
||||
bondName = "FTSO/gDAI";
|
||||
break;
|
||||
case FTSO_DAI_LP_ADDRESSES[chainId]:
|
||||
bondName = "LP FTSO/gDAI"
|
||||
break;
|
||||
}
|
||||
return bondName;
|
||||
return stringValue;
|
||||
}
|
||||
|
||||
export const getTokenPurchaseLink = (chainId, tokenAddress) => {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { useReadContract, useToken, useBalance as useInnerBalance } from "wagmi";
|
||||
import { useReadContract, useReadContracts, useToken, useBalance as useInnerBalance } from "wagmi";
|
||||
import { simulateContract, writeContract, waitForTransactionReceipt } from "@wagmi/core";
|
||||
import toast from "react-hot-toast";
|
||||
|
||||
@ -72,6 +72,23 @@ export const useTokenSymbol = (chainId, name) => {
|
||||
return { symbol, refetch };
|
||||
}
|
||||
|
||||
export const useTokenSymbols = (chainId, names) => {
|
||||
const { data: symbols } = useReadContracts({
|
||||
contracts: names?.map((name) => {
|
||||
const contractAddress = getTokenAddress(chainId, name);
|
||||
return {
|
||||
abi: getTokenAbi(name),
|
||||
address: contractAddress,
|
||||
functionName: "symbol",
|
||||
scopeKey: `symbol-${contractAddress}-${chainId}`,
|
||||
chainId: chainId,
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
return { symbols };
|
||||
}
|
||||
|
||||
export const useConversionRate = (chainId, name) => {
|
||||
const contractAddress = getTokenAddress(chainId, name);
|
||||
const { data: rateRaw } = useReadContract({
|
||||
|
Loading…
Reference in New Issue
Block a user