Skip to content

Commit 9a9c573

Browse files
foodakaCopilot
andauthored
feat: estimated sgho rewards (#2636)
Co-authored-by: Copilot <[email protected]>
1 parent 9008abb commit 9a9c573

File tree

9 files changed

+142
-15
lines changed

9 files changed

+142
-15
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
"@mui/icons-material": "^5.10.14",
5050
"@mui/lab": "5.0.0-alpha.103",
5151
"@mui/material": "^5.10.9",
52+
"@number-flow/react": "^0.5.10",
5253
"@paraswap/sdk": "6.10.0",
5354
"@safe-global/safe-apps-provider": "^0.18.4",
5455
"@safe-global/safe-apps-sdk": "^9.1.0",

src/components/AddressBlockedModal.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ export const AddressBlockedModal = ({
4646
<br />
4747
<Typography variant="helperText" sx={{ mb: 1 }}>
4848
{' '}
49-
<Trans>error code: 1</Trans>{' '}
49+
<Trans>error code: 2455</Trans>{' '}
5050
</Typography>
5151
</>
5252
)}

src/locales/el/messages.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/locales/en/messages.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/locales/en/messages.po

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1026,6 +1026,10 @@ msgstr "Reactivate cooldown period to unstake {0} {stakedToken}"
10261026
msgid "Migrate to v3"
10271027
msgstr "Migrate to v3"
10281028

1029+
#: src/components/AddressBlockedModal.tsx
1030+
msgid "error code: 2455"
1031+
msgstr "error code: 2455"
1032+
10291033
#: src/components/transactions/Bridge/BridgeModalContent.tsx
10301034
msgid "The source chain time to finality is the main factor that determines the time to destination. <0>Learn more</0>"
10311035
msgstr "The source chain time to finality is the main factor that determines the time to destination. <0>Learn more</0>"
@@ -1450,10 +1454,6 @@ msgstr "Maximum amount received"
14501454
msgid "Activating Cooldown"
14511455
msgstr "Activating Cooldown"
14521456

1453-
#: src/components/AddressBlockedModal.tsx
1454-
msgid "error code: 1"
1455-
msgstr "error code: 1"
1456-
14571457
#: src/components/transactions/GovDelegation/GovDelegationModalContent.tsx
14581458
msgid "Recipient address"
14591459
msgstr "Recipient address"
@@ -1523,6 +1523,10 @@ msgstr "View all"
15231523
msgid "Swap to"
15241524
msgstr "Swap to"
15251525

1526+
#: src/modules/sGho/SGhoHeader.tsx
1527+
msgid "Weekly Rewards"
1528+
msgstr "Weekly Rewards"
1529+
15261530
#: src/components/transactions/CollateralChange/CollateralChangeActions.tsx
15271531
#: src/components/transactions/Faucet/FaucetActions.tsx
15281532
msgid "Pending..."
@@ -2754,6 +2758,10 @@ msgstr "Safety Module"
27542758
msgid "Deposit GHO into savings GHO (sGHO) and earn <0>{0}%</0> APY on your GHO holdings. There's no lockups, no rehypothecation, and you can withdraw anytime. Simply deposit GHO, receive sGHO tokens representing your balance, and watch your savings grow earning claimable rewards from merit."
27552759
msgstr "Deposit GHO into savings GHO (sGHO) and earn <0>{0}%</0> APY on your GHO holdings. There's no lockups, no rehypothecation, and you can withdraw anytime. Simply deposit GHO, receive sGHO tokens representing your balance, and watch your savings grow earning claimable rewards from merit."
27562760

2761+
#: src/modules/sGho/SGhoHeader.tsx
2762+
msgid "Estimated weekly rewards based on your current sGHO balance and APR. Actual rewards may vary depending on market conditions."
2763+
msgstr "Estimated weekly rewards based on your current sGHO balance and APR. Actual rewards may vary depending on market conditions."
2764+
27572765
#: src/modules/dashboard/lists/SlippageList.tsx
27582766
msgid "Select slippage tolerance"
27592767
msgstr "Select slippage tolerance"

src/locales/es/messages.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/locales/fr/messages.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/modules/sGho/SGhoHeader.tsx

Lines changed: 104 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
1+
import { Stake } from '@aave/contract-helpers';
2+
import { valueToBigNumber } from '@aave/math-utils';
13
import { AaveSafetyModule } from '@bgd-labs/aave-address-book';
24
import { Trans } from '@lingui/macro';
35
import { Box, Stack, Typography, useMediaQuery, useTheme } from '@mui/material';
4-
import { useEffect } from 'react';
6+
import NumberFlow from '@number-flow/react';
7+
import { BigNumber } from 'bignumber.js';
8+
import { formatEther } from 'ethers/lib/utils';
9+
import { useEffect, useState } from 'react';
510
import { FormattedNumber } from 'src/components/primitives/FormattedNumber';
611
import { TokenIcon } from 'src/components/primitives/TokenIcon';
12+
import { TextWithTooltip } from 'src/components/TextWithTooltip';
713
import { TopInfoPanel } from 'src/components/TopInfoPanel/TopInfoPanel';
814
import { useAppDataContext } from 'src/hooks/app-data-provider/useAppDataProvider';
915
import { StakeTokenFormatted, useGeneralStakeUiData } from 'src/hooks/stake/useGeneralStakeUiData';
16+
import { useUserStakeUiData } from 'src/hooks/stake/useUserStakeUiData';
1017
import { useStakeTokenAPR } from 'src/hooks/useStakeTokenAPR';
1118
import { useWeb3Context } from 'src/libs/hooks/useWeb3Context';
1219
import { useRootStore } from 'src/store/root';
@@ -68,7 +75,10 @@ export const SGHOHeader: React.FC = () => {
6875
<Trans>
6976
Deposit GHO into savings GHO (sGHO) and earn{' '}
7077
<Box component="span" sx={{ color: '#338E3C', fontWeight: 'bold' }}>
71-
{((stakeAPR?.apr ? convertAprToApy(parseFloat(stakeAPR.apr)) : 0) * 100).toFixed(2)}
78+
{(
79+
(stakeAPR?.apr ? convertAprToApy(new BigNumber(stakeAPR.apr).toNumber()) : 0) *
80+
100
81+
).toFixed(2)}
7282
%
7383
</Box>{' '}
7484
APY on your GHO holdings. There&apos;s no lockups, no rehypothecation, and you can
@@ -90,6 +100,7 @@ export const SGHOHeader: React.FC = () => {
90100
};
91101

92102
const SGhoHeaderUserDetails = ({
103+
currentMarketData,
93104
valueTypographyVariant,
94105
symbolsTypographyVariant,
95106
stkGho,
@@ -100,6 +111,7 @@ const SGhoHeaderUserDetails = ({
100111
stkGho: StakeTokenFormatted;
101112
}) => {
102113
const { data: stakeAPR, isLoading: isLoadingStakeAPR } = useStakeTokenAPR();
114+
const { data: stakeUserResult } = useUserStakeUiData(currentMarketData, Stake.gho);
103115
const { reserves } = useAppDataContext();
104116

105117
const {
@@ -114,13 +126,33 @@ const SGhoHeaderUserDetails = ({
114126

115127
const downToSM = useMediaQuery(theme.breakpoints.down('sm'));
116128

129+
const stakeUserData = stakeUserResult?.[0];
130+
const userSGhoBalance = stakeUserData?.stakeTokenRedeemableAmount || '0';
131+
const userSGhoBalanceFormatted = formatEther(userSGhoBalance);
132+
133+
// Calculate estimated weekly rewards with precision
134+
// Formula: (balance * APR) / 52 weeks
135+
const aprBN = stakeAPR?.apr ? new BigNumber(stakeAPR.apr) : new BigNumber(0);
136+
const balanceBN = new BigNumber(userSGhoBalanceFormatted || '0');
137+
const weeklyRewardsEstimateBN = balanceBN.multipliedBy(aprBN).dividedBy(52);
138+
const weeklyRewardsEstimate = weeklyRewardsEstimateBN.toNumber();
139+
140+
const [displayedWeeklyRewards, setDisplayedWeeklyRewards] = useState(0);
141+
142+
const symbolsColor = theme.palette.text.muted;
143+
const iconSize = valueTypographyVariant === 'main21' ? 20 : 16;
144+
145+
useEffect(() => {
146+
setDisplayedWeeklyRewards(Math.max(0, weeklyRewardsEstimate));
147+
}, [weeklyRewardsEstimate]);
148+
117149
return (
118150
<>
119151
<TopInfoPanelItem hideIcon title={<Trans>APY</Trans>} loading={isLoadingStakeAPR}>
120152
<FormattedNumber
121-
value={stakeAPR?.apr ? convertAprToApy(parseFloat(stakeAPR.apr)) : 0}
153+
value={stakeAPR?.apr ? convertAprToApy(valueToBigNumber(stakeAPR.apr).toNumber()) : 0}
122154
variant={valueTypographyVariant}
123-
symbolsColor="#A5A8B6"
155+
symbolsColor={symbolsColor}
124156
visibleDecimals={2}
125157
percent
126158
symbolsVariant={symbolsTypographyVariant}
@@ -140,7 +172,7 @@ const SGhoHeaderUserDetails = ({
140172
symbol="USD"
141173
variant={valueTypographyVariant}
142174
symbolsVariant={symbolsTypographyVariant}
143-
symbolsColor="#A5A8B6"
175+
symbolsColor={symbolsColor}
144176
visibleDecimals={2}
145177
/>
146178
</TopInfoPanelItem>
@@ -158,11 +190,77 @@ const SGhoHeaderUserDetails = ({
158190
symbol="USD"
159191
variant={valueTypographyVariant}
160192
symbolsVariant={symbolsTypographyVariant}
161-
symbolsColor="#A5A8B6"
193+
symbolsColor={symbolsColor}
162194
visibleDecimals={2}
163195
/>
164196
</TopInfoPanelItem>
165197

198+
<TopInfoPanelItem
199+
hideIcon
200+
title={
201+
<Stack direction="row" alignItems="center">
202+
<TextWithTooltip text={<Trans>Weekly Rewards</Trans>} variant="inherit">
203+
<Trans>
204+
Estimated weekly rewards based on your current sGHO balance and APR. Actual rewards
205+
may vary depending on market conditions.
206+
</Trans>
207+
</TextWithTooltip>
208+
</Stack>
209+
}
210+
loading={isLoadingStakeAPR}
211+
>
212+
{balanceBN.gt(0) ? (
213+
<Typography
214+
variant={valueTypographyVariant}
215+
sx={{
216+
display: 'inline-flex',
217+
flexDirection: 'row',
218+
alignItems: 'center',
219+
position: 'relative',
220+
'& number-flow-react.custom-number-flow': {
221+
'--number-flow-mask-height': '0',
222+
'--number-flow-char-height': '1em',
223+
fontVariantNumeric: 'tabular-nums',
224+
display: 'inline-block',
225+
verticalAlign: 'baseline',
226+
paddingLeft: '12px',
227+
paddingRight: '12px',
228+
paddingTop: '2px',
229+
},
230+
}}
231+
noWrap
232+
>
233+
<NumberFlow
234+
value={displayedWeeklyRewards}
235+
format={{
236+
minimumFractionDigits: 2,
237+
maximumFractionDigits: 2,
238+
}}
239+
style={{
240+
color: 'inherit',
241+
fontFamily: 'inherit',
242+
fontSize: 'inherit',
243+
fontWeight: 'inherit',
244+
lineHeight: 'inherit',
245+
}}
246+
className="custom-number-flow"
247+
/>
248+
<TokenIcon
249+
symbol="sgho"
250+
sx={{
251+
ml: 0.5,
252+
width: iconSize,
253+
height: iconSize,
254+
}}
255+
/>
256+
</Typography>
257+
) : (
258+
<Typography variant={valueTypographyVariant} color={symbolsColor}>
259+
260+
</Typography>
261+
)}
262+
</TopInfoPanelItem>
263+
166264
<Box sx={{ display: 'inline-flex', alignItems: 'center', height: '40px' }}>
167265
{poolReserve && (
168266
<>

yarn.lock

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3492,6 +3492,14 @@
34923492
resolved "https://registry.yarnpkg.com/@nolyfill/is-core-module/-/is-core-module-1.0.39.tgz#3dc35ba0f1e66b403c00b39344f870298ebb1c8e"
34933493
integrity sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==
34943494

3495+
"@number-flow/react@^0.5.10":
3496+
version "0.5.10"
3497+
resolved "https://registry.yarnpkg.com/@number-flow/react/-/react-0.5.10.tgz#7468384c0aaf03148986e4948d534ac832fe42e9"
3498+
integrity sha512-a8Wh5eNITn7Km4xbddAH7QH8eNmnduR6k34ER1hkHSGO4H2yU1DDnuAWLQM99vciGInFODemSc0tdxrXkJEpbA==
3499+
dependencies:
3500+
esm-env "^1.1.4"
3501+
number-flow "0.5.8"
3502+
34953503
"@openzeppelin/merkle-tree@^1.0.8":
34963504
version "1.0.8"
34973505
resolved "https://registry.yarnpkg.com/@openzeppelin/merkle-tree/-/merkle-tree-1.0.8.tgz#31ea9cdc09de37315c32650a9772db1352dcdcd8"
@@ -7516,6 +7524,11 @@ eslint@^8.29.0:
75167524
strip-ansi "^6.0.1"
75177525
text-table "^0.2.0"
75187526

7527+
esm-env@^1.1.4:
7528+
version "1.2.2"
7529+
resolved "https://registry.yarnpkg.com/esm-env/-/esm-env-1.2.2.tgz#263c9455c55861f41618df31b20cb571fc20b75e"
7530+
integrity sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==
7531+
75197532
espree@^9.6.0, espree@^9.6.1:
75207533
version "9.6.1"
75217534
resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f"
@@ -10995,6 +11008,13 @@ nth-check@^2.0.1:
1099511008
dependencies:
1099611009
boolbase "^1.0.0"
1099711010

11011+
11012+
version "0.5.8"
11013+
resolved "https://registry.yarnpkg.com/number-flow/-/number-flow-0.5.8.tgz#39bbf5fbce414513f1add06d717c27a299f1e433"
11014+
integrity sha512-FPr1DumWyGi5Nucoug14bC6xEz70A1TnhgSHhKyfqjgji2SOTz+iLJxKtv37N5JyJbteGYCm6NQ9p1O4KZ7iiA==
11015+
dependencies:
11016+
esm-env "^1.1.4"
11017+
1099811018
nwsapi@^2.2.2:
1099911019
version "2.2.16"
1100011020
resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.16.tgz#177760bba02c351df1d2644e220c31dfec8cdb43"

0 commit comments

Comments
 (0)