Skip to content

Commit 930dc79

Browse files
authored
feat: juice apys (#2550)
1 parent 771a5e0 commit 930dc79

File tree

16 files changed

+878
-157
lines changed

16 files changed

+878
-157
lines changed

src/components/incentives/IncentivesButton.tsx

Lines changed: 169 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import { ProtocolAction } from '@aave/contract-helpers';
22
import { valueToBigNumber } from '@aave/math-utils';
33
import { ReserveIncentiveResponse } from '@aave/math-utils/dist/esm/formatters/incentive/calculate-reserve-incentives';
4-
import { DotsHorizontalIcon } from '@heroicons/react/solid';
5-
import { Box, SvgIcon, Typography } from '@mui/material';
4+
import { Box, Typography } from '@mui/material';
65
import { useState } from 'react';
76
import { useEthenaIncentives } from 'src/hooks/useEthenaIncentives';
87
import { useEtherfiIncentives } from 'src/hooks/useEtherfiIncentives';
@@ -14,18 +13,100 @@ import { DASHBOARD } from 'src/utils/events';
1413

1514
import { ContentWithTooltip } from '../ContentWithTooltip';
1615
import { FormattedNumber } from '../primitives/FormattedNumber';
17-
import { TokenIcon } from '../primitives/TokenIcon';
1816
import { EthenaAirdropTooltipContent } from './EthenaIncentivesTooltipContent';
1917
import { EtherFiAirdropTooltipContent } from './EtherfiIncentivesTooltipContent';
20-
import { getSymbolMap, IncentivesTooltipContent } from './IncentivesTooltipContent';
18+
import { IncentivesTooltipContent } from './IncentivesTooltipContent';
2119
import { MeritIncentivesTooltipContent } from './MeritIncentivesTooltipContent';
2220
import { MerklIncentivesTooltipContent } from './MerklIncentivesTooltipContent';
2321
import { SonicAirdropTooltipContent } from './SonicIncentivesTooltipContent';
2422

23+
const INFINITY = 'Infinity';
24+
25+
export type IconProps = {
26+
className?: string;
27+
width?: string | number;
28+
height?: string | number;
29+
viewBox?: string;
30+
style?: React.CSSProperties;
31+
color?: string;
32+
};
33+
34+
export type IconWrapperProps = {
35+
children?: React.ReactNode;
36+
} & IconProps;
37+
38+
export const Icon = ({
39+
className = '',
40+
width = '24px',
41+
height = '24px',
42+
viewBox = '0 0 20 20',
43+
children,
44+
color,
45+
...props
46+
}: IconWrapperProps) => {
47+
return (
48+
<svg
49+
width={width}
50+
height={height}
51+
viewBox={viewBox}
52+
data-color={color}
53+
fill="none"
54+
xmlns="http://www.w3.org/2000/svg"
55+
xmlnsXlink="http://www.w3.org/1999/xlink"
56+
className={className}
57+
style={{
58+
display: 'flex',
59+
flexShrink: 0,
60+
...props.style,
61+
}}
62+
{...props}
63+
>
64+
{children}
65+
</svg>
66+
);
67+
};
68+
2569
interface IncentivesButtonProps {
2670
symbol: string;
2771
incentives?: ReserveIncentiveResponse[];
2872
displayBlank?: boolean;
73+
market?: string;
74+
protocolAction?: ProtocolAction;
75+
protocolAPY?: number;
76+
address?: string;
77+
}
78+
79+
export function IncentivesIcon(props: IconProps) {
80+
return (
81+
<svg
82+
xmlns="http://www.w3.org/2000/svg"
83+
fill="none"
84+
{...props}
85+
viewBox="0 0 16 16"
86+
className={props.className}
87+
style={{
88+
display: 'flex',
89+
flexShrink: 0,
90+
...props.style,
91+
}}
92+
>
93+
<circle
94+
cx="7.2"
95+
cy="7.2"
96+
r="7.2"
97+
stroke="#9391F7"
98+
strokeWidth="1.5"
99+
transform="matrix(1 0 0 -1 .8 15.2)"
100+
/>
101+
<path
102+
stroke="#BCBBFF"
103+
strokeLinecap="round"
104+
strokeLinejoin="round"
105+
strokeWidth="1.5"
106+
d="m4.557 8.082.891 1.132a1 1 0 0 0 1.591-.026l1.75-2.376a1 1 0 0 1 1.591-.026l1.064 1.35"
107+
/>
108+
</svg>
109+
);
29110
}
30111

31112
const BlankIncentives = () => {
@@ -49,6 +130,8 @@ export const MeritIncentivesButton = (params: {
49130
symbol: string;
50131
market: string;
51132
protocolAction?: ProtocolAction;
133+
protocolAPY?: number;
134+
protocolIncentives?: ReserveIncentiveResponse[];
52135
}) => {
53136
const [open, setOpen] = useState(false);
54137
const { data: meritIncentives } = useMeritIncentives(params);
@@ -57,14 +140,17 @@ export const MeritIncentivesButton = (params: {
57140
return null;
58141
}
59142

143+
// Show only merit incentives APR
144+
const displayValue = +meritIncentives.incentiveAPR;
145+
60146
return (
61147
<ContentWithTooltip
62148
tooltipContent={<MeritIncentivesTooltipContent meritIncentives={meritIncentives} />}
63149
withoutHover
64150
setOpen={setOpen}
65151
open={open}
66152
>
67-
<Content incentives={[meritIncentives]} incentivesNetAPR={+meritIncentives.incentiveAPR} />
153+
<Content incentives={[meritIncentives]} incentivesNetAPR={displayValue} />
68154
</ContentWithTooltip>
69155
);
70156
};
@@ -73,6 +159,8 @@ export const MerklIncentivesButton = (params: {
73159
market: string;
74160
rewardedAsset?: string;
75161
protocolAction?: ProtocolAction;
162+
protocolAPY?: number;
163+
protocolIncentives?: ReserveIncentiveResponse[];
76164
}) => {
77165
const [open, setOpen] = useState(false);
78166
const { data: merklIncentives } = useMerklIncentives(params);
@@ -158,7 +246,15 @@ export const SonicIncentivesButton = ({ rewardedAsset }: { rewardedAsset?: strin
158246
);
159247
};
160248

161-
export const IncentivesButton = ({ incentives, symbol, displayBlank }: IncentivesButtonProps) => {
249+
export const IncentivesButton = ({
250+
incentives,
251+
symbol,
252+
displayBlank,
253+
market,
254+
protocolAction,
255+
protocolAPY,
256+
address,
257+
}: IncentivesButtonProps) => {
162258
const [open, setOpen] = useState(false);
163259

164260
if (!(incentives && incentives.length > 0)) {
@@ -169,18 +265,16 @@ export const IncentivesButton = ({ incentives, symbol, displayBlank }: Incentive
169265
}
170266
}
171267

172-
const isIncentivesInfinity = incentives.some(
173-
(incentive) => incentive.incentiveAPR === 'Infinity'
174-
);
268+
const isIncentivesInfinity = incentives.some((incentive) => incentive.incentiveAPR === INFINITY);
175269
const incentivesAPRSum = isIncentivesInfinity
176-
? 'Infinity'
270+
? INFINITY
177271
: incentives.reduce((aIncentive, bIncentive) => aIncentive + +bIncentive.incentiveAPR, 0);
178272

179273
const incentivesNetAPR = isIncentivesInfinity
180-
? 'Infinity'
181-
: incentivesAPRSum !== 'Infinity'
274+
? INFINITY
275+
: incentivesAPRSum !== INFINITY
182276
? valueToBigNumber(incentivesAPRSum || 0).toNumber()
183-
: 'Infinity';
277+
: INFINITY;
184278

185279
return (
186280
<ContentWithTooltip
@@ -189,6 +283,10 @@ export const IncentivesButton = ({ incentives, symbol, displayBlank }: Incentive
189283
incentives={incentives}
190284
incentivesNetAPR={incentivesNetAPR}
191285
symbol={symbol}
286+
market={market}
287+
protocolAction={protocolAction}
288+
protocolAPY={protocolAPY}
289+
address={address}
192290
/>
193291
}
194292
withoutHover
@@ -211,7 +309,7 @@ const Content = ({
211309
plus,
212310
}: {
213311
incentives: ReserveIncentiveResponse[];
214-
incentivesNetAPR: number | 'Infinity';
312+
incentivesNetAPR: number | typeof INFINITY;
215313
displayBlank?: boolean;
216314
plus?: boolean;
217315
}) => {
@@ -235,48 +333,72 @@ const Content = ({
235333
}
236334

237335
const incentivesButtonValue = () => {
238-
if (incentivesNetAPR !== 'Infinity' && incentivesNetAPR < 10000) {
239-
return (
240-
<FormattedNumber
241-
value={incentivesNetAPR}
242-
percent
243-
variant="secondary12"
244-
color="text.secondary"
245-
/>
246-
);
247-
} else if (incentivesNetAPR !== 'Infinity' && incentivesNetAPR > 9999) {
248-
return (
249-
<FormattedNumber
250-
value={incentivesNetAPR}
251-
percent
252-
compact
253-
variant="secondary12"
254-
color="text.secondary"
255-
/>
256-
);
257-
} else if (incentivesNetAPR === 'Infinity') {
258-
return (
259-
<Typography variant="main12" color="text.secondary">
260-
261-
</Typography>
262-
);
336+
// NOTE: For GHO incentives, we want to show the formatted number given its on sGHO page only
337+
338+
const hasGhoIncentives = incentives.some(
339+
(incentive) =>
340+
incentive.rewardTokenSymbol?.toLowerCase().includes('gho') ||
341+
incentive.rewardTokenSymbol?.toLowerCase().includes('agho') ||
342+
incentive.rewardTokenSymbol?.toLowerCase().includes('abasgho')
343+
);
344+
345+
if (hasGhoIncentives) {
346+
if (incentivesNetAPR !== INFINITY && incentivesNetAPR < 10000) {
347+
return (
348+
<Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}>
349+
<FormattedNumber
350+
value={incentivesNetAPR}
351+
percent
352+
variant="secondary12"
353+
color="text.secondary"
354+
/>
355+
<IncentivesIcon width="16" height="16" />
356+
</Box>
357+
);
358+
} else if (incentivesNetAPR !== INFINITY && incentivesNetAPR > 9999) {
359+
return (
360+
<Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}>
361+
<FormattedNumber
362+
value={incentivesNetAPR}
363+
percent
364+
compact
365+
variant="secondary12"
366+
color="text.secondary"
367+
/>
368+
<IncentivesIcon width="16" height="16" />
369+
</Box>
370+
);
371+
} else if (incentivesNetAPR === INFINITY) {
372+
return (
373+
<Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}>
374+
<Typography variant="main12" color="text.secondary">
375+
376+
</Typography>
377+
<IncentivesIcon width="16" height="16" />
378+
</Box>
379+
);
380+
}
263381
}
382+
383+
// Default behavior: show icon for non-GHO incentives
384+
return (
385+
<>
386+
<IncentivesIcon width="16" height="16" />
387+
</>
388+
);
264389
};
265390

266-
const iconSize = 12;
391+
// const iconSize = 12;
267392

268393
return (
269394
<Box
270-
sx={(theme) => ({
271-
p: { xs: '0 4px', xsm: '2px 4px' },
272-
border: `1px solid ${open ? theme.palette.action.disabled : theme.palette.divider}`,
395+
sx={() => ({
273396
borderRadius: '4px',
274397
cursor: 'pointer',
275398
display: 'flex',
276399
alignItems: 'center',
277400
justifyContent: 'center',
278401
transition: 'opacity 0.2s ease',
279-
bgcolor: open ? 'action.hover' : 'transparent',
280402
'&:hover': {
281403
bgcolor: 'action.hover',
282404
borderColor: 'action.disabled',
@@ -288,10 +410,10 @@ const Content = ({
288410
setOpen(!open);
289411
}}
290412
>
291-
<Box sx={{ mr: 2 }}>
413+
<Box sx={{ p: 0.5 }}>
292414
{plus ? '+' : ''} {incentivesButtonValue()}
293415
</Box>
294-
<Box sx={{ display: 'inline-flex' }}>
416+
{/* <Box sx={{ display: 'inline-flex' }}>
295417
<>
296418
{incentives.length < 5 ? (
297419
<>
@@ -333,7 +455,7 @@ const Content = ({
333455
</>
334456
)}
335457
</>
336-
</Box>
458+
</Box> */}
337459
</Box>
338460
);
339461
};

0 commit comments

Comments
 (0)