utils#isBlindMode TypeScript Examples
The following examples show how to use
utils#isBlindMode.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: index.tsx From vvs-ui with GNU General Public License v3.0 | 6 votes |
UserBanner = () => {
return (
<StyledCard p={['16px', null, null, '24px']}>
<Flex alignItems="unset" justifyContent="center" flexDirection={['column', null, 'column', 'row']}>
<Flex mr={[null, null, null, '40px']}>
<UserDetail />
</Flex>
<Flex flex="1" width={['100%', null, 'auto']} justifyContent="space-between" flexDirection={['column', 'column', 'row', null]}>
<Flex flex="1" mb={[null, '20px', null, '0px']} mr={[null, null, '10px', '20px']}>
{!isBlindMode() && <DepositsCard />}
</Flex>
<Flex flex="1" mb={[null, '20px', null, '0px']} mr={[null, null, null, '20px']}>
{!isBlindMode() && <PlatformYieldCard />}
</Flex>
</Flex>
<Flex width={[null, null, null, '350px']}>
<HarvestCard />
</Flex>
</Flex>
<BgSvg />
</StyledCard>
)
}
Example #2
Source File: RecentVvsProfitBalance.tsx From vvs-ui with GNU General Public License v3.0 | 6 votes |
RecentVvsProfitBalance: React.FC<RecentVvsProfitBalanceProps> = ({
vvsToDisplay,
dollarValueToDisplay,
dateStringToDisplay,
}) => {
const { t } = useTranslation()
const { targetRef, tooltip, tooltipVisible } = useTooltip(
<>
<Balance fontSize="16px" value={vvsToDisplay} decimals={3} bold unit=" VVS" />
{!isBlindMode() && <Balance fontSize="16px" value={dollarValueToDisplay} decimals={2} bold prefix="~$" />}
{t('Earned since your last action')}
<Text>{dateStringToDisplay}</Text>
</>,
{
placement: 'bottom-end',
},
)
return (
<>
{tooltipVisible && tooltip}
<TooltipText ref={targetRef} small>
<Balance fontSize="14px" value={vvsToDisplay} />
</TooltipText>
</>
)
}
Example #3
Source File: AprCell.tsx From vvs-ui with GNU General Public License v3.0 | 6 votes |
AprCell: React.FC<AprCellProps> = ({ pool }) => {
const { t } = useTranslation()
const { isMobile } = useMatchBreakpoints()
const { userData } = pool
const stakedBalance = userData?.stakedBalance ? new BigNumber(userData.stakedBalance) : BIG_ZERO
return (
<StyledCell role="cell">
<CellContent>
<Text fontSize="12px" color="textSubtle" textAlign="left">
{isBlindMode() ? t('VVS Allocation') : t('APR')}
</Text>
{isBlindMode() ? "/ Block" : <Apr pool={pool} stakedBalance={stakedBalance} showIcon={!isMobile} />}
</CellContent>
</StyledCell>
)
}
Example #4
Source File: DetailsSection.tsx From vvs-ui with GNU General Public License v3.0 | 6 votes |
DetailsSection: React.FC<ExpandableSectionProps> = ({
bscScanAddress,
infoAddress,
removed,
totalValueFormatted,
lpLabel,
addLiquidityUrl,
}) => {
const { t } = useTranslation()
return (
<Wrapper>
<Flex justifyContent="space-between" mb="8px">
<Text color="textSubtle" fontSize="13px">
{t('Total Liquidity')}:
</Text>
{totalValueFormatted ? <Text>{totalValueFormatted}</Text> : <Skeleton width={75} height={25} />}
</Flex>
{!removed && (
<StyledLinkExternal color="blue" href={addLiquidityUrl}>
{t('Get %symbol%', { symbol: lpLabel })}
</StyledLinkExternal>
)}
<StyledLinkExternal color="blue" href={bscScanAddress}>
{t('View Contract')}
</StyledLinkExternal>
{!isBlindMode() && <StyledLinkExternal color="blue" href={infoAddress}>
{t('See Pair Info')}
</StyledLinkExternal>}
</Wrapper>
)
}
Example #5
Source File: AutoAprCell.tsx From vvs-ui with GNU General Public License v3.0 | 6 votes |
AutoAprCell: React.FC<AprCellProps> = ({ pool }) => {
const { t } = useTranslation()
const { isMobile } = useMatchBreakpoints()
const {
userData: { userShares },
fees: { performanceFee },
pricePerFullShare,
} = useVvsVault()
const { vvsAsBigNumber } = convertSharesToVvs(userShares, pricePerFullShare)
const performanceFeeAsDecimal = performanceFee && performanceFee / 100
return (
<StyledCell role="cell">
<CellContent>
<Text fontSize="12px" color="textSubtle" textAlign="left">
{isBlindMode() ? t('VVS Allocation') : t('APY')}
</Text>
{isBlindMode() ? "/ Block" : <Apr pool={pool} stakedBalance={vvsAsBigNumber} performanceFee={performanceFeeAsDecimal} showIcon={!isMobile} />}
</CellContent>
</StyledCell>
)
}
Example #6
Source File: HarvestActions.tsx From vvs-ui with GNU General Public License v3.0 | 5 votes |
HarvestActions: React.FC<HarvestActionsProps> = ({
earnings,
earningToken,
sousId,
isBnbPool,
earningTokenPrice,
isLoading = false,
}) => {
const { t } = useTranslation()
const earningTokenBalance = getBalanceNumber(earnings, earningToken.decimals)
const formattedBalance = formatNumber(earningTokenBalance, 3, 3)
const earningTokenDollarBalance = getBalanceNumber(earnings.multipliedBy(earningTokenPrice), earningToken.decimals)
const fullBalance = getFullDisplayBalance(earnings, earningToken.decimals)
const hasEarnings = earnings.toNumber() > 0
const isCompoundPool = sousId === 0
const [onPresentCollect] = useModal(
<CollectModal
formattedBalance={formattedBalance}
fullBalance={fullBalance}
earningToken={earningToken}
earningsDollarValue={earningTokenDollarBalance}
sousId={sousId}
isBnbPool={isBnbPool}
isCompoundPool={isCompoundPool}
/>,
)
return (
<Flex justifyContent="space-between" alignItems="center" mb="16px">
<Flex flexDirection="column">
{isLoading ? (
<Skeleton width="80px" height="48px" />
) : (
<>
{hasEarnings ? (
<>
<Balance bold fontSize="20px" decimals={5} value={earningTokenBalance} />
{isBlindMode() ? <Skeleton mt={1} width={60} /> : (earningTokenPrice > 0 && (
<Balance
display="inline"
fontSize="12px"
color="textSubtle"
decimals={2}
prefix="~"
value={earningTokenDollarBalance}
unit=" USD"
/>
))}
</>
) : (
<>
<Heading color="textDisabled">0</Heading>
<Text fontSize="12px" color="textDisabled">
0 USD
</Text>
</>
)}
</>
)}
</Flex>
<Button disabled={!hasEarnings} onClick={onPresentCollect}>
{isCompoundPool ? t('Collect') : t('Harvest')}
</Button>
</Flex>
)
}
Example #7
Source File: PlatformYieldCard.tsx From vvs-ui with GNU General Public License v3.0 | 5 votes |
PlatformYieldCard = () => {
const { t } = useTranslation()
const { account } = useWeb3React()
const vvsPriceUsdc = usePriceVvsUsdc()
const [harvestedSum, setHarvestedSum] = useState(0)
const { earningsSum: farmEarningsSum } = useFarmsWithBalance()
useEffect(() => {
const fetchHarvestedData = async () => {
const { user: harvested } = await getUsersHarvestedData(account)
if (harvested?.totalClaimAmount || harvested?.totalVVSVaultProfit) {
setHarvestedSum(Number(harvested.totalClaimAmount) + Number(harvested.totalVVSVaultProfit))
}
}
if (account) {
fetchHarvestedData()
}
}, [account])
const totalPlatformYield = (getBalanceNumber(new BigNumber(harvestedSum), tokens.vvs.decimals) + farmEarningsSum) * vvsPriceUsdc.toNumber()
return (
<StyledCard>
<CardBody>
<Flex
flexDirection={['column', null, null, 'row']}
justifyContent="space-between"
alignItems={['flex-start', null, null, 'center']}
>
<Flex flexDirection="column" alignItems={['flex-start', null, null, 'flex-start']}>
<Text color="blue" style={{ lineHeight: 1 }} bold fontSize="24px">
{isBlindMode() ? <Skeleton width={96} height={24} my="2px" />
: (
<Balance
decimals={totalPlatformYield > 0 ? 2 : 0}
fontSize="24px"
bold
prefix={totalPlatformYield > 0 ? '~$' : '$'}
lineHeight="1.1"
value={totalPlatformYield}
/>
)}
</Text>
<Text color="textSubtle" fontSize="13px" style={{ whiteSpace: 'nowrap' }}>
{t('Total Platform Yield')}
</Text>
</Flex>
</Flex>
</CardBody>
</StyledCard>
)
}
Example #8
Source File: AprRow.tsx From vvs-ui with GNU General Public License v3.0 | 5 votes |
AprRow: React.FC<AprRowProps> = ({ pool, stakedBalance, performanceFee = 0 }) => {
const { t } = useTranslation()
const { stakingToken, earningToken, isFinished, apr, earningTokenPrice, stakingTokenPrice, userData, isAutoVault } =
pool
const stakingTokenBalance = userData?.stakingTokenBalance ? new BigNumber(userData.stakingTokenBalance) : BIG_ZERO
const tooltipContent = isBlindMode() ? t('Amount of VVS rewards allocated to the Glitter mine participants issued with each Cronos block (~5-6s/block). We will convert this value to APY/APR value after Pioneer Farming Mode is completed.') : (isAutoVault
? t('APY displayed for auto-compounded deposits.')
: t('APY displayed for non auto-compounded deposits.'))
const { targetRef, tooltip, tooltipVisible } = useTooltip(tooltipContent, { placement: 'bottom-start' })
const { apr: earningsPercentageToDisplay, autoCompoundFrequency } = getAprData(pool, performanceFee)
const apyModalLink = stakingToken.address ? `/swap?outputCurrency=${stakingToken.address}` : '/swap'
const [onPresentApyModal] = useModal(
<RoiCalculatorModal
earningTokenPrice={earningTokenPrice}
stakingTokenPrice={stakingTokenPrice}
apr={apr}
linkLabel={t('Get %symbol%', { symbol: stakingToken.symbol })}
linkHref={apyModalLink}
stakingTokenBalance={stakedBalance.plus(stakingTokenBalance)}
stakingTokenSymbol={stakingToken.symbol}
earningTokenSymbol={earningToken.symbol}
autoCompoundFrequency={autoCompoundFrequency}
performanceFee={performanceFee}
/>,
)
const vvsFarm = useFarmFromPid(0)
return (
isBlindMode() ? <Flex alignItems="center" justifyContent="space-between">
{tooltipVisible && tooltip}
<TooltipText color="textSubtle" small ref={targetRef}>
{`${t('VVS Allocation')}`}
</TooltipText>
<Flex alignItems="center">
{vvsFarm && vvsFarm.poolWeight ? `${(VVS_PER_BLOCK * vvsFarm.poolWeight.toNumber()).toFixed(2)}/ Block` : ''}
</Flex>
</Flex> : <Flex alignItems="center" justifyContent="space-between">
{tooltipVisible && tooltip}
<TooltipText color="textSubtle" small ref={targetRef}>
{isAutoVault ? `${t('APY')}:` : `${t('APR')}:`}
</TooltipText>
{isFinished || !apr ? (
<Skeleton width="82px" height="32px" />
) : (
<ApyLabelContainer alignItems="center" onClick={onPresentApyModal}>
<Balance
fontSize="16px"
isDisabled={isFinished}
value={earningsPercentageToDisplay}
decimals={2}
unit="%"
onClick={onPresentApyModal}
/>
<IconButton variant="text" scale="sm">
<CalculateIcon color="textSubtle" width="18px" />
</IconButton>
</ApyLabelContainer>
)}
</Flex>
)
}
Example #9
Source File: TopBlingFarmAndCrystalPool.tsx From vvs-ui with GNU General Public License v3.0 | 5 votes |
PoolInfoModule = ({ name, primarySrc, secondarySrc, percent, title, type, ...restProps }: TopItemProps & FlexProps) => {
const { isDesktop } = useMatchBreakpoints()
return (
<CenterFlex flexDirection={['column', 'column', 'column', 'row']} {...restProps}>
<CenterFlex marginBottom={['10px', '10px', '10px', '0px']}>
<Image
src="/images/darkPurpleVector.svg"
height={24}
width={24}
style={{
minWidth: '24px',
minHeight: '24px',
}}
/>
<Text
fontSize={isDesktop ? '16px' : '13px'}
fontWeight="600"
ml="10px"
mr="15px"
style={{
whiteSpace: 'nowrap',
}}
>
{title}:
</Text>
</CenterFlex>
<CenterFlex mr={['0px', '0px', '0px', '15px']} width={32} height={32}>
<TokenPairImage variant="inverted" primarySrc={primarySrc} secondarySrc={secondarySrc} width={32} height={32} />
</CenterFlex>
<CenterFlex mr={['0px', '0px', '0px', '20px']}>
<Text
fontSize={isDesktop ? '16px' : '13px'}
fontWeight="600"
style={{
whiteSpace: 'nowrap',
}}
>
{name}
</Text>
</CenterFlex>
<CenterFlex>
<Text fontSize="28px" fontWeight="600" color="blue">
{isBlindMode() ? "---" : <Balance
decimals={percent > 0 ? 2 : 0}
fontSize="28px"
bold
display="inline-block"
unit="%"
lineHeight="1.1"
value={percent}
/>}
<Text as="sup" ml="3px" fontSize="13px" verticalAlign="super" fontWeight="400" color="blue">
{type}
</Text>
</Text>
</CenterFlex>
</CenterFlex>
)
}
Example #10
Source File: HarvestAction.tsx From vvs-ui with GNU General Public License v3.0 | 5 votes |
HarvestAction: React.FunctionComponent<HarvestActionProps> = ({ pid, userData, userDataReady }) => {
const { toastSuccess, toastError } = useToast()
const earningsBigNumber = new BigNumber(userData.earnings)
const vvsPrice = usePriceVvsUsdc()
let earnings = BIG_ZERO
let earningsUsdc = 0
let displayBalance = userDataReady ? earnings.toNumber().toLocaleString() : <Skeleton width={60} />
// If user didn't connect wallet default balance will be 0
if (!earningsBigNumber.isZero()) {
earnings = getBalanceAmount(earningsBigNumber)
earningsUsdc = earnings.multipliedBy(vvsPrice).toNumber()
displayBalance = earnings.toNumber().toLocaleString()
}
const [pendingTx, setPendingTx] = useState(false)
const { onReward } = useHarvestFarm(pid)
const { t } = useTranslation()
const dispatch = useAppDispatch()
const { account } = useWeb3React()
return (
<ActionContainer>
<ActionTitles>
<Text textTransform="uppercase" fontSize="13px" pr="4px">
VVS
</Text>
<Text textTransform="uppercase" fontSize="13px">
{t('Earned')}
</Text>
</ActionTitles>
<ActionContent>
<div>
<Heading color="textSubtle">{displayBalance}</Heading>
{earningsUsdc > 0 && !isBlindMode() ? (
<Balance fontSize="12px" color="textSubtle" decimals={2} value={earningsUsdc} unit=" USD" prefix="~" />
) : (<Skeleton mt={1} width={60} />)}
</div>
<Button
disabled={earnings.eq(0) || pendingTx || !userDataReady}
onClick={async () => {
setPendingTx(true)
try {
await onReward()
toastSuccess(
`${t('Harvested')}!`,
t('Your %symbol% earnings have been sent to your wallet!', { symbol: 'VVS' }),
)
} catch (e) {
toastError(
t('Error'),
t('Please try again. Confirm the transaction and make sure you are paying enough gas!'),
)
console.error(e)
} finally {
setPendingTx(false)
}
dispatch(fetchFarmUserDataAsync({ account, pids: [pid] }))
}}
ml="4px"
>
{t('Harvest')}
</Button>
</ActionContent>
</ActionContainer>
)
}
Example #11
Source File: ActionPanel.tsx From vvs-ui with GNU General Public License v3.0 | 5 votes |
ActionPanel: React.FunctionComponent<ActionPanelProps> = ({
details,
apr,
allocation,
multiplier,
liquidity,
userDataReady,
expanded,
}) => {
const farm = details
const { t } = useTranslation()
const isActive = farm.multiplier !== '0X'
const { quoteToken, token, dual } = farm
// const lpLabel = farm.lpSymbol && farm.lpSymbol.toUpperCase().replace('VVS', '') // FIXME replace ??
const lpLabel = farm.lpSymbol && farm.lpSymbol.toUpperCase()
const liquidityUrlPathParts = getLiquidityUrlPathParts({
quoteTokenAddress: quoteToken.address,
tokenAddress: token.address,
})
const lpAddress = getAddress(farm.lpAddresses)
const bsc = getExplorerLink(lpAddress, 'address')
const info = `/info/farm/${lpAddress}`
return (
<Container expanded={expanded} background="#F4F5F1">
<InfoContainer>
{isActive && (
<StakeContainer>
<StyledLinkExternal color="blue" href={`/add/${liquidityUrlPathParts}`}>
{t('Get %symbol%', { symbol: lpLabel })}
</StyledLinkExternal>
</StakeContainer>
)}
<StyledLinkExternal color="blue" href={bsc}>
{t('View Contract')}
</StyledLinkExternal>
{!isBlindMode() && <StyledLinkExternal color="blue" href={info}>
{t('See Pair Info')}
</StyledLinkExternal>}
{/* <TagsContainer>
{farm.isCommunity ? <CommunityTag /> : <CoreTag />}
{dual ? <DualTag /> : null}
</TagsContainer> */}
</InfoContainer>
<ValueContainer>
{isBlindMode() ? (
<ValueWrapper>
<Text color="textSubtle">{t('VVS Allocation')}</Text>
<VvsAllocation {...allocation} />
</ValueWrapper>
) : (<ValueWrapper>
<Text color="textSubtle">{t('APR')}</Text>
<Apr {...apr} />
</ValueWrapper>)}
<ValueWrapper>
<Text color="textSubtle">{t('Multiplier')}</Text>
<Multiplier {...multiplier} />
</ValueWrapper>
<ValueWrapper>
<Text color="textSubtle">{t('Liquidity')}</Text>
<Liquidity {...liquidity} />
</ValueWrapper>
</ValueContainer>
<ActionContainer>
<HarvestAction {...farm} userDataReady={userDataReady} />
<StakedAction {...farm} userDataReady={userDataReady} lpLabel={lpLabel} displayApr={apr?.value} />
</ActionContainer>
</Container>
)
}
Example #12
Source File: HarvestAction.tsx From vvs-ui with GNU General Public License v3.0 | 5 votes |
HarvestAction: React.FC<FarmCardActionsProps> = ({ earnings, pid }) => {
const { account } = useWeb3React()
const { toastSuccess, toastError } = useToast()
const { t } = useTranslation()
const [pendingTx, setPendingTx] = useState(false)
const { onReward } = useHarvestFarm(pid)
const vvsPrice = usePriceVvsUsdc()
const dispatch = useAppDispatch()
const rawEarningsBalance = account ? getBalanceAmount(earnings) : BIG_ZERO
// const displayBalance = rawEarningsBalance.toFixed(3, BigNumber.ROUND_DOWN)
const earningsUsdc = rawEarningsBalance ? rawEarningsBalance.multipliedBy(vvsPrice).toNumber() : 0
return (
<Flex mb="8px" justifyContent="space-between" alignItems="center">
<Flex flexDirection="column" alignItems="flex-start">
<Heading color={rawEarningsBalance.eq(0) ? 'textDisabled' : 'text'}>
{rawEarningsBalance.toNumber().toLocaleString('en-US', { maximumFractionDigits: 3 })}
</Heading>
{earningsUsdc > 0 && isBlindMode() ? <Skeleton mt={1} width={60} /> : (earningsUsdc > 0 && (
<Balance fontSize="12px" color="textSubtle" decimals={2} value={earningsUsdc} unit=" USD" prefix="~" />
))}
</Flex>
<Button
disabled={rawEarningsBalance.eq(0) || pendingTx}
onClick={async () => {
setPendingTx(true)
try {
await onReward()
toastSuccess(
`${t('Harvested')}!`,
t('Your %symbol% earnings have been sent to your wallet!', { symbol: 'VVS' }),
)
} catch (e) {
toastError(
t('Error'),
t('Please try again. Confirm the transaction and make sure you are paying enough gas!'),
)
console.error(e)
} finally {
setPendingTx(false)
}
dispatch(fetchFarmUserDataAsync({ account, pids: [pid] }))
}}
>
{t('Harvest')}
</Button>
</Flex>
)
}
Example #13
Source File: EarningsCell.tsx From vvs-ui with GNU General Public License v3.0 | 5 votes |
EarningsCell: React.FC<EarningsCellProps> = ({ pool, account, userDataLoaded }) => {
const { t } = useTranslation()
const { isMobile } = useMatchBreakpoints()
const { sousId, earningToken, poolCategory, userData, earningTokenPrice } = pool
const isManualVvsPool = sousId === 0
const earnings = userData?.pendingReward ? new BigNumber(userData.pendingReward) : BIG_ZERO
const earningTokenBalance = getBalanceNumber(earnings, earningToken.decimals)
const earningTokenDollarBalance = getBalanceNumber(earnings.multipliedBy(earningTokenPrice), earningToken.decimals)
const hasEarnings = account && earnings.gt(0)
const fullBalance = getFullDisplayBalance(earnings, earningToken.decimals)
const formattedBalance = formatNumber(earningTokenBalance, 3, 3)
const isBnbPool = poolCategory === PoolCategory.BINANCE
const labelText = t('%asset% Earned', { asset: earningToken.symbol })
const [onPresentCollect] = useModal(
<CollectModal
formattedBalance={formattedBalance}
fullBalance={fullBalance}
earningToken={earningToken}
earningsDollarValue={earningTokenDollarBalance}
sousId={sousId}
isBnbPool={isBnbPool}
isCompoundPool={isManualVvsPool}
/>,
)
const handleEarningsClick = (event: React.MouseEvent<HTMLElement>) => {
event.stopPropagation()
onPresentCollect()
}
return (
<StyledCell role="cell">
<CellContent>
<Text fontSize="12px" color="textSubtle" textAlign="left">
{labelText}
</Text>
{!userDataLoaded && account || !isBlindMode() ? (
<Skeleton width="80px" height="16px" />
) : (
<>
<Flex>
<Box mr="8px" height="32px" onClick={hasEarnings ? handleEarningsClick : undefined}>
<Balance
mt="4px"
bold={!isMobile}
fontSize={isMobile ? '14px' : '16px'}
color={hasEarnings ? 'primary' : 'textDisabled'}
decimals={hasEarnings ? 5 : 1}
value={hasEarnings ? earningTokenBalance : 0}
/>
{hasEarnings ? (
<>
{earningTokenPrice > 0 && (
<Balance
display="inline"
fontSize="12px"
color="textSubtle"
decimals={2}
prefix="~"
value={earningTokenDollarBalance}
unit=" USD"
/>
)}
</>
) : (
<Text mt="4px" fontSize="12px" color="textDisabled">
0 USD
</Text>
)}
</Box>
</Flex>
</>
)}
</CellContent>
</StyledCell>
)
}
Example #14
Source File: HasSharesActions.tsx From vvs-ui with GNU General Public License v3.0 | 5 votes |
HasSharesActions: React.FC<HasStakeActionProps> = ({ pool, stakingTokenBalance, performanceFee }) => {
const {
userData: { userShares },
pricePerFullShare,
} = useVvsVault()
const { stakingToken } = pool
const { vvsAsBigNumber, vvsAsNumberBalance } = convertSharesToVvs(userShares, pricePerFullShare)
const vvsPriceUsdc = usePriceVvsUsdc()
const stakedDollarValue = vvsPriceUsdc.gt(0)
? getBalanceNumber(vvsAsBigNumber.multipliedBy(vvsPriceUsdc), stakingToken.decimals)
: 0
const [onPresentTokenRequired] = useModal(<NotEnoughTokensModal tokenSymbol={stakingToken.symbol} />)
const [onPresentStake] = useModal(
<VaultStakeModal stakingMax={stakingTokenBalance} performanceFee={performanceFee} pool={pool} />,
)
const [onPresentUnstake] = useModal(<VaultStakeModal stakingMax={vvsAsBigNumber} pool={pool} isRemovingStake />)
return (
<Flex justifyContent="space-between" alignItems="center">
<Flex flexDirection="column">
<Balance fontSize="20px" bold value={vvsAsNumberBalance} decimals={5} />
<Text fontSize="12px" color="textSubtle">
{vvsPriceUsdc.gt(0) && !isBlindMode() ? (
<Balance value={stakedDollarValue} fontSize="12px" color="textSubtle" decimals={2} prefix="~" unit=" USD" />
) : (
<Skeleton mt="1px" height={16} width={64} />
)}
</Text>
</Flex>
<Flex>
<IconButton variant="secondary" onClick={onPresentUnstake} mr="6px">
<MinusIcon color="primary" width="24px" />
</IconButton>
<IconButton variant="secondary" onClick={stakingTokenBalance.gt(0) ? onPresentStake : onPresentTokenRequired}>
<AddIcon color="primary" width="24px" height="24px" />
</IconButton>
</Flex>
</Flex>
)
}
Example #15
Source File: index.tsx From vvs-ui with GNU General Public License v3.0 | 5 votes |
FarmsCard = () => {
const { t } = useTranslation()
const { isDesktop } = useMatchBreakpoints()
const { data: farmsLP } = useFarms()
const vvsPrice = usePriceVvsUsdc()
usePollFarmsWithUserData(true)
// const activeFarms = farmsLP.filter(farm => farm.pid !== 0 && farm.multiplier !== '0X' && !isArchivedPid(farm.pid))
const activeFarms = farmsLP.filter(farm => farm.pid !== 0 && farm.pid !== 3) // FIXME temp show CRO/VVS and CRO/USDC with 0x
const stakedOnlyFarms = activeFarms.filter(farm =>
farm.userData && new BigNumber(farm.userData.stakedBalance).isGreaterThan(0),
)
let totalStakedFarms = BIG_ZERO
let totalFarms = 0
let totalApr = 0
stakedOnlyFarms.forEach(farm => {
if (farm.lpTotalSupply.gt(0) && farm.lpTotalInQuoteToken.gt(0)) {
const valueOfBaseTokenInFarm = new BigNumber(farm.tokenPriceUsdc).times(farm.tokenAmountTotal)
const overallValueOfAllTokensInFarm = valueOfBaseTokenInFarm.times(2)
const totalLpTokens = getBalanceAmount(farm.lpTotalSupply)
const lpPrice = overallValueOfAllTokensInFarm.div(totalLpTokens)
totalStakedFarms = totalStakedFarms.plus(getBalanceNumber(lpPrice.times(farm.userData.stakedBalance)))
totalFarms += 1
const totalLiquidity = new BigNumber(farm.lpTotalInQuoteToken).times(farm.quoteTokenPriceUsdc)
const { vvsRewardsApr } = getFarmApr(new BigNumber(farm.poolWeight), vvsPrice, totalLiquidity, getAddress(farm.lpAddresses))
totalApr += vvsRewardsApr
}
})
return (
<Wrapper mt={['24px', null, '36px', null]} mb={['24px', null, '36px', null]} flexDirection="column">
<Heading color="primary">
{t('Crystal Farms')}
</Heading>
<Flex className="info" justifyContent={['space-between', null, null, 'flex-start']}>
<Flex flexDirection="column" mt="10px" mr="24px">
<Text minWidth={['110px', null, null, '160px']} color="white" bold fontSize="20px">
<Balance
decimals={totalStakedFarms.gt(0) ? 2 : 0}
fontSize="20px"
color="white"
bold
prefix={totalStakedFarms.gt(0) ? '~$' : '$'}
lineHeight="1.1"
value={totalStakedFarms.toNumber()}
/>
</Text>
<Text minWidth={['110px', null, null, '160px']} color="grey" fontSize="13px">
{t('Total Staked')}
</Text>
</Flex>
<Flex flexDirection="column" mt="10px">
<Text minWidth={['110px', null, null, '160px']} color="white" bold fontSize="20px">
{isBlindMode() ? <Skeleton width={60} /> : <Balance
decimals={totalApr > 0 ? 2 : 0}
fontSize="20px"
color="white"
bold
unit="%"
lineHeight="1.1"
value={totalApr ? totalApr / totalFarms : 0}
/>}
</Text>
<Text minWidth={['110px', null, null, '160px']} color="grey" fontSize="13px">
{t('Average APR')}
</Text>
</Flex>
</Flex>
{
isDesktop && <Image className="bg bg-farms" src="/images/dashboard/farms-bg.png" width={220} height={170} />
}
</Wrapper>
)
}
Example #16
Source File: index.tsx From vvs-ui with GNU General Public License v3.0 | 5 votes |
Menu = (props) => {
const { isDark, toggleTheme } = useTheme()
const vvsPriceUsd = usePriceVvsUsdc()
const { profile } = useProfile()
const { currentLanguage, setLanguage, t } = useTranslation()
const { pathname } = useLocation()
const activeMenuItem = getActiveMenuItem({ menuConfig: config(t), pathname })
const activeSubMenuItem = getActiveSubMenuItem({ menuItem: activeMenuItem, pathname })
return (
<UikitMenu
userMenu={isCountdown() ? null : <UserMenu />}
globalMenu={isCountdown() ? null : <GlobalSettings />}
isDark={isDark}
isBlindMode={isBlindMode()}
toggleTheme={toggleTheme}
t={t}
currentLang={currentLanguage.code}
langs={languageList}
setLang={setLanguage}
vvsPriceUsd={vvsPriceUsd.toNumber()}
showVvsPrice={showVvsPrice()}
links={isCountdown() ? [] : config(t)}
subLinks={activeMenuItem?.hideSubNav ? [] : activeMenuItem?.items}
footerLinks={footerLinks(t)}
activeItem={activeMenuItem?.href}
activeSubItem={activeSubMenuItem?.href}
buyVvsLabel={t('Buy VVS')}
profile={{
username: profile?.username,
image: profile?.nft ? `/images/nfts/${profile.nft?.images.sm}` : undefined,
profileLink: '/profile',
noProfileLink: '/profile',
showPip: !profile?.username,
}}
iconCallback={() => registerToken(tokens.vvs.address, tokens.vvs.symbol, tokens.vvs.decimals)}
vvsAddress={tokens.vvs.address}
{...props}
/>
)
}
Example #17
Source File: StakeModal.tsx From vvs-ui with GNU General Public License v3.0 | 4 votes |
StakeModal: React.FC<StakeModalProps> = ({
isBnbPool,
pool,
stakingTokenBalance,
stakingTokenPrice,
isRemovingStake = false,
onDismiss,
}) => {
const { sousId, stakingToken, earningTokenPrice, apr, userData, stakingLimit, earningToken } = pool
const { t } = useTranslation()
const { theme } = useTheme()
const { onStake } = useStakePool(sousId, isBnbPool)
const { onUnstake } = useUnstakePool(sousId, pool.enableEmergencyWithdraw)
const { toastSuccess, toastError } = useToast()
const [pendingTx, setPendingTx] = useState(false)
const [stakeAmount, setStakeAmount] = useState('')
const [hasReachedStakeLimit, setHasReachedStakedLimit] = useState(false)
const [percent, setPercent] = useState(0)
const [showRoiCalculator, setShowRoiCalculator] = useState(false)
const getCalculatedStakingLimit = () => {
if (isRemovingStake) {
return userData.stakedBalance
}
return stakingLimit.gt(0) && stakingTokenBalance.gt(stakingLimit) ? stakingLimit : stakingTokenBalance
}
const fullDecimalStakeAmount = getDecimalAmount(new BigNumber(stakeAmount), stakingToken.decimals)
const userNotEnoughToken = isRemovingStake
? userData.stakedBalance.lt(fullDecimalStakeAmount)
: userData.stakingTokenBalance.lt(fullDecimalStakeAmount)
const usdValueStaked = new BigNumber(stakeAmount).times(stakingTokenPrice)
const formattedUsdValueStaked = !usdValueStaked.isNaN() && formatNumber(usdValueStaked.toNumber())
const interestBreakdown = getInterestBreakdown({
principalInUSD: !usdValueStaked.isNaN() ? usdValueStaked.toNumber() : 0,
apr,
earningTokenPrice,
})
const annualRoi = interestBreakdown[3] * pool.earningTokenPrice
const formattedAnnualRoi = formatNumber(annualRoi, annualRoi > 10000 ? 0 : 2, annualRoi > 10000 ? 0 : 2)
const getTokenLink = stakingToken.address ? `/swap?outputCurrency=${stakingToken.address}` : '/swap'
useEffect(() => {
if (stakingLimit.gt(0) && !isRemovingStake) {
setHasReachedStakedLimit(fullDecimalStakeAmount.plus(userData.stakedBalance).gt(stakingLimit))
}
}, [
stakeAmount,
stakingLimit,
userData,
stakingToken,
isRemovingStake,
setHasReachedStakedLimit,
fullDecimalStakeAmount,
])
const handleStakeInputChange = (input: string) => {
if (input) {
const convertedInput = getDecimalAmount(new BigNumber(input), stakingToken.decimals)
const percentage = Math.floor(convertedInput.dividedBy(getCalculatedStakingLimit()).multipliedBy(100).toNumber())
setPercent(Math.min(percentage, 100))
} else {
setPercent(0)
}
setStakeAmount(input)
}
const handleChangePercent = (sliderPercent: number) => {
if (sliderPercent > 0) {
const percentageOfStakingMax = getCalculatedStakingLimit().dividedBy(100).multipliedBy(sliderPercent)
const amountToStake = getFullDisplayBalance(percentageOfStakingMax, stakingToken.decimals, stakingToken.decimals)
setStakeAmount(amountToStake)
} else {
setStakeAmount('')
}
setPercent(sliderPercent)
}
const handleConfirmClick = async () => {
setPendingTx(true)
try {
if (isRemovingStake) {
// unstaking
await onUnstake(stakeAmount, stakingToken.decimals)
toastSuccess(
`${t('Unstaked')}!`,
t('Your %symbol% earnings have also been harvested to your wallet!', {
symbol: earningToken.symbol,
}),
)
} else {
// staking
await onStake(stakeAmount, stakingToken.decimals)
toastSuccess(
`${t('Staked')}!`,
t('Your %symbol% funds have been staked in the pool!', {
symbol: stakingToken.symbol,
}),
)
}
setPendingTx(false)
onDismiss()
} catch (e) {
toastError(t('Error'), t('Please try again. Confirm the transaction and make sure you are paying enough gas!'))
setPendingTx(false)
}
}
if (showRoiCalculator) {
return (
<RoiCalculatorModal
earningTokenPrice={earningTokenPrice}
stakingTokenPrice={stakingTokenPrice}
apr={apr}
linkLabel={t('Get %symbol%', { symbol: stakingToken.symbol })}
linkHref={getTokenLink}
stakingTokenBalance={userData.stakedBalance.plus(stakingTokenBalance)}
stakingTokenSymbol={stakingToken.symbol}
earningTokenSymbol={earningToken.symbol}
onBack={() => setShowRoiCalculator(false)}
initialValue={stakeAmount}
/>
)
}
return (
<Modal
minWidth="346px"
title={isRemovingStake ? t('Unstake') : t('Stake in Mine')}
onDismiss={onDismiss}
headerBackground={theme.colors.gradients.cardHeader}
>
{stakingLimit.gt(0) && !isRemovingStake && (
<Text color="secondary" bold mb="24px" style={{ textAlign: 'center' }} fontSize="16px">
{t('Max stake for this pool: %amount% %token%', {
amount: getFullDisplayBalance(stakingLimit, stakingToken.decimals, 0),
token: stakingToken.symbol,
})}
</Text>
)}
<Flex alignItems="center" justifyContent="space-between" mb="8px">
<Text bold>{isRemovingStake ? t('Unstake') : t('Stake')}:</Text>
<Flex alignItems="center" minWidth="70px">
<Image src={`/images/tokens/${stakingToken.address}.png`} width={24} height={24} alt={stakingToken.symbol} />
<Text ml="4px" bold>
{stakingToken.symbol}
</Text>
</Flex>
</Flex>
<BalanceInput
value={stakeAmount}
onUserInput={handleStakeInputChange}
currencyValue={isBlindMode() ? null : (stakingTokenPrice !== 0 && `~${formattedUsdValueStaked || 0} USD`)}
isWarning={hasReachedStakeLimit || userNotEnoughToken}
decimals={stakingToken.decimals}
/>
{hasReachedStakeLimit && (
<Text color="failure" fontSize="12px" style={{ textAlign: 'right' }} mt="4px">
{t('Maximum total stake: %amount% %token%', {
amount: getFullDisplayBalance(new BigNumber(stakingLimit), stakingToken.decimals, 0),
token: stakingToken.symbol,
})}
</Text>
)}
{userNotEnoughToken && (
<Text color="failure" fontSize="12px" style={{ textAlign: 'right' }} mt="4px">
{t('Insufficient %symbol% balance', {
symbol: stakingToken.symbol,
})}
</Text>
)}
<Text ml="auto" color="textSubtle" fontSize="12px" mb="8px">
{t('Balance: %balance%', {
balance: getFullDisplayBalance(getCalculatedStakingLimit(), stakingToken.decimals),
})}
</Text>
<Slider
min={0}
max={100}
value={percent}
onValueChanged={handleChangePercent}
name="stake"
valueLabel={`${percent}%`}
step={1}
/>
<Flex alignItems="center" justifyContent="space-between" mt="8px">
<PercentageButton onClick={() => handleChangePercent(25)}>25%</PercentageButton>
<PercentageButton onClick={() => handleChangePercent(50)}>50%</PercentageButton>
<PercentageButton onClick={() => handleChangePercent(75)}>75%</PercentageButton>
<PercentageButton onClick={() => handleChangePercent(100)}>{t('Max')}</PercentageButton>
</Flex>
{!isRemovingStake && (
<Flex mt="24px" alignItems="center" justifyContent="space-between">
<Text mr="8px" color="textSubtle">
{t('Annual ROI at current rates')}:
</Text>
{!isBlindMode() && <AnnualRoiContainer alignItems="center" onClick={() => setShowRoiCalculator(true)}>
<AnnualRoiDisplay>${formattedAnnualRoi}</AnnualRoiDisplay>
<IconButton variant="text" scale="sm">
<CalculateIcon color="textSubtle" width="18px" />
</IconButton>
</AnnualRoiContainer>}
</Flex>
)}
<Button
isLoading={pendingTx}
endIcon={pendingTx ? <AutoRenewIcon spin color="currentColor" /> : null}
onClick={handleConfirmClick}
disabled={!stakeAmount || parseFloat(stakeAmount) === 0 || hasReachedStakeLimit || userNotEnoughToken}
mt="24px"
>
{pendingTx ? t('Confirming') : t('Confirm')}
</Button>
{!isRemovingStake && (
<StyledLink external href={getTokenLink}>
<Button width="100%" mt="8px" variant="secondary">
{t('Get %symbol%', { symbol: stakingToken.symbol })}
</Button>
</StyledLink>
)}
</Modal>
)
}
Example #18
Source File: ActionPanel.tsx From vvs-ui with GNU General Public License v3.0 | 4 votes |
ActionPanel: React.FC<ActionPanelProps> = ({ account, pool, userDataLoaded, expanded, breakpoints }) => {
const {
sousId,
stakingToken,
earningToken,
totalStaked,
startBlock,
endBlock,
stakingLimit,
contractAddress,
userData,
isAutoVault,
} = pool
const { t } = useTranslation()
const { chainId } = useActiveWeb3React()
const poolContractAddress = getAddress(contractAddress)
const vvsVaultContractAddress = getVvsVaultAddress()
const { currentBlock } = useBlock()
const { isXs, isSm, isMd } = breakpoints
const showSubtitle = (isXs || isSm) && sousId === 0
const { shouldShowBlockCountdown, blocksUntilStart, blocksRemaining, hasPoolStarted, blocksToDisplay } =
getPoolBlockInfo(pool, currentBlock)
const isMetaMaskInScope = !!window.ethereum?.isMetaMask
const tokenAddress = earningToken.address || ''
const {
totalVvsInVault,
userData: { userShares },
fees: { performanceFee },
pricePerFullShare,
} = useVvsVault()
const stakingTokenBalance = userData?.stakingTokenBalance ? new BigNumber(userData.stakingTokenBalance) : BIG_ZERO
const stakedBalance = userData?.stakedBalance ? new BigNumber(userData.stakedBalance) : BIG_ZERO
const { vvsAsBigNumber } = convertSharesToVvs(userShares, pricePerFullShare)
const poolStakingTokenBalance = isAutoVault
? vvsAsBigNumber.plus(stakingTokenBalance)
: stakedBalance.plus(stakingTokenBalance)
const performanceFeeAsDecimal = performanceFee && performanceFee / 100
const isManualVvsPool = sousId === 0
const getTotalStakedBalance = () => {
if (isAutoVault) {
return getBalanceNumber(totalVvsInVault, stakingToken.decimals)
}
if (isManualVvsPool) {
const manualVvsTotalMinusAutoVault = new BigNumber(totalStaked).minus(totalVvsInVault)
return getBalanceNumber(manualVvsTotalMinusAutoVault, stakingToken.decimals)
}
return getBalanceNumber(totalStaked, stakingToken.decimals)
}
const {
targetRef: totalStakedTargetRef,
tooltip: totalStakedTooltip,
tooltipVisible: totalStakedTooltipVisible,
} = useTooltip(t('Total amount of %symbol% staked in this pool', { symbol: stakingToken.symbol }), {
placement: 'bottom',
})
const manualTooltipText = t('You must harvest and compound your earnings from this pool manually.')
const autoTooltipText = t(
'Any funds you stake in this pool will be automagically harvested and restaked (compounded) for you.',
)
const {
targetRef: tagTargetRef,
tooltip: tagTooltip,
tooltipVisible: tagTooltipVisible,
} = useTooltip(isAutoVault ? autoTooltipText : manualTooltipText, {
placement: 'bottom-start',
})
const maxStakeRow = stakingLimit.gt(0) ? (
<Flex mb="8px" justifyContent="space-between">
<Text>{t('Max. stake per user')}:</Text>
<Text>{`${getFullDisplayBalance(stakingLimit, stakingToken.decimals, 0)} ${stakingToken.symbol}`}</Text>
</Flex>
) : null
const blocksRow =
blocksRemaining || blocksUntilStart ? (
<Flex mb="8px" justifyContent="space-between">
<Text>{hasPoolStarted ? t('Ends in') : t('Starts in')}:</Text>
<Flex>
<Link external href={getExplorerLink(hasPoolStarted ? endBlock : startBlock, 'countdown')}>
<Balance fontSize="16px" value={blocksToDisplay} decimals={0} color="primary" />
<Text ml="4px" color="primary" textTransform="lowercase">
{t('Blocks')}
</Text>
<TimerIcon ml="4px" color="primary" />
</Link>
</Flex>
</Flex>
) : (
<Skeleton width="56px" height="16px" />
)
const aprRow = (
<Flex justifyContent="space-between" alignItems="center" mb="8px">
<Text>{isAutoVault ? t('APY') : t('APR')}:</Text>
<Apr
pool={pool}
showIcon
stakedBalance={poolStakingTokenBalance}
performanceFee={isAutoVault ? performanceFeeAsDecimal : 0}
/>
</Flex>
)
const totalStakedRow = (
<Flex justifyContent="space-between" alignItems="center" mb="8px">
<Text maxWidth={['50px', '100%']}>{t('Total staked')}:</Text>
<Flex alignItems="center">
{totalStaked && totalStaked.gte(0) ? (
<>
<Balance fontSize="16px" value={getTotalStakedBalance()} decimals={0} unit={` ${stakingToken.symbol}`} />
<span ref={totalStakedTargetRef}>
<HelpIcon color="textSubtle" width="20px" ml="4px" />
</span>
</>
) : (
<Skeleton width="56px" height="16px" />
)}
{totalStakedTooltipVisible && totalStakedTooltip}
</Flex>
</Flex>
)
return (
<StyledActionPanel expanded={expanded}>
<InfoSection>
{maxStakeRow}
{(isXs || isSm) && aprRow}
{(isXs || isSm || isMd) && totalStakedRow}
{shouldShowBlockCountdown && blocksRow}
{!isBlindMode() && <Flex mb="8px" justifyContent={['flex-end', 'flex-end', 'flex-start']}>
<LinkExternal href={`/info/token/${earningToken.address}`} bold={false}>
{t('See Token Info')}
</LinkExternal>
</Flex>}
<Flex mb="8px" justifyContent={['flex-end', 'flex-end', 'flex-start']}>
<LinkExternal href={earningToken.projectLink} bold={false}>
{t('View Project Site')}
</LinkExternal>
</Flex>
{poolContractAddress && (
<Flex mb="8px" justifyContent={['flex-end', 'flex-end', 'flex-start']}>
<LinkExternal
href={`${BASE_EXPLORER_URLS[chainId]}/address/${isAutoVault ? vvsVaultContractAddress : poolContractAddress}`}
bold={false}
>
{t('View Contract')}
</LinkExternal>
</Flex>
)}
{account && isMetaMaskInScope && tokenAddress && (
<Flex mb="8px" justifyContent={['flex-end', 'flex-end', 'flex-start']}>
<Button
variant="text"
p="0"
height="auto"
onClick={() => registerToken(tokenAddress, earningToken.symbol, earningToken.decimals)}
>
<Text color="primary">{t('Add to Metamask')}</Text>
<MetamaskIcon ml="4px" />
</Button>
</Flex>
)}
{isAutoVault ? <CompoundingPoolTag /> : <ManualPoolTag />}
{tagTooltipVisible && tagTooltip}
<span ref={tagTargetRef}>
<HelpIcon ml="4px" width="20px" height="20px" color="textSubtle" />
</span>
</InfoSection>
<ActionContainer>
{showSubtitle && (
<Text mt="4px" mb="16px" color="textSubtle">
{isAutoVault ? t('Automatic restaking') : `${t('Earn')} VVS ${t('Stake').toLocaleLowerCase()} VVS`}
</Text>
)}
{pool.isAutoVault ? (
<AutoHarvest {...pool} userDataLoaded={userDataLoaded} />
) : (
<Harvest {...pool} userDataLoaded={userDataLoaded} />
)}
<Stake pool={pool} userDataLoaded={userDataLoaded} />
</ActionContainer>
</StyledActionPanel>
)
}
Example #19
Source File: AutoHarvest.tsx From vvs-ui with GNU General Public License v3.0 | 4 votes |
AutoHarvestAction: React.FunctionComponent<AutoHarvestActionProps> = ({ userDataLoaded, earningTokenPrice }) => {
const { t } = useTranslation()
const { account } = useWeb3React()
const {
userData: { vvsAtLastUserAction, userShares },
pricePerFullShare,
fees: { performanceFee },
} = useVvsVault()
const { hasAutoEarnings, autoVvsToDisplay, autoUsdToDisplay } = getVvsVaultEarnings(
account,
vvsAtLastUserAction,
userShares,
pricePerFullShare,
earningTokenPrice,
)
const earningTokenBalance = autoVvsToDisplay
const earningTokenDollarBalance = autoUsdToDisplay
const hasEarnings = hasAutoEarnings
const { targetRef, tooltip, tooltipVisible } = useTooltip(
t('Subtracted automatically from each yield harvest and burned.'),
{ placement: 'bottom-start' },
)
const actionTitle = (
<Text fontSize="12px" bold color="secondary" as="span" textTransform="uppercase">
{t('Recent VVS profit')}
</Text>
)
if (!account) {
return (
<ActionContainer>
<ActionTitles>{actionTitle}</ActionTitles>
<ActionContent>
<Heading>0</Heading>
</ActionContent>
</ActionContainer>
)
}
if (!userDataLoaded) {
return (
<ActionContainer>
<ActionTitles>{actionTitle}</ActionTitles>
<ActionContent>
<Skeleton width={180} height="32px" marginTop={14} />
</ActionContent>
</ActionContainer>
)
}
return (
<ActionContainer isAutoVault>
<ActionTitles>{actionTitle}</ActionTitles>
<ActionContent>
<Flex flex="1" pt="16px" flexDirection="column" alignSelf="flex-start">
<>
{hasEarnings ? (
<>
<Balance lineHeight="1" bold fontSize="20px" decimals={5} value={earningTokenBalance} />
{isBlindMode() ? <Skeleton mt={1} width={60} /> : (earningTokenPrice > 0 && (
<Balance
display="inline"
fontSize="12px"
color="textSubtle"
decimals={2}
prefix="~"
value={earningTokenDollarBalance}
unit=" USD"
/>
))}
</>
) : (
<>
<Heading color="textDisabled">0</Heading>
<Text fontSize="12px" color="textDisabled">
0 USD
</Text>
</>
)}
</>
</Flex>
<Flex flex="1.3" flexDirection="column" alignSelf="flex-start" alignItems="flex-start">
<UnstakingFeeCountdownRow isTableVariant />
<Flex mb="2px" justifyContent="space-between" alignItems="center">
{tooltipVisible && tooltip}
<TooltipText ref={targetRef} small>
{t('Performance Fee')}
</TooltipText>
<Flex alignItems="center">
<Text ml="4px" small>
{performanceFee / 100}%
</Text>
</Flex>
</Flex>
</Flex>
</ActionContent>
</ActionContainer>
)
}
Example #20
Source File: VaultStakeModal.tsx From vvs-ui with GNU General Public License v3.0 | 4 votes |
VaultStakeModal: React.FC<VaultStakeModalProps> = ({ pool, stakingMax, performanceFee, isRemovingStake = false, onDismiss, }) => { const dispatch = useAppDispatch() const { stakingToken, earningToken, apr, stakingTokenPrice, earningTokenPrice } = pool const { account } = useWeb3React() const vvsVaultContract = useVvsVaultContract() const { callWithGasPrice } = useCallWithGasPrice() const { userData: { lastDepositedTime, userShares }, pricePerFullShare, } = useVvsVault() const { t } = useTranslation() const { theme } = useTheme() const { toastSuccess, toastError } = useToast() const [pendingTx, setPendingTx] = useState(false) const [stakeAmount, setStakeAmount] = useState('') const [percent, setPercent] = useState(0) const [showRoiCalculator, setShowRoiCalculator] = useState(false) const { hasUnstakingFee } = useWithdrawalFeeTimer(parseInt(lastDepositedTime, 10), userShares) const vvsPriceUsdc = usePriceVvsUsdc() const usdValueStaked = new BigNumber(stakeAmount).times(vvsPriceUsdc) const formattedUsdValueStaked = vvsPriceUsdc.gt(0) && stakeAmount ? formatNumber(usdValueStaked.toNumber()) : '' const { vvsAsBigNumber } = convertSharesToVvs(userShares, pricePerFullShare) const interestBreakdown = getInterestBreakdown({ principalInUSD: !usdValueStaked.isNaN() ? usdValueStaked.toNumber() : 0, apr, earningTokenPrice, performanceFee, }) const annualRoi = interestBreakdown[3] * pool.earningTokenPrice const formattedAnnualRoi = formatNumber(annualRoi, annualRoi > 10000 ? 0 : 2, annualRoi > 10000 ? 0 : 2) const getTokenLink = stakingToken.address ? `/swap?outputCurrency=${stakingToken.address}` : '/swap' const handleStakeInputChange = (input: string) => { if (input) { const convertedInput = new BigNumber(input).multipliedBy(BIG_TEN.pow(stakingToken.decimals)) const percentage = Math.floor(convertedInput.dividedBy(stakingMax).multipliedBy(100).toNumber()) setPercent(percentage > 100 ? 100 : percentage) } else { setPercent(0) } setStakeAmount(input) } const handleChangePercent = (sliderPercent: number) => { if (sliderPercent > 0) { const percentageOfStakingMax = stakingMax.dividedBy(100).multipliedBy(sliderPercent) const amountToStake = getFullDisplayBalance(percentageOfStakingMax, stakingToken.decimals, stakingToken.decimals) setStakeAmount(amountToStake) } else { setStakeAmount('') } setPercent(sliderPercent) } const handleWithdrawal = async (convertedStakeAmount: BigNumber) => { setPendingTx(true) const shareStakeToWithdraw = convertVvsToShares(convertedStakeAmount, pricePerFullShare) // trigger withdrawAll function if the withdrawal will leave 0.000001 VVS or less const triggerWithdrawAllThreshold = new BigNumber(1000000000000) const sharesRemaining = userShares.minus(shareStakeToWithdraw.sharesAsBigNumber) const isWithdrawingAll = sharesRemaining.lte(triggerWithdrawAllThreshold) if (isWithdrawingAll) { try { const tx = await callWithGasPrice(vvsVaultContract, 'withdrawAll', undefined, callOptions) const receipt = await tx.wait() if (receipt.status) { toastSuccess( t('Unstaked!'), <ToastDescriptionWithTx txHash={receipt.transactionHash}> {t('Your earnings have also been harvested to your wallet')} </ToastDescriptionWithTx>, ) setPendingTx(false) onDismiss() dispatch(fetchVvsVaultUserData({ account })) } } catch (error) { toastError(t('Error'), t('Please try again. Confirm the transaction and make sure you are paying enough gas!')) setPendingTx(false) } } else { // .toString() being called to fix a BigNumber error in prod // as suggested here https://github.com/ChainSafe/web3.js/issues/2077 try { const tx = await callWithGasPrice( vvsVaultContract, 'withdraw', [shareStakeToWithdraw.sharesAsBigNumber.toString()], callOptions, ) const receipt = await tx.wait() if (receipt.status) { toastSuccess( t('Unstaked!'), <ToastDescriptionWithTx txHash={receipt.transactionHash}> {t('Your earnings have also been harvested to your wallet')} </ToastDescriptionWithTx>, ) setPendingTx(false) onDismiss() dispatch(fetchVvsVaultUserData({ account })) } } catch (error) { toastError(t('Error'), t('Please try again. Confirm the transaction and make sure you are paying enough gas!')) setPendingTx(false) } } } const handleDeposit = async (convertedStakeAmount: BigNumber) => { setPendingTx(true) try { // .toString() being called to fix a BigNumber error in prod // as suggested here https://github.com/ChainSafe/web3.js/issues/2077 const tx = await callWithGasPrice(vvsVaultContract, 'deposit', [convertedStakeAmount.toString()], callOptions) const receipt = await tx.wait() if (receipt.status) { toastSuccess( t('Staked!'), <ToastDescriptionWithTx txHash={receipt.transactionHash}> {t('Your funds have been staked in the pool')} </ToastDescriptionWithTx>, ) setPendingTx(false) onDismiss() dispatch(fetchVvsVaultUserData({ account })) } } catch (error) { toastError(t('Error'), t('Please try again. Confirm the transaction and make sure you are paying enough gas!')) setPendingTx(false) } } const handleConfirmClick = async () => { const convertedStakeAmount = getDecimalAmount(new BigNumber(stakeAmount), stakingToken.decimals) if (isRemovingStake) { // unstaking handleWithdrawal(convertedStakeAmount) } else { // staking handleDeposit(convertedStakeAmount) } } if (showRoiCalculator) { return ( <RoiCalculatorModal earningTokenPrice={earningTokenPrice} stakingTokenPrice={stakingTokenPrice} apr={apr} linkLabel={t('Get %symbol%', { symbol: stakingToken.symbol })} linkHref={getTokenLink} stakingTokenBalance={vvsAsBigNumber.plus(stakingMax)} stakingTokenSymbol={stakingToken.symbol} earningTokenSymbol={earningToken.symbol} onBack={() => setShowRoiCalculator(false)} initialValue={stakeAmount} performanceFee={performanceFee} /> ) } return ( <Modal title={isRemovingStake ? t('Unstake') : t('Stake in Mine')} onDismiss={onDismiss} headerBackground={theme.colors.gradients.cardHeader} > <Flex alignItems="center" justifyContent="space-between" mb="8px"> <Text bold>{isRemovingStake ? t('Unstake') : t('Stake')}:</Text> <Flex alignItems="center" minWidth="70px"> <Image src={`/images/tokens/${stakingToken.address}.png`} width={24} height={24} alt={stakingToken.symbol} /> <Text ml="4px" bold> {stakingToken.symbol} </Text> </Flex> </Flex> <BalanceInput value={stakeAmount} onUserInput={handleStakeInputChange} currencyValue={isBlindMode() ? null : (vvsPriceUsdc.gt(0) && `~${formattedUsdValueStaked || 0} USD`)} decimals={stakingToken.decimals} /> <Text mt="8px" ml="auto" color="textSubtle" fontSize="12px" mb="8px"> {t('Balance: %balance%', { balance: getFullDisplayBalance(stakingMax, stakingToken.decimals) })} </Text> <Slider min={0} max={100} value={percent} onValueChanged={handleChangePercent} name="stake" valueLabel={`${percent}%`} step={1} /> <Flex alignItems="center" justifyContent="space-between" mt="8px"> <StyledButton scale="xs" mx="2px" p="4px 16px" variant="tertiary" onClick={() => handleChangePercent(25)}> 25% </StyledButton> <StyledButton scale="xs" mx="2px" p="4px 16px" variant="tertiary" onClick={() => handleChangePercent(50)}> 50% </StyledButton> <StyledButton scale="xs" mx="2px" p="4px 16px" variant="tertiary" onClick={() => handleChangePercent(75)}> 75% </StyledButton> <StyledButton scale="xs" mx="2px" p="4px 16px" variant="tertiary" onClick={() => handleChangePercent(100)}> {t('Max')} </StyledButton> </Flex> {isRemovingStake && hasUnstakingFee && ( <FeeSummary stakingTokenSymbol={stakingToken.symbol} stakeAmount={stakeAmount} /> )} {!isRemovingStake && ( <Flex mt="24px" alignItems="center" justifyContent="space-between"> <Text mr="8px" color="textSubtle"> {t('Annual ROI at current rates')}: </Text> {!isBlindMode() && <AnnualRoiContainer alignItems="center" onClick={() => setShowRoiCalculator(true)}> <AnnualRoiDisplay>${formattedAnnualRoi}</AnnualRoiDisplay> <IconButton variant="text" scale="sm"> <CalculateIcon color="textSubtle" width="18px" /> </IconButton> </AnnualRoiContainer>} </Flex> )} <Button isLoading={pendingTx} endIcon={pendingTx ? <AutoRenewIcon spin color="currentColor" /> : null} onClick={handleConfirmClick} disabled={!stakeAmount || parseFloat(stakeAmount) === 0} mt="24px" > {pendingTx ? t('Confirming') : t('Confirm')} </Button> {!isRemovingStake && ( <Button mt="8px" as="a" external href={getTokenLink} variant="secondary"> {t('Get %symbol%', { symbol: stakingToken.symbol })} </Button> )} </Modal> ) }
Example #21
Source File: Harvest.tsx From vvs-ui with GNU General Public License v3.0 | 4 votes |
HarvestAction: React.FunctionComponent<HarvestActionProps> = ({
sousId,
poolCategory,
earningToken,
userData,
userDataLoaded,
earningTokenPrice,
}) => {
const { t } = useTranslation()
const { account } = useWeb3React()
const earnings = userData?.pendingReward ? new BigNumber(userData.pendingReward) : BIG_ZERO
const earningTokenBalance = getBalanceNumber(earnings, earningToken.decimals)
const earningTokenDollarBalance = getBalanceNumber(earnings.multipliedBy(earningTokenPrice), earningToken.decimals)
const hasEarnings = earnings.gt(0)
const fullBalance = getFullDisplayBalance(earnings, earningToken.decimals)
const formattedBalance = formatNumber(earningTokenBalance, 3, 3)
const isCompoundPool = sousId === 0
const isBnbPool = poolCategory === PoolCategory.BINANCE
const [onPresentCollect] = useModal(
<CollectModal
formattedBalance={formattedBalance}
fullBalance={fullBalance}
earningToken={earningToken}
earningsDollarValue={earningTokenDollarBalance}
sousId={sousId}
isBnbPool={isBnbPool}
isCompoundPool={isCompoundPool}
/>,
)
const actionTitle = (
<>
<Text fontSize="12px" bold color="secondary" as="span" textTransform="uppercase">
{earningToken.symbol}{' '}
</Text>
<Text fontSize="12px" bold color="textSubtle" as="span" textTransform="uppercase">
{t('Earned')}
</Text>
</>
)
if (!account) {
return (
<ActionContainer>
<ActionTitles>{actionTitle}</ActionTitles>
<ActionContent>
<Heading>0</Heading>
<Button disabled>{isCompoundPool ? t('Collect') : t('Harvest')}</Button>
</ActionContent>
</ActionContainer>
)
}
if (!userDataLoaded) {
return (
<ActionContainer>
<ActionTitles>{actionTitle}</ActionTitles>
<ActionContent>
<Skeleton width={180} height="32px" marginTop={14} />
</ActionContent>
</ActionContainer>
)
}
return (
<ActionContainer>
<ActionTitles>{actionTitle}</ActionTitles>
<ActionContent>
<Flex flex="1" pt="16px" flexDirection="column" alignSelf="flex-start">
<>
{hasEarnings ? (
<>
<Balance lineHeight="1" bold fontSize="20px" decimals={5} value={earningTokenBalance} />
{isBlindMode() ? <Skeleton mt={1} width={60} /> : (earningTokenPrice > 0 && (
<Balance
display="inline"
fontSize="12px"
color="textSubtle"
decimals={2}
prefix="~"
value={earningTokenDollarBalance}
unit=" USD"
/>
))}
</>
) : (
<>
<Heading color="textDisabled">0</Heading>
<Text fontSize="12px" color="textDisabled">
0 USD
</Text>
</>
)}
</>
</Flex>
<Button disabled={!hasEarnings} onClick={onPresentCollect}>
{isCompoundPool ? t('Collect') : t('Harvest')}
</Button>
</ActionContent>
</ActionContainer>
)
}
Example #22
Source File: Stake.tsx From vvs-ui with GNU General Public License v3.0 | 4 votes |
Staked: React.FunctionComponent<StackedActionProps> = ({ pool, userDataLoaded }) => {
const {
sousId,
stakingToken,
earningToken,
stakingLimit,
isFinished,
poolCategory,
userData,
stakingTokenPrice,
isAutoVault,
} = pool
const { t } = useTranslation()
const { account } = useWeb3React()
const stakingTokenContract = useERC20(stakingToken.address || '')
const { handleApprove: handlePoolApprove, requestedApproval: requestedPoolApproval } = useApprovePool(
stakingTokenContract,
sousId,
earningToken.symbol,
)
const { isVaultApproved, setLastUpdated } = useCheckVaultApprovalStatus()
const { handleApprove: handleVaultApprove, requestedApproval: requestedVaultApproval } =
useVaultApprove(setLastUpdated)
const handleApprove = isAutoVault ? handleVaultApprove : handlePoolApprove
const requestedApproval = isAutoVault ? requestedVaultApproval : requestedPoolApproval
const isBnbPool = poolCategory === PoolCategory.BINANCE
const allowance = userData?.allowance ? new BigNumber(userData.allowance) : BIG_ZERO
const stakedBalance = userData?.stakedBalance ? new BigNumber(userData.stakedBalance) : BIG_ZERO
const isNotVaultAndHasStake = !isAutoVault && stakedBalance.gt(0)
const stakingTokenBalance = userData?.stakingTokenBalance ? new BigNumber(userData.stakingTokenBalance) : BIG_ZERO
const stakedTokenBalance = getBalanceNumber(stakedBalance, stakingToken.decimals)
const stakedTokenDollarBalance = getBalanceNumber(
stakedBalance.multipliedBy(stakingTokenPrice),
stakingToken.decimals,
)
const {
userData: { userShares },
pricePerFullShare,
} = useVvsVault()
const { vvsAsBigNumber, vvsAsNumberBalance } = convertSharesToVvs(userShares, pricePerFullShare)
const hasSharesStaked = userShares && userShares.gt(0)
const isVaultWithShares = isAutoVault && hasSharesStaked
const stakedAutoDollarValue = getBalanceNumber(vvsAsBigNumber.multipliedBy(stakingTokenPrice), stakingToken.decimals)
const needsApproval = isAutoVault ? !isVaultApproved : !allowance.gt(0) && !isBnbPool
const [onPresentTokenRequired] = useModal(<NotEnoughTokensModal tokenSymbol={stakingToken.symbol} />)
const [onPresentStake] = useModal(
<StakeModal
isBnbPool={isBnbPool}
pool={pool}
stakingTokenBalance={stakingTokenBalance}
stakingTokenPrice={stakingTokenPrice}
/>,
)
const [onPresentVaultStake] = useModal(<VaultStakeModal stakingMax={stakingTokenBalance} pool={pool} />)
const [onPresentUnstake] = useModal(
<StakeModal
stakingTokenBalance={stakingTokenBalance}
isBnbPool={isBnbPool}
pool={pool}
stakingTokenPrice={stakingTokenPrice}
isRemovingStake
/>,
)
const [onPresentVaultUnstake] = useModal(<VaultStakeModal stakingMax={vvsAsBigNumber} pool={pool} isRemovingStake />)
const onStake = () => {
if (isAutoVault) {
onPresentVaultStake()
} else {
onPresentStake()
}
}
const onUnstake = () => {
if (isAutoVault) {
onPresentVaultUnstake()
} else {
onPresentUnstake()
}
}
const { targetRef, tooltip, tooltipVisible } = useTooltip(
t("You've already staked the maximum amount you can stake in this pool!"),
{ placement: 'bottom' },
)
const reachStakingLimit = stakingLimit.gt(0) && userData.stakedBalance.gte(stakingLimit)
if (!account) {
return (
<ActionContainer>
<ActionTitles>
<Text fontSize="12px" bold color="textSubtle" as="span" textTransform="uppercase">
{t('Start staking')}
</Text>
</ActionTitles>
<ActionContent>
<ConnectWalletButton width="100%" />
</ActionContent>
</ActionContainer>
)
}
if (!userDataLoaded) {
return (
<ActionContainer>
<ActionTitles>
<Text fontSize="12px" bold color="textSubtle" as="span" textTransform="uppercase">
{t('Start staking')}
</Text>
</ActionTitles>
<ActionContent>
<Skeleton width={180} height="32px" marginTop={14} />
</ActionContent>
</ActionContainer>
)
}
if (needsApproval) {
return (
<ActionContainer>
<ActionTitles>
<Text fontSize="12px" bold color="textSubtle" as="span" textTransform="uppercase">
{t('Enable pool')}
</Text>
</ActionTitles>
<ActionContent>
<Button width="100%" disabled={requestedApproval} onClick={handleApprove} variant="secondary">
{t('Enable')}
</Button>
</ActionContent>
</ActionContainer>
)
}
// Wallet connected, user data loaded and approved
if (isNotVaultAndHasStake || isVaultWithShares) {
return (
<ActionContainer isAutoVault={isAutoVault}>
<ActionTitles>
<Text fontSize="12px" bold color="secondary" as="span" textTransform="uppercase">
{stakingToken.symbol}{' '}
</Text>
<Text fontSize="12px" bold color="textSubtle" as="span" textTransform="uppercase">
{isAutoVault ? t('Staked (compounding)') : t('Staked')}
</Text>
</ActionTitles>
<ActionContent>
<Flex flex="1" pt="16px" flexDirection="column" alignSelf="flex-start">
<Balance
lineHeight="1"
bold
fontSize="20px"
decimals={5}
value={isAutoVault ? vvsAsNumberBalance : stakedTokenBalance}
/>
{isBlindMode() ? <Skeleton mt={1} width={60} /> : <Balance
fontSize="12px"
display="inline"
color="textSubtle"
decimals={2}
value={isAutoVault ? stakedAutoDollarValue : stakedTokenDollarBalance}
unit=" USD"
prefix="~"
/>}
</Flex>
<IconButtonWrapper>
<IconButton variant="secondary" onClick={onUnstake} mr="6px">
<MinusIcon color="primary" width="14px" />
</IconButton>
{reachStakingLimit ? (
<span ref={targetRef}>
<IconButton variant="secondary" disabled>
<AddIcon color="textDisabled" width="24px" height="24px" />
</IconButton>
</span>
) : (
<IconButton
variant="secondary"
onClick={stakingTokenBalance.gt(0) ? onStake : onPresentTokenRequired}
disabled={isFinished}
>
<AddIcon color="primary" width="14px" />
</IconButton>
)}
</IconButtonWrapper>
{tooltipVisible && tooltip}
</ActionContent>
</ActionContainer>
)
}
return (
<ActionContainer>
<ActionTitles>
<Text fontSize="12px" bold color="secondary" as="span" textTransform="uppercase">
{t('Stake')}{' '}
</Text>
<Text fontSize="12px" bold color="textSubtle" as="span" textTransform="uppercase">
{stakingToken.symbol}
</Text>
</ActionTitles>
<ActionContent>
<Button
width="100%"
onClick={stakingTokenBalance.gt(0) ? onStake : onPresentTokenRequired}
variant="secondary"
disabled={isFinished}
>
{t('Stake')}
</Button>
</ActionContent>
</ActionContainer>
)
}
Example #23
Source File: AutoEarningsCell.tsx From vvs-ui with GNU General Public License v3.0 | 4 votes |
AutoEarningsCell: React.FC<AutoEarningsCellProps> = ({ pool, account, userDataLoaded }) => {
const { t } = useTranslation()
const { isMobile } = useMatchBreakpoints()
const { earningTokenPrice } = pool
const {
userData: { vvsAtLastUserAction, userShares, lastUserActionTime },
pricePerFullShare,
} = useVvsVault()
const { hasAutoEarnings, autoVvsToDisplay, autoUsdToDisplay } = getVvsVaultEarnings(
account,
vvsAtLastUserAction,
userShares,
pricePerFullShare,
earningTokenPrice,
)
const labelText = t('Recent VVS profit')
const earningTokenBalance = autoVvsToDisplay
const hasEarnings = hasAutoEarnings
const earningTokenDollarBalance = autoUsdToDisplay
const lastActionInMs = lastUserActionTime && parseInt(lastUserActionTime) * 1000
const dateTimeLastAction = new Date(lastActionInMs)
const dateStringToDisplay = dateTimeLastAction.toLocaleString()
const { targetRef, tooltip, tooltipVisible } = useTooltip(
<>
<Balance fontSize="16px" value={autoVvsToDisplay} decimals={3} bold unit=" VVS" />
{!isBlindMode() && <Balance fontSize="16px" value={autoUsdToDisplay} decimals={2} bold prefix="~$" />}
{t('Earned since your last action')}
<Text>{dateStringToDisplay}</Text>
</>,
{ placement: 'bottom' },
)
return (
<StyledCell role="cell">
<CellContent>
<Text fontSize="12px" color="textSubtle" textAlign="left">
{labelText}
</Text>
{!userDataLoaded && account || isBlindMode() ? (
<Skeleton width="80px" height="16px" />
) : (
<>
{tooltipVisible && tooltip}
<Flex>
<Box mr="8px" height="32px">
<Balance
mt="4px"
bold={!isMobile}
fontSize={isMobile ? '14px' : '16px'}
color={hasEarnings ? 'primary' : 'textDisabled'}
decimals={hasEarnings ? 5 : 1}
value={hasEarnings ? earningTokenBalance : 0}
/>
{hasEarnings ? (
<>
{earningTokenPrice > 0 && (
<Balance
display="inline"
fontSize="12px"
color="textSubtle"
decimals={2}
prefix="~"
value={earningTokenDollarBalance}
unit=" USD"
/>
)}
</>
) : (
<Text mt="4px" fontSize="12px" color="textDisabled">
0 USD
</Text>
)}
</Box>
{hasEarnings && !isMobile && (
<HelpIconWrapper ref={targetRef}>
<HelpIcon color="textSubtle" />
</HelpIconWrapper>
)}
</Flex>
</>
)}
</CellContent>
</StyledCell>
)
}
Example #24
Source File: BountyRow.tsx From vvs-ui with GNU General Public License v3.0 | 4 votes |
BountyRow = () => {
const { t } = useTranslation()
const {
estimatedVvsBountyReward,
fees: { callFee },
} = useVvsVault()
const vvsPriceUsdc = usePriceVvsUsdc()
const estimatedDollarBountyReward = useMemo(() => {
return new BigNumber(estimatedVvsBountyReward).multipliedBy(vvsPriceUsdc)
}, [vvsPriceUsdc, estimatedVvsBountyReward])
const hasFetchedDollarBounty = estimatedDollarBountyReward.gte(0)
const hasFetchedVvsBounty = estimatedVvsBountyReward ? estimatedVvsBountyReward.gte(0) : false
const dollarBountyToDisplay = hasFetchedDollarBounty ? getBalanceNumber(estimatedDollarBountyReward, 18) : 0
const vvsBountyToDisplay = hasFetchedVvsBounty ? getBalanceNumber(estimatedVvsBountyReward, 18) : 0
const TooltipComponent = ({ fee }: { fee: number }) => (
<>
<Text mb="16px">{t('Optional Feature: Auto-compound Bounty Reward')}</Text>
<Text mb="16px">
{t(
'Whenever you successfully claim the bounty, you’re also helping to trigger auto-compounding for all auto VVS users. The displayed amount does not belong to you until claimed.',
)}
</Text>
<Text style={{ fontWeight: 'bold' }}>
{t('Bounty Amount: %fee%% of all Auto VVS pool pending rewards', { fee: fee / 100 })}
</Text>
</>
)
const [onPresentBountyModal] = useModal(<BountyModal TooltipComponent={TooltipComponent} />)
const { targetRef, tooltip, tooltipVisible } = useTooltip(<TooltipComponent fee={callFee} />, {
placement: 'bottom-end',
tooltipOffset: [20, 10],
})
return (
<>
{tooltipVisible && tooltip}
<Flex alignItems="center" mb="12px">
<Text small textTransform="uppercase" mr="8px">
{t('Bounty')}
</Text>
<Box ref={targetRef}>
<HelpIcon color="primary" />
</Box>
</Flex>
<Flex alignItems="center" justifyContent="space-between">
<Flex flexDirection="column" mr="12px">
<Heading>
{hasFetchedVvsBounty ? (
<Balance color="textSubtle" fontSize="20px" bold value={vvsBountyToDisplay} decimals={3} />
) : (
<Skeleton height={20} width={96} mb="2px" />
)}
</Heading>
{hasFetchedDollarBounty && !isBlindMode() ? (
<Balance
fontSize="14px"
color="textSubtle"
value={dollarBountyToDisplay}
decimals={2}
unit=" USD"
prefix="~"
/>
) : (
<Skeleton height={16} width={62} />
)}
</Flex>
<Button
disabled={!dollarBountyToDisplay || !vvsBountyToDisplay || !callFee}
onClick={onPresentBountyModal}
id="clickClaimVaultBounty"
>
{t('Claim')}
</Button>
</Flex>
</>
)
}
Example #25
Source File: App.tsx From vvs-ui with GNU General Public License v3.0 | 4 votes |
App: React.FC = () => {
usePollBlockNumber()
useEagerConnect()
// useFetchProfile()
// usePollCoreFarmData()
return (
<Router history={history}>
<ScrollToTop>
<ResetCSS />
<GlobalStyle />
{/* <GlobalCheckClaimStatus excludeLocations={['/collectibles']} /> */}
<Menu>
<SuspenseWithChunkError fallback={<PageLoader />}>
<Switch>
<Route path="/" exact>
<Home />
</Route>
{/* <Route exact path="/farms/auction">
<FarmAuction />
</Route> */}
<Route path="/farms">
<Farms />
</Route>
<Route path="/mines">
<Pools />
</Route>
<Route path="/dashboard">
<Dashboard />
</Route>
{/* <Route path="/lottery">
<Lottery />
</Route>
<Route path="/ifo">
<Ifos />
</Route>
<Route path="/collectibles">
<Collectibles />
</Route>
<Route exact path="/teams">
<Teams />
</Route>
<Route path="/teams/:id">
<Team />
</Route>
<Route path="/profile">
<Profile />
</Route>
<Route path="/competition">
<TradingCompetition />
</Route>
<Route exact path="/prediction">
<Predictions />
</Route>
<Route path="/prediction/leaderboard">
<PredictionsLeaderboard />
</Route>
<Route exact path="/voting">
<Voting />
</Route>
<Route exact path="/voting/proposal/create">
<CreateProposal />
</Route>
<Route path="/voting/proposal/:id">
<Proposal />
</Route> */}
{/* Info pages */}
{!isBlindMode() && <Route path="/info">
<Info />
</Route>}
{/* Using this format because these components use routes injected props. We need to rework them with hooks */}
<Route exact strict path="/swap" component={Swap} />
<Route exact strict path="/swap/:outputCurrency" component={RedirectToSwap} />
<Route exact strict path="/send" component={RedirectPathToSwapOnly} />
<Route exact strict path="/find" component={PoolFinder} />
<Route exact strict path="/liquidity" component={Liquidity} />
<Route exact strict path="/create" component={RedirectToAddLiquidity} />
<Route exact path="/add" component={AddLiquidity} />
<Route exact path="/add/:currencyIdA" component={RedirectOldAddLiquidityPathStructure} />
<Route exact path="/add/:currencyIdA/:currencyIdB" component={RedirectDuplicateTokenIds} />
<Route exact path="/create" component={AddLiquidity} />
<Route exact path="/create/:currencyIdA" component={RedirectOldAddLiquidityPathStructure} />
<Route exact path="/create/:currencyIdA/:currencyIdB" component={RedirectDuplicateTokenIds} />
<Route exact strict path="/remove/:tokens" component={RedirectOldRemoveLiquidityPathStructure} />
<Route exact strict path="/remove/:currencyIdA/:currencyIdB" component={RemoveLiquidity} />
{/* Redirect */}
<Route path="/pool">
<Redirect to="/liquidity" />
</Route>
<Route path="/staking">
<Redirect to="/mines" />
</Route>
<Route path="/syrup">
<Redirect to="/mines" />
</Route>
{/* <Route path="/nft">
<Redirect to="/collectibles" />
</Route> */}
{/* 404 */}
<Route component={NotFound} />
</Switch>
</SuspenseWithChunkError>
</Menu>
<EasterEgg iterations={2} />
<ToastListener />
<DatePickerPortal />
</ScrollToTop>
</Router>
)
}
Example #26
Source File: CollectModal.tsx From vvs-ui with GNU General Public License v3.0 | 4 votes |
CollectModal: React.FC<CollectModalProps> = ({
formattedBalance,
fullBalance,
earningToken,
earningsDollarValue,
sousId,
isBnbPool,
isCompoundPool = false,
onDismiss,
}) => {
const { t } = useTranslation()
const { theme } = useTheme()
const { toastSuccess, toastError } = useToast()
const { onReward } = useHarvestPool(sousId, isBnbPool)
const { onStake } = useStakePool(sousId, isBnbPool)
const [pendingTx, setPendingTx] = useState(false)
const [shouldCompound, setShouldCompound] = useState(isCompoundPool)
const { targetRef, tooltip, tooltipVisible } = useTooltip(
<>
<Text mb="12px">{t('Compound: collect and restake VVS into pool.')}</Text>
<Text>{t('Harvest: collect VVS and send to wallet')}</Text>
</>,
{ placement: 'bottom-end', tooltipOffset: [20, 10] },
)
const handleHarvestConfirm = async () => {
setPendingTx(true)
// compounding
if (shouldCompound) {
try {
await onStake(fullBalance, earningToken.decimals)
toastSuccess(
`${t('Compounded')}!`,
t('Your %symbol% earnings have been re-invested into the pool!', { symbol: earningToken.symbol }),
)
setPendingTx(false)
onDismiss()
} catch (e) {
toastError(t('Error'), t('Please try again. Confirm the transaction and make sure you are paying enough gas!'))
console.error(e)
setPendingTx(false)
}
} else {
// harvesting
try {
await onReward()
toastSuccess(
`${t('Harvested')}!`,
t('Your %symbol% earnings have been sent to your wallet!', { symbol: earningToken.symbol }),
)
setPendingTx(false)
onDismiss()
} catch (e) {
toastError(t('Error'), t('Please try again. Confirm the transaction and make sure you are paying enough gas!'))
console.error(e)
setPendingTx(false)
}
}
}
return (
<Modal
title={`${earningToken.symbol} ${isCompoundPool ? t('Collect') : t('Harvest')}`}
onDismiss={onDismiss}
headerBackground={theme.colors.gradients.cardHeader}
>
{isCompoundPool && (
<Flex justifyContent="center" alignItems="center" mb="24px">
<ButtonMenu
activeIndex={shouldCompound ? 0 : 1}
scale="sm"
variant="subtle"
onItemClick={(index) => setShouldCompound(!index)}
>
<ButtonMenuItem as="button">{t('Compound')}</ButtonMenuItem>
<ButtonMenuItem as="button">{t('Harvest')}</ButtonMenuItem>
</ButtonMenu>
<Flex ml="10px" ref={targetRef}>
<HelpIcon color="textSubtle" />
</Flex>
{tooltipVisible && tooltip}
</Flex>
)}
<Flex justifyContent="space-between" alignItems="center" mb="24px">
<Text>{shouldCompound ? t('Compounding') : t('Harvesting')}:</Text>
<Flex flexDirection="column">
<Heading>
{formattedBalance} {earningToken.symbol}
</Heading>
{isBlindMode() ? <Skeleton mt={1} width={60} /> : (earningsDollarValue > 0 && (
<Text fontSize="12px" color="textSubtle">{`~${formatNumber(earningsDollarValue)} USD`}</Text>
))}
</Flex>
</Flex>
<Button
mt="8px"
onClick={handleHarvestConfirm}
isLoading={pendingTx}
endIcon={pendingTx ? <AutoRenewIcon spin color="currentColor" /> : null}
>
{pendingTx ? t('Confirming') : t('Confirm')}
</Button>
<Button variant="text" onClick={onDismiss} pb="0px">
{t('Close Window')}
</Button>
</Modal>
)
}
Example #27
Source File: ExpandedFooter.tsx From vvs-ui with GNU General Public License v3.0 | 4 votes |
ExpandedFooter: React.FC<ExpandedFooterProps> = ({ pool, account }) => {
const { t } = useTranslation()
const { chainId } = useActiveWeb3React()
const { currentBlock } = useBlock()
const {
totalVvsInVault,
fees: { performanceFee },
} = useVvsVault()
const {
stakingToken,
earningToken,
totalStaked,
startBlock,
endBlock,
stakingLimit,
contractAddress,
sousId,
isAutoVault,
} = pool
const tokenAddress = earningToken.address || ''
const poolContractAddress = getAddress(contractAddress)
const vvsVaultContractAddress = getVvsVaultAddress()
const isMetaMaskInScope = !!window.ethereum?.isMetaMask
const isManualVvsPool = sousId === 0
const { shouldShowBlockCountdown, blocksUntilStart, blocksRemaining, hasPoolStarted, blocksToDisplay } =
getPoolBlockInfo(pool, currentBlock)
const { targetRef, tooltip, tooltipVisible } = useTooltip(
t('Subtracted automatically from each yield harvest and burned.'),
{ placement: 'bottom-start' },
)
const getTotalStakedBalance = () => {
if (isAutoVault) {
return getBalanceNumber(totalVvsInVault, stakingToken.decimals)
}
if (isManualVvsPool) {
const manualVvsTotalMinusAutoVault = new BigNumber(totalStaked).minus(totalVvsInVault)
return getBalanceNumber(manualVvsTotalMinusAutoVault, stakingToken.decimals)
}
return getBalanceNumber(totalStaked, stakingToken.decimals)
}
const {
targetRef: totalStakedTargetRef,
tooltip: totalStakedTooltip,
tooltipVisible: totalStakedTooltipVisible,
} = useTooltip(t('Total amount of %symbol% staked in this pool', { symbol: stakingToken.symbol }), {
placement: 'bottom',
})
return (
<ExpandedWrapper flexDirection="column">
<Flex mb="2px" justifyContent="space-between" alignItems="center">
<Text small>{t('Total staked')}:</Text>
<Flex alignItems="flex-start">
{totalStaked && totalStaked.gte(0) ? (
<>
<Balance small value={getTotalStakedBalance()} decimals={0} unit={` ${stakingToken.symbol}`} />
<span ref={totalStakedTargetRef}>
<HelpIcon color="textSubtle" width="20px" ml="6px" mt="4px" />
</span>
</>
) : (
<Skeleton width="90px" height="21px" />
)}
{totalStakedTooltipVisible && totalStakedTooltip}
</Flex>
</Flex>
{stakingLimit && stakingLimit.gt(0) && (
<Flex mb="2px" justifyContent="space-between">
<Text small>{t('Max. stake per user')}:</Text>
<Text small>{`${getFullDisplayBalance(stakingLimit, stakingToken.decimals, 0)} ${stakingToken.symbol}`}</Text>
</Flex>
)}
{shouldShowBlockCountdown && (
<Flex mb="2px" justifyContent="space-between" alignItems="center">
<Text small>{hasPoolStarted ? t('Ends in') : t('Starts in')}:</Text>
{blocksRemaining || blocksUntilStart ? (
<Flex alignItems="center">
<Link external href={getExplorerLink(hasPoolStarted ? endBlock : startBlock, 'countdown')}>
<Balance small value={blocksToDisplay} decimals={0} color="primary" />
<Text small ml="4px" color="primary" textTransform="lowercase">
{t('Blocks')}
</Text>
<TimerIcon ml="4px" color="primary" />
</Link>
</Flex>
) : (
<Skeleton width="54px" height="21px" />
)}
</Flex>
)}
{isAutoVault && (
<Flex mb="2px" justifyContent="space-between" alignItems="center">
{tooltipVisible && tooltip}
<TooltipText ref={targetRef} small>
{t('Performance Fee')}
</TooltipText>
<Flex alignItems="center">
{performanceFee ? (
<Text ml="4px" small>
{performanceFee / 100}%
</Text>
) : (
<Skeleton width="90px" height="21px" />
)}
</Flex>
</Flex>
)}
{!isBlindMode() && <Flex mb="2px" justifyContent="flex-end">
<LinkExternal href={`/info/token/${earningToken.address}`} bold={false} small>
{t('See Token Info')}
</LinkExternal>
</Flex>}
<Flex mb="2px" justifyContent="flex-end">
<LinkExternal href={earningToken.projectLink} bold={false} small>
{t('View Project Site')}
</LinkExternal>
</Flex>
{poolContractAddress && (
<Flex mb="2px" justifyContent="flex-end">
<LinkExternal
href={`${BASE_EXPLORER_URLS[chainId]}/address/${isAutoVault ? vvsVaultContractAddress : poolContractAddress}`}
bold={false}
small
>
{t('View Contract')}
</LinkExternal>
</Flex>
)}
{account && isMetaMaskInScope && tokenAddress && (
<Flex justifyContent="flex-end">
<Button
variant="text"
p="0"
height="auto"
onClick={() => registerToken(tokenAddress, earningToken.symbol, earningToken.decimals)}
>
<Text color="primary" fontSize="14px">
{t('Add to Metamask')}
</Text>
<MetamaskIcon ml="4px" />
</Button>
</Flex>
)}
</ExpandedWrapper>
)
}
Example #28
Source File: StakeActions.tsx From vvs-ui with GNU General Public License v3.0 | 4 votes |
StakeAction: React.FC<StakeActionsProps> = ({
pool,
stakingTokenBalance,
stakedBalance,
isBnbPool,
isStaked,
isLoading = false,
}) => {
const { stakingToken, stakingTokenPrice, stakingLimit, isFinished, userData } = pool
const { t } = useTranslation()
const stakedTokenBalance = getBalanceNumber(stakedBalance, stakingToken.decimals)
const stakedTokenDollarBalance = getBalanceNumber(
stakedBalance.multipliedBy(stakingTokenPrice),
stakingToken.decimals,
)
const [onPresentTokenRequired] = useModal(<NotEnoughTokensModal tokenSymbol={stakingToken.symbol} />)
const [onPresentStake] = useModal(
<StakeModal
isBnbPool={isBnbPool}
pool={pool}
stakingTokenBalance={stakingTokenBalance}
stakingTokenPrice={stakingTokenPrice}
/>,
)
const [onPresentUnstake] = useModal(
<StakeModal
stakingTokenBalance={stakingTokenBalance}
isBnbPool={isBnbPool}
pool={pool}
stakingTokenPrice={stakingTokenPrice}
isRemovingStake
/>,
)
const { targetRef, tooltip, tooltipVisible } = useTooltip(
t('You’ve already staked the maximum amount you can stake in this pool!'),
{ placement: 'bottom' },
)
const reachStakingLimit = stakingLimit.gt(0) && userData.stakedBalance.gte(stakingLimit)
const renderStakeAction = () => {
return isStaked ? (
<Flex justifyContent="space-between" alignItems="center">
<Flex flexDirection="column">
<>
<Balance bold fontSize="20px" decimals={3} value={stakedTokenBalance} />
{stakingTokenPrice !== 0 && !isBlindMode() && (
<Text fontSize="12px" color="textSubtle">
<Balance
fontSize="12px"
color="textSubtle"
decimals={2}
value={stakedTokenDollarBalance}
prefix="~"
unit=" USD"
/>
</Text>
)}
</>
</Flex>
<Flex>
<IconButton variant="secondary" onClick={onPresentUnstake} mr="6px">
<MinusIcon color="primary" width="24px" />
</IconButton>
{reachStakingLimit ? (
<span ref={targetRef}>
<IconButton variant="secondary" disabled>
<AddIcon color="textDisabled" width="24px" height="24px" />
</IconButton>
</span>
) : (
<IconButton
variant="secondary"
onClick={stakingTokenBalance.gt(0) ? onPresentStake : onPresentTokenRequired}
disabled={isFinished}
>
<AddIcon color="primary" width="24px" height="24px" />
</IconButton>
)}
</Flex>
{tooltipVisible && tooltip}
</Flex>
) : (
<Button disabled={isFinished} onClick={stakingTokenBalance.gt(0) ? onPresentStake : onPresentTokenRequired}>
{t('Stake')}
</Button>
)
}
return <Flex flexDirection="column">{isLoading ? <Skeleton width="100%" height="52px" /> : renderStakeAction()}</Flex>
}
Example #29
Source File: BountyModal.tsx From vvs-ui with GNU General Public License v3.0 | 4 votes |
BountyModal: React.FC<BountyModalProps> = ({ onDismiss, TooltipComponent }) => {
const { t } = useTranslation()
const { account } = useWeb3React()
const { theme } = useTheme()
const { toastError, toastSuccess } = useToast()
const vvsVaultContract = useVvsVaultContract()
const [pendingTx, setPendingTx] = useState(false)
const {
estimatedVvsBountyReward,
totalPendingVvsHarvest,
fees: { callFee },
} = useVvsVault()
const { callWithGasPrice } = useCallWithGasPrice()
const vvsPriceUsdc = usePriceVvsUsdc()
const callFeeAsDecimal = callFee / 100
const totalYieldToDisplay = getBalanceNumber(totalPendingVvsHarvest, 18)
const estimatedDollarBountyReward = useMemo(() => {
return new BigNumber(estimatedVvsBountyReward).multipliedBy(vvsPriceUsdc)
}, [vvsPriceUsdc, estimatedVvsBountyReward])
const hasFetchedDollarBounty = estimatedDollarBountyReward.gte(0)
const hasFetchedVvsBounty = estimatedVvsBountyReward ? estimatedVvsBountyReward.gte(0) : false
const dollarBountyToDisplay = hasFetchedDollarBounty ? getBalanceNumber(estimatedDollarBountyReward, 18) : 0
const vvsBountyToDisplay = hasFetchedVvsBounty ? getBalanceNumber(estimatedVvsBountyReward, 18) : 0
const { targetRef, tooltip, tooltipVisible } = useTooltip(<TooltipComponent fee={callFee} />, {
placement: 'bottom',
tooltipPadding: { right: 15 },
})
const handleConfirmClick = async () => {
setPendingTx(true)
try {
const tx = await callWithGasPrice(vvsVaultContract, 'harvest', undefined, { gasLimit: 300000 })
const receipt = await tx.wait()
if (receipt.status) {
toastSuccess(
t('Bounty collected!'),
<ToastDescriptionWithTx txHash={receipt.transactionHash}>
{t('VVS bounty has been sent to your wallet.')}
</ToastDescriptionWithTx>,
)
setPendingTx(false)
onDismiss()
}
} catch (error) {
toastError(t('Error'), t('Please try again. Confirm the transaction and make sure you are paying enough gas!'))
setPendingTx(false)
}
}
return (
<Modal title={t('Claim Bounty')} onDismiss={onDismiss} headerBackground={theme.colors.gradients.cardHeader} width='380px'>
{tooltipVisible && tooltip}
<Flex alignItems="flex-start" justifyContent="space-between">
<Text>{t('You’ll claim')}</Text>
<Flex flexDirection="column">
<Balance bold value={vvsBountyToDisplay} decimals={7} unit=" VVS" />
<Text fontSize="12px" color="textSubtle">
{isBlindMode() ? <Skeleton mt={1} width={60} /> : <Balance
fontSize="12px"
color="textSubtle"
value={dollarBountyToDisplay}
decimals={2}
unit=" USD"
prefix="~"
/>}
</Text>
</Flex>
</Flex>
<Divider />
<Flex alignItems="center" justifyContent="space-between">
<Text fontSize="14px" color="textSubtle">
{t('Pool total pending yield')}
</Text>
<Balance color="textSubtle" value={totalYieldToDisplay} unit=" VVS" />
</Flex>
<Flex alignItems="center" justifyContent="space-between" mb="24px">
<Text fontSize="14px" color="textSubtle">
{t('Bounty')}
</Text>
<Text fontSize="14px" color="textSubtle">
{callFeeAsDecimal}%
</Text>
</Flex>
{account ? (
<Button
isLoading={pendingTx}
disabled={!dollarBountyToDisplay || !vvsBountyToDisplay || !callFee}
endIcon={pendingTx ? <AutoRenewIcon spin color="currentColor" /> : null}
onClick={handleConfirmClick}
mb="28px"
id="autoVvsConfirmBounty"
>
{pendingTx ? t('Confirming') : t('Confirm')}
</Button>
) : (
<ConnectWalletButton mb="28px" />
)}
<Flex justifyContent="center" alignItems="center">
<Text fontSize="16px" bold color="textSubtle" mr="4px">
{t('What’s this?')}
</Text>
<span ref={targetRef}>
<HelpIcon color="textSubtle" />
</span>
</Flex>
</Modal>
)
}