Skip to content

Commit

Permalink
fix: incorrect use of AmountInput
Browse files Browse the repository at this point in the history
  • Loading branch information
Majorfi committed Oct 17, 2023
1 parent 5554bfa commit a7aed0a
Show file tree
Hide file tree
Showing 10 changed files with 134 additions and 151 deletions.
19 changes: 6 additions & 13 deletions apps/common/components/AmountInput.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import {Renderable} from '@yearn-finance/web-lib/components/Renderable';
import {isZero} from '@yearn-finance/web-lib/utils/isZero';

import type {ReactElement} from 'react';
import type {TNormalizedBN} from '@common/types/types';

type TAmountInputProps = {
amount: string | number;
maxAmount?: string | number;
amount: TNormalizedBN;
maxAmount?: TNormalizedBN;
maxLabel?: string;
label?: string;
placeholder?: string;
Expand All @@ -31,13 +31,6 @@ export function AmountInput({
onLegendClick,
onMaxClick
}: TAmountInputProps): ReactElement {
let displayedAmount = amount.toString();
if (isZero(displayedAmount) && !disabled) {
displayedAmount = '';
}
if (isZero(displayedAmount) && disabled) {
displayedAmount = '0';
}
return (
<div className={'w-full'}>
{label && (
Expand All @@ -49,10 +42,10 @@ export function AmountInput({
<div className={'relative flex w-full items-center justify-center'}>
<input
className={`h-10 w-full p-2 font-mono text-base font-normal outline-none ${maxAmount && !disabled ? 'pr-12' : null} ${error ? 'border border-solid border-[#EA5204] focus:border-[#EA5204]' : 'border-0 border-none'} ${disabled ? 'bg-neutral-300 text-neutral-600' : 'bg-neutral-0'}`}
type={'number'}
min={0}
type={'text'}
autoComplete={'off'}
aria-label={label}
value={displayedAmount}
value={amount.normalized}
onChange={onAmountChange ? (e): void => onAmountChange(e.target.value) : undefined}
placeholder={loading ? '' : placeholder ?? '0'}
disabled={disabled}
Expand Down
13 changes: 10 additions & 3 deletions apps/common/hooks/useTokenPrice.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@

import {useMemo} from 'react';
import {ETH_TOKEN_ADDRESS, YFI_ADDRESS} from '@yearn-finance/web-lib/utils/constants';
import {formatToNormalizedValue, toBigInt} from '@yearn-finance/web-lib/utils/format.bigNumber';
import {useYearn} from '@common/contexts/useYearn';

Expand All @@ -8,9 +9,15 @@ import type {TAddress} from '@yearn-finance/web-lib/types';
export function useTokenPrice(address: TAddress): number {
const {prices} = useYearn();

const tokenPrice = useMemo((): number => (
formatToNormalizedValue(toBigInt(prices?.[address] || 0), 6)
), [address, prices]);
const tokenPrice = useMemo((): number => {
if (address === YFI_ADDRESS) {
return 5150.96; //TODO: REMOVE
}
if (address === ETH_TOKEN_ADDRESS) {
return 1601.69; //TODO: REMOVE
}
return formatToNormalizedValue(toBigInt(prices?.[address] || 0), 6);
}, [address, prices]);

return tokenPrice;
}
7 changes: 3 additions & 4 deletions apps/veyfi/components/ClaimTab.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import {useCallback, useState} from 'react';
import {formatUnits} from 'viem';
import {useVotingEscrow} from '@veYFI/contexts/useVotingEscrow';
import {withdrawUnlockedVeYFI} from '@veYFI/utils/actions';
import {VEYFI_CHAIN_ID} from '@veYFI/utils/constants';
import {validateNetwork} from '@veYFI/utils/validations';
import {Button} from '@yearn-finance/web-lib/components/Button';
import {useWeb3} from '@yearn-finance/web-lib/contexts/useWeb3';
import {useChainID} from '@yearn-finance/web-lib/hooks/useChainID';
import {toBigInt} from '@yearn-finance/web-lib/utils/format.bigNumber';
import {toBigInt, toNormalizedBN} from '@yearn-finance/web-lib/utils/format.bigNumber';
import {getTimeUntil} from '@yearn-finance/web-lib/utils/time';
import {defaultTxStatus} from '@yearn-finance/web-lib/utils/web3/transaction';
import {AmountInput} from '@common/components/AmountInput';
Expand All @@ -24,7 +23,7 @@ export function ClaimTab(): ReactElement {
const hasLockedAmount = toBigInt(positions?.deposit?.underlyingBalance) > 0n;
const timeUntilUnlock = positions?.unlockTime ? getTimeUntil(positions?.unlockTime) : 0;
const isClaimable = hasLockedAmount && !timeUntilUnlock;
const claimableAmount = isClaimable ? positions?.deposit?.underlyingBalance : '0';
const claimableAmount = toNormalizedBN(toBigInt(isClaimable ? positions?.deposit?.underlyingBalance : 0));
const {isValid: isValidNetwork} = validateNetwork({supportedNetwork: VEYFI_CHAIN_ID, walletNetwork: safeChainID});

const refreshData = useCallback(async (): Promise<void> => {
Expand Down Expand Up @@ -60,7 +59,7 @@ export function ClaimTab(): ReactElement {
<div className={'grid grid-cols-1 gap-6 md:mt-14 md:grid-cols-2'}>
<AmountInput
label={'Unlocked YFI'}
amount={formatUnits(toBigInt(claimableAmount), 18)}
amount={claimableAmount}
disabled />
<Button
className={'w-full md:mt-7'}
Expand Down
25 changes: 16 additions & 9 deletions apps/veyfi/components/LockTab.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import {useCallback, useEffect, useMemo, useState} from 'react';
import {formatUnits} from 'viem';
import {useVotingEscrow} from '@veYFI/contexts/useVotingEscrow';
import {getVotingPower} from '@veYFI/utils';
import {increaseVeYFILockAmount, lockVeYFI} from '@veYFI/utils/actions';
Expand All @@ -21,6 +20,7 @@ import {useBalance} from '@common/hooks/useBalance';
import {approveERC20} from '@common/utils/actions';

import type {ReactElement} from 'react';
import type {TNormalizedBN} from '@yearn-finance/web-lib/utils/format.bigNumber';
import type {TMilliseconds} from '@yearn-finance/web-lib/utils/time';

export function LockTab(): ReactElement {
Expand All @@ -40,8 +40,8 @@ export function LockTab(): ReactElement {
return positions?.unlockTime || Date.now() + fromWeeks(toTime(lockTime));
}, [positions?.unlockTime, lockTime]);

const votingPower = useMemo((): bigint => {
return getVotingPower(toBigInt(positions?.deposit?.underlyingBalance) + toBigInt(lockAmount.raw), unlockTime);
const votingPower = useMemo((): TNormalizedBN => {
return toNormalizedBN(getVotingPower(toBigInt(positions?.deposit?.underlyingBalance) + toBigInt(lockAmount.raw), unlockTime), 18);
}, [positions?.deposit?.underlyingBalance, lockAmount, unlockTime]);

const refreshData = useCallback(async (): Promise<void> => {
Expand Down Expand Up @@ -163,18 +163,25 @@ export function LockTab(): ReactElement {
<div className={'mt-0 grid grid-cols-1 gap-6 md:mt-14 md:grid-cols-2'}>
<AmountInput
label={'YFI'}
amount={lockAmount.normalized}
maxAmount={formatAmount(tokenBalance.normalized, 0, 6)}
amount={lockAmount}
maxAmount={tokenBalance}
onAmountChange={(amount): void => set_lockAmount(handleInputChangeEventValue(amount, 18))}
onLegendClick={(): void => set_lockAmount(tokenBalance)}
onMaxClick={(): void => set_lockAmount(tokenBalance)}
legend={`Available: ${formatAmount(tokenBalance.normalized, 4)} YFI`}
error={lockAmountError} />
<AmountInput
label={'Current lock period (weeks)'}
amount={isZero(toTime(lockTime)) ? '' : Math.floor(toTime(lockTime)).toString()}
onAmountChange={set_lockTime}
maxAmount={(MAX_LOCK_TIME + 1).toString()}
amount={toNormalizedBN(isZero(toTime(lockTime)) ? '' : Math.floor(toTime(lockTime)).toString(), 0)}
onAmountChange={(v: string): void => {
const inputed = handleInputChangeEventValue(v, 0);
if (Number(inputed.normalized) > MAX_LOCK_TIME + 1) {
set_lockTime((MAX_LOCK_TIME + 1).toString());
} else {
set_lockTime(inputed.normalized.toString());
}
}}
maxAmount={toNormalizedBN(MAX_LOCK_TIME + 1, 0)}
onMaxClick={(): void => set_lockTime((MAX_LOCK_TIME + 1).toString())}
disabled={hasLockedAmount}
legend={'Minimum: 1 week'}
Expand All @@ -183,7 +190,7 @@ export function LockTab(): ReactElement {
<div className={'grid grid-cols-1 gap-6 md:grid-cols-2'}>
<AmountInput
label={'Total veYFI'}
amount={formatUnits(votingPower, 18)}
amount={votingPower}
disabled />
<Button
className={'w-full md:mt-7'}
Expand Down
43 changes: 26 additions & 17 deletions apps/veyfi/components/ManageLockTab.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import {useCallback, useMemo, useState} from 'react';
import {formatUnits} from 'viem';
import {useVotingEscrow} from '@veYFI/contexts/useVotingEscrow';
import {getVotingPower} from '@veYFI/utils';
import {extendVeYFILockTime, withdrawLockedVeYFI} from '@veYFI/utils/actions';
Expand All @@ -8,31 +7,33 @@ import {validateAmount, validateNetwork} from '@veYFI/utils/validations';
import {Button} from '@yearn-finance/web-lib/components/Button';
import {useWeb3} from '@yearn-finance/web-lib/contexts/useWeb3';
import {useChainID} from '@yearn-finance/web-lib/hooks/useChainID';
import {toBigInt} from '@yearn-finance/web-lib/utils/format.bigNumber';
import {toBigInt, toNormalizedBN} from '@yearn-finance/web-lib/utils/format.bigNumber';
import {handleInputChangeEventValue} from '@yearn-finance/web-lib/utils/handlers/handleInputChangeEventValue';
import {fromWeeks, getTimeUntil, toSeconds, toTime, toWeeks} from '@yearn-finance/web-lib/utils/time';
import {defaultTxStatus} from '@yearn-finance/web-lib/utils/web3/transaction';
import {AmountInput} from '@common/components/AmountInput';
import {useWallet} from '@common/contexts/useWallet';

import type {ReactElement} from 'react';
import type {TNormalizedBN} from '@common/types/types';

export function ManageLockTab(): ReactElement {
const [lockTime, set_lockTime] = useState('');
const [lockTime, set_lockTime] = useState<TNormalizedBN>(toNormalizedBN(0, 0));
const {provider, address, isActive} = useWeb3();
const {safeChainID} = useChainID();
const {refresh: refreshBalances} = useWallet();
const {votingEscrow, positions, refresh: refreshVotingEscrow} = useVotingEscrow();
const hasLockedAmount = toBigInt(positions?.deposit?.underlyingBalance) > 0n;
const willExtendLock = toBigInt(lockTime) > 0n;
const willExtendLock = toBigInt(lockTime.raw) > 0n;
const timeUntilUnlock = positions?.unlockTime ? getTimeUntil(positions?.unlockTime) : undefined;
const weeksToUnlock = toWeeks(timeUntilUnlock);
const newUnlockTime = toTime(positions?.unlockTime) + fromWeeks(toTime(lockTime));
const weeksToUnlock = toNormalizedBN(toWeeks(timeUntilUnlock), 0);
const newUnlockTime = toTime(positions?.unlockTime) + fromWeeks(toTime(lockTime.normalized));
const hasPenalty = toBigInt(positions?.penalty) > 0n;
const [extendLockTimeStatus, set_extendLockTimeStatus] = useState(defaultTxStatus);
const [withdrawLockedStatus, set_withdrawLockedStatus] = useState(defaultTxStatus);

const onTxSuccess = useCallback(async (): Promise<void> => {
await Promise.all([refreshVotingEscrow(), refreshBalances(), set_lockTime('')]);
await Promise.all([refreshVotingEscrow(), refreshBalances(), set_lockTime(toNormalizedBN(0, 0))]);
}, [refreshBalances, refreshVotingEscrow]);

const onExtendLockTime = useCallback(async (): Promise<void> => {
Expand Down Expand Up @@ -60,20 +61,21 @@ export function ManageLockTab(): ReactElement {
}
}, [onTxSuccess, provider, votingEscrow?.address]);

const votingPower = useMemo((): bigint => {
const votingPower = useMemo((): TNormalizedBN => {
if(!positions?.deposit || !newUnlockTime) {
return 0n;
return toNormalizedBN(0);
}
return willExtendLock ? getVotingPower(positions?.deposit?.underlyingBalance, newUnlockTime) : toBigInt(positions?.deposit?.balance);
return toNormalizedBN(willExtendLock ? getVotingPower(positions?.deposit?.underlyingBalance, newUnlockTime) : toBigInt(positions?.deposit?.balance));
}, [positions?.deposit, newUnlockTime, willExtendLock]);

const {isValid: isValidLockTime, error: lockTimeError} = validateAmount({
amount: lockTime,
amount: lockTime.normalized,
minAmountAllowed: MIN_LOCK_TIME
});

const {isValid: isValidNetwork} = validateNetwork({supportedNetwork: VEYFI_CHAIN_ID, walletNetwork: safeChainID});

const maxTime = MAX_LOCK_TIME - Number(weeksToUnlock?.normalized || 0) > 0 ? MAX_LOCK_TIME - Number(weeksToUnlock?.normalized || 0) : 0;
return (
<div className={'grid grid-cols-1 gap-6 md:grid-cols-2 md:gap-16'}>
<div className={'col-span-1 grid w-full gap-6'}>
Expand All @@ -93,17 +95,24 @@ export function ManageLockTab(): ReactElement {
<AmountInput
label={'Increase lock period (weeks)'}
amount={lockTime}
onAmountChange={(amount): void => set_lockTime(Math.floor(toTime(amount)).toString())}
maxAmount={MAX_LOCK_TIME - weeksToUnlock > 0 ? MAX_LOCK_TIME - weeksToUnlock : 0}
onMaxClick={(): void => set_lockTime(Math.floor(toTime(MAX_LOCK_TIME - weeksToUnlock > 0 ? MAX_LOCK_TIME - weeksToUnlock : 0)).toString())}
onAmountChange={(v: string): void => {
const inputed = handleInputChangeEventValue(v, 0);
if (Number(inputed.normalized) > maxTime) {
set_lockTime(toNormalizedBN(maxTime, 0));
} else {
set_lockTime(toNormalizedBN(Math.floor(toTime(v)), 0));
}
}}
maxAmount={toNormalizedBN(maxTime, 0)}
onMaxClick={(): void => set_lockTime(toNormalizedBN(Math.floor(toTime(maxTime)), 0))}
disabled={!hasLockedAmount}
error={lockTimeError}
legend={'Minimum: 1 week'} />
</div>
<div className={'grid grid-cols-1 gap-6 md:grid-cols-2 md:pb-5'}>
<AmountInput
label={'Total veYFI'}
amount={formatUnits(votingPower, 18)}
amount={votingPower}
disabled />
<Button
className={'w-full md:mt-7'}
Expand All @@ -127,7 +136,7 @@ export function ManageLockTab(): ReactElement {
<div className={'grid grid-cols-1 gap-6 md:grid-cols-2 md:pb-5'}>
<AmountInput
label={'veYFI you have'}
amount={formatUnits(toBigInt(positions?.deposit?.balance), 18)}
amount={toNormalizedBN(toBigInt(positions?.deposit?.underlyingBalance), 18)}
disabled />
<AmountInput
label={'Current lock time (weeks)'}
Expand All @@ -137,7 +146,7 @@ export function ManageLockTab(): ReactElement {
<div className={'grid grid-cols-1 gap-6 md:grid-cols-2'}>
<AmountInput
label={'YFI you get'}
amount={formatUnits(toBigInt(positions?.withdrawable), 18)}
amount={toNormalizedBN(toBigInt(positions?.withdrawable), 18)}
legend={`Penalty: ${((positions?.penaltyRatio ?? 0) * 100).toFixed(2)}%`}
disabled />
<Button
Expand Down
Loading

0 comments on commit a7aed0a

Please sign in to comment.