Skip to content

Commit 0d6c834

Browse files
committed
feat: wip
1 parent c1b2207 commit 0d6c834

13 files changed

Lines changed: 170 additions & 155 deletions

File tree

apps/evm/src/components/SelectTokenTextField/TokenList/index.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@ import { type InputHTMLAttributes, useMemo, useState } from 'react';
55
import { TokenIconWithSymbol } from 'components/TokenIconWithSymbol';
66
import { useTranslation } from 'libs/translations';
77
import type { Token, TokenBalance } from 'types';
8-
import { convertMantissaToTokens } from 'utilities';
8+
import { areTokensEqual, convertMantissaToTokens } from 'utilities';
99

1010
import { SenaryButton } from '@venusprotocol/ui';
11+
import { Icon } from 'components';
1112
import { TextField } from '../../TextField';
1213
import { useStyles as useParentStyles } from '../styles';
1314
import { getTokenListItemTestId } from '../testIdGetters';
@@ -18,6 +19,7 @@ export interface TokenListProps {
1819
tokenBalances: OptionalTokenBalance[];
1920
onTokenClick: (token: Token) => void;
2021
displayCommonTokenButtons: boolean;
22+
selectedToken: Token;
2123
'data-testid'?: string;
2224
}
2325

@@ -27,6 +29,7 @@ export const TokenList: React.FC<TokenListProps> = ({
2729
tokenBalances,
2830
onTokenClick,
2931
displayCommonTokenButtons,
32+
selectedToken,
3033
'data-testid': testId,
3134
}) => {
3235
const { t } = useTranslation();
@@ -137,6 +140,10 @@ export const TokenList: React.FC<TokenListProps> = ({
137140
})}
138141
</Typography>
139142
)}
143+
144+
{!tokenBalance.balanceMantissa && areTokensEqual(tokenBalance.token, selectedToken) && (
145+
<Icon name="mark" className="text-green size-5" />
146+
)}
140147
</div>
141148
))}
142149
</div>

apps/evm/src/components/SelectTokenTextField/index.tsx

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { useState } from 'react';
44

55
import type { Token } from 'types';
66

7-
import { TertiaryButton, cn } from '@venusprotocol/ui';
7+
import { TertiaryButton } from '@venusprotocol/ui';
88
import { Icon } from '../Icon';
99
import { TokenIcon } from '../TokenIcon';
1010
import { TokenTextField, type TokenTextFieldProps } from '../TokenTextField';
@@ -17,12 +17,13 @@ import {
1717
} from './testIdGetters';
1818
import type { OptionalTokenBalance } from './types';
1919

20+
export * from './types';
21+
2022
export interface SelectTokenTextFieldProps extends Omit<TokenTextFieldProps, 'max' | 'token'> {
2123
tokenBalances: OptionalTokenBalance[];
2224
selectedToken: Token;
2325
onChangeSelectedToken: (token: Token) => void;
2426
token?: Token;
25-
selectedTokenLabel?: string;
2627
displayCommonTokenButtons?: boolean;
2728
'data-testid'?: string;
2829
}
@@ -38,7 +39,6 @@ export const SelectTokenTextField: React.FC<SelectTokenTextFieldProps> = ({
3839
rightMaxButton,
3940
'data-testid': testId,
4041
description,
41-
selectedTokenLabel,
4242
displayCommonTokenButtons = false,
4343
...otherTokenTextFieldProps
4444
}) => {
@@ -72,15 +72,7 @@ export const SelectTokenTextField: React.FC<SelectTokenTextFieldProps> = ({
7272
<div className="flex items-center gap-x-2">
7373
<TokenIcon token={selectedToken} className="h-5 w-5" />
7474

75-
<div className="text-left">
76-
<div className={cn(!!selectedTokenLabel && 'leading-3')}>
77-
{selectedToken.symbol}
78-
</div>
79-
80-
{!!selectedTokenLabel && (
81-
<p className="text-xs text-grey leading-3 font-normal">{selectedTokenLabel}</p>
82-
)}
83-
</div>
75+
<div className="text-left">{selectedToken.symbol}</div>
8476
</div>
8577

8678
<Icon
@@ -112,6 +104,7 @@ export const SelectTokenTextField: React.FC<SelectTokenTextFieldProps> = ({
112104
tokenBalances={tokenBalances}
113105
data-testid={testId}
114106
onTokenClick={handleChangeSelectedToken}
107+
selectedToken={selectedToken}
115108
displayCommonTokenButtons={displayCommonTokenButtons}
116109
/>
117110
)}

apps/evm/src/libs/translations/translations/en.json

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -225,14 +225,15 @@
225225
}
226226
},
227227
"apyBreakdown": {
228-
"borrowApy": "Borrow APY",
228+
"borrowApy": "Borrow APY (-)",
229229
"distributionApy": "Distribution APY",
230230
"distributionTooltip": "Distribution rewards are initiated and implemented by the decentralized Venus community. The Venus protocol does not guarantee them and accepts no liability.",
231231
"externalDistributionApy": "{{description}} APY",
232232
"intrinsicApy": "Intrinsic APY",
233233
"intrinsicApyTooltip": "APY earned directly from the asset itself (e.g. staking or external rewards), separate from Venus lending yield. The Venus protocol does not guarantee them and accepts no liability.",
234234
"netApy": {
235-
"label": "Net APY"
235+
"label": "Net APY",
236+
"tooltip": "Sum of the APYs of all the markets involved"
236237
},
237238
"offChainApy": "Off-chain APY",
238239
"offChainApyTooltip": "Additional yield from off-chain activities, such as airdrop or promotional campaigns, managed by third parties. The Venus protocol does not guarantee them and accepts no liability.",
@@ -663,12 +664,10 @@
663664
"borrow": "Borrow {{ tokenSymbol }}",
664665
"supply": "Supply {{ tokenSymbol }}",
665666
"swap": "Swap"
666-
},
667-
"supply": "Supply"
667+
}
668668
},
669669
"boostTabAltText": "Rocket icon",
670670
"boostTabTitle": "Boost",
671-
"borrowBalance": "Borrow balance ({{ tokenSymbol }})",
672671
"borrowTabTitle": "Borrow",
673672
"error": {
674673
"borrowCapReached": "The borrow cap of {{assetBorrowCap}} has been reached for this pool. You can not borrow from this market anymore until loans are repaid or its borrow cap is increased.",
@@ -716,7 +715,6 @@
716715
"supply": {
717716
"collateral": "Collateral"
718717
},
719-
"supplyBalance": "Supply balance ({{ tokenSymbol }})",
720718
"supplyTabTitle": "Supply",
721719
"swapDetails": {
722720
"label": {

apps/evm/src/pages/Market/OperationForm/ApyBreakdown/__tests__/__snapshots__/index.spec.tsx.snap

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
22

3-
exports[`ApyBreakdown > renders correct values: 'borrow' 1`] = `"Borrow APY-4.97%Distribution APY0.52%Total APY6.50%"`;
3+
exports[`ApyBreakdown > renders correct values: 'borrow' 1`] = `"Borrow APY (-)-4.97%Distribution APY0.52%Total APY6.50%"`;
44

5-
exports[`ApyBreakdown > renders correct values: 'multiple mutations' 1`] = `"Supply APY0.05%Distribution APY0.12%Borrow APY-4.97%Distribution APY0.52%Net APY7.67%"`;
5+
exports[`ApyBreakdown > renders correct values: 'multiple mutations' 1`] = `"Supply APY0.05%Distribution APY0.12%Borrow APY (-)-4.97%Distribution APY0.52%Net APY7.67%"`;
66

77
exports[`ApyBreakdown > renders correct values: 'no mutations' 1`] = `"Total APY0%"`;
88

9-
exports[`ApyBreakdown > renders correct values: 'repay' 1`] = `"Borrow APY-4.97%Distribution APY0.52%Total APY6.50%"`;
9+
exports[`ApyBreakdown > renders correct values: 'repay' 1`] = `"Borrow APY (-)-4.97%Distribution APY0.52%Total APY6.50%"`;
1010

1111
exports[`ApyBreakdown > renders correct values: 'supply' 1`] = `"Supply APY0.05%Distribution APY0.12%Total APY1.17%"`;
1212

apps/evm/src/pages/Market/OperationForm/ApyBreakdown/index.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,16 +84,17 @@ export const ApyBreakdown: React.FC<ApyBreakdownProps> = ({
8484

8585
if (balanceMutations.length > 1) {
8686
label = t('apyBreakdown.netApy.label');
87+
tooltip = t('apyBreakdown.netApy.tooltip');
8788
} else {
8889
const balanceMutationAction = balanceMutations[0]?.action;
8990

9091
tooltip =
91-
balanceMutationAction === 'borrow' || balanceMutationAction === 'repay'
92-
? t('apyBreakdown.totalApy.borrowApyTooltip')
93-
: t('apyBreakdown.totalApy.supplyApyTooltip');
92+
balanceMutationAction === 'supply' || balanceMutationAction === 'withdraw'
93+
? t('apyBreakdown.totalApy.supplyApyTooltip')
94+
: t('apyBreakdown.totalApy.borrowApyTooltip');
9495
}
9596

96-
const rowsDom = rows.map(row => <LabeledInlineContent {...row} key={row.label} />);
97+
const rowsDom = rows.map((row, i) => <LabeledInlineContent {...row} key={`${row.label}-${i}`} />);
9798

9899
if (renderType === 'block') {
99100
return (

apps/evm/src/pages/Market/OperationForm/BoostForm/Flow/index.tsx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,20 @@ import { Icon } from 'components';
22
import { useTranslation } from 'libs/translations';
33

44
export interface FlowProps {
5-
fromTokenSymbol: string;
6-
toTokenSymbol: string;
5+
borrowedTokenSymbol: string;
6+
suppliedTokenSymbol: string;
77
}
88

9-
export const Flow: React.FC<FlowProps> = ({ fromTokenSymbol, toTokenSymbol }) => {
9+
// TODO: add tests
10+
11+
export const Flow: React.FC<FlowProps> = ({ borrowedTokenSymbol, suppliedTokenSymbol }) => {
1012
const { t } = useTranslation();
1113

1214
return (
1315
<div className="flex items-center gap-x-[2px] text-grey text-sm">
1416
<p>
1517
{t('operationForm.boost.flows.borrow', {
16-
tokenSymbol: fromTokenSymbol,
18+
tokenSymbol: borrowedTokenSymbol,
1719
})}
1820
</p>
1921

@@ -25,7 +27,7 @@ export const Flow: React.FC<FlowProps> = ({ fromTokenSymbol, toTokenSymbol }) =>
2527

2628
<p>
2729
{t('operationForm.boost.flows.supply', {
28-
tokenSymbol: toTokenSymbol,
30+
tokenSymbol: suppliedTokenSymbol,
2931
})}
3032
</p>
3133
</div>

apps/evm/src/pages/Market/OperationForm/BoostForm/LeverageSlider/index.tsx

Lines changed: 2 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,14 @@
11
import BigNumber from 'bignumber.js';
22
import { useState } from 'react';
33

4-
import {
5-
LabeledInlineContent,
6-
Slider,
7-
TextField,
8-
type TextFieldProps,
9-
ValueUpdate,
10-
} from 'components';
4+
import { LabeledInlineContent, Slider, TextField, type TextFieldProps } from 'components';
115
import { useTranslation } from 'libs/translations';
126
import type { Asset } from 'types';
13-
import { formatTokensToReadableValue, getDecimals } from 'utilities';
7+
import { getDecimals } from 'utilities';
148

159
const MAX_LEVERAGE_FACTOR_DECIMALS = 1;
1610

1711
export interface LeverageSliderProps {
18-
fromAsset: Asset;
1912
toAsset: Asset;
2013
value: string;
2114
onChange: (newValue: string) => void;
@@ -24,7 +17,6 @@ export interface LeverageSliderProps {
2417

2518
export const LeverageSlider: React.FC<LeverageSliderProps> = ({
2619
value,
27-
fromAsset,
2820
toAsset,
2921
onChange,
3022
disabled = false,
@@ -66,8 +58,6 @@ export const LeverageSlider: React.FC<LeverageSliderProps> = ({
6658
onBlur={() => setIsLeverageFactorInputFocused(false)}
6759
value={isLeverageFactorInputFocused ? value : `${value || 0}x`}
6860
step={0.1}
69-
variant="tertiary"
70-
size="xxs"
7161
className="w-[54px]"
7262
type={isLeverageFactorInputFocused ? 'number' : 'string'}
7363
min={0}
@@ -90,40 +80,6 @@ export const LeverageSlider: React.FC<LeverageSliderProps> = ({
9080
))}
9181
</div>
9282
</div>
93-
94-
<div className="space-y-2">
95-
<LabeledInlineContent
96-
label={t('operationForm.supplyBalance', {
97-
tokenSymbol: toAsset.vToken.underlyingToken.symbol,
98-
})}
99-
iconSrc={toAsset.vToken.underlyingToken}
100-
>
101-
<ValueUpdate
102-
original={formatTokensToReadableValue({
103-
value: toAsset.userSupplyBalanceTokens,
104-
token: toAsset.vToken.underlyingToken,
105-
addSymbol: false,
106-
})}
107-
// TODO: add hypothetical supply balance
108-
/>
109-
</LabeledInlineContent>
110-
111-
<LabeledInlineContent
112-
label={t('operationForm.borrowBalance', {
113-
tokenSymbol: fromAsset.vToken.underlyingToken.symbol,
114-
})}
115-
iconSrc={fromAsset.vToken.underlyingToken}
116-
>
117-
<ValueUpdate
118-
original={formatTokensToReadableValue({
119-
value: fromAsset.userBorrowBalanceTokens,
120-
token: fromAsset.vToken.underlyingToken,
121-
addSymbol: false,
122-
})}
123-
// TODO: add hypothetical borrow balance
124-
/>
125-
</LabeledInlineContent>
126-
</div>
12783
</div>
12884
);
12985
};
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import BigNumber from 'bignumber.js';
2+
3+
import type { Asset } from 'types';
4+
import { clampToZero } from 'utilities';
5+
6+
export const calculateUserMaxBorrowTokens = ({
7+
borrowedAsset,
8+
suppliedAsset,
9+
userBorrowingPowerCents,
10+
}: { borrowedAsset: Asset; suppliedAsset: Asset; userBorrowingPowerCents: BigNumber }) => {
11+
const userMaxBorrowCents = userBorrowingPowerCents.div(
12+
new BigNumber(1).minus(suppliedAsset.userCollateralFactor),
13+
);
14+
15+
const userMaxBorrowTokens = userMaxBorrowCents
16+
.div(borrowedAsset.tokenPriceCents)
17+
.dp(borrowedAsset.vToken.underlyingToken.decimals);
18+
19+
const marginWithBorrowCapTokens = borrowedAsset.borrowCapTokens.minus(
20+
borrowedAsset.borrowBalanceTokens,
21+
);
22+
23+
// Take borrow cap in consideration
24+
return clampToZero({
25+
value: BigNumber.min(userMaxBorrowTokens, marginWithBorrowCapTokens),
26+
});
27+
};

0 commit comments

Comments
 (0)