Skip to content

Commit

Permalink
🚸 staking: update text for exaVouchers rewards and staking progress
Browse files Browse the repository at this point in the history
  • Loading branch information
franm91 committed Sep 20, 2024
1 parent f7ce90f commit 1131e7b
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 27 deletions.
2 changes: 1 addition & 1 deletion components/charts/StakeChart/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ const StakeChart = () => {
xAxisId="date"
type="monotone"
dataKey="restValue"
name={isEnded ? t('Not available to claim') : t('Projected Remainder')}
name={isEnded ? t('Not available to claim') : t('Claimable on completion')}
stroke="none"
fill="url(#rest)"
fillOpacity={1}
Expand Down
87 changes: 72 additions & 15 deletions components/staking/StakingOperations/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,15 @@ import WAD from '@exactly/lib/esm/fixed-point-math/WAD';
import { formatEther, parseEther } from 'viem';
import { Transaction } from 'types/Transaction';
import { useStakeEXA } from 'contexts/StakeEXAContext';
import { toPercentage } from 'utils/utils';
import parseTimestamp from 'utils/parseTimestamp';
import { LoadingButton } from '@mui/lab';
import { useStakedEXA } from 'hooks/useStakedEXA';
import { gasLimit } from 'utils/gas';
import waitForTransaction from 'utils/waitForTransaction';
import LoadingTransaction from 'components/common/modal/Loading';
import { toPercentage } from 'utils/utils';
import Link from 'next/link';
import { useRouter } from 'next/router';

function PaperComponent(props: PaperProps | undefined) {
const ref = useRef<HTMLDivElement>(null);
Expand Down Expand Up @@ -132,7 +134,7 @@ function StakingProgress() {
const stakedEXA = useStakedEXA();
const { connect, isConnected, impersonateActive, opts } = useWeb3();

const { start: stakingStart, balance, totalClaimable, parameters, refetch } = useStakeEXA();
const { start: stakingStart, balance, totalClaimable, totalEarned, parameters, refetch } = useStakeEXA();
const [tx, setTx] = useState<Transaction>();
const [isLoading, setIsLoading] = useState(false);

Expand All @@ -158,18 +160,37 @@ function StakingProgress() {
}
};

const stakedProgress = useMemo(() => {
if (!stakingStart || !parameters) return 0;
const { daysLeft, hasStakingEnded } = useMemo(() => {
if (!stakingStart || !parameters) {
return { daysLeft: 0, hasStakingEnded: false };
}
const now = Math.floor(Date.now() / 1000);
const avgStart = stakingStart === 0n ? parseEther(now.toString()) : stakingStart;
const startTime = Number(avgStart / WAD);
const endTime = Number(avgStart / WAD + parameters.refTime);
const elapsedTime = now - startTime;
const percentage = elapsedTime / (endTime - startTime);
const secondsLeft = Number(parameters.refTime) - elapsedTime;
const remainingDays = Math.floor(secondsLeft / 86_400);

return Math.min(percentage, 100);
return {
daysLeft: remainingDays,
hasStakingEnded: secondsLeft <= 0,
elapsedTime,
};
}, [parameters, stakingStart]);

const currentAPR = useMemo(() => {
if (!EXAUsdValue || !stakingStart || !totalEarned) return undefined;
const now = Math.floor(Date.now() / 1000);
const principal = Number(EXAUsdValue);
const interestEarned = Number(formatEther(totalEarned));
const startTime = Number(stakingStart / WAD);
const secondsElapsed = now - startTime;
const SECONDS_IN_YEAR = 31_556_926;
if (principal <= 0 || secondsElapsed <= 0) return undefined;

return (interestEarned / Number(EXAUsdValue)) * (SECONDS_IN_YEAR / secondsElapsed);
}, [EXAUsdValue, stakingStart, totalEarned]);

const onClose = useCallback(() => {
setTx(undefined);
}, []);
Expand Down Expand Up @@ -258,18 +279,25 @@ function StakingProgress() {
${formatNumber(EXAUsdValue || '0', 'USD')}
</Typography>
</Box>
{stakedProgress > 0 && balance !== undefined && balance > 0n && (
{balance !== undefined && balance > 0n && (
<Box>
<Grid container>
<Grid item xs={6}>
<Typography fontSize={16}>{t('Progress')}</Typography>
</Grid>
<Grid item xs={6}>
<Typography align="right" fontSize={19} fontWeight={700} color={stakedProgress > 1 ? 'error' : ''}>
{toPercentage(stakedProgress)}
<Typography align="right" fontSize={18} fontWeight={700} color={hasStakingEnded ? 'error' : ''}>
{hasStakingEnded ? `${Math.abs(daysLeft)} ${t('days overdue')}` : `${daysLeft} ${t('days left')}`}
</Typography>
</Grid>
<Grid item xs={6}>
<Typography fontSize={16}>{t('Your current APR')}</Typography>
</Grid>
<Grid item xs={6}>
<Typography align="right" fontSize={18} fontWeight={700}>
{toPercentage(currentAPR)}
</Typography>
</Grid>

<Grid item xs={6}>
<Typography fontSize={16}>{t('Started')}</Typography>
</Grid>
Expand All @@ -279,7 +307,7 @@ function StakingProgress() {
<Skeleton width={90} height={20} />
</Box>
) : (
<Typography align="right" fontSize={19} fontWeight={700}>
<Typography align="right" fontSize={18} fontWeight={700}>
{parseTimestamp(formatEther(stakingStart))}
</Typography>
)}
Expand All @@ -294,7 +322,7 @@ function StakingProgress() {
<Skeleton width={90} height={20} />
</Box>
) : (
<Typography align="right" fontSize={19} fontWeight={700}>
<Typography align="right" fontSize={18} fontWeight={700}>
{parseTimestamp(stakingStart / WAD + parameters.refTime)}
</Typography>
)}
Expand Down Expand Up @@ -328,7 +356,7 @@ function StakingProgress() {
}}
style={{ flexGrow: 1 }}
>
{stakedProgress && stakedProgress < 1 ? t('Early Withdraw') : t('Withdraw')}
{hasStakingEnded ? t('Withdraw') : t('Early Withdraw')}
</Button>
<StakeEXAModal
operation={operation}
Expand All @@ -345,6 +373,35 @@ function StakingProgress() {
}
export default React.memo(StakingProgress);

function SuccesMessage() {
const { query } = useRouter();
const { t } = useTranslation();
const { claimableTokens } = useStakeEXA();

const ct = Object.keys(claimableTokens).filter((key) => {
return key.startsWith('exa') && key.length > 3;
});

return ct.length === 0 ? (
'success'
) : (
<Box display="flex" flexDirection="column" gap={1}>
<Typography color="figma.grey.500" fontWeight={500} fontSize={13} textAlign="center">
{t(
`{{exaVouchers}} holders have the capability of redeeming and receiving the underlying assets plus their interests at any time, subject to available liquidity in the Variable Rate Pool.`,
{
exaVouchers: ct.join(', '),
},
)}
</Typography>

<Link href={{ pathname: '/dashboard', query }} style={{ width: '100%', textAlign: 'center' }}>
<Button variant="contained">{t('Go to dashboard')}</Button>
</Link>
</Box>
);
}

function LoadingModal({ tx, onClose }: { tx: Transaction; onClose: () => void }) {
const { t } = useTranslation();
const { breakpoints, spacing, palette } = useTheme();
Expand Down Expand Up @@ -401,7 +458,7 @@ function LoadingModal({ tx, onClose }: { tx: Transaction; onClose: () => void })
tx={tx}
messages={{
pending: t('pending'),
success: t('success'),
success: <SuccesMessage />,
error: t('error'),
}}
/>
Expand Down
30 changes: 21 additions & 9 deletions components/staking/StakingProgress/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import { formatEther } from 'viem';
import { useStakeEXA } from 'contexts/StakeEXAContext';
import Image from 'next/image';
import { useTranslation } from 'react-i18next';
import parseTimestamp from 'utils/parseTimestamp';
import WAD from '@exactly/lib/esm/fixed-point-math/WAD';

const ProgressBar = styled('div')<{ ended: boolean }>(({ ended, theme }) => ({
display: 'flex',
Expand Down Expand Up @@ -116,7 +118,7 @@ const StakingProgressBar: FC<DualProgressBarProps> = ({
}) => {
const { palette } = useTheme();
const { t } = useTranslation();
const { rewardsTokens, claimableTokens, claimedTokens, earnedTokens } = useStakeEXA();
const { rewardsTokens, claimableTokens, claimedTokens, earnedTokens, start, parameters } = useStakeEXA();

const claimedPercentage = total > 0n ? Number((claimed * 100n) / total) : 0;
const claimablePercentage = total > 0n ? Number((claimable * 100n) / total) : 0;
Expand Down Expand Up @@ -180,7 +182,7 @@ const StakingProgressBar: FC<DualProgressBarProps> = ({
<Grid item>
<Typography fontSize={32}>${formatNumber(formatEther(claimed), 'USD')}</Typography>
</Grid>
<Grid item>
<Grid item alignContent="center">
<Tooltip title={<TooltipContent tokensData={claimedTokens} />} placement="top" arrow>
<AvatarGroup
max={6}
Expand All @@ -199,7 +201,7 @@ const StakingProgressBar: FC<DualProgressBarProps> = ({
</Grid>
</Grid>
<Grid item xs={12} sm={4} textAlign="center">
<Grid container justifyContent="center" alignItems="center" spacing={1}>
<Grid container justifyContent="center" alignItems="center" spacing={0.5}>
<Grid item>
<Box
minWidth={16}
Expand Down Expand Up @@ -229,7 +231,7 @@ const StakingProgressBar: FC<DualProgressBarProps> = ({
<Grid item>
<Typography fontSize={32}>${formatNumber(formatEther(claimable), 'USD')}</Typography>
</Grid>
<Grid item>
<Grid item alignContent="center">
<Tooltip title={<TooltipContent tokensData={claimableTokens} />} placement="top" arrow>
<AvatarGroup
max={6}
Expand All @@ -247,7 +249,7 @@ const StakingProgressBar: FC<DualProgressBarProps> = ({
</Grid>
</Grid>
</Grid>
<Grid item xs={12} sm={4} textAlign="center">
<Grid xs={12} sm={4} textAlign="center" sx={{ pt: 5 }}>
<Grid container justifyContent="center" alignItems="center" spacing={1}>
<Grid item>
<Box
Expand All @@ -266,16 +268,26 @@ const StakingProgressBar: FC<DualProgressBarProps> = ({
/>
</Grid>
<Grid item>
<Typography fontSize={16} fontWeight={700}>
{ended ? t('Not available to claim') : t('Projected Remainder')}
</Typography>
<Tooltip
title={
start && parameters
? `${t('completion on: ')} ${parseTimestamp(start / WAD + parameters.refTime)}`
: null
}
placement="top"
arrow
>
<Typography fontSize={16} fontWeight={700}>
{ended ? t('Not available to claim') : t('Claimable on completion')}
</Typography>
</Tooltip>
</Grid>
</Grid>
<Grid container justifyContent="center" spacing={1}>
<Grid item>
<Typography fontSize={32}>${formatNumber(formatEther(total - claimable - claimed), 'USD')}</Typography>
</Grid>
<Grid item>
<Grid item alignContent="center">
<Tooltip title={<TooltipContent tokensData={remainingTokens} />} placement="top" arrow>
<AvatarGroup
max={6}
Expand Down
11 changes: 9 additions & 2 deletions i18n/es/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -644,7 +644,6 @@
"EXA Staking": "Staking de EXA",
"Staking status": "Estado de Staking",
"Not available to claim": "No disponible para reclamar",
"Projected Remainder": "Remanente Proyectado",
"Growth Factor": "Factor de Crecimiento",
"Total EXA Staked": "Total de EXA Stakeado",
"EXA": "EXA",
Expand All @@ -670,5 +669,13 @@
"Start staking now": "Comienza a stakear ahora",
"Stake EXA and Claim rewards": "Stakea EXA y Reclama recompensas",
"The 'Estimated APR' is equal to 50% of last week's treasury fees from the USDC market (annualized) divided by the total EXA Staked (in $).": "La 'TNA Estimada' es igual al 50% de las tarifas del tesoro de la semana pasada del mercado USDC (anualizado) dividido por el total de EXA Stakeado (en $).",
"Available to claim": "Disponible para reclamar"
"Available to claim": "Disponible para reclamar",
"Claimable on completion": "Reclamable al completar",
"USD": "USD",
"days overdue": "días pasados",
"days left": "días restantes",
"Your current APR": "Tu TNA actual",
"{{exaVouchers}} holders have the capability of redeeming and receiving the underlying assets plus their interests at any time, subject to available liquidity in the Variable Rate Pool.": "los titulares de {{exaVouchers}} tienen la capacidad de canjear y recibir los activos subyacentes más sus intereses en cualquier momento, sujeto a la liquidez disponible en el Pool de Tasa Variable.",
"Go to dashboard": "Ir al panel de control",
"completion on: ": "completado el: "
}

0 comments on commit 1131e7b

Please sign in to comment.