Skip to content

Commit

Permalink
Merge pull request #258 from yearn/feat/veyfi-gauges-merged-gauges-tab
Browse files Browse the repository at this point in the history
feat: Migrate GaugesTab to wagmi
  • Loading branch information
karelianpie committed Jul 3, 2023
2 parents bb00929 + c2595b8 commit 8d0c5fd
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 91 deletions.
66 changes: 48 additions & 18 deletions apps/veyfi/components/GaugesTab.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import {useState} from 'react';
import {useGauge} from '@veYFI/contexts/useGauge';
import {useTransaction} from '@veYFI/hooks/useTransaction';
import * as GaugeActions from '@veYFI/utils/actions/gauge';
import {validateNetwork} from '@veYFI/utils/validations';
import {Button} from '@yearn-finance/web-lib/components/Button';
Expand All @@ -9,12 +8,12 @@ import {allowanceKey, toAddress} from '@yearn-finance/web-lib/utils/address';
import {formatBigNumberAsAmount, toBigInt, toNormalizedValue} from '@yearn-finance/web-lib/utils/format.bigNumber';
import {formatAmount, formatPercent} from '@yearn-finance/web-lib/utils/format.number';
import {isZero} from '@yearn-finance/web-lib/utils/isZero';
import {defaultTxStatus} from '@yearn-finance/web-lib/utils/web3/transaction';
import {ImageWithFallback} from '@common/components/ImageWithFallback';
import {Table} from '@common/components/Table';
import {useWallet} from '@common/contexts/useWallet';
import {useYearn} from '@common/contexts/useYearn';

import type {ethers} from 'ethers';
import type {ReactElement} from 'react';
import type {TAddress} from '@yearn-finance/web-lib/types';

Expand Down Expand Up @@ -42,11 +41,10 @@ function GaugesTab(): ReactElement {
const {vaults} = useYearn();
const {balances, refresh: refreshBalances} = useWallet();
const refreshData = (): unknown => Promise.all([refreshGauges(), refreshBalances()]);
const [approveAndStake, approveAndStakeStatus] = useTransaction(GaugeActions.approveAndStake, refreshData);
const [stake, stakeStatus] = useTransaction(GaugeActions.stake, refreshData);
const [unstake, unstakeStatus] = useTransaction(GaugeActions.unstake, refreshData);
const [approveAndStakeStatus, set_approveAndStakeStatus] = useState(defaultTxStatus);
const [stakeStatus, set_stakeStatus] = useState(defaultTxStatus);
const [unstakeStatus, set_unstakeStatus] = useState(defaultTxStatus);

const web3Provider = provider as ethers.providers.Web3Provider;
const userAddress = address as TAddress;

const gaugesData = gaugeAddresses.map((address): TGaugeData => {
Expand All @@ -73,22 +71,54 @@ function GaugesTab(): ReactElement {

const {isValid: isValidNetwork} = validateNetwork({supportedNetwork: 1, walletNetwork: chainID});

const onApproveAndStake = (vaultAddress: TAddress, gaugeAddress: TAddress, amount: bigint, allowance: bigint): void => {
const onApproveAndStake = async (vaultAddress: TAddress, gaugeAddress: TAddress, amount: bigint, allowance: bigint): Promise<void> => {
set_selectedGauge(gaugeAddress);
set_selectedAction('stake');
approveAndStake(web3Provider, userAddress, vaultAddress, gaugeAddress, amount, allowance);
const response = await GaugeActions.approveAndStake({
connector: provider,
contractAddress: gaugeAddress,
vaultAddress,
amount,
allowance,
statusHandler: set_approveAndStakeStatus
});

if (response.isSuccessful) {
await refreshData();
}
};

const onStake = (gaugeAddress: TAddress, amount: bigint): void => {
const onStake = async (gaugeAddress: TAddress, amount: bigint): Promise<void> => {
set_selectedGauge(gaugeAddress);
set_selectedAction('stake');
stake(web3Provider, userAddress, gaugeAddress, amount);

const response = await GaugeActions.stake({
connector: provider,
contractAddress: gaugeAddress,
amount,
statusHandler: set_stakeStatus
});

if (response.isSuccessful) {
await refreshData();
}
};

const onUnstake = (gaugeAddress: TAddress, amount: bigint): void => {
const onUnstake = async (gaugeAddress: TAddress, amount: bigint): Promise<void> => {
set_selectedGauge(gaugeAddress);
set_selectedAction('unstake');
unstake(web3Provider, userAddress, gaugeAddress, amount);

const response = await GaugeActions.unstake({
connector: provider,
contractAddress: gaugeAddress,
accountAddress: userAddress,
amount,
statusHandler: set_unstakeStatus
});

if (response.isSuccessful) {
await refreshData();
}
};

return (
Expand Down Expand Up @@ -157,28 +187,28 @@ function GaugesTab(): ReactElement {
<div className={'flex flex-row justify-center space-x-2 md:justify-end'}>
<Button
className={'w-full md:w-24'}
onClick={(): void => onUnstake(gaugeAddress, gaugeStaked)}
onClick={async (): Promise<void> => onUnstake(gaugeAddress, gaugeStaked)}
disabled={!isActive || !isValidNetwork || isZero(gaugeStaked)}
isBusy={gaugeAddress === selectedGauge && selectedAction === 'unstake' && unstakeStatus.loading}
isBusy={gaugeAddress === selectedGauge && selectedAction === 'unstake' && unstakeStatus.none}
>
{'Unstake'}
</Button>
{!isApproved && (
<Button
className={'w-full md:w-24'}
onClick={(): void => onApproveAndStake(vaultAddress, gaugeAddress, vaultDeposited, allowance)}
onClick={async (): Promise<void> => onApproveAndStake(vaultAddress, gaugeAddress, vaultDeposited, allowance)}
disabled={!isActive || !isValidNetwork || isZero(vaultDeposited)}
isBusy={(isLoadingGauges && vaultDeposited > 0n) || (gaugeAddress === selectedGauge && selectedAction === 'stake' && approveAndStakeStatus.loading)}
isBusy={(isLoadingGauges && vaultDeposited > 0n) || (gaugeAddress === selectedGauge && selectedAction === 'stake' && approveAndStakeStatus.none)}
>
{'Stake'}
</Button>
)}
{isApproved && (
<Button
className={'w-full md:w-24'}
onClick={(): void => onStake(gaugeAddress, vaultDeposited)}
onClick={async (): Promise<void> => onStake(gaugeAddress, vaultDeposited)}
disabled={!isActive || !isValidNetwork || isZero(vaultDeposited)}
isBusy={(isLoadingGauges && vaultDeposited > 0n) || (gaugeAddress === selectedGauge && selectedAction === 'stake' && stakeStatus.loading)}
isBusy={(isLoadingGauges && vaultDeposited > 0n) || (gaugeAddress === selectedGauge && selectedAction === 'stake' && stakeStatus.none)}
>
{'Stake'}
</Button>
Expand Down
86 changes: 54 additions & 32 deletions apps/veyfi/utils/actions/gauge.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {ethers} from 'ethers';
import {handleTx} from '@yearn-finance/web-lib/utils/web3/transaction';
import {assert} from '@common/utils/assert';
import {assertAddress, assertAddresses, handleTx as handleTxWagmi} from '@common/utils/toWagmiProvider';

import VEYFI_CLAIM_REWARDS_ZAP_ABI from '../abi/veYFIClaimRewardsZap.abi';
Expand All @@ -21,44 +22,65 @@ export async function approveStake(
return await handleTx(contract.approve(gaugeAddress, amount));
}

export async function approveAndStake(
provider: ethers.providers.Web3Provider,
accountAddress: TAddress,
vaultAddress: TAddress,
gaugeAddress: TAddress,
amount: bigint,
allowance: bigint
): Promise<TTxResponse> {
const signer = provider.getSigner(accountAddress);
if(!(allowance >= amount)) {
const contract = new ethers.Contract(vaultAddress, ['function approve(address _spender, uint256 _value) external'], signer);
await contract.approve(gaugeAddress, amount);
type TApproveAndStake = TWriteTransaction & {
vaultAddress: TAddress;
allowance: bigint;
amount: bigint;
};
export async function approveAndStake(props: TApproveAndStake): Promise<TTxResponse> {
assertAddress(props.contractAddress);
assertAddress(props.vaultAddress);
assert(props.amount > 0n, 'Amount is 0');

if(!(props.allowance >= props.amount)) {
await handleTxWagmi(props, {
address: props.vaultAddress,
abi: ['function approve(address _spender, uint256 _value) external'],
functionName: 'approve',
args: [props.contractAddress, props.amount]
});
}
const gaugeContract = new ethers.Contract(gaugeAddress, VEYFI_GAUGE_ABI, signer);
return handleTx(gaugeContract.deposit(amount));

return await handleTxWagmi(props, {
address: props.contractAddress,
abi: VEYFI_GAUGE_ABI,
functionName: 'deposit',
args: [props.amount]
});
}

export async function stake(
provider: ethers.providers.Web3Provider,
accountAddress: TAddress,
gaugeAddress: TAddress,
amount: bigint
): Promise<TTxResponse> {
const signer = provider.getSigner(accountAddress);
const gaugeContract = new ethers.Contract(gaugeAddress, VEYFI_GAUGE_ABI, signer);
return handleTx(gaugeContract.deposit(amount));
type TStake = TWriteTransaction & {
amount: bigint;
};
export async function stake(props: TStake): Promise<TTxResponse> {
assertAddress(props.contractAddress);
assert(props.amount > 0n, 'Amount is 0');

return await handleTxWagmi(props, {
address: props.contractAddress,
abi: VEYFI_GAUGE_ABI,
functionName: 'deposit',
args: [props.amount]
});
}

export async function unstake(
provider: ethers.providers.Web3Provider,
accountAddress: TAddress,
gaugeAddress: TAddress,
amount: bigint
): Promise<TTxResponse> {
type TUnstake = TWriteTransaction & {
accountAddress: TAddress;
amount: bigint;
};
export async function unstake(props: TUnstake): Promise<TTxResponse> {
assertAddress(props.contractAddress);
assertAddress(props.accountAddress);
assert(props.amount > 0n, 'Amount is 0');

const willClaim = false;
const signer = provider.getSigner(accountAddress);
const gaugeContract = new ethers.Contract(gaugeAddress, VEYFI_GAUGE_ABI, signer);
return handleTx(gaugeContract.withdraw(amount, accountAddress, accountAddress, willClaim));

return await handleTxWagmi(props, {
address: props.contractAddress,
abi: VEYFI_GAUGE_ABI,
functionName: 'withdraw',
args: [props.amount, props.accountAddress, props.accountAddress, willClaim]
});
}

type TClaimRewards = TWriteTransaction;
Expand Down
5 changes: 3 additions & 2 deletions apps/veyfi/utils/actions/option.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {assert} from 'vitest';
import VEYFI_OPTIONS_ABI from '@veYFI/utils/abi/veYFIOptions.abi';
import {assert} from '@common/utils/assert';
import {assertAddress, handleTx as handleTxWagmi} from '@common/utils/toWagmiProvider';

import type {TAddress} from '@yearn-finance/web-lib/types';
Expand All @@ -20,6 +20,7 @@ export async function redeem(props: TRedeem): Promise<TTxResponse> {
address: props.contractAddress,
abi: VEYFI_OPTIONS_ABI,
functionName: 'exercise',
args: [props.amount, props.accountAddress, {value: props.ethRequired}]
value: props.ethRequired,
args: [props.amount, props.accountAddress]
});
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@
"sharp": "^0.32.1",
"ts-loader": "^9.4.3",
"typescript": "^5.1.3",
"vitest": "^0.32.0"
"vitest": "^0.32.2"
},
"resolutions": {
"bn.js": "5.2.1",
Expand Down
81 changes: 43 additions & 38 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2682,47 +2682,47 @@
"@babel/plugin-transform-react-jsx-source" "^7.19.6"
react-refresh "^0.14.0"

"@vitest/expect@0.32.0":
version "0.32.0"
resolved "https://registry.yarnpkg.com/@vitest/expect/-/expect-0.32.0.tgz#5b10cdc822d54cb870aef917462fbf847202e4e0"
integrity sha512-VxVHhIxKw9Lux+O9bwLEEk2gzOUe93xuFHy9SzYWnnoYZFYg1NfBtnfnYWiJN7yooJ7KNElCK5YtA7DTZvtXtg==
"@vitest/expect@0.32.2":
version "0.32.2"
resolved "https://registry.yarnpkg.com/@vitest/expect/-/expect-0.32.2.tgz#8111f6ab1ff3b203efbe3a25e8bb2d160ce4b720"
integrity sha512-6q5yzweLnyEv5Zz1fqK5u5E83LU+gOMVBDuxBl2d2Jfx1BAp5M+rZgc5mlyqdnxquyoiOXpXmFNkcGcfFnFH3Q==
dependencies:
"@vitest/spy" "0.32.0"
"@vitest/utils" "0.32.0"
"@vitest/spy" "0.32.2"
"@vitest/utils" "0.32.2"
chai "^4.3.7"

"@vitest/runner@0.32.0":
version "0.32.0"
resolved "https://registry.yarnpkg.com/@vitest/runner/-/runner-0.32.0.tgz#d2a391bf4bb373e324cf2f372d8bb913ab323f08"
integrity sha512-QpCmRxftHkr72xt5A08xTEs9I4iWEXIOCHWhQQguWOKE4QH7DXSKZSOFibuwEIMAD7G0ERvtUyQn7iPWIqSwmw==
"@vitest/runner@0.32.2":
version "0.32.2"
resolved "https://registry.yarnpkg.com/@vitest/runner/-/runner-0.32.2.tgz#18dd979ce4e8766bcc90948d11b4c8ae6ed90b89"
integrity sha512-06vEL0C1pomOEktGoLjzZw+1Fb+7RBRhmw/06WkDrd1akkT9i12su0ku+R/0QM69dfkIL/rAIDTG+CSuQVDcKw==
dependencies:
"@vitest/utils" "0.32.0"
"@vitest/utils" "0.32.2"
concordance "^5.0.4"
p-limit "^4.0.0"
pathe "^1.1.0"

"@vitest/snapshot@0.32.0":
version "0.32.0"
resolved "https://registry.yarnpkg.com/@vitest/snapshot/-/snapshot-0.32.0.tgz#49c6a08da12ab903ab4582386c97d70b293bc644"
integrity sha512-yCKorPWjEnzpUxQpGlxulujTcSPgkblwGzAUEL+z01FTUg/YuCDZ8dxr9sHA08oO2EwxzHXNLjQKWJ2zc2a19Q==
"@vitest/snapshot@0.32.2":
version "0.32.2"
resolved "https://registry.yarnpkg.com/@vitest/snapshot/-/snapshot-0.32.2.tgz#500b6453e88e4c50a0aded39839352c16b519b9e"
integrity sha512-JwhpeH/PPc7GJX38vEfCy9LtRzf9F4er7i4OsAJyV7sjPwjj+AIR8cUgpMTWK4S3TiamzopcTyLsZDMuldoi5A==
dependencies:
magic-string "^0.30.0"
pathe "^1.1.0"
pretty-format "^27.5.1"

"@vitest/spy@0.32.0":
version "0.32.0"
resolved "https://registry.yarnpkg.com/@vitest/spy/-/spy-0.32.0.tgz#3ccb4e6dd4cbda7bb837c467d8405e2f8cc107a2"
integrity sha512-MruAPlM0uyiq3d53BkwTeShXY0rYEfhNGQzVO5GHBmmX3clsxcWp79mMnkOVcV244sNTeDcHbcPFWIjOI4tZvw==
"@vitest/spy@0.32.2":
version "0.32.2"
resolved "https://registry.yarnpkg.com/@vitest/spy/-/spy-0.32.2.tgz#f3ef7afe0d34e863b90df7c959fa5af540a6aaf9"
integrity sha512-Q/ZNILJ4ca/VzQbRM8ur3Si5Sardsh1HofatG9wsJY1RfEaw0XKP8IVax2lI1qnrk9YPuG9LA2LkZ0EI/3d4ug==
dependencies:
tinyspy "^2.1.0"

"@vitest/utils@0.32.0":
version "0.32.0"
resolved "https://registry.yarnpkg.com/@vitest/utils/-/utils-0.32.0.tgz#ffbc023083e0ef8401a3562086de0ff1b0599635"
integrity sha512-53yXunzx47MmbuvcOPpLaVljHaeSu1G2dHdmy7+9ngMnQIkBQcvwOcoclWFnxDMxFbnq8exAfh3aKSZaK71J5A==
"@vitest/utils@0.32.2":
version "0.32.2"
resolved "https://registry.yarnpkg.com/@vitest/utils/-/utils-0.32.2.tgz#809c720cafbf4b35ce651deb8570d57785e77819"
integrity sha512-lnJ0T5i03j0IJaeW73hxe2AuVnZ/y1BhhCOuIcl9LIzXnbpXJT9Lrt6brwKHXLOiA7MZ6N5hSJjt0xE1dGNCzQ==
dependencies:
concordance "^5.0.4"
diff-sequences "^29.4.3"
loupe "^2.3.6"
pretty-format "^27.5.1"

Expand Down Expand Up @@ -4278,6 +4278,11 @@ didyoumean@^1.2.2:
resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.2.tgz#989346ffe9e839b4555ecf5666edea0d3e8ad037"
integrity sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==

diff-sequences@^29.4.3:
version "29.4.3"
resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.4.3.tgz#9314bc1fabe09267ffeca9cbafc457d8499a13f2"
integrity sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==

dijkstrajs@^1.0.1:
version "1.0.3"
resolved "https://registry.yarnpkg.com/dijkstrajs/-/dijkstrajs-1.0.3.tgz#4c8dbdea1f0f6478bff94d9c49c784d623e4fc23"
Expand Down Expand Up @@ -8500,10 +8505,10 @@ viem@^1.0.0, viem@^1.0.5:
isomorphic-ws "5.0.0"
ws "8.12.0"

vite-node@0.32.0:
version "0.32.0"
resolved "https://registry.yarnpkg.com/vite-node/-/vite-node-0.32.0.tgz#8ee54539fa75d1271adaa9788c8ba526480f4519"
integrity sha512-220P/y8YacYAU+daOAqiGEFXx2A8AwjadDzQqos6wSukjvvTWNqleJSwoUn0ckyNdjHIKoxn93Nh1vWBqEKr3Q==
vite-node@0.32.2:
version "0.32.2"
resolved "https://registry.yarnpkg.com/vite-node/-/vite-node-0.32.2.tgz#bfccdfeb708b2309ea9e5fe424951c75bb9c0096"
integrity sha512-dTQ1DCLwl2aEseov7cfQ+kDMNJpM1ebpyMMMwWzBvLbis8Nla/6c9WQcqpPssTwS6Rp/+U6KwlIj8Eapw4bLdA==
dependencies:
cac "^6.7.14"
debug "^4.3.4"
Expand All @@ -8523,19 +8528,19 @@ vite-node@0.32.0:
optionalDependencies:
fsevents "~2.3.2"

vitest@^0.32.0:
version "0.32.0"
resolved "https://registry.yarnpkg.com/vitest/-/vitest-0.32.0.tgz#125212b8abbfdae047fa72e516bc7257fd0a67db"
integrity sha512-SW83o629gCqnV3BqBnTxhB10DAwzwEx3z+rqYZESehUB+eWsJxwcBQx7CKy0otuGMJTYh7qCVuUX23HkftGl/Q==
vitest@^0.32.2:
version "0.32.2"
resolved "https://registry.yarnpkg.com/vitest/-/vitest-0.32.2.tgz#758ce2220f609e240ac054eca7ad11a5140679ab"
integrity sha512-hU8GNNuQfwuQmqTLfiKcqEhZY72Zxb7nnN07koCUNmntNxbKQnVbeIS6sqUgR3eXSlbOpit8+/gr1KpqoMgWCQ==
dependencies:
"@types/chai" "^4.3.5"
"@types/chai-subset" "^1.3.3"
"@types/node" "*"
"@vitest/expect" "0.32.0"
"@vitest/runner" "0.32.0"
"@vitest/snapshot" "0.32.0"
"@vitest/spy" "0.32.0"
"@vitest/utils" "0.32.0"
"@vitest/expect" "0.32.2"
"@vitest/runner" "0.32.2"
"@vitest/snapshot" "0.32.2"
"@vitest/spy" "0.32.2"
"@vitest/utils" "0.32.2"
acorn "^8.8.2"
acorn-walk "^8.2.0"
cac "^6.7.14"
Expand All @@ -8551,7 +8556,7 @@ vitest@^0.32.0:
tinybench "^2.5.0"
tinypool "^0.5.0"
vite "^3.0.0 || ^4.0.0"
vite-node "0.32.0"
vite-node "0.32.2"
why-is-node-running "^2.2.2"

wagmi@^1.1.0, wagmi@^1.1.1:
Expand Down

0 comments on commit 8d0c5fd

Please sign in to comment.