diff --git a/package.json b/package.json index a528549..d996006 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "ghost-dao-interface", "private": true, - "version": "0.1.2", + "version": "0.1.3", "type": "module", "scripts": { "dev": "vite", diff --git a/src/assets/tokens/eGHST.svg b/src/assets/tokens/FTSO.svg similarity index 100% rename from src/assets/tokens/eGHST.svg rename to src/assets/tokens/FTSO.svg diff --git a/src/assets/tokens/sGHST.svg b/src/assets/tokens/STNK.svg similarity index 100% rename from src/assets/tokens/sGHST.svg rename to src/assets/tokens/STNK.svg diff --git a/src/components/Sidebar/NavContent.jsx b/src/components/Sidebar/NavContent.jsx index b499421..d6139ca 100644 --- a/src/components/Sidebar/NavContent.jsx +++ b/src/components/Sidebar/NavContent.jsx @@ -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 ( @@ -82,10 +86,10 @@ const NavContent = ({ chainId, addressChainId }) => { - FTSO Price: {formatCurrency(ftsoPrice, 2)} + {ftsoSymbol} Price: {formatCurrency(ftsoPrice, 2)} - GHST Price: {formatCurrency(ghstPrice, 2)} + {ghstSymbol} Price: {formatCurrency(ghstPrice, 2)} diff --git a/src/components/Token/Token.jsx b/src/components/Token/Token.jsx index e57af9d..bb06b0a 100644 --- a/src/components/Token/Token.jsx +++ b/src/components/Token/Token.jsx @@ -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; diff --git a/src/components/TopBar/Wallet/Token.tsx b/src/components/TopBar/Wallet/Token.tsx index 0cd273e..72f8089 100644 --- a/src/components/TopBar/Wallet/Token.tsx +++ b/src/components/TopBar/Wallet/Token.tsx @@ -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 > - Get on {symbol === "GDAI" ? "Faucet" : "Uniswap"} + Get on {symbol.toUpperCase() === "GDAI" ? "Faucet" : "Uniswap"} @@ -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 => ( - + {alwaysShowTokens.map((token, i) => ( + ))} ); diff --git a/src/containers/Bond/Bonds.jsx b/src/containers/Bond/Bonds.jsx index 5ecddb5..058c831 100644 --- a/src/containers/Bond/Bonds.jsx +++ b/src/containers/Bond/Bonds.jsx @@ -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 ( - + { isLoading={false} /> diff --git a/src/containers/Bond/components/BondInfoText.jsx b/src/containers/Bond/components/BondInfoText.jsx index e8c7b87..4352843 100644 --- a/src/containers/Bond/components/BondInfoText.jsx +++ b/src/containers/Bond/components/BondInfoText.jsx @@ -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.   - {formatCurrency(amountInBaseToken, formatDecimals, "FTSO")} + {formatCurrency(amountInBaseToken, formatDecimals, ftsoSymbol)} {" "} {!!currentIndex && ( - (≈{formatCurrency(amountInBaseToken.div(currentIndex), formatDecimals, "GHST")}) + (≈{formatCurrency(amountInBaseToken.div(currentIndex), formatDecimals, ghstSymbol)}) )} @@ -182,8 +185,8 @@ const BondInputArea = ({ balance={ {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)})`} } /> @@ -191,7 +194,7 @@ const BondInputArea = ({ } - 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`} /> { 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 }) => { diff --git a/src/containers/Bond/components/ClaimBonds.jsx b/src/containers/Bond/components/ClaimBonds.jsx index 6dc4a1b..48b6f03 100644 --- a/src/containers/Bond/components/ClaimBonds.jsx +++ b/src/containers/Bond/components/ClaimBonds.jsx @@ -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" } }} > - - + + @@ -105,8 +110,8 @@ export const ClaimBonds = ({ chainId, address, secondsTo }) => { {isPayoutGhst - ? formatCurrency(totalClaimableBalance, 5, "GHST") - : formatCurrency(currentIndex.mul(totalClaimableBalance), 5, "STNK") + ? formatCurrency(totalClaimableBalance, 5, ghstSymbol) + : formatCurrency(currentIndex.mul(totalClaimableBalance), 5, stnkSymbol) } @@ -152,8 +157,8 @@ export const ClaimBonds = ({ chainId, address, secondsTo }) => { Payout {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) } @@ -208,8 +213,8 @@ export const ClaimBonds = ({ chainId, address, secondsTo }) => { {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) } diff --git a/src/containers/Dex/TokenModal.jsx b/src/containers/Dex/TokenModal.jsx index e904adc..fc0642d 100644 --- a/src/containers/Dex/TokenModal.jsx +++ b/src/containers/Dex/TokenModal.jsx @@ -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)) { diff --git a/src/containers/Faucet/Faucet.jsx b/src/containers/Faucet/Faucet.jsx index 79e75b3..9280ea1 100644 --- a/src/containers/Faucet/Faucet.jsx +++ b/src/containers/Faucet/Faucet.jsx @@ -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 }) => { - Get {faucetToken.name} + Get {faucetSymbol} {!isSemiSmallScreen && Check on {scanInfo.name} } @@ -167,11 +156,11 @@ const Faucet = ({ chainId, address, config, connect }) => { {!isVerySmallScreen && You will get:} - {formatCurrency(estimatedAmount, 5, faucetToken.name)} + {formatCurrency(estimatedAmount, 5, faucetSymbol)} - {!isVerySmallScreen && Your {faucetToken.name} balance:} - {formatCurrency(daiBalance, 5, faucetToken.name)} + {!isVerySmallScreen && Your {faucetSymbol} balance:} + {formatCurrency(daiBalance, 5, faucetSymbol)} { 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 ( - + { > - + - + - + diff --git a/src/containers/Stake/components/ClaimConfirmationModal.jsx b/src/containers/Stake/components/ClaimConfirmationModal.jsx index d8d7dac..413de21 100644 --- a/src/containers/Stake/components/ClaimConfirmationModal.jsx +++ b/src/containers/Stake/components/ClaimConfirmationModal.jsx @@ -55,7 +55,7 @@ const ClaimConfirmationModal = (props) => { /> - {props.outputToken} + {props.outputTokenName} diff --git a/src/containers/Stake/components/ClaimsArea.jsx b/src/containers/Stake/components/ClaimsArea.jsx index b7630a0..62c17d5 100644 --- a/src/containers/Stake/components/ClaimsArea.jsx +++ b/src/containers/Stake/components/ClaimsArea.jsx @@ -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"} > - Your active {isPayoutGhst ? "GHST" : "STNK"} claim + Your active {isPayoutGhst ? ghstSymbol : stnkSymbol} claim { onChange={(_, view) => setIsPayoutGhstInner(view === 1)} TabIndicatorProps={{ style: { display: "none" } }} > - - + + } @@ -124,6 +129,8 @@ export const ClaimsArea = ({ chainId, address, epoch }) => { claim={claim} epoch={epoch} isClaimable={claim.expiry > epoch.number} + stnkSymbol={stnkSymbol} + ghstSymbol={ghstSymbol} /> ) : ( @@ -142,6 +149,8 @@ export const ClaimsArea = ({ chainId, address, epoch }) => { claim={claim} epoch={epoch} isClaimable={claim.expiry > epoch.number} + stnkSymbol={stnkSymbol} + ghstSymbol={ghstSymbol} />
@@ -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 ( - + - {isPayoutGhst ? "GHST" : "STNK"} + {isPayoutGhst ? ghstSymbol : stnkSymbol} - {`${formatNumber(prepareBalance, 5)} ${isPayoutGhst ? "GHST" : "STNK"}`} + {`${formatNumber(prepareBalance, 5)} ${isPayoutGhst ? ghstSymbol : stnkSymbol}`} @@ -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 ( - + - {isPayoutGhst ? "GHST" : "STNK"} + {isPayoutGhst ? ghstSymbol : stnkSymbol} diff --git a/src/containers/Stake/components/FarmPools.jsx b/src/containers/Stake/components/FarmPools.jsx index 277426f..eba7cfd 100644 --- a/src/containers/Stake/components/FarmPools.jsx +++ b/src/containers/Stake/components/FarmPools.jsx @@ -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 ( - +
Asset diff --git a/src/containers/Stake/components/Metric.jsx b/src/containers/Stake/components/Metric.jsx index 96afecf..e05e5a9 100644 --- a/src/containers/Stake/components/Metric.jsx +++ b/src/containers/Stake/components/Metric.jsx @@ -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)}`; diff --git a/src/containers/Stake/components/StakeConfirmationModal.jsx b/src/containers/Stake/components/StakeConfirmationModal.jsx index d777635..fb2d16e 100644 --- a/src/containers/Stake/components/StakeConfirmationModal.jsx +++ b/src/containers/Stake/components/StakeConfirmationModal.jsx @@ -39,7 +39,7 @@ const StakeConfirmationModal = (props) => { checkedIcon={} /> } - 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`} /> @@ -115,7 +115,7 @@ const StakeConfirmationModal = (props) => { /> - {props.upperToken} + {props.upperToken === "FTSO" ? props.ftsoSymbol : props.upperToken === "STNK" ? props.stnkSymbol : props.ghstSymbol} @@ -127,7 +127,7 @@ const StakeConfirmationModal = (props) => { /> - {props.bottomToken} + {props.bottomToken === "FTSO" ? props.ftsoSymbol : props.bottomToken === "STNK" ? props.stnkSymbol : props.ghstSymbol} @@ -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 diff --git a/src/containers/Stake/components/StakeInputArea.jsx b/src/containers/Stake/components/StakeInputArea.jsx index 5243f2a..553de9a 100644 --- a/src/containers/Stake/components/StakeInputArea.jsx +++ b/src/containers/Stake/components/StakeInputArea.jsx @@ -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 ( handleModal(true)} inputProps={{ "data-testid": `${tokenName.toLowerCase()}-input`, min: "0" }} value={tokenAmount} @@ -228,24 +245,30 @@ export const StakeInputArea = ({ {upperTokenModalOpen && ( 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 && ( 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} /> ); diff --git a/src/containers/Stake/components/TokenModal.jsx b/src/containers/Stake/components/TokenModal.jsx index 0beeae9..d97b76e 100644 --- a/src/containers/Stake/components/TokenModal.jsx +++ b/src/containers/Stake/components/TokenModal.jsx @@ -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 ( { - handleSelect({name, isUpper}); + handleSelect({token, isUpper}); handleClose(); }} sx={{ borderBottom: `1px solid ${theme.colors.gray[500]}` }} @@ -35,7 +38,7 @@ const TokenModal = ({ {icon ? ( ) : ( - + )} - {} - {} - {} + {} + {} + {} diff --git a/src/containers/TreasuryDashboard/TreasuryDashboard.jsx b/src/containers/TreasuryDashboard/TreasuryDashboard.jsx index e0ab880..69f5026 100644 --- a/src/containers/TreasuryDashboard/TreasuryDashboard.jsx +++ b/src/containers/TreasuryDashboard/TreasuryDashboard.jsx @@ -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 }) => { - + - + - + - + - + - + diff --git a/src/containers/TreasuryDashboard/components/Metric.jsx b/src/containers/TreasuryDashboard/components/Metric.jsx index 1d13d3f..e0a0c1e 100644 --- a/src/containers/TreasuryDashboard/components/Metric.jsx +++ b/src/containers/TreasuryDashboard/components/Metric.jsx @@ -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 ; @@ -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); diff --git a/src/containers/TreasuryDashboard/components/TokenInfo.jsx b/src/containers/TreasuryDashboard/components/TokenInfo.jsx index ce5d1ee..739a419 100644 --- a/src/containers/TreasuryDashboard/components/TokenInfo.jsx +++ b/src/containers/TreasuryDashboard/components/TokenInfo.jsx @@ -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.`} /> { 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.`} /> { 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.`} /> diff --git a/src/hooks/bonds/index.jsx b/src/hooks/bonds/index.jsx index 19536f2..17e7b15 100644 --- a/src/hooks/bonds/index.jsx +++ b/src/hooks/bonds/index.jsx @@ -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, diff --git a/src/hooks/helpers.js b/src/hooks/helpers.js index 52231ec..e4a47fe 100644 --- a/src/hooks/helpers.js +++ b/src/hooks/helpers.js @@ -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) => { diff --git a/src/hooks/tokens/index.js b/src/hooks/tokens/index.js index f3e121e..0734e31 100644 --- a/src/hooks/tokens/index.js +++ b/src/hooks/tokens/index.js @@ -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({