Compare commits
5 Commits
5b067f50f0
...
6213504ef3
| Author | SHA1 | Date | |
|---|---|---|---|
| 6213504ef3 | |||
| 6156549754 | |||
| 55b047e02f | |||
| 643211efc9 | |||
| ef129af5ad |
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "ghost-dao-interface",
|
||||
"private": true,
|
||||
"version": "0.6.8",
|
||||
"version": "0.6.13",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import React from "react";
|
||||
import { useMemo } from "react";
|
||||
|
||||
import "./Sidebar.scss";
|
||||
|
||||
@ -26,7 +26,7 @@ import HubIcon from '@mui/icons-material/Hub';
|
||||
import PublicIcon from '@mui/icons-material/Public';
|
||||
import ForkRightIcon from '@mui/icons-material/ForkRight';
|
||||
import GavelIcon from '@mui/icons-material/Gavel';
|
||||
import ForumIcon from '@mui/icons-material/Forum';
|
||||
import CasinoIcon from '@mui/icons-material/Casino';
|
||||
import ErrorOutlineIcon from '@mui/icons-material/ErrorOutline';
|
||||
import BookIcon from '@mui/icons-material/Book';
|
||||
import CurrencyExchangeIcon from '@mui/icons-material/CurrencyExchange';
|
||||
@ -41,6 +41,7 @@ import WrapIcon from "../Icon/WrapIcon";
|
||||
|
||||
import { isNetworkAvailable, isNetworkLegacy, isGovernanceAvailable } from "../../constants";
|
||||
import { AVAILABLE_DEXES } from "../../constants/dexes";
|
||||
import { GATEKEEPER_ADDRESSES } from "../../constants/addresses";
|
||||
import { ECOSYSTEM } from "../../constants/ecosystem";
|
||||
import { DecimalBigNumber } from "../../helpers/DecimalBigNumber";
|
||||
import { sortBondsByDiscount, formatCurrency } from "../../helpers";
|
||||
@ -51,7 +52,6 @@ import ShowerIcon from '@mui/icons-material/Shower';
|
||||
import WifiProtectedSetupIcon from '@mui/icons-material/WifiProtectedSetup';
|
||||
|
||||
import { useTokenSymbol } from "../../hooks/tokens";
|
||||
import { useFtsoPrice, useGhstPrice, useGhostedSupplyPrice } from "../../hooks/prices";
|
||||
import { useLiveBonds } from "../../hooks/bonds/index";
|
||||
import pckg from "../../../package.json"
|
||||
|
||||
@ -69,13 +69,15 @@ const StyledBox = styled(Box)(({ theme }) => ({
|
||||
|
||||
const NavContent = ({ chainId, addressChainId }) => {
|
||||
const { liveBonds: ghostBonds } = useLiveBonds(chainId);
|
||||
const ftsoPrice = useFtsoPrice(chainId);
|
||||
const ghstPrice = useGhstPrice(chainId);
|
||||
const ghostedSupplyPrice = useGhostedSupplyPrice(chainId);
|
||||
|
||||
const { symbol: ftsoSymbol } = useTokenSymbol(chainId, "FTSO");
|
||||
const { symbol: ghstSymbol } = useTokenSymbol(chainId, "GHST");
|
||||
|
||||
const bridgeNumbers = useMemo(() => {
|
||||
const connectedNetworks = Object.keys(GATEKEEPER_ADDRESSES).length;
|
||||
const number = 1 + connectedNetworks * 3;
|
||||
return `(${number}, ${number})`;
|
||||
}, [chainId]);
|
||||
|
||||
return (
|
||||
<Paper className="dapp-sidebar">
|
||||
<Box className="dapp-sidebar-inner" display="flex" justifyContent="space-between" flexDirection="column">
|
||||
@ -92,17 +94,6 @@ const NavContent = ({ chainId, addressChainId }) => {
|
||||
Version {pckg.version}
|
||||
</Box>
|
||||
</Link>
|
||||
<Box display="flex" flexDirection="column" mt="10px">
|
||||
<Box fontSize="12px" fontWeight="500" lineHeight={"15px"}>
|
||||
{ftsoSymbol} Price: {formatCurrency(ftsoPrice, 2)}
|
||||
</Box>
|
||||
<Box fontSize="12px" fontWeight="500" lineHeight="15px">
|
||||
{ghstSymbol} Price: {formatCurrency(ghstPrice, 2)}
|
||||
</Box>
|
||||
<Box fontSize="12px" fontWeight="500" lineHeight={"15px"}>
|
||||
GHOSTed Supply: {formatCurrency(ghostedSupplyPrice, 2)}
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
<Box className="menu-divider">
|
||||
@ -114,14 +105,35 @@ const NavContent = ({ chainId, addressChainId }) => {
|
||||
{isNetworkAvailable(chainId, addressChainId) &&
|
||||
<>
|
||||
<NavItem icon={DashboardIcon} label={`Dashboard`} to="/dashboard" />
|
||||
{isNetworkLegacy(chainId)
|
||||
? <NavItem icon={ShowerIcon} label={`Faucet`} to="/faucet" />
|
||||
: <NavItem icon={WifiProtectedSetupIcon} label={`Wrapper`} to="/wrapper" />
|
||||
}
|
||||
<NavItem
|
||||
icon={CurrencyExchangeIcon}
|
||||
label={`(3, 3) Swap`}
|
||||
to={'/dex/uniswap'}
|
||||
children={
|
||||
AVAILABLE_DEXES[chainId].length > 1 && <AccordionDetails style={{ margin: "0 0 -10px", display: "flex", flexDirection: "column", gap: "10px" }}>
|
||||
{AVAILABLE_DEXES[chainId].map((dex, index) => {
|
||||
return (
|
||||
<Link
|
||||
component={NavLink}
|
||||
to={`/dex/${dex.name.toLowerCase()}`}
|
||||
key={index}
|
||||
style={{ textDecoration: "none" }}
|
||||
>
|
||||
<Box display="flex" alignItems="center" justifyContent="end">
|
||||
<GhostStyledIcon color="inherit" viewBox={dex.viewBox} component={dex.icon} />
|
||||
{dex.name} v2
|
||||
</Box>
|
||||
</Link>
|
||||
)
|
||||
})}
|
||||
</AccordionDetails>
|
||||
}
|
||||
/>
|
||||
<NavItem icon={StakeIcon} label={`(3, 3) Stake`} to="/stake" />
|
||||
<NavItem
|
||||
defaultExpanded
|
||||
icon={BondIcon}
|
||||
label={`Bond`}
|
||||
label={`(1, 1) Bond`}
|
||||
to="/bonds"
|
||||
children={
|
||||
<AccordionDetails style={{ margin: "0 0 -20px", display: "flex", flexDirection: "column", gap: "10px" }}>
|
||||
@ -154,32 +166,7 @@ const NavContent = ({ chainId, addressChainId }) => {
|
||||
</AccordionDetails>
|
||||
}
|
||||
/>
|
||||
<NavItem
|
||||
icon={CurrencyExchangeIcon}
|
||||
label={`Dex`}
|
||||
to={'/dex/uniswap'}
|
||||
children={
|
||||
<AccordionDetails style={{ margin: "0 0 -10px", display: "flex", flexDirection: "column", gap: "10px" }}>
|
||||
{AVAILABLE_DEXES[chainId].map((dex, index) => {
|
||||
return (
|
||||
<Link
|
||||
component={NavLink}
|
||||
to={`/dex/${dex.name.toLowerCase()}`}
|
||||
key={index}
|
||||
style={{ textDecoration: "none" }}
|
||||
>
|
||||
<Box display="flex" alignItems="center" justifyContent="end">
|
||||
<GhostStyledIcon color="inherit" viewBox={dex.viewBox} component={dex.icon} />
|
||||
{dex.name} v2
|
||||
</Box>
|
||||
</Link>
|
||||
)
|
||||
})}
|
||||
</AccordionDetails>
|
||||
}
|
||||
/>
|
||||
<NavItem icon={StakeIcon} label={`Stake`} to="/stake" />
|
||||
<NavItem icon={ForkRightIcon} label={`Bridge`} to="/bridge" />
|
||||
<NavItem icon={ForkRightIcon} label={`${bridgeNumbers} GHOST Staking`} to="/bridge" />
|
||||
{isGovernanceAvailable(chainId, addressChainId) && <NavItem icon={GavelIcon} label={`Governance`} to="/governance" />}
|
||||
<Box className="menu-divider">
|
||||
<Divider />
|
||||
@ -192,9 +179,8 @@ const NavContent = ({ chainId, addressChainId }) => {
|
||||
|
||||
<Box>
|
||||
<NavItem href="http://ecosystem.ghostchain.io" icon={PublicIcon} label={`Ecosystem`} />
|
||||
<NavItem href="http://ghostchain.io/builders" icon={ForumIcon} label={`Forum`} />
|
||||
<NavItem href="https://docs.ghostchain.io/" icon={BookIcon} label={`Docs`} />
|
||||
<NavItem href="https://git.ghostchain.io/ghostchain/ghost-dao-contracts/issues" icon={ErrorOutlineIcon} label={`Git Issues`} />
|
||||
<NavItem href="https://ghostchain.io/game-theory-3-3" icon={CasinoIcon} label={`(3, 3) Game Theory`} />
|
||||
<NavItem href="https://docs.ghostchain.io/" icon={BookIcon} label={`Documentation`} />
|
||||
<StyledBox display="flex" justifyContent="space-around" paddingY="24px">
|
||||
<Link href="https://git.ghostchain.io/ghostchain/ghost-dao-contracts" target="_blank" rel="noopener noreferrer">
|
||||
<GhostStyledIcon viewBox="0 0 24 24" component={GitHubIcon} className={classes.gray} />
|
||||
|
||||
@ -27,7 +27,6 @@ import {
|
||||
useNativePrice,
|
||||
useReservePrice,
|
||||
useFtsoPrice,
|
||||
useStnkPrice,
|
||||
useGhstPrice
|
||||
} from "../../../hooks/prices";
|
||||
import { useLpValuation } from "../../../hooks/treasury";
|
||||
@ -178,11 +177,6 @@ export const useWallet = (chainId, userAddress) => {
|
||||
refetch: ftsoRefetch,
|
||||
contractAddress: ftsoAddress,
|
||||
} = useBalance(chainId, "FTSO", userAddress);
|
||||
const {
|
||||
balance: stnkBalance,
|
||||
refetch: stnkRefetch,
|
||||
contractAddress: stnkAddress,
|
||||
} = useBalance(chainId, "STNK", userAddress);
|
||||
const {
|
||||
balance: ghstBalance,
|
||||
refetch: ghstRefetch,
|
||||
@ -200,7 +194,6 @@ export const useWallet = (chainId, userAddress) => {
|
||||
const nativePrice = useNativePrice(chainId);
|
||||
const reservePrice = useReservePrice(chainId);
|
||||
const ftsoPrice = useFtsoPrice(chainId);
|
||||
const stnkPrice = useStnkPrice(chainId);
|
||||
const ghstPrice = useGhstPrice(chainId);
|
||||
const lpReserveFtsoPrice = useLpValuation(chainId, "RESERVE_FTSO", 1000000000000000000n);
|
||||
|
||||
@ -209,7 +202,6 @@ export const useWallet = (chainId, userAddress) => {
|
||||
const nativeSymbol = config?.getClient()?.chain?.nativeCurrency?.symbol;
|
||||
const { symbol: reserveSymbol } = useTokenSymbol(chainId, "RESERVE");
|
||||
const { symbol: ftsoSymbol } = useTokenSymbol(chainId, "FTSO");
|
||||
const { symbol: stnkSymbol } = useTokenSymbol(chainId, "STNK");
|
||||
const { symbol: ghstSymbol } = useTokenSymbol(chainId, "GHST");
|
||||
const { symbol: lpReserveFtsoSymbol } = useTokenSymbol(chainId, "RESERVE_FTSO");
|
||||
|
||||
@ -235,7 +227,6 @@ export const useWallet = (chainId, userAddress) => {
|
||||
balance: nativeBalance,
|
||||
price: nativePrice,
|
||||
refetch: nativeBalanceRefetch,
|
||||
faucetPath: isNetworkLegacy(chainId) ? "/faucet" : "/wrapper",
|
||||
},
|
||||
reserve: {
|
||||
symbol: reserveSymbol,
|
||||
@ -247,7 +238,6 @@ export const useWallet = (chainId, userAddress) => {
|
||||
? "https://ghostchain.io/wp-content/uploads/2025/03/gDAI.svg"
|
||||
: "https://ghostchain.io/wp-content/uploads/2025/11/6A-Classic-ETC-Token.svg",
|
||||
refetch: reserveRefetch,
|
||||
faucetPath: isNetworkLegacy(chainId) ? "/faucet" : "/wrapper",
|
||||
},
|
||||
ftso: {
|
||||
symbol: ftsoSymbol,
|
||||
@ -258,15 +248,6 @@ export const useWallet = (chainId, userAddress) => {
|
||||
externalUrl: "https://ghostchain.io/wp-content/uploads/2025/03/eGHST.svg",
|
||||
refetch: ftsoRefetch,
|
||||
},
|
||||
stnk: {
|
||||
symbol: stnkSymbol,
|
||||
address: stnkAddress,
|
||||
balance: stnkBalance,
|
||||
price: stnkPrice,
|
||||
icons: ["STNK"],
|
||||
externalUrl: "https://ghostchain.io/wp-content/uploads/2025/03/sGHST.svg",
|
||||
refetch: stnkRefetch,
|
||||
},
|
||||
ghst: {
|
||||
symbol: ghstSymbol,
|
||||
address: ghstAddress,
|
||||
@ -301,7 +282,7 @@ export const useWallet = (chainId, userAddress) => {
|
||||
|
||||
export const Tokens = ({ address, tokens, onClose }) => {
|
||||
const [expanded, setExpanded] = useState(null);
|
||||
const alwaysShowTokens = [tokens.native, tokens.reserve, tokens.ftso, tokens.stnk, tokens.ghst, tokens.reserveFtso];
|
||||
const alwaysShowTokens = [tokens.native, tokens.reserve, tokens.ftso, tokens.ghst, tokens.reserveFtso];
|
||||
|
||||
const tokenProps = (token) => ({
|
||||
...token,
|
||||
|
||||
@ -26,10 +26,7 @@ export const ClaimBonds = ({ chainId, address, secondsTo }) => {
|
||||
const [isPending, setIsPending] = useState(false);
|
||||
const [isWarmup, setIsWapmup] = useState(false);
|
||||
const [isPreClaimConfirmed, setPreClaimConfirmed] = useState(false);
|
||||
const [isPayoutGhst, setIsPayoutGhst] = useState(localStorage.getItem("bond-isGhstPayout")
|
||||
? localStorage.getItem("bond-isGhstPayout") === "true"
|
||||
: true
|
||||
);
|
||||
const [isPayoutGhst, _] = useState(true);
|
||||
|
||||
const { epoch } = useEpoch(chainId);
|
||||
const { warmupExists } = useWarmupLength(chainId);
|
||||
@ -39,7 +36,6 @@ export const ClaimBonds = ({ chainId, address, secondsTo }) => {
|
||||
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;
|
||||
@ -52,11 +48,6 @@ export const ClaimBonds = ({ chainId, address, secondsTo }) => {
|
||||
18
|
||||
);
|
||||
|
||||
const setIsPayoutGhstInner = (value) => {
|
||||
setIsPayoutGhst(value);
|
||||
localStorage.setItem("bond-isGhstPayout", value);
|
||||
}
|
||||
|
||||
const onSubmit = async (indexes) => {
|
||||
const isFundsInWarmup = warmupInfo.deposit._value > 0n;
|
||||
if (warmupExists && isFundsInWarmup && !isPreClaimConfirmed) {
|
||||
@ -94,24 +85,6 @@ export const ClaimBonds = ({ chainId, address, secondsTo }) => {
|
||||
</Box>
|
||||
}
|
||||
>
|
||||
<Box display="flex" flexDirection="column" alignItems="center">
|
||||
<Typography variant="h4" align="center" color="textSecondary">
|
||||
Payout Options
|
||||
</Typography>
|
||||
<Tabs
|
||||
centered
|
||||
textColor="primary"
|
||||
indicatorColor="primary"
|
||||
value={isPayoutGhst ? 1 : 0}
|
||||
aria-label="Payout token tabs"
|
||||
onChange={(_, view) => setIsPayoutGhstInner(view === 1)}
|
||||
TabIndicatorProps={{ style: { display: "none" } }}
|
||||
>
|
||||
<Tab aria-label="payout-stnk-button" label={stnkSymbol} style={{ fontSize: "1rem" }} />
|
||||
<Tab aria-label="payout-ghst-button" label={ghstSymbol} style={{ fontSize: "1rem" }} />
|
||||
</Tabs>
|
||||
</Box>
|
||||
|
||||
<Box display="flex" justifyContent="center">
|
||||
<Box display="flex" flexDirection="column" alignItems="center" mt="24px" width={isSmallScreen ? "100%" : "50%"}>
|
||||
<Typography variant="h5" align="center" color="textSecondary" style={{ fontSize: "1.2rem" }}>
|
||||
|
||||
@ -131,7 +131,35 @@ const PoolContainer = ({
|
||||
}
|
||||
}
|
||||
|
||||
}, [addressBottom, balanceTop, balanceBottom, amountTop, amountBottom, tokenAddresses, pairReserves])
|
||||
}, [addressBottom, balanceTop, balanceBottom, amountTop, amountBottom, tokenAddresses, pairReserves]);
|
||||
|
||||
const poolShares = useMemo(() => {
|
||||
const hundred = new DecimalBigNumber(1n, 2);
|
||||
if (lpTotalSupply?._value == 0n) {
|
||||
return { currentShares: lpTotalSupply, nextShares: lpTotalSupply };
|
||||
}
|
||||
const currentShares = lpBalance.div(lpTotalSupply).div(hundred);
|
||||
const nextShares = (lpBalance.add(estimatedAmountOut)).div(lpTotalSupply.add(estimatedAmountOut)).div(hundred);
|
||||
return { currentShares, nextShares };
|
||||
}, [lpBalance, lpTotalSupply, estimatedAmountOut]);
|
||||
|
||||
const poolPrices = useMemo(() => {
|
||||
const amountIn = addressTop.toUpperCase() === tokenAddresses.token0.toUpperCase()
|
||||
? pairReserves.reserve0
|
||||
: pairReserves.reserve1;
|
||||
|
||||
const amountOut = addressBottom.toUpperCase() === tokenAddresses.token1.toUpperCase()
|
||||
? pairReserves.reserve1
|
||||
: pairReserves.reserve0;
|
||||
|
||||
let priceIn = "0";
|
||||
let priceOut = "0";
|
||||
|
||||
if (amountIn?._value > 0n) priceIn = (amountOut.div(amountIn)).toString();
|
||||
if (amountOut?._value > 0n) priceOut = (amountIn.div(amountOut)).toString();
|
||||
|
||||
return { priceIn , priceOut }
|
||||
}, [addressTop, addressBottom, balanceTop, tokenAddresses, pairReserves]);
|
||||
|
||||
const addLiquidityInner = async () => {
|
||||
setIsPending(true);
|
||||
@ -218,7 +246,7 @@ const PoolContainer = ({
|
||||
}
|
||||
arrowOnClick={onSwap}
|
||||
/>
|
||||
{!isSmallScreen && <Box
|
||||
<Box
|
||||
m="10px 0"
|
||||
display="flex"
|
||||
flexDirection="column"
|
||||
@ -229,18 +257,22 @@ const PoolContainer = ({
|
||||
style={{ fontSize: "12px", color: theme.colors.gray[40] }}
|
||||
>
|
||||
<Box width="100%" display="flex" justifyContent="space-between">
|
||||
<Typography fontSize="12px" lineHeight="15px">Current Balance:</Typography>
|
||||
<Typography fontSize="12px" lineHeight="15px">{formatNumber(lpBalance, formatDecimals)} LP</Typography>
|
||||
<Typography fontSize="12px" lineHeight="15px">{`1 ${tokenNameTop}`}</Typography>
|
||||
<Typography fontSize="12px" lineHeight="15px">{formatCurrency(poolPrices.priceIn, formatDecimals, tokenNameBottom)}</Typography>
|
||||
</Box>
|
||||
<Box width="100%" display="flex" justifyContent="space-between">
|
||||
<Typography fontSize="12px" lineHeight="15px">Total Supply:</Typography>
|
||||
<Typography fontSize="12px" lineHeight="15px">{formatNumber(lpTotalSupply, formatDecimals)} LP</Typography>
|
||||
<Typography fontSize="12px" lineHeight="15px">{`1 ${tokenNameBottom}`}</Typography>
|
||||
<Typography fontSize="12px" lineHeight="15px">{formatCurrency(poolPrices.priceOut, formatDecimals, tokenNameTop)}</Typography>
|
||||
</Box>
|
||||
<Box width="100%" display="flex" justifyContent="space-between">
|
||||
<Typography fontSize="12px" lineHeight="15px">Extra Balance:</Typography>
|
||||
<Typography fontSize="12px" lineHeight="15px">~{formatNumber(estimatedAmountOut, formatDecimals)} LP</Typography>
|
||||
<Typography fontSize="12px" lineHeight="15px">Current Pool Share:</Typography>
|
||||
<Typography fontSize="12px" lineHeight="15px">{formatNumber(poolShares.currentShares, formatDecimals)}%</Typography>
|
||||
</Box>
|
||||
</Box>}
|
||||
<Box width="100%" display="flex" justifyContent="space-between">
|
||||
<Typography fontSize="12px" lineHeight="15px">Next Pool Share:</Typography>
|
||||
<Typography fontSize="12px" lineHeight="15px">{formatNumber(poolShares.nextShares, formatDecimals)}%</Typography>
|
||||
</Box>
|
||||
</Box>
|
||||
<TokenAllowanceGuard
|
||||
spendAmount={new DecimalBigNumber(amountTop, balanceTop._decimals)}
|
||||
tokenName={tokenNameTop}
|
||||
|
||||
@ -102,24 +102,45 @@ const SwapContainer = ({
|
||||
const amountIn = addressTop.toUpperCase() === tokenAddresses.token0.toUpperCase() ? pairReserves.reserve0 : pairReserves.reserve1;
|
||||
const amountOut = addressBottom.toUpperCase() === tokenAddresses.token1.toUpperCase() ? pairReserves.reserve1 : pairReserves.reserve0;
|
||||
|
||||
if (amountIn.eq(zero)) {
|
||||
if (amountOut.eq(zero)) {
|
||||
setCurrentPrice("");
|
||||
} else {
|
||||
setCurrentPrice(amountIn.div(amountOut).toString());
|
||||
}
|
||||
|
||||
if (amountIn.eq(zero) || amountInWithFee.eq(zero)) {
|
||||
if (amountOut.eq(zero) || amountInWithFee.eq(zero)) {
|
||||
setAmountBottom("");
|
||||
setNextPrice("");
|
||||
} else {
|
||||
const nominator = amountOut.mul(amountIn);
|
||||
const nominator = amountOut.mul(amountInWithFee);
|
||||
const denominator = amountIn.add(amountInWithFee);
|
||||
const newAmountOut = nominator.div(denominator);
|
||||
|
||||
setAmountBottom(amountOut.sub(newAmountOut).toString());
|
||||
setNextPrice(denominator.div(newAmountOut).toString())
|
||||
const newReserveIn = amountIn.add(amountInWithFee);
|
||||
const newReserveOut = amountOut.sub(newAmountOut);
|
||||
const nextPrice = newReserveIn.div(newReserveOut);
|
||||
|
||||
setAmountBottom(newAmountOut.toString());
|
||||
setNextPrice(nextPrice.toString());
|
||||
}
|
||||
}, [amountTop, addressTop, isWrapping, isUnwrapping]);
|
||||
}, [pairReserves, addressBottom, amountTop, addressTop, isWrapping, isUnwrapping]);
|
||||
|
||||
const minReceived = useMemo(() => {
|
||||
const decimals = 7;
|
||||
const shares = Math.pow(10, decimals);
|
||||
const one = BigInt(shares * 100);
|
||||
|
||||
const floatSlippage = slippage === "" ? 0 : parseFloat(slippage);
|
||||
const bigIntSlippage = one - BigInt(Math.round(floatSlippage * shares));
|
||||
const slippageDecimalBigNumber = new DecimalBigNumber(bigIntSlippage, 2);
|
||||
|
||||
const bigIntAmount = BigInt(Math.round(amountBottom * shares));
|
||||
const amountDecimalBigNumber = new DecimalBigNumber(bigIntAmount, decimals);
|
||||
|
||||
const tmpResult = amountDecimalBigNumber.mul(slippageDecimalBigNumber);
|
||||
const result = new DecimalBigNumber(tmpResult?._value, tmpResult?._decimals + decimals);
|
||||
return result?.toString();
|
||||
}, [amountBottom, amountBottom, slippage, balanceBottom]);
|
||||
|
||||
const buttonText = useMemo(() => {
|
||||
let text = "Swap";
|
||||
@ -215,7 +236,7 @@ const SwapContainer = ({
|
||||
}
|
||||
arrowOnClick={onSwap}
|
||||
/>
|
||||
{!isSmallScreen && <Box
|
||||
<Box
|
||||
m="10px 0"
|
||||
display="flex"
|
||||
flexDirection="column"
|
||||
@ -226,18 +247,22 @@ const SwapContainer = ({
|
||||
style={{ fontSize: "12px", color: theme.colors.gray[40] }}
|
||||
>
|
||||
<Box width="100%" display="flex" justifyContent="space-between">
|
||||
<Typography fontSize="12px" lineHeight="15px">Current price:</Typography>
|
||||
<Typography fontSize="12px" lineHeight="15px">{`1 ${tokenNameBottom} (Current)`}</Typography>
|
||||
<Typography fontSize="12px" lineHeight="15px">{formatCurrency(currentPrice, formatDecimals, tokenNameTop)}</Typography>
|
||||
</Box>
|
||||
<Box width="100%" display="flex" justifyContent="space-between">
|
||||
<Typography fontSize="12px" lineHeight="15px">Next price:</Typography>
|
||||
<Typography fontSize="12px" lineHeight="15px">{`1 ${tokenNameBottom} (Next)`}</Typography>
|
||||
<Typography fontSize="12px" lineHeight="15px">{formatCurrency(nextPrice === "" ? currentPrice : nextPrice, formatDecimals, tokenNameTop)}</Typography>
|
||||
</Box>
|
||||
<Box width="100%" display="flex" justifyContent="space-between">
|
||||
<Typography fontSize="12px" lineHeight="15px">Transaction deadline:</Typography>
|
||||
<Typography fontSize="12px" lineHeight="15px">Min. Receive:</Typography>
|
||||
<Typography fontSize="12px" lineHeight="15px">{formatCurrency(minReceived, formatDecimals, tokenNameBottom)}</Typography>
|
||||
</Box>
|
||||
<Box width="100%" display="flex" justifyContent="space-between">
|
||||
<Typography fontSize="12px" lineHeight="15px">Tx. Deadline:</Typography>
|
||||
<Typography fontSize="12px" lineHeight="15px">~{prettifySecondsInDays(secondsToWait)}</Typography>
|
||||
</Box>
|
||||
</Box>}
|
||||
</Box>
|
||||
<TokenAllowanceGuard
|
||||
spendAmount={new DecimalBigNumber(amountTop, balanceTop._decimals)}
|
||||
tokenName={tokenNameTop}
|
||||
|
||||
@ -24,7 +24,6 @@ import { isNetworkLegacy } from "../../constants";
|
||||
import {
|
||||
RESERVE_ADDRESSES,
|
||||
FTSO_ADDRESSES,
|
||||
STNK_ADDRESSES,
|
||||
GHST_ADDRESSES,
|
||||
EMPTY_ADDRESS
|
||||
} from "../../constants/addresses";
|
||||
@ -48,12 +47,10 @@ const TokenModal = ({ chainId, account, chainSymbol, listOpen, setListOpen, setT
|
||||
const { balance: nativeBalance } = useBalance(chainId, chainSymbol, account);
|
||||
const { balance: reserveBalance } = useBalance(chainId, "RESERVE", account);
|
||||
const { balance: ftsoBalance } = useBalance(chainId, "FTSO", account);
|
||||
const { balance: stnkBalance } = useBalance(chainId, "STNK", account);
|
||||
const { balance: ghstBalance } = useBalance(chainId, "GHST", account);
|
||||
|
||||
const { symbol: reserveSymbol } = useTokenSymbol(chainId, "RESERVE");
|
||||
const { symbol: ftsoSymbol } = useTokenSymbol(chainId, "FTSO");
|
||||
const { symbol: stnkSymbol } = useTokenSymbol(chainId, "STNK");
|
||||
const { symbol: ghstSymbol } = useTokenSymbol(chainId, "GHST");
|
||||
|
||||
const searchToken = useMemo(() => {
|
||||
@ -85,12 +82,6 @@ const TokenModal = ({ chainId, account, chainSymbol, listOpen, setListOpen, setT
|
||||
balance: ftsoBalance,
|
||||
address: FTSO_ADDRESSES[chainId]
|
||||
},
|
||||
{
|
||||
name: stnkSymbol,
|
||||
icons: ["STNK"],
|
||||
balance: stnkBalance,
|
||||
address: STNK_ADDRESSES[chainId]
|
||||
},
|
||||
{
|
||||
name: ghstSymbol,
|
||||
icons: ["GHST"],
|
||||
@ -98,7 +89,7 @@ const TokenModal = ({ chainId, account, chainSymbol, listOpen, setListOpen, setT
|
||||
address: GHST_ADDRESSES[chainId]
|
||||
}
|
||||
]
|
||||
}, [reserveSymbol, ftsoSymbol, stnkSymbol, ghstSymbol, reserveBalance, ftsoBalance, stnkBalance, ghstBalance]);
|
||||
}, [reserveSymbol, ftsoSymbol, ghstSymbol, reserveBalance, ftsoBalance, ghstBalance]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isAddress(userInput)) {
|
||||
|
||||
@ -19,7 +19,6 @@ const Stake = ({ chainId, address, isOpened, closeModal, connect }) => {
|
||||
const [settingsModalOpen, setSettingsModalOpen] = useState(false);
|
||||
|
||||
const { symbol: ftsoSymbol } = useTokenSymbol(chainId, "FTSO");
|
||||
const { symbol: stnkSymbol } = useTokenSymbol(chainId, "STNK");
|
||||
const { symbol: ghstSymbol } = useTokenSymbol(chainId, "GHST");
|
||||
|
||||
const [upperToken, setUpperToken] = useState(ftsoSymbol);
|
||||
@ -31,28 +30,16 @@ const Stake = ({ chainId, address, isOpened, closeModal, connect }) => {
|
||||
|
||||
useEffect(() => {
|
||||
switch (true) {
|
||||
case (upperToken === ftsoSymbol && bottomToken === stnkSymbol):
|
||||
setAction("STAKE")
|
||||
break;
|
||||
case (upperToken === ftsoSymbol && bottomToken === ghstSymbol):
|
||||
setAction("STAKE")
|
||||
break;
|
||||
case (upperToken === stnkSymbol && bottomToken === ftsoSymbol):
|
||||
setAction("UNSTAKE")
|
||||
break;
|
||||
case (upperToken === ghstSymbol && bottomToken === ftsoSymbol):
|
||||
setAction("UNSTAKE")
|
||||
break;
|
||||
case (upperToken === stnkSymbol && bottomToken === ghstSymbol):
|
||||
setAction("WRAP")
|
||||
break;
|
||||
case (upperToken === ghstSymbol && bottomToken === stnkSymbol):
|
||||
setAction("UNWRAP")
|
||||
break;
|
||||
default:
|
||||
setAction("STAKE")
|
||||
}
|
||||
}, [upperToken, bottomToken])
|
||||
}, [ftsoSymbol, ghstSymbol, upperToken, bottomToken])
|
||||
|
||||
return (
|
||||
<Modal
|
||||
|
||||
@ -21,7 +21,6 @@ import InfoTooltip from "../../../components/Tooltip/InfoTooltip";
|
||||
import Paper from "../../../components/Paper/Paper";
|
||||
import Token from "../../../components/Token/Token";
|
||||
import { PrimaryButton, SecondaryButton } from "../../../components/Button";
|
||||
import { Tab, Tabs } from "../../../components/Tabs/Tabs";
|
||||
|
||||
import { DecimalBigNumber } from "../../../helpers/DecimalBigNumber";
|
||||
import { prettifySecondsInDays } from "../../../helpers/timeUtil";
|
||||
@ -52,10 +51,7 @@ export const ClaimsArea = ({ chainId, address, epoch }) => {
|
||||
const isSmallScreen = useMediaQuery("(max-width: 745px)");
|
||||
|
||||
const [confirmationModalOpen, setConfirmationModalOpen] = useState(false);
|
||||
const [isPayoutGhst, setIsPayoutGhst] = useState(localStorage.getItem("stake-isGhstPayout")
|
||||
? localStorage.getItem("stake-isGhstPayout")
|
||||
: false
|
||||
);
|
||||
const [isPayoutGhst, _] = useState(true);
|
||||
|
||||
const { warmupInfo: claim, refetch: claimRefetch } = useWarmupInfo(chainId, address);
|
||||
const { currentIndex, refetch: currentIndexRefetch } = useCurrentIndex(chainId);
|
||||
@ -73,11 +69,6 @@ export const ClaimsArea = ({ chainId, address, epoch }) => {
|
||||
|
||||
if (claim.shares === 0n) return <></>;
|
||||
|
||||
const setIsPayoutGhstInner = (value) => {
|
||||
setIsPayoutGhst(value);
|
||||
localStorage.setItem("bond-isGhstPayout", value);
|
||||
}
|
||||
|
||||
const warmupTooltip = `Your claim earns rebases during warmup. You can emergency withdraw, but this forfeits the rebases`;
|
||||
|
||||
return (
|
||||
@ -106,18 +97,6 @@ export const ClaimsArea = ({ chainId, address, epoch }) => {
|
||||
flexDirection={isSmallScreen ? "column" : "row"}
|
||||
>
|
||||
<Typography variant="h6">Your active {isPayoutGhst ? ghstSymbol : stnkSymbol} claim</Typography>
|
||||
<Tabs
|
||||
centered
|
||||
textColor="primary"
|
||||
indicatorColor="primary"
|
||||
value={isPayoutGhst ? 1 : 0}
|
||||
aria-label="Claim token tabs"
|
||||
onChange={(_, view) => setIsPayoutGhstInner(view === 1)}
|
||||
TabIndicatorProps={{ style: { display: "none" } }}
|
||||
>
|
||||
<Tab aria-label="payout-stnk-button" label={stnkSymbol} style={{ fontSize: "1rem" }} />
|
||||
<Tab aria-label="payout-ghst-button" label={ghstSymbol} style={{ fontSize: "1rem" }} />
|
||||
</Tabs>
|
||||
</Box>
|
||||
}
|
||||
tooltip={warmupTooltip}
|
||||
|
||||
@ -11,13 +11,14 @@ import { isNetworkLegacy } from "../../../constants"
|
||||
import { useBalance, useTokenSymbol } from "../../../hooks/tokens";
|
||||
import {
|
||||
useFtsoPrice,
|
||||
useStnkPrice,
|
||||
useGhstPrice,
|
||||
useReservePrice,
|
||||
useNativePrice,
|
||||
} from "../../../hooks/prices";
|
||||
import { tokenNameConverter } from "../../../helpers/tokenConverter";
|
||||
|
||||
import { EMPTY_ADDRESS, WETH_ADDRESSES } from "../../../constants/addresses";
|
||||
|
||||
const TokenTab = ({ isMobileScreen, theme, tokenName, tokenUrl, tokenUrlParams, balance, price, description }) => {
|
||||
const navigate = useNavigate();
|
||||
const actualBalance = balance ? balance : new DecimalBigNumber(0, 0);
|
||||
@ -58,10 +59,13 @@ const TokenTab = ({ isMobileScreen, theme, tokenName, tokenUrl, tokenUrlParams,
|
||||
|
||||
<Box display="flex" justifyContent="center" width="100%">
|
||||
<SecondaryButton
|
||||
onClick={() => navigate({
|
||||
pathname: tokenUrl,
|
||||
search: tokenUrlParams.toString()
|
||||
})}
|
||||
onClick={() => tokenUrlParams
|
||||
? navigate({
|
||||
pathname: tokenUrl,
|
||||
search: tokenUrlParams.toString()
|
||||
})
|
||||
: window.open(tokenUrl, '_blank')
|
||||
}
|
||||
fullWidth
|
||||
>
|
||||
Get {tokenName}
|
||||
@ -83,18 +87,15 @@ const TokenInfo = ({ chainId, isMobileScreen }) => {
|
||||
|
||||
const nativePrice = useNativePrice(chainId);
|
||||
const ftsoPrice = useFtsoPrice(chainId);
|
||||
const stnkPrice = useStnkPrice(chainId);
|
||||
const ghstPrice = useGhstPrice(chainId);
|
||||
const reservePrice = useReservePrice(chainId);
|
||||
|
||||
const { symbol: reserveSymbol } = useTokenSymbol(chainId, "RESERVE");
|
||||
const { symbol: ftsoSymbol } = useTokenSymbol(chainId, "FTSO");
|
||||
const { symbol: stnkSymbol } = useTokenSymbol(chainId, "STNK");
|
||||
const { symbol: ghstSymbol } = useTokenSymbol(chainId, "GHST");
|
||||
|
||||
const { data: nativeBalance } = useBalanceNative({ address });
|
||||
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);
|
||||
const { balance: reserveBalance, contractAddress: reserveAddress } = useBalance(chainId, "RESERVE", address);
|
||||
|
||||
@ -114,19 +115,6 @@ const TokenInfo = ({ chainId, isMobileScreen }) => {
|
||||
price={ftsoPrice}
|
||||
description={`${ftsoSymbol} is the native token of the ghostDAO protocol, fully backed by stablecoin reserves held in the ghostDAO treasury.`}
|
||||
/>
|
||||
<TokenTab
|
||||
isMobileScreen={isMobileScreen}
|
||||
tokenUrl="/dex/uniswap"
|
||||
tokenUrlParams={createSearchParams({
|
||||
from: `${reserveAddress}`,
|
||||
to: `${stnkAddress}`,
|
||||
})}
|
||||
theme={theme}
|
||||
tokenName={stnkSymbol}
|
||||
balance={stnkBalance}
|
||||
price={stnkPrice}
|
||||
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}
|
||||
tokenUrl="/dex/uniswap"
|
||||
@ -140,10 +128,24 @@ const TokenInfo = ({ chainId, isMobileScreen }) => {
|
||||
price={ghstPrice}
|
||||
description={`${ghstSymbol} is the governance token enabling pure Web3 cross-chain magic. 1 ${ghstSymbol} = 1 ${ftsoSymbol} x Current Index.`}
|
||||
/>
|
||||
{!isNetworkLegacy(chainId) && (
|
||||
<TokenTab
|
||||
isMobileScreen={isMobileScreen}
|
||||
tokenUrl={"https://ghostchain.io/faucet/"}
|
||||
theme={theme}
|
||||
tokenName={nativeSymbol}
|
||||
balance={new DecimalBigNumber(nativeBalance?.value ?? 0n, 18)}
|
||||
price={reservePrice}
|
||||
description={`${nativeSymbol} is the native currency of the ${networkName} Network, functioning as the backing asset for the ghostDAO.`}
|
||||
/>
|
||||
)}
|
||||
<TokenTab
|
||||
isMobileScreen={isMobileScreen}
|
||||
tokenUrl={isNetworkLegacy(chainId) ? "/faucet" : "/wrapper"}
|
||||
tokenUrlParams=""
|
||||
tokenUrl="/dex/uniswap"
|
||||
tokenUrlParams={createSearchParams({
|
||||
from: `${EMPTY_ADDRESS}`,
|
||||
to: `${WETH_ADDRESSES[chainId]}`,
|
||||
})}
|
||||
theme={theme}
|
||||
tokenName={reserveSymbol}
|
||||
balance={reserveBalance}
|
||||
@ -154,20 +156,6 @@ const TokenInfo = ({ chainId, isMobileScreen }) => {
|
||||
}
|
||||
/>
|
||||
</Box>
|
||||
{!isNetworkLegacy(chainId) && (
|
||||
<Box width="100%" mt="25px">
|
||||
<TokenTab
|
||||
isMobileScreen={true}
|
||||
tokenUrl={isNetworkLegacy(chainId) ? "/faucet" : "/wrapper"}
|
||||
tokenUrlParams=""
|
||||
theme={theme}
|
||||
tokenName={nativeSymbol}
|
||||
balance={new DecimalBigNumber(nativeBalance?.value ?? 0n, 18)}
|
||||
price={reservePrice}
|
||||
description={`${nativeSymbol} is the native currency of the ${networkName} Network, functioning as the backing asset for the ghostDAO.`}
|
||||
/>
|
||||
</Box>
|
||||
)}
|
||||
</Grid>
|
||||
)
|
||||
}
|
||||
|
||||
@ -4,6 +4,8 @@ export const tokenNameConverter = (chainId, name, address) => {
|
||||
case 63:
|
||||
name = "wmETC"
|
||||
break;
|
||||
default:
|
||||
name = "wETH";
|
||||
}
|
||||
}
|
||||
return name;
|
||||
|
||||
@ -20,6 +20,7 @@ import { useTokenSymbol, useTokenSymbols } from "../tokens";
|
||||
import { getTokenAddress, getTokenIcons, getBondNameDisplayName, getTokenPurchaseLink } from "../helpers";
|
||||
import { DecimalBigNumber } from "../../helpers/DecimalBigNumber";
|
||||
import { shorten } from "../../helpers";
|
||||
import { tokenNameConverter } from "../../helpers/tokenConverter";
|
||||
|
||||
export const useLiveBonds = (chainId) => {
|
||||
const ftsoPrice = useFtsoPrice(chainId);
|
||||
@ -150,7 +151,7 @@ export const useLiveBonds = (chainId) => {
|
||||
);
|
||||
|
||||
const zero = new DecimalBigNumber(0n, 0);
|
||||
const bondName = `${baseTokenSymbol}/${quoteTokenSymbol}`;
|
||||
const bondName = `${baseTokenSymbol}/${tokenNameConverter(chainId, "WETH")}`;
|
||||
|
||||
return {
|
||||
id,
|
||||
@ -163,7 +164,7 @@ export const useLiveBonds = (chainId) => {
|
||||
tokenAddress: getTokenAddress(chainId, "FTSO")
|
||||
},
|
||||
quoteToken: {
|
||||
name: quoteTokenSymbol,
|
||||
name: tokenNameConverter(chainId, quoteTokenSymbol),
|
||||
purchaseUrl: getTokenPurchaseLink(chainId, quoteTokenAddress),
|
||||
icons: getTokenIcons(chainId, quoteTokenAddress),
|
||||
decimals: quoteTokenDecimals,
|
||||
@ -172,7 +173,7 @@ export const useLiveBonds = (chainId) => {
|
||||
duration: terms?.at(index).result?.at(3) ? terms.at(index).result.at(3) : 0,
|
||||
vesting: terms?.at(index).result?.at(2) ? terms.at(index).result.at(2) : 0,
|
||||
isFixedTerm: terms?.at(index).result?.at(0) ? terms.at(index).result.at(0) : true,
|
||||
isSoldOut: capacityInBaseToken.eq(zero) || capacityInBaseToken.eq(zero),
|
||||
isSoldOut: capacityInBaseToken.eq(zero),
|
||||
price: {
|
||||
inUsd: priceInUsd,
|
||||
inBaseToken: quoteTokenPerBaseToken,
|
||||
@ -250,7 +251,7 @@ export const useNotes = (chainId, address) => {
|
||||
return {
|
||||
id,
|
||||
quoteToken: {
|
||||
name: quoteTokenSymbol,
|
||||
name: tokenNameConverter(chainId, quoteTokenSymbol),
|
||||
icons: getTokenIcons(chainId, quoteTokenAddress),
|
||||
},
|
||||
vesting: terms?.at(index).result?.at(2) ? terms.at(index).result.at(2) : 0,
|
||||
|
||||
@ -7,6 +7,8 @@ import {
|
||||
WETH_ADDRESSES,
|
||||
} from "../constants/addresses";
|
||||
|
||||
import { tokenNameConverter } from "../helpers/tokenConverter";
|
||||
|
||||
import { abi as DaiAbi } from "../abi/Reserve.json";
|
||||
import { abi as FatsoAbi } from "../abi/Fatso.json";
|
||||
import { abi as StinkyAbi } from "../abi/Stinky.json";
|
||||
@ -156,7 +158,7 @@ export const getTokenIcons = (chainId, address) => {
|
||||
let icons = [""];
|
||||
switch (address) {
|
||||
case RESERVE_ADDRESSES[chainId]:
|
||||
icons = ["WETH"];
|
||||
icons = [tokenNameConverter(chainId, "WETH")];
|
||||
break;
|
||||
case FTSO_ADDRESSES[chainId]:
|
||||
icons = ["FTSO"];
|
||||
@ -178,7 +180,7 @@ export const getTokenIcons = (chainId, address) => {
|
||||
|
||||
export const getBondNameDisplayName = (chainId, stringValue, tokenAddress) => {
|
||||
if (tokenAddress.toUpperCase() === FTSO_DAI_LP_ADDRESSES[chainId].toUpperCase()) {
|
||||
stringValue = `LP ${stringValue}`;
|
||||
stringValue = `${stringValue} LP`;
|
||||
}
|
||||
return stringValue;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user