@@ -100,19 +104,15 @@ export function RedeemTab(): ReactElement {
{
- const amount = handleInputChangeEventValue(value, 18);
- set_redeemAmount(amount);
- fetchRequiredEth.execute(amount.raw);
- }}
+ amount={redeemAmount}
+ maxAmount={dYFIBalance}
+ onAmountChange={onChangeInput}
onLegendClick={(): void => set_redeemAmount(dYFIBalance)}
onMaxClick={(): void => set_redeemAmount(dYFIBalance)}
legend={formatCounterValue(redeemAmount.normalized, yfiPrice)}
@@ -121,15 +121,14 @@ export function RedeemTab(): ReactElement {
diff --git a/apps/veyfi/components/RewardsTab.tsx b/apps/veyfi/components/RewardsTab.tsx
index 211fef069..0f401c67e 100644
--- a/apps/veyfi/components/RewardsTab.tsx
+++ b/apps/veyfi/components/RewardsTab.tsx
@@ -7,9 +7,9 @@ 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 {toAddress, truncateHex} from '@yearn-finance/web-lib/utils/address';
-import {toBigInt, toNormalizedAmount} from '@yearn-finance/web-lib/utils/format.bigNumber';
+import {toBigInt, toNormalizedBN} from '@yearn-finance/web-lib/utils/format.bigNumber';
+import {formatAmount} from '@yearn-finance/web-lib/utils/format.number';
import {formatCounterValue} from '@yearn-finance/web-lib/utils/format.value';
-import {isZero} from '@yearn-finance/web-lib/utils/isZero';
import {defaultTxStatus} from '@yearn-finance/web-lib/utils/web3/transaction';
import {AmountInput} from '@common/components/AmountInput';
import {Dropdown} from '@common/components/Dropdown';
@@ -27,7 +27,7 @@ export function RewardsTab(): ReactElement {
const refreshData = useCallback((): unknown => Promise.all([refreshGauges()]), [refreshGauges]);
const [claimStatus, set_claimStatus] = useState(defaultTxStatus);
const selectedGaugeAddress = toAddress(selectedGauge?.id);
- const selectedGaugeRewards = toBigInt(positionsMap[selectedGaugeAddress]?.reward?.balance?.raw);
+ const selectedGaugeRewards = toNormalizedBN(toBigInt(positionsMap[selectedGaugeAddress]?.reward?.balance?.raw));
const onClaim = useCallback(async (): Promise
=> {
const result = await GaugeActions.claimRewards({
@@ -74,16 +74,15 @@ export function RewardsTab(): ReactElement {
/>
diff --git a/apps/veyfi/contexts/useOption.tsx b/apps/veyfi/contexts/useOption.tsx
index 7667847e8..318f0059b 100644
--- a/apps/veyfi/contexts/useOption.tsx
+++ b/apps/veyfi/contexts/useOption.tsx
@@ -1,6 +1,5 @@
-import React, {createContext, memo, useCallback, useContext, useEffect, useMemo} from 'react';
-import {ethers} from 'ethers';
-import {useAsync} from '@react-hookz/web';
+import React, {createContext, memo, useCallback, useContext, useState} from 'react';
+import {useDeepCompareMemo} from '@react-hookz/web';
import {VEYFI_DYFI_ABI} from '@veYFI/utils/abi/veYFIdYFI.abi';
import {VEYFI_OPTIONS_ABI} from '@veYFI/utils/abi/veYFIOptions.abi';
import {VEYFI_CHAIN_ID, VEYFI_DYFI_ADDRESS,VEYFI_OPTIONS_ADDRESS} from '@veYFI/utils/constants';
@@ -8,73 +7,40 @@ import {erc20ABI, readContract} from '@wagmi/core';
import {useWeb3} from '@yearn-finance/web-lib/contexts/useWeb3';
import {allowanceKey} from '@yearn-finance/web-lib/utils/address';
import {BIG_ZERO, ETH_TOKEN_ADDRESS, YFI_ADDRESS} from '@yearn-finance/web-lib/utils/constants';
-import {toBigInt, toNormalizedValue} from '@yearn-finance/web-lib/utils/format.bigNumber';
+import {toBigInt, toNormalizedBN, toNormalizedValue} from '@yearn-finance/web-lib/utils/format.bigNumber';
+import {useAsyncTrigger} from '@common/hooks/useAsyncEffect';
import {useTokenPrice} from '@common/hooks/useTokenPrice';
import type {ReactElement} from 'react';
import type {TDict} from '@yearn-finance/web-lib/types';
-
-export type TOptionPosition = {
- balance: bigint,
-}
+import type {TNormalizedBN} from '@common/types/types';
export type TOptionContext = {
getRequiredEth: (amount: bigint) => Promise
,
price: number | undefined,
- positions: TOptionPosition | undefined,
+ position: TNormalizedBN,
allowances: TDict,
- isLoading: boolean,
refresh: () => void,
}
const defaultProps: TOptionContext = {
getRequiredEth: async (): Promise => BIG_ZERO,
price: undefined,
- positions: undefined,
+ position: toNormalizedBN(0),
allowances: {},
- isLoading: true,
refresh: (): void => undefined
};
const OptionContext = createContext(defaultProps);
export const OptionContextApp = memo(function OptionContextApp({children}: {children: ReactElement}): ReactElement {
- const {provider, address: userAddress, isActive} = useWeb3();
+ const {address: userAddress, isActive} = useWeb3();
+ const [price, set_price] = useState(undefined);
+ const [position, set_position] = useState(toNormalizedBN(0));
+ const [allowances, set_allowances] = useState>({});
const yfiPrice = useTokenPrice(YFI_ADDRESS);
const ethPrice = useTokenPrice(ETH_TOKEN_ADDRESS);
- const [{result: price, status: fetchPriceStatus}, {execute: refreshPrice}] = useAsync(async (): Promise => {
- if (!isActive || provider) {
- return;
- }
- return priceFetcher();
- }, 0);
-
- const [{result: positions, status: fetchPositionsStatus}, {execute: refreshPositions}] = useAsync(async (): Promise => {
- if (!isActive || provider) {
- return;
- }
- return positionsFetcher();
- }, {balance: 0n});
-
- const [{result: allowances, status: fetchAllowancesStatus}, {execute: refreshAllowances}] = useAsync(async (): Promise | undefined> => {
- if (!isActive || provider) {
- return;
- }
- return allowancesFetcher();
- }, {});
-
- const refresh = useCallback((): void => {
- refreshPrice();
- refreshPositions();
- refreshAllowances();
- }, [refreshPrice, refreshPositions, refreshAllowances]);
-
- useEffect((): void => {
- refresh();
- }, [refresh]);
-
const getRequiredEth = useCallback(async (amount: bigint): Promise => {
- // TODO: update once abi is available
return readContract({
address: VEYFI_OPTIONS_ADDRESS,
abi: VEYFI_OPTIONS_ABI,
@@ -84,37 +50,36 @@ export const OptionContextApp = memo(function OptionContextApp({children}: {chil
});
}, []);
- const priceFetcher = useCallback(async (): Promise => {
+ const refreshPrice = useAsyncTrigger(async (): Promise => {
+ console.log(ethPrice, yfiPrice);
if(!ethPrice || !yfiPrice) {
return undefined;
}
- const oneOption = ethers.utils.parseEther('1');
- const requiredEthPerOption = await getRequiredEth(toBigInt(oneOption.toString()));
+ const oneOption = toBigInt(1e18);
+ const requiredEthPerOption = await getRequiredEth(oneOption);
const requiredEthValuePerOption = toNormalizedValue(requiredEthPerOption, 18) * ethPrice;
const pricePerOption = yfiPrice - requiredEthValuePerOption;
- return pricePerOption;
+ set_price(pricePerOption);
}, [ethPrice, yfiPrice, getRequiredEth]);
- const positionsFetcher = useCallback(async (): Promise => {
+ const refreshPositions = useAsyncTrigger(async (): Promise => {
if (!isActive || !userAddress) {
- return undefined;
+ return;
}
- // TODO: update once abi is available
- return {
- balance: await readContract({
- address: VEYFI_DYFI_ADDRESS,
- abi: VEYFI_DYFI_ABI,
- functionName: 'balanceOf',
- args: [userAddress],
- chainId: VEYFI_CHAIN_ID
- })
- };
+ const dYFIBalance = await readContract({
+ address: VEYFI_DYFI_ADDRESS,
+ abi: VEYFI_DYFI_ABI,
+ functionName: 'balanceOf',
+ args: [userAddress],
+ chainId: VEYFI_CHAIN_ID
+ });
+ set_position(toNormalizedBN(dYFIBalance));
}, [isActive, userAddress]);
- const allowancesFetcher = useCallback(async (): Promise> => {
+ const refreshAllowances = useAsyncTrigger(async (): Promise => {
if (!isActive || !userAddress) {
- return {};
+ return;
}
const dYFIAllowanceOptions = await readContract({
@@ -125,19 +90,24 @@ export const OptionContextApp = memo(function OptionContextApp({children}: {chil
chainId: VEYFI_CHAIN_ID
});
- return ({
+ set_allowances({
[allowanceKey(VEYFI_CHAIN_ID, VEYFI_DYFI_ADDRESS, VEYFI_OPTIONS_ADDRESS, userAddress)]: dYFIAllowanceOptions
});
}, [isActive, userAddress]);
- const contextValue = useMemo((): TOptionContext => ({
+ const refresh = useCallback((): void => {
+ refreshPrice();
+ refreshPositions();
+ refreshAllowances();
+ }, [refreshPrice, refreshPositions, refreshAllowances]);
+
+ const contextValue = useDeepCompareMemo((): TOptionContext => ({
getRequiredEth,
price,
- positions,
+ position,
allowances: allowances ?? {},
- isLoading: fetchPriceStatus === 'loading' || fetchPositionsStatus === 'loading' || fetchAllowancesStatus === 'loading',
refresh
- }), [allowances, fetchAllowancesStatus, fetchPositionsStatus, fetchPriceStatus, getRequiredEth, positions, price, refresh]);
+ }), [allowances, getRequiredEth, position, price, refresh]);
return (
diff --git a/package.json b/package.json
index 4968a54db..f3b6acafb 100644
--- a/package.json
+++ b/package.json
@@ -19,7 +19,7 @@
"@rainbow-me/rainbowkit": "^1.1.2",
"@wagmi/chains": "^1.8.0",
"@wagmi/core": "^1.4.3",
- "@yearn-finance/web-lib": "^3.0.56",
+ "@yearn-finance/web-lib": "^3.0.57",
"axios": "^1.5.0",
"dayjs": "^1.11.9",
"eslint-plugin-react-hooks": "^4.6.0",
diff --git a/yarn.lock b/yarn.lock
index 861cf6031..e5ff280d7 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3381,10 +3381,10 @@
resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d"
integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==
-"@yearn-finance/web-lib@^3.0.56":
- version "3.0.56"
- resolved "https://registry.yarnpkg.com/@yearn-finance/web-lib/-/web-lib-3.0.56.tgz#321e556abf0d8d8b2e4a854d70ab1fa7ec531ea0"
- integrity sha512-DO3H4XHtH7jK+a4r8+rFeV3+UEnTtQWiRAldqUC0U5Oy44Hb1ha22yHulQG0yWEqw9CG6TLlWtbc2/S5V/nisw==
+"@yearn-finance/web-lib@^3.0.57":
+ version "3.0.57"
+ resolved "https://registry.yarnpkg.com/@yearn-finance/web-lib/-/web-lib-3.0.57.tgz#a1918e313c1d53d48641c7de9a71e2f977379c9f"
+ integrity sha512-AOrv6MzQuTuF+VWkLXhqpMXWNVju8PiFDt3+qZTttfJB7QggeRTb7Hc2mJAVuyhW5CX/4xW4fDTs4+hpEBQp7A==
dependencies:
"@babel/core" "^7.23.0"
"@headlessui/react" "^1.7.17"